112 #define PHYSFS_SUPPORTS_MVL 0 |
112 #define PHYSFS_SUPPORTS_MVL 0 |
113 #endif |
113 #endif |
114 #ifndef PHYSFS_SUPPORTS_WAD |
114 #ifndef PHYSFS_SUPPORTS_WAD |
115 #define PHYSFS_SUPPORTS_WAD 0 |
115 #define PHYSFS_SUPPORTS_WAD 0 |
116 #endif |
116 #endif |
|
117 #ifndef PHYSFS_SUPPORTS_SLB |
|
118 #define PHYSFS_SUPPORTS_SLB 0 |
|
119 #endif |
117 #ifndef PHYSFS_SUPPORTS_ISO9660 |
120 #ifndef PHYSFS_SUPPORTS_ISO9660 |
118 #define PHYSFS_SUPPORTS_ISO9660 0 |
121 #define PHYSFS_SUPPORTS_ISO9660 0 |
119 #endif |
122 #endif |
120 |
123 |
121 /* The latest supported PHYSFS_Io::version value. */ |
124 /* The latest supported PHYSFS_Io::version value. */ |
122 #define CURRENT_PHYSFS_IO_API_VERSION 0 |
125 #define CURRENT_PHYSFS_IO_API_VERSION 0 |
123 |
126 |
124 /* Opaque data for file and dir handlers... */ |
127 /* The latest supported PHYSFS_Archiver::version value. */ |
125 typedef void PHYSFS_Dir; |
128 #define CURRENT_PHYSFS_ARCHIVER_API_VERSION 0 |
126 |
129 |
127 typedef struct |
130 /* This byteorder stuff was lifted from SDL. https://www.libsdl.org/ */ |
128 { |
|
129 /* |
|
130 * Basic info about this archiver... |
|
131 */ |
|
132 const PHYSFS_ArchiveInfo info; |
|
133 |
|
134 |
|
135 /* |
|
136 * DIRECTORY ROUTINES: |
|
137 * These functions are for dir handles. Generate a handle with the |
|
138 * openArchive() method, then pass it as the "opaque" PHYSFS_Dir to the |
|
139 * others. |
|
140 * |
|
141 * Symlinks should always be followed (except in stat()); PhysicsFS will |
|
142 * use the stat() method to check for symlinks and make a judgement on |
|
143 * whether to continue to call other methods based on that. |
|
144 */ |
|
145 |
|
146 /* |
|
147 * Open a dirhandle for dir/archive data provided by (io). |
|
148 * (name) is a filename associated with (io), but doesn't necessarily |
|
149 * map to anything, let alone a real filename. This possibly- |
|
150 * meaningless name is in platform-dependent notation. |
|
151 * (forWrite) is non-zero if this is to be used for |
|
152 * the write directory, and zero if this is to be used for an |
|
153 * element of the search path. |
|
154 * Returns NULL on failure. We ignore any error code you set here. |
|
155 * Returns non-NULL on success. The pointer returned will be |
|
156 * passed as the "opaque" parameter for later calls. |
|
157 */ |
|
158 PHYSFS_Dir *(*openArchive)(PHYSFS_Io *io, const char *name, int forWrite); |
|
159 |
|
160 /* |
|
161 * List all files in (dirname). Each file is passed to (cb), |
|
162 * where a copy is made if appropriate, so you should dispose of |
|
163 * it properly upon return from the callback. |
|
164 * You should omit symlinks if (omitSymLinks) is non-zero. |
|
165 * If you have a failure, report as much as you can. |
|
166 * (dirname) is in platform-independent notation. |
|
167 */ |
|
168 void (*enumerateFiles)(PHYSFS_Dir *opaque, const char *dirname, |
|
169 int omitSymLinks, PHYSFS_EnumFilesCallback cb, |
|
170 const char *origdir, void *callbackdata); |
|
171 |
|
172 /* |
|
173 * Open file for reading. |
|
174 * This filename, (fnm), is in platform-independent notation. |
|
175 * If you can't handle multiple opens of the same file, |
|
176 * you can opt to fail for the second call. |
|
177 * Fail if the file does not exist. |
|
178 * Returns NULL on failure, and calls __PHYSFS_setError(). |
|
179 * Returns non-NULL on success. The pointer returned will be |
|
180 * passed as the "opaque" parameter for later file calls. |
|
181 * |
|
182 * Regardless of success or failure, please set *exists to |
|
183 * non-zero if the file existed (even if it's a broken symlink!), |
|
184 * zero if it did not. |
|
185 */ |
|
186 PHYSFS_Io *(*openRead)(PHYSFS_Dir *opaque, const char *fnm, int *exists); |
|
187 |
|
188 /* |
|
189 * Open file for writing. |
|
190 * If the file does not exist, it should be created. If it exists, |
|
191 * it should be truncated to zero bytes. The writing |
|
192 * offset should be the start of the file. |
|
193 * This filename is in platform-independent notation. |
|
194 * If you can't handle multiple opens of the same file, |
|
195 * you can opt to fail for the second call. |
|
196 * Returns NULL on failure, and calls __PHYSFS_setError(). |
|
197 * Returns non-NULL on success. The pointer returned will be |
|
198 * passed as the "opaque" parameter for later file calls. |
|
199 */ |
|
200 PHYSFS_Io *(*openWrite)(PHYSFS_Dir *opaque, const char *filename); |
|
201 |
|
202 /* |
|
203 * Open file for appending. |
|
204 * If the file does not exist, it should be created. The writing |
|
205 * offset should be the end of the file. |
|
206 * This filename is in platform-independent notation. |
|
207 * If you can't handle multiple opens of the same file, |
|
208 * you can opt to fail for the second call. |
|
209 * Returns NULL on failure, and calls __PHYSFS_setError(). |
|
210 * Returns non-NULL on success. The pointer returned will be |
|
211 * passed as the "opaque" parameter for later file calls. |
|
212 */ |
|
213 PHYSFS_Io *(*openAppend)(PHYSFS_Dir *opaque, const char *filename); |
|
214 |
|
215 /* |
|
216 * Delete a file in the archive/directory. |
|
217 * Return non-zero on success, zero on failure. |
|
218 * This filename is in platform-independent notation. |
|
219 * This method may be NULL. |
|
220 * On failure, call __PHYSFS_setError(). |
|
221 */ |
|
222 int (*remove)(PHYSFS_Dir *opaque, const char *filename); |
|
223 |
|
224 /* |
|
225 * Create a directory in the archive/directory. |
|
226 * If the application is trying to make multiple dirs, PhysicsFS |
|
227 * will split them up into multiple calls before passing them to |
|
228 * your driver. |
|
229 * Return non-zero on success, zero on failure. |
|
230 * This filename is in platform-independent notation. |
|
231 * This method may be NULL. |
|
232 * On failure, call __PHYSFS_setError(). |
|
233 */ |
|
234 int (*mkdir)(PHYSFS_Dir *opaque, const char *filename); |
|
235 |
|
236 /* |
|
237 * Close directories/archives, and free any associated memory, |
|
238 * including the original PHYSFS_Io and (opaque) itself, if |
|
239 * applicable. Implementation can assume that it won't be called if |
|
240 * there are still files open from this archive. |
|
241 */ |
|
242 void (*closeArchive)(PHYSFS_Dir *opaque); |
|
243 |
|
244 /* |
|
245 * Obtain basic file metadata. |
|
246 * Returns non-zero on success, zero on failure. |
|
247 * On failure, call __PHYSFS_setError(). |
|
248 */ |
|
249 int (*stat)(PHYSFS_Dir *opaque, const char *fn, |
|
250 int *exists, PHYSFS_Stat *stat); |
|
251 } PHYSFS_Archiver; |
|
252 |
|
253 |
|
254 /* |
|
255 * Call this to set the message returned by PHYSFS_getLastError(). |
|
256 * Please only use the ERR_* constants above, or add new constants to the |
|
257 * above group, but I want these all in one place. |
|
258 * |
|
259 * Calling this with a NULL argument is a safe no-op. |
|
260 */ |
|
261 void __PHYSFS_setError(const PHYSFS_ErrorCode err); |
|
262 |
|
263 |
|
264 /* This byteorder stuff was lifted from SDL. http://www.libsdl.org/ */ |
|
265 #define PHYSFS_LIL_ENDIAN 1234 |
131 #define PHYSFS_LIL_ENDIAN 1234 |
266 #define PHYSFS_BIG_ENDIAN 4321 |
132 #define PHYSFS_BIG_ENDIAN 4321 |
267 |
133 |
268 #if defined(__i386__) || defined(__ia64__) || \ |
134 #ifdef __linux__ |
269 defined(_M_IX86) || defined(_M_IA64) || defined(_M_X64) || \ |
135 #include <endian.h> |
270 (defined(__alpha__) || defined(__alpha)) || \ |
136 #define PHYSFS_BYTEORDER __BYTE_ORDER |
271 defined(__arm__) || defined(ARM) || \ |
137 #else /* __linux__ */ |
272 (defined(__mips__) && defined(__MIPSEL__)) || \ |
138 #if defined(__hppa__) || \ |
273 defined(__SYMBIAN32__) || \ |
139 defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ |
274 defined(__x86_64__) || \ |
140 (defined(__MIPS__) && defined(__MISPEB__)) || \ |
275 defined(__LITTLE_ENDIAN__) |
141 defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ |
276 #define PHYSFS_BYTEORDER PHYSFS_LIL_ENDIAN |
142 defined(__sparc__) |
|
143 #define PHYSFS_BYTEORDER PHYSFS_BIG_ENDIAN |
277 #else |
144 #else |
278 #define PHYSFS_BYTEORDER PHYSFS_BIG_ENDIAN |
145 #define PHYSFS_BYTEORDER PHYSFS_LIL_ENDIAN |
279 #endif |
146 #endif |
|
147 #endif /* __linux__ */ |
280 |
148 |
281 |
149 |
282 /* |
150 /* |
283 * When sorting the entries in an archive, we use a modified QuickSort. |
151 * When sorting the entries in an archive, we use a modified QuickSort. |
284 * When there are less then PHYSFS_QUICKSORT_THRESHOLD entries left to sort, |
152 * When there are less then PHYSFS_QUICKSORT_THRESHOLD entries left to sort, |
308 * It means: there was an error, but someone else already set it for us. |
174 * It means: there was an error, but someone else already set it for us. |
309 */ |
175 */ |
310 #define ERRPASS PHYSFS_ERR_OK |
176 #define ERRPASS PHYSFS_ERR_OK |
311 |
177 |
312 /* These get used all over for lessening code clutter. */ |
178 /* These get used all over for lessening code clutter. */ |
313 #define BAIL_MACRO(e, r) do { if (e) __PHYSFS_setError(e); return r; } while (0) |
179 #define BAIL_MACRO(e, r) do { if (e) PHYSFS_setErrorCode(e); return r; } while (0) |
314 #define BAIL_IF_MACRO(c, e, r) do { if (c) { if (e) __PHYSFS_setError(e); return r; } } while (0) |
180 #define BAIL_IF_MACRO(c, e, r) do { if (c) { if (e) PHYSFS_setErrorCode(e); return r; } } while (0) |
315 #define BAIL_MACRO_MUTEX(e, m, r) do { if (e) __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); return r; } while (0) |
181 #define BAIL_MACRO_MUTEX(e, m, r) do { if (e) PHYSFS_setErrorCode(e); __PHYSFS_platformReleaseMutex(m); return r; } while (0) |
316 #define BAIL_IF_MACRO_MUTEX(c, e, m, r) do { if (c) { if (e) __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); return r; } } while (0) |
182 #define BAIL_IF_MACRO_MUTEX(c, e, m, r) do { if (c) { if (e) PHYSFS_setErrorCode(e); __PHYSFS_platformReleaseMutex(m); return r; } } while (0) |
317 #define GOTO_MACRO(e, g) do { if (e) __PHYSFS_setError(e); goto g; } while (0) |
183 #define GOTO_MACRO(e, g) do { if (e) PHYSFS_setErrorCode(e); goto g; } while (0) |
318 #define GOTO_IF_MACRO(c, e, g) do { if (c) { if (e) __PHYSFS_setError(e); goto g; } } while (0) |
184 #define GOTO_IF_MACRO(c, e, g) do { if (c) { if (e) PHYSFS_setErrorCode(e); goto g; } } while (0) |
319 #define GOTO_MACRO_MUTEX(e, m, g) do { if (e) __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); goto g; } while (0) |
185 #define GOTO_MACRO_MUTEX(e, m, g) do { if (e) PHYSFS_setErrorCode(e); __PHYSFS_platformReleaseMutex(m); goto g; } while (0) |
320 #define GOTO_IF_MACRO_MUTEX(c, e, m, g) do { if (c) { if (e) __PHYSFS_setError(e); __PHYSFS_platformReleaseMutex(m); goto g; } } while (0) |
186 #define GOTO_IF_MACRO_MUTEX(c, e, m, g) do { if (c) { if (e) PHYSFS_setErrorCode(e); __PHYSFS_platformReleaseMutex(m); goto g; } } while (0) |
321 |
187 |
322 #define __PHYSFS_ARRAYLEN(x) ( (sizeof (x)) / (sizeof (x[0])) ) |
188 #define __PHYSFS_ARRAYLEN(x) ( (sizeof (x)) / (sizeof (x[0])) ) |
323 |
189 |
324 #ifdef PHYSFS_NO_64BIT_SUPPORT |
190 #ifdef PHYSFS_NO_64BIT_SUPPORT |
325 #define __PHYSFS_SI64(x) ((PHYSFS_sint64) (x)) |
191 #define __PHYSFS_SI64(x) ((PHYSFS_sint64) (x)) |
415 |
291 |
416 /* These are shared between some archivers. */ |
292 /* These are shared between some archivers. */ |
417 |
293 |
418 typedef struct |
294 typedef struct |
419 { |
295 { |
420 char name[56]; |
296 char name[64]; |
421 PHYSFS_uint32 startPos; |
297 PHYSFS_uint32 startPos; |
422 PHYSFS_uint32 size; |
298 PHYSFS_uint32 size; |
423 } UNPKentry; |
299 } UNPKentry; |
424 |
300 |
425 void UNPK_closeArchive(PHYSFS_Dir *opaque); |
301 void UNPK_closeArchive(void *opaque); |
426 PHYSFS_Dir *UNPK_openArchive(PHYSFS_Io *io,UNPKentry *e,const PHYSFS_uint32 n); |
302 void *UNPK_openArchive(PHYSFS_Io *io,UNPKentry *e,const PHYSFS_uint32 n); |
427 void UNPK_enumerateFiles(PHYSFS_Dir *opaque, const char *dname, |
303 void UNPK_enumerateFiles(void *opaque, const char *dname, |
428 int omitSymLinks, PHYSFS_EnumFilesCallback cb, |
304 PHYSFS_EnumFilesCallback cb, |
429 const char *origdir, void *callbackdata); |
305 const char *origdir, void *callbackdata); |
430 PHYSFS_Io *UNPK_openRead(PHYSFS_Dir *opaque, const char *fnm, int *fileExists); |
306 PHYSFS_Io *UNPK_openRead(void *opaque, const char *name); |
431 PHYSFS_Io *UNPK_openWrite(PHYSFS_Dir *opaque, const char *name); |
307 PHYSFS_Io *UNPK_openWrite(void *opaque, const char *name); |
432 PHYSFS_Io *UNPK_openAppend(PHYSFS_Dir *opaque, const char *name); |
308 PHYSFS_Io *UNPK_openAppend(void *opaque, const char *name); |
433 int UNPK_remove(PHYSFS_Dir *opaque, const char *name); |
309 int UNPK_remove(void *opaque, const char *name); |
434 int UNPK_mkdir(PHYSFS_Dir *opaque, const char *name); |
310 int UNPK_mkdir(void *opaque, const char *name); |
435 int UNPK_stat(PHYSFS_Dir *opaque, const char *fn, int *exist, PHYSFS_Stat *st); |
311 int UNPK_stat(void *opaque, const char *fn, PHYSFS_Stat *st); |
436 |
312 |
437 |
313 |
438 /*--------------------------------------------------------------------------*/ |
314 /*--------------------------------------------------------------------------*/ |
439 /*--------------------------------------------------------------------------*/ |
315 /*--------------------------------------------------------------------------*/ |
440 /*------------ ----------------*/ |
316 /*------------ ----------------*/ |
576 * the file. (opaque) should be cast to whatever data type your platform |
452 * the file. (opaque) should be cast to whatever data type your platform |
577 * uses. |
453 * uses. |
578 * |
454 * |
579 * Not all file types can "tell"; this is to be expected by the caller. |
455 * Not all file types can "tell"; this is to be expected by the caller. |
580 * |
456 * |
581 * On error, call __PHYSFS_setError() and return -1. On success, return >= 0. |
457 * On error, call PHYSFS_setErrorCode() and return -1. On success, return >= 0. |
582 */ |
458 */ |
583 PHYSFS_sint64 __PHYSFS_platformTell(void *opaque); |
459 PHYSFS_sint64 __PHYSFS_platformTell(void *opaque); |
584 |
460 |
585 |
461 |
586 /* |
462 /* |
587 * Determine the current size of a file, in 8-bit bytes, from an open file. |
463 * Determine the current size of a file, in 8-bit bytes, from an open file. |
588 * |
464 * |
589 * The caller expects that this information may not be available for all |
465 * The caller expects that this information may not be available for all |
590 * file types on all platforms. |
466 * file types on all platforms. |
591 * |
467 * |
592 * Return -1 if you can't do it, and call __PHYSFS_setError(). Otherwise, |
468 * Return -1 if you can't do it, and call PHYSFS_setErrorCode(). Otherwise, |
593 * return the file length in 8-bit bytes. |
469 * return the file length in 8-bit bytes. |
594 */ |
470 */ |
595 PHYSFS_sint64 __PHYSFS_platformFileLength(void *handle); |
471 PHYSFS_sint64 __PHYSFS_platformFileLength(void *handle); |
596 |
472 |
597 |
473 |
598 /* |
474 /* |
599 * !!! FIXME: comment me. |
475 * !!! FIXME: comment me. |
600 */ |
476 */ |
601 int __PHYSFS_platformStat(const char *fn, int *exists, PHYSFS_Stat *stat); |
477 int __PHYSFS_platformStat(const char *fn, PHYSFS_Stat *stat); |
602 |
478 |
603 /* |
479 /* |
604 * Flush any pending writes to disk. (opaque) should be cast to whatever data |
480 * Flush any pending writes to disk. (opaque) should be cast to whatever data |
605 * type your platform uses. Be sure to check for errors; the caller expects |
481 * type your platform uses. Be sure to check for errors; the caller expects |
606 * that this function can fail if there was a flushing error, etc. |
482 * that this function can fail if there was a flushing error, etc. |
724 void __PHYSFS_platformDestroyMutex(void *mutex); |
599 void __PHYSFS_platformDestroyMutex(void *mutex); |
725 |
600 |
726 /* |
601 /* |
727 * Grab possession of a platform-specific mutex. Mutexes should be recursive; |
602 * Grab possession of a platform-specific mutex. Mutexes should be recursive; |
728 * that is, the same thread should be able to call this function multiple |
603 * that is, the same thread should be able to call this function multiple |
729 * times in a row without causing a deadlock. This function should block |
604 * times in a row without causing a deadlock. This function should block |
730 * until a thread can gain possession of the mutex. |
605 * until a thread can gain possession of the mutex. |
731 * |
606 * |
732 * Return non-zero if the mutex was grabbed, zero if there was an |
607 * Return non-zero if the mutex was grabbed, zero if there was an |
733 * unrecoverable problem grabbing it (this should not be a matter of |
608 * unrecoverable problem grabbing it (this should not be a matter of |
734 * timing out! We're talking major system errors; block until the mutex |
609 * timing out! We're talking major system errors; block until the mutex |
735 * is available otherwise.) |
610 * is available otherwise.) |
736 * |
611 * |
737 * _DO NOT_ call __PHYSFS_setError() in here! Since setError calls this |
612 * _DO NOT_ call PHYSFS_setErrorCode() in here! Since setErrorCode calls this |
738 * function, you'll cause an infinite recursion. This means you can't |
613 * function, you'll cause an infinite recursion. This means you can't |
739 * use the BAIL_*MACRO* macros, either. |
614 * use the BAIL_*MACRO* macros, either. |
740 */ |
615 */ |
741 int __PHYSFS_platformGrabMutex(void *mutex); |
616 int __PHYSFS_platformGrabMutex(void *mutex); |
742 |
617 |
743 /* |
618 /* |
744 * Relinquish possession of the mutex when this method has been called |
619 * Relinquish possession of the mutex when this method has been called |
745 * once for each time that platformGrabMutex was called. Once possession has |
620 * once for each time that platformGrabMutex was called. Once possession has |
746 * been released, the next thread in line to grab the mutex (if any) may |
621 * been released, the next thread in line to grab the mutex (if any) may |
747 * proceed. |
622 * proceed. |
748 * |
623 * |
749 * _DO NOT_ call __PHYSFS_setError() in here! Since setError calls this |
624 * _DO NOT_ call PHYSFS_setErrorCode() in here! Since setErrorCode calls this |
750 * function, you'll cause an infinite recursion. This means you can't |
625 * function, you'll cause an infinite recursion. This means you can't |
751 * use the BAIL_*MACRO* macros, either. |
626 * use the BAIL_*MACRO* macros, either. |
752 */ |
627 */ |
753 void __PHYSFS_platformReleaseMutex(void *mutex); |
628 void __PHYSFS_platformReleaseMutex(void *mutex); |
754 |
629 |