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

📄 xdgmimecache.c

📁 linux下电话本所依赖的一些图形库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- mode: C; c-file-style: "gnu" -*- *//* xdgmimealias.c: Private file.  mmappable caches for mime data * * More info can be found at http://www.freedesktop.org/standards/ * * Copyright (C) 2005  Matthias Clasen <mclasen@redhat.com> * * Licensed under the Academic Free License version 2.0 * Or under the following terms: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <unistd.h>#include <fnmatch.h>#include <assert.h>#include <netinet/in.h> /* for ntohl/ntohs */#ifdef HAVE_MMAP#include <sys/mman.h>#endif#include <sys/stat.h>#include <sys/types.h>#include "xdgmimecache.h"#include "xdgmimeint.h"#ifndef MAX#define MAX(a,b) ((a) > (b) ? (a) : (b))#endif#ifndef	FALSE#define	FALSE	(0)#endif#ifndef	TRUE#define	TRUE	(!FALSE)#endif#ifndef _O_BINARY#define _O_BINARY 0#endif#ifndef MAP_FAILED#define MAP_FAILED ((void *) -1)#endif#define MAJOR_VERSION 1#define MINOR_VERSION 0extern XdgMimeCache **caches;extern int n_caches;struct _XdgMimeCache{  int ref_count;  size_t  size;  char   *buffer;};#define GET_UINT16(cache,offset) (ntohs(*(xdg_uint16_t*)((cache) + (offset))))#define GET_UINT32(cache,offset) (ntohl(*(xdg_uint32_t*)((cache) + (offset))))XdgMimeCache *_xdg_mime_cache_ref (XdgMimeCache *cache){  cache->ref_count++;  return cache;}void_xdg_mime_cache_unref (XdgMimeCache *cache){  cache->ref_count--;  if (cache->ref_count == 0)    {#ifdef HAVE_MMAP      munmap (cache->buffer, cache->size);#endif      free (cache);    }}XdgMimeCache *_xdg_mime_cache_new_from_file (const char *file_name){  XdgMimeCache *cache = NULL;#ifdef HAVE_MMAP  int fd = -1;  struct stat st;  char *buffer = NULL;  /* Open the file and map it into memory */  fd = open (file_name, O_RDONLY|_O_BINARY, 0);  if (fd < 0)    return NULL;    if (fstat (fd, &st) < 0 || st.st_size < 4)    goto done;  buffer = (char *) mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);  if (buffer == MAP_FAILED)    goto done;  /* Verify version */  if (GET_UINT16 (buffer, 0) != MAJOR_VERSION ||      GET_UINT16 (buffer, 2) != MINOR_VERSION)    {      munmap (buffer, st.st_size);      goto done;    }    cache = (XdgMimeCache *) malloc (sizeof (XdgMimeCache));  cache->ref_count = 1;  cache->buffer = buffer;  cache->size = st.st_size; done:  if (fd != -1)    close (fd);#endif  /* HAVE_MMAP */  return cache;}static intcache_magic_matchlet_compare_to_data (XdgMimeCache *cache, 				      xdg_uint32_t  offset,				      const void   *data,				      size_t        len){  xdg_uint32_t range_start = GET_UINT32 (cache->buffer, offset);  xdg_uint32_t range_length = GET_UINT32 (cache->buffer, offset + 4);  xdg_uint32_t data_length = GET_UINT32 (cache->buffer, offset + 12);  xdg_uint32_t data_offset = GET_UINT32 (cache->buffer, offset + 16);  xdg_uint32_t mask_offset = GET_UINT32 (cache->buffer, offset + 20);    int i, j;  for (i = range_start; i <= range_start + range_length; i++)    {      int valid_matchlet = TRUE;            if (i + data_length > len)	return FALSE;      if (mask_offset)	{	  for (j = 0; j < data_length; j++)	    {	      if ((cache->buffer[data_offset + j] & cache->buffer[mask_offset + j]) !=		  ((((unsigned char *) data)[j + i]) & cache->buffer[mask_offset + j]))		{		  valid_matchlet = FALSE;		  break;		}	    }	}      else	{	  for (j = 0; j < data_length; j++)	    {	      if (cache->buffer[data_offset + j] != ((unsigned char *) data)[j + i])		{		  valid_matchlet = FALSE;		  break;		}	    }	}            if (valid_matchlet)	return TRUE;    }    return FALSE;  }static intcache_magic_matchlet_compare (XdgMimeCache *cache, 			      xdg_uint32_t  offset,			      const void   *data,			      size_t        len){  xdg_uint32_t n_children = GET_UINT32 (cache->buffer, offset + 24);  xdg_uint32_t child_offset = GET_UINT32 (cache->buffer, offset + 28);  int i;    if (cache_magic_matchlet_compare_to_data (cache, offset, data, len))    {      if (n_children == 0)	return TRUE;            for (i = 0; i < n_children; i++)	{	  if (cache_magic_matchlet_compare (cache, child_offset + 32 * i,					    data, len))	    return TRUE;	}    }    return FALSE;  }static const char *cache_magic_compare_to_data (XdgMimeCache *cache, 			     xdg_uint32_t  offset,			     const void   *data, 			     size_t        len, 			     int          *prio){  xdg_uint32_t priority = GET_UINT32 (cache->buffer, offset);  xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, offset + 4);  xdg_uint32_t n_matchlets = GET_UINT32 (cache->buffer, offset + 8);  xdg_uint32_t matchlet_offset = GET_UINT32 (cache->buffer, offset + 12);  int i;  for (i = 0; i < n_matchlets; i++)    {      if (cache_magic_matchlet_compare (cache, matchlet_offset + i * 32, 					data, len))	{	  *prio = priority;	  	  return cache->buffer + mimetype_offset;	}    }  return NULL;}static const char *cache_magic_lookup_data (XdgMimeCache *cache, 			 const void   *data, 			 size_t        len, 			 int          *prio){  xdg_uint32_t list_offset;  xdg_uint32_t n_entries;  xdg_uint32_t offset;  int j;  *prio = 0;  list_offset = GET_UINT32 (cache->buffer, 24);  n_entries = GET_UINT32 (cache->buffer, list_offset);  offset = GET_UINT32 (cache->buffer, list_offset + 8);    for (j = 0; j < n_entries; j++)    {      const char *match = cache_magic_compare_to_data (cache, offset + 16 * j, 						       data, len, prio);      if (match)	return match;    }  return NULL;}static const char *cache_alias_lookup (const char *alias){  const char *ptr;  int i, min, max, mid, cmp;  for (i = 0; i < n_caches; i++)    {      XdgMimeCache *cache = caches[i];      xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, 4 );      xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset);      xdg_uint32_t offset;      min = 0;       max = n_entries - 1;      while (max >= min) 	{	  mid = (min + max) / 2;	  offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid);	  ptr = cache->buffer + offset;	  cmp = strcmp (ptr, alias);	  	  if (cmp < 0)	    min = mid + 1;	  else if (cmp > 0)	    max = mid - 1;	  else	    {	      offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid + 4);	      return cache->buffer + offset;	    }	}    }  return NULL;}static const char *cache_glob_lookup_literal (const char *file_name){  const char *ptr;  int i, min, max, mid, cmp;  for (i = 0; i < n_caches; i++)    {      XdgMimeCache *cache = caches[i];      xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, 12);      xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset);      xdg_uint32_t offset;      min = 0;       max = n_entries - 1;      while (max >= min) 	{	  mid = (min + max) / 2;	  offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid);	  ptr = cache->buffer + offset;	  cmp = strcmp (ptr, file_name);	  	  if (cmp < 0)	    min = mid + 1;	  else if (cmp > 0)	    max = mid - 1;	  else	    {	      offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid + 4);	      return  cache->buffer + offset;	    }	}    }  return NULL;}static const char *cache_glob_lookup_fnmatch (const char *file_name){  const char *mime_type;  const char *ptr;  int i, j;  for (i = 0; i < n_caches; i++)    {      XdgMimeCache *cache = caches[i];      xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, 20);      xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset);      for (j = 0; j < n_entries; j++)	{	  xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j);	  xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j + 4);	  ptr = cache->buffer + offset;	  mime_type = cache->buffer + mimetype_offset;	  /* FIXME: Not UTF-8 safe */	  if (fnmatch (ptr, file_name, 0) == 0)	    return mime_type;	}    }  return NULL;}static const char *cache_glob_node_lookup_suffix (XdgMimeCache *cache,			       xdg_uint32_t  n_entries,			       xdg_uint32_t  offset,			       const char   *suffix, 			       int           ignore_case){  xdg_unichar_t character;  xdg_unichar_t match_char;

⌨️ 快捷键说明

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