}
+/**
+ * Remove all items in the container.
+ *
+ * @param md metadata to manipulate
+ */
+void
+GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md)
+{
+ struct MetaItem *item;
+
+ if (md == NULL)
+ return;
+ while (NULL != (item = md->items))
+ {
+ md->items = item->next;
+ meta_item_free (item);
+ }
+ GNUNET_free_non_null (md->sbuf);
+ memset (md, 0, sizeof (struct GNUNET_CONTAINER_MetaData));
+}
+
+
+
/**
* Test if two MDs are equal. We consider them equal if
* the meta types, formats and content match (we do not
}
+/**
+ * Merge given meta data.
+ *
+ * @param cls the 'struct GNUNET_CONTAINER_MetaData' to merge into
+ * @param plugin_name name of the plugin that produced this value;
+ * special values can be used (i.e. '<zlib>' for zlib being
+ * used in the main libextractor library and yielding
+ * meta data).
+ * @param type libextractor-type describing the meta data
+ * @param format basic format information about data
+ * @param data_mime_type mime-type of data (not of the original file);
+ * can be NULL (if mime-type is not known)
+ * @param data actual meta-data found
+ * @param data_len number of bytes in data
+ * @return 0 (to continue)
+ */
+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_len)
+{
+ struct GNUNET_CONTAINER_MetaData *md = cls;
+ (void) GNUNET_CONTAINER_meta_data_insert (md, plugin_name,
+ type, format,
+ data_mime_type, data, data_len);
+ return 0;
+}
+
+
+/**
+ * Extend metadata. Merges the meta data from the second argument
+ * into the first, discarding duplicate key-value pairs.
+ *
+ * @param md metadata to extend
+ * @param in metadata to merge
+ */
+void
+GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md,
+ const struct GNUNET_CONTAINER_MetaData *in)
+{
+ GNUNET_CONTAINER_meta_data_iterate (in, &merge_helper, md);
+}
+
+
/**
* Remove an item.
*
{
struct MetaItem *pos;
+ if (md == NULL)
+ return 0;
if (iter == NULL)
return md->item_count;
pos = md->items;
{
struct MetaItem *pos;
+ if (md == NULL)
+ return NULL;
pos = md->items;
while (NULL != pos)
{
va_list args;
enum EXTRACTOR_MetaType type;
+ if (md == NULL)
+ return NULL;
ret = NULL;
va_start (args, md);
while (1)
struct MetaItem *pos;
struct MetaItem *match;
+ if (md == NULL)
+ return 0;
match = NULL;
pos = md->items;
while (NULL != pos)
- {
- if ( (0 == strncasecmp ("image/", pos->mime_type,
+ {
+ if ( (NULL != pos->mime_type) &&
+ (0 == strncasecmp ("image/", pos->mime_type,
strlen("image/"))) &&
(pos->format == EXTRACTOR_METAFORMAT_BINARY) )
{
}
pos = pos->next;
}
- if (match == NULL)
+ if ( (match == NULL) ||
+ (match->data_size == 0) )
return 0;
*thumb = GNUNET_malloc (match->data_size);
memcpy (*thumb, match->data, match->data_size);
}
-/**
- * Add meta data that libextractor finds to our meta data
- * container.
- *
- * @param cls closure, our meta data container
- * @param plugin_name name of the plugin that produced this value;
- * special values can be used (i.e. '<zlib>' for zlib being
- * used in the main libextractor library and yielding
- * meta data).
- * @param type libextractor-type describing the meta data
- * @param format basic format information about data
- * @param data_mime_type mime-type of data (not of the original file);
- * can be NULL (if mime-type is not known)
- * @param data actual meta-data found
- * @param data_len number of bytes in data
- * @return always 0 to continue extracting
- */
-static int
-add_to_md(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)
-{
- struct GNUNET_CONTAINER_MetaData *md = cls;
- (void) GNUNET_CONTAINER_meta_data_insert (md,
- plugin_name,
- type,
- format,
- data_mime_type,
- data,
- data_len);
- return 0;
-}
-
-
-/**
- * Extract meta-data from a file.
- *
- * @return GNUNET_SYSERR on error, otherwise the number
- * of meta-data items obtained
- */
-int
-GNUNET_CONTAINER_meta_data_extract_from_file (struct GNUNET_CONTAINER_MetaData
- *md, const char *filename,
- struct EXTRACTOR_PluginList *
- extractors)
-{
- unsigned int old;
-
- if (filename == NULL)
- return GNUNET_SYSERR;
- if (extractors == NULL)
- return 0;
- old = md->item_count;
- EXTRACTOR_extract (extractors,
- filename,
- NULL, 0,
- &add_to_md,
- md);
- return (int) (md->item_count - old);
-}
-
/**
* Try to compress the given block of data.
{
struct GNUNET_CONTAINER_MetaData *vmd;
struct MetaItem *pos;
+ struct MetaDataHeader ihdr;
struct MetaDataHeader *hdr;
struct MetaDataEntry *ent;
+ char *dst;
unsigned int i;
uint64_t msize;
size_t off;
size_t size;
size_t left;
size_t clen;
+ size_t rlen;
int comp;
if (max < sizeof (struct MetaDataHeader))
return GNUNET_SYSERR; /* far too small */
if (md == NULL)
return 0;
-
+
if (md->sbuf != NULL)
{
/* try to use serialization cache */
return GNUNET_SYSERR; /* can say that this will fail */
/* need to compute a partial serialization, sbuf useless ... */
}
-
-
+ dst = NULL;
msize = 0;
pos = md->items;
while (NULL != pos)
off -= pos->data_size;
memcpy (&mdata[off], pos->data, pos->data_size);
off -= plen;
- memcpy (&mdata[off], pos->plugin_name, plen);
+ if (pos->plugin_name != NULL)
+ memcpy (&mdata[off], pos->plugin_name, plen);
off -= mlen;
- memcpy (&mdata[off], pos->mime_type, mlen);
+ if (pos->mime_type != NULL)
+ memcpy (&mdata[off], pos->mime_type, mlen);
i++;
pos = pos->next;
}
GNUNET_assert (off == 0);
+ clen = 0;
+ cdata = NULL;
left = size;
- for (i=0;i<md->item_count;i++)
+ i = 0;
+ pos = md->items;
+ while (pos != NULL)
{
comp = GNUNET_NO;
if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS))
hdr->entries = htonl (md->item_count);
if (GNUNET_YES == comp)
{
+ GNUNET_assert (clen < left);
hdr->version = htonl (2 | HEADER_COMPRESSED);
memcpy (&hdr[1],
cdata,
/* success, this now fits! */
if (GNUNET_YES == comp)
{
- hdr = (struct MetaDataHeader*) *target;
- if (hdr == NULL)
- {
- hdr = GNUNET_malloc (clen + sizeof (struct MetaDataHeader));
- *target = (char*) hdr;
- }
+ if (dst == NULL)
+ dst = GNUNET_malloc (clen + sizeof (struct MetaDataHeader));
+ hdr = (struct MetaDataHeader*) dst;
hdr->version = htonl (2 | HEADER_COMPRESSED);
hdr->size = htonl (left);
hdr->entries = htonl (md->item_count - i);
- memcpy (&(*target)[sizeof(struct MetaDataHeader)],
+ memcpy (&dst[sizeof(struct MetaDataHeader)],
cdata,
clen);
GNUNET_free (cdata);
GNUNET_free (ent);
- return clen + sizeof (struct MetaDataHeader);
+ rlen = clen + sizeof (struct MetaDataHeader);
}
else
{
- hdr = (struct MetaDataHeader*) *target;
- if (hdr == NULL)
- {
- hdr = GNUNET_malloc (left + sizeof (struct MetaDataHeader));
- *target = (char*) hdr;
- }
+ if (dst == NULL)
+ dst = GNUNET_malloc (left + sizeof (struct MetaDataHeader));
+ hdr = (struct MetaDataHeader*) dst;
hdr->version = htonl (2);
hdr->entries = htonl (md->item_count - i);
hdr->size = htonl (left);
- memcpy (&(*target)[sizeof(struct MetaDataHeader)],
+ memcpy (&dst[sizeof(struct MetaDataHeader)],
&ent[i],
left);
GNUNET_free (ent);
- return left + sizeof (struct MetaDataHeader);
+ rlen = left + sizeof (struct MetaDataHeader);
+ }
+ if (NULL != *target)
+ {
+ memcpy (*target, dst, clen + sizeof (struct MetaDataHeader));
+ GNUNET_free (dst);
+ }
+ else
+ {
+ *target = dst;
}
+ return rlen;
}
if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART))
if (pos->plugin_name != NULL)
left -= strlen (pos->plugin_name) + 1;
if (pos->mime_type != NULL)
- left -= strlen (pos->mime_type) + 1;
+ left -= strlen (pos->mime_type) + 1;
+ pos = pos->next;
+ i++;
}
GNUNET_free (ent);
/* nothing fit, only write header! */
- hdr = (struct MetaDataHeader*) *target;
- if (hdr == NULL)
- {
- hdr = GNUNET_malloc (sizeof (struct MetaDataHeader));
- *target = (char*) hdr;
- }
- hdr->version = htonl (2);
- hdr->entries = htonl (0);
- hdr->size = htonl (0);
+ ihdr.version = htonl (2);
+ ihdr.entries = htonl (0);
+ ihdr.size = htonl (0);
+ if (*target == NULL)
+ *target = GNUNET_malloc (sizeof (struct MetaDataHeader));
+ memcpy (*target, &ihdr, sizeof (struct MetaDataHeader));
return sizeof (struct MetaDataHeader);
}