#include <extractor.h>
#include <zlib.h>
+#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
+
/**
* Meta data item.
*/
{
/**
* This is a linked list.
- */
+ */
struct MetaItem *next;
/**
/**
* Create a fresh struct CONTAINER_MetaData token.
- *
+ *
* @return empty meta-data container
*/
struct GNUNET_CONTAINER_MetaData *
if (md == NULL)
return;
while (NULL != (item = md->items))
- {
- md->items = item->next;
- meta_item_free (item);
- }
+ {
+ md->items = item->next;
+ meta_item_free (item);
+ }
GNUNET_free_non_null (md->sbuf);
GNUNET_free (md);
}
+/**
+ * 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
i = md1->items;
while (NULL != i)
+ {
+ found = GNUNET_NO;
+ j = md2->items;
+ while (NULL != j)
{
- found = GNUNET_NO;
- j = md2->items;
- while (NULL != j)
- {
- if ( (i->type == j->type) &&
- (i->format == j->format) &&
- (i->data_size == j->data_size) &&
- (0 == memcmp (i->data,
- j->data,
- i->data_size)))
- {
- found = GNUNET_YES;
- break;
- }
- j = j->next;
- }
- if (found == GNUNET_NO)
- return GNUNET_NO;
- i = i->next;
+ if ((i->type == j->type) && (i->format == j->format) &&
+ (i->data_size == j->data_size) &&
+ (0 == memcmp (i->data, j->data, i->data_size)))
+ {
+ found = GNUNET_YES;
+ break;
+ }
+ j = j->next;
}
+ if (found == GNUNET_NO)
+ return GNUNET_NO;
+ i = i->next;
+ }
return GNUNET_YES;
}
* 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 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
*/
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_len)
+ 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 MetaItem *prev;
struct MetaItem *pos;
prev = NULL;
pos = md->items;
while (NULL != pos)
+ {
+ if (pos->data_size < data_len)
+ break;
+ if ((pos->type == type) && (pos->data_size == data_len) &&
+ (0 == memcmp (pos->data, data, data_len)))
{
- if (pos->data_size < data_len)
- break;
- if ( (pos->type == type) &&
- (pos->format == format) &&
- (pos->data_size == data_len) &&
- (0 == memcmp (pos->data,
- data,
- data_len)))
- {
- if ( (pos->mime_type == NULL) &&
- (data_mime_type != NULL) )
- {
- pos->mime_type = GNUNET_strdup (data_mime_type);
- invalidate_sbuf (md);
- }
- return GNUNET_SYSERR;
- }
- prev = pos;
- pos = pos->next;
+ if ((pos->mime_type == NULL) && (data_mime_type != NULL))
+ {
+ pos->mime_type = GNUNET_strdup (data_mime_type);
+ invalidate_sbuf (md);
+ }
+ if ((pos->format == EXTRACTOR_METAFORMAT_C_STRING) &&
+ (format == EXTRACTOR_METAFORMAT_UTF8))
+ {
+ pos->format = EXTRACTOR_METAFORMAT_UTF8;
+ invalidate_sbuf (md);
+ }
+ return GNUNET_SYSERR;
}
+ prev = pos;
+ pos = pos->next;
+ }
md->item_count++;
i = GNUNET_malloc (sizeof (struct MetaItem));
i->type = type;
md->items = i;
else
prev->next = i;
- i->mime_type = (data_mime_type == NULL) ? NULL : GNUNET_strdup (data_mime_type);
+ i->mime_type =
+ (data_mime_type == NULL) ? NULL : GNUNET_strdup (data_mime_type);
i->plugin_name = (plugin_name == NULL) ? NULL : GNUNET_strdup (plugin_name);
i->data = GNUNET_malloc (data_len);
memcpy (i->data, data, data_len);
/* change OS native dir separators to unix '/' and others to '_' */
if (type == EXTRACTOR_METATYPE_FILENAME)
+ {
+ p = i->data;
+ while ((*p != '\0') && (p < i->data + data_len))
{
- p = i->data;
- while ( (*p != '\0') &&
- (p < i->data + data_len) )
- {
- if (*p == DIR_SEPARATOR)
- *p = '/';
- else if (*p == '\\')
- *p = '_';
- p++;
- }
+ if (*p == DIR_SEPARATOR)
+ *p = '/';
+ else if (*p == '\\')
+ *p = '_';
+ p++;
}
+ }
invalidate_sbuf (md);
return GNUNET_OK;
}
* 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 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)
+ */
+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);
+
+ (void) GNUNET_CONTAINER_meta_data_insert (md, plugin_name, type, format,
+ data_mime_type, data, data_len);
return 0;
}
* @param md metadata to extend
* @param in metadata to merge
*/
-void
+void
GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md,
- const struct GNUNET_CONTAINER_MetaData *in)
+ const struct GNUNET_CONTAINER_MetaData *in)
{
GNUNET_CONTAINER_meta_data_iterate (in, &merge_helper, md);
}
*/
int
GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md,
- enum EXTRACTOR_MetaType type,
- const char *data,
- size_t data_len)
+ enum EXTRACTOR_MetaType type,
+ const char *data, size_t data_len)
{
struct MetaItem *pos;
struct MetaItem *prev;
prev = NULL;
pos = md->items;
while (NULL != pos)
+ {
+ if ((pos->type == type) &&
+ ((data == NULL) ||
+ ((pos->data_size == data_len) &&
+ (0 == memcmp (pos->data, data, data_len)))))
{
- if ( (pos->type == type) &&
- ( (data == NULL) ||
- ( (pos->data_size == data_len) &&
- (0 == memcmp (pos->data,
- data,
- data_len))) ) )
- {
- if (prev == NULL)
- md->items = pos->next;
- else
- prev->next = pos->next;
- meta_item_free (pos);
- md->item_count--;
- invalidate_sbuf (md);
- return GNUNET_OK;
- }
- prev = pos;
- pos = pos->next;
+ if (prev == NULL)
+ md->items = pos->next;
+ else
+ prev->next = pos->next;
+ meta_item_free (pos);
+ md->item_count--;
+ invalidate_sbuf (md);
+ return GNUNET_OK;
}
+ prev = pos;
+ pos = pos->next;
+ }
return GNUNET_SYSERR;
}
*/
void
GNUNET_CONTAINER_meta_data_add_publication_date (struct
- GNUNET_CONTAINER_MetaData
- *md)
+ GNUNET_CONTAINER_MetaData *md)
{
char *dat;
struct GNUNET_TIME_Absolute t;
t = GNUNET_TIME_absolute_get ();
- GNUNET_CONTAINER_meta_data_delete (md,
- EXTRACTOR_METATYPE_PUBLICATION_DATE,
- NULL,
- 0);
+ GNUNET_CONTAINER_meta_data_delete (md, EXTRACTOR_METATYPE_PUBLICATION_DATE,
+ NULL, 0);
dat = GNUNET_STRINGS_absolute_time_to_string (t);
- GNUNET_CONTAINER_meta_data_insert (md,
- "<gnunet>",
- EXTRACTOR_METATYPE_PUBLICATION_DATE,
- EXTRACTOR_METAFORMAT_UTF8,
- "text/plain",
- dat,
- strlen(dat)+1);
+ GNUNET_CONTAINER_meta_data_insert (md, "<gnunet>",
+ EXTRACTOR_METATYPE_PUBLICATION_DATE,
+ EXTRACTOR_METAFORMAT_UTF8, "text/plain",
+ dat, strlen (dat) + 1);
GNUNET_free (dat);
}
* @return number of entries
*/
int
-GNUNET_CONTAINER_meta_data_iterate (const struct
- GNUNET_CONTAINER_MetaData *md,
- EXTRACTOR_MetaDataProcessor
- iter, void *iter_cls)
+GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData *md,
+ EXTRACTOR_MetaDataProcessor iter,
+ void *iter_cls)
{
struct MetaItem *pos;
+ if (md == NULL)
+ return 0;
if (iter == NULL)
return md->item_count;
pos = md->items;
while (NULL != pos)
- {
- if (0 != iter (iter_cls,
- pos->plugin_name,
- pos->type,
- pos->format,
- pos->mime_type,
- pos->data,
- pos->data_size))
- return md->item_count;
- pos = pos->next;
- }
+ {
+ if (0 !=
+ iter (iter_cls, pos->plugin_name, pos->type, pos->format,
+ pos->mime_type, pos->data, pos->data_size))
+ return md->item_count;
+ pos = pos->next;
+ }
return md->item_count;
}
{
struct MetaItem *pos;
+ if (md == NULL)
+ return NULL;
pos = md->items;
while (NULL != pos)
- {
- if ( (type == pos->type) &&
- ( (pos->format == EXTRACTOR_METAFORMAT_UTF8) ||
- (pos->format == EXTRACTOR_METAFORMAT_C_STRING) ) )
- return GNUNET_strdup (pos->data);
- pos = pos->next;
- }
+ {
+ if ((type == pos->type) &&
+ ((pos->format == EXTRACTOR_METAFORMAT_UTF8) ||
+ (pos->format == EXTRACTOR_METAFORMAT_C_STRING)))
+ return GNUNET_strdup (pos->data);
+ pos = pos->next;
+ }
return NULL;
}
va_list args;
enum EXTRACTOR_MetaType type;
+ if (md == NULL)
+ return NULL;
ret = NULL;
va_start (args, md);
while (1)
- {
- type = va_arg (args, enum EXTRACTOR_MetaType);
- if (type == -1)
- break;
- ret = GNUNET_CONTAINER_meta_data_get_by_type (md, type);
- if (ret != NULL)
- break;
- }
+ {
+ type = va_arg (args, enum EXTRACTOR_MetaType);
+
+ if (type == -1)
+ break;
+ ret = GNUNET_CONTAINER_meta_data_get_by_type (md, type);
+ if (ret != NULL)
+ break;
+ }
va_end (args);
return ret;
}
* @return number of bytes in thumbnail, 0 if not available
*/
size_t
-GNUNET_CONTAINER_meta_data_get_thumbnail (const struct
- GNUNET_CONTAINER_MetaData * md,
- unsigned char **thumb)
+GNUNET_CONTAINER_meta_data_get_thumbnail (const struct GNUNET_CONTAINER_MetaData
+ * md, unsigned char **thumb)
{
struct MetaItem *pos;
struct MetaItem *match;
+ if (md == NULL)
+ return 0;
match = NULL;
pos = md->items;
while (NULL != pos)
+ {
+ if ((NULL != pos->mime_type) &&
+ (0 == strncasecmp ("image/", pos->mime_type, strlen ("image/"))) &&
+ (pos->format == EXTRACTOR_METAFORMAT_BINARY))
{
- if ( (0 == strncasecmp ("image/", pos->mime_type,
- strlen("image/"))) &&
- (pos->format == EXTRACTOR_METAFORMAT_BINARY) )
- {
- if (match == NULL)
- match = pos;
- else if ( (match->type != EXTRACTOR_METATYPE_THUMBNAIL) &&
- (pos->type == EXTRACTOR_METATYPE_THUMBNAIL) )
- match = pos;
- }
- pos = pos->next;
+ if (match == NULL)
+ match = pos;
+ else if ((match->type != EXTRACTOR_METATYPE_THUMBNAIL) &&
+ (pos->type == EXTRACTOR_METATYPE_THUMBNAIL))
+ match = pos;
}
- if ( (match == NULL) ||
- (match->data_size == 0) )
+ pos = pos->next;
+ }
+ if ((match == NULL) || (match->data_size == 0))
return 0;
*thumb = GNUNET_malloc (match->data_size);
memcpy (*thumb, match->data, match->data_size);
/**
* Duplicate struct GNUNET_CONTAINER_MetaData.
- *
+ *
* @param md what to duplicate
* @return duplicate meta-data container
*/
ret = GNUNET_CONTAINER_meta_data_create ();
pos = md->items;
while (NULL != pos)
- {
- GNUNET_CONTAINER_meta_data_insert (ret,
- pos->plugin_name,
- pos->type,
- pos->format,
- pos->mime_type,
- pos->data,
- pos->data_size);
- pos = pos->next;
- }
+ {
+ GNUNET_CONTAINER_meta_data_insert (ret, pos->plugin_name, pos->type,
+ pos->format, pos->mime_type, pos->data,
+ pos->data_size);
+ pos = pos->next;
+ }
return ret;
}
-/**
- * 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.
* GNUNET_NO if compression did not help
*/
static int
-try_compression (const char *data,
- size_t oldSize,
- char **result,
- size_t *newSize)
+try_compression (const char *data, size_t oldSize, char **result,
+ size_t * newSize)
{
char *tmp;
uLongf dlen;
#else
dlen = oldSize + (oldSize / 100) + 20;
/* documentation says 100.1% oldSize + 12 bytes, but we
- should be able to overshoot by more to be safe */
+ * should be able to overshoot by more to be safe */
#endif
tmp = GNUNET_malloc (dlen);
- if (Z_OK == compress2 ((Bytef *) tmp,
- &dlen, (const Bytef *) data, oldSize, 9))
+ if (Z_OK ==
+ compress2 ((Bytef *) tmp, &dlen, (const Bytef *) data, oldSize, 9))
+ {
+ if (dlen < oldSize)
{
- if (dlen < oldSize)
- {
- *result = tmp;
- *newSize = dlen;
- return GNUNET_YES;
- }
+ *result = tmp;
+ *newSize = dlen;
+ return GNUNET_YES;
}
+ }
GNUNET_free (tmp);
return GNUNET_NO;
}
{
/**
* Meta data type. Corresponds to an 'enum EXTRACTOR_MetaType'
- */
+ */
uint32_t type;
/**
{
struct GNUNET_CONTAINER_MetaData *vmd;
struct MetaItem *pos;
- struct MetaDataHeader *hdr;
+ 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 0;
if (md->sbuf != NULL)
+ {
+ /* try to use serialization cache */
+ if (md->sbuf_size <= max)
{
- /* try to use serialization cache */
- if (md->sbuf_size <= max)
- {
- if (NULL == *target)
- *target = GNUNET_malloc (md->sbuf_size);
- memcpy (*target,
- md->sbuf,
- md->sbuf_size);
- return md->sbuf_size;
- }
- if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART))
- return GNUNET_SYSERR; /* can say that this will fail */
- /* need to compute a partial serialization, sbuf useless ... */
+ if (NULL == *target)
+ *target = GNUNET_malloc (md->sbuf_size);
+ memcpy (*target, md->sbuf, md->sbuf_size);
+ return md->sbuf_size;
}
-
-
+ if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART))
+ 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)
- {
- msize += sizeof (struct MetaDataEntry);
- msize += pos->data_size;
- if (pos->plugin_name != NULL)
- msize += strlen (pos->plugin_name) + 1;
- if (pos->mime_type != NULL)
- msize += strlen (pos->mime_type) + 1;
- pos = pos->next;
- }
+ {
+ msize += sizeof (struct MetaDataEntry);
+ msize += pos->data_size;
+ if (pos->plugin_name != NULL)
+ msize += strlen (pos->plugin_name) + 1;
+ if (pos->mime_type != NULL)
+ msize += strlen (pos->mime_type) + 1;
+ pos = pos->next;
+ }
size = (size_t) msize;
if (size != msize)
- {
- GNUNET_break (0); /* integer overflow */
- return GNUNET_SYSERR;
- }
+ {
+ GNUNET_break (0); /* integer overflow */
+ return GNUNET_SYSERR;
+ }
if (size >= GNUNET_MAX_MALLOC_CHECKED)
- {
- /* too large to be processed */
- return GNUNET_SYSERR;
- }
+ {
+ /* too large to be processed */
+ return GNUNET_SYSERR;
+ }
ent = GNUNET_malloc (size);
mdata = (char *) &ent[md->item_count];
- off = size - (md->item_count * sizeof(struct MetaDataEntry));
+ off = size - (md->item_count * sizeof (struct MetaDataEntry));
i = 0;
pos = md->items;
while (NULL != pos)
- {
- ent[i].type = htonl ((uint32_t) pos->type);
- ent[i].format = htonl ((uint32_t) pos->format);
- ent[i].data_size = htonl ((uint32_t) pos->data_size);
- if (pos->plugin_name == NULL)
- plen = 0;
- else
- plen = strlen (pos->plugin_name) + 1;
- ent[i].plugin_name_len = htonl ( (uint32_t) plen);
- if (pos->mime_type == NULL)
- mlen = 0;
- else
- mlen = strlen (pos->mime_type) + 1;
- ent[i].mime_type_len = htonl ((uint32_t) mlen);
- off -= pos->data_size;
- memcpy (&mdata[off], pos->data, pos->data_size);
- off -= plen;
- if (pos->plugin_name != NULL)
- memcpy (&mdata[off], pos->plugin_name, plen);
- off -= mlen;
- if (pos->mime_type != NULL)
- memcpy (&mdata[off], pos->mime_type, mlen);
- i++;
- pos = pos->next;
- }
+ {
+ ent[i].type = htonl ((uint32_t) pos->type);
+ ent[i].format = htonl ((uint32_t) pos->format);
+ ent[i].data_size = htonl ((uint32_t) pos->data_size);
+ if (pos->plugin_name == NULL)
+ plen = 0;
+ else
+ plen = strlen (pos->plugin_name) + 1;
+ ent[i].plugin_name_len = htonl ((uint32_t) plen);
+ if (pos->mime_type == NULL)
+ mlen = 0;
+ else
+ mlen = strlen (pos->mime_type) + 1;
+ ent[i].mime_type_len = htonl ((uint32_t) mlen);
+ off -= pos->data_size;
+ memcpy (&mdata[off], pos->data, pos->data_size);
+ off -= plen;
+ if (pos->plugin_name != NULL)
+ memcpy (&mdata[off], pos->plugin_name, plen);
+ off -= mlen;
+ if (pos->mime_type != NULL)
+ memcpy (&mdata[off], pos->mime_type, mlen);
+ i++;
+ pos = pos->next;
+ }
GNUNET_assert (off == 0);
clen = 0;
i = 0;
pos = md->items;
while (pos != NULL)
- {
- comp = GNUNET_NO;
- if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS))
- comp = try_compression ((const char*) &ent[i],
- left,
- &cdata,
- &clen);
-
- if ( (md->sbuf == NULL) &&
- (i == 0) )
- {
- /* fill 'sbuf'; this "modifies" md, but since this is only
- an internal cache we will cast away the 'const' instead
- of making the API look strange. */
- vmd = (struct GNUNET_CONTAINER_MetaData*) md;
- hdr = GNUNET_malloc (left + sizeof (struct MetaDataHeader));
- hdr->size = htonl (left);
- hdr->entries = htonl (md->item_count);
- if (GNUNET_YES == comp)
- {
- GNUNET_assert (clen < left);
- hdr->version = htonl (2 | HEADER_COMPRESSED);
- memcpy (&hdr[1],
- cdata,
- clen);
- vmd->sbuf_size = clen + sizeof (struct MetaDataHeader);
- }
- else
- {
- hdr->version = htonl (2);
- memcpy (&hdr[1],
- &ent[0],
- left);
- vmd->sbuf_size = left + sizeof (struct MetaDataHeader);
- }
- vmd->sbuf = (char*) hdr;
- }
-
- if ( ( (left + sizeof (struct MetaDataHeader)) <= max) ||
- ( (comp == GNUNET_YES) &&
- (clen <= max)) )
- {
- /* 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;
- }
- hdr->version = htonl (2 | HEADER_COMPRESSED);
- hdr->size = htonl (left);
- hdr->entries = htonl (md->item_count - i);
- memcpy (&(*target)[sizeof(struct MetaDataHeader)],
- cdata,
- clen);
- GNUNET_free (cdata);
- GNUNET_free (ent);
- return clen + sizeof (struct MetaDataHeader);
- }
- else
- {
- hdr = (struct MetaDataHeader*) *target;
- if (hdr == NULL)
- {
- hdr = GNUNET_malloc (left + sizeof (struct MetaDataHeader));
- *target = (char*) hdr;
- }
- hdr->version = htonl (2);
- hdr->entries = htonl (md->item_count - i);
- hdr->size = htonl (left);
- memcpy (&(*target)[sizeof(struct MetaDataHeader)],
- &ent[i],
- left);
- GNUNET_free (ent);
- return left + sizeof (struct MetaDataHeader);
- }
- }
-
- if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART))
- {
- /* does not fit! */
- GNUNET_free (ent);
- return GNUNET_SYSERR;
- }
-
- /* next iteration: ignore the corresponding meta data at the
- end and try again without it */
- left -= sizeof (struct MetaDataEntry);
- left -= pos->data_size;
- if (pos->plugin_name != NULL)
- left -= strlen (pos->plugin_name) + 1;
- if (pos->mime_type != NULL)
- left -= strlen (pos->mime_type) + 1;
- pos = pos->next;
- i++;
+ {
+ comp = GNUNET_NO;
+ if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS))
+ comp = try_compression ((const char *) &ent[i], left, &cdata, &clen);
+
+ if ((md->sbuf == NULL) && (i == 0))
+ {
+ /* fill 'sbuf'; this "modifies" md, but since this is only
+ * an internal cache we will cast away the 'const' instead
+ * of making the API look strange. */
+ vmd = (struct GNUNET_CONTAINER_MetaData *) md;
+ hdr = GNUNET_malloc (left + sizeof (struct MetaDataHeader));
+ hdr->size = htonl (left);
+ hdr->entries = htonl (md->item_count);
+ if (GNUNET_YES == comp)
+ {
+ GNUNET_assert (clen < left);
+ hdr->version = htonl (2 | HEADER_COMPRESSED);
+ memcpy (&hdr[1], cdata, clen);
+ vmd->sbuf_size = clen + sizeof (struct MetaDataHeader);
+ }
+ else
+ {
+ hdr->version = htonl (2);
+ memcpy (&hdr[1], &ent[0], left);
+ vmd->sbuf_size = left + sizeof (struct MetaDataHeader);
+ }
+ vmd->sbuf = (char *) hdr;
}
- GNUNET_free (ent);
- /* nothing fit, only write header! */
- hdr = (struct MetaDataHeader*) *target;
- if (hdr == NULL)
+ if (((left + sizeof (struct MetaDataHeader)) <= max) ||
+ ((comp == GNUNET_YES) && (clen <= max)))
+ {
+ /* success, this now fits! */
+ if (GNUNET_YES == comp)
+ {
+ 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 (&dst[sizeof (struct MetaDataHeader)], cdata, clen);
+ GNUNET_free (cdata);
+ GNUNET_free (ent);
+ rlen = clen + sizeof (struct MetaDataHeader);
+ }
+ else
+ {
+ 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 (&dst[sizeof (struct MetaDataHeader)], &ent[i], left);
+ GNUNET_free (ent);
+ 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))
{
- hdr = GNUNET_malloc (sizeof (struct MetaDataHeader));
- *target = (char*) hdr;
+ /* does not fit! */
+ GNUNET_free (ent);
+ return GNUNET_SYSERR;
}
- hdr->version = htonl (2);
- hdr->entries = htonl (0);
- hdr->size = htonl (0);
+
+ /* next iteration: ignore the corresponding meta data at the
+ * end and try again without it */
+ left -= sizeof (struct MetaDataEntry);
+ left -= pos->data_size;
+ if (pos->plugin_name != NULL)
+ left -= strlen (pos->plugin_name) + 1;
+ if (pos->mime_type != NULL)
+ left -= strlen (pos->mime_type) + 1;
+ pos = pos->next;
+ i++;
+ }
+ GNUNET_free (ent);
+
+ /* nothing fit, only write header! */
+ 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);
}
* @return number of bytes needed for serialization, -1 on error
*/
ssize_t
-GNUNET_CONTAINER_meta_data_get_serialized_size (const struct GNUNET_CONTAINER_MetaData *md)
+GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
+ GNUNET_CONTAINER_MetaData *md)
{
ssize_t ret;
char *ptr;
-
+
if (md->sbuf != NULL)
return md->sbuf_size;
ptr = NULL;
- ret = GNUNET_CONTAINER_meta_data_serialize (md,
- &ptr,
- GNUNET_MAX_MALLOC_CHECKED,
- GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);
+ ret =
+ GNUNET_CONTAINER_meta_data_serialize (md, &ptr, GNUNET_MAX_MALLOC_CHECKED,
+ GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);
if (ret != -1)
GNUNET_free (ptr);
return ret;
* @return NULL on error
*/
static char *
-decompress (const char *input,
- size_t inputSize,
- size_t outputSize)
+decompress (const char *input, size_t inputSize, size_t outputSize)
{
char *output;
uLongf olen;
olen = outputSize;
output = GNUNET_malloc (olen);
- if (Z_OK == uncompress ((Bytef *) output,
- &olen, (const Bytef *) input, inputSize))
- {
- return output;
- }
+ if (Z_OK ==
+ uncompress ((Bytef *) output, &olen, (const Bytef *) input, inputSize))
+ {
+ return output;
+ }
else
- {
- GNUNET_free (output);
- return NULL;
- }
+ {
+ GNUNET_free (output);
+ return NULL;
+ }
}
if (size < sizeof (struct MetaDataHeader))
return NULL;
- memcpy (&hdr,
- input,
- sizeof (struct MetaDataHeader));
+ memcpy (&hdr, input, sizeof (struct MetaDataHeader));
version = ntohl (hdr.version) & HEADER_VERSION_MASK;
compressed = (ntohl (hdr.version) & HEADER_COMPRESSED) != 0;
if (version == 1)
- return NULL; /* null pointer */
+ return NULL; /* null pointer */
if (version != 2)
- {
- GNUNET_break_op (0); /* unsupported version */
- return NULL;
- }
+ {
+ GNUNET_break_op (0); /* unsupported version */
+ return NULL;
+ }
ic = ntohl (hdr.entries);
- dataSize = ntohl (hdr.size);
+ dataSize = ntohl (hdr.size);
if ((sizeof (struct MetaDataEntry) * ic) > dataSize)
- {
- GNUNET_break_op (0);
- return NULL;
- }
+ {
+ GNUNET_break_op (0);
+ return NULL;
+ }
if (compressed)
+ {
+ if (dataSize >= GNUNET_MAX_MALLOC_CHECKED)
{
- if (dataSize >= GNUNET_MAX_MALLOC_CHECKED)
- {
- /* make sure we don't blow our memory limit because of a mal-formed
- message... */
- GNUNET_break_op (0);
- return NULL;
- }
- data =
+ /* make sure we don't blow our memory limit because of a mal-formed
+ * message... */
+ GNUNET_break_op (0);
+ return NULL;
+ }
+ data =
decompress ((const char *) &input[sizeof (struct MetaDataHeader)],
size - sizeof (struct MetaDataHeader), dataSize);
- if (data == NULL)
- {
- GNUNET_break_op (0);
- return NULL;
- }
- cdata = data;
+ if (data == NULL)
+ {
+ GNUNET_break_op (0);
+ return NULL;
}
+ cdata = data;
+ }
else
+ {
+ data = NULL;
+ cdata = (const char *) &input[sizeof (struct MetaDataHeader)];
+ if (dataSize != size - sizeof (struct MetaDataHeader))
{
- data = NULL;
- cdata = (const char *) &input[sizeof (struct MetaDataHeader)];
- if (dataSize != size - sizeof (struct MetaDataHeader))
- {
- GNUNET_break_op (0);
- return NULL;
- }
+ GNUNET_break_op (0);
+ return NULL;
}
+ }
md = GNUNET_CONTAINER_meta_data_create ();
left = dataSize - ic * sizeof (struct MetaDataEntry);
mdata = &cdata[ic * sizeof (struct MetaDataEntry)];
- for (i=0;i<ic;i++)
+ for (i = 0; i < ic; i++)
+ {
+ memcpy (&ent, &cdata[i * sizeof (struct MetaDataEntry)],
+ sizeof (struct MetaDataEntry));
+ format = (enum EXTRACTOR_MetaFormat) ntohl (ent.format);
+ if ((format != EXTRACTOR_METAFORMAT_UTF8) &&
+ (format != EXTRACTOR_METAFORMAT_C_STRING) &&
+ (format != EXTRACTOR_METAFORMAT_BINARY))
{
- memcpy (&ent,
- &cdata[i * sizeof(struct MetaDataEntry)],
- sizeof (struct MetaDataEntry));
- format = (enum EXTRACTOR_MetaFormat) ntohl (ent.format);
- if ( (format != EXTRACTOR_METAFORMAT_UTF8) &&
- (format != EXTRACTOR_METAFORMAT_C_STRING) &&
- (format != EXTRACTOR_METAFORMAT_BINARY) )
- {
- GNUNET_break_op (0);
- break;
- }
- dlen = ntohl (ent.data_size);
- plen = ntohl (ent.plugin_name_len);
- mlen = ntohl (ent.mime_type_len);
- if (dlen > left)
- {
- GNUNET_break_op (0);
- break;
- }
- left -= dlen;
- meta_data = &mdata[left];
- if ( (format == EXTRACTOR_METAFORMAT_UTF8) ||
- (format == EXTRACTOR_METAFORMAT_C_STRING) )
- {
- if ( (dlen == 0) ||
- (mdata[left + dlen - 1] != '\0') )
- {
- GNUNET_break_op (0);
- break;
- }
- }
- if (plen > left)
- {
- GNUNET_break_op (0);
- break;
- }
- left -= plen;
- if ( (plen > 0) &&
- (mdata[left + plen - 1] != '\0') )
- {
- GNUNET_break_op (0);
- break;
- }
- if (plen == 0)
- plugin_name = NULL;
- else
- plugin_name = &mdata[left];
-
- if (mlen > left)
- {
- GNUNET_break_op (0);
- break;
- }
- left -= mlen;
- if ( (mlen > 0) &&
- (mdata[left + mlen - 1] != '\0') )
- {
- GNUNET_break_op (0);
- break;
- }
- if (mlen == 0)
- mime_type = NULL;
- else
- mime_type = &mdata[left];
- GNUNET_CONTAINER_meta_data_insert (md,
- plugin_name,
- (enum EXTRACTOR_MetaType) ntohl (ent.type),
- format,
- mime_type,
- meta_data,
- dlen);
+ GNUNET_break_op (0);
+ break;
+ }
+ dlen = ntohl (ent.data_size);
+ plen = ntohl (ent.plugin_name_len);
+ mlen = ntohl (ent.mime_type_len);
+ if (dlen > left)
+ {
+ GNUNET_break_op (0);
+ break;
+ }
+ left -= dlen;
+ meta_data = &mdata[left];
+ if ((format == EXTRACTOR_METAFORMAT_UTF8) ||
+ (format == EXTRACTOR_METAFORMAT_C_STRING))
+ {
+ if ((dlen == 0) || (mdata[left + dlen - 1] != '\0'))
+ {
+ GNUNET_break_op (0);
+ break;
+ }
+ }
+ if (plen > left)
+ {
+ GNUNET_break_op (0);
+ break;
+ }
+ left -= plen;
+ if ((plen > 0) && (mdata[left + plen - 1] != '\0'))
+ {
+ GNUNET_break_op (0);
+ break;
+ }
+ if (plen == 0)
+ plugin_name = NULL;
+ else
+ plugin_name = &mdata[left];
+
+ if (mlen > left)
+ {
+ GNUNET_break_op (0);
+ break;
+ }
+ left -= mlen;
+ if ((mlen > 0) && (mdata[left + mlen - 1] != '\0'))
+ {
+ GNUNET_break_op (0);
+ break;
}
- GNUNET_free_non_null (data);
+ if (mlen == 0)
+ mime_type = NULL;
+ else
+ mime_type = &mdata[left];
+ GNUNET_CONTAINER_meta_data_insert (md, plugin_name,
+ (enum EXTRACTOR_MetaType)
+ ntohl (ent.type), format, mime_type,
+ meta_data, dlen);
+ }
+ GNUNET_free_non_null (data);
return md;
}