1 /**
2 * @file libcomprex/fsiter.c Filesystem iteration API
3 *
4 * $Id: fsiter.c,v 1.8 2003/01/01 06:22:36 chipx86 Exp $
5 *
6 * @Copyright (C) 2001-2003 The GNUpdate Project.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
22 */
23 #include <libcomprex/internal.h>
24
25 static CxFsNode *
__findFirstNode(CxFsNode * baseNode,CxFsNodeType type)26 __findFirstNode(CxFsNode *baseNode, CxFsNodeType type)
27 {
28 CxFsNode *node;
29
30 for (node = baseNode; node != NULL; node = node->next)
31 {
32 if (type == CX_FSNODETYPE_UNKNOWN || cxGetFsNodeType(node) == type)
33 return node;
34
35 if (cxGetFsNodeType(node) == CX_FSNODETYPE_DIRECTORY)
36 {
37 CxFsNode *tempNode = __findFirstNode(node->u.dir->children, type);
38
39 if (tempNode != NULL)
40 return tempNode;
41 }
42 }
43
44 return NULL;
45 }
46
47 static CxFsNode *
__findNextNode(CxFsNode * baseNode,CxFsNodeType type)48 __findNextNode(CxFsNode *baseNode, CxFsNodeType type)
49 {
50 CxFsNode *node = NULL;
51
52 while (baseNode != NULL && node == NULL)
53 {
54 if (cxGetFsNodeType(baseNode) == CX_FSNODETYPE_DIRECTORY)
55 node = baseNode->u.dir->children;
56
57 if (node == NULL)
58 node = cxGetNextFsNode(baseNode);
59
60 /* Descend down the directories. */
61 while (node == NULL && baseNode != NULL)
62 {
63 baseNode = cxGetFsNodeParent(baseNode);
64
65 if (cxGetNextFsNode(baseNode) != NULL)
66 {
67 baseNode = cxGetNextFsNode(baseNode);
68 node = baseNode;
69 }
70 }
71
72 if (node != NULL &&
73 (type == CX_FSNODETYPE_UNKNOWN || cxGetFsNodeType(node) == type))
74 {
75 return node;
76 }
77 else
78 node = NULL; /* Continue on. */
79 }
80
81 return NULL;
82 }
83
84 CxFsIterator *
cxNewFsIterator(CxArchive * archive,CxFsIteratorType type)85 cxNewFsIterator(CxArchive *archive, CxFsIteratorType type)
86 {
87 CxFsIterator *iterator;
88
89 if (archive == NULL)
90 return NULL;
91
92 MEM_CHECK(iterator = (CxFsIterator *)malloc(sizeof(CxFsIterator)));
93 memset(iterator, 0, sizeof(CxFsIterator));
94
95 iterator->type = type;
96 iterator->archive = archive;
97
98 return iterator;
99 }
100
101 void
cxDestroyFsIterator(CxFsIterator * iterator)102 cxDestroyFsIterator(CxFsIterator *iterator)
103 {
104 if (iterator == NULL)
105 return;
106
107 free(iterator);
108 }
109
110 CxFsNode *
cxGetFsIterFirst(CxFsIterator * iterator)111 cxGetFsIterFirst(CxFsIterator *iterator)
112 {
113 CxDirectory *root;
114
115 if (iterator == NULL)
116 return NULL;
117
118 root = cxGetArchiveRoot(iterator->archive);
119
120 if (iterator->type == CX_FSITER_DIRS)
121 {
122 iterator->lastNode = __findFirstNode(root->u.dir->children,
123 CX_FSNODETYPE_DIRECTORY);
124 }
125 else if (iterator->type == CX_FSITER_FILES)
126 {
127 iterator->lastNode = __findFirstNode(root->u.dir->children,
128 CX_FSNODETYPE_FILE);
129 }
130 else if (iterator->type == CX_FSITER_FILES_DIRS)
131 {
132 iterator->lastNode = root->u.dir->children;
133 }
134
135 return iterator->lastNode;
136 }
137
138 CxFsNode *
cxGetFsIterNext(CxFsIterator * iterator)139 cxGetFsIterNext(CxFsIterator *iterator)
140 {
141 if (iterator == NULL)
142 return NULL;
143
144 if (iterator->type == CX_FSITER_DIRS)
145 {
146 iterator->lastNode = __findNextNode(iterator->lastNode,
147 CX_FSNODETYPE_DIRECTORY);
148 }
149 else if (iterator->type == CX_FSITER_FILES)
150 {
151 iterator->lastNode = __findNextNode(iterator->lastNode,
152 CX_FSNODETYPE_FILE);
153 }
154 else if (iterator->type == CX_FSITER_FILES_DIRS)
155 {
156 iterator->lastNode = __findNextNode(iterator->lastNode,
157 CX_FSNODETYPE_UNKNOWN);
158 }
159
160 return iterator->lastNode;
161 }
162
163 CxFsNode *
cxGetFsIterPrev(CxFsIterator * iterator)164 cxGetFsIterPrev(CxFsIterator *iterator)
165 {
166 if (iterator == NULL)
167 return NULL;
168
169 return NULL;
170 }
171
172