~ubuntu-branches/debian/experimental/thunar/experimental

« back to all changes in this revision

Viewing changes to thunar-vfs/thunar-vfs-mime-legacy.c

  • Committer: Bazaar Package Importer
  • Author(s): Yves-Alexis Perez
  • Date: 2006-01-02 23:42:32 UTC
  • Revision ID: james.westby@ubuntu.com-20060102234232-8xeq0lqhyn70syr0
Tags: upstream-0.1.4svn+r18850
ImportĀ upstreamĀ versionĀ 0.1.4svn+r18850

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: thunar-vfs-mime-legacy.c 18843 2005-11-14 14:25:58Z benny $ */
 
2
/*-
 
3
 * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU Library General Public
 
7
 * License as published by the Free Software Foundation; either
 
8
 * version 2 of the License, or (at your option) any later version.
 
9
 *
 
10
 * This library is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * Library General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Library General Public
 
16
 * License along with this library; if not, write to the
 
17
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
18
 * Boston, MA 02111-1307, USA.
 
19
 *
 
20
 * Based on code initially written by Matthias Clasen <mclasen@redhat.com>
 
21
 * for the xdgmime library.
 
22
 */
 
23
 
 
24
#ifdef HAVE_CONFIG_H
 
25
#include <config.h>
 
26
#endif
 
27
 
 
28
#ifdef HAVE_FNMATCH_H
 
29
#include <fnmatch.h>
 
30
#endif
 
31
#ifdef HAVE_MEMORY_H
 
32
#include <memory.h>
 
33
#endif
 
34
#include <stdio.h>
 
35
#ifdef HAVE_STRING_H
 
36
#include <string.h>
 
37
#endif
 
38
 
 
39
#include <thunar-vfs/thunar-vfs-mime-legacy.h>
 
40
 
 
41
 
 
42
 
 
43
#define THUNAR_VFS_MIME_LEGACY_GLOB(obj)   ((ThunarVfsMimeLegacyGlob *) (obj))
 
44
#define THUNAR_VFS_MIME_LEGACY_SUFFIX(obj) ((ThunarVfsMimeLegacySuffix *) (obj))
 
45
 
 
46
 
 
47
 
 
48
typedef struct _ThunarVfsMimeLegacyGlob   ThunarVfsMimeLegacyGlob;
 
49
typedef struct _ThunarVfsMimeLegacySuffix ThunarVfsMimeLegacySuffix;
 
50
 
 
51
 
 
52
 
 
53
static void         thunar_vfs_mime_legacy_class_init             (ThunarVfsMimeLegacyClass *klass);
 
54
static void         thunar_vfs_mime_legacy_init                   (ThunarVfsMimeLegacy      *legacy);
 
55
static void         thunar_vfs_mime_legacy_finalize               (GObject                  *object);
 
56
static const gchar *thunar_vfs_mime_legacy_lookup_data            (ThunarVfsMimeProvider    *provider,
 
57
                                                                   gconstpointer             data,
 
58
                                                                   gsize                     length,
 
59
                                                                   gint                     *priority);
 
60
static const gchar *thunar_vfs_mime_legacy_lookup_literal         (ThunarVfsMimeProvider    *provider,
 
61
                                                                   const gchar              *filename);
 
62
static const gchar *thunar_vfs_mime_legacy_lookup_suffix          (ThunarVfsMimeProvider    *provider,
 
63
                                                                   const gchar              *suffix,
 
64
                                                                   gboolean                  ignore_case);
 
65
static const gchar *thunar_vfs_mime_legacy_lookup_glob            (ThunarVfsMimeProvider    *provider,
 
66
                                                                   const gchar              *filename);
 
67
static const gchar *thunar_vfs_mime_legacy_lookup_alias           (ThunarVfsMimeProvider    *provider,
 
68
                                                                   const gchar              *alias);
 
69
static guint        thunar_vfs_mime_legacy_lookup_parents         (ThunarVfsMimeProvider    *provider,
 
70
                                                                   const gchar              *mime_type,
 
71
                                                                   gchar                   **parents,
 
72
                                                                   guint                     max_parents);
 
