diff options
Diffstat (limited to 'src/util/container_meta_data.c')
-rw-r--r-- | src/util/container_meta_data.c | 948 |
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 | */ |
53 | int | 54 | int |
54 | GNUNET_try_compression(const char *data, | 55 | GNUNET_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 | */ |
100 | char * | 101 | char * |
101 | GNUNET_decompress(const char *input, | 102 | GNUNET_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 | */ |
124 | struct MetaItem { | 125 | struct 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 | */ |
169 | struct GNUNET_CONTAINER_MetaData { | 171 | struct 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 | */ |
203 | struct GNUNET_CONTAINER_MetaData * | 206 | struct GNUNET_CONTAINER_MetaData * |
204 | GNUNET_CONTAINER_meta_data_create() | 207 | GNUNET_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 | */ |
215 | static void | 218 | static void |
216 | meta_item_free(struct MetaItem *mi) | 219 | meta_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 | */ |
231 | static void | 234 | static void |
232 | invalidate_sbuf(struct GNUNET_CONTAINER_MetaData *md) | 235 | invalidate_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 | */ |
247 | void | 250 | void |
248 | GNUNET_CONTAINER_meta_data_destroy(struct GNUNET_CONTAINER_MetaData *md) | 251 | GNUNET_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 | */ |
269 | void | 272 | void |
270 | GNUNET_CONTAINER_meta_data_clear(struct GNUNET_CONTAINER_MetaData *md) | 273 | GNUNET_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 | */ |
296 | int | 299 | int |
297 | GNUNET_CONTAINER_meta_data_test_equal(const struct GNUNET_CONTAINER_MetaData | 300 | GNUNET_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 | */ |
350 | int | 353 | int |
351 | GNUNET_CONTAINER_meta_data_insert(struct GNUNET_CONTAINER_MetaData *md, | 354 | GNUNET_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 | */ |
439 | static int | 442 | static int |
440 | merge_helper(void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, | 443 | merge_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 | */ |
459 | void | 462 | void |
460 | GNUNET_CONTAINER_meta_data_merge(struct GNUNET_CONTAINER_MetaData *md, | 463 | GNUNET_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 | */ |
477 | int | 480 | int |
478 | GNUNET_CONTAINER_meta_data_delete(struct GNUNET_CONTAINER_MetaData *md, | 481 | GNUNET_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 | */ |
510 | void | 513 | void |
511 | GNUNET_CONTAINER_meta_data_add_publication_date(struct | 514 | GNUNET_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 | */ |
537 | int | 540 | int |
538 | GNUNET_CONTAINER_meta_data_iterate(const struct GNUNET_CONTAINER_MetaData *md, | 541 | GNUNET_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 | */ |
567 | char * | 570 | char * |
568 | GNUNET_CONTAINER_meta_data_get_by_type(const struct GNUNET_CONTAINER_MetaData *md, | 571 | GNUNET_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 | */ |
595 | char * | 599 | char * |
596 | GNUNET_CONTAINER_meta_data_get_first_by_types(const struct | 600 | GNUNET_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 | */ |
629 | size_t | 633 | size_t |
630 | GNUNET_CONTAINER_meta_data_get_thumbnail(const struct GNUNET_CONTAINER_MetaData | 634 | GNUNET_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 | */ |
666 | struct GNUNET_CONTAINER_MetaData * | 670 | struct GNUNET_CONTAINER_MetaData * |
667 | GNUNET_CONTAINER_meta_data_duplicate(const struct GNUNET_CONTAINER_MetaData | 671 | GNUNET_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 | */ |
699 | struct MetaDataHeader { | 703 | struct 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 | */ |
732 | struct MetaDataEntry { | 737 | struct 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 | */ |
774 | ssize_t | 780 | ssize_t |
775 | GNUNET_CONTAINER_meta_data_serialize(const struct GNUNET_CONTAINER_MetaData | 781 | GNUNET_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 | */ |
998 | ssize_t | 1004 | ssize_t |
999 | GNUNET_CONTAINER_meta_data_get_serialized_size(const struct | 1005 | GNUNET_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 | */ |
1025 | struct GNUNET_CONTAINER_MetaData * | 1031 | struct GNUNET_CONTAINER_MetaData * |
1026 | GNUNET_CONTAINER_meta_data_deserialize(const char *input, size_t size) | 1032 | GNUNET_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 | ||