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.c792
1 files changed, 395 insertions, 397 deletions
diff --git a/src/util/container_meta_data.c b/src/util/container_meta_data.c
index 1ea77f63a..c2ec01c04 100644
--- a/src/util/container_meta_data.c
+++ b/src/util/container_meta_data.c
@@ -162,10 +162,10 @@ GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData *md)
162 if (md == NULL) 162 if (md == NULL)
163 return; 163 return;
164 while (NULL != (item = md->items)) 164 while (NULL != (item = md->items))
165 { 165 {
166 md->items = item->next; 166 md->items = item->next;
167 meta_item_free (item); 167 meta_item_free (item);
168 } 168 }
169 GNUNET_free_non_null (md->sbuf); 169 GNUNET_free_non_null (md->sbuf);
170 GNUNET_free (md); 170 GNUNET_free (md);
171} 171}
@@ -184,10 +184,10 @@ GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md)
184 if (md == NULL) 184 if (md == NULL)
185 return; 185 return;
186 while (NULL != (item = md->items)) 186 while (NULL != (item = md->items))
187 { 187 {
188 md->items = item->next; 188 md->items = item->next;
189 meta_item_free (item); 189 meta_item_free (item);
190 } 190 }
191 GNUNET_free_non_null (md->sbuf); 191 GNUNET_free_non_null (md->sbuf);
192 memset (md, 0, sizeof (struct GNUNET_CONTAINER_MetaData)); 192 memset (md, 0, sizeof (struct GNUNET_CONTAINER_MetaData));
193} 193}
@@ -206,9 +206,9 @@ GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md)
206 */ 206 */
207int 207int
208GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData 208GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData
209 *md1, 209 *md1,
210 const struct GNUNET_CONTAINER_MetaData 210 const struct GNUNET_CONTAINER_MetaData
211 *md2) 211 *md2)
212{ 212{
213 struct MetaItem *i; 213 struct MetaItem *i;
214 struct MetaItem *j; 214 struct MetaItem *j;
@@ -221,24 +221,24 @@ GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData
221 221
222 i = md1->items; 222 i = md1->items;
223 while (NULL != i) 223 while (NULL != i)
224 {
225 found = GNUNET_NO;
226 j = md2->items;
227 while (NULL != j)
224 { 228 {
225 found = GNUNET_NO; 229 if ((i->type == j->type) && (i->format == j->format) &&
226 j = md2->items; 230 (i->data_size == j->data_size) &&
227 while (NULL != j) 231 (0 == memcmp (i->data, j->data, i->data_size)))
228 { 232 {
229 if ((i->type == j->type) && (i->format == j->format) && 233 found = GNUNET_YES;
230 (i->data_size == j->data_size) && 234 break;
231 (0 == memcmp (i->data, j->data, i->data_size))) 235 }
232 { 236 j = j->next;
233 found = GNUNET_YES;
234 break;
235 }
236 j = j->next;
237 }
238 if (found == GNUNET_NO)
239 return GNUNET_NO;
240 i = i->next;
241 } 237 }
238 if (found == GNUNET_NO)
239 return GNUNET_NO;
240 i = i->next;
241 }
242 return GNUNET_YES; 242 return GNUNET_YES;
243} 243}
244 244
@@ -263,11 +263,11 @@ GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData
263 */ 263 */
264int 264int
265GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md, 265GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md,
266 const char *plugin_name, 266 const char *plugin_name,
267 enum EXTRACTOR_MetaType type, 267 enum EXTRACTOR_MetaType type,
268 enum EXTRACTOR_MetaFormat format, 268 enum EXTRACTOR_MetaFormat format,
269 const char *data_mime_type, 269 const char *data_mime_type, const char *data,
270 const char *data, size_t data_len) 270 size_t data_len)
271{ 271{
272 struct MetaItem *prev; 272 struct MetaItem *prev;
273 struct MetaItem *pos; 273 struct MetaItem *pos;
@@ -277,28 +277,28 @@ GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md,
277 prev = NULL; 277 prev = NULL;
278 pos = md->items; 278 pos = md->items;
279 while (NULL != pos) 279 while (NULL != pos)
280 {
281 if (pos->data_size < data_len)
282 break;
283 if ((pos->type == type) && (pos->data_size == data_len) &&
284 (0 == memcmp (pos->data, data, data_len)))
280 { 285 {
281 if (pos->data_size < data_len) 286 if ((pos->mime_type == NULL) && (data_mime_type != NULL))
282 break; 287 {
283 if ((pos->type == type) && (pos->data_size == data_len) && 288 pos->mime_type = GNUNET_strdup (data_mime_type);
284 (0 == memcmp (pos->data, data, data_len))) 289 invalidate_sbuf (md);
285 { 290 }
286 if ((pos->mime_type == NULL) && (data_mime_type != NULL)) 291 if ((pos->format == EXTRACTOR_METAFORMAT_C_STRING) &&
287 { 292 (format == EXTRACTOR_METAFORMAT_UTF8))
288 pos->mime_type = GNUNET_strdup (data_mime_type); 293 {
289 invalidate_sbuf (md); 294 pos->format = EXTRACTOR_METAFORMAT_UTF8;
290 } 295 invalidate_sbuf (md);
291 if ((pos->format == EXTRACTOR_METAFORMAT_C_STRING) && 296 }
292 (format == EXTRACTOR_METAFORMAT_UTF8)) 297 return GNUNET_SYSERR;
293 {
294 pos->format = EXTRACTOR_METAFORMAT_UTF8;
295 invalidate_sbuf (md);
296 }
297 return GNUNET_SYSERR;
298 }
299 prev = pos;
300 pos = pos->next;
301 } 298 }
299 prev = pos;
300 pos = pos->next;
301 }
302 md->item_count++; 302 md->item_count++;
303 i = GNUNET_malloc (sizeof (struct MetaItem)); 303 i = GNUNET_malloc (sizeof (struct MetaItem));
304 i->type = type; 304 i->type = type;
@@ -310,23 +310,23 @@ GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md,
310 else 310 else
311 prev->next = i; 311 prev->next = i;
312 i->mime_type = 312 i->mime_type =
313 (data_mime_type == NULL) ? NULL : GNUNET_strdup (data_mime_type); 313 (data_mime_type == NULL) ? NULL : GNUNET_strdup (data_mime_type);
314 i->plugin_name = (plugin_name == NULL) ? NULL : GNUNET_strdup (plugin_name); 314 i->plugin_name = (plugin_name == NULL) ? NULL : GNUNET_strdup (plugin_name);
315 i->data = GNUNET_malloc (data_len); 315 i->data = GNUNET_malloc (data_len);
316 memcpy (i->data, data, data_len); 316 memcpy (i->data, data, data_len);
317 /* change OS native dir separators to unix '/' and others to '_' */ 317 /* change OS native dir separators to unix '/' and others to '_' */
318 if (type == EXTRACTOR_METATYPE_FILENAME) 318 if (type == EXTRACTOR_METATYPE_FILENAME)
319 {
320 p = i->data;
321 while ((*p != '\0') && (p < i->data + data_len))
319 { 322 {
320 p = i->data; 323 if (*p == DIR_SEPARATOR)
321 while ((*p != '\0') && (p < i->data + data_len)) 324 *p = '/';
322 { 325 else if (*p == '\\')
323 if (*p == DIR_SEPARATOR) 326 *p = '_';
324 *p = '/'; 327 p++;
325 else if (*p == '\\')
326 *p = '_';
327 p++;
328 }
329 } 328 }
329 }
330 invalidate_sbuf (md); 330 invalidate_sbuf (md);
331 return GNUNET_OK; 331 return GNUNET_OK;
332} 332}
@@ -349,14 +349,14 @@ GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md,
349 * @return 0 (to continue) 349 * @return 0 (to continue)
350 */ 350 */
351static int 351static int
352merge_helper (void *cls, const char *plugin_name, 352merge_helper (void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type,
353 enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, 353 enum EXTRACTOR_MetaFormat format, const char *data_mime_type,
354 const char *data_mime_type, const char *data, size_t data_len) 354 const char *data, size_t data_len)
355{ 355{
356 struct GNUNET_CONTAINER_MetaData *md = cls; 356 struct GNUNET_CONTAINER_MetaData *md = cls;
357 357
358 (void) GNUNET_CONTAINER_meta_data_insert (md, plugin_name, type, format, 358 (void) GNUNET_CONTAINER_meta_data_insert (md, plugin_name, type, format,
359 data_mime_type, data, data_len); 359 data_mime_type, data, data_len);
360 return 0; 360 return 0;
361} 361}
362 362
@@ -370,7 +370,7 @@ merge_helper (void *cls, const char *plugin_name,
370 */ 370 */
371void 371void
372GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md, 372GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md,
373 const struct GNUNET_CONTAINER_MetaData *in) 373 const struct GNUNET_CONTAINER_MetaData *in)
374{ 374{
375 GNUNET_CONTAINER_meta_data_iterate (in, &merge_helper, md); 375 GNUNET_CONTAINER_meta_data_iterate (in, &merge_helper, md);
376} 376}
@@ -388,8 +388,8 @@ GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md,
388 */ 388 */
389int 389int
390GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md, 390GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md,
391 enum EXTRACTOR_MetaType type, 391 enum EXTRACTOR_MetaType type,
392 const char *data, size_t data_len) 392 const char *data, size_t data_len)
393{ 393{
394 struct MetaItem *pos; 394 struct MetaItem *pos;
395 struct MetaItem *prev; 395 struct MetaItem *prev;
@@ -397,24 +397,24 @@ GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md,
397 prev = NULL; 397 prev = NULL;
398 pos = md->items; 398 pos = md->items;
399 while (NULL != pos) 399 while (NULL != pos)
400 {
401 if ((pos->type == type) &&
402 ((data == NULL) ||
403 ((pos->data_size == data_len) &&
404 (0 == memcmp (pos->data, data, data_len)))))
400 { 405 {
401 if ((pos->type == type) && 406 if (prev == NULL)
402 ((data == NULL) || 407 md->items = pos->next;
403 ((pos->data_size == data_len) && 408 else
404 (0 == memcmp (pos->data, data, data_len))))) 409 prev->next = pos->next;
405 { 410 meta_item_free (pos);
406 if (prev == NULL) 411 md->item_count--;
407 md->items = pos->next; 412 invalidate_sbuf (md);
408 else 413 return GNUNET_OK;
409 prev->next = pos->next;
410 meta_item_free (pos);
411 md->item_count--;
412 invalidate_sbuf (md);
413 return GNUNET_OK;
414 }
415 prev = pos;
416 pos = pos->next;
417 } 414 }
415 prev = pos;
416 pos = pos->next;
417 }
418 return GNUNET_SYSERR; 418 return GNUNET_SYSERR;
419} 419}
420 420
@@ -427,20 +427,19 @@ GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md,
427 */ 427 */
428void 428void
429GNUNET_CONTAINER_meta_data_add_publication_date (struct 429GNUNET_CONTAINER_meta_data_add_publication_date (struct
430 GNUNET_CONTAINER_MetaData 430 GNUNET_CONTAINER_MetaData *md)
431 *md)
432{ 431{
433 char *dat; 432 char *dat;
434 struct GNUNET_TIME_Absolute t; 433 struct GNUNET_TIME_Absolute t;
435 434
436 t = GNUNET_TIME_absolute_get (); 435 t = GNUNET_TIME_absolute_get ();
437 GNUNET_CONTAINER_meta_data_delete (md, EXTRACTOR_METATYPE_PUBLICATION_DATE, 436 GNUNET_CONTAINER_meta_data_delete (md, EXTRACTOR_METATYPE_PUBLICATION_DATE,
438 NULL, 0); 437 NULL, 0);
439 dat = GNUNET_STRINGS_absolute_time_to_string (t); 438 dat = GNUNET_STRINGS_absolute_time_to_string (t);
440 GNUNET_CONTAINER_meta_data_insert (md, "<gnunet>", 439 GNUNET_CONTAINER_meta_data_insert (md, "<gnunet>",
441 EXTRACTOR_METATYPE_PUBLICATION_DATE, 440 EXTRACTOR_METATYPE_PUBLICATION_DATE,
442 EXTRACTOR_METAFORMAT_UTF8, "text/plain", 441 EXTRACTOR_METAFORMAT_UTF8, "text/plain",
443 dat, strlen (dat) + 1); 442 dat, strlen (dat) + 1);
444 GNUNET_free (dat); 443 GNUNET_free (dat);
445} 444}
446 445
@@ -454,9 +453,9 @@ GNUNET_CONTAINER_meta_data_add_publication_date (struct
454 * @return number of entries 453 * @return number of entries
455 */ 454 */
456int 455int
457GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData 456GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData *md,
458 *md, EXTRACTOR_MetaDataProcessor iter, 457 EXTRACTOR_MetaDataProcessor iter,
459 void *iter_cls) 458 void *iter_cls)
460{ 459{
461 struct MetaItem *pos; 460 struct MetaItem *pos;
462 461
@@ -466,13 +465,13 @@ GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData
466 return md->item_count; 465 return md->item_count;
467 pos = md->items; 466 pos = md->items;
468 while (NULL != pos) 467 while (NULL != pos)
469 { 468 {
470 if (0 != 469 if (0 !=
471 iter (iter_cls, pos->plugin_name, pos->type, pos->format, 470 iter (iter_cls, pos->plugin_name, pos->type, pos->format,
472 pos->mime_type, pos->data, pos->data_size)) 471 pos->mime_type, pos->data, pos->data_size))
473 return md->item_count; 472 return md->item_count;
474 pos = pos->next; 473 pos = pos->next;
475 } 474 }
476 return md->item_count; 475 return md->item_count;
477} 476}
478 477
@@ -489,7 +488,7 @@ GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData
489 */ 488 */
490char * 489char *
491GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData 490GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData
492 *md, enum EXTRACTOR_MetaType type) 491 *md, enum EXTRACTOR_MetaType type)
493{ 492{
494 struct MetaItem *pos; 493 struct MetaItem *pos;
495 494
@@ -497,13 +496,13 @@ GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData
497 return NULL; 496 return NULL;
498 pos = md->items; 497 pos = md->items;
499 while (NULL != pos) 498 while (NULL != pos)
500 { 499 {
501 if ((type == pos->type) && 500 if ((type == pos->type) &&
502 ((pos->format == EXTRACTOR_METAFORMAT_UTF8) || 501 ((pos->format == EXTRACTOR_METAFORMAT_UTF8) ||
503 (pos->format == EXTRACTOR_METAFORMAT_C_STRING))) 502 (pos->format == EXTRACTOR_METAFORMAT_C_STRING)))
504 return GNUNET_strdup (pos->data); 503 return GNUNET_strdup (pos->data);
505 pos = pos->next; 504 pos = pos->next;
506 } 505 }
507 return NULL; 506 return NULL;
508} 507}
509 508
@@ -521,8 +520,8 @@ GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData
521 */ 520 */
522char * 521char *
523GNUNET_CONTAINER_meta_data_get_first_by_types (const struct 522GNUNET_CONTAINER_meta_data_get_first_by_types (const struct
524 GNUNET_CONTAINER_MetaData *md, 523 GNUNET_CONTAINER_MetaData *md,
525 ...) 524 ...)
526{ 525{
527 char *ret; 526 char *ret;
528 va_list args; 527 va_list args;
@@ -533,15 +532,15 @@ GNUNET_CONTAINER_meta_data_get_first_by_types (const struct
533 ret = NULL; 532 ret = NULL;
534 va_start (args, md); 533 va_start (args, md);
535 while (1) 534 while (1)
536 { 535 {
537 type = va_arg (args, enum EXTRACTOR_MetaType); 536 type = va_arg (args, enum EXTRACTOR_MetaType);
538 537
539 if (type == -1) 538 if (type == -1)
540 break; 539 break;
541 ret = GNUNET_CONTAINER_meta_data_get_by_type (md, type); 540 ret = GNUNET_CONTAINER_meta_data_get_by_type (md, type);
542 if (ret != NULL) 541 if (ret != NULL)
543 break; 542 break;
544 } 543 }
545 va_end (args); 544 va_end (args);
546 return ret; 545 return ret;
547} 546}
@@ -556,9 +555,8 @@ GNUNET_CONTAINER_meta_data_get_first_by_types (const struct
556 * @return number of bytes in thumbnail, 0 if not available 555 * @return number of bytes in thumbnail, 0 if not available
557 */ 556 */
558size_t 557size_t
559GNUNET_CONTAINER_meta_data_get_thumbnail (const struct 558GNUNET_CONTAINER_meta_data_get_thumbnail (const struct GNUNET_CONTAINER_MetaData
560 GNUNET_CONTAINER_MetaData * md, 559 * md, unsigned char **thumb)
561 unsigned char **thumb)
562{ 560{
563 struct MetaItem *pos; 561 struct MetaItem *pos;
564 struct MetaItem *match; 562 struct MetaItem *match;
@@ -568,19 +566,19 @@ GNUNET_CONTAINER_meta_data_get_thumbnail (const struct
568 match = NULL; 566 match = NULL;
569 pos = md->items; 567 pos = md->items;
570 while (NULL != pos) 568 while (NULL != pos)
569 {
570 if ((NULL != pos->mime_type) &&
571 (0 == strncasecmp ("image/", pos->mime_type, strlen ("image/"))) &&
572 (pos->format == EXTRACTOR_METAFORMAT_BINARY))
571 { 573 {
572 if ((NULL != pos->mime_type) && 574 if (match == NULL)
573 (0 == strncasecmp ("image/", pos->mime_type, strlen ("image/"))) && 575 match = pos;
574 (pos->format == EXTRACTOR_METAFORMAT_BINARY)) 576 else if ((match->type != EXTRACTOR_METATYPE_THUMBNAIL) &&
575 { 577 (pos->type == EXTRACTOR_METATYPE_THUMBNAIL))
576 if (match == NULL) 578 match = pos;
577 match = pos;
578 else if ((match->type != EXTRACTOR_METATYPE_THUMBNAIL) &&
579 (pos->type == EXTRACTOR_METATYPE_THUMBNAIL))
580 match = pos;
581 }
582 pos = pos->next;
583 } 579 }
580 pos = pos->next;
581 }
584 if ((match == NULL) || (match->data_size == 0)) 582 if ((match == NULL) || (match->data_size == 0))
585 return 0; 583 return 0;
586 *thumb = GNUNET_malloc (match->data_size); 584 *thumb = GNUNET_malloc (match->data_size);
@@ -597,7 +595,7 @@ GNUNET_CONTAINER_meta_data_get_thumbnail (const struct
597 */ 595 */
598struct GNUNET_CONTAINER_MetaData * 596struct GNUNET_CONTAINER_MetaData *
599GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData 597GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData
600 *md) 598 *md)
601{ 599{
602 struct GNUNET_CONTAINER_MetaData *ret; 600 struct GNUNET_CONTAINER_MetaData *ret;
603 struct MetaItem *pos; 601 struct MetaItem *pos;
@@ -607,12 +605,12 @@ GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData
607 ret = GNUNET_CONTAINER_meta_data_create (); 605 ret = GNUNET_CONTAINER_meta_data_create ();
608 pos = md->items; 606 pos = md->items;
609 while (NULL != pos) 607 while (NULL != pos)
610 { 608 {
611 GNUNET_CONTAINER_meta_data_insert (ret, pos->plugin_name, pos->type, 609 GNUNET_CONTAINER_meta_data_insert (ret, pos->plugin_name, pos->type,
612 pos->format, pos->mime_type, 610 pos->format, pos->mime_type, pos->data,
613 pos->data, pos->data_size); 611 pos->data_size);
614 pos = pos->next; 612 pos = pos->next;
615 } 613 }
616 return ret; 614 return ret;
617} 615}
618 616
@@ -633,7 +631,7 @@ GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData
633 */ 631 */
634static int 632static int
635try_compression (const char *data, size_t oldSize, char **result, 633try_compression (const char *data, size_t oldSize, char **result,
636 size_t * newSize) 634 size_t * newSize)
637{ 635{
638 char *tmp; 636 char *tmp;
639 uLongf dlen; 637 uLongf dlen;
@@ -648,14 +646,14 @@ try_compression (const char *data, size_t oldSize, char **result,
648 tmp = GNUNET_malloc (dlen); 646 tmp = GNUNET_malloc (dlen);
649 if (Z_OK == 647 if (Z_OK ==
650 compress2 ((Bytef *) tmp, &dlen, (const Bytef *) data, oldSize, 9)) 648 compress2 ((Bytef *) tmp, &dlen, (const Bytef *) data, oldSize, 9))
649 {
650 if (dlen < oldSize)
651 { 651 {
652 if (dlen < oldSize) 652 *result = tmp;
653 { 653 *newSize = dlen;
654 *result = tmp; 654 return GNUNET_YES;
655 *newSize = dlen;
656 return GNUNET_YES;
657 }
658 } 655 }
656 }
659 GNUNET_free (tmp); 657 GNUNET_free (tmp);
660 return GNUNET_NO; 658 return GNUNET_NO;
661} 659}
@@ -756,10 +754,10 @@ struct MetaDataEntry
756 */ 754 */
757ssize_t 755ssize_t
758GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData 756GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData
759 *md, char **target, size_t max, 757 *md, char **target, size_t max,
760 enum 758 enum
761 GNUNET_CONTAINER_MetaDataSerializationOptions 759 GNUNET_CONTAINER_MetaDataSerializationOptions
762 opt) 760 opt)
763{ 761{
764 struct GNUNET_CONTAINER_MetaData *vmd; 762 struct GNUNET_CONTAINER_MetaData *vmd;
765 struct MetaItem *pos; 763 struct MetaItem *pos;
@@ -781,79 +779,79 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData
781 int comp; 779 int comp;
782 780
783 if (max < sizeof (struct MetaDataHeader)) 781 if (max < sizeof (struct MetaDataHeader))
784 return GNUNET_SYSERR; /* far too small */ 782 return GNUNET_SYSERR; /* far too small */
785 if (md == NULL) 783 if (md == NULL)
786 return 0; 784 return 0;
787 785
788 if (md->sbuf != NULL) 786 if (md->sbuf != NULL)
787 {
788 /* try to use serialization cache */
789 if (md->sbuf_size <= max)
789 { 790 {
790 /* try to use serialization cache */ 791 if (NULL == *target)
791 if (md->sbuf_size <= max) 792 *target = GNUNET_malloc (md->sbuf_size);
792 { 793 memcpy (*target, md->sbuf, md->sbuf_size);
793 if (NULL == *target) 794 return md->sbuf_size;
794 *target = GNUNET_malloc (md->sbuf_size);
795 memcpy (*target, md->sbuf, md->sbuf_size);
796 return md->sbuf_size;
797 }
798 if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART))
799 return GNUNET_SYSERR; /* can say that this will fail */
800 /* need to compute a partial serialization, sbuf useless ... */
801 } 795 }
796 if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART))
797 return GNUNET_SYSERR; /* can say that this will fail */
798 /* need to compute a partial serialization, sbuf useless ... */
799 }
802 dst = NULL; 800 dst = NULL;
803 msize = 0; 801 msize = 0;
804 pos = md->items; 802 pos = md->items;
805 while (NULL != pos) 803 while (NULL != pos)
806 { 804 {
807 msize += sizeof (struct MetaDataEntry); 805 msize += sizeof (struct MetaDataEntry);
808 msize += pos->data_size; 806 msize += pos->data_size;
809 if (pos->plugin_name != NULL) 807 if (pos->plugin_name != NULL)
810 msize += strlen (pos->plugin_name) + 1; 808 msize += strlen (pos->plugin_name) + 1;
811 if (pos->mime_type != NULL) 809 if (pos->mime_type != NULL)
812 msize += strlen (pos->mime_type) + 1; 810 msize += strlen (pos->mime_type) + 1;
813 pos = pos->next; 811 pos = pos->next;
814 } 812 }
815 size = (size_t) msize; 813 size = (size_t) msize;
816 if (size != msize) 814 if (size != msize)
817 { 815 {
818 GNUNET_break (0); /* integer overflow */ 816 GNUNET_break (0); /* integer overflow */
819 return GNUNET_SYSERR; 817 return GNUNET_SYSERR;
820 } 818 }
821 if (size >= GNUNET_MAX_MALLOC_CHECKED) 819 if (size >= GNUNET_MAX_MALLOC_CHECKED)
822 { 820 {
823 /* too large to be processed */ 821 /* too large to be processed */
824 return GNUNET_SYSERR; 822 return GNUNET_SYSERR;
825 } 823 }
826 ent = GNUNET_malloc (size); 824 ent = GNUNET_malloc (size);
827 mdata = (char *) &ent[md->item_count]; 825 mdata = (char *) &ent[md->item_count];
828 off = size - (md->item_count * sizeof (struct MetaDataEntry)); 826 off = size - (md->item_count * sizeof (struct MetaDataEntry));
829 i = 0; 827 i = 0;
830 pos = md->items; 828 pos = md->items;
831 while (NULL != pos) 829 while (NULL != pos)
832 { 830 {
833 ent[i].type = htonl ((uint32_t) pos->type); 831 ent[i].type = htonl ((uint32_t) pos->type);
834 ent[i].format = htonl ((uint32_t) pos->format); 832 ent[i].format = htonl ((uint32_t) pos->format);
835 ent[i].data_size = htonl ((uint32_t) pos->data_size); 833 ent[i].data_size = htonl ((uint32_t) pos->data_size);
836 if (pos->plugin_name == NULL) 834 if (pos->plugin_name == NULL)
837 plen = 0; 835 plen = 0;
838 else 836 else
839 plen = strlen (pos->plugin_name) + 1; 837 plen = strlen (pos->plugin_name) + 1;
840 ent[i].plugin_name_len = htonl ((uint32_t) plen); 838 ent[i].plugin_name_len = htonl ((uint32_t) plen);
841 if (pos->mime_type == NULL) 839 if (pos->mime_type == NULL)
842 mlen = 0; 840 mlen = 0;
843 else 841 else
844 mlen = strlen (pos->mime_type) + 1; 842 mlen = strlen (pos->mime_type) + 1;
845 ent[i].mime_type_len = htonl ((uint32_t) mlen); 843 ent[i].mime_type_len = htonl ((uint32_t) mlen);
846 off -= pos->data_size; 844 off -= pos->data_size;
847 memcpy (&mdata[off], pos->data, pos->data_size); 845 memcpy (&mdata[off], pos->data, pos->data_size);
848 off -= plen; 846 off -= plen;
849 if (pos->plugin_name != NULL) 847 if (pos->plugin_name != NULL)
850 memcpy (&mdata[off], pos->plugin_name, plen); 848 memcpy (&mdata[off], pos->plugin_name, plen);
851 off -= mlen; 849 off -= mlen;
852 if (pos->mime_type != NULL) 850 if (pos->mime_type != NULL)
853 memcpy (&mdata[off], pos->mime_type, mlen); 851 memcpy (&mdata[off], pos->mime_type, mlen);
854 i++; 852 i++;
855 pos = pos->next; 853 pos = pos->next;
856 } 854 }
857 GNUNET_assert (off == 0); 855 GNUNET_assert (off == 0);
858 856
859 clen = 0; 857 clen = 0;
@@ -862,95 +860,95 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData
862 i = 0; 860 i = 0;
863 pos = md->items; 861 pos = md->items;
864 while (pos != NULL) 862 while (pos != NULL)
863 {
864 comp = GNUNET_NO;
865 if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS))
866 comp = try_compression ((const char *) &ent[i], left, &cdata, &clen);
867
868 if ((md->sbuf == NULL) && (i == 0))
869 {
870 /* fill 'sbuf'; this "modifies" md, but since this is only
871 * an internal cache we will cast away the 'const' instead
872 * of making the API look strange. */
873 vmd = (struct GNUNET_CONTAINER_MetaData *) md;
874 hdr = GNUNET_malloc (left + sizeof (struct MetaDataHeader));
875 hdr->size = htonl (left);
876 hdr->entries = htonl (md->item_count);
877 if (GNUNET_YES == comp)
878 {
879 GNUNET_assert (clen < left);
880 hdr->version = htonl (2 | HEADER_COMPRESSED);
881 memcpy (&hdr[1], cdata, clen);
882 vmd->sbuf_size = clen + sizeof (struct MetaDataHeader);
883 }
884 else
885 {
886 hdr->version = htonl (2);
887 memcpy (&hdr[1], &ent[0], left);
888 vmd->sbuf_size = left + sizeof (struct MetaDataHeader);
889 }
890 vmd->sbuf = (char *) hdr;
891 }
892
893 if (((left + sizeof (struct MetaDataHeader)) <= max) ||
894 ((comp == GNUNET_YES) && (clen <= max)))
895 {
896 /* success, this now fits! */
897 if (GNUNET_YES == comp)
898 {
899 if (dst == NULL)
900 dst = GNUNET_malloc (clen + sizeof (struct MetaDataHeader));
901 hdr = (struct MetaDataHeader *) dst;
902 hdr->version = htonl (2 | HEADER_COMPRESSED);
903 hdr->size = htonl (left);
904 hdr->entries = htonl (md->item_count - i);
905 memcpy (&dst[sizeof (struct MetaDataHeader)], cdata, clen);
906 GNUNET_free (cdata);
907 GNUNET_free (ent);
908 rlen = clen + sizeof (struct MetaDataHeader);
909 }
910 else
911 {
912 if (dst == NULL)
913 dst = GNUNET_malloc (left + sizeof (struct MetaDataHeader));
914 hdr = (struct MetaDataHeader *) dst;
915 hdr->version = htonl (2);
916 hdr->entries = htonl (md->item_count - i);
917 hdr->size = htonl (left);
918 memcpy (&dst[sizeof (struct MetaDataHeader)], &ent[i], left);
919 GNUNET_free (ent);
920 rlen = left + sizeof (struct MetaDataHeader);
921 }
922 if (NULL != *target)
923 {
924 memcpy (*target, dst, clen + sizeof (struct MetaDataHeader));
925 GNUNET_free (dst);
926 }
927 else
928 {
929 *target = dst;
930 }
931 return rlen;
932 }
933
934 if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART))
865 { 935 {
866 comp = GNUNET_NO; 936 /* does not fit! */
867 if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS)) 937 GNUNET_free (ent);
868 comp = try_compression ((const char *) &ent[i], left, &cdata, &clen); 938 return GNUNET_SYSERR;
869
870 if ((md->sbuf == NULL) && (i == 0))
871 {
872 /* fill 'sbuf'; this "modifies" md, but since this is only
873 * an internal cache we will cast away the 'const' instead
874 * of making the API look strange. */
875 vmd = (struct GNUNET_CONTAINER_MetaData *) md;
876 hdr = GNUNET_malloc (left + sizeof (struct MetaDataHeader));
877 hdr->size = htonl (left);
878 hdr->entries = htonl (md->item_count);
879 if (GNUNET_YES == comp)
880 {
881 GNUNET_assert (clen < left);
882 hdr->version = htonl (2 | HEADER_COMPRESSED);
883 memcpy (&hdr[1], cdata, clen);
884 vmd->sbuf_size = clen + sizeof (struct MetaDataHeader);
885 }
886 else
887 {
888 hdr->version = htonl (2);
889 memcpy (&hdr[1], &ent[0], left);
890 vmd->sbuf_size = left + sizeof (struct MetaDataHeader);
891 }
892 vmd->sbuf = (char *) hdr;
893 }
894
895 if (((left + sizeof (struct MetaDataHeader)) <= max) ||
896 ((comp == GNUNET_YES) && (clen <= max)))
897 {
898 /* success, this now fits! */
899 if (GNUNET_YES == comp)
900 {
901 if (dst == NULL)
902 dst = GNUNET_malloc (clen + sizeof (struct MetaDataHeader));
903 hdr = (struct MetaDataHeader *) dst;
904 hdr->version = htonl (2 | HEADER_COMPRESSED);
905 hdr->size = htonl (left);
906 hdr->entries = htonl (md->item_count - i);
907 memcpy (&dst[sizeof (struct MetaDataHeader)], cdata, clen);
908 GNUNET_free (cdata);
909 GNUNET_free (ent);
910 rlen = clen + sizeof (struct MetaDataHeader);
911 }
912 else
913 {
914 if (dst == NULL)
915 dst = GNUNET_malloc (left + sizeof (struct MetaDataHeader));
916 hdr = (struct MetaDataHeader *) dst;
917 hdr->version = htonl (2);
918 hdr->entries = htonl (md->item_count - i);
919 hdr->size = htonl (left);
920 memcpy (&dst[sizeof (struct MetaDataHeader)], &ent[i], left);
921 GNUNET_free (ent);
922 rlen = left + sizeof (struct MetaDataHeader);
923 }
924 if (NULL != *target)
925 {
926 memcpy (*target, dst, clen + sizeof (struct MetaDataHeader));
927 GNUNET_free (dst);
928 }
929 else
930 {
931 *target = dst;
932 }
933 return rlen;
934 }
935
936 if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART))
937 {
938 /* does not fit! */
939 GNUNET_free (ent);
940 return GNUNET_SYSERR;
941 }
942
943 /* next iteration: ignore the corresponding meta data at the
944 * end and try again without it */
945 left -= sizeof (struct MetaDataEntry);
946 left -= pos->data_size;
947 if (pos->plugin_name != NULL)
948 left -= strlen (pos->plugin_name) + 1;
949 if (pos->mime_type != NULL)
950 left -= strlen (pos->mime_type) + 1;
951 pos = pos->next;
952 i++;
953 } 939 }
940
941 /* next iteration: ignore the corresponding meta data at the
942 * end and try again without it */
943 left -= sizeof (struct MetaDataEntry);
944 left -= pos->data_size;
945 if (pos->plugin_name != NULL)
946 left -= strlen (pos->plugin_name) + 1;
947 if (pos->mime_type != NULL)
948 left -= strlen (pos->mime_type) + 1;
949 pos = pos->next;
950 i++;
951 }
954 GNUNET_free (ent); 952 GNUNET_free (ent);
955 953
956 /* nothing fit, only write header! */ 954 /* nothing fit, only write header! */
@@ -972,7 +970,7 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData
972 */ 970 */
973ssize_t 971ssize_t
974GNUNET_CONTAINER_meta_data_get_serialized_size (const struct 972GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
975 GNUNET_CONTAINER_MetaData *md) 973 GNUNET_CONTAINER_MetaData *md)
976{ 974{
977 ssize_t ret; 975 ssize_t ret;
978 char *ptr; 976 char *ptr;
@@ -981,8 +979,8 @@ GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
981 return md->sbuf_size; 979 return md->sbuf_size;
982 ptr = NULL; 980 ptr = NULL;
983 ret = 981 ret =
984 GNUNET_CONTAINER_meta_data_serialize (md, &ptr, GNUNET_MAX_MALLOC_CHECKED, 982 GNUNET_CONTAINER_meta_data_serialize (md, &ptr, GNUNET_MAX_MALLOC_CHECKED,
985 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL); 983 GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);
986 if (ret != -1) 984 if (ret != -1)
987 GNUNET_free (ptr); 985 GNUNET_free (ptr);
988 return ret; 986 return ret;
@@ -1009,14 +1007,14 @@ decompress (const char *input, size_t inputSize, size_t outputSize)
1009 output = GNUNET_malloc (olen); 1007 output = GNUNET_malloc (olen);
1010 if (Z_OK == 1008 if (Z_OK ==
1011 uncompress ((Bytef *) output, &olen, (const Bytef *) input, inputSize)) 1009 uncompress ((Bytef *) output, &olen, (const Bytef *) input, inputSize))
1012 { 1010 {
1013 return output; 1011 return output;
1014 } 1012 }
1015 else 1013 else
1016 { 1014 {
1017 GNUNET_free (output); 1015 GNUNET_free (output);
1018 return NULL; 1016 return NULL;
1019 } 1017 }
1020} 1018}
1021 1019
1022 1020
@@ -1058,121 +1056,121 @@ GNUNET_CONTAINER_meta_data_deserialize (const char *input, size_t size)
1058 compressed = (ntohl (hdr.version) & HEADER_COMPRESSED) != 0; 1056 compressed = (ntohl (hdr.version) & HEADER_COMPRESSED) != 0;
1059 1057
1060 if (version == 1) 1058 if (version == 1)
1061 return NULL; /* null pointer */ 1059 return NULL; /* null pointer */
1062 if (version != 2) 1060 if (version != 2)
1063 { 1061 {
1064 GNUNET_break_op (0); /* unsupported version */ 1062 GNUNET_break_op (0); /* unsupported version */
1065 return NULL; 1063 return NULL;
1066 } 1064 }
1067 1065
1068 ic = ntohl (hdr.entries); 1066 ic = ntohl (hdr.entries);
1069 dataSize = ntohl (hdr.size); 1067 dataSize = ntohl (hdr.size);
1070 if ((sizeof (struct MetaDataEntry) * ic) > dataSize) 1068 if ((sizeof (struct MetaDataEntry) * ic) > dataSize)
1069 {
1070 GNUNET_break_op (0);
1071 return NULL;
1072 }
1073
1074 if (compressed)
1075 {
1076 if (dataSize >= GNUNET_MAX_MALLOC_CHECKED)
1071 { 1077 {
1078 /* make sure we don't blow our memory limit because of a mal-formed
1079 * message... */
1072 GNUNET_break_op (0); 1080 GNUNET_break_op (0);
1073 return NULL; 1081 return NULL;
1074 } 1082 }
1075 1083 data =
1076 if (compressed) 1084 decompress ((const char *) &input[sizeof (struct MetaDataHeader)],
1085 size - sizeof (struct MetaDataHeader), dataSize);
1086 if (data == NULL)
1077 { 1087 {
1078 if (dataSize >= GNUNET_MAX_MALLOC_CHECKED) 1088 GNUNET_break_op (0);
1079 { 1089 return NULL;
1080 /* make sure we don't blow our memory limit because of a mal-formed
1081 * message... */
1082 GNUNET_break_op (0);
1083 return NULL;
1084 }
1085 data =
1086 decompress ((const char *) &input[sizeof (struct MetaDataHeader)],
1087 size - sizeof (struct MetaDataHeader), dataSize);
1088 if (data == NULL)
1089 {
1090 GNUNET_break_op (0);
1091 return NULL;
1092 }
1093 cdata = data;
1094 } 1090 }
1091 cdata = data;
1092 }
1095 else 1093 else
1094 {
1095 data = NULL;
1096 cdata = (const char *) &input[sizeof (struct MetaDataHeader)];
1097 if (dataSize != size - sizeof (struct MetaDataHeader))
1096 { 1098 {
1097 data = NULL; 1099 GNUNET_break_op (0);
1098 cdata = (const char *) &input[sizeof (struct MetaDataHeader)]; 1100 return NULL;
1099 if (dataSize != size - sizeof (struct MetaDataHeader))
1100 {
1101 GNUNET_break_op (0);
1102 return NULL;
1103 }
1104 } 1101 }
1102 }
1105 1103
1106 md = GNUNET_CONTAINER_meta_data_create (); 1104 md = GNUNET_CONTAINER_meta_data_create ();
1107 left = dataSize - ic * sizeof (struct MetaDataEntry); 1105 left = dataSize - ic * sizeof (struct MetaDataEntry);
1108 mdata = &cdata[ic * sizeof (struct MetaDataEntry)]; 1106 mdata = &cdata[ic * sizeof (struct MetaDataEntry)];
1109 for (i = 0; i < ic; i++) 1107 for (i = 0; i < ic; i++)
1108 {
1109 memcpy (&ent, &cdata[i * sizeof (struct MetaDataEntry)],
1110 sizeof (struct MetaDataEntry));
1111 format = (enum EXTRACTOR_MetaFormat) ntohl (ent.format);
1112 if ((format != EXTRACTOR_METAFORMAT_UTF8) &&
1113 (format != EXTRACTOR_METAFORMAT_C_STRING) &&
1114 (format != EXTRACTOR_METAFORMAT_BINARY))
1110 { 1115 {
1111 memcpy (&ent, &cdata[i * sizeof (struct MetaDataEntry)], 1116 GNUNET_break_op (0);
1112 sizeof (struct MetaDataEntry)); 1117 break;
1113 format = (enum EXTRACTOR_MetaFormat) ntohl (ent.format); 1118 }
1114 if ((format != EXTRACTOR_METAFORMAT_UTF8) && 1119 dlen = ntohl (ent.data_size);
1115 (format != EXTRACTOR_METAFORMAT_C_STRING) && 1120 plen = ntohl (ent.plugin_name_len);
1116 (format != EXTRACTOR_METAFORMAT_BINARY)) 1121 mlen = ntohl (ent.mime_type_len);
1117 { 1122 if (dlen > left)
1118 GNUNET_break_op (0); 1123 {
1119 break; 1124 GNUNET_break_op (0);
1120 } 1125 break;
1121 dlen = ntohl (ent.data_size); 1126 }
1122 plen = ntohl (ent.plugin_name_len); 1127 left -= dlen;
1123 mlen = ntohl (ent.mime_type_len); 1128 meta_data = &mdata[left];
1124 if (dlen > left) 1129 if ((format == EXTRACTOR_METAFORMAT_UTF8) ||
1125 { 1130 (format == EXTRACTOR_METAFORMAT_C_STRING))
1126 GNUNET_break_op (0); 1131 {
1127 break; 1132 if ((dlen == 0) || (mdata[left + dlen - 1] != '\0'))
1128 } 1133 {
1129 left -= dlen; 1134 GNUNET_break_op (0);
1130 meta_data = &mdata[left]; 1135 break;
1131 if ((format == EXTRACTOR_METAFORMAT_UTF8) || 1136 }
1132 (format == EXTRACTOR_METAFORMAT_C_STRING)) 1137 }
1133 { 1138 if (plen > left)
1134 if ((dlen == 0) || (mdata[left + dlen - 1] != '\0')) 1139 {
1135 { 1140 GNUNET_break_op (0);
1136 GNUNET_break_op (0); 1141 break;
1137 break; 1142 }
1138 } 1143 left -= plen;
1139 } 1144 if ((plen > 0) && (mdata[left + plen - 1] != '\0'))
1140 if (plen > left) 1145 {
1141 { 1146 GNUNET_break_op (0);
1142 GNUNET_break_op (0); 1147 break;
1143 break; 1148 }
1144 } 1149 if (plen == 0)
1145 left -= plen; 1150 plugin_name = NULL;
1146 if ((plen > 0) && (mdata[left + plen - 1] != '\0')) 1151 else
1147 { 1152 plugin_name = &mdata[left];
1148 GNUNET_break_op (0); 1153
1149 break; 1154 if (mlen > left)
1150 } 1155 {
1151 if (plen == 0) 1156 GNUNET_break_op (0);
1152 plugin_name = NULL; 1157 break;
1153 else 1158 }
1154 plugin_name = &mdata[left]; 1159 left -= mlen;
1155 1160 if ((mlen > 0) && (mdata[left + mlen - 1] != '\0'))
1156 if (mlen > left) 1161 {
1157 { 1162 GNUNET_break_op (0);
1158 GNUNET_break_op (0); 1163 break;
1159 break;
1160 }
1161 left -= mlen;
1162 if ((mlen > 0) && (mdata[left + mlen - 1] != '\0'))
1163 {
1164 GNUNET_break_op (0);
1165 break;
1166 }
1167 if (mlen == 0)
1168 mime_type = NULL;
1169 else
1170 mime_type = &mdata[left];
1171 GNUNET_CONTAINER_meta_data_insert (md, plugin_name,
1172 (enum EXTRACTOR_MetaType)
1173 ntohl (ent.type), format, mime_type,
1174 meta_data, dlen);
1175 } 1164 }
1165 if (mlen == 0)
1166 mime_type = NULL;
1167 else
1168 mime_type = &mdata[left];
1169 GNUNET_CONTAINER_meta_data_insert (md, plugin_name,
1170 (enum EXTRACTOR_MetaType)
1171 ntohl (ent.type), format, mime_type,
1172 meta_data, dlen);
1173 }
1176 GNUNET_free_non_null (data); 1174 GNUNET_free_non_null (data);
1177 return md; 1175 return md;
1178} 1176}