aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-10-08 11:28:07 +0000
committerChristian Grothoff <christian@grothoff.org>2015-10-08 11:28:07 +0000
commit0f4a6dabe46a75ceb41f962e9f60e4a164feb9ec (patch)
tree3507d5e0cd7da76fa245989a01f22786138e6ed6
parent383814672c031e49c4dffca0a69af3b0973d2248 (diff)
downloadgnunet-0f4a6dabe46a75ceb41f962e9f60e4a164feb9ec.tar.gz
gnunet-0f4a6dabe46a75ceb41f962e9f60e4a164feb9ec.zip
export compression/decompression functions
-rw-r--r--src/include/gnunet_container_lib.h39
-rw-r--r--src/util/container_meta_data.c165
2 files changed, 131 insertions, 73 deletions
diff --git a/src/include/gnunet_container_lib.h b/src/include/gnunet_container_lib.h
index 4375cdbb1..aa6a17150 100644
--- a/src/include/gnunet_container_lib.h
+++ b/src/include/gnunet_container_lib.h
@@ -36,6 +36,45 @@
36/* add error and config prototypes */ 36/* add error and config prototypes */
37#include "gnunet_crypto_lib.h" 37#include "gnunet_crypto_lib.h"
38 38
39
40/**
41 * Try to compress the given block of data using libz. Only returns
42 * the compressed block if compression worked and the new block is
43 * actually smaller. Decompress using #GNUNET_decompress().
44 *
45 * @param data block to compress; if compression
46 * resulted in a smaller block, the first
47 * bytes of data are updated to the compressed
48 * data
49 * @param old_size number of bytes in data
50 * @param[out] result set to the compressed data, if compression worked
51 * @param[out] new_size set to size of result, if compression worked
52 * @return #GNUNET_YES if compression reduce the size,
53 * #GNUNET_NO if compression did not help
54 */
55int
56GNUNET_try_compression (const char *data,
57 size_t old_size,
58 char **result,
59 size_t *new_size);
60
61
62/**
63 * Decompress input, return the decompressed data as output. Dual to
64 * #GNUNET_try_compression(). Caller must set @a output_size to the
65 * number of bytes that were originally compressed.
66 *
67 * @param input compressed data
68 * @param input_size number of bytes in input
69 * @param output_size expected size of the output
70 * @return NULL on error, buffer of @a output_size decompressed bytes otherwise
71 */
72char *
73GNUNET_decompress (const char *input,
74 size_t input_size,
75 size_t output_size);
76
77
39#if HAVE_EXTRACTOR_H && HAVE_LIBEXTRACTOR 78#if HAVE_EXTRACTOR_H && HAVE_LIBEXTRACTOR
40 79
41#include <extractor.h> 80#include <extractor.h>
diff --git a/src/util/container_meta_data.c b/src/util/container_meta_data.c
index f978c3011..91b3dbb8c 100644
--- a/src/util/container_meta_data.c
+++ b/src/util/container_meta_data.c
@@ -33,6 +33,91 @@
33 33
34#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) 34#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
35 35
36
37
38/**
39 * Try to compress the given block of data using libz. Only returns
40 * the compressed block if compression worked and the new block is
41 * actually smaller. Decompress using #GNUNET_decompress().
42 *
43 * @param data block to compress; if compression
44 * resulted in a smaller block, the first
45 * bytes of data are updated to the compressed
46 * data
47 * @param old_size number of bytes in data
48 * @param[out] result set to the compressed data, if compression worked
49 * @param[out] new_size set to size of result, if compression worked
50 * @return #GNUNET_YES if compression reduce the size,
51 * #GNUNET_NO if compression did not help
52 */
53int
54GNUNET_try_compression (const char *data,
55 size_t old_size,
56 char **result,
57 size_t *new_size)
58{
59 char *tmp;
60 uLongf dlen;
61
62 *result = NULL;
63 *new_size = 0;
64#ifdef compressBound
65 dlen = compressBound (old_size);
66#else
67 dlen = old_size + (old_size / 100) + 20;
68 /* documentation says 100.1% oldSize + 12 bytes, but we
69 * should be able to overshoot by more to be safe */
70#endif
71 tmp = GNUNET_malloc (dlen);
72 if (Z_OK ==
73 compress2 ((Bytef *) tmp,
74 &dlen,
75 (const Bytef *) data,
76 old_size, 9))
77 {
78 if (dlen < old_size)
79 {
80 *result = tmp;
81 *new_size = dlen;
82 return GNUNET_YES;
83 }
84 }
85 GNUNET_free (tmp);
86 return GNUNET_NO;
87}
88
89
90/**
91 * Decompress input, return the decompressed data as output. Dual to
92 * #GNUNET_try_compression(). Caller must set @a output_size to the
93 * number of bytes that were originally compressed.
94 *
95 * @param input compressed data
96 * @param input_size number of bytes in input
97 * @param output_size expected size of the output
98 * @return NULL on error, buffer of @a output_size decompressed bytes otherwise
99 */
100char *
101GNUNET_decompress (const char *input,
102 size_t input_size,
103 size_t output_size)
104{
105 char *output;
106 uLongf olen;
107
108 olen = output_size;
109 output = GNUNET_malloc (olen);
110 if (Z_OK ==
111 uncompress ((Bytef *) output,
112 &olen,
113 (const Bytef *) input,
114 input_size))
115 return output;
116 GNUNET_free (output);
117 return NULL;
118}
119
120
36/** 121/**
37 * Meta data item. 122 * Meta data item.
38 */ 123 */
@@ -600,50 +685,6 @@ GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData
600} 685}
601 686
602 687
603
604/**
605 * Try to compress the given block of data.
606 *
607 * @param data block to compress; if compression
608 * resulted in a smaller block, the first
609 * bytes of data are updated to the compressed
610 * data
611 * @param oldSize number of bytes in data
612 * @param result set to the compressed data
613 * @param newSize set to size of result
614 * @return #GNUNET_YES if compression reduce the size,
615 * #GNUNET_NO if compression did not help
616 */
617static int
618try_compression (const char *data, size_t oldSize, char **result,
619 size_t * newSize)
620{
621 char *tmp;
622 uLongf dlen;
623
624#ifdef compressBound
625 dlen = compressBound (oldSize);
626#else
627 dlen = oldSize + (oldSize / 100) + 20;
628 /* documentation says 100.1% oldSize + 12 bytes, but we
629 * should be able to overshoot by more to be safe */
630#endif
631 tmp = GNUNET_malloc (dlen);
632 if (Z_OK ==
633 compress2 ((Bytef *) tmp, &dlen, (const Bytef *) data, oldSize, 9))
634 {
635 if (dlen < oldSize)
636 {
637 *result = tmp;
638 *newSize = dlen;
639 return GNUNET_YES;
640 }
641 }
642 GNUNET_free (tmp);
643 return GNUNET_NO;
644}
645
646
647/** 688/**
648 * Flag in 'version' that indicates compressed meta-data. 689 * Flag in 'version' that indicates compressed meta-data.
649 */ 690 */
@@ -846,7 +887,10 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData
846 { 887 {
847 comp = GNUNET_NO; 888 comp = GNUNET_NO;
848 if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS)) 889 if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS))
849 comp = try_compression ((const char *) &ent[i], left, &cdata, &clen); 890 comp = GNUNET_try_compression ((const char *) &ent[i],
891 left,
892 &cdata,
893 &clen);
850 894
851 if ((NULL == md->sbuf) && (0 == i)) 895 if ((NULL == md->sbuf) && (0 == i))
852 { 896 {
@@ -978,32 +1022,6 @@ GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
978 1022
979 1023
980/** 1024/**
981 * Decompress input, return the decompressed data
982 * as output, set outputSize to the number of bytes
983 * that were found.
984 *
985 * @param input compressed data
986 * @param inputSize number of bytes in input
987 * @param outputSize expected size of the output
988 * @return NULL on error
989 */
990static char *
991decompress (const char *input, size_t inputSize, size_t outputSize)
992{
993 char *output;
994 uLongf olen;
995
996 olen = outputSize;
997 output = GNUNET_malloc (olen);
998 if (Z_OK ==
999 uncompress ((Bytef *) output, &olen, (const Bytef *) input, inputSize))
1000 return output;
1001 GNUNET_free (output);
1002 return NULL;
1003}
1004
1005
1006/**
1007 * Deserialize meta-data. Initializes md. 1025 * Deserialize meta-data. Initializes md.
1008 * 1026 *
1009 * @param input buffer with the serialized metadata 1027 * @param input buffer with the serialized metadata
@@ -1068,8 +1086,9 @@ GNUNET_CONTAINER_meta_data_deserialize (const char *input, size_t size)
1068 return NULL; 1086 return NULL;
1069 } 1087 }
1070 data = 1088 data =
1071 decompress ((const char *) &input[sizeof (struct MetaDataHeader)], 1089 GNUNET_decompress ((const char *) &input[sizeof (struct MetaDataHeader)],
1072 size - sizeof (struct MetaDataHeader), dataSize); 1090 size - sizeof (struct MetaDataHeader),
1091 dataSize);
1073 if (NULL == data) 1092 if (NULL == data)
1074 { 1093 {
1075 GNUNET_break_op (0); 1094 GNUNET_break_op (0);