static int _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node, xdg_unichar_t *file_name, int len, int ignore_case, MimeWeight mime_types[], int n_mime_types) { int n; XdgGlobHashNode *node; xdg_unichar_t character; if (glob_hash_node == NULL) return 0; character = file_name[len - 1]; if (ignore_case) character = _xdg_ucs4_to_lower(character); for (node = glob_hash_node; node && character >= node->character; node = node->next) { if (character == node->character) { len--; n = 0; if (len > 0) { n = _xdg_glob_hash_node_lookup_file_name (node->child, file_name, len, ignore_case, mime_types, n_mime_types); } if (n == 0) { if (node->mime_type) { mime_types[n].mime = node->mime_type; mime_types[n].weight = node->weight; n++; } node = node->child; while (n < n_mime_types && node && node->character == 0) { if (node->mime_type) { mime_types[n].mime = node->mime_type; mime_types[n].weight = node->weight; n++; } node = node->next; } } return n; } } return 0; }
static int _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node, const char *file_name, int ignore_case, const char *mime_types[], int n_mime_types) { int n; XdgGlobHashNode *node; xdg_unichar_t character; if (glob_hash_node == NULL) return 0; character = _xdg_utf8_to_ucs4 (file_name); if (ignore_case) character = _xdg_ucs4_to_lower(character); for (node = glob_hash_node; node && character >= node->character; node = node->next) { if (character == node->character) { file_name = _xdg_utf8_next_char (file_name); if (*file_name == '\000') { n = 0; if (node->mime_type) mime_types[n++] = node->mime_type; node = node->child; while (n < n_mime_types && node && node->character == 0) { if (node->mime_type) mime_types[n++] = node->mime_type; node = node->next; } } else { n = _xdg_glob_hash_node_lookup_file_name (node->child, file_name, ignore_case, mime_types, n_mime_types); } return n; } } return 0; }
static int cache_glob_node_lookup_suffix (XdgMimeCache *cache, xdg_uint32_t n_entries, xdg_uint32_t offset, xdg_unichar_t *file_name, int len, int ignore_case, MimeWeight mime_types[], int n_mime_types) { xdg_unichar_t character; xdg_unichar_t match_char; xdg_uint32_t mimetype_offset; xdg_uint32_t n_children; xdg_uint32_t child_offset; int weight; int min, max, mid, n, i; character = file_name[len - 1]; if (ignore_case) character = _xdg_ucs4_to_lower (character); assert (character != 0); min = 0; max = n_entries - 1; while (max >= min) { mid = (min + max) / 2; match_char = GET_UINT32 (cache->buffer, offset + 12 * mid); if (match_char < character) min = mid + 1; else if (match_char > character) max = mid - 1; else { len--; n = 0; n_children = GET_UINT32 (cache->buffer, offset + 12 * mid + 4); child_offset = GET_UINT32 (cache->buffer, offset + 12 * mid + 8); if (len > 0) { n = cache_glob_node_lookup_suffix (cache, n_children, child_offset, file_name, len, ignore_case, mime_types, n_mime_types); } if (n == 0) { i = 0; while (n < (int) n_mime_types && i < (int) n_children) { match_char = GET_UINT32 (cache->buffer, child_offset + 12 * i); if (match_char != 0) break; mimetype_offset = GET_UINT32 (cache->buffer, child_offset + 12 * i + 4); weight = GET_UINT32 (cache->buffer, child_offset + 12 * i + 8); mime_types[n].mime = cache->buffer + mimetype_offset; mime_types[n].weight = weight; n++; i++; } } return n; } } return 0; }
static int cache_glob_node_lookup_suffix (XdgMimeCache *cache, xdg_uint32_t n_entries, xdg_uint32_t offset, const char *suffix, int ignore_case, const char *mime_types[], int n_mime_types) { xdg_unichar_t character; xdg_unichar_t match_char; xdg_uint32_t mimetype_offset; xdg_uint32_t n_children; xdg_uint32_t child_offset; int min, max, mid, n, i; character = _xdg_utf8_to_ucs4 (suffix); if (ignore_case) 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; if (cache->buffer[mimetype_offset]) 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; }