summaryrefslogtreecommitdiff
path: root/src/libs/uio/gphys.h
blob: 7a9d6bea4dcbb34fc3e43439af7bc14f81757634 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
/*
 * Copyright (C) 2003  Serge van den Boom
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 * Nota bene: later versions of the GNU General Public License do not apply
 * to this program.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#ifndef LIBS_UIO_GPHYS_H_
#define LIBS_UIO_GPHYS_H_

#include "uioport.h"

#ifndef uio_INTERNAL_PHYSICAL
typedef void *uio_GPRootExtra;
typedef void *uio_GPDirExtra;
typedef void *uio_GPFileExtra;
#endif

typedef struct CharHashTable_HashTable uio_GPDirEntries;

#define uio_GPDirEntries_new() \
		((uio_GPDirEntries *) CharHashTable_newHashTable(NULL, NULL, NULL, \
		NULL, NULL, 0, 0.85, 0.9))
#define uio_GPDirEntries_add(hashTable, name, item) \
		CharHashTable_add((CharHashTable_HashTable *) hashTable, name, \
		(void *) item)
#define uio_GPDirEntries_remove(hashTable, name) \
		CharHashTable_remove((CharHashTable_HashTable *) hashTable, name)
#define uio_GPDirEntries_count(hashTable) \
		CharHashTable_count((CharHashTable_HashTable *) hashTable)
#define uio_GPDirEntries_find(hashTable, name) \
		((uio_GPDirEntry *) CharHashTable_find( \
		(CharHashTable_HashTable *) hashTable, name))
#define uio_GPDirEntries_deleteHashTable(hashTable) \
		CharHashTable_deleteHashTable((CharHashTable_HashTable *) hashTable)
//#define uio_GPDirEntries_clear(hashTable)
//		CharHashTable_clear((CharHashTable_HashTable *) hashTable)
#define uio_GPDirEntries_getIterator(hashTable) \
		((uio_GPDirEntries_Iterator *) CharHashTable_getIterator( \
		(const CharHashTable_HashTable *) hashTable))
#define uio_GPDirEntries_iteratorDone(iterator) \
		CharHashTable_iteratorDone((const CharHashTable_Iterator *) iterator)
#define uio_GPDirEntries_iteratorName(iterator) \
		CharHashTable_iteratorKey((CharHashTable_Iterator *) iterator)
#define uio_GPDirEntries_iteratorItem(iterator) \
		((uio_GPDirEntry *) CharHashTable_iteratorValue( \
		(CharHashTable_Iterator *) iterator))
#define uio_GPDirEntries_iteratorNext(iterator) \
		((uio_GPDirEntries_Iterator *) CharHashTable_iteratorNext( \
		(CharHashTable_Iterator *) iterator))
#define uio_GPDirEntries_freeIterator(iterator) \
		CharHashTable_freeIterator(iterator)

// 'forward' declarations
typedef struct uio_GPDirEntry uio_GPDirEntry;
typedef struct uio_GPDir uio_GPDir;
typedef struct uio_GPFile uio_GPFile;
typedef struct uio_GPRoot_Operations uio_GPRoot_Operations;
typedef struct uio_GPRoot uio_GPRoot;

#include "charhashtable.h"
typedef CharHashTable_Iterator uio_GPDirEntries_Iterator;

#ifdef uio_INTERNAL_GPHYS
typedef uio_GPDirEntries_Iterator *uio_NativeEntriesContext;
#endif
typedef struct uio_GPRoot *uio_PRootExtra;
typedef struct uio_GPDir uio_GPDirHandle;
typedef uio_GPDirHandle *uio_PDirHandleExtra;
typedef struct uio_GPFile uio_GPFileHandle;
typedef uio_GPFileHandle *uio_PFileHandleExtra;


#ifdef DEBUG
#	include <stdio.h>
#endif
#include "iointrn.h"
#ifdef uio_MEM_DEBUG
#	include "memdebug.h"
#endif

struct uio_GPRoot_Operations {
	void (*fillGPDir)(uio_GPDir *);
	void (*deleteGPRootExtra)(uio_GPRootExtra);
	void (*deleteGPDirExtra)(uio_GPDirExtra);
	void (*deleteGPFileExtra)(uio_GPFileExtra);
};

struct uio_GPRoot {
	int flags;
#define uio_GPRoot_PERSISTENT 0x4000
			/* Set if directories in this file system should not be deleted
			 * as long as the file system is mounted. If this flag is not
			 * set, the GPDir structure is only a cache.
			 */
	uio_GPRoot_Operations *ops;
	uio_GPRootExtra extra;
};