73
static GList       *thunar_vfs_mime_legacy_get_stop_characters    (ThunarVfsMimeProvider    *provider);
 
74
static gsize        thunar_vfs_mime_legacy_get_max_buffer_extents (ThunarVfsMimeProvider    *provider);
 
75
static void         thunar_vfs_mime_legacy_parse_aliases          (ThunarVfsMimeLegacy      *legacy,
 
76
                                                                   const gchar              *directory);
 
77
static gboolean     thunar_vfs_mime_legacy_parse_globs            (ThunarVfsMimeLegacy      *legacy,
 
78
                                                                   const gchar              *directory);
 
79
static void         thunar_vfs_mime_legacy_parse_subclasses       (ThunarVfsMimeLegacy      *legacy,
 
80
                                                                   const gchar              *directory);
 
81
 
 
82
 
 
83
 
 
84
struct _ThunarVfsMimeLegacyClass
 
85
{
 
86
  ThunarVfsMimeProviderClass __parent__;
 
87
};
 
88
 
 
89
struct _ThunarVfsMimeLegacy
 
90
{
 
91
  ThunarVfsMimeProvider __parent__;
 
92
 
 
93
  GStringChunk              *string_chunk;
 
94
  GMemChunk                 *suffix_chunk;
 
95
  GMemChunk                 *glob_chunk;
 
96
 
 
97
  GHashTable                *literals;
 
98
  ThunarVfsMimeLegacySuffix *suffixes;
 
99
  GList                     *globs;
 
100
 
 
101
  GHashTable                *aliases;
 
102
  GHashTable                *parents;
 
103
};
 
104
 
 
105
struct _ThunarVfsMimeLegacyGlob
 
106
{
 
107
  const gchar *pattern;
 
108
  const gchar *mime_type;
 
109
};
 
110
 
 
111
struct _ThunarVfsMimeLegacySuffix
 
112
{
 
113
  ThunarVfsMimeLegacySuffix *child;
 
114
  ThunarVfsMimeLegacySuffix *next;
 
115
  const gchar               *mime_type;
 
116
  gunichar                   character;
 
117
};
 
118
 
 
119
 
 
120
 
 
121
static GObjectClass *thunar_vfs_mime_legacy_parent_class;
 
122
 
 
123
 
 
124
 
 
125
GType
 
126
thunar_vfs_mime_legacy_get_type (void)
 
127
{
 
128
  static GType type = G_TYPE_INVALID;
 
129
 
 
130
  if (G_UNLIKELY (type == G_TYPE_INVALID))
 
131
    {
 
132
      static const GTypeInfo info =
 
133
      {
 
134
        sizeof (ThunarVfsMimeLegacyClass),
 
135
        NULL,
 
136
        NULL,
 
137
        (GClassInitFunc) thunar_vfs_mime_legacy_class_init,
 
138
        NULL,
 
139
        NULL,
 
140
        sizeof (ThunarVfsMimeLegacy),
 
141
        0,
 
142
        (GInstanceInitFunc) thunar_vfs_mime_legacy_init,
 
143
        NULL,
 
144
      };
 
145
 
 
146
      type = g_type_register_static (THUNAR_VFS_TYPE_MIME_PROVIDER,
 
147
                                     "ThunarVfsMimeLegacy", &info, 0);
 
148
    }
 
149
 
 
150
  return type;
 
151
}
 
152
 
 
153
 
 
154
 
 
155
static void
 
156
thunar_vfs_mime_legacy_class_init (ThunarVfsMimeLegacyClass *klass)
 
