/
dir.c
286 lines (220 loc) · 7.71 KB
1
2
3
4
5
6
7
8
/*
* Standard directory I/O support routines for PhysicsFS.
*
* Please see the file LICENSE in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
9
10
11
12
#if HAVE_CONFIG_H
# include <config.h>
#endif
13
14
#include <stdio.h>
#include <stdlib.h>
15
#include <string.h>
16
#include "physfs.h"
17
18
19
20
#define __PHYSICSFS_INTERNAL__
#include "physfs_internal.h"
21
static PHYSFS_sint64 DIR_read(fvoid *opaque, void *buffer,
22
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
23
{
24
PHYSFS_sint64 retval;
25
retval = __PHYSFS_platformRead(opaque, buffer, objSize, objCount);
26
return(retval);
27
28
29
} /* DIR_read */
30
static PHYSFS_sint64 DIR_write(fvoid *opaque, const void *buffer,
31
PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
32
{
33
PHYSFS_sint64 retval;
34
retval = __PHYSFS_platformWrite(opaque, buffer, objSize, objCount);
35
return(retval);
36
37
38
} /* DIR_write */
39
static int DIR_eof(fvoid *opaque)
40
{
41
return(__PHYSFS_platformEOF(opaque));
42
43
44
} /* DIR_eof */
45
static PHYSFS_sint64 DIR_tell(fvoid *opaque)
46
{
47
return(__PHYSFS_platformTell(opaque));
48
49
50
} /* DIR_tell */
51
static int DIR_seek(fvoid *opaque, PHYSFS_uint64 offset)
52
{
53
return(__PHYSFS_platformSeek(opaque, offset));
54
55
56
} /* DIR_seek */
57
static PHYSFS_sint64 DIR_fileLength(fvoid *opaque)
58
{
59
return(__PHYSFS_platformFileLength(opaque));
60
61
62
} /* DIR_fileLength */
63
static int DIR_fileClose(fvoid *opaque)
64
65
{
/*
66
* we manually flush the buffer, since that's the place a close will
67
* most likely fail, but that will leave the file handle in an undefined
68
* state if it fails. Flush failures we can recover from.
69
*/
70
71
BAIL_IF_MACRO(!__PHYSFS_platformFlush(opaque), NULL, 0);
BAIL_IF_MACRO(!__PHYSFS_platformClose(opaque), NULL, 0);
72
73
74
75
76
77
78
79
80
81
82
return(1);
} /* DIR_fileClose */
static int DIR_isArchive(const char *filename, int forWriting)
{
/* directories ARE archives in this driver... */
return(__PHYSFS_platformIsDirectory(filename));
} /* DIR_isArchive */
83
static void *DIR_openArchive(const char *name, int forWriting)
84
{
85
const char *dirsep = PHYSFS_getDirSeparator();
86
char *retval = NULL;
87
88
size_t namelen = strlen(name);
size_t seplen = strlen(dirsep);
89
90
/* !!! FIXME: when is this not called right before openArchive? */
91
BAIL_IF_MACRO(!DIR_isArchive(name, forWriting),
92
ERR_UNSUPPORTED_ARCHIVE, 0);
93
94
retval = malloc(namelen + seplen + 1);
95
96
97
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
/* make sure there's a dir separator at the end of the string */
98
strcpy(retval, name);
99
if (strcmp((name + namelen) - seplen, dirsep) != 0)
100
strcat(retval, dirsep);
101
102
103
104
105
return(retval);
} /* DIR_openArchive */
106
107
108
static void DIR_enumerateFiles(dvoid *opaque, const char *dname,
int omitSymLinks, PHYSFS_StringCallback cb,
void *callbackdata)
109
{
110
char *d = __PHYSFS_platformCvtToDependent((char *)opaque, dname, NULL);
111
112
113
114
115
if (d != NULL)
{
__PHYSFS_platformEnumerateFiles(d, omitSymLinks, cb, callbackdata);
free(d);
} /* if */
116
117
118
} /* DIR_enumerateFiles */
119
static int DIR_exists(dvoid *opaque, const char *name)
120
{
121
char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
122
123
124
125
126
127
128
129
130
int retval;
BAIL_IF_MACRO(f == NULL, NULL, 0);
retval = __PHYSFS_platformExists(f);
free(f);
return(retval);
} /* DIR_exists */
131
static int DIR_isDirectory(dvoid *opaque, const char *name, int *fileExists)
132
{
133
char *d = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
134
int retval = 0;
135
136
BAIL_IF_MACRO(d == NULL, NULL, 0);
137
138
139
*fileExists = __PHYSFS_platformExists(d);
if (*fileExists)
retval = __PHYSFS_platformIsDirectory(d);
140
141
142
143
144
free(d);
return(retval);
} /* DIR_isDirectory */
145
static int DIR_isSymLink(dvoid *opaque, const char *name, int *fileExists)
146
{
147
char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
148
int retval = 0;
149
150
BAIL_IF_MACRO(f == NULL, NULL, 0);
151
152
153
*fileExists = __PHYSFS_platformExists(f);
if (*fileExists)
retval = __PHYSFS_platformIsSymLink(f);
154
155
156
157
158
free(f);
return(retval);
} /* DIR_isSymLink */
159
static PHYSFS_sint64 DIR_getLastModTime(dvoid *opaque,
160
161
const char *name,
int *fileExists)
162
{
163
char *d = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
164
PHYSFS_sint64 retval = -1;
165
166
BAIL_IF_MACRO(d == NULL, NULL, 0);
167
168
169
*fileExists = __PHYSFS_platformExists(d);
if (*fileExists)
retval = __PHYSFS_platformGetLastModTime(d);
170
171
172
173
174
free(d);
return(retval);
} /* DIR_getLastModTime */
175
176
177
static fvoid *doOpen(dvoid *opaque, const char *name,
void *(*openFunc)(const char *filename),
int *fileExists)
178
{
179
char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
180
void *rc = NULL;
181
182
183
BAIL_IF_MACRO(f == NULL, NULL, NULL);
184
185
186
187
188
189
190
191
192
193
if (fileExists != NULL)
{
*fileExists = __PHYSFS_platformExists(f);
if (!(*fileExists))
{
free(f);
return(NULL);
} /* if */
} /* if */
194
rc = openFunc(f);
195
196
free(f);
197
return((fvoid *) rc);
198
199
200
} /* doOpen */
201
static fvoid *DIR_openRead(dvoid *opaque, const char *fnm, int *exist)
202
{
203
return(doOpen(opaque, fnm, __PHYSFS_platformOpenRead, exist));
204
205
206
} /* DIR_openRead */
207
static fvoid *DIR_openWrite(dvoid *opaque, const char *filename)
208
{
209
return(doOpen(opaque, filename, __PHYSFS_platformOpenWrite, NULL));
210
211
212
} /* DIR_openWrite */
213
static fvoid *DIR_openAppend(dvoid *opaque, const char *filename)
214
{
215
return(doOpen(opaque, filename, __PHYSFS_platformOpenAppend, NULL));
216
217
218
} /* DIR_openAppend */
219
static int DIR_remove(dvoid *opaque, const char *name)
220
{
221
char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
222
223
224
int retval;
BAIL_IF_MACRO(f == NULL, NULL, 0);
225
retval = __PHYSFS_platformDelete(f);
226
227
228
229
230
free(f);
return(retval);
} /* DIR_remove */
231
static int DIR_mkdir(dvoid *opaque, const char *name)
232
{
233
char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
234
235
236
int retval;
BAIL_IF_MACRO(f == NULL, NULL, 0);
237
retval = __PHYSFS_platformMkDir(f);
238
239
240
241
242
free(f);
return(retval);
} /* DIR_mkdir */
243
static void DIR_dirClose(dvoid *opaque)
244
{
245
free(opaque);
246
247
} /* DIR_dirClose */
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
const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_DIR =
{
"",
DIR_ARCHIVE_DESCRIPTION,
"Ryan C. Gordon <icculus@clutteredmind.org>",
"http://icculus.org/physfs/",
};
const PHYSFS_Archiver __PHYSFS_Archiver_DIR =
{
&__PHYSFS_ArchiveInfo_DIR,
DIR_isArchive, /* isArchive() method */
DIR_openArchive, /* openArchive() method */
DIR_enumerateFiles, /* enumerateFiles() method */
DIR_exists, /* exists() method */
DIR_isDirectory, /* isDirectory() method */
DIR_isSymLink, /* isSymLink() method */
DIR_getLastModTime, /* getLastModTime() method */
DIR_openRead, /* openRead() method */
DIR_openWrite, /* openWrite() method */
DIR_openAppend, /* openAppend() method */
DIR_remove, /* remove() method */
DIR_mkdir, /* mkdir() method */
DIR_dirClose, /* dirClose() method */
DIR_read, /* read() method */
DIR_write, /* write() method */
DIR_eof, /* eof() method */
DIR_tell, /* tell() method */
DIR_seek, /* seek() method */
DIR_fileLength, /* fileLength() method */
DIR_fileClose /* fileClose() method */
};
285
/* end of dir.c ... */