#define uio_GPDirEntry_COMMON \
	int flags; \
	int ref; \
			/* Number of times this structure is referenced from the \
			 * outside (so not counting the references from subdirs \
			 * or files when the entry is a directory) \
			 */

#define uio_GPDirEntry_NOCACHE   uio_PRoot_NOCACHE

/*
 * uio_GPDirEntry
 * super-'class' of uio_GPDir and uio_GPFile
 */
struct uio_GPDirEntry {
	uio_GPDirEntry_COMMON
	void *extra;
};

#define uio_GPDirEntry_TYPE_REG  0x0000
#define uio_GPDirEntry_TYPE_DIR  0x0001
#define uio_GPDirEntry_TYPEMASK  0x0001

/*
 * uio_GPDir
 * Represents a directory in a physical directory structure.
 * sub-'class' of uio_GPDirEntry
 */
struct uio_GPDir {
	uio_GPDirEntry_COMMON
#			define uio_GPDir_NOCACHE  uio_GPDirEntry_NOCACHE
			/* This directory info will not be cached.
			 * PDIR_COMPLETE is irrelevant in this case */
#			define uio_GPDir_COMPLETE 0x1000
			/* Set if fillDir should not be called if an entry does not
			 * exist in a directory. Usually set if the entire dir has been
			 * completely read in.
			 */
#			define uio_GPDir_DETACHED 0x2000
			/* Set if this dir is not linked to from elsewhere in the physical
			 * structure */
#			define uio_GPDir_PERSISTENT 0x4000
			/* Set if this dir should not be deleted as long as the file
			 * system is mounted. If this flag is not set, the GPDir
			 * structure is only a cache.
			 */
	uio_GPDirExtra extra;
			/* extra internal data for some filesystem types */
	uio_PRoot *pRoot;
	uio_GPDirEntries *entries;
};


/*
 * uio_GPFile
 * Represents a file in a physical directory structure.
 * sub-'class' of uio_GPDirEntry
 */
struct uio_GPFile {
	uio_GPDirEntry_COMMON
#			define uio_GPFile_NOCACHE  uio_GPDirEntry_NOCACHE
			/* Info on this file will not be cached. */
	uio_GPFileExtra extra;
			/* extra internal data for some filesystem types */
	uio_PRoot *pRoot;
};


static inline uio_bool
uio_GPDirEntry_isReg(uio_GPDirEntry *gPDirEntry) {
	return (gPDirEntry->flags & uio_GPDirEntry_TYPEMASK) ==
			uio_GPDirEntry_TYPE_REG;
}

static inline uio_bool
uio_GPDirEntry_isDir(uio_GPDirEntry *gPDirEntry) {
	return (gPDirEntry->flags & uio_GPDirEntry_TYPEMASK) ==
			uio_GPDirEntry_TYPE_DIR;
}


#ifdef DEBUG
void uio_GPDirEntry_print(FILE *outStream, uio_GPDirEntry *gPDirEntry);
void uio_GPDir_print(FILE *outStream, uio_GPDir *gPDir);
void uio_GPFile_print(FILE *outStream, uio_GPFile *pFile);
#endif

uio_NativeEntriesContext uio_GPDir_openEntries(uio_PDirHandle *pDirHandle);
int uio_GPDir_readEntries(uio_NativeEntriesContext *iterator,
		char *buf, size_t len);
void uio_GPDir_closeEntries(uio_NativeEntriesContext iterator);
int uio_GPDir_entryCount(const uio_GPDir *gPDir);

int uio_gPDirFlagsFromPRootFlags(int flags);
int uio_gPFileFlagsFromPRootFlags(int flags);
uio_PRoot *uio_GPRoot_makePRoot(uio_FileSystemHandler *handler, int pRootFlags,
		uio_GPRoot_Operations *ops, uio_GPRootExtra gPRootExtra, int gPRootFlags,
		uio_Handle *handle, uio_GPDirExtra gPDirExtra, int gPDirFlags);
int uio_GPRoot_umount(uio_PRoot *pRoot);

uio_GPDir *uio_GPDir_prepareSubDir(uio_GPDir *gPDir, const char *dirName);
void uio_GPDir_commitSubDir(uio_GPDir *gPDir, const char *dirName,
		uio_GPDir *subDir);
