[glib] xdgmime - support the new case sensitive flag
- From: Alexander Larsson <alexl src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [glib] xdgmime - support the new case sensitive flag
- Date: Fri, 2 Oct 2009 13:34:30 +0000 (UTC)
commit e1643fd76daf66ccffd9e6818e4f4ec8272e2a51
Author: Alexander Larsson <alexl redhat com>
Date: Fri Oct 2 09:49:51 2009 +0200
xdgmime - support the new case sensitive flag
gio/xdgmime/xdgmimecache.c | 86 +++++++++++++++++++++++++++++++++----------
gio/xdgmime/xdgmimeglob.c | 88 +++++++++++++++++++++++++++++++++++--------
2 files changed, 137 insertions(+), 37 deletions(-)
---
diff --git a/gio/xdgmime/xdgmimecache.c b/gio/xdgmime/xdgmimecache.c
index 0f2d83a..60e2e4f 100644
--- a/gio/xdgmime/xdgmimecache.c
+++ b/gio/xdgmime/xdgmimecache.c
@@ -361,7 +361,8 @@ typedef struct {
static int
cache_glob_lookup_literal (const char *file_name,
const char *mime_types[],
- int n_mime_types)
+ int n_mime_types,
+ int case_sensitive_check)
{
const char *ptr;
int i, min, max, mid, cmp;
@@ -382,17 +383,25 @@ cache_glob_lookup_literal (const char *file_name,
offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * 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 + 12 * mid + 4);
- mime_types[0] = (const char *)(cache->buffer + offset);
-
- return 1;
+ int weight = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * mid + 8);
+ int case_sensitive = weight & 0x100;
+ weight = weight & 0xff;
+
+ if (case_sensitive_check || !case_sensitive)
+ {
+ offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * mid + 4);
+ mime_types[0] = (const char *)(cache->buffer + offset);
+
+ return 1;
+ }
+ return 0;
}
}
}
@@ -423,6 +432,7 @@ cache_glob_lookup_fnmatch (const char *file_name,
xdg_uint32_t offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j);
xdg_uint32_t mimetype_offset = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j + 4);
int weight = GET_UINT32 (cache->buffer, list_offset + 4 + 12 * j + 8);
+ weight = weight & 0xff;
ptr = cache->buffer + offset;
mime_type = cache->buffer + mimetype_offset;
@@ -448,7 +458,7 @@ cache_glob_node_lookup_suffix (XdgMimeCache *cache,
xdg_uint32_t offset,
const char *file_name,
int len,
- int ignore_case,
+ int case_sensitive_check,
MimeWeight mime_types[],
int n_mime_types)
{
@@ -458,12 +468,11 @@ cache_glob_node_lookup_suffix (XdgMimeCache *cache,
xdg_uint32_t n_children;
xdg_uint32_t child_offset;
int weight;
+ int case_sensitive;
int min, max, mid, n, i;
character = file_name[len - 1];
- if (ignore_case)
- character = tolower (character);
assert (character != 0);
@@ -489,7 +498,7 @@ cache_glob_node_lookup_suffix (XdgMimeCache *cache,
n = cache_glob_node_lookup_suffix (cache,
n_children, child_offset,
file_name, len,
- ignore_case,
+ case_sensitive_check,
mime_types,
n_mime_types);
}
@@ -504,10 +513,15 @@ cache_glob_node_lookup_suffix (XdgMimeCache *cache,
mimetype_offset = GET_UINT32 (cache->buffer, child_offset + 12 * i + 4);
weight = GET_UINT32 (cache->buffer, child_offset + 12 * i + 8);
+ case_sensitive = weight & 0x100;
+ weight = weight & 0xff;
- mime_types[n].mime = cache->buffer + mimetype_offset;
- mime_types[n].weight = weight;
- n++;
+ if (case_sensitive_check || !case_sensitive)
+ {
+ mime_types[n].mime = cache->buffer + mimetype_offset;
+ mime_types[n].weight = weight;
+ n++;
+ }
i++;
}
}
@@ -555,6 +569,22 @@ static int compare_mime_weight (const void *a, const void *b)
return aa->weight - bb->weight;
}
+#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z')
+static char *
+ascii_tolower (const char *str)
+{
+ char *p, *lower;
+
+ lower = strdup (str);
+ p = lower;
+ while (*p != 0)
+ {
+ char c = *p;
+ *p++ = ISUPPER (c) ? c - 'A' + 'a' : c;
+ }
+ return lower;
+}
+
static int
cache_glob_lookup_file_name (const char *file_name,
const char *mime_types[],
@@ -565,20 +595,36 @@ cache_glob_lookup_file_name (const char *file_name,
int n_mimes = 10;
int i;
int len;
-
+ char *lower_case;
+ int try_lower_case;
+
assert (file_name != NULL && n_mime_types > 0);
/* First, check the literals */
- n = cache_glob_lookup_literal (file_name, mime_types, n_mime_types);
+
+ lower_case = ascii_tolower (file_name);
+
+ n = cache_glob_lookup_literal (lower_case, mime_types, n_mime_types, FALSE);
if (n > 0)
- return n;
+ {
+ free (lower_case);
+ return n;
+ }
- len = strlen (file_name);
- n = cache_glob_lookup_suffix (file_name, len, FALSE, mimes, n_mimes);
+ n = cache_glob_lookup_literal (file_name, mime_types, n_mime_types, TRUE);
+ if (n > 0)
+ {
+ free (lower_case);
+ return n;
+ }
+ len = strlen (file_name);
+ n = cache_glob_lookup_suffix (lower_case, len, FALSE, mimes, n_mimes);
if (n == 0)
n = cache_glob_lookup_suffix (file_name, len, TRUE, mimes, n_mimes);
-
+
+ free (lower_case);
+
/* Last, try fnmatch */
if (n == 0)
n = cache_glob_lookup_fnmatch (file_name, mimes, n_mimes);
diff --git a/gio/xdgmime/xdgmimeglob.c b/gio/xdgmime/xdgmimeglob.c
index 392eaab..b2ebda8 100644
--- a/gio/xdgmime/xdgmimeglob.c
+++ b/gio/xdgmime/xdgmimeglob.c
@@ -54,6 +54,7 @@ struct XdgGlobHashNode
xdg_unichar_t character;
const char *mime_type;
int weight;
+ int case_sensitive;
XdgGlobHashNode *next;
XdgGlobHashNode *child;
};
@@ -62,6 +63,7 @@ struct XdgGlobList
const char *data;
const char *mime_type;
int weight;
+ int case_sensitive;
XdgGlobList *next;
};
@@ -111,15 +113,27 @@ static XdgGlobList *
_xdg_glob_list_append (XdgGlobList *glob_list,
void *data,
const char *mime_type,
- int weight)
+ int weight,
+ int case_sensitive)
{
XdgGlobList *new_element;
XdgGlobList *tmp_element;
+ tmp_element = glob_list;
+ while (tmp_element != NULL)
+ {
+ if (strcmp (tmp_element->data, data) == 0 &&
+ strcmp (tmp_element->mime_type, mime_type) == 0)
+ return glob_list;
+
+ tmp_element = tmp_element->next;
+ }
+
new_element = _xdg_glob_list_new ();
new_element->data = data;
new_element->mime_type = mime_type;
new_element->weight = weight;
+ new_element->case_sensitive = case_sensitive;
if (glob_list == NULL)
return new_element;
@@ -168,7 +182,8 @@ static XdgGlobHashNode *
_xdg_glob_hash_insert_ucs4 (XdgGlobHashNode *glob_hash_node,
xdg_unichar_t *text,
const char *mime_type,
- int weight)
+ int weight,
+ int case_sensitive)
{
XdgGlobHashNode *node;
xdg_unichar_t character;
@@ -232,11 +247,11 @@ _xdg_glob_hash_insert_ucs4 (XdgGlobHashNode *glob_hash_node,
{
if (node->mime_type)
{
- if (strcmp (node->mime_type, mime_type))
+ if (strcmp (node->mime_type, mime_type) != 0)
{
XdgGlobHashNode *child;
int found_node = FALSE;
-
+
child = node->child;
while (child && child->character == 0)
{
@@ -254,6 +269,7 @@ _xdg_glob_hash_insert_ucs4 (XdgGlobHashNode *glob_hash_node,
child->character = 0;
child->mime_type = strdup (mime_type);
child->weight = weight;
+ child->case_sensitive = case_sensitive;
child->child = NULL;
child->next = node->child;
node->child = child;
@@ -264,11 +280,12 @@ _xdg_glob_hash_insert_ucs4 (XdgGlobHashNode *glob_hash_node,
{
node->mime_type = strdup (mime_type);
node->weight = weight;
+ node->case_sensitive = case_sensitive;
}
}
else
{
- node->child = _xdg_glob_hash_insert_ucs4 (node->child, text, mime_type, weight);
+ node->child = _xdg_glob_hash_insert_ucs4 (node->child, text, mime_type, weight, case_sensitive);
}
return glob_hash_node;
}
@@ -278,7 +295,8 @@ static XdgGlobHashNode *
_xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node,
const char *text,
const char *mime_type,
- int weight)
+ int weight,
+ int case_sensitive)
{
XdgGlobHashNode *node;
xdg_unichar_t *unitext;
@@ -286,7 +304,7 @@ _xdg_glob_hash_insert_text (XdgGlobHashNode *glob_hash_node,
unitext = _xdg_convert_to_ucs4 (text, &len);
_xdg_reverse_ucs4 (unitext, len);
- node = _xdg_glob_hash_insert_ucs4 (glob_hash_node, unitext, mime_type, weight);
+ node = _xdg_glob_hash_insert_ucs4 (glob_hash_node, unitext, mime_type, weight, case_sensitive);
free (unitext);
return node;
}
@@ -300,7 +318,7 @@ static int
_xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
const char *file_name,
int len,
- int ignore_case,
+ int case_sensitive_check,
MimeWeight mime_types[],
int n_mime_types)
{
@@ -312,8 +330,6 @@ _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
return 0;
character = file_name[len - 1];
- if (ignore_case)
- character = tolower(character);
for (node = glob_hash_node; node && character >= node->character; node = node->next)
{
@@ -326,13 +342,15 @@ _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
n = _xdg_glob_hash_node_lookup_file_name (node->child,
file_name,
len,
- ignore_case,
+ case_sensitive_check,
mime_types,
n_mime_types);
}
if (n == 0)
{
- if (node->mime_type)
+ if (node->mime_type &&
+ (case_sensitive_check ||
+ !node->case_sensitive))
{
mime_types[n].mime = node->mime_type;
mime_types[n].weight = node->weight;
@@ -341,7 +359,9 @@ _xdg_glob_hash_node_lookup_file_name (XdgGlobHashNode *glob_hash_node,
node = node->child;
while (n < n_mime_types && node && node->character == 0)
{
- if (node->mime_type)
+ if (node->mime_type &&
+ (case_sensitive_check ||
+ !node->case_sensitive))
{
mime_types[n].mime = node->mime_type;
mime_types[n].weight = node->weight;
@@ -365,6 +385,22 @@ static int compare_mime_weight (const void *a, const void *b)
return aa->weight - bb->weight;
}
+#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z')
+static char *
+ascii_tolower (const char *str)
+{
+ char *p, *lower;
+
+ lower = strdup (str);
+ p = lower;
+ while (*p != 0)
+ {
+ char c = *p;
+ *p++ = ISUPPER (c) ? c - 'A' + 'a' : c;
+ }
+ return lower;
+}
+
int
_xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
const char *file_name,
@@ -376,6 +412,8 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
MimeWeight mimes[10];
int n_mimes = 10;
int len;
+ char *lower_case;
+ int try_lower_case;
/* First, check the literals */
@@ -383,17 +421,32 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
n = 0;
+ lower_case = ascii_tolower (file_name);
+
for (list = glob_hash->literal_list; list; list = list->next)
{
if (strcmp ((const char *)list->data, file_name) == 0)
{
mime_types[0] = list->mime_type;
+ free (lower_case);
return 1;
}
}
+ for (list = glob_hash->literal_list; list; list = list->next)
+ {
+ if (!list->case_sensitive &&
+ strcmp ((const char *)list->data, lower_case) == 0)
+ {
+ mime_types[0] = list->mime_type;
+ free (lower_case);
+ return 1;
+ }
+ }
+
+
len = strlen (file_name);
- n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, file_name, len, FALSE,
+ n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, lower_case, len, FALSE,
mimes, n_mimes);
if (n == 0)
n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, file_name, len, TRUE,
@@ -411,6 +464,7 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
}
}
}
+ free (lower_case);
qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight);
@@ -506,13 +560,13 @@ _xdg_glob_hash_append_glob (XdgGlobHash *glob_hash,
switch (type)
{
case XDG_GLOB_LITERAL:
- glob_hash->literal_list = _xdg_glob_list_append (glob_hash->literal_list, strdup (glob), strdup (mime_type), weight);
+ glob_hash->literal_list = _xdg_glob_list_append (glob_hash->literal_list, strdup (glob), strdup (mime_type), weight, case_sensitive);
break;
case XDG_GLOB_SIMPLE:
- glob_hash->simple_node = _xdg_glob_hash_insert_text (glob_hash->simple_node, glob + 1, mime_type, weight);
+ glob_hash->simple_node = _xdg_glob_hash_insert_text (glob_hash->simple_node, glob + 1, mime_type, weight, case_sensitive);
break;
case XDG_GLOB_FULL:
- glob_hash->full_list = _xdg_glob_list_append (glob_hash->full_list, strdup (glob), strdup (mime_type), weight);
+ glob_hash->full_list = _xdg_glob_list_append (glob_hash->full_list, strdup (glob), strdup (mime_type), weight, case_sensitive);
break;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]