157
{
 
158
  ThunarVfsMimeProviderClass *thunarvfs_mime_provider_class;
 
159
  GObjectClass               *gobject_class;
 
160
 
 
161
  thunar_vfs_mime_legacy_parent_class = g_type_class_peek_parent (klass);
 
162
 
 
163
  gobject_class = G_OBJECT_CLASS (klass);
 
164
  gobject_class->finalize = thunar_vfs_mime_legacy_finalize;
 
165
 
 
166
  thunarvfs_mime_provider_class = THUNAR_VFS_MIME_PROVIDER_CLASS (klass);
 
167
  thunarvfs_mime_provider_class->lookup_data = thunar_vfs_mime_legacy_lookup_data;
 
168
  thunarvfs_mime_provider_class->lookup_literal = thunar_vfs_mime_legacy_lookup_literal;
 
169
  thunarvfs_mime_provider_class->lookup_suffix = thunar_vfs_mime_legacy_lookup_suffix;
 
170
  thunarvfs_mime_provider_class->lookup_glob = thunar_vfs_mime_legacy_lookup_glob;
 
171
  thunarvfs_mime_provider_class->lookup_alias = thunar_vfs_mime_legacy_lookup_alias;
 
172
  thunarvfs_mime_provider_class->lookup_parents = thunar_vfs_mime_legacy_lookup_parents;
 
173
  thunarvfs_mime_provider_class->get_stop_characters = thunar_vfs_mime_legacy_get_stop_characters;
 
174
  thunarvfs_mime_provider_class->get_max_buffer_extents = thunar_vfs_mime_legacy_get_max_buffer_extents;
 
175
}
 
176
 
 
177
 
 
178
 
 
179
static void
 
180
thunar_vfs_mime_legacy_init (ThunarVfsMimeLegacy *legacy)
 
181
{
 
182
  legacy->string_chunk = g_string_chunk_new (1024);
 
183
  legacy->glob_chunk = g_mem_chunk_create (ThunarVfsMimeLegacyGlob, 32, G_ALLOC_ONLY);
 
184
  legacy->suffix_chunk = g_mem_chunk_create (ThunarVfsMimeLegacySuffix, 128, G_ALLOC_ONLY);
 
185
 
 
186
  legacy->literals = g_hash_table_new (g_str_hash, g_str_equal);
 
187
 
 
188
  legacy->aliases = g_hash_table_new (g_str_hash, g_str_equal);
 
189
  legacy->parents = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_list_free);
 
190
}
 
191
 
 
192
 
 
193
 
 
194
static void
 
195
thunar_vfs_mime_legacy_finalize (GObject *object)
 
196
{
 
197
  ThunarVfsMimeLegacy *legacy = THUNAR_VFS_MIME_LEGACY (object);
 
198
 
 
199
  /* free parents hash table */
 
200
  g_hash_table_destroy (legacy->parents);
 
201
 
 
202
  /* free aliases hash table */
 
203
  g_hash_table_destroy (legacy->aliases);
 
204
 
 
205
  /* free the list of globs */
 
206
  g_list_free (legacy->globs);
 
207
 
 
208
  /* free literals hash table */
 
209
  g_hash_table_destroy (legacy->literals);
 
210
 
 
211
  /* free chunks */
 
212
  g_string_chunk_free (legacy->string_chunk);
 
213
  g_mem_chunk_destroy (legacy->suffix_chunk);
 
214
  g_mem_chunk_destroy (legacy->glob_chunk);
 
215
 
 
216
  (*G_OBJECT_CLASS (thunar_vfs_mime_legacy_parent_class)->finalize) (object);
 
217
}
 
218
 
 
219
 
 
220
 
 
221
static const gchar*
 
222
thunar_vfs_mime_legacy_lookup_data (ThunarVfsMimeProvider *provider,
 
223
                                    gconstpointer          data,
 
224
                                    gsize                  length,
 
225
                                    gint                  *priority)
 
226
{
 
227
  return NULL;
 
228
}
 
229
 
 
230
 
 
231
 
 
232
static const gchar*
 
233
thunar_vfs_mime_legacy_lookup_literal (ThunarVfsMimeProvider *provider,
 
234
                                       const gchar           *filename)
 
235
{
 
236
  return g_hash_table_lookup (THUNAR_VFS_MIME_LEGACY (provider)->literals, filename);
 
237
}
 
238
 
 
239
 
 
240
 
 
241
static ThunarVfsMimeLegacySuffix*
 
242
suffix_insert (ThunarVfsMimeLegacy       *legacy,
 
243
               ThunarVfsMimeLegacySuffix *suffix_node,
 
244
               const gchar               *pattern,
 
245
               const gchar               *mime_type)
 
