⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 meta.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 2 页
字号:
/*     This file is part of GNUnet.     (C) 2003, 2004, 2005, 2006, 2008 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/containers/meta.c * @brief Storing of meta data * @author Christian Grothoff */#include "platform.h"#include "gnunet_util.h"#include <extractor.h>#include <zlib.h>#define EXTRA_CHECKS ALLOW_EXTRA_CHECKStypedef struct{  EXTRACTOR_KeywordType type;  char *data;} Item;/** * Meta data to associate with a file, directory or namespace. */typedef struct GNUNET_MetaData{  unsigned int itemCount;  Item *items;} MetaData;/** * Create a fresh MetaData token. */MetaData *GNUNET_meta_data_create (){  MetaData *ret;  ret = GNUNET_malloc (sizeof (MetaData));  ret->items = NULL;  ret->itemCount = 0;  return ret;}/** * Free meta data. */voidGNUNET_meta_data_destroy (MetaData * md){  int i;  if (md == NULL)    return;  for (i = 0; i < md->itemCount; i++)    GNUNET_free (md->items[i].data);  GNUNET_array_grow (md->items, md->itemCount, 0);  GNUNET_free (md);}/** * Add the current time as the publication date * to the meta-data. */voidGNUNET_meta_data_add_publication_date (MetaData * md){  char *dat;  GNUNET_Int32Time t;  GNUNET_get_time_int32 (&t);  GNUNET_meta_data_delete (md, EXTRACTOR_PUBLICATION_DATE, NULL);  dat = GNUNET_int32_time_to_string (&t);  GNUNET_meta_data_insert (md, EXTRACTOR_PUBLICATION_DATE, dat);  GNUNET_free (dat);}/** * Extend metadata. * @return GNUNET_OK on success, GNUNET_SYSERR if this entry already exists */intGNUNET_meta_data_insert (MetaData * md,                         EXTRACTOR_KeywordType type, const char *data){  int idx;  char *p;  GNUNET_GE_ASSERT (NULL, data != NULL);  for (idx = 0; idx < md->itemCount; idx++)    {      if ((md->items[idx].type == type) &&          (0 == strcmp (md->items[idx].data, data)))        return GNUNET_SYSERR;    }  idx = md->itemCount;  GNUNET_array_grow (md->items, md->itemCount, md->itemCount + 1);  md->items[idx].type = type;  md->items[idx].data = p = GNUNET_strdup (data);  /* change OS native dir separators to unix '/' and others to '_' */  if (type == EXTRACTOR_FILENAME)    {      while (*p != '\0')        {          if (*p == DIR_SEPARATOR)            *p = '/';          else if (*p == '\\')            *p = '_';          p++;        }    }  return GNUNET_OK;}/** * Remove an item. * @return GNUNET_OK on success, GNUNET_SYSERR if the item does not exist in md */intGNUNET_meta_data_delete (MetaData * md,                         EXTRACTOR_KeywordType type, const char *data){  int idx;  int ret = GNUNET_SYSERR;  for (idx = 0; idx < md->itemCount; idx++)    {      if ((md->items[idx].type == type) &&          ((data == NULL) || (0 == strcmp (md->items[idx].data, data))))        {          GNUNET_free (md->items[idx].data);          md->items[idx] = md->items[md->itemCount - 1];          GNUNET_array_grow (md->items, md->itemCount, md->itemCount - 1);          if (data == NULL)            {              ret = GNUNET_OK;              continue;            }          return GNUNET_OK;        }    }  return ret;}/** * Iterate over MD entries, excluding thumbnails. * * @return number of entries */intGNUNET_meta_data_get_contents (const MetaData * md,                               GNUNET_MetaDataProcessor iterator,                               void *closure){  int i;  int sub;  sub = 0;  for (i = md->itemCount - 1; i >= 0; i--)    {      if (!EXTRACTOR_isBinaryType (md->items[i].type))        {          if ((iterator != NULL) &&              (GNUNET_OK != iterator (md->items[i].type,                                      md->items[i].data, closure)))            return GNUNET_SYSERR;        }      else        sub++;    }  return md->itemCount - sub;}/** * Iterate over MD entries * * @return number of entries */char *GNUNET_meta_data_get_by_type (const MetaData * md, EXTRACTOR_KeywordType type){  int i;  for (i = md->itemCount - 1; i >= 0; i--)    if (type == md->items[i].type)      return GNUNET_strdup (md->items[i].data);  return NULL;}/** * Iterate over MD entries * * @return number of entries */char *GNUNET_meta_data_get_first_by_types (const MetaData * md, ...){  char *ret;  va_list args;  EXTRACTOR_KeywordType type;  ret = NULL;  va_start (args, md);  while (1)    {      type = va_arg (args, EXTRACTOR_KeywordType);      if (type == -1)        break;      ret = GNUNET_meta_data_get_by_type (md, type);      if (ret != NULL)        break;    }  va_end (args);  return ret;}/** * Get a thumbnail from the meta-data (if present). * * @param thumb will be set to the thumbnail data.  Must be *        freed by the caller! * @return number of bytes in thumbnail, 0 if not available */size_tGNUNET_meta_data_get_thumbnail (const struct GNUNET_MetaData * md,                                unsigned char **thumb){  char *encoded;  int ret;  size_t size;  encoded = GNUNET_meta_data_get_by_type (md, EXTRACTOR_THUMBNAIL_DATA);  if (encoded == NULL)    return 0;  if (strlen (encoded) == 0)    {      GNUNET_free (encoded);      return 0;                 /* invalid */    }  *thumb = NULL;  ret = EXTRACTOR_binaryDecode (encoded, thumb, &size);  GNUNET_free (encoded);  if (ret != 0)    return 0;  return size;}/** * Duplicate MetaData. */MetaData *GNUNET_meta_data_duplicate (const MetaData * md){  int i;  MetaData *ret;  if (md == NULL)    return NULL;  ret = GNUNET_meta_data_create ();  for (i = md->itemCount - 1; i >= 0; i--)    GNUNET_meta_data_insert (ret, md->items[i].type, md->items[i].data);  return ret;}/** * Extract meta-data from a file. * * @return GNUNET_SYSERR on error, otherwise the number *   of meta-data items obtained */intGNUNET_meta_data_extract_from_file (struct GNUNET_GE_Context *ectx,                                    MetaData * md,                                    const char *filename,                                    EXTRACTOR_ExtractorList * extractors){  EXTRACTOR_KeywordList *head;  EXTRACTOR_KeywordList *pos;  int ret;  if (filename == NULL)    return GNUNET_SYSERR;  if (extractors == NULL)    return 0;  head = EXTRACTOR_getKeywords (extractors, filename);  head = EXTRACTOR_removeDuplicateKeywords (head,                                            EXTRACTOR_DUPLICATES_REMOVE_UNKNOWN);  pos = head;  ret = 0;  while (pos != NULL)    {      if (GNUNET_OK ==          GNUNET_meta_data_insert (md, pos->keywordType, pos->keyword))        ret++;      pos = pos->next;    }  EXTRACTOR_freeKeywords (head);  return ret;}static unsigned inttryCompression (char *data, unsigned int oldSize){  char *tmp;  uLongf dlen;#ifdef compressBound  dlen = compressBound (oldSize);#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 */#endif  tmp = GNUNET_malloc (dlen);  if (Z_OK == compress2 ((Bytef *) tmp,                         &dlen, (const Bytef *) data, oldSize, 9))    {      if (dlen < oldSize)        {          memcpy (data, tmp, dlen);          GNUNET_free (tmp);          return dlen;        }    }  GNUNET_free (tmp);  return oldSize;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -