GNUnet  0.17.6
container_meta_data.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #if HAVE_EXTRACTOR_H
30 #include <extractor.h>
31 #endif
32 #include <zlib.h>
33 
34 #define LOG(kind, ...) GNUNET_log_from (kind, "util-container-meta-data", \
35  __VA_ARGS__)
36 
37 
53 int
55  size_t old_size,
56  char **result,
57  size_t *new_size)
58 {
59  char *tmp;
60  uLongf dlen;
61 
62  *result = NULL;
63  *new_size = 0;
64 #ifdef compressBound
65  dlen = compressBound (old_size);
66 #else
67  dlen = old_size + (old_size / 100) + 20;
68  /* documentation says 100.1% oldSize + 12 bytes, but we
69  * should be able to overshoot by more to be safe */
70 #endif
71  tmp = GNUNET_malloc (dlen);
72  if (Z_OK ==
73  compress2 ((Bytef *) tmp,
74  &dlen,
75  (const Bytef *) data,
76  old_size, 9))
77  {
78  if (dlen < old_size)
79  {
80  *result = tmp;
81  *new_size = dlen;
82  return GNUNET_YES;
83  }
84  }
85  GNUNET_free (tmp);
86  return GNUNET_NO;
87 }
88 
89 
100 char *
101 GNUNET_decompress (const char *input,
102  size_t input_size,
103  size_t output_size)
104 {
105  char *output;
106  uLongf olen;
107 
108  olen = output_size;
109  output = GNUNET_malloc (olen);
110  if (Z_OK ==
111  uncompress ((Bytef *) output,
112  &olen,
113  (const Bytef *) input,
114  input_size))
115  return output;
116  GNUNET_free (output);
117  return NULL;
118 }
119 
120 
124 struct MetaItem
125 {
129  struct MetaItem *next;
130 
134  struct MetaItem *prev;
135 
139  char *plugin_name;
140 
144  char *mime_type;
145 
149  char *data;
150 
154  size_t data_size;
155 
160 
165 };
166 
171 {
176 
181 
186  char *sbuf;
187 
191  size_t sbuf_size;
192 
196  unsigned int item_count;
197 };
198 
199 
207 {
208  return GNUNET_new (struct GNUNET_CONTAINER_MetaData);
209 }
210 
211 
217 static void
219 {
220  GNUNET_free (mi->plugin_name);
221  GNUNET_free (mi->mime_type);
222  GNUNET_free (mi->data);
223  GNUNET_free (mi);
224 }
225 
226 
233 static void
235 {
236  if (NULL == md->sbuf)
237  return;
238  GNUNET_free (md->sbuf);
239  md->sbuf = NULL;
240  md->sbuf_size = 0;
241 }
242 
243 
244 void
246 {
247  struct MetaItem *pos;
248 
249  if (NULL == md)
250  return;
251  while (NULL != (pos = md->items_head))
252  {
254  meta_item_free (pos);
255  }
256  GNUNET_free (md->sbuf);
257  GNUNET_free (md);
258 }
259 
260 
261 void
263 {
264  struct MetaItem *mi;
265 
266  if (NULL == md)
267  return;
268  while (NULL != (mi = md->items_head))
269  {
271  meta_item_free (mi);
272  }
273  GNUNET_free (md->sbuf);
274  memset (md, 0, sizeof(struct GNUNET_CONTAINER_MetaData));
275 }
276 
277 
278 int
280  *md1,
281  const struct GNUNET_CONTAINER_MetaData
282  *md2)
283 {
284  struct MetaItem *i;
285  struct MetaItem *j;
286  int found;
287 
288  if (md1 == md2)
289  return GNUNET_YES;
290  if (md1->item_count != md2->item_count)
291  return GNUNET_NO;
292  for (i = md1->items_head; NULL != i; i = i->next)
293  {
294  found = GNUNET_NO;
295  for (j = md2->items_head; NULL != j; j = j->next)
296  {
297  if ((i->type == j->type) && (i->format == j->format) &&
298  (i->data_size == j->data_size) &&
299  (0 == memcmp (i->data, j->data, i->data_size)))
300  {
301  found = GNUNET_YES;
302  break;
303  }
304  if (j->data_size < i->data_size)
305  break; /* elements are sorted by (decreasing) size... */
306  }
307  if (GNUNET_NO == found)
308  return GNUNET_NO;
309  }
310  return GNUNET_YES;
311 }
312 
313 
332 int
334  const char *plugin_name,
337  const char *data_mime_type, const char *data,
338  size_t data_size)
339 {
340  struct MetaItem *pos;
341  struct MetaItem *mi;
342  char *p;
343 
346  GNUNET_break ('\0' == data[data_size - 1]);
347 
348  for (pos = md->items_head; NULL != pos; pos = pos->next)
349  {
350  if (pos->data_size < data_size)
351  break; /* elements are sorted by size in the list */
352  if ((pos->type == type) && (pos->data_size == data_size) &&
353  (0 == memcmp (pos->data, data, data_size)))
354  {
355  if ((NULL == pos->mime_type) && (NULL != data_mime_type))
356  {
357  pos->mime_type = GNUNET_strdup (data_mime_type);
358  invalidate_sbuf (md);
359  }
360  if ((EXTRACTOR_METAFORMAT_C_STRING == pos->format) &&
362  {
364  invalidate_sbuf (md);
365  }
366  return GNUNET_SYSERR;
367  }
368  }
369  md->item_count++;
370  mi = GNUNET_new (struct MetaItem);
371  mi->type = type;
372  mi->format = format;
373  mi->data_size = data_size;
374  if (NULL == pos)
376  md->items_tail,
377  mi);
378  else
380  md->items_tail,
381  pos->prev,
382  mi);
383  mi->mime_type =
384  (NULL == data_mime_type) ? NULL : GNUNET_strdup (data_mime_type);
385  mi->plugin_name = (NULL == plugin_name) ? NULL : GNUNET_strdup (plugin_name);
386  mi->data = GNUNET_malloc (data_size);
388  /* change all dir separators to POSIX style ('/') */
391  {
392  p = mi->data;
393  while (('\0' != *p) && (p < mi->data + data_size))
394  {
395  if ('\\' == *p)
396  *p = '/';
397  p++;
398  }
399  }
400  invalidate_sbuf (md);
401  return GNUNET_OK;
402 }
403 
404 
421 static int
422 merge_helper (void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type,
423  enum EXTRACTOR_MetaFormat format, const char *data_mime_type,
424  const char *data, size_t data_size)
425 {
426  struct GNUNET_CONTAINER_MetaData *md = cls;
427 
429  data_mime_type, data, data_size);
430  return 0;
431 }
432 
433 
434 void
436  const struct GNUNET_CONTAINER_MetaData *in)
437 {
439 }
440 
441 
442 int
445  const char *data, size_t data_size)
446 {
447  struct MetaItem *pos;
448 
449  for (pos = md->items_head; NULL != pos; pos = pos->next)
450  {
451  if (pos->data_size < data_size)
452  break; /* items are sorted by (decreasing) size */
453  if ((pos->type == type) &&
454  ((NULL == data) ||
455  ((pos->data_size == data_size) &&
456  (0 == memcmp (pos->data, data, data_size)))))
457  {
459  meta_item_free (pos);
460  md->item_count--;
461  invalidate_sbuf (md);
462  return GNUNET_OK;
463  }
464  }
465  return GNUNET_SYSERR;
466 }
467 
468 
469 void
472 {
473  const char *dat;
474  struct GNUNET_TIME_Absolute t;
475 
479  NULL, 0);
481  GNUNET_CONTAINER_meta_data_insert (md, "<gnunet>",
483  EXTRACTOR_METAFORMAT_UTF8, "text/plain",
484  dat, strlen (dat) + 1);
485 }
486 
487 
496 int
499  void *iter_cls)
500 {
501  struct MetaItem *pos;
502 
503  if (NULL == md)
504  return 0;
505  if (NULL == iter)
506  return md->item_count;
507  for (pos = md->items_head; NULL != pos; pos = pos->next)
508  if (0 !=
509  iter (iter_cls, pos->plugin_name, pos->type, pos->format,
510  pos->mime_type, pos->data, pos->data_size))
511  return md->item_count;
512  return md->item_count;
513 }
514 
515 
516 char *
520 {
521  struct MetaItem *pos;
522 
523  if (NULL == md)
524  return NULL;
525  for (pos = md->items_head; NULL != pos; pos = pos->next)
526  if ((type == pos->type) &&
527  ((pos->format == EXTRACTOR_METAFORMAT_UTF8) ||
529  return GNUNET_strdup (pos->data);
530  return NULL;
531 }
532 
533 
534 char *
537  ...)
538 {
539  char *ret;
540  va_list args;
541  int type;
542 
543  if (NULL == md)
544  return NULL;
545  ret = NULL;
546  va_start (args, md);
547  while (1)
548  {
549  type = va_arg (args, int);
550  if (-1 == type)
551  break;
552  if (NULL != (ret = GNUNET_CONTAINER_meta_data_get_by_type (md, type)))
553  break;
554  }
555  va_end (args);
556  return ret;
557 }
558 
559 
568 size_t
570  *md, unsigned char **thumb)
571 {
572  struct MetaItem *pos;
573  struct MetaItem *match;
574 
575  if (NULL == md)
576  return 0;
577  match = NULL;
578  for (pos = md->items_head; NULL != pos; pos = pos->next)
579  {
580  if ((NULL != pos->mime_type) &&
581  (0 == strncasecmp ("image/", pos->mime_type, strlen ("image/"))) &&
583  {
584  if (NULL == match)
585  match = pos;
586  else if ((match->type != EXTRACTOR_METATYPE_THUMBNAIL) &&
588  match = pos;
589  }
590  }
591  if ((NULL == match) || (0 == match->data_size))
592  return 0;
593  *thumb = GNUNET_malloc (match->data_size);
594  GNUNET_memcpy (*thumb, match->data, match->data_size);
595  return match->data_size;
596 }
597 
598 
607  *md)
608 {
610  struct MetaItem *pos;
611 
612  if (NULL == md)
613  return NULL;
615  for (pos = md->items_tail; NULL != pos; pos = pos->prev)
617  pos->format, pos->mime_type, pos->data,
618  pos->data_size);
619  return ret;
620 }
621 
622 
626 #define HEADER_COMPRESSED 0x80000000
627 
628 
632 #define HEADER_VERSION_MASK 0x7FFFFFFF
633 
634 
639 {
649  uint32_t version;
650 
654  uint32_t entries;
655 
659  uint32_t size;
660 
666 };
667 
668 
673 {
677  uint32_t type;
678 
682  uint32_t format;
683 
687  uint32_t data_size;
688 
692  uint32_t plugin_name_len;
693 
697  uint32_t mime_type_len;
698 };
699 
700 
715 ssize_t
717  *md, char **target, size_t max,
718  enum
720  opt)
721 {
722  struct GNUNET_CONTAINER_MetaData *vmd;
723  struct MetaItem *pos;
724  struct MetaDataHeader ihdr;
725  struct MetaDataHeader *hdr;
726  struct MetaDataEntry *ent;
727  char *dst;
728  unsigned int i;
729  uint64_t msize;
730  size_t off;
731  char *mdata;
732  char *cdata;
733  size_t mlen;
734  size_t plen;
735  size_t size;
736  size_t left;
737  size_t clen;
738  size_t rlen;
739  int comp;
740 
741  if (max < sizeof(struct MetaDataHeader))
742  return GNUNET_SYSERR; /* far too small */
743  if (NULL == md)
744  return 0;
745 
746  if (NULL != md->sbuf)
747  {
748  /* try to use serialization cache */
749  if (md->sbuf_size <= max)
750  {
751  if (NULL == *target)
752  *target = GNUNET_malloc (md->sbuf_size);
753  GNUNET_memcpy (*target, md->sbuf, md->sbuf_size);
754  return md->sbuf_size;
755  }
757  return GNUNET_SYSERR; /* can say that this will fail */
758  /* need to compute a partial serialization, sbuf useless ... */
759  }
760  dst = NULL;
761  msize = 0;
762  for (pos = md->items_tail; NULL != pos; pos = pos->prev)
763  {
764  msize += sizeof(struct MetaDataEntry);
765  msize += pos->data_size;
766  if (NULL != pos->plugin_name)
767  msize += strlen (pos->plugin_name) + 1;
768  if (NULL != pos->mime_type)
769  msize += strlen (pos->mime_type) + 1;
770  }
771  size = (size_t) msize;
772  if (size != msize)
773  {
774  GNUNET_break (0); /* integer overflow */
775  return GNUNET_SYSERR;
776  }
778  {
779  /* too large to be processed */
780  return GNUNET_SYSERR;
781  }
782  ent = GNUNET_malloc (size);
783  mdata = (char *) &ent[md->item_count];
784  off = size - (md->item_count * sizeof(struct MetaDataEntry));
785  i = 0;
786  for (pos = md->items_head; NULL != pos; pos = pos->next)
787  {
788  ent[i].type = htonl ((uint32_t) pos->type);
789  ent[i].format = htonl ((uint32_t) pos->format);
790  ent[i].data_size = htonl ((uint32_t) pos->data_size);
791  if (NULL == pos->plugin_name)
792  plen = 0;
793  else
794  plen = strlen (pos->plugin_name) + 1;
795  ent[i].plugin_name_len = htonl ((uint32_t) plen);
796  if (NULL == pos->mime_type)
797  mlen = 0;
798  else
799  mlen = strlen (pos->mime_type) + 1;
800  ent[i].mime_type_len = htonl ((uint32_t) mlen);
801  off -= pos->data_size;
802  if ((EXTRACTOR_METAFORMAT_UTF8 == pos->format) ||
804  GNUNET_break ('\0' == pos->data[pos->data_size - 1]);
805  GNUNET_memcpy (&mdata[off], pos->data, pos->data_size);
806  off -= plen;
807  if (NULL != pos->plugin_name)
808  GNUNET_memcpy (&mdata[off], pos->plugin_name, plen);
809  off -= mlen;
810  if (NULL != pos->mime_type)
811  GNUNET_memcpy (&mdata[off], pos->mime_type, mlen);
812  i++;
813  }
814  GNUNET_assert (0 == off);
815 
816  clen = 0;
817  cdata = NULL;
818  left = size;
819  i = 0;
820  for (pos = md->items_head; NULL != pos; pos = pos->next)
821  {
822  comp = GNUNET_NO;
824  comp = GNUNET_try_compression ((const char *) &ent[i],
825  left,
826  &cdata,
827  &clen);
828 
829  if ((NULL == md->sbuf) && (0 == i))
830  {
831  /* fill 'sbuf'; this "modifies" md, but since this is only
832  * an internal cache we will cast away the 'const' instead
833  * of making the API look strange. */
834  vmd = (struct GNUNET_CONTAINER_MetaData *) md;
835  hdr = GNUNET_malloc (left + sizeof(struct MetaDataHeader));
836  hdr->size = htonl (left);
837  hdr->entries = htonl (md->item_count);
838  if (GNUNET_YES == comp)
839  {
840  GNUNET_assert (clen < left);
841  hdr->version = htonl (2 | HEADER_COMPRESSED);
842  GNUNET_memcpy (&hdr[1], cdata, clen);
843  vmd->sbuf_size = clen + sizeof(struct MetaDataHeader);
844  }
845  else
846  {
847  hdr->version = htonl (2);
848  GNUNET_memcpy (&hdr[1], &ent[0], left);
849  vmd->sbuf_size = left + sizeof(struct MetaDataHeader);
850  }
851  vmd->sbuf = (char *) hdr;
852  }
853 
854  if (((left + sizeof(struct MetaDataHeader)) <= max) ||
855  ((GNUNET_YES == comp) && (clen <= max)))
856  {
857  /* success, this now fits! */
858  if (GNUNET_YES == comp)
859  {
860  if (NULL == dst)
861  dst = GNUNET_malloc (clen + sizeof(struct MetaDataHeader));
862  hdr = (struct MetaDataHeader *) dst;
863  hdr->version = htonl (2 | HEADER_COMPRESSED);
864  hdr->size = htonl (left);
865  hdr->entries = htonl (md->item_count - i);
866  GNUNET_memcpy (&dst[sizeof(struct MetaDataHeader)], cdata, clen);
867  GNUNET_free (cdata);
868  cdata = NULL;
869  GNUNET_free (ent);
870  rlen = clen + sizeof(struct MetaDataHeader);
871  }
872  else
873  {
874  if (NULL == dst)
875  dst = GNUNET_malloc (left + sizeof(struct MetaDataHeader));
876  hdr = (struct MetaDataHeader *) dst;
877  hdr->version = htonl (2);
878  hdr->entries = htonl (md->item_count - i);
879  hdr->size = htonl (left);
880  GNUNET_memcpy (&dst[sizeof(struct MetaDataHeader)], &ent[i], left);
881  GNUNET_free (ent);
882  rlen = left + sizeof(struct MetaDataHeader);
883  }
884  if (NULL != *target)
885  {
886  if (GNUNET_YES == comp)
887  GNUNET_memcpy (*target, dst, clen + sizeof(struct MetaDataHeader));
888  else
889  GNUNET_memcpy (*target, dst, left + sizeof(struct MetaDataHeader));
890  GNUNET_free (dst);
891  }
892  else
893  {
894  *target = dst;
895  }
896  return rlen;
897  }
898 
900  {
901  /* does not fit! */
902  GNUNET_free (ent);
903  if (NULL != cdata)
904  GNUNET_free (cdata);
905  cdata = NULL;
906  return GNUNET_SYSERR;
907  }
908 
909  /* next iteration: ignore the corresponding meta data at the
910  * end and try again without it */
911  left -= sizeof(struct MetaDataEntry);
912  left -= pos->data_size;
913  if (NULL != pos->plugin_name)
914  left -= strlen (pos->plugin_name) + 1;
915  if (NULL != pos->mime_type)
916  left -= strlen (pos->mime_type) + 1;
917 
918  if (NULL != cdata)
919  GNUNET_free (cdata);
920  cdata = NULL;
921  i++;
922  }
923  GNUNET_free (ent);
924 
925  /* nothing fit, only write header! */
926  ihdr.version = htonl (2);
927  ihdr.entries = htonl (0);
928  ihdr.size = htonl (0);
929  if (NULL == *target)
930  *target = (char *) GNUNET_new (struct MetaDataHeader);
931  GNUNET_memcpy (*target, &ihdr, sizeof(struct MetaDataHeader));
932  return sizeof(struct MetaDataHeader);
933 }
934 
935 
936 ssize_t
939 {
940  ssize_t ret;
941  char *ptr;
942 
943  if (NULL != md->sbuf)
944  return md->sbuf_size;
945  ptr = NULL;
946  ret =
949  if (-1 != ret)
950  GNUNET_free (ptr);
951  return ret;
952 }
953 
954 
964 GNUNET_CONTAINER_meta_data_deserialize (const char *input, size_t size)
965 {
966  struct GNUNET_CONTAINER_MetaData *md;
967  struct MetaDataHeader hdr;
968  struct MetaDataEntry ent;
969  uint32_t ic;
970  uint32_t i;
971  char *data;
972  const char *cdata;
973  uint32_t version;
974  uint32_t dataSize;
975  int compressed;
976  size_t left;
977  uint32_t mlen;
978  uint32_t plen;
979  uint32_t dlen;
980  const char *mdata;
981  const char *meta_data;
982  const char *plugin_name;
983  const char *mime_type;
985 
986  if (size < sizeof(struct MetaDataHeader))
987  return NULL;
988  GNUNET_memcpy (&hdr, input, sizeof(struct MetaDataHeader));
989  version = ntohl (hdr.version) & HEADER_VERSION_MASK;
990  compressed = (ntohl (hdr.version) & HEADER_COMPRESSED) != 0;
991 
992  if (1 == version)
993  return NULL; /* null pointer */
994  if (2 != version)
995  {
996  GNUNET_break_op (0); /* unsupported version */
997  return NULL;
998  }
999 
1000  ic = ntohl (hdr.entries);
1001  dataSize = ntohl (hdr.size);
1002  if (((sizeof(struct MetaDataEntry) * ic) > dataSize) ||
1003  ((0 != ic) &&
1004  (dataSize / ic < sizeof(struct MetaDataEntry))))
1005  {
1006  GNUNET_break_op (0);
1007  return NULL;
1008  }
1009 
1010  if (compressed)
1011  {
1012  if (dataSize >= GNUNET_MAX_MALLOC_CHECKED)
1013  {
1014  /* make sure we don't blow our memory limit because of a mal-formed
1015  * message... */
1016  GNUNET_break_op (0);
1017  return NULL;
1018  }
1019  data =
1020  GNUNET_decompress ((const char *) &input[sizeof(struct MetaDataHeader)],
1021  size - sizeof(struct MetaDataHeader),
1022  dataSize);
1023  if (NULL == data)
1024  {
1025  GNUNET_break_op (0);
1026  return NULL;
1027  }
1028  cdata = data;
1029  }
1030  else
1031  {
1032  data = NULL;
1033  cdata = (const char *) &input[sizeof(struct MetaDataHeader)];
1034  if (dataSize != size - sizeof(struct MetaDataHeader))
1035  {
1036  GNUNET_break_op (0);
1037  return NULL;
1038  }
1039  }
1040 
1042  left = dataSize - ic * sizeof(struct MetaDataEntry);
1043  mdata = &cdata[ic * sizeof(struct MetaDataEntry)];
1044  for (i = 0; i < ic; i++)
1045  {
1046  GNUNET_memcpy (&ent, &cdata[i * sizeof(struct MetaDataEntry)],
1047  sizeof(struct MetaDataEntry));
1048  format = (enum EXTRACTOR_MetaFormat) ntohl (ent.format);
1049  if ((EXTRACTOR_METAFORMAT_UTF8 != format) &&
1052  {
1053  GNUNET_break_op (0);
1054  break;
1055  }
1056  dlen = ntohl (ent.data_size);
1057  plen = ntohl (ent.plugin_name_len);
1058  mlen = ntohl (ent.mime_type_len);
1059  if (dlen > left)
1060  {
1061  GNUNET_break_op (0);
1062  break;
1063  }
1064  left -= dlen;
1065  meta_data = &mdata[left];
1066  if ((EXTRACTOR_METAFORMAT_UTF8 == format) ||
1068  {
1069  if (0 == dlen)
1070  {
1071  GNUNET_break_op (0);
1072  break;
1073  }
1074  if ('\0' != meta_data[dlen - 1])
1075  {
1076  GNUNET_break_op (0);
1077  break;
1078  }
1079  }
1080  if (plen > left)
1081  {
1082  GNUNET_break_op (0);
1083  break;
1084  }
1085  left -= plen;
1086  if ((plen > 0) && ('\0' != mdata[left + plen - 1]))
1087  {
1088  GNUNET_break_op (0);
1089  break;
1090  }
1091  if (0 == plen)
1092  plugin_name = NULL;
1093  else
1094  plugin_name = &mdata[left];
1095 
1096  if (mlen > left)
1097  {
1098  GNUNET_break_op (0);
1099  break;
1100  }
1101  left -= mlen;
1102  if ((mlen > 0) && ('\0' != mdata[left + mlen - 1]))
1103  {
1104  GNUNET_break_op (0);
1105  break;
1106  }
1107  if (0 == mlen)
1108  mime_type = NULL;
1109  else
1110  mime_type = &mdata[left];
1112  (enum EXTRACTOR_MetaType)
1113  ntohl (ent.type), format, mime_type,
1114  meta_data, dlen);
1115  }
1116  GNUNET_free (data);
1117  return md;
1118 }
1119 
1120 
1121 /* end of container_meta_data.c */
static void meta_item_free(struct MetaItem *mi)
Free meta data item.
#define HEADER_VERSION_MASK
Bits in 'version' that give the version number.
static int merge_helper(void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, const char *data_mime_type, const char *data, size_t data_size)
Merge given meta data.
static void invalidate_sbuf(struct GNUNET_CONTAINER_MetaData *md)
The meta data has changed, invalidate its serialization buffer.
#define HEADER_COMPRESSED
Flag in 'version' that indicates compressed meta-data.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
uint32_t data
The data value.
static int result
Global testing status.
static char * plugin_name
Name of our plugin.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:37
static struct GNUNET_SCHEDULER_Task * t
Main task.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_after(head, tail, other, element)
Insert an element into a DLL after the given other element.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
char * GNUNET_decompress(const char *input, size_t input_size, size_t output_size)
Decompress input, return the decompressed data as output.
int(* EXTRACTOR_MetaDataProcessor)(void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, const char *data_mime_type, const char *data, size_t data_len)
Type of a function that libextractor calls for each meta data item found.
int GNUNET_try_compression(const char *data, size_t old_size, char **result, size_t *new_size)
Try to compress the given block of data using libz.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
EXTRACTOR_MetaFormat
Format in which the extracted meta data is presented.
EXTRACTOR_MetaType
Enumeration defining various sources of keywords.
@ EXTRACTOR_METAFORMAT_BINARY
Some kind of binary format, see given Mime type.
@ EXTRACTOR_METAFORMAT_C_STRING
0-terminated string.
@ EXTRACTOR_METAFORMAT_UTF8
0-terminated, UTF-8 encoded string.
@ GNUNET_OK
Definition: gnunet_common.h:99
@ GNUNET_YES
@ GNUNET_NO
Definition: gnunet_common.h:98
@ GNUNET_SYSERR
Definition: gnunet_common.h:97
@ EXTRACTOR_METATYPE_PUBLICATION_DATE
@ EXTRACTOR_METATYPE_THUMBNAIL
@ EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME
@ EXTRACTOR_METATYPE_FILENAME
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_MAX_MALLOC_CHECKED
Maximum allocation with GNUNET_malloc macro.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
char * GNUNET_CONTAINER_meta_data_get_by_type(const struct GNUNET_CONTAINER_MetaData *md, enum EXTRACTOR_MetaType type)
Get the first MD entry of the given type.
ssize_t GNUNET_CONTAINER_meta_data_serialize(const struct GNUNET_CONTAINER_MetaData *md, char **target, size_t max, enum GNUNET_CONTAINER_MetaDataSerializationOptions opt)
Serialize meta-data to target.
int GNUNET_CONTAINER_meta_data_iterate(const struct GNUNET_CONTAINER_MetaData *md, EXTRACTOR_MetaDataProcessor iter, void *iter_cls)
Iterate over MD entries.
void GNUNET_CONTAINER_meta_data_merge(struct GNUNET_CONTAINER_MetaData *md, const struct GNUNET_CONTAINER_MetaData *in)
Extend metadata.
size_t GNUNET_CONTAINER_meta_data_get_thumbnail(const struct GNUNET_CONTAINER_MetaData *md, unsigned char **thumb)
Get a thumbnail from the meta-data (if present).
GNUNET_CONTAINER_MetaDataSerializationOptions
Options for metadata serialization.
int GNUNET_CONTAINER_meta_data_delete(struct GNUNET_CONTAINER_MetaData *md, enum EXTRACTOR_MetaType type, const char *data, size_t data_size)
Remove an item.
struct GNUNET_CONTAINER_MetaData * GNUNET_CONTAINER_meta_data_deserialize(const char *input, size_t size)
Deserialize meta-data.
int GNUNET_CONTAINER_meta_data_test_equal(const struct GNUNET_CONTAINER_MetaData *md1, const struct GNUNET_CONTAINER_MetaData *md2)
Test if two MDs are equal.
ssize_t GNUNET_CONTAINER_meta_data_get_serialized_size(const struct GNUNET_CONTAINER_MetaData *md)
Get the size of the full meta-data in serialized form.
char * GNUNET_CONTAINER_meta_data_get_first_by_types(const struct GNUNET_CONTAINER_MetaData *md,...)
Get the first matching MD entry of the given types.
struct GNUNET_CONTAINER_MetaData * GNUNET_CONTAINER_meta_data_create()
Create a fresh struct CONTAINER_MetaData token.
void GNUNET_CONTAINER_meta_data_destroy(struct GNUNET_CONTAINER_MetaData *md)
Free meta data.
struct GNUNET_CONTAINER_MetaData * GNUNET_CONTAINER_meta_data_duplicate(const struct GNUNET_CONTAINER_MetaData *md)
Duplicate a struct GNUNET_CONTAINER_MetaData.
void GNUNET_CONTAINER_meta_data_add_publication_date(struct GNUNET_CONTAINER_MetaData *md)
Add the current time as the publication date to the meta-data.
int GNUNET_CONTAINER_meta_data_insert(struct GNUNET_CONTAINER_MetaData *md, const char *plugin_name, enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, const char *data_mime_type, const char *data, size_t data_size)
Extend metadata.
void GNUNET_CONTAINER_meta_data_clear(struct GNUNET_CONTAINER_MetaData *md)
Remove all items in the container.
@ GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS
Speed is of the essence, do not allow compression.
@ GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL
Serialize all of the data.
@ GNUNET_CONTAINER_META_DATA_SERIALIZE_PART
If not enough space is available, it is acceptable to only serialize some of the metadata.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:110
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:617
#define max(x, y)
static unsigned int size
Size of the "table".
Definition: peer.c:67
Meta data to associate with a file, directory or namespace.
char * sbuf
Complete serialized and compressed buffer of the items.
size_t sbuf_size
Number of bytes in 'sbuf'.
unsigned int item_count
Number of items in the linked list.
struct MetaItem * items_head
Head of linked list of the meta data items.
struct MetaItem * items_tail
Tail of linked list of the meta data items.
Time for absolute times used by GNUnet, in microseconds.
Entry of serialized meta data.
uint32_t plugin_name_len
Number of bytes in the plugin name including 0-terminator.
uint32_t mime_type_len
Number of bytes in the mime type including 0-terminator.
uint32_t type
Meta data type.
uint32_t data_size
Number of bytes of meta data.
uint32_t format
Meta data format.
Header for serialized meta data.
uint32_t entries
How many MD entries are there?
uint32_t size
Size of the decompressed meta data.
uint32_t version
The version of the MD serialization.
Meta data item.
struct MetaItem * prev
This is a doubly linked list.
struct MetaItem * next
This is a doubly linked list.
enum EXTRACTOR_MetaType type
Type of the meta data.
size_t data_size
Number of bytes in 'data'.
char * mime_type
Mime-type of data.
enum EXTRACTOR_MetaFormat format
Format of the meta data.
char * data
The actual meta data.
char * plugin_name
Name of the extracting plugin.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model