246
{
 
247
  ThunarVfsMimeLegacySuffix *previous;
 
248
  ThunarVfsMimeLegacySuffix *node;
 
249
  gboolean                   found_node = FALSE;
 
250
  gunichar                   character;
 
251
 
 
252
  character = g_utf8_get_char (pattern);
 
253
 
 
254
  if (suffix_node == NULL || character < suffix_node->character)
 
255
    {
 
256
      node = g_chunk_new0 (ThunarVfsMimeLegacySuffix, legacy->suffix_chunk);
 
257
      node->next = suffix_node;
 
258
      node->character = character;
 
259
      suffix_node = node;
 
260
    }
 
261
  else if (character == suffix_node->character)
 
262
    {
 
263
      node = suffix_node;
 
264
    }
 
265
  else
 
266
    {
 
267
      for (previous = suffix_node, node = previous->next; node != NULL; previous = node, node = node->next)
 
268
        {
 
269
          if (character < node->character)
 
270
            {
 
271
              node = g_chunk_new0 (ThunarVfsMimeLegacySuffix, legacy->suffix_chunk);
 
272
              node->next = previous->next;
 
273
              node->character = character;
 
274
              previous->next = node;
 
275
              found_node = TRUE;
 
276
              break;
 
277
            }
 
278
          else if (character == node->character)
 
279
            {
 
280
              found_node = TRUE;
 
281
              break;
 
282
            }
 
283
        }
 
284
 
 
285
      if (!found_node)
 
286
        {
 
287
          node = g_chunk_new0 (ThunarVfsMimeLegacySuffix, legacy->suffix_chunk);
 
288
          node->next = previous->next;
 
289
          node->character = character;
 
290
          previous->next = node;
 
291
        }
 
292
    }
 
293
 
 
294
  pattern = g_utf8_next_char (pattern);
 
295
  if (G_UNLIKELY (*pattern == '\0'))
 
296
    node->mime_type = mime_type;
 
297
  else
 
298
    node->child = suffix_insert (legacy, node->child, pattern, mime_type);
 
299
 
 
300
  return suffix_node;
 
301
}
 
302
 
 
303
 
 
304
 
 
305
static const gchar*
 
306
suffix_lookup (ThunarVfsMimeLegacySuffix *suffix_node,
 
307
               const gchar               *filename,
 
308
               gboolean                   ignore_case)
 
309
{
 
310
  ThunarVfsMimeLegacySuffix *node;
 
311
  gunichar                   character;
 
312
 
 
313
  if (G_UNLIKELY (suffix_node == NULL))
 
314
    return NULL;
 
315
 
 
316
  character = g_utf8_get_char (filename);
 
317
  if (G_UNLIKELY (ignore_case))
 
318
    character = g_unichar_tolower (character);
 
319
 
 
320
  for (node = suffix_node; node != NULL && character >= node->character; node = node->next)
 
321
    if (character == node->character)
 
322
      {
 
323
        filename = g_utf8_next_char (filename);
 
324
        if (*filename == '\0')
 
325
          return node->mime_type;
 
326
        else
 
327
          return suffix_lookup (node->child, filename, ignore_case);
 
328
      }
 
329
 
 
330
  return NULL;
 
331
}
 
332
 
 
333
 
 
334
 
 
335
static const gchar*
 
336
thunar_vfs_mime_legacy_lookup_suffix (ThunarVfsMimeProvider *provider,
 
337
                                      const gchar           *suffix,
 
338
                                      gboolean               ignore_case)
 
339
{
 
340
  return suffix_lookup (THUNAR_VFS_MIME_LEGACY (provider)->suffixes, suffix, ignore_case);
 
341
}
 
342
 
 
343
 
 
344
 
 
345
static const gchar*
 
346
thunar_vfs_mime_legacy_lookup_glob (ThunarVfsMimeProvider *provider,
 
347
                                    const gchar           *filename)
 
348
{
 
349
  GList *lp;
 
350
 
 
351
  for (lp = THUNAR_VFS_MIME_LEGACY (provider)->globs; lp != NULL; lp = lp->next)
 
352
    if (fnmatch (THUNAR_VFS_MIME_LEGACY_GLOB (lp->data)->pattern, filename, 0) == 0)
 
353
      return THUNAR_VFS_MIME_LEGACY_GLOB (lp->data)->mime_type;
 
354
 
 
355
  return NULL;
 
356
}
 
