diff options
Diffstat (limited to 'src/util/container_meta_data.c')
-rw-r--r-- | src/util/container_meta_data.c | 975 |
1 files changed, 484 insertions, 491 deletions
diff --git a/src/util/container_meta_data.c b/src/util/container_meta_data.c index 4989b876a..e134ef869 100644 --- a/src/util/container_meta_data.c +++ b/src/util/container_meta_data.c | |||
@@ -11,12 +11,12 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
18 | SPDX-License-Identifier: AGPL3.0-or-later | 18 | SPDX-License-Identifier: AGPL3.0-or-later |
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file util/container_meta_data.c | 22 | * @file util/container_meta_data.c |
@@ -31,7 +31,7 @@ | |||
31 | #endif | 31 | #endif |
32 | #include <zlib.h> | 32 | #include <zlib.h> |
33 | 33 | ||
34 | #define LOG(kind,...) GNUNET_log_from (kind, "util-container-meta-data", __VA_ARGS__) | 34 | #define LOG(kind, ...) GNUNET_log_from(kind, "util-container-meta-data", __VA_ARGS__) |
35 | 35 | ||
36 | 36 | ||
37 | 37 | ||
@@ -51,10 +51,10 @@ | |||
51 | * #GNUNET_NO if compression did not help | 51 | * #GNUNET_NO if compression did not help |
52 | */ | 52 | */ |
53 | int | 53 | int |
54 | GNUNET_try_compression (const char *data, | 54 | GNUNET_try_compression(const char *data, |
55 | size_t old_size, | 55 | size_t old_size, |
56 | char **result, | 56 | char **result, |
57 | size_t *new_size) | 57 | size_t *new_size) |
58 | { | 58 | { |
59 | char *tmp; | 59 | char *tmp; |
60 | uLongf dlen; | 60 | uLongf dlen; |
@@ -62,27 +62,27 @@ GNUNET_try_compression (const char *data, | |||
62 | *result = NULL; | 62 | *result = NULL; |
63 | *new_size = 0; | 63 | *new_size = 0; |
64 | #ifdef compressBound | 64 | #ifdef compressBound |
65 | dlen = compressBound (old_size); | 65 | dlen = compressBound(old_size); |
66 | #else | 66 | #else |
67 | dlen = old_size + (old_size / 100) + 20; | 67 | dlen = old_size + (old_size / 100) + 20; |
68 | /* documentation says 100.1% oldSize + 12 bytes, but we | 68 | /* documentation says 100.1% oldSize + 12 bytes, but we |
69 | * should be able to overshoot by more to be safe */ | 69 | * should be able to overshoot by more to be safe */ |
70 | #endif | 70 | #endif |
71 | tmp = GNUNET_malloc (dlen); | 71 | tmp = GNUNET_malloc(dlen); |
72 | if (Z_OK == | 72 | if (Z_OK == |
73 | compress2 ((Bytef *) tmp, | 73 | compress2((Bytef *)tmp, |
74 | &dlen, | 74 | &dlen, |
75 | (const Bytef *) data, | 75 | (const Bytef *)data, |
76 | old_size, 9)) | 76 | old_size, 9)) |
77 | { | ||
78 | if (dlen < old_size) | ||
79 | { | 77 | { |
80 | *result = tmp; | 78 | if (dlen < old_size) |
81 | *new_size = dlen; | 79 | { |
82 | return GNUNET_YES; | 80 | *result = tmp; |
81 | *new_size = dlen; | ||
82 | return GNUNET_YES; | ||
83 | } | ||
83 | } | 84 | } |
84 | } | 85 | GNUNET_free(tmp); |
85 | GNUNET_free (tmp); | ||
86 | return GNUNET_NO; | 86 | return GNUNET_NO; |
87 | } | 87 | } |
88 | 88 | ||
@@ -98,22 +98,22 @@ GNUNET_try_compression (const char *data, | |||
98 | * @return NULL on error, buffer of @a output_size decompressed bytes otherwise | 98 | * @return NULL on error, buffer of @a output_size decompressed bytes otherwise |
99 | */ | 99 | */ |
100 | char * | 100 | char * |
101 | GNUNET_decompress (const char *input, | 101 | GNUNET_decompress(const char *input, |
102 | size_t input_size, | 102 | size_t input_size, |
103 | size_t output_size) | 103 | size_t output_size) |
104 | { | 104 | { |
105 | char *output; | 105 | char *output; |
106 | uLongf olen; | 106 | uLongf olen; |
107 | 107 | ||
108 | olen = output_size; | 108 | olen = output_size; |
109 | output = GNUNET_malloc (olen); | 109 | output = GNUNET_malloc(olen); |
110 | if (Z_OK == | 110 | if (Z_OK == |
111 | uncompress ((Bytef *) output, | 111 | uncompress((Bytef *)output, |
112 | &olen, | 112 | &olen, |
113 | (const Bytef *) input, | 113 | (const Bytef *)input, |
114 | input_size)) | 114 | input_size)) |
115 | return output; | 115 | return output; |
116 | GNUNET_free (output); | 116 | GNUNET_free(output); |
117 | return NULL; | 117 | return NULL; |
118 | } | 118 | } |
119 | 119 | ||
@@ -121,8 +121,7 @@ GNUNET_decompress (const char *input, | |||
121 | /** | 121 | /** |
122 | * Meta data item. | 122 | * Meta data item. |
123 | */ | 123 | */ |
124 | struct MetaItem | 124 | struct MetaItem { |
125 | { | ||
126 | /** | 125 | /** |
127 | * This is a doubly linked list. | 126 | * This is a doubly linked list. |
128 | */ | 127 | */ |
@@ -162,14 +161,12 @@ struct MetaItem | |||
162 | * Format of the meta data. | 161 | * Format of the meta data. |
163 | */ | 162 | */ |
164 | enum EXTRACTOR_MetaFormat format; | 163 | enum EXTRACTOR_MetaFormat format; |
165 | |||
166 | }; | 164 | }; |
167 | 165 | ||
168 | /** | 166 | /** |
169 | * Meta data to associate with a file, directory or namespace. | 167 | * Meta data to associate with a file, directory or namespace. |
170 | */ | 168 | */ |
171 | struct GNUNET_CONTAINER_MetaData | 169 | struct GNUNET_CONTAINER_MetaData { |
172 | { | ||
173 | /** | 170 | /** |
174 | * Head of linked list of the meta data items. | 171 | * Head of linked list of the meta data items. |
175 | */ | 172 | */ |
@@ -195,7 +192,6 @@ struct GNUNET_CONTAINER_MetaData | |||
195 | * Number of items in the linked list. | 192 | * Number of items in the linked list. |
196 | */ | 193 | */ |
197 | unsigned int item_count; | 194 | unsigned int item_count; |
198 | |||
199 | }; | 195 | }; |
200 | 196 | ||
201 | 197 | ||
@@ -205,9 +201,9 @@ struct GNUNET_CONTAINER_MetaData | |||
205 | * @return empty meta-data container | 201 | * @return empty meta-data container |
206 | */ | 202 | */ |
207 | struct GNUNET_CONTAINER_MetaData * | 203 | struct GNUNET_CONTAINER_MetaData * |
208 | GNUNET_CONTAINER_meta_data_create () | 204 | GNUNET_CONTAINER_meta_data_create() |
209 | { | 205 | { |
210 | return GNUNET_new (struct GNUNET_CONTAINER_MetaData); | 206 | return GNUNET_new(struct GNUNET_CONTAINER_MetaData); |
211 | } | 207 | } |
212 | 208 | ||
213 | 209 | ||
@@ -217,12 +213,12 @@ GNUNET_CONTAINER_meta_data_create () | |||
217 | * @param mi item to free | 213 | * @param mi item to free |
218 | */ | 214 | */ |
219 | static void | 215 | static void |
220 | meta_item_free (struct MetaItem *mi) | 216 | meta_item_free(struct MetaItem *mi) |
221 | { | 217 | { |
222 | GNUNET_free_non_null (mi->plugin_name); | 218 | GNUNET_free_non_null(mi->plugin_name); |
223 | GNUNET_free_non_null (mi->mime_type); | 219 | GNUNET_free_non_null(mi->mime_type); |
224 | GNUNET_free_non_null (mi->data); | 220 | GNUNET_free_non_null(mi->data); |
225 | GNUNET_free (mi); | 221 | GNUNET_free(mi); |
226 | } | 222 | } |
227 | 223 | ||
228 | 224 | ||
@@ -233,11 +229,11 @@ meta_item_free (struct MetaItem *mi) | |||
233 | * @param md meta data that changed | 229 | * @param md meta data that changed |
234 | */ | 230 | */ |
235 | static void | 231 | static void |
236 | invalidate_sbuf (struct GNUNET_CONTAINER_MetaData *md) | 232 | invalidate_sbuf(struct GNUNET_CONTAINER_MetaData *md) |
237 | { | 233 | { |
238 | if (NULL == md->sbuf) | 234 | if (NULL == md->sbuf) |
239 | return; | 235 | return; |
240 | GNUNET_free (md->sbuf); | 236 | GNUNET_free(md->sbuf); |
241 | md->sbuf = NULL; | 237 | md->sbuf = NULL; |
242 | md->sbuf_size = 0; | 238 | md->sbuf_size = 0; |
243 | } | 239 | } |
@@ -249,19 +245,19 @@ invalidate_sbuf (struct GNUNET_CONTAINER_MetaData *md) | |||
249 | * @param md what to free | 245 | * @param md what to free |
250 | */ | 246 | */ |
251 | void | 247 | void |
252 | GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData *md) | 248 | GNUNET_CONTAINER_meta_data_destroy(struct GNUNET_CONTAINER_MetaData *md) |
253 | { | 249 | { |
254 | struct MetaItem *pos; | 250 | struct MetaItem *pos; |
255 | 251 | ||
256 | if (NULL == md) | 252 | if (NULL == md) |
257 | return; | 253 | return; |
258 | while (NULL != (pos = md->items_head)) | 254 | while (NULL != (pos = md->items_head)) |
259 | { | 255 | { |
260 | GNUNET_CONTAINER_DLL_remove (md->items_head, md->items_tail, pos); | 256 | GNUNET_CONTAINER_DLL_remove(md->items_head, md->items_tail, pos); |
261 | meta_item_free (pos); | 257 | meta_item_free(pos); |
262 | } | 258 | } |
263 | GNUNET_free_non_null (md->sbuf); | 259 | GNUNET_free_non_null(md->sbuf); |
264 | GNUNET_free (md); | 260 | GNUNET_free(md); |
265 | } | 261 | } |
266 | 262 | ||
267 | 263 | ||
@@ -271,19 +267,19 @@ GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData *md) | |||
271 | * @param md metadata to manipulate | 267 | * @param md metadata to manipulate |
272 | */ | 268 | */ |
273 | void | 269 | void |
274 | GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md) | 270 | GNUNET_CONTAINER_meta_data_clear(struct GNUNET_CONTAINER_MetaData *md) |
275 | { | 271 | { |
276 | struct MetaItem *mi; | 272 | struct MetaItem *mi; |
277 | 273 | ||
278 | if (NULL == md) | 274 | if (NULL == md) |
279 | return; | 275 | return; |
280 | while (NULL != (mi = md->items_head)) | 276 | while (NULL != (mi = md->items_head)) |
281 | { | 277 | { |
282 | GNUNET_CONTAINER_DLL_remove (md->items_head, md->items_tail, mi); | 278 | GNUNET_CONTAINER_DLL_remove(md->items_head, md->items_tail, mi); |
283 | meta_item_free (mi); | 279 | meta_item_free(mi); |
284 | } | 280 | } |
285 | GNUNET_free_non_null (md->sbuf); | 281 | GNUNET_free_non_null(md->sbuf); |
286 | memset (md, 0, sizeof (struct GNUNET_CONTAINER_MetaData)); | 282 | memset(md, 0, sizeof(struct GNUNET_CONTAINER_MetaData)); |
287 | } | 283 | } |
288 | 284 | ||
289 | 285 | ||
@@ -298,10 +294,10 @@ GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md) | |||
298 | * @return #GNUNET_YES if they are equal | 294 | * @return #GNUNET_YES if they are equal |
299 | */ | 295 | */ |
300 | int | 296 | int |
301 | GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData | 297 | GNUNET_CONTAINER_meta_data_test_equal(const struct GNUNET_CONTAINER_MetaData |
302 | *md1, | 298 | *md1, |
303 | const struct GNUNET_CONTAINER_MetaData | 299 | const struct GNUNET_CONTAINER_MetaData |
304 | *md2) | 300 | *md2) |
305 | { | 301 | { |
306 | struct MetaItem *i; | 302 | struct MetaItem *i; |
307 | struct MetaItem *j; | 303 | struct MetaItem *j; |
@@ -312,23 +308,23 @@ GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData | |||
312 | if (md1->item_count != md2->item_count) | 308 | if (md1->item_count != md2->item_count) |
313 | return GNUNET_NO; | 309 | return GNUNET_NO; |
314 | for (i = md1->items_head; NULL != i; i = i->next) | 310 | for (i = md1->items_head; NULL != i; i = i->next) |
315 | { | ||
316 | found = GNUNET_NO; | ||
317 | for (j = md2->items_head; NULL != j; j = j->next) | ||
318 | { | 311 | { |
319 | if ((i->type == j->type) && (i->format == j->format) && | 312 | found = GNUNET_NO; |
320 | (i->data_size == j->data_size) && | 313 | for (j = md2->items_head; NULL != j; j = j->next) |
321 | (0 == memcmp (i->data, j->data, i->data_size))) | 314 | { |
322 | { | 315 | if ((i->type == j->type) && (i->format == j->format) && |
323 | found = GNUNET_YES; | 316 | (i->data_size == j->data_size) && |
324 | break; | 317 | (0 == memcmp(i->data, j->data, i->data_size))) |
325 | } | 318 | { |
326 | if (j->data_size < i->data_size) | 319 | found = GNUNET_YES; |
327 | break; /* elements are sorted by (decreasing) size... */ | 320 | break; |
321 | } | ||
322 | if (j->data_size < i->data_size) | ||
323 | break; /* elements are sorted by (decreasing) size... */ | ||
324 | } | ||
325 | if (GNUNET_NO == found) | ||
326 | return GNUNET_NO; | ||
328 | } | 327 | } |
329 | if (GNUNET_NO == found) | ||
330 | return GNUNET_NO; | ||
331 | } | ||
332 | return GNUNET_YES; | 328 | return GNUNET_YES; |
333 | } | 329 | } |
334 | 330 | ||
@@ -352,12 +348,12 @@ GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData | |||
352 | * data_mime_type and plugin_name are not considered for "exists" checks | 348 | * data_mime_type and plugin_name are not considered for "exists" checks |
353 | */ | 349 | */ |
354 | int | 350 | int |
355 | GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md, | 351 | GNUNET_CONTAINER_meta_data_insert(struct GNUNET_CONTAINER_MetaData *md, |
356 | const char *plugin_name, | 352 | const char *plugin_name, |
357 | enum EXTRACTOR_MetaType type, | 353 | enum EXTRACTOR_MetaType type, |
358 | enum EXTRACTOR_MetaFormat format, | 354 | enum EXTRACTOR_MetaFormat format, |
359 | const char *data_mime_type, const char *data, | 355 | const char *data_mime_type, const char *data, |
360 | size_t data_size) | 356 | size_t data_size) |
361 | { | 357 | { |
362 | struct MetaItem *pos; | 358 | struct MetaItem *pos; |
363 | struct MetaItem *mi; | 359 | struct MetaItem *mi; |
@@ -365,61 +361,61 @@ GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md, | |||
365 | 361 | ||
366 | if ((EXTRACTOR_METAFORMAT_UTF8 == format) || | 362 | if ((EXTRACTOR_METAFORMAT_UTF8 == format) || |
367 | (EXTRACTOR_METAFORMAT_C_STRING == format)) | 363 | (EXTRACTOR_METAFORMAT_C_STRING == format)) |
368 | GNUNET_break ('\0' == data[data_size - 1]); | 364 | GNUNET_break('\0' == data[data_size - 1]); |
369 | 365 | ||
370 | for (pos = md->items_head; NULL != pos; pos = pos->next) | 366 | for (pos = md->items_head; NULL != pos; pos = pos->next) |
371 | { | ||
372 | if (pos->data_size < data_size) | ||
373 | break; /* elements are sorted by size in the list */ | ||
374 | if ((pos->type == type) && (pos->data_size == data_size) && | ||
375 | (0 == memcmp (pos->data, data, data_size))) | ||
376 | { | 367 | { |
377 | if ((NULL == pos->mime_type) && (NULL != data_mime_type)) | 368 | if (pos->data_size < data_size) |
378 | { | 369 | break; /* elements are sorted by size in the list */ |
379 | pos->mime_type = GNUNET_strdup (data_mime_type); | 370 | if ((pos->type == type) && (pos->data_size == data_size) && |
380 | invalidate_sbuf (md); | 371 | (0 == memcmp(pos->data, data, data_size))) |
381 | } | 372 | { |
382 | if ((EXTRACTOR_METAFORMAT_C_STRING == pos->format) && | 373 | if ((NULL == pos->mime_type) && (NULL != data_mime_type)) |
383 | (EXTRACTOR_METAFORMAT_UTF8 == format)) | 374 | { |
384 | { | 375 | pos->mime_type = GNUNET_strdup(data_mime_type); |
385 | pos->format = EXTRACTOR_METAFORMAT_UTF8; | 376 | invalidate_sbuf(md); |
386 | invalidate_sbuf (md); | 377 | } |
387 | } | 378 | if ((EXTRACTOR_METAFORMAT_C_STRING == pos->format) && |
388 | return GNUNET_SYSERR; | 379 | (EXTRACTOR_METAFORMAT_UTF8 == format)) |
380 | { | ||
381 | pos->format = EXTRACTOR_METAFORMAT_UTF8; | ||
382 | invalidate_sbuf(md); | ||
383 | } | ||
384 | return GNUNET_SYSERR; | ||
385 | } | ||
389 | } | 386 | } |
390 | } | ||
391 | md->item_count++; | 387 | md->item_count++; |
392 | mi = GNUNET_new (struct MetaItem); | 388 | mi = GNUNET_new(struct MetaItem); |
393 | mi->type = type; | 389 | mi->type = type; |
394 | mi->format = format; | 390 | mi->format = format; |
395 | mi->data_size = data_size; | 391 | mi->data_size = data_size; |
396 | if (NULL == pos) | 392 | if (NULL == pos) |
397 | GNUNET_CONTAINER_DLL_insert_tail (md->items_head, | 393 | GNUNET_CONTAINER_DLL_insert_tail(md->items_head, |
398 | md->items_tail, | 394 | md->items_tail, |
399 | mi); | 395 | mi); |
400 | else | 396 | else |
401 | GNUNET_CONTAINER_DLL_insert_after (md->items_head, | 397 | GNUNET_CONTAINER_DLL_insert_after(md->items_head, |
402 | md->items_tail, | 398 | md->items_tail, |
403 | pos->prev, | 399 | pos->prev, |
404 | mi); | 400 | mi); |
405 | mi->mime_type = | 401 | mi->mime_type = |
406 | (NULL == data_mime_type) ? NULL : GNUNET_strdup (data_mime_type); | 402 | (NULL == data_mime_type) ? NULL : GNUNET_strdup(data_mime_type); |
407 | mi->plugin_name = (NULL == plugin_name) ? NULL : GNUNET_strdup (plugin_name); | 403 | mi->plugin_name = (NULL == plugin_name) ? NULL : GNUNET_strdup(plugin_name); |
408 | mi->data = GNUNET_malloc (data_size); | 404 | mi->data = GNUNET_malloc(data_size); |
409 | GNUNET_memcpy (mi->data, data, data_size); | 405 | GNUNET_memcpy(mi->data, data, data_size); |
410 | /* change all dir separators to POSIX style ('/') */ | 406 | /* change all dir separators to POSIX style ('/') */ |
411 | if ( (EXTRACTOR_METATYPE_FILENAME == type) || | 407 | if ((EXTRACTOR_METATYPE_FILENAME == type) || |
412 | (EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME == type) ) | 408 | (EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME == type)) |
413 | { | ||
414 | p = mi->data; | ||
415 | while (('\0' != *p) && (p < mi->data + data_size)) | ||
416 | { | 409 | { |
417 | if ('\\' == *p) | 410 | p = mi->data; |
418 | *p = '/'; | 411 | while (('\0' != *p) && (p < mi->data + data_size)) |
419 | p++; | 412 | { |
413 | if ('\\' == *p) | ||
414 | *p = '/'; | ||
415 | p++; | ||
416 | } | ||
420 | } | 417 | } |
421 | } | 418 | invalidate_sbuf(md); |
422 | invalidate_sbuf (md); | ||
423 | return GNUNET_OK; | 419 | return GNUNET_OK; |
424 | } | 420 | } |
425 | 421 | ||
@@ -441,14 +437,14 @@ GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md, | |||
441 | * @return 0 (to continue) | 437 | * @return 0 (to continue) |
442 | */ | 438 | */ |
443 | static int | 439 | static int |
444 | merge_helper (void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, | 440 | merge_helper(void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, |
445 | enum EXTRACTOR_MetaFormat format, const char *data_mime_type, | 441 | enum EXTRACTOR_MetaFormat format, const char *data_mime_type, |
446 | const char *data, size_t data_size) | 442 | const char *data, size_t data_size) |
447 | { | 443 | { |
448 | struct GNUNET_CONTAINER_MetaData *md = cls; | 444 | struct GNUNET_CONTAINER_MetaData *md = cls; |
449 | 445 | ||
450 | (void) GNUNET_CONTAINER_meta_data_insert (md, plugin_name, type, format, | 446 | (void)GNUNET_CONTAINER_meta_data_insert(md, plugin_name, type, format, |
451 | data_mime_type, data, data_size); | 447 | data_mime_type, data, data_size); |
452 | return 0; | 448 | return 0; |
453 | } | 449 | } |
454 | 450 | ||
@@ -461,10 +457,10 @@ merge_helper (void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, | |||
461 | * @param in metadata to merge | 457 | * @param in metadata to merge |
462 | */ | 458 | */ |
463 | void | 459 | void |
464 | GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md, | 460 | GNUNET_CONTAINER_meta_data_merge(struct GNUNET_CONTAINER_MetaData *md, |
465 | const struct GNUNET_CONTAINER_MetaData *in) | 461 | const struct GNUNET_CONTAINER_MetaData *in) |
466 | { | 462 | { |
467 | GNUNET_CONTAINER_meta_data_iterate (in, &merge_helper, md); | 463 | GNUNET_CONTAINER_meta_data_iterate(in, &merge_helper, md); |
468 | } | 464 | } |
469 | 465 | ||
470 | 466 | ||
@@ -479,28 +475,28 @@ GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md, | |||
479 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the item does not exist in md | 475 | * @return #GNUNET_OK on success, #GNUNET_SYSERR if the item does not exist in md |
480 | */ | 476 | */ |
481 | int | 477 | int |
482 | GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md, | 478 | GNUNET_CONTAINER_meta_data_delete(struct GNUNET_CONTAINER_MetaData *md, |
483 | enum EXTRACTOR_MetaType type, | 479 | enum EXTRACTOR_MetaType type, |
484 | const char *data, size_t data_size) | 480 | const char *data, size_t data_size) |
485 | { | 481 | { |
486 | struct MetaItem *pos; | 482 | struct MetaItem *pos; |
487 | 483 | ||
488 | for (pos = md->items_head; NULL != pos; pos = pos->next) | 484 | for (pos = md->items_head; NULL != pos; pos = pos->next) |
489 | { | ||
490 | if (pos->data_size < data_size) | ||
491 | break; /* items are sorted by (decreasing) size */ | ||
492 | if ((pos->type == type) && | ||
493 | ((NULL == data) || | ||
494 | ((pos->data_size == data_size) && | ||
495 | (0 == memcmp (pos->data, data, data_size))))) | ||
496 | { | 485 | { |
497 | GNUNET_CONTAINER_DLL_remove (md->items_head, md->items_tail, pos); | 486 | if (pos->data_size < data_size) |
498 | meta_item_free (pos); | 487 | break; /* items are sorted by (decreasing) size */ |
499 | md->item_count--; | 488 | if ((pos->type == type) && |
500 | invalidate_sbuf (md); | 489 | ((NULL == data) || |
501 | return GNUNET_OK; | 490 | ((pos->data_size == data_size) && |
491 | (0 == memcmp(pos->data, data, data_size))))) | ||
492 | { | ||
493 | GNUNET_CONTAINER_DLL_remove(md->items_head, md->items_tail, pos); | ||
494 | meta_item_free(pos); | ||
495 | md->item_count--; | ||
496 | invalidate_sbuf(md); | ||
497 | return GNUNET_OK; | ||
498 | } | ||
502 | } | 499 | } |
503 | } | ||
504 | return GNUNET_SYSERR; | 500 | return GNUNET_SYSERR; |
505 | } | 501 | } |
506 | 502 | ||
@@ -512,21 +508,21 @@ GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md, | |||
512 | * @param md metadata to modify | 508 | * @param md metadata to modify |
513 | */ | 509 | */ |
514 | void | 510 | void |
515 | GNUNET_CONTAINER_meta_data_add_publication_date (struct | 511 | GNUNET_CONTAINER_meta_data_add_publication_date(struct |
516 | GNUNET_CONTAINER_MetaData *md) | 512 | GNUNET_CONTAINER_MetaData *md) |
517 | { | 513 | { |
518 | const char *dat; | 514 | const char *dat; |
519 | struct GNUNET_TIME_Absolute t; | 515 | struct GNUNET_TIME_Absolute t; |
520 | 516 | ||
521 | t = GNUNET_TIME_absolute_get (); | 517 | t = GNUNET_TIME_absolute_get(); |
522 | GNUNET_CONTAINER_meta_data_delete (md, | 518 | GNUNET_CONTAINER_meta_data_delete(md, |
523 | EXTRACTOR_METATYPE_PUBLICATION_DATE, | 519 | EXTRACTOR_METATYPE_PUBLICATION_DATE, |
524 | NULL, 0); | 520 | NULL, 0); |
525 | dat = GNUNET_STRINGS_absolute_time_to_string (t); | 521 | dat = GNUNET_STRINGS_absolute_time_to_string(t); |
526 | GNUNET_CONTAINER_meta_data_insert (md, "<gnunet>", | 522 | GNUNET_CONTAINER_meta_data_insert(md, "<gnunet>", |
527 | EXTRACTOR_METATYPE_PUBLICATION_DATE, | 523 | EXTRACTOR_METATYPE_PUBLICATION_DATE, |
528 | EXTRACTOR_METAFORMAT_UTF8, "text/plain", | 524 | EXTRACTOR_METAFORMAT_UTF8, "text/plain", |
529 | dat, strlen (dat) + 1); | 525 | dat, strlen(dat) + 1); |
530 | } | 526 | } |
531 | 527 | ||
532 | 528 | ||
@@ -539,9 +535,9 @@ GNUNET_CONTAINER_meta_data_add_publication_date (struct | |||
539 | * @return number of entries | 535 | * @return number of entries |
540 | */ | 536 | */ |
541 | int | 537 | int |
542 | GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData *md, | 538 | GNUNET_CONTAINER_meta_data_iterate(const struct GNUNET_CONTAINER_MetaData *md, |
543 | EXTRACTOR_MetaDataProcessor iter, | 539 | EXTRACTOR_MetaDataProcessor iter, |
544 | void *iter_cls) | 540 | void *iter_cls) |
545 | { | 541 | { |
546 | struct MetaItem *pos; | 542 | struct MetaItem *pos; |
547 | 543 | ||
@@ -551,8 +547,8 @@ GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData *md, | |||
551 | return md->item_count; | 547 | return md->item_count; |
552 | for (pos = md->items_head; NULL != pos; pos = pos->next) | 548 | for (pos = md->items_head; NULL != pos; pos = pos->next) |
553 | if (0 != | 549 | if (0 != |
554 | iter (iter_cls, pos->plugin_name, pos->type, pos->format, | 550 | iter(iter_cls, pos->plugin_name, pos->type, pos->format, |
555 | pos->mime_type, pos->data, pos->data_size)) | 551 | pos->mime_type, pos->data, pos->data_size)) |
556 | return md->item_count; | 552 | return md->item_count; |
557 | return md->item_count; | 553 | return md->item_count; |
558 | } | 554 | } |
@@ -569,8 +565,8 @@ GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData *md, | |||
569 | * @return NULL if no entry was found | 565 | * @return NULL if no entry was found |
570 | */ | 566 | */ |
571 | char * | 567 | char * |
572 | GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData *md, | 568 | GNUNET_CONTAINER_meta_data_get_by_type(const struct GNUNET_CONTAINER_MetaData *md, |
573 | enum EXTRACTOR_MetaType type) | 569 | enum EXTRACTOR_MetaType type) |
574 | { | 570 | { |
575 | struct MetaItem *pos; | 571 | struct MetaItem *pos; |
576 | 572 | ||
@@ -580,7 +576,7 @@ GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData * | |||
580 | if ((type == pos->type) && | 576 | if ((type == pos->type) && |
581 | ((pos->format == EXTRACTOR_METAFORMAT_UTF8) || | 577 | ((pos->format == EXTRACTOR_METAFORMAT_UTF8) || |
582 | (pos->format == EXTRACTOR_METAFORMAT_C_STRING))) | 578 | (pos->format == EXTRACTOR_METAFORMAT_C_STRING))) |
583 | return GNUNET_strdup (pos->data); | 579 | return GNUNET_strdup(pos->data); |
584 | return NULL; | 580 | return NULL; |
585 | } | 581 | } |
586 | 582 | ||
@@ -597,9 +593,9 @@ GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData * | |||
597 | * otherwise client is responsible for freeing the value! | 593 | * otherwise client is responsible for freeing the value! |
598 | */ | 594 | */ |
599 | char * | 595 | char * |
600 | GNUNET_CONTAINER_meta_data_get_first_by_types (const struct | 596 | GNUNET_CONTAINER_meta_data_get_first_by_types(const struct |
601 | GNUNET_CONTAINER_MetaData *md, | 597 | GNUNET_CONTAINER_MetaData *md, |
602 | ...) | 598 | ...) |
603 | { | 599 | { |
604 | char *ret; | 600 | char *ret; |
605 | va_list args; | 601 | va_list args; |
@@ -608,16 +604,16 @@ GNUNET_CONTAINER_meta_data_get_first_by_types (const struct | |||
608 | if (NULL == md) | 604 | if (NULL == md) |
609 | return NULL; | 605 | return NULL; |
610 | ret = NULL; | 606 | ret = NULL; |
611 | va_start (args, md); | 607 | va_start(args, md); |
612 | while (1) | 608 | while (1) |
613 | { | 609 | { |
614 | type = va_arg (args, int); | 610 | type = va_arg(args, int); |
615 | if (-1 == type) | 611 | if (-1 == type) |
616 | break; | 612 | break; |
617 | if (NULL != (ret = GNUNET_CONTAINER_meta_data_get_by_type (md, type))) | 613 | if (NULL != (ret = GNUNET_CONTAINER_meta_data_get_by_type(md, type))) |
618 | break; | 614 | break; |
619 | } | 615 | } |
620 | va_end (args); | 616 | va_end(args); |
621 | return ret; | 617 | return ret; |
622 | } | 618 | } |
623 | 619 | ||
@@ -631,8 +627,8 @@ GNUNET_CONTAINER_meta_data_get_first_by_types (const struct | |||
631 | * @return number of bytes in thumbnail, 0 if not available | 627 | * @return number of bytes in thumbnail, 0 if not available |
632 | */ | 628 | */ |
633 | size_t | 629 | size_t |
634 | GNUNET_CONTAINER_meta_data_get_thumbnail (const struct GNUNET_CONTAINER_MetaData | 630 | GNUNET_CONTAINER_meta_data_get_thumbnail(const struct GNUNET_CONTAINER_MetaData |
635 | * md, unsigned char **thumb) | 631 | * md, unsigned char **thumb) |
636 | { | 632 | { |
637 | struct MetaItem *pos; | 633 | struct MetaItem *pos; |
638 | struct MetaItem *match; | 634 | struct MetaItem *match; |
@@ -641,22 +637,22 @@ GNUNET_CONTAINER_meta_data_get_thumbnail (const struct GNUNET_CONTAINER_MetaData | |||
641 | return 0; | 637 | return 0; |
642 | match = NULL; | 638 | match = NULL; |
643 | for (pos = md->items_head; NULL != pos; pos = pos->next) | 639 | for (pos = md->items_head; NULL != pos; pos = pos->next) |
644 | { | ||
645 | if ((NULL != pos->mime_type) && | ||
646 | (0 == strncasecmp ("image/", pos->mime_type, strlen ("image/"))) && | ||
647 | (EXTRACTOR_METAFORMAT_BINARY == pos->format)) | ||
648 | { | 640 | { |
649 | if (NULL == match) | 641 | if ((NULL != pos->mime_type) && |
650 | match = pos; | 642 | (0 == strncasecmp("image/", pos->mime_type, strlen("image/"))) && |
651 | else if ((match->type != EXTRACTOR_METATYPE_THUMBNAIL) && | 643 | (EXTRACTOR_METAFORMAT_BINARY == pos->format)) |
652 | (pos->type == EXTRACTOR_METATYPE_THUMBNAIL)) | 644 | { |
653 | match = pos; | 645 | if (NULL == match) |
646 | match = pos; | ||
647 | else if ((match->type != EXTRACTOR_METATYPE_THUMBNAIL) && | ||
648 | (pos->type == EXTRACTOR_METATYPE_THUMBNAIL)) | ||
649 | match = pos; | ||
650 | } | ||
654 | } | 651 | } |
655 | } | ||
656 | if ((NULL == match) || (0 == match->data_size)) | 652 | if ((NULL == match) || (0 == match->data_size)) |
657 | return 0; | 653 | return 0; |
658 | *thumb = GNUNET_malloc (match->data_size); | 654 | *thumb = GNUNET_malloc(match->data_size); |
659 | GNUNET_memcpy (*thumb, match->data, match->data_size); | 655 | GNUNET_memcpy(*thumb, match->data, match->data_size); |
660 | return match->data_size; | 656 | return match->data_size; |
661 | } | 657 | } |
662 | 658 | ||
@@ -668,19 +664,19 @@ GNUNET_CONTAINER_meta_data_get_thumbnail (const struct GNUNET_CONTAINER_MetaData | |||
668 | * @return duplicate meta-data container | 664 | * @return duplicate meta-data container |
669 | */ | 665 | */ |
670 | struct GNUNET_CONTAINER_MetaData * | 666 | struct GNUNET_CONTAINER_MetaData * |
671 | GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData | 667 | GNUNET_CONTAINER_meta_data_duplicate(const struct GNUNET_CONTAINER_MetaData |
672 | *md) | 668 | *md) |
673 | { | 669 | { |
674 | struct GNUNET_CONTAINER_MetaData *ret; | 670 | struct GNUNET_CONTAINER_MetaData *ret; |
675 | struct MetaItem *pos; | 671 | struct MetaItem *pos; |
676 | 672 | ||
677 | if (NULL == md) | 673 | if (NULL == md) |
678 | return NULL; | 674 | return NULL; |
679 | ret = GNUNET_CONTAINER_meta_data_create (); | 675 | ret = GNUNET_CONTAINER_meta_data_create(); |
680 | for (pos = md->items_tail; NULL != pos; pos = pos->prev) | 676 | for (pos = md->items_tail; NULL != pos; pos = pos->prev) |
681 | GNUNET_CONTAINER_meta_data_insert (ret, pos->plugin_name, pos->type, | 677 | GNUNET_CONTAINER_meta_data_insert(ret, pos->plugin_name, pos->type, |
682 | pos->format, pos->mime_type, pos->data, | 678 | pos->format, pos->mime_type, pos->data, |
683 | pos->data_size); | 679 | pos->data_size); |
684 | return ret; | 680 | return ret; |
685 | } | 681 | } |
686 | 682 | ||
@@ -700,8 +696,7 @@ GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData | |||
700 | /** | 696 | /** |
701 | * Header for serialized meta data. | 697 | * Header for serialized meta data. |
702 | */ | 698 | */ |
703 | struct MetaDataHeader | 699 | struct MetaDataHeader { |
704 | { | ||
705 | /** | 700 | /** |
706 | * The version of the MD serialization. The highest bit is used to | 701 | * The version of the MD serialization. The highest bit is used to |
707 | * indicate compression. | 702 | * indicate compression. |
@@ -734,8 +729,7 @@ struct MetaDataHeader | |||
734 | /** | 729 | /** |
735 | * Entry of serialized meta data. | 730 | * Entry of serialized meta data. |
736 | */ | 731 | */ |
737 | struct MetaDataEntry | 732 | struct MetaDataEntry { |
738 | { | ||
739 | /** | 733 | /** |
740 | * Meta data type. Corresponds to an 'enum EXTRACTOR_MetaType' | 734 | * Meta data type. Corresponds to an 'enum EXTRACTOR_MetaType' |
741 | */ | 735 | */ |
@@ -760,7 +754,6 @@ struct MetaDataEntry | |||
760 | * Number of bytes in the mime type including 0-terminator. 0 for NULL. | 754 | * Number of bytes in the mime type including 0-terminator. 0 for NULL. |
761 | */ | 755 | */ |
762 | uint32_t mime_type_len; | 756 | uint32_t mime_type_len; |
763 | |||
764 | }; | 757 | }; |
765 | 758 | ||
766 | 759 | ||
@@ -779,11 +772,11 @@ struct MetaDataEntry | |||
779 | * space) | 772 | * space) |
780 | */ | 773 | */ |
781 | ssize_t | 774 | ssize_t |
782 | GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData | 775 | GNUNET_CONTAINER_meta_data_serialize(const struct GNUNET_CONTAINER_MetaData |
783 | *md, char **target, size_t max, | 776 | *md, char **target, size_t max, |
784 | enum | 777 | enum |
785 | GNUNET_CONTAINER_MetaDataSerializationOptions | 778 | GNUNET_CONTAINER_MetaDataSerializationOptions |
786 | opt) | 779 | opt) |
787 | { | 780 | { |
788 | struct GNUNET_CONTAINER_MetaData *vmd; | 781 | struct GNUNET_CONTAINER_MetaData *vmd; |
789 | struct MetaItem *pos; | 782 | struct MetaItem *pos; |
@@ -804,195 +797,195 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData | |||
804 | size_t rlen; | 797 | size_t rlen; |
805 | int comp; | 798 | int comp; |
806 | 799 | ||
807 | if (max < sizeof (struct MetaDataHeader)) | 800 | if (max < sizeof(struct MetaDataHeader)) |
808 | return GNUNET_SYSERR; /* far too small */ | 801 | return GNUNET_SYSERR; /* far too small */ |
809 | if (NULL == md) | 802 | if (NULL == md) |
810 | return 0; | 803 | return 0; |
811 | 804 | ||
812 | if (NULL != md->sbuf) | 805 | if (NULL != md->sbuf) |
813 | { | ||
814 | /* try to use serialization cache */ | ||
815 | if (md->sbuf_size <= max) | ||
816 | { | 806 | { |
817 | if (NULL == *target) | 807 | /* try to use serialization cache */ |
818 | *target = GNUNET_malloc (md->sbuf_size); | 808 | if (md->sbuf_size <= max) |
819 | GNUNET_memcpy (*target, md->sbuf, md->sbuf_size); | 809 | { |
820 | return md->sbuf_size; | 810 | if (NULL == *target) |
811 | *target = GNUNET_malloc(md->sbuf_size); | ||
812 | GNUNET_memcpy(*target, md->sbuf, md->sbuf_size); | ||
813 | return md->sbuf_size; | ||
814 | } | ||
815 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART)) | ||
816 | return GNUNET_SYSERR; /* can say that this will fail */ | ||
817 | /* need to compute a partial serialization, sbuf useless ... */ | ||
821 | } | 818 | } |
822 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART)) | ||
823 | return GNUNET_SYSERR; /* can say that this will fail */ | ||
824 | /* need to compute a partial serialization, sbuf useless ... */ | ||
825 | } | ||
826 | dst = NULL; | 819 | dst = NULL; |
827 | msize = 0; | 820 | msize = 0; |
828 | for (pos = md->items_tail; NULL != pos; pos = pos->prev) | 821 | for (pos = md->items_tail; NULL != pos; pos = pos->prev) |
829 | { | 822 | { |
830 | msize += sizeof (struct MetaDataEntry); | 823 | msize += sizeof(struct MetaDataEntry); |
831 | msize += pos->data_size; | 824 | msize += pos->data_size; |
832 | if (NULL != pos->plugin_name) | 825 | if (NULL != pos->plugin_name) |
833 | msize += strlen (pos->plugin_name) + 1; | 826 | msize += strlen(pos->plugin_name) + 1; |
834 | if (NULL != pos->mime_type) | 827 | if (NULL != pos->mime_type) |
835 | msize += strlen (pos->mime_type) + 1; | 828 | msize += strlen(pos->mime_type) + 1; |
836 | } | 829 | } |
837 | size = (size_t) msize; | 830 | size = (size_t)msize; |
838 | if (size != msize) | 831 | if (size != msize) |
839 | { | 832 | { |
840 | GNUNET_break (0); /* integer overflow */ | 833 | GNUNET_break(0); /* integer overflow */ |
841 | return GNUNET_SYSERR; | 834 | return GNUNET_SYSERR; |
842 | } | 835 | } |
843 | if (size >= GNUNET_MAX_MALLOC_CHECKED) | 836 | if (size >= GNUNET_MAX_MALLOC_CHECKED) |
844 | { | 837 | { |
845 | /* too large to be processed */ | 838 | /* too large to be processed */ |
846 | return GNUNET_SYSERR; | 839 | return GNUNET_SYSERR; |
847 | } | 840 | } |
848 | ent = GNUNET_malloc (size); | 841 | ent = GNUNET_malloc(size); |
849 | mdata = (char *) &ent[md->item_count]; | 842 | mdata = (char *)&ent[md->item_count]; |
850 | off = size - (md->item_count * sizeof (struct MetaDataEntry)); | 843 | off = size - (md->item_count * sizeof(struct MetaDataEntry)); |
851 | i = 0; | 844 | i = 0; |
852 | for (pos = md->items_head; NULL != pos; pos = pos->next) | 845 | for (pos = md->items_head; NULL != pos; pos = pos->next) |
853 | { | 846 | { |
854 | ent[i].type = htonl ((uint32_t) pos->type); | 847 | ent[i].type = htonl((uint32_t)pos->type); |
855 | ent[i].format = htonl ((uint32_t) pos->format); | 848 | ent[i].format = htonl((uint32_t)pos->format); |
856 | ent[i].data_size = htonl ((uint32_t) pos->data_size); | 849 | ent[i].data_size = htonl((uint32_t)pos->data_size); |
857 | if (NULL == pos->plugin_name) | 850 | if (NULL == pos->plugin_name) |
858 | plen = 0; | 851 | plen = 0; |
859 | else | 852 | else |
860 | plen = strlen (pos->plugin_name) + 1; | 853 | plen = strlen(pos->plugin_name) + 1; |
861 | ent[i].plugin_name_len = htonl ((uint32_t) plen); | 854 | ent[i].plugin_name_len = htonl((uint32_t)plen); |
862 | if (NULL == pos->mime_type) | 855 | if (NULL == pos->mime_type) |
863 | mlen = 0; | 856 | mlen = 0; |
864 | else | 857 | else |
865 | mlen = strlen (pos->mime_type) + 1; | 858 | mlen = strlen(pos->mime_type) + 1; |
866 | ent[i].mime_type_len = htonl ((uint32_t) mlen); | 859 | ent[i].mime_type_len = htonl((uint32_t)mlen); |
867 | off -= pos->data_size; | 860 | off -= pos->data_size; |
868 | if ((EXTRACTOR_METAFORMAT_UTF8 == pos->format) || | 861 | if ((EXTRACTOR_METAFORMAT_UTF8 == pos->format) || |
869 | (EXTRACTOR_METAFORMAT_C_STRING == pos->format)) | 862 | (EXTRACTOR_METAFORMAT_C_STRING == pos->format)) |
870 | GNUNET_break ('\0' == pos->data[pos->data_size - 1]); | 863 | GNUNET_break('\0' == pos->data[pos->data_size - 1]); |
871 | GNUNET_memcpy (&mdata[off], pos->data, pos->data_size); | 864 | GNUNET_memcpy(&mdata[off], pos->data, pos->data_size); |
872 | off -= plen; | 865 | off -= plen; |
873 | if (NULL != pos->plugin_name) | 866 | if (NULL != pos->plugin_name) |
874 | GNUNET_memcpy (&mdata[off], pos->plugin_name, plen); | 867 | GNUNET_memcpy(&mdata[off], pos->plugin_name, plen); |
875 | off -= mlen; | 868 | off -= mlen; |
876 | if (NULL != pos->mime_type) | 869 | if (NULL != pos->mime_type) |
877 | GNUNET_memcpy (&mdata[off], pos->mime_type, mlen); | 870 | GNUNET_memcpy(&mdata[off], pos->mime_type, mlen); |
878 | i++; | 871 | i++; |
879 | } | 872 | } |
880 | GNUNET_assert (0 == off); | 873 | GNUNET_assert(0 == off); |
881 | 874 | ||
882 | clen = 0; | 875 | clen = 0; |
883 | cdata = NULL; | 876 | cdata = NULL; |
884 | left = size; | 877 | left = size; |
885 | i = 0; | 878 | i = 0; |
886 | for (pos = md->items_head; NULL != pos; pos = pos->next) | 879 | for (pos = md->items_head; NULL != pos; pos = pos->next) |
887 | { | ||
888 | comp = GNUNET_NO; | ||
889 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS)) | ||
890 | comp = GNUNET_try_compression ((const char *) &ent[i], | ||
891 | left, | ||
892 | &cdata, | ||
893 | &clen); | ||
894 | |||
895 | if ((NULL == md->sbuf) && (0 == i)) | ||
896 | { | 880 | { |
897 | /* fill 'sbuf'; this "modifies" md, but since this is only | 881 | comp = GNUNET_NO; |
898 | * an internal cache we will cast away the 'const' instead | 882 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS)) |
899 | * of making the API look strange. */ | 883 | comp = GNUNET_try_compression((const char *)&ent[i], |
900 | vmd = (struct GNUNET_CONTAINER_MetaData *) md; | 884 | left, |
901 | hdr = GNUNET_malloc (left + sizeof (struct MetaDataHeader)); | 885 | &cdata, |
902 | hdr->size = htonl (left); | 886 | &clen); |
903 | hdr->entries = htonl (md->item_count); | 887 | |
904 | if (GNUNET_YES == comp) | 888 | if ((NULL == md->sbuf) && (0 == i)) |
905 | { | 889 | { |
906 | GNUNET_assert (clen < left); | 890 | /* fill 'sbuf'; this "modifies" md, but since this is only |
907 | hdr->version = htonl (2 | HEADER_COMPRESSED); | 891 | * an internal cache we will cast away the 'const' instead |
908 | GNUNET_memcpy (&hdr[1], cdata, clen); | 892 | * of making the API look strange. */ |
909 | vmd->sbuf_size = clen + sizeof (struct MetaDataHeader); | 893 | vmd = (struct GNUNET_CONTAINER_MetaData *)md; |
910 | } | 894 | hdr = GNUNET_malloc(left + sizeof(struct MetaDataHeader)); |
911 | else | 895 | hdr->size = htonl(left); |
912 | { | 896 | hdr->entries = htonl(md->item_count); |
913 | hdr->version = htonl (2); | 897 | if (GNUNET_YES == comp) |
914 | GNUNET_memcpy (&hdr[1], &ent[0], left); | 898 | { |
915 | vmd->sbuf_size = left + sizeof (struct MetaDataHeader); | 899 | GNUNET_assert(clen < left); |
916 | } | 900 | hdr->version = htonl(2 | HEADER_COMPRESSED); |
917 | vmd->sbuf = (char *) hdr; | 901 | GNUNET_memcpy(&hdr[1], cdata, clen); |
902 | vmd->sbuf_size = clen + sizeof(struct MetaDataHeader); | ||
903 | } | ||
904 | else | ||
905 | { | ||
906 | hdr->version = htonl(2); | ||
907 | GNUNET_memcpy(&hdr[1], &ent[0], left); | ||
908 | vmd->sbuf_size = left + sizeof(struct MetaDataHeader); | ||
909 | } | ||
910 | vmd->sbuf = (char *)hdr; | ||
911 | } | ||
912 | |||
913 | if (((left + sizeof(struct MetaDataHeader)) <= max) || | ||
914 | ((GNUNET_YES == comp) && (clen <= max))) | ||
915 | { | ||
916 | /* success, this now fits! */ | ||
917 | if (GNUNET_YES == comp) | ||
918 | { | ||
919 | if (NULL == dst) | ||
920 | dst = GNUNET_malloc(clen + sizeof(struct MetaDataHeader)); | ||
921 | hdr = (struct MetaDataHeader *)dst; | ||
922 | hdr->version = htonl(2 | HEADER_COMPRESSED); | ||
923 | hdr->size = htonl(left); | ||
924 | hdr->entries = htonl(md->item_count - i); | ||
925 | GNUNET_memcpy(&dst[sizeof(struct MetaDataHeader)], cdata, clen); | ||
926 | GNUNET_free(cdata); | ||
927 | cdata = NULL; | ||
928 | GNUNET_free(ent); | ||
929 | rlen = clen + sizeof(struct MetaDataHeader); | ||
930 | } | ||
931 | else | ||
932 | { | ||
933 | if (NULL == dst) | ||
934 | dst = GNUNET_malloc(left + sizeof(struct MetaDataHeader)); | ||
935 | hdr = (struct MetaDataHeader *)dst; | ||
936 | hdr->version = htonl(2); | ||
937 | hdr->entries = htonl(md->item_count - i); | ||
938 | hdr->size = htonl(left); | ||
939 | GNUNET_memcpy(&dst[sizeof(struct MetaDataHeader)], &ent[i], left); | ||
940 | GNUNET_free(ent); | ||
941 | rlen = left + sizeof(struct MetaDataHeader); | ||
942 | } | ||
943 | if (NULL != *target) | ||
944 | { | ||
945 | if (GNUNET_YES == comp) | ||
946 | GNUNET_memcpy(*target, dst, clen + sizeof(struct MetaDataHeader)); | ||
947 | else | ||
948 | GNUNET_memcpy(*target, dst, left + sizeof(struct MetaDataHeader)); | ||
949 | GNUNET_free(dst); | ||
950 | } | ||
951 | else | ||
952 | { | ||
953 | *target = dst; | ||
954 | } | ||
955 | return rlen; | ||
956 | } | ||
957 | |||
958 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART)) | ||
959 | { | ||
960 | /* does not fit! */ | ||
961 | GNUNET_free(ent); | ||
962 | return GNUNET_SYSERR; | ||
963 | } | ||
964 | |||
965 | /* next iteration: ignore the corresponding meta data at the | ||
966 | * end and try again without it */ | ||
967 | left -= sizeof(struct MetaDataEntry); | ||
968 | left -= pos->data_size; | ||
969 | if (NULL != pos->plugin_name) | ||
970 | left -= strlen(pos->plugin_name) + 1; | ||
971 | if (NULL != pos->mime_type) | ||
972 | left -= strlen(pos->mime_type) + 1; | ||
973 | |||
974 | GNUNET_free_non_null(cdata); | ||
975 | cdata = NULL; | ||
976 | |||
977 | i++; | ||
918 | } | 978 | } |
919 | 979 | GNUNET_free(ent); | |
920 | if (((left + sizeof (struct MetaDataHeader)) <= max) || | ||
921 | ((GNUNET_YES == comp) && (clen <= max))) | ||
922 | { | ||
923 | /* success, this now fits! */ | ||
924 | if (GNUNET_YES == comp) | ||
925 | { | ||
926 | if (NULL == dst) | ||
927 | dst = GNUNET_malloc (clen + sizeof (struct MetaDataHeader)); | ||
928 | hdr = (struct MetaDataHeader *) dst; | ||
929 | hdr->version = htonl (2 | HEADER_COMPRESSED); | ||
930 | hdr->size = htonl (left); | ||
931 | hdr->entries = htonl (md->item_count - i); | ||
932 | GNUNET_memcpy (&dst[sizeof (struct MetaDataHeader)], cdata, clen); | ||
933 | GNUNET_free (cdata); | ||
934 | cdata = NULL; | ||
935 | GNUNET_free (ent); | ||
936 | rlen = clen + sizeof (struct MetaDataHeader); | ||
937 | } | ||
938 | else | ||
939 | { | ||
940 | if (NULL == dst) | ||
941 | dst = GNUNET_malloc (left + sizeof (struct MetaDataHeader)); | ||
942 | hdr = (struct MetaDataHeader *) dst; | ||
943 | hdr->version = htonl (2); | ||
944 | hdr->entries = htonl (md->item_count - i); | ||
945 | hdr->size = htonl (left); | ||
946 | GNUNET_memcpy (&dst[sizeof (struct MetaDataHeader)], &ent[i], left); | ||
947 | GNUNET_free (ent); | ||
948 | rlen = left + sizeof (struct MetaDataHeader); | ||
949 | } | ||
950 | if (NULL != *target) | ||
951 | { | ||
952 | if (GNUNET_YES == comp) | ||
953 | GNUNET_memcpy (*target, dst, clen + sizeof (struct MetaDataHeader)); | ||
954 | else | ||
955 | GNUNET_memcpy (*target, dst, left + sizeof (struct MetaDataHeader)); | ||
956 | GNUNET_free (dst); | ||
957 | } | ||
958 | else | ||
959 | { | ||
960 | *target = dst; | ||
961 | } | ||
962 | return rlen; | ||
963 | } | ||
964 | |||
965 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART)) | ||
966 | { | ||
967 | /* does not fit! */ | ||
968 | GNUNET_free (ent); | ||
969 | return GNUNET_SYSERR; | ||
970 | } | ||
971 | |||
972 | /* next iteration: ignore the corresponding meta data at the | ||
973 | * end and try again without it */ | ||
974 | left -= sizeof (struct MetaDataEntry); | ||
975 | left -= pos->data_size; | ||
976 | if (NULL != pos->plugin_name) | ||
977 | left -= strlen (pos->plugin_name) + 1; | ||
978 | if (NULL != pos->mime_type) | ||
979 | left -= strlen (pos->mime_type) + 1; | ||
980 | |||
981 | GNUNET_free_non_null (cdata); | ||
982 | cdata = NULL; | ||
983 | |||
984 | i++; | ||
985 | } | ||
986 | GNUNET_free (ent); | ||
987 | 980 | ||
988 | /* nothing fit, only write header! */ | 981 | /* nothing fit, only write header! */ |
989 | ihdr.version = htonl (2); | 982 | ihdr.version = htonl(2); |
990 | ihdr.entries = htonl (0); | 983 | ihdr.entries = htonl(0); |
991 | ihdr.size = htonl (0); | 984 | ihdr.size = htonl(0); |
992 | if (NULL == *target) | 985 | if (NULL == *target) |
993 | *target = (char *) GNUNET_new (struct MetaDataHeader); | 986 | *target = (char *)GNUNET_new(struct MetaDataHeader); |
994 | GNUNET_memcpy (*target, &ihdr, sizeof (struct MetaDataHeader)); | 987 | GNUNET_memcpy(*target, &ihdr, sizeof(struct MetaDataHeader)); |
995 | return sizeof (struct MetaDataHeader); | 988 | return sizeof(struct MetaDataHeader); |
996 | } | 989 | } |
997 | 990 | ||
998 | 991 | ||
@@ -1003,8 +996,8 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData | |||
1003 | * @return number of bytes needed for serialization, -1 on error | 996 | * @return number of bytes needed for serialization, -1 on error |
1004 | */ | 997 | */ |
1005 | ssize_t | 998 | ssize_t |
1006 | GNUNET_CONTAINER_meta_data_get_serialized_size (const struct | 999 | GNUNET_CONTAINER_meta_data_get_serialized_size(const struct |
1007 | GNUNET_CONTAINER_MetaData *md) | 1000 | GNUNET_CONTAINER_MetaData *md) |
1008 | { | 1001 | { |
1009 | ssize_t ret; | 1002 | ssize_t ret; |
1010 | char *ptr; | 1003 | char *ptr; |
@@ -1013,10 +1006,10 @@ GNUNET_CONTAINER_meta_data_get_serialized_size (const struct | |||
1013 | return md->sbuf_size; | 1006 | return md->sbuf_size; |
1014 | ptr = NULL; | 1007 | ptr = NULL; |
1015 | ret = | 1008 | ret = |
1016 | GNUNET_CONTAINER_meta_data_serialize (md, &ptr, GNUNET_MAX_MALLOC_CHECKED, | 1009 | GNUNET_CONTAINER_meta_data_serialize(md, &ptr, GNUNET_MAX_MALLOC_CHECKED, |
1017 | GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL); | 1010 | GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL); |
1018 | if (-1 != ret) | 1011 | if (-1 != ret) |
1019 | GNUNET_free (ptr); | 1012 | GNUNET_free(ptr); |
1020 | return ret; | 1013 | return ret; |
1021 | } | 1014 | } |
1022 | 1015 | ||
@@ -1030,7 +1023,7 @@ GNUNET_CONTAINER_meta_data_get_serialized_size (const struct | |||
1030 | * bad format) | 1023 | * bad format) |
1031 | */ | 1024 | */ |
1032 | struct GNUNET_CONTAINER_MetaData * | 1025 | struct GNUNET_CONTAINER_MetaData * |
1033 | GNUNET_CONTAINER_meta_data_deserialize (const char *input, size_t size) | 1026 | GNUNET_CONTAINER_meta_data_deserialize(const char *input, size_t size) |
1034 | { | 1027 | { |
1035 | struct GNUNET_CONTAINER_MetaData *md; | 1028 | struct GNUNET_CONTAINER_MetaData *md; |
1036 | struct MetaDataHeader hdr; | 1029 | struct MetaDataHeader hdr; |
@@ -1052,137 +1045,137 @@ GNUNET_CONTAINER_meta_data_deserialize (const char *input, size_t size) | |||
1052 | const char *mime_type; | 1045 | const char *mime_type; |
1053 | enum EXTRACTOR_MetaFormat format; | 1046 | enum EXTRACTOR_MetaFormat format; |
1054 | 1047 | ||
1055 | if (size < sizeof (struct MetaDataHeader)) | 1048 | if (size < sizeof(struct MetaDataHeader)) |
1056 | return NULL; | 1049 | return NULL; |
1057 | GNUNET_memcpy (&hdr, input, sizeof (struct MetaDataHeader)); | 1050 | GNUNET_memcpy(&hdr, input, sizeof(struct MetaDataHeader)); |
1058 | version = ntohl (hdr.version) & HEADER_VERSION_MASK; | 1051 | version = ntohl(hdr.version) & HEADER_VERSION_MASK; |
1059 | compressed = (ntohl (hdr.version) & HEADER_COMPRESSED) != 0; | 1052 | compressed = (ntohl(hdr.version) & HEADER_COMPRESSED) != 0; |
1060 | 1053 | ||
1061 | if (1 == version) | 1054 | if (1 == version) |
1062 | return NULL; /* null pointer */ | 1055 | return NULL; /* null pointer */ |
1063 | if (2 != version) | 1056 | if (2 != version) |
1064 | { | ||
1065 | GNUNET_break_op (0); /* unsupported version */ | ||
1066 | return NULL; | ||
1067 | } | ||
1068 | |||
1069 | ic = ntohl (hdr.entries); | ||
1070 | dataSize = ntohl (hdr.size); | ||
1071 | if ( ((sizeof (struct MetaDataEntry) * ic) > dataSize) || | ||
1072 | ( (0 != ic) && | ||
1073 | (dataSize / ic < sizeof (struct MetaDataEntry)) ) ) | ||
1074 | { | ||
1075 | GNUNET_break_op (0); | ||
1076 | return NULL; | ||
1077 | } | ||
1078 | |||
1079 | if (compressed) | ||
1080 | { | ||
1081 | if (dataSize >= GNUNET_MAX_MALLOC_CHECKED) | ||
1082 | { | 1057 | { |
1083 | /* make sure we don't blow our memory limit because of a mal-formed | 1058 | GNUNET_break_op(0); /* unsupported version */ |
1084 | * message... */ | ||
1085 | GNUNET_break_op (0); | ||
1086 | return NULL; | 1059 | return NULL; |
1087 | } | 1060 | } |
1088 | data = | 1061 | |
1089 | GNUNET_decompress ((const char *) &input[sizeof (struct MetaDataHeader)], | 1062 | ic = ntohl(hdr.entries); |
1090 | size - sizeof (struct MetaDataHeader), | 1063 | dataSize = ntohl(hdr.size); |
1091 | dataSize); | 1064 | if (((sizeof(struct MetaDataEntry) * ic) > dataSize) || |
1092 | if (NULL == data) | 1065 | ((0 != ic) && |
1093 | { | 1066 | (dataSize / ic < sizeof(struct MetaDataEntry)))) |
1094 | GNUNET_break_op (0); | ||
1095 | return NULL; | ||
1096 | } | ||
1097 | cdata = data; | ||
1098 | } | ||
1099 | else | ||
1100 | { | ||
1101 | data = NULL; | ||
1102 | cdata = (const char *) &input[sizeof (struct MetaDataHeader)]; | ||
1103 | if (dataSize != size - sizeof (struct MetaDataHeader)) | ||
1104 | { | 1067 | { |
1105 | GNUNET_break_op (0); | 1068 | GNUNET_break_op(0); |
1106 | return NULL; | 1069 | return NULL; |
1107 | } | 1070 | } |
1108 | } | ||
1109 | 1071 | ||
1110 | md = GNUNET_CONTAINER_meta_data_create (); | 1072 | if (compressed) |
1111 | left = dataSize - ic * sizeof (struct MetaDataEntry); | ||
1112 | mdata = &cdata[ic * sizeof (struct MetaDataEntry)]; | ||
1113 | for (i = 0; i < ic; i++) | ||
1114 | { | ||
1115 | GNUNET_memcpy (&ent, &cdata[i * sizeof (struct MetaDataEntry)], | ||
1116 | sizeof (struct MetaDataEntry)); | ||
1117 | format = (enum EXTRACTOR_MetaFormat) ntohl (ent.format); | ||
1118 | if ((EXTRACTOR_METAFORMAT_UTF8 != format) && | ||
1119 | (EXTRACTOR_METAFORMAT_C_STRING != format) && | ||
1120 | (EXTRACTOR_METAFORMAT_BINARY != format)) | ||
1121 | { | ||
1122 | GNUNET_break_op (0); | ||
1123 | break; | ||
1124 | } | ||
1125 | dlen = ntohl (ent.data_size); | ||
1126 | plen = ntohl (ent.plugin_name_len); | ||
1127 | mlen = ntohl (ent.mime_type_len); | ||
1128 | if (dlen > left) | ||
1129 | { | ||
1130 | GNUNET_break_op (0); | ||
1131 | break; | ||
1132 | } | ||
1133 | left -= dlen; | ||
1134 | meta_data = &mdata[left]; | ||
1135 | if ((EXTRACTOR_METAFORMAT_UTF8 == format) || | ||
1136 | (EXTRACTOR_METAFORMAT_C_STRING == format)) | ||
1137 | { | ||
1138 | if (0 == dlen) | ||
1139 | { | ||
1140 | GNUNET_break_op (0); | ||
1141 | break; | ||
1142 | } | ||
1143 | if ('\0' != meta_data[dlen - 1]) | ||
1144 | { | ||
1145 | GNUNET_break_op (0); | ||
1146 | break; | ||
1147 | } | ||
1148 | } | ||
1149 | if (plen > left) | ||
1150 | { | 1073 | { |
1151 | GNUNET_break_op (0); | 1074 | if (dataSize >= GNUNET_MAX_MALLOC_CHECKED) |
1152 | break; | 1075 | { |
1076 | /* make sure we don't blow our memory limit because of a mal-formed | ||
1077 | * message... */ | ||
1078 | GNUNET_break_op(0); | ||
1079 | return NULL; | ||
1080 | } | ||
1081 | data = | ||
1082 | GNUNET_decompress((const char *)&input[sizeof(struct MetaDataHeader)], | ||
1083 | size - sizeof(struct MetaDataHeader), | ||
1084 | dataSize); | ||
1085 | if (NULL == data) | ||
1086 | { | ||
1087 | GNUNET_break_op(0); | ||
1088 | return NULL; | ||
1089 | } | ||
1090 | cdata = data; | ||
1153 | } | 1091 | } |
1154 | left -= plen; | 1092 | else |
1155 | if ((plen > 0) && ('\0' != mdata[left + plen - 1])) | ||
1156 | { | 1093 | { |
1157 | GNUNET_break_op (0); | 1094 | data = NULL; |
1158 | break; | 1095 | cdata = (const char *)&input[sizeof(struct MetaDataHeader)]; |
1096 | if (dataSize != size - sizeof(struct MetaDataHeader)) | ||
1097 | { | ||
1098 | GNUNET_break_op(0); | ||
1099 | return NULL; | ||
1100 | } | ||
1159 | } | 1101 | } |
1160 | if (0 == plen) | ||
1161 | plugin_name = NULL; | ||
1162 | else | ||
1163 | plugin_name = &mdata[left]; | ||
1164 | 1102 | ||
1165 | if (mlen > left) | 1103 | md = GNUNET_CONTAINER_meta_data_create(); |
1166 | { | 1104 | left = dataSize - ic * sizeof(struct MetaDataEntry); |
1167 | GNUNET_break_op (0); | 1105 | mdata = &cdata[ic * sizeof(struct MetaDataEntry)]; |
1168 | break; | 1106 | for (i = 0; i < ic; i++) |
1169 | } | ||
1170 | left -= mlen; | ||
1171 | if ((mlen > 0) && ('\0' != mdata[left + mlen - 1])) | ||
1172 | { | 1107 | { |
1173 | GNUNET_break_op (0); | 1108 | GNUNET_memcpy(&ent, &cdata[i * sizeof(struct MetaDataEntry)], |
1174 | break; | 1109 | sizeof(struct MetaDataEntry)); |
1110 | format = (enum EXTRACTOR_MetaFormat)ntohl(ent.format); | ||
1111 | if ((EXTRACTOR_METAFORMAT_UTF8 != format) && | ||
1112 | (EXTRACTOR_METAFORMAT_C_STRING != format) && | ||
1113 | (EXTRACTOR_METAFORMAT_BINARY != format)) | ||
1114 | { | ||
1115 | GNUNET_break_op(0); | ||
1116 | break; | ||
1117 | } | ||
1118 | dlen = ntohl(ent.data_size); | ||
1119 | plen = ntohl(ent.plugin_name_len); | ||
1120 | mlen = ntohl(ent.mime_type_len); | ||
1121 | if (dlen > left) | ||
1122 | { | ||
1123 | GNUNET_break_op(0); | ||
1124 | break; | ||
1125 | } | ||
1126 | left -= dlen; | ||
1127 | meta_data = &mdata[left]; | ||
1128 | if ((EXTRACTOR_METAFORMAT_UTF8 == format) || | ||
1129 | (EXTRACTOR_METAFORMAT_C_STRING == format)) | ||
1130 | { | ||
1131 | if (0 == dlen) | ||
1132 | { | ||
1133 | GNUNET_break_op(0); | ||
1134 | break; | ||
1135 | } | ||
1136 | if ('\0' != meta_data[dlen - 1]) | ||
1137 | { | ||
1138 | GNUNET_break_op(0); | ||
1139 | break; | ||
1140 | } | ||
1141 | } | ||
1142 | if (plen > left) | ||
1143 | { | ||
1144 | GNUNET_break_op(0); | ||
1145 | break; | ||
1146 | } | ||
1147 | left -= plen; | ||
1148 | if ((plen > 0) && ('\0' != mdata[left + plen - 1])) | ||
1149 | { | ||
1150 | GNUNET_break_op(0); | ||
1151 | break; | ||
1152 | } | ||
1153 | if (0 == plen) | ||
1154 | plugin_name = NULL; | ||
1155 | else | ||
1156 | plugin_name = &mdata[left]; | ||
1157 | |||
1158 | if (mlen > left) | ||
1159 | { | ||
1160 | GNUNET_break_op(0); | ||
1161 | break; | ||
1162 | } | ||
1163 | left -= mlen; | ||
1164 | if ((mlen > 0) && ('\0' != mdata[left + mlen - 1])) | ||
1165 | { | ||
1166 | GNUNET_break_op(0); | ||
1167 | break; | ||
1168 | } | ||
1169 | if (0 == mlen) | ||
1170 | mime_type = NULL; | ||
1171 | else | ||
1172 | mime_type = &mdata[left]; | ||
1173 | GNUNET_CONTAINER_meta_data_insert(md, plugin_name, | ||
1174 | (enum EXTRACTOR_MetaType) | ||
1175 | ntohl(ent.type), format, mime_type, | ||
1176 | meta_data, dlen); | ||
1175 | } | 1177 | } |
1176 | if (0 == mlen) | 1178 | GNUNET_free_non_null(data); |
1177 | mime_type = NULL; | ||
1178 | else | ||
1179 | mime_type = &mdata[left]; | ||
1180 | GNUNET_CONTAINER_meta_data_insert (md, plugin_name, | ||
1181 | (enum EXTRACTOR_MetaType) | ||
1182 | ntohl (ent.type), format, mime_type, | ||
1183 | meta_data, dlen); | ||
1184 | } | ||
1185 | GNUNET_free_non_null (data); | ||
1186 | return md; | 1179 | return md; |
1187 | } | 1180 | } |
1188 | 1181 | ||