void uio_GPDir_addFile(uio_GPDir *gPDir, const char *fileName,
		uio_GPFile *file);
void uio_GPDir_removeFile(uio_GPDir *gPDir, const char *fileName);
void uio_GPDir_removeSubDir(uio_GPDir *gPDir, const char *dirName);
void uio_GPDir_setComplete(uio_GPDir *gPDir, uio_bool flag);
uio_GPDirEntry *uio_GPDir_getGPDirEntry(uio_GPDir *gPDir,
		const char *name);
uio_PDirEntryHandle *uio_GPDir_getPDirEntryHandle(
		const uio_PDirHandle *pDirHandle, const char *name);
int uio_walkGPPath(uio_GPDir *startGPDir, const char *path,
		size_t pathLen, uio_GPDir **endGPDir, const char **pathRest);
uio_PDirHandle *uio_GPDir_makePDirHandle(uio_GPDir *gPDir);

void uio_GPDir_fill(uio_GPDir *gPDir);
void uio_GPRoot_deleteGPRootExtra(uio_GPRoot *gPRoot);
void uio_GPDir_deleteGPDirExtra(uio_GPDir *gPDir);
void uio_GPFile_deleteGPFileExtra(uio_GPFile *gPFile);

void uio_GPDirHandle_delete(uio_GPDirHandle *gPDirHandle);
void uio_GPFileHandle_delete(uio_GPFileHandle *gPFileHandle);
void uio_GPDirEntry_delete(uio_GPDirEntry *gPDirEntry);
uio_GPRoot *uio_GPRoot_new(uio_GPRoot_Operations *ops, uio_GPRootExtra extra,
		int flags);
void uio_GPRoot_delete(uio_GPRoot *gPRoot);
uio_GPDir *uio_GPDir_new(uio_PRoot *pRoot, uio_GPDirExtra extra, int flags);
void uio_GPDir_delete(uio_GPDir *gPDir);
uio_GPFile *uio_GPFile_new(uio_PRoot *pRoot, uio_GPFileExtra extra, int flags);
void uio_GPFile_delete(uio_GPFile *gPFile);


static inline void
uio_GPDirEntry_ref(uio_GPDirEntry *gPDirEntry) {
#ifdef uio_MEM_DEBUG
	if (uio_GPDirEntry_isDir(gPDirEntry)) {
		uio_MemDebug_debugRef(uio_GPDir, (void *) gPDirEntry);
	} else {
		uio_MemDebug_debugRef(uio_GPFile, (void *) gPDirEntry);
	}
#endif
	gPDirEntry->ref++;
}

static inline void
uio_GPDirEntry_unref(uio_GPDirEntry *gPDirEntry) {
	assert(gPDirEntry->ref > 0);
#ifdef uio_MEM_DEBUG
	if (uio_GPDirEntry_isDir(gPDirEntry)) {
		uio_MemDebug_debugUnref(uio_GPDir, (void *) gPDirEntry);
	} else {
		uio_MemDebug_debugUnref(uio_GPFile, (void *) gPDirEntry);
	}
#endif
	gPDirEntry->ref--;
	if (gPDirEntry->ref == 0)
		uio_GPDirEntry_delete(gPDirEntry);
}

static inline void
uio_GPDir_ref(uio_GPDir *gPDir) {
#ifdef uio_MEM_DEBUG
	uio_MemDebug_debugRef(uio_GPDir, (void *) gPDir);
#endif
	gPDir->ref++;
}

static inline void
uio_GPDir_unref(uio_GPDir *gPDir) {
	assert(gPDir->ref > 0);
#ifdef uio_MEM_DEBUG
	uio_MemDebug_debugUnref(uio_GPDir, (void *) gPDir);
#endif
	gPDir->ref--;
	if (gPDir->ref == 0)
		uio_GPDir_delete(gPDir);
}

static inline void
uio_GPFile_ref(uio_GPFile *gPFile) {
#ifdef uio_MEM_DEBUG
	uio_MemDebug_debugRef(uio_GPFile, (void *) gPFile);
#endif
	gPFile->ref++;
}

static inline void
uio_GPFile_unref(uio_GPFile *gPFile) {
	assert(gPFile->ref > 0);
#ifdef uio_MEM_DEBUG
	uio_MemDebug_debugUnref(uio_GPFile, (void *) gPFile);
#endif
	gPFile->ref--;
	if (gPFile->ref == 0)
		uio_GPFile_delete(gPFile);
}


#endif  /* LIBS_UIO_GPHYS_H_ */