357
 
 
358
 
 
359
 
 
360
static const gchar*
 
361
thunar_vfs_mime_legacy_lookup_alias (ThunarVfsMimeProvider *provider,
 
362
                                     const gchar           *alias)
 
363
{
 
364
  return g_hash_table_lookup (THUNAR_VFS_MIME_LEGACY (provider)->aliases, alias);
 
365
}
 
366
 
 
367
 
 
368
 
 
369
static guint
 
370
thunar_vfs_mime_legacy_lookup_parents (ThunarVfsMimeProvider *provider,
 
371
                                       const gchar           *mime_type,
 
372
                                       gchar                **parents,
 
373
                                       guint                  max_parents)
 
374
{
 
375
  GList *lp;
 
376
  guint  n = 0;
 
377
 
 
378
  /* determine the known parents for the MIME-type */
 
379
  lp = g_hash_table_lookup (THUNAR_VFS_MIME_LEGACY (provider)->parents, mime_type);
 
380
  for (; lp != NULL && n < max_parents; lp = lp->next, ++n, ++parents)
 
381
    *parents = lp->data;
 
382
 
 
383
  return n;
 
384
}
 
385
 
 
386
 
 
387
 
 
388
static GList*
 
389
thunar_vfs_mime_legacy_get_stop_characters (ThunarVfsMimeProvider *provider)
 
390
{
 
391
  ThunarVfsMimeLegacySuffix *node;
 
392
  GList                     *stopchars = NULL;
 
393
 
 
394
  for (node = THUNAR_VFS_MIME_LEGACY (provider)->suffixes; node != NULL; node = node->next)
 
395
    if (node->character < 128u)
 
396
      stopchars = g_list_prepend (stopchars, GUINT_TO_POINTER (node->character));
 
397
 
 
398
  return stopchars;
 
399
}
 
400
 
 
401
 
 
402
 
 
403
static gsize
 
404
thunar_vfs_mime_legacy_get_max_buffer_extents (ThunarVfsMimeProvider *provider)
 
405
{
 
406
  return 0;
 
407
}
 
408
 
 
409
 
 
410
 
 
411
static void
 
412
thunar_vfs_mime_legacy_parse_aliases (ThunarVfsMimeLegacy *legacy,
 
413
                                      const gchar         *directory)
 
414
{
 
415
  gchar  line[2048];
 
416
  gchar *alias;
 
417
  gchar *name;
 
418
  gchar *path;
 
419
  gchar *lp;
 
420
  FILE  *fp;
 
421
 
 
422
  /* try to open the "aliases" file */
 
423
  path = g_build_filename (directory, "aliases", NULL);
 
424
  fp = fopen (path, "r");
 
425
  g_free (path);
 
426
 
 
427
  /* check if we succeed */
 
428
  if (G_UNLIKELY (fp == NULL))
 
429
    return;
 
430
 
 
431
  /* parse all aliases */
 
432
  while (fgets (line, sizeof (line), fp) != NULL)
 
433
    {
 
434
      /* skip whitespace/comments */
 
435
      for (lp = line; g_ascii_isspace (*lp); ++lp);
 
436
      if (G_UNLIKELY (*lp == '\0' || *lp == '#'))
 
437
        continue;
 
438
 
 
439
      /* extract the alias name */
 
440
      for (alias = lp; *lp != '\0' && !g_ascii_isspace (*lp); ++lp);
 
441
      if (G_UNLIKELY (*lp == '\0' || alias == lp))
 
442
        continue;
 
443
      *lp++ = '\0';
 
444
 
 
445
      /* skip whitespace */
 
446
      for (; G_UNLIKELY (g_ascii_isspace (*lp)); ++lp);
 
447
      if (G_UNLIKELY (*lp == '\0'))
 
448
        continue;
 
449
 
 
450
      /* extract the MIME-type name */
 
451
      for (name = lp; *lp != '\0' && *lp != '\n' && *lp != '\r'; ++lp);
 
452
      if (G_UNLIKELY (name == lp))
 
453
        continue;
 
454
      *lp = '\0';
 
455
 
 
456
      /* insert the alias into the string chunk */
 
457
      alias = g_string_chunk_insert_const (legacy->string_chunk, alias);
 
458
 
 
459
      /* insert the MIME-type name into the string chunk */
 
460
      name = g_string_chunk_insert_const (legacy->string_chunk, name);
 
461
 
 
462
      /* insert the association into the aliases hash table */
 
463
      g_hash_table_insert (legacy->aliases, alias, name);
 
464
    }
 
465
 
 
466
  fclose (fp);
 
467
}
 
