diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-10-08 11:28:07 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-10-08 11:28:07 +0000 |
commit | 0f4a6dabe46a75ceb41f962e9f60e4a164feb9ec (patch) | |
tree | 3507d5e0cd7da76fa245989a01f22786138e6ed6 | |
parent | 383814672c031e49c4dffca0a69af3b0973d2248 (diff) | |
download | gnunet-0f4a6dabe46a75ceb41f962e9f60e4a164feb9ec.tar.gz gnunet-0f4a6dabe46a75ceb41f962e9f60e4a164feb9ec.zip |
export compression/decompression functions
-rw-r--r-- | src/include/gnunet_container_lib.h | 39 | ||||
-rw-r--r-- | src/util/container_meta_data.c | 165 |
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 | */ | ||
55 | int | ||
56 | GNUNET_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 | */ | ||
72 | char * | ||
73 | GNUNET_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 | */ | ||
53 | int | ||
54 | GNUNET_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 | */ | ||
100 | char * | ||
101 | GNUNET_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 | */ | ||
617 | static int | ||
618 | try_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 | */ | ||
990 | static char * | ||
991 | decompress (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); |