407
414
for (j = 0; j < n_entries && n < n_mime_types; j++)
409
xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j);
410
xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j + 4);
416
xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j);
417
xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j + 4);
418
int weight = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j + 8);
411
419
ptr = cache->buffer + offset;
412
420
mime_type = cache->buffer + mimetype_offset;
414
422
/* FIXME: Not UTF-8 safe */
415
423
if (fnmatch (ptr, file_name, 0) == 0)
416
mime_types[n++] = mime_type;
425
mime_types[n].mime = mime_type;
426
mime_types[n].weight = weight;
427
cache_glob_node_lookup_suffix (XdgMimeCache *cache,
428
xdg_uint32_t n_entries,
432
const char *mime_types[],
439
cache_glob_node_lookup_suffix (XdgMimeCache *cache,
440
xdg_uint32_t n_entries,
442
xdg_unichar_t *file_name,
445
MimeWeight mime_types[],
435
448
xdg_unichar_t character;
436
449
xdg_unichar_t match_char;
437
450
xdg_uint32_t mimetype_offset;
438
451
xdg_uint32_t n_children;
439
452
xdg_uint32_t child_offset;
441
455
int min, max, mid, n, i;
443
character = _xdg_utf8_to_ucs4 (suffix);
457
character = file_name[len - 1];
445
459
character = _xdg_ucs4_to_lower (character);
461
assert (character != 0);
448
464
max = n_entries - 1;
449
465
while (max >= min)
451
467
mid = (min + max) / 2;
453
match_char = GET_UINT32 (cache->buffer, offset + 16 * mid);
468
match_char = GET_UINT32 (cache->buffer, offset + 12 * mid);
455
469
if (match_char < character)
457
471
else if (match_char > character)
461
suffix = _xdg_utf8_next_char (suffix);
464
mimetype_offset = GET_UINT32 (cache->buffer, offset + 16 * mid + 4);
466
mime_types[n++] = cache->buffer + mimetype_offset;
468
n_children = GET_UINT32 (cache->buffer, offset + 16 * mid + 8);
469
child_offset = GET_UINT32 (cache->buffer, offset + 16 * mid + 12);
477
n_children = GET_UINT32 (cache->buffer, offset + 12 * mid + 4);
478
child_offset = GET_UINT32 (cache->buffer, offset + 12 * mid + 8);
482
n = cache_glob_node_lookup_suffix (cache,
483
n_children, child_offset,
471
492
while (n < n_mime_types && i < n_children)
473
match_char = GET_UINT32 (cache->buffer, child_offset + 16 * i);
474
mimetype_offset = GET_UINT32 (cache->buffer, offset + 16 * i + 4);
494
match_char = GET_UINT32 (cache->buffer, child_offset + 12 * i);
475
495
if (match_char != 0)
478
mime_types[n++] = cache->buffer + mimetype_offset;
498
mimetype_offset = GET_UINT32 (cache->buffer, child_offset + 12 * i + 4);
499
weight = GET_UINT32 (cache->buffer, child_offset + 12 * i + 8);
501
mime_types[n].mime = cache->buffer + mimetype_offset;
502
mime_types[n].weight = weight;
486
n_children = GET_UINT32 (cache->buffer, offset + 16 * mid + 8);
487
child_offset = GET_UINT32 (cache->buffer, offset + 16 * mid + 12);
489
return cache_glob_node_lookup_suffix (cache,
490
n_children, child_offset,
502
cache_glob_lookup_suffix (const char *suffix,
504
const char *mime_types[],
514
cache_glob_lookup_suffix (xdg_unichar_t *file_name,
517
MimeWeight mime_types[],
530
find_stopchars (char *stopchars)
543
static int compare_mime_weight (const void *a, const void *b)
535
for (i = 0; _caches[i]; i++)
537
XdgMimeCache *cache = _caches[i];
539
xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, 16);
540
xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset);
541
xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4);
543
for (j = 0; j < n_entries; j++)
545
xdg_uint32_t match_char = GET_UINT32 (cache->buffer, offset);
547
if (match_char < 128)
549
for (l = 0; l < k; l++)
550
if (stopchars[l] == match_char)
554
stopchars[k] = (char) match_char;
545
const MimeWeight *aa = (const MimeWeight *)a;
546
const MimeWeight *bb = (const MimeWeight *)b;
548
return aa->weight - bb->weight;
568
553
const char *mime_types[],
569
554
int n_mime_types)
557
MimeWeight mimes[10];
575
assert (file_name != NULL);
563
assert (file_name != NULL && n_mime_types > 0);
577
565
/* First, check the literals */
578
566
n = cache_glob_lookup_literal (file_name, mime_types, n_mime_types);
582
find_stopchars (stopchars);
584
/* Next, check suffixes */
585
ptr = strpbrk (file_name, stopchars);
588
n = cache_glob_lookup_suffix (ptr, FALSE, mime_types, n_mime_types);
592
n = cache_glob_lookup_suffix (ptr, TRUE, mime_types, n_mime_types);
596
ptr = strpbrk (ptr + 1, stopchars);
570
ucs4 = _xdg_convert_to_ucs4 (file_name, &len);
571
n = cache_glob_lookup_suffix (ucs4, len, FALSE, mimes, n_mimes);
574
n = cache_glob_lookup_suffix (ucs4, len, TRUE, mimes, n_mimes);
599
577
/* Last, try fnmatch */
600
return cache_glob_lookup_fnmatch (file_name, mime_types, n_mime_types);
579
n = cache_glob_lookup_fnmatch (file_name, mimes, n_mimes);
581
qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight);
583
if (n_mime_types < n)
586
for (i = 0; i < n; i++)
587
mime_types[i] = mimes[i].mime;
865
870
for (j = 0; j < n_entries; j++)
867
xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * i);
868
xdg_uint32_t parents_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * i + 4);
872
xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j);
873
xdg_uint32_t parents_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * j + 4);
870
875
if (strcmp (cache->buffer + mimetype_offset, mime) == 0)
877
xdg_uint32_t parent_mime_offset;
872
878
xdg_uint32_t n_parents = GET_UINT32 (cache->buffer, parents_offset);
874
for (j = 0; j < n_parents; j++)
875
all_parents[p++] = cache->buffer + parents_offset + 4 + 4 * j;
880
for (k = 0; k < n_parents && p < 127; k++)
882
parent_mime_offset = GET_UINT32 (cache->buffer, parents_offset + 4 + 4 * k);
884
/* Don't add same parent multiple times.
885
* This can happen for instance if the same type is listed in multiple directories
887
for (l = 0; l < p; l++)
889
if (strcmp (all_parents[l], cache->buffer + parent_mime_offset) == 0)
894
all_parents[p++] = cache->buffer + parent_mime_offset;
881
all_parents[p++] = 0;
901
all_parents[p++] = NULL;
883
903
result = (char **) malloc (p * sizeof (char *));
884
904
memcpy (result, all_parents, p * sizeof (char *));
910
cache_lookup_icon (const char *mime, int header)
913
int i, min, max, mid, cmp;
915
for (i = 0; _caches[i]; i++)
917
XdgMimeCache *cache = _caches[i];
918
xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, header);
919
xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset);
926
mid = (min + max) / 2;
928
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid);
929
ptr = cache->buffer + offset;
930
cmp = strcmp (ptr, mime);
938
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid + 4);
939
return cache->buffer + offset;
948
_xdg_mime_cache_get_generic_icon (const char *mime)
950
return cache_lookup_icon (mime, 36);
954
_xdg_mime_cache_get_icon (const char *mime)
958
icon = cache_lookup_icon (mime, 32);
961
icon = _xdg_mime_cache_get_generic_icon (mime);
967
dump_glob_node (XdgMimeCache *cache,
971
xdg_unichar_t character;
972
xdg_uint32_t mime_offset;
973
xdg_uint32_t n_children;
974
xdg_uint32_t child_offset;
977
character = GET_UINT32 (cache->buffer, offset);
978
mime_offset = GET_UINT32 (cache->buffer, offset + 4);
979
n_children = GET_UINT32 (cache->buffer, offset + 8);
980
child_offset = GET_UINT32 (cache->buffer, offset + 12);
981
for (i = 0; i < depth; i++)
983
printf ("%c", character);
985
printf (" - %s", cache->buffer + mime_offset);
989
for (i = 0; i < n_children; i++)
990
dump_glob_node (cache, child_offset + 20 * i, depth + 1);
995
_xdg_mime_cache_glob_dump (void)
998
for (i = 0; _caches[i]; i++)
1000
XdgMimeCache *cache = _caches[i];
1001
xdg_uint32_t list_offset;
1002
xdg_uint32_t n_entries;
1003
xdg_uint32_t offset;
1004
list_offset = GET_UINT32 (cache->buffer, 16);
1005
n_entries = GET_UINT32 (cache->buffer, list_offset);
1006
offset = GET_UINT32 (cache->buffer, list_offset + 4);
1007
for (j = 0; j < n_entries; j++)
1008
dump_glob_node (cache, offset + 20 * j, 0);