407
415
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);
417
xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j);
418
xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j + 4);
419
int weight = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j + 8);
411
420
ptr = cache->buffer + offset;
412
421
mime_type = cache->buffer + mimetype_offset;
414
423
/* FIXME: Not UTF-8 safe */
415
424
if (fnmatch (ptr, file_name, 0) == 0)
416
mime_types[n++] = mime_type;
426
mime_types[n].mime = mime_type;
427
mime_types[n].weight = weight;
427
cache_glob_node_lookup_suffix (XdgMimeCache *cache,
428
xdg_uint32_t n_entries,
432
const char *mime_types[],
440
cache_glob_node_lookup_suffix (XdgMimeCache *cache,
441
xdg_uint32_t n_entries,
443
const char *file_name,
446
MimeWeight mime_types[],
435
449
xdg_unichar_t character;
436
450
xdg_unichar_t match_char;
437
451
xdg_uint32_t mimetype_offset;
438
452
xdg_uint32_t n_children;
439
453
xdg_uint32_t child_offset;
441
456
int min, max, mid, n, i;
443
character = _xdg_utf8_to_ucs4 (suffix);
458
character = file_name[len - 1];
445
character = _xdg_ucs4_to_lower (character);
460
character = tolower (character);
462
assert (character != 0);
448
465
max = n_entries - 1;
449
466
while (max >= min)
451
468
mid = (min + max) / 2;
453
match_char = GET_UINT32 (cache->buffer, offset + 16 * mid);
469
match_char = GET_UINT32 (cache->buffer, offset + 12 * mid);
455
470
if (match_char < character)
457
472
else if (match_char > character)
461
suffix = _xdg_utf8_next_char (suffix);
464
mimetype_offset = GET_UINT32 (cache->buffer, offset + 16 * mid + 4);
467
mime_types[n++] = cache->buffer + mimetype_offset;
469
n_children = GET_UINT32 (cache->buffer, offset + 16 * mid + 8);
470
child_offset = GET_UINT32 (cache->buffer, offset + 16 * mid + 12);
478
n_children = GET_UINT32 (cache->buffer, offset + 12 * mid + 4);
479
child_offset = GET_UINT32 (cache->buffer, offset + 12 * mid + 8);
483
n = cache_glob_node_lookup_suffix (cache,
484
n_children, child_offset,
472
493
while (n < n_mime_types && i < n_children)
474
match_char = GET_UINT32 (cache->buffer, child_offset + 16 * i);
475
mimetype_offset = GET_UINT32 (cache->buffer, offset + 16 * i + 4);
495
match_char = GET_UINT32 (cache->buffer, child_offset + 12 * i);
476
496
if (match_char != 0)
479
mime_types[n++] = cache->buffer + mimetype_offset;
499
mimetype_offset = GET_UINT32 (cache->buffer, child_offset + 12 * i + 4);
500
weight = GET_UINT32 (cache->buffer, child_offset + 12 * i + 8);
502
mime_types[n].mime = cache->buffer + mimetype_offset;
503
mime_types[n].weight = weight;
487
n_children = GET_UINT32 (cache->buffer, offset + 16 * mid + 8);
488
child_offset = GET_UINT32 (cache->buffer, offset + 16 * mid + 12);
490
return cache_glob_node_lookup_suffix (cache,
491
n_children, child_offset,
503
cache_glob_lookup_suffix (const char *suffix,
515
cache_glob_lookup_suffix (const char *file_name,
505
const char *mime_types[],
518
MimeWeight mime_types[],
506
519
int n_mime_types)
531
find_stopchars (char *stopchars)
544
static int compare_mime_weight (const void *a, const void *b)
536
for (i = 0; _caches[i]; i++)
538
XdgMimeCache *cache = _caches[i];
540
xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, 16);
541
xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset);
542
xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4);
544
for (j = 0; j < n_entries; j++)
546
xdg_uint32_t match_char = GET_UINT32 (cache->buffer, offset);
548
if (match_char < 128)
550
for (l = 0; l < k; l++)
551
if (stopchars[l] == match_char)
555
stopchars[k] = (char) match_char;
546
const MimeWeight *aa = (const MimeWeight *)a;
547
const MimeWeight *bb = (const MimeWeight *)b;
549
return aa->weight - bb->weight;
569
554
const char *mime_types[],
570
555
int n_mime_types)
558
MimeWeight mimes[10];
576
assert (file_name != NULL);
563
assert (file_name != NULL && n_mime_types > 0);
578
565
/* First, check the literals */
579
566
n = cache_glob_lookup_literal (file_name, mime_types, n_mime_types);
583
find_stopchars (stopchars);
585
/* Next, check suffixes */
586
ptr = strpbrk (file_name, stopchars);
589
n = cache_glob_lookup_suffix (ptr, FALSE, mime_types, n_mime_types);
593
n = cache_glob_lookup_suffix (ptr, TRUE, mime_types, n_mime_types);
597
ptr = strpbrk (ptr + 1, stopchars);
570
len = strlen (file_name);
571
n = cache_glob_lookup_suffix (file_name, len, FALSE, mimes, n_mimes);
574
n = cache_glob_lookup_suffix (file_name, len, TRUE, mimes, n_mimes);
600
576
/* Last, try fnmatch */
601
return cache_glob_lookup_fnmatch (file_name, mime_types, n_mime_types);
578
n = cache_glob_lookup_fnmatch (file_name, mimes, n_mimes);
580
qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight);
582
if (n_mime_types < n)
585
for (i = 0; i < n; i++)
586
mime_types[i] = mimes[i].mime;
909
cache_lookup_icon (const char *mime, int header)
912
int i, min, max, mid, cmp;
914
for (i = 0; _caches[i]; i++)
916
XdgMimeCache *cache = _caches[i];
917
xdg_uint32_t list_offset = GET_UINT32 (cache->buffer, header);
918
xdg_uint32_t n_entries = GET_UINT32 (cache->buffer, list_offset);
925
mid = (min + max) / 2;
927
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid);
928
ptr = cache->buffer + offset;
929
cmp = strcmp (ptr, mime);
937
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 8 * mid + 4);
938
return cache->buffer + offset;
947
_xdg_mime_cache_get_generic_icon (const char *mime)
949
return cache_lookup_icon (mime, 36);
953
_xdg_mime_cache_get_icon (const char *mime)
955
return cache_lookup_icon (mime, 32);
959
dump_glob_node (XdgMimeCache *cache,
963
xdg_unichar_t character;
964
xdg_uint32_t mime_offset;
965
xdg_uint32_t n_children;
966
xdg_uint32_t child_offset;
969
character = GET_UINT32 (cache->buffer, offset);
970
mime_offset = GET_UINT32 (cache->buffer, offset + 4);
971
n_children = GET_UINT32 (cache->buffer, offset + 8);
972
child_offset = GET_UINT32 (cache->buffer, offset + 12);
973
for (i = 0; i < depth; i++)
975
printf ("%c", character);
977
printf (" - %s", cache->buffer + mime_offset);
981
for (i = 0; i < n_children; i++)
982
dump_glob_node (cache, child_offset + 20 * i, depth + 1);
987
_xdg_mime_cache_glob_dump (void)
990
for (i = 0; _caches[i]; i++)
992
XdgMimeCache *cache = _caches[i];
993
xdg_uint32_t list_offset;
994
xdg_uint32_t n_entries;
996
list_offset = GET_UINT32 (cache->buffer, 16);
997
n_entries = GET_UINT32 (cache->buffer, list_offset);
998
offset = GET_UINT32 (cache->buffer, list_offset + 4);
999
for (j = 0; j < n_entries; j++)
1000
dump_glob_node (cache, offset + 20 * j, 0);