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