468
 
 
469
 
 
470
 
 
471
static gboolean
 
472
thunar_vfs_mime_legacy_parse_globs (ThunarVfsMimeLegacy *legacy,
 
473
                                    const gchar         *directory)
 
474
{
 
475
  ThunarVfsMimeLegacyGlob *glob;
 
476
  gchar                    line[2048];
 
477
  gchar                   *pattern;
 
478
  gchar                   *path;
 
479
  gchar                   *name;
 
480
  gchar                   *lp;
 
481
  FILE                    *fp;
 
482
 
 
483
  /* try to open the "globs" file */
 
484
  path = g_build_filename (directory, "globs", NULL);
 
485
  fp = fopen (path, "r");
 
486
  g_free (path);
 
487
 
 
488
  /* cannot continue */
 
489
  if (G_UNLIKELY (fp == NULL))
 
490
    return FALSE;
 
491
 
 
492
  /* parse all globs */
 
493
  while (fgets (line, sizeof (line), fp) != NULL)
 
494
    {
 
495
      /* skip whitespace/comments */
 
496
      for (lp = line; g_ascii_isspace (*lp); ++lp);
 
497
      if (*lp == '\0' || *lp == '#')
 
498
        continue;
 
499
 
 
500
      /* extract the MIME-type name */
 
501
      for (name = lp; *lp != '\0' && *lp != ':'; ++lp);
 
502
      if (*lp == '\0' || name == lp)
 
503
        continue;
 
504
 
 
505
      /* extract the pattern */
 
506
      for (*lp = '\0', pattern = ++lp; *lp != '\0' && *lp != '\n' && *lp != '\r'; ++lp);
 
507
      *lp = '\0';
 
508
      if (*pattern == '\0')
 
509
        continue;
 
510
 
 
511
      /* insert the name into the string chunk */
 
512
      name = g_string_chunk_insert_const (legacy->string_chunk, name);
 
513
 
 
514
      /* determine the type of the pattern */
 
515
      if (strpbrk (pattern, "*?[") == NULL)
 
516
        {
 
517
          g_hash_table_insert (legacy->literals, g_string_chunk_insert (legacy->string_chunk, pattern), name);
 
518
        }
 
519
      else if (pattern[0] == '*' && pattern[1] == '.' && strpbrk (pattern + 2, "*?[") == NULL)
 
520
        {
 
521
          legacy->suffixes = suffix_insert (legacy, legacy->suffixes, pattern + 1, name);
 
522
        }
 
523
      else
 
524
        {
 
525
          glob = g_chunk_new (ThunarVfsMimeLegacyGlob, legacy->glob_chunk);
 
526
          glob->pattern = g_string_chunk_insert (legacy->string_chunk, pattern);
 
527
          glob->mime_type = name;
 
528
          legacy->globs = g_list_append (legacy->globs, glob);
 
529
        }
 
530
    }
 
531
 
 
532
  fclose (fp);
 
533
 
 
534
  return TRUE;
 
535
}
 
536
 
 
537
 
 
538
 
 
539
static void
 
540
thunar_vfs_mime_legacy_parse_subclasses (ThunarVfsMimeLegacy *legacy,
 
541
                                         const gchar         *directory)
 
