source: trunk/third/gnome-vfs/libgnomevfs/gnome-vfs-directory-list.c @ 15497

Revision 15497, 14.5 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15496, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2/* gnome-vfs-directory-list.c - Support for directory lists in the
3   GNOME Virtual File System.
4
5   Copyright (C) 1999 Free Software Foundation
6
7   The Gnome Library is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Library General Public License as
9   published by the Free Software Foundation; either version 2 of the
10   License, or (at your option) any later version.
11
12   The Gnome Library is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   Library General Public License for more details.
16
17   You should have received a copy of the GNU Library General Public
18   License along with the Gnome Library; see the file COPYING.LIB.  If not,
19   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20   Boston, MA 02111-1307, USA.
21
22   Author: Ettore Perazzoli <ettore@comm2000.it> */
23
24#ifdef HAVE_CONFIG_H
25#include <config.h>
26#endif
27
28#include <unistd.h>
29#include <fnmatch.h>
30#include <regex.h>
31
32#include "gnome-vfs.h"
33#include "gnome-vfs-private.h"
34
35
36struct GnomeVFSDirectoryList {
37        GList *entries;         /* GnomeVFSFileInfo */
38        GList *current_entry;
39        GList *last_entry;
40
41        guint num_entries;
42};
43
44
45static void
46remove_entry (GnomeVFSDirectoryList *list,
47              GList *p)
48{
49        GnomeVFSFileInfo *info;
50
51        info = p->data;
52        gnome_vfs_file_info_unref (info);
53
54        if (list->current_entry == p)
55                list->current_entry = NULL;
56        if (list->last_entry == p)
57                list->last_entry = p->prev;
58        list->entries = g_list_remove_link (list->entries, p);
59
60        list->num_entries--;
61
62        g_list_free (p);
63}
64
65
66/**
67 * gnome_vfs_directory_list_new:
68 *
69 * Create a new directory list object.
70 *
71 * Return value: A pointer to the newly created object.
72 **/
73GnomeVFSDirectoryList *
74gnome_vfs_directory_list_new (void)
75{
76        GnomeVFSDirectoryList *new;
77
78        new = g_new (GnomeVFSDirectoryList, 1);
79
80        new->entries = NULL;
81        new->current_entry = NULL;
82        new->last_entry = NULL;
83        new->num_entries = 0;
84
85        return new;
86}
87
88/**
89 * gnome_vfs_directory_list_destroy:
90 * @list: A directory list
91 *
92 * Destroy @list
93 **/
94void
95gnome_vfs_directory_list_destroy (GnomeVFSDirectoryList *list)
96{
97        GList *p;
98
99        g_return_if_fail (list != NULL);
100
101        if (list->entries != NULL) {
102                for (p = list->entries; p != NULL; p = p->next) {
103                        GnomeVFSFileInfo *info;
104
105                        info = p->data;
106                        gnome_vfs_file_info_unref (info);
107                }
108                g_list_free (list->entries);
109        }
110
111        g_free (list);
112}
113
114/**
115 * gnome_vfs_directory_list_prepend:
116 * @list: A directory list
117 * @info: Information to be added to the list
118 *
119 * Add @info at the beginning of @list.
120 **/
121void
122gnome_vfs_directory_list_prepend (GnomeVFSDirectoryList *list,
123                                  GnomeVFSFileInfo *info)
124{
125        g_return_if_fail (list != NULL);
126        g_return_if_fail (info != NULL);
127
128        list->entries = g_list_prepend (list->entries, info);
129        if (list->last_entry == NULL)
130                list->last_entry = list->entries;
131
132        list->num_entries++;
133}
134
135/**
136 * gnome_vfs_directory_list_append:
137 * @list: A directory list
138 * @info: Information to be added to the list
139 *
140 * Add @info at the end of @list.
141 *
142 **/
143void
144gnome_vfs_directory_list_append (GnomeVFSDirectoryList *list,
145                                 GnomeVFSFileInfo *info)
146{
147        g_return_if_fail (list != NULL);
148        g_return_if_fail (info != NULL);
149
150        if (list->entries == NULL) {
151                list->entries = g_list_alloc ();
152                list->entries->data = info;
153                list->last_entry = list->entries;
154        } else {
155                g_list_append (list->last_entry, info);
156                list->last_entry = list->last_entry->next;
157        }
158
159        list->num_entries++;
160}
161
162
163/**
164 * gnome_vfs_directory_list_first:
165 * @list: A directory list
166 *
167 * Retrieve the first item in @list, and set it as the current entry.
168 *
169 * Return value: A pointer to the information retrieved.
170 **/
171GnomeVFSFileInfo *
172gnome_vfs_directory_list_first (GnomeVFSDirectoryList *list)
173{
174        g_return_val_if_fail (list != NULL, NULL);
175
176        list->current_entry = list->entries;
177        if (list->current_entry == NULL)
178                return NULL;
179
180        return list->current_entry->data;
181}
182
183/**
184 * gnome_vfs_directory_list_last:
185 * @list: A directory list
186 *
187 * Retrieve the last item in @list, and set it as the current entry.
188 *
189 * Return value: A pointer to the information retrieved.
190 **/
191GnomeVFSFileInfo *
192gnome_vfs_directory_list_last (GnomeVFSDirectoryList *list)
193{
194        g_return_val_if_fail (list != NULL, NULL);
195
196        list->current_entry = list->last_entry;
197        if (list->current_entry == NULL)
198                return NULL;
199
200        return list->current_entry->data;
201}
202
203/**
204 * gnome_vfs_directory_list_next:
205 * @list: A directory list
206 *
207 * Retrieve the next item in @list, and set it as the current entry.
208 *
209 * Return value: A pointer to the information retrieved, or NULL if the current
210 * entry is the last one.
211 **/
212GnomeVFSFileInfo *
213gnome_vfs_directory_list_next (GnomeVFSDirectoryList *list)
214{
215        g_return_val_if_fail (list != NULL, NULL);
216
217        if (list->current_entry == NULL)
218                return NULL;
219
220        list->current_entry = list->current_entry->next;
221        if (list->current_entry == NULL)
222                return NULL;
223
224        return list->current_entry->data;
225}
226
227/**
228 * gnome_vfs_directory_list_prev:
229 * @list: A directory list
230 *
231 * Retrieve the previous item in @list, and set it as the current entry.
232 *
233 * Return value: A pointer to the information retrieved, or %NULL if the
234 * current entry is the last one.
235 **/
236GnomeVFSFileInfo *
237gnome_vfs_directory_list_prev (GnomeVFSDirectoryList *list)
238{
239        g_return_val_if_fail (list != NULL, NULL);
240
241        if (list->current_entry == NULL)
242                return NULL;
243
244        list->current_entry = list->current_entry->prev;
245        if (list->current_entry == NULL)
246                return NULL;
247
248        return list->current_entry->data;
249}
250
251/**
252 * gnome_vfs_directory_list_current:
253 * @list: A directory list
254 *
255 * Retrieve the current entry in @list.
256 *
257 * Return value: A pointer to the current entry, or %NULL if no current entry
258 * is set.
259 **/
260GnomeVFSFileInfo *
261gnome_vfs_directory_list_current (GnomeVFSDirectoryList *list)
262{
263        g_return_val_if_fail (list != NULL, NULL);
264
265        if (list->current_entry == NULL)
266                return NULL;
267
268        return list->current_entry->data;
269}
270
271/**
272 * gnome_vfs_directory_list_nth:
273 * @list: A directory list
274 * @n: Ordinal number of the element to retrieve
275 *
276 * Retrieve the @n'th element in @list.
277 *
278 * Return value: A pointer to the @n'th element in @list, or %NULL if no such
279 * element exists.
280 **/
281GnomeVFSFileInfo *
282gnome_vfs_directory_list_nth (GnomeVFSDirectoryList *list, guint n)
283{
284        g_return_val_if_fail (list != NULL, NULL);
285
286        list->current_entry = g_list_nth (list->entries, n);
287        if (list->current_entry == NULL)
288                return NULL;
289
290        return list->current_entry->data;
291}
292
293
294/**
295 * gnome_vfs_directory_list_filter:
296 * @list: A directory list
297 * @filter: A directory filter
298 *
299 * Filter @list through @filter
300 **/
301void
302gnome_vfs_directory_list_filter (GnomeVFSDirectoryList *list,
303                                 GnomeVFSDirectoryFilter *filter)
304{
305        GList *p;
306
307        g_return_if_fail (list != NULL);
308
309        if (filter == NULL)
310                return;
311
312        p = list->entries;
313        while (p != NULL) {
314                GnomeVFSFileInfo *info;
315                GList *pnext;
316
317                info = p->data;
318                pnext = p->next;
319
320                if (! gnome_vfs_directory_filter_apply (filter, info))
321                        remove_entry (list, p);
322
323                p = pnext;
324        }
325}
326
327
328/**
329 * gnome_vfs_directory_list_sort:
330 * @list: A directory list
331 * @reversed: Boolean specifying whether the sort order should be reversed
332 * @rules: %NULL-terminated array of sorting rules
333 *
334 * Sort @list according to @rules.
335 **/
336void
337gnome_vfs_directory_list_sort (GnomeVFSDirectoryList *list,
338                               gboolean reversed,
339                               const GnomeVFSDirectorySortRule *rules)
340{
341        GnomeVFSListCompareFunc func;
342
343        g_return_if_fail (list != NULL);
344        g_return_if_fail (rules[0] != GNOME_VFS_DIRECTORY_SORT_NONE);
345
346        if (reversed)
347                func = (GnomeVFSListCompareFunc) gnome_vfs_file_info_compare_for_sort_reversed;
348        else
349                func = (GnomeVFSListCompareFunc) gnome_vfs_file_info_compare_for_sort;
350
351        list->entries = gnome_vfs_list_sort (list->entries,
352                                             func, (gpointer) rules);
353
354        gnome_vfs_directory_list_set_position
355                (list, GNOME_VFS_DIRECTORY_LIST_POSITION_NONE);
356}
357
358/**
359 * gnome_vfs_directory_list_sort_custom:
360 * @list: A directory list
361 * @func: A directory sorting function
362 * @data: Data to be passed to @func at each iteration
363 *
364 * Sort @list using @func.  @func should return -1 if the element in the first
365 * argument should come before the element in the second; +1 if the element in
366 * the first argument should come after the element in the second; 0 if it
367 * elements are equal from the point of view of sorting.
368 **/
369void
370gnome_vfs_directory_list_sort_custom (GnomeVFSDirectoryList *list,
371                                      GnomeVFSDirectorySortFunc func,
372                                      gpointer data)
373{
374        g_return_if_fail (list != NULL);
375        g_return_if_fail (func != NULL);
376
377        gnome_vfs_list_sort (list->entries, (GnomeVFSListCompareFunc) func,
378                             data);
379}
380
381
382/**
383 * gnome_vfs_directory_list_get:
384 * @list: A directory list
385 * @position: A directory list position
386 *
387 * Retrieve element at @position.
388 *
389 * Return value: A pointer to the element at @position.
390 **/
391GnomeVFSFileInfo *
392gnome_vfs_directory_list_get (GnomeVFSDirectoryList *list,
393                              GnomeVFSDirectoryListPosition position)
394{
395        GList *p;
396        GnomeVFSFileInfo *info;
397
398        g_return_val_if_fail (list != NULL, NULL);
399        g_return_val_if_fail (position != GNOME_VFS_DIRECTORY_LIST_POSITION_NONE,
400                              NULL);
401
402        p = (GList *) position;
403        info = p->data;
404
405        return info;
406}
407
408
409/**
410 * gnome_vfs_directory_list_get_num_entries:
411 * @list: A directory list
412 *
413 * Retrieve the number of elements in @list.  This is an O(0) operation.
414 *
415 * Return value: The number of elements in @list.
416 **/
417guint
418gnome_vfs_directory_list_get_num_entries (GnomeVFSDirectoryList *list)
419{
420        g_return_val_if_fail (list != NULL, 0);
421
422        return list->num_entries;
423}
424
425/**
426 * gnome_vfs_directory_list_get_position:
427 * @list: A directory list
428 *
429 * Retrieve the current position in @list.
430 *
431 * Return value: An opaque value representing the current position in @list.
432 **/
433GnomeVFSDirectoryListPosition
434gnome_vfs_directory_list_get_position (GnomeVFSDirectoryList *list)
435{
436        g_return_val_if_fail (list != NULL, NULL);
437
438        return list->current_entry;
439}
440
441/**
442 * gnome_vfs_directory_list_set_position:
443 * @list: A directory list
444 * @position: A position in @list
445 *
446 * Set @list's current position.
447 **/
448void
449gnome_vfs_directory_list_set_position (GnomeVFSDirectoryList *list,
450                                       GnomeVFSDirectoryListPosition position)
451{
452        g_return_if_fail (list != NULL);
453
454        list->current_entry = position;
455}
456
457/**
458 * gnome_vfs_directory_list_get_last_position:
459 * @list: A directory list
460 *
461 * Get the position of the last element in @list.
462 *
463 * Return value: An opaque type representing the position of the last element
464 * in @list.
465 **/
466GnomeVFSDirectoryListPosition
467gnome_vfs_directory_list_get_last_position (GnomeVFSDirectoryList *list)
468{
469        g_return_val_if_fail (list != NULL, NULL);
470
471        return list->last_entry;
472}
473
474/**
475 * gnome_vfs_directory_list_get_first_position:
476 * @list: A directory list
477 *
478 * Get the position of the first element in @list.
479 *
480 * Return value: An opaque type representing the position of the first element
481 * in @list.
482 **/
483GnomeVFSDirectoryListPosition
484gnome_vfs_directory_list_get_first_position (GnomeVFSDirectoryList *list)
485{
486        g_return_val_if_fail (list != NULL, NULL);
487
488        return list->entries;
489}
490
491/**
492 * gnome_vfs_directory_list_position_next:
493 * @position: A directory list position
494 *
495 * Get the position next to @position.
496 *
497 * Return value: An opaque type representing the position of the element that
498 * comes after @position.
499 **/
500GnomeVFSDirectoryListPosition
501gnome_vfs_directory_list_position_next (GnomeVFSDirectoryListPosition position)
502{
503        GList *list;
504
505        g_return_val_if_fail (position != GNOME_VFS_DIRECTORY_LIST_POSITION_NONE, GNOME_VFS_DIRECTORY_LIST_POSITION_NONE);
506
507        list = position;
508        return list->next;
509}
510
511/**
512 * gnome_vfs_directory_list_position_prev:
513 * @position: A directory list position
514 *
515 * Get the position previous to @position.
516 *
517 * Return value: An opaque type representing the position of the element that
518 * comes before @position.
519 **/
520GnomeVFSDirectoryListPosition
521gnome_vfs_directory_list_position_prev (GnomeVFSDirectoryListPosition position)
522{
523        GList *list;
524
525        g_return_val_if_fail (position != NULL, NULL);
526
527        list = position;
528        return list->prev;
529}
530
531
532
533static GnomeVFSResult
534load_from_handle (GnomeVFSDirectoryList **list,
535                  GnomeVFSDirectoryHandle *handle)
536{
537        GnomeVFSResult result;
538        GnomeVFSFileInfo *info;
539
540        *list = gnome_vfs_directory_list_new ();
541
542        while (1) {
543                info = gnome_vfs_file_info_new ();
544                result = gnome_vfs_directory_read_next (handle, info);
545                if (result != GNOME_VFS_OK)
546                        break;
547                gnome_vfs_directory_list_append (*list, info);
548        }
549
550        gnome_vfs_file_info_unref (info);
551
552        if (result != GNOME_VFS_ERROR_EOF) {
553                gnome_vfs_directory_list_destroy (*list);
554                return result;
555        }
556
557        return GNOME_VFS_OK;
558}
559
560/**
561 * gnome_vfs_directory_list_load:
562 * @list: A pointer to a pointer to a directory list
563 * @text_uri: A text URI
564 * @options: Options for loading the directory
565 * @filter: Filter to be applied to the files being read
566 *
567 * Load a directory from @text_uri with the specified @options
568 * into a newly created directory list.  Directory entries are filtered through
569 * @filter.  On return @*list will point to such a list.
570 *
571 * Return value: An integer representing the result of the operation.
572 **/
573GnomeVFSResult
574gnome_vfs_directory_list_load (GnomeVFSDirectoryList **list,
575                               const gchar *text_uri,
576                               GnomeVFSFileInfoOptions options,
577                               const GnomeVFSDirectoryFilter *filter)
578{
579        GnomeVFSDirectoryHandle *handle;
580        GnomeVFSResult result;
581
582        result = gnome_vfs_directory_open (&handle, text_uri, options,
583                                           filter);
584        if (result != GNOME_VFS_OK)
585                return result;
586
587        result = load_from_handle (list, handle);
588
589        gnome_vfs_directory_close (handle);
590        return result;
591}
592
593/**
594 * gnome_vfs_directory_list_load_from_uri:
595 * @list: A pointer to a pointer to a directory list
596 * @uri: A GnomeVFSURI
597 * @options: Options for loading the directory
598 * @filter: Filter to be applied to the files being read
599 *
600 * Load a directory from @uri with the specified @options
601 * into a newly created directory list.  Directory entries are filtered through
602 * @filter.  On return @*list will point to such a list.
603 *
604 * Return value: An integer representing the result of the operation.
605 **/
606GnomeVFSResult
607gnome_vfs_directory_list_load_from_uri (GnomeVFSDirectoryList **list,
608                                        GnomeVFSURI *uri,
609                                        GnomeVFSFileInfoOptions options,
610                                        const GnomeVFSDirectoryFilter *filter)
611{
612        GnomeVFSDirectoryHandle *handle;
613        GnomeVFSResult result;
614
615        result = gnome_vfs_directory_open_from_uri (&handle, uri, options,
616                                                    filter);
617        if (result != GNOME_VFS_OK)
618                return result;
619
620        result = load_from_handle (list, handle);
621
622        gnome_vfs_directory_close (handle);
623        return result;
624}
625
Note: See TracBrowser for help on using the repository browser.