/*
This file is part of GNUnet.
(C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 2, or (at your
option) any later version.
GNUnet is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/**
* @file util/container_meta_data.c
* @brief Storing of meta data
* @author Christian Grothoff
*/
#include "platform.h"
#include "gnunet_common.h"
#include "gnunet_container_lib.h"
#include "gnunet_strings_lib.h"
#include "gnunet_time_lib.h"
#include <extractor.h>
#include <zlib.h>
#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
/**
* Meta data item.
*/
struct MetaItem
{
/**
* This is a doubly linked list.
*/
struct MetaItem *next;
/**
* This is a doubly linked list.
*/
struct MetaItem *prev;
/**
* Name of the extracting plugin.
*/
char *plugin_name;
/**
* Mime-type of data.
*/
char *mime_type;
/**
* The actual meta data.
*/
char *data;
/**
* Number of bytes in 'data'.
*/
size_t data_size;
/**
* Type of the meta data.
*/
enum EXTRACTOR_MetaType type;
/**
* Format of the meta data.
*/
enum EXTRACTOR_MetaFormat format;
};
/**
* Meta data to associate with a file, directory or namespace.
*/
struct GNUNET_CONTAINER_MetaData
{
/**
* Head of linked list of the meta data items.
*/
struct MetaItem *items_head;
/**
* Tail of linked list of the meta data items.
*/
struct MetaItem *items_tail;
/**
* Complete serialized and compressed buffer of the items.
* NULL if we have not computed that buffer yet.
*/
char *sbuf;
/**
* Number of bytes in 'sbuf'. 0 if the buffer is stale.
*/
size_t sbuf_size;
/**
* Number of items in the linked list.
*/
unsigned int item_count;
};
/**
* Create a fresh struct CONTAINER_MetaData token.
*
* @return empty meta-data container
*/
struct GNUNET_CONTAINER_MetaData *
GNUNET_CONTAINER_meta_data_create ()
{
return GNUNET_malloc (sizeof (struct GNUNET_CONTAINER_MetaData));
}
/**
* Free meta data item.
*
* @param mi item to free
*/
static void
meta_item_free (struct MetaItem *mi)
{
GNUNET_free_non_null (mi->plugin_name);
GNUNET_free_non_null (mi->mime_type);
GNUNET_free_non_null (mi->data);
GNUNET_free (mi);
}
/**
* The meta data has changed, invalidate its serialization
* buffer.
*
* @param md meta data that changed
*/
static void
invalidate_sbuf (struct GNUNET_CONTAINER_MetaData *md)
{
if (NULL == md->sbuf)
return;
GNUNET_free (md->sbuf);
md->sbuf = NULL;
md->sbuf_size = 0;
}
/**
* Free meta data.
*
* @param md what to free
*/
void
GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData *md)
{
struct MetaItem *pos;
if (NULL == md)
return;
while (NULL != (pos = md->items_head))
{
GNUNET_CONTAINER_DLL_remove (md->items_head, md->items_tail, pos);
meta_item_free (pos);
}
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 *mi;
if (NULL == md)
return;
while (NULL != (mi = md->items_head))
{
GNUNET_CONTAINER_DLL_remove (md->items_head, md->items_tail, mi);
meta_item_free (mi);
}
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
* include the mime types and plugins names in this
* consideration).
*
* @param md1 first value to check
* @param md2 other value to check
* @return GNUNET_YES if they are equal
*/
int
GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData
*md1,
const struct GNUNET_CONTAINER_MetaData
*md2)