542
{
 
543
  gchar  line[2048];
 
544
  GList *parents;
 
545
  gchar *subclass;
 
546
  gchar *name;
 
547
  gchar *path;
 
548
  gchar *lp;
 
549
  FILE  *fp;
 
550
 
 
551
  /* try to open the "subclasses" file */
 
552
  path = g_build_filename (directory, "subclasses", NULL);
 
553
  fp = fopen (path, "r");
 
554
  g_free (path);
 
555
 
 
556
  /* check if we succeed */
 
557
  if (G_UNLIKELY (fp == NULL))
 
558
    return;
 
559
 
 
560
  /* parse all subclasses */
 
561
  while (fgets (line, sizeof (line), fp) != NULL)
 
562
    {
 
563
      /* skip whitespace/comments */
 
564
      for (lp = line; g_ascii_isspace (*lp); ++lp);
 
565
      if (G_UNLIKELY (*lp == '\0' || *lp == '#'))
 
566
        continue;
 
567
 
 
568
      /* extract the subclass name */
 
569
      for (subclass = lp; *lp != '\0' && !g_ascii_isspace (*lp); ++lp);
 
570
      if (G_UNLIKELY (*lp == '\0' || subclass == lp))
 
571
        continue;
 
572
      *lp++ = '\0';
 
573
 
 
574
      /* skip whitespace */
 
575
      for (; G_UNLIKELY (g_ascii_isspace (*lp)); ++lp);
 
576
      if (G_UNLIKELY (*lp == '\0'))
 
577
        continue;
 
578
 
 
579
      /* extract the MIME-type name */
 
580
      for (name = lp; *lp != '\0' && *lp != '\n' && *lp != '\r'; ++lp);
 
581
      if (G_UNLIKELY (name == lp))
 
582
        continue;
 
583
      *lp = '\0';
 
584
 
 
585
      /* insert the subclass into the string chunk */
 
586
      subclass = g_string_chunk_insert_const (legacy->string_chunk, subclass);
 
587
 
 
588
      /* insert the MIME-type name into the string chunk */
 
589
      name = g_string_chunk_insert_const (legacy->string_chunk, name);
 
590
 
 
591
      /* add the MIME-type name to the list of parents for the subclass */
 
592
      parents = g_hash_table_lookup (legacy->parents, subclass);
 
593
      if (G_UNLIKELY (parents != NULL))
 
594
        parents = g_list_copy (parents);
 
595
      parents = g_list_append (parents, name);
 
596
      g_hash_table_insert (legacy->parents, subclass, parents);
 
597
    }
 
598
 
 
599
  fclose (fp);
 
600
}
 
601
 
 
602
 
 
603
 
 
604
/**
 
605
 * thunar_vfs_mime_legacy_new:
 
606
 * @directory : an XDG mime base directory.
 
607
 *
 
608
 * Allocates a new #ThunarVfsMimeLegacy for @directory and
 
609
 * returns the instance on success, or %NULL on error.
 
610
 *
 
611
 * The caller is responsible to free the returned instance
 
612
 * using g_object_unref().
 
613
 *
 
614
 * Return value: the newly allocated #ThunarVfsMimeLegacy
 
615
 *               instance or %NULL on error.
 
616
 **/
 
617
ThunarVfsMimeProvider*
 
618
thunar_vfs_mime_legacy_new (const gchar *directory)
 
619
{
 
620
  ThunarVfsMimeLegacy *legacy;
 
621
 
 
622
  /* allocate the new object */
 
623
  legacy = g_object_new (THUNAR_VFS_TYPE_MIME_LEGACY, NULL);
 
624
 
 
625
  /* try to parse the globs file */
 
626
  if (!thunar_vfs_mime_legacy_parse_globs (legacy, directory))
 
627
    {
 
628
      g_object_unref (legacy);
 
629
      return NULL;
 
630
    }
 
631
 
 
632
  /* parse the aliases file (optional) */
 
633
  thunar_vfs_mime_legacy_parse_aliases (legacy, directory);
 
634
 
 
635
  /* parse the subclasses file (optional) */
 
636
  thunar_vfs_mime_legacy_parse_subclasses (legacy, directory);
 
637
 
 
638
  /* we got it */
 
639
  return THUNAR_VFS_MIME_PROVIDER (legacy);
 
640
}
 
641
 
 
642
 
 
643