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

📄 xdgmimecache.c

📁 台湾人开发的Linux下的文件管理器
💻 C
📖 第 1 页 / 共 2 页
字号:
    character = _xdg_ucs4_to_lower ( character );  min = 0;  max = n_entries - 1;  while ( max >= min )  {    mid = ( min + max ) / 2;    match_char = GET_UINT32 ( cache->buffer, offset + 16 * mid );    if ( match_char < character )      min = mid + 1;    else if ( match_char > character )      max = mid - 1;    else    {      suffix = _xdg_utf8_next_char ( suffix );      if ( *suffix == '\0' )      {        mimetype_offset = GET_UINT32 ( cache->buffer, offset + 16 * mid + 4 );        n = 0;        mime_types[ n++ ] = cache->buffer + mimetype_offset;        n_children = GET_UINT32 ( cache->buffer, offset + 16 * mid + 8 );        child_offset = GET_UINT32 ( cache->buffer, offset + 16 * mid + 12 );        i = 0;        while ( n < n_mime_types && i < n_children )        {          match_char = GET_UINT32 ( cache->buffer, child_offset + 16 * i );          mimetype_offset = GET_UINT32 ( cache->buffer, offset + 16 * i + 4 );          if ( match_char != 0 )            break;          mime_types[ n++ ] = cache->buffer + mimetype_offset;          i++;        }        return n;      }      else      {        n_children = GET_UINT32 ( cache->buffer, offset + 16 * mid + 8 );        child_offset = GET_UINT32 ( cache->buffer, offset + 16 * mid + 12 );        return cache_glob_node_lookup_suffix ( cache,                                               n_children, child_offset,                                               suffix, ignore_case,                                               mime_types,                                               n_mime_types );      }    }  }  return 0;}static intcache_glob_lookup_suffix ( const char *suffix,                           int ignore_case,                           const char *mime_types[],                           int n_mime_types ){  int i, n;  for ( i = 0; _caches[ i ]; i++ )  {    XdgMimeCache *cache = _caches[ i ];    xdg_uint32_t list_offset = GET_UINT32 ( cache->buffer, 16 );    xdg_uint32_t n_entries = GET_UINT32 ( cache->buffer, list_offset );    xdg_uint32_t offset = GET_UINT32 ( cache->buffer, list_offset + 4 );    n = cache_glob_node_lookup_suffix ( cache,                                        n_entries, offset,                                        suffix, ignore_case,                                        mime_types,                                        n_mime_types );    if ( n > 0 )      return n;  }  return 0;}static voidfind_stopchars ( char *stopchars ){  int i, j, k, l;  k = 0;  for ( i = 0; _caches[ i ]; i++ )  {    XdgMimeCache *cache = _caches[ i ];    xdg_uint32_t list_offset = GET_UINT32 ( cache->buffer, 16 );    xdg_uint32_t n_entries = GET_UINT32 ( cache->buffer, list_offset );    xdg_uint32_t offset = GET_UINT32 ( cache->buffer, list_offset + 4 );    for ( j = 0; j < n_entries; j++ )    {      xdg_uint32_t match_char = GET_UINT32 ( cache->buffer, offset );      if ( match_char < 128 )      {        for ( l = 0; l < k; l++ )          if ( stopchars[ l ] == match_char )            break;        if ( l == k )        {          stopchars[ k ] = ( char ) match_char;          k++;        }      }      offset += 16;    }  }  stopchars[ k ] = '\0';}static intcache_glob_lookup_file_name ( const char *file_name,                              const char *mime_types[],                              int n_mime_types ){  const char * ptr;  char stopchars[ 128 ];  int n;  assert ( file_name != NULL );  /* First, check the literals */  n = cache_glob_lookup_literal ( file_name, mime_types, n_mime_types );  if ( n > 0 )    return n;  find_stopchars ( stopchars );  /* Next, check suffixes */  ptr = strpbrk ( file_name, stopchars );  while ( ptr )  {    n = cache_glob_lookup_suffix ( ptr, FALSE, mime_types, n_mime_types );    if ( n > 0 )      return n;    n = cache_glob_lookup_suffix ( ptr, TRUE, mime_types, n_mime_types );    if ( n > 0 )      return n;    ptr = strpbrk ( ptr + 1, stopchars );  }  /* Last, try fnmatch */  return cache_glob_lookup_fnmatch ( file_name, mime_types, n_mime_types );}int_xdg_mime_cache_get_max_buffer_extents ( void ){  xdg_uint32_t offset;  xdg_uint32_t max_extent;  int i;  max_extent = 0;  for ( i = 0; _caches[ i ]; i++ )  {    XdgMimeCache *cache = _caches[ i ];    offset = GET_UINT32 ( cache->buffer, 24 );    max_extent = MAX ( max_extent, GET_UINT32 ( cache->buffer, offset + 4 ) );  }  return max_extent;}static const char *cache_get_mime_type_for_data ( const void *data,                               size_t len,                               const char *mime_types[],                               int n_mime_types ){  const char * mime_type;  int i, n, priority;  priority = 0;  mime_type = NULL;  for ( i = 0; _caches[ i ]; i++ )  {    XdgMimeCache *cache = _caches[ i ];    int prio;    const char *match;    match = cache_magic_lookup_data ( cache, data, len, &prio,                                      mime_types, n_mime_types );    if ( prio > priority )    {      priority = prio;      mime_type = match;    }  }  if ( priority > 0 )    return mime_type;  for ( n = 0; n < n_mime_types; n++ )  {    if ( mime_types[ n ] )      return mime_types[ n ];  }  return XDG_MIME_TYPE_UNKNOWN;}const char *_xdg_mime_cache_get_mime_type_for_data ( const void *data,        size_t len ){  return cache_get_mime_type_for_data ( data, len, NULL, 0 );}const char *_xdg_mime_cache_get_mime_type_for_file ( const char *file_name,        struct stat *statbuf ){  const char *mime_type;  const char *mime_types[ 2 ];  FILE *file;  unsigned char *data;  int max_extent;  int bytes_read;  struct stat buf;  const char *base_name;  int n;  if ( file_name == NULL )    return NULL;  if ( ! _xdg_utf8_validate ( file_name ) )    return NULL;  base_name = _xdg_get_base_name ( file_name );  n = cache_glob_lookup_file_name ( base_name, mime_types, 2 );  if ( n == 1 )    return mime_types[ 0 ];  if ( !statbuf )  {    if ( stat ( file_name, &buf ) != 0 )      return XDG_MIME_TYPE_UNKNOWN;    statbuf = &buf;  }  if ( !S_ISREG ( statbuf->st_mode ) )    return XDG_MIME_TYPE_UNKNOWN;  /* FIXME: Need to make sure that max_extent isn't totally broken.  This could   * be large and need getting from a stream instead of just reading it all   * in. */  max_extent = _xdg_mime_cache_get_max_buffer_extents ();  data = malloc ( max_extent );  if ( data == NULL )    return XDG_MIME_TYPE_UNKNOWN;  file = fopen ( file_name, "r" );  if ( file == NULL )  {    free ( data );    return XDG_MIME_TYPE_UNKNOWN;  }  bytes_read = fread ( data, 1, max_extent, file );  if ( ferror ( file ) )  {    free ( data );    fclose ( file );    return XDG_MIME_TYPE_UNKNOWN;  }  mime_type = cache_get_mime_type_for_data ( data, bytes_read,              mime_types, n );  free ( data );  fclose ( file );  return mime_type;}const char *_xdg_mime_cache_get_mime_type_from_file_name ( const char *file_name ){  const char * mime_types[ 2 ];  if ( cache_glob_lookup_file_name ( file_name, mime_types, 2 ) == 1 )    return mime_types[ 0 ];  else    return XDG_MIME_TYPE_UNKNOWN;}#if 1static intis_super_type ( const char *mime ){  int length;  const char *type;  length = strlen ( mime );  type = &( mime[ length - 2 ] );  if ( strcmp ( type, "/*" ) == 0 )    return 1;  return 0;}#endifint_xdg_mime_cache_mime_type_subclass ( const char *mime,                                     const char *base ){  const char * umime, *ubase;  int i, j, min, max, med, cmp;  umime = _xdg_mime_cache_unalias_mime_type ( mime );  ubase = _xdg_mime_cache_unalias_mime_type ( base );  if ( strcmp ( umime, ubase ) == 0 )    return 1;  /* We really want to handle text/ * in GtkFileFilter, so we just   * turn on the supertype matching   */#if 1  /* Handle supertypes */  if ( is_super_type ( ubase ) &&          xdg_mime_media_type_equal ( umime, ubase ) )    return 1;#endif  /*  Handle special cases text/plain and application/octet-stream */  if ( strcmp ( ubase, XDG_MIME_TYPE_PLAIN_TEXT ) == 0 &&          strncmp ( umime, "text/", 5 ) == 0 )    return 1;  if ( strcmp ( ubase, XDG_MIME_TYPE_UNKNOWN ) == 0 )    return 1;  for ( i = 0; _caches[ i ]; i++ )  {    XdgMimeCache *cache = _caches[ i ];    xdg_uint32_t list_offset = GET_UINT32 ( cache->buffer, 8 );    xdg_uint32_t n_entries = GET_UINT32 ( cache->buffer, list_offset );    xdg_uint32_t offset, n_parents, parent_offset;    min = 0;    max = n_entries - 1;    while ( max >= min )    {      med = ( min + max ) / 2;      offset = GET_UINT32 ( cache->buffer, list_offset + 4 + 8 * med );      cmp = strcmp ( cache->buffer + offset, umime );      if ( cmp < 0 )        min = med + 1;      else if ( cmp > 0 )        max = med - 1;      else      {        offset = GET_UINT32 ( cache->buffer, list_offset + 4 + 8 * med + 4 );        n_parents = GET_UINT32 ( cache->buffer, offset );        for ( j = 0; j < n_parents; j++ )        {          parent_offset = GET_UINT32 ( cache->buffer, offset + 4 + 4 * j );          if ( _xdg_mime_cache_mime_type_subclass ( cache->buffer + parent_offset, ubase ) )            return 1;        }        break;      }    }  }  return 0;}const char *_xdg_mime_cache_unalias_mime_type ( const char *mime ){  const char * lookup;  lookup = cache_alias_lookup ( mime );  if ( lookup )    return lookup;  return mime;}char **_xdg_mime_cache_list_mime_parents ( const char *mime ){  int i, j, p;  char *all_parents[ 128 ]; /* we'll stop at 128 */  char **result;  p = 0;  for ( i = 0; _caches[ i ]; i++ )  {    XdgMimeCache *cache = _caches[ i ];    xdg_uint32_t list_offset = GET_UINT32 ( cache->buffer, 8 );    xdg_uint32_t n_entries = GET_UINT32 ( cache->buffer, list_offset );    for ( j = 0; j < n_entries; j++ )    {      xdg_uint32_t mimetype_offset = GET_UINT32 ( cache->buffer, list_offset + 4 + 8 * i );      xdg_uint32_t parents_offset = GET_UINT32 ( cache->buffer, list_offset + 4 + 8 * i + 4 );      if ( strcmp ( cache->buffer + mimetype_offset, mime ) == 0 )      {        xdg_uint32_t n_parents = GET_UINT32 ( cache->buffer, parents_offset );        for ( j = 0; j < n_parents; j++ )          all_parents[ p++ ] = cache->buffer + parents_offset + 4 + 4 * j;        break;      }    }  }  all_parents[ p++ ] = 0;  result = ( char ** ) malloc ( p * sizeof ( char * ) );  memcpy ( result, all_parents, p * sizeof ( char * ) );  return result;}

⌨️ 快捷键说明

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