src/physfs.c
author Ryan C. Gordon <icculus@icculus.org>
Mon, 14 Aug 2017 11:43:18 -0400
changeset 1575 be0a87101943
parent 1574 87100b3836cd
child 1576 b25da658b8ee
permissions -rw-r--r--
Fix symlink filtering for enumeration under a virtual mount point.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     1
/**
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     2
 * PhysicsFS; a portable, flexible file i/o abstraction.
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     3
 *
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     4
 * Documentation is in physfs.h. It's verbose, honest.  :)
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     5
 *
809
116b8fe30371 Renamed LICENSE to LICENSE.txt
Ryan C. Gordon <icculus@icculus.org>
parents: 808
diff changeset
     6
 * Please see the file LICENSE.txt in the source's root directory.
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     7
 *
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     8
 *  This file written by Ryan C. Gordon.
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
     9
 */
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    10
7
07d5e6e8259d More work. Getting better.
Ryan C. Gordon <icculus@icculus.org>
parents: 5
diff changeset
    11
#define __PHYSICSFS_INTERNAL__
07d5e6e8259d More work. Getting better.
Ryan C. Gordon <icculus@icculus.org>
parents: 5
diff changeset
    12
#include "physfs_internal.h"
07d5e6e8259d More work. Getting better.
Ryan C. Gordon <icculus@icculus.org>
parents: 5
diff changeset
    13
1429
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    14
#if defined(_MSC_VER)
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    15
#include <stdarg.h>
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    16
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    17
/* this code came from https://stackoverflow.com/a/8712996 */
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    18
int __PHYSFS_msvc_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    19
{
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    20
    int count = -1;
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    21
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    22
    if (size != 0)
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    23
        count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    24
    if (count == -1)
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    25
        count = _vscprintf(format, ap);
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    26
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    27
    return count;
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    28
}
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    29
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    30
int __PHYSFS_msvc_snprintf(char *outBuf, size_t size, const char *format, ...)
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    31
{
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    32
    int count;
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    33
    va_list ap;
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    34
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    35
    va_start(ap, format);
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    36
    count = __PHYSFS_msvc_vsnprintf(outBuf, size, format, ap);
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    37
    va_end(ap);
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    38
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    39
    return count;
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    40
}
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    41
#endif
cd23c2c2d730 Patched to compile on Visual Studio.
Ryan C. Gordon <icculus@icculus.org>
parents: 1428
diff changeset
    42
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
    43
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
    44
typedef struct __PHYSFS_DIRHANDLE__
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
    45
{
650
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    46
    void *opaque;  /* Instance data unique to the archiver. */
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    47
    char *dirName;  /* Path to archive in platform-dependent notation. */
679
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
    48
    char *mountPoint; /* Mountpoint in virtual file tree. */
650
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    49
    const PHYSFS_Archiver *funcs;  /* Ptr to archiver info for this handle. */
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    50
    struct __PHYSFS_DIRHANDLE__ *next;  /* linked list stuff. */
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    51
} DirHandle;
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    52
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
    53
650
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    54
typedef struct __PHYSFS_FILEHANDLE__
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    55
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
    56
    PHYSFS_Io *io;  /* Instance data unique to the archiver for this file. */
650
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    57
    PHYSFS_uint8 forReading; /* Non-zero if reading, zero if write/append */
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    58
    const DirHandle *dirHandle;  /* Archiver instance that created this */
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    59
    PHYSFS_uint8 *buffer;  /* Buffer, if set (NULL otherwise). Don't touch! */
1540
7ee52240b696 PHYSFS_File buffering now uses size_t.
Ryan C. Gordon <icculus@icculus.org>
parents: 1538
diff changeset
    60
    size_t bufsize;  /* Bufsize, if set (0 otherwise). Don't touch! */
7ee52240b696 PHYSFS_File buffering now uses size_t.
Ryan C. Gordon <icculus@icculus.org>
parents: 1538
diff changeset
    61
    size_t buffill;  /* Buffer fill size. Don't touch! */
7ee52240b696 PHYSFS_File buffering now uses size_t.
Ryan C. Gordon <icculus@icculus.org>
parents: 1538
diff changeset
    62
    size_t bufpos;  /* Buffer position. Don't touch! */
650
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    63
    struct __PHYSFS_FILEHANDLE__ *next;  /* linked list stuff. */
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    64
} FileHandle;
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
    65
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
    66
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
    67
typedef struct __PHYSFS_ERRSTATETYPE__
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    68
{
1012
f254870dd7dd Attempt to clean up the thread ID mess in platform_unix ...
Ryan C. Gordon <icculus@icculus.org>
parents: 986
diff changeset
    69
    void *tid;
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
    70
    PHYSFS_ErrorCode code;
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
    71
    struct __PHYSFS_ERRSTATETYPE__ *next;
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
    72
} ErrState;
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    73
11
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    74
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    75
/* General PhysicsFS state ... */
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    76
static int initialized = 0;
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
    77
static ErrState *errorStates = NULL;
650
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    78
static DirHandle *searchPath = NULL;
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    79
static DirHandle *writeDir = NULL;
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    80
static FileHandle *openWriteList = NULL;
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
    81
static FileHandle *openReadList = NULL;
11
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    82
static char *baseDir = NULL;
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    83
static char *userDir = NULL;
1242
1e6db80d2393 Added PHYSFS_getPrefDir().
Ryan C. Gordon <icculus@icculus.org>
parents: 1240
diff changeset
    84
static char *prefDir = NULL;
11
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    85
static int allowSymLinks = 0;
1456
2328964939fd Fixed compiler warnings on Visual Studio about const qualifiers.
Ryan C. Gordon <icculus@icculus.org>
parents: 1449
diff changeset
    86
static PHYSFS_Archiver **archivers = NULL;
2328964939fd Fixed compiler warnings on Visual Studio about const qualifiers.
Ryan C. Gordon <icculus@icculus.org>
parents: 1449
diff changeset
    87
static PHYSFS_ArchiveInfo **archiveInfo = NULL;
1322
5476917b8ddf Allow application-supplied archivers.
Ryan C. Gordon <icculus@icculus.org>
parents: 1315
diff changeset
    88
static volatile size_t numArchivers = 0;
11
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    89
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
    90
/* mutexes ... */
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
    91
static void *errorLock = NULL;     /* protects error message list.        */
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
    92
static void *stateLock = NULL;     /* protects other PhysFS static state. */
11
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    93
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 634
diff changeset
    94
/* allocator ... */
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 634
diff changeset
    95
static int externalAllocator = 0;
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 688
diff changeset
    96
PHYSFS_Allocator allocator;
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 634
diff changeset
    97
11
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    98
1538
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
    99
#ifdef PHYSFS_NEED_ATOMIC_OP_FALLBACK
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   100
static inline int __PHYSFS_atomicAdd(int *ptrval, const int val)
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   101
{
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   102
    int retval;
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   103
    __PHYSFS_platformGrabMutex(stateLock);
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   104
    retval = *ptrval;
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   105
    *ptrval = retval + val;
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   106
    __PHYSFS_platformReleaseMutex(stateLock);
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   107
    return retval;
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   108
} /* __PHYSFS_atomicAdd */
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   109
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   110
int __PHYSFS_ATOMIC_INCR(int *ptrval)
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   111
{
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   112
    return __PHYSFS_atomicAdd(ptrval, 1);
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   113
} /* __PHYSFS_ATOMIC_INCR */
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   114
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   115
int __PHYSFS_ATOMIC_DECR(int *ptrval)
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   116
{
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   117
    return __PHYSFS_atomicAdd(ptrval, -1);
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   118
} /* __PHYSFS_ATOMIC_DECR */
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   119
#endif
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   120
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   121
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   122
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   123
/* PHYSFS_Io implementation for i/o to physical filesystem... */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   124
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   125
/* !!! FIXME: maybe refcount the paths in a string pool? */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   126
typedef struct __PHYSFS_NativeIoInfo
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   127
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   128
    void *handle;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   129
    const char *path;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   130
    int mode;   /* 'r', 'w', or 'a' */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   131
} NativeIoInfo;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   132
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   133
static PHYSFS_sint64 nativeIo_read(PHYSFS_Io *io, void *buf, PHYSFS_uint64 len)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   134
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   135
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   136
    return __PHYSFS_platformRead(info->handle, buf, len);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   137
} /* nativeIo_read */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   138
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   139
static PHYSFS_sint64 nativeIo_write(PHYSFS_Io *io, const void *buffer,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   140
                                    PHYSFS_uint64 len)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   141
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   142
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   143
    return __PHYSFS_platformWrite(info->handle, buffer, len);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   144
} /* nativeIo_write */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   145
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   146
static int nativeIo_seek(PHYSFS_Io *io, PHYSFS_uint64 offset)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   147
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   148
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   149
    return __PHYSFS_platformSeek(info->handle, offset);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   150
} /* nativeIo_seek */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   151
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   152
static PHYSFS_sint64 nativeIo_tell(PHYSFS_Io *io)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   153
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   154
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   155
    return __PHYSFS_platformTell(info->handle);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   156
} /* nativeIo_tell */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   157
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   158
static PHYSFS_sint64 nativeIo_length(PHYSFS_Io *io)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   159
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   160
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   161
    return __PHYSFS_platformFileLength(info->handle);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   162
} /* nativeIo_length */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   163
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   164
static PHYSFS_Io *nativeIo_duplicate(PHYSFS_Io *io)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   165
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   166
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   167
    return __PHYSFS_createNativeIo(info->path, info->mode);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   168
} /* nativeIo_duplicate */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   169
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   170
static int nativeIo_flush(PHYSFS_Io *io)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   171
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   172
    return __PHYSFS_platformFlush(io->opaque);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   173
} /* nativeIo_flush */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   174
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   175
static void nativeIo_destroy(PHYSFS_Io *io)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   176
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   177
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   178
    __PHYSFS_platformClose(info->handle);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   179
    allocator.Free((void *) info->path);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   180
    allocator.Free(info);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   181
    allocator.Free(io);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   182
} /* nativeIo_destroy */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   183
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   184
static const PHYSFS_Io __PHYSFS_nativeIoInterface =
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   185
{
1280
bd174b99fa5b Add binary compatibility to PHYSFS_Io.
Ryan C. Gordon <icculus@icculus.org>
parents: 1279
diff changeset
   186
    CURRENT_PHYSFS_IO_API_VERSION, NULL,
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   187
    nativeIo_read,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   188
    nativeIo_write,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   189
    nativeIo_seek,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   190
    nativeIo_tell,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   191
    nativeIo_length,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   192
    nativeIo_duplicate,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   193
    nativeIo_flush,
1280
bd174b99fa5b Add binary compatibility to PHYSFS_Io.
Ryan C. Gordon <icculus@icculus.org>
parents: 1279
diff changeset
   194
    nativeIo_destroy
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   195
};
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   196
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   197
PHYSFS_Io *__PHYSFS_createNativeIo(const char *path, const int mode)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   198
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   199
    PHYSFS_Io *io = NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   200
    NativeIoInfo *info = NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   201
    void *handle = NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   202
    char *pathdup = NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   203
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   204
    assert((mode == 'r') || (mode == 'w') || (mode == 'a'));
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   205
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   206
    io = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   207
    GOTO_IF(!io, PHYSFS_ERR_OUT_OF_MEMORY, createNativeIo_failed);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   208
    info = (NativeIoInfo *) allocator.Malloc(sizeof (NativeIoInfo));
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   209
    GOTO_IF(!info, PHYSFS_ERR_OUT_OF_MEMORY, createNativeIo_failed);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   210
    pathdup = (char *) allocator.Malloc(strlen(path) + 1);
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   211
    GOTO_IF(!pathdup, PHYSFS_ERR_OUT_OF_MEMORY, createNativeIo_failed);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   212
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   213
    if (mode == 'r')
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   214
        handle = __PHYSFS_platformOpenRead(path);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   215
    else if (mode == 'w')
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   216
        handle = __PHYSFS_platformOpenWrite(path);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   217
    else if (mode == 'a')
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   218
        handle = __PHYSFS_platformOpenAppend(path);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   219
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   220
    GOTO_IF_ERRPASS(!handle, createNativeIo_failed);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   221
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   222
    strcpy(pathdup, path);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   223
    info->handle = handle;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   224
    info->path = pathdup;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   225
    info->mode = mode;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   226
    memcpy(io, &__PHYSFS_nativeIoInterface, sizeof (*io));
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   227
    io->opaque = info;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   228
    return io;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   229
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   230
createNativeIo_failed:
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   231
    if (handle != NULL) __PHYSFS_platformClose(handle);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   232
    if (pathdup != NULL) allocator.Free(pathdup);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   233
    if (info != NULL) allocator.Free(info);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   234
    if (io != NULL) allocator.Free(io);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   235
    return NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   236
} /* __PHYSFS_createNativeIo */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   237
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   238
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   239
/* PHYSFS_Io implementation for i/o to a memory buffer... */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   240
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   241
typedef struct __PHYSFS_MemoryIoInfo
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   242
{
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   243
    const PHYSFS_uint8 *buf;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   244
    PHYSFS_uint64 len;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   245
    PHYSFS_uint64 pos;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   246
    PHYSFS_Io *parent;
1546
f42ba130a039 Fixed compiler warnings on GCC.
Ryan C. Gordon <icculus@icculus.org>
parents: 1545
diff changeset
   247
    int refcount;
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   248
    void (*destruct)(void *);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   249
} MemoryIoInfo;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   250
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   251
static PHYSFS_sint64 memoryIo_read(PHYSFS_Io *io, void *buf, PHYSFS_uint64 len)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   252
{
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   253
    MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   254
    const PHYSFS_uint64 avail = info->len - info->pos;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   255
    assert(avail <= info->len);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   256
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   257
    if (avail == 0)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   258
        return 0;  /* we're at EOF; nothing to do. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   259
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   260
    if (len > avail)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   261
        len = avail;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   262
1208
3edcb015089a Fixed some compiler warnings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1204
diff changeset
   263
    memcpy(buf, info->buf + info->pos, (size_t) len);
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   264
    info->pos += len;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   265
    return len;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   266
} /* memoryIo_read */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   267
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   268
static PHYSFS_sint64 memoryIo_write(PHYSFS_Io *io, const void *buffer,
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   269
                                    PHYSFS_uint64 len)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   270
{
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   271
    BAIL(PHYSFS_ERR_OPEN_FOR_READING, -1);
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   272
} /* memoryIo_write */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   273
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   274
static int memoryIo_seek(PHYSFS_Io *io, PHYSFS_uint64 offset)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   275
{
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   276
    MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   277
    BAIL_IF(offset > info->len, PHYSFS_ERR_PAST_EOF, 0);
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   278
    info->pos = offset;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   279
    return 1;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   280
} /* memoryIo_seek */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   281
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   282
static PHYSFS_sint64 memoryIo_tell(PHYSFS_Io *io)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   283
{
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   284
    const MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   285
    return (PHYSFS_sint64) info->pos;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   286
} /* memoryIo_tell */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   287
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   288
static PHYSFS_sint64 memoryIo_length(PHYSFS_Io *io)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   289
{
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   290
    const MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   291
    return (PHYSFS_sint64) info->len;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   292
} /* memoryIo_length */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   293
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   294
static PHYSFS_Io *memoryIo_duplicate(PHYSFS_Io *io)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   295
{
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   296
    MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   297
    MemoryIoInfo *newinfo = NULL;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   298
    PHYSFS_Io *parent = info->parent;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   299
    PHYSFS_Io *retval = NULL;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   300
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   301
    /* avoid deep copies. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   302
    assert((!parent) || (!((MemoryIoInfo *) parent->opaque)->parent) );
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   303
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   304
    /* share the buffer between duplicates. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   305
    if (parent != NULL)  /* dup the parent, increment its refcount. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   306
        return parent->duplicate(parent);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   307
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   308
    /* we're the parent. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   309
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   310
    retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   311
    BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   312
    newinfo = (MemoryIoInfo *) allocator.Malloc(sizeof (MemoryIoInfo));
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   313
    if (!newinfo)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   314
    {
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   315
        allocator.Free(retval);
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   316
        BAIL(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   317
    } /* if */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   318
1538
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   319
    __PHYSFS_ATOMIC_INCR(&info->refcount);
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   320
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   321
    memset(newinfo, '\0', sizeof (*info));
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   322
    newinfo->buf = info->buf;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   323
    newinfo->len = info->len;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   324
    newinfo->pos = 0;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   325
    newinfo->parent = io;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   326
    newinfo->refcount = 0;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   327
    newinfo->destruct = NULL;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   328
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   329
    memcpy(retval, io, sizeof (*retval));
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   330
    retval->opaque = newinfo;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   331
    return retval;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   332
} /* memoryIo_duplicate */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   333
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   334
static int memoryIo_flush(PHYSFS_Io *io) { return 1;  /* it's read-only. */ }
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   335
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   336
static void memoryIo_destroy(PHYSFS_Io *io)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   337
{
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   338
    MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   339
    PHYSFS_Io *parent = info->parent;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   340
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   341
    if (parent != NULL)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   342
    {
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   343
        assert(info->buf == ((MemoryIoInfo *) info->parent->opaque)->buf);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   344
        assert(info->len == ((MemoryIoInfo *) info->parent->opaque)->len);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   345
        assert(info->refcount == 0);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   346
        assert(info->destruct == NULL);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   347
        allocator.Free(info);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   348
        allocator.Free(io);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   349
        parent->destroy(parent);  /* decrements refcount. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   350
        return;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   351
    } /* if */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   352
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   353
    /* we _are_ the parent. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   354
    assert(info->refcount > 0);  /* even in a race, we hold a reference. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   355
1538
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   356
    if (__PHYSFS_ATOMIC_DECR(&info->refcount) == 0)
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   357
    {
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   358
        void (*destruct)(void *) = info->destruct;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   359
        void *buf = (void *) info->buf;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   360
        io->opaque = NULL;  /* kill this here in case of race. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   361
        allocator.Free(info);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   362
        allocator.Free(io);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   363
        if (destruct != NULL)
1191
f02c977477b9 Fixed up some bugs that clang's static analysis reported.
Ryan C. Gordon <icculus@icculus.org>
parents: 1135
diff changeset
   364
            destruct(buf);
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   365
    } /* if */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   366
} /* memoryIo_destroy */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   367
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   368
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   369
static const PHYSFS_Io __PHYSFS_memoryIoInterface =
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   370
{
1280
bd174b99fa5b Add binary compatibility to PHYSFS_Io.
Ryan C. Gordon <icculus@icculus.org>
parents: 1279
diff changeset
   371
    CURRENT_PHYSFS_IO_API_VERSION, NULL,
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   372
    memoryIo_read,
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   373
    memoryIo_write,
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   374
    memoryIo_seek,
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   375
    memoryIo_tell,
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   376
    memoryIo_length,
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   377
    memoryIo_duplicate,
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   378
    memoryIo_flush,
1280
bd174b99fa5b Add binary compatibility to PHYSFS_Io.
Ryan C. Gordon <icculus@icculus.org>
parents: 1279
diff changeset
   379
    memoryIo_destroy
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   380
};
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   381
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   382
PHYSFS_Io *__PHYSFS_createMemoryIo(const void *buf, PHYSFS_uint64 len,
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   383
                                   void (*destruct)(void *))
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   384
{
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   385
    PHYSFS_Io *io = NULL;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   386
    MemoryIoInfo *info = NULL;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   387
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   388
    io = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   389
    GOTO_IF(!io, PHYSFS_ERR_OUT_OF_MEMORY, createMemoryIo_failed);
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   390
    info = (MemoryIoInfo *) allocator.Malloc(sizeof (MemoryIoInfo));
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   391
    GOTO_IF(!info, PHYSFS_ERR_OUT_OF_MEMORY, createMemoryIo_failed);
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   392
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   393
    memset(info, '\0', sizeof (*info));
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   394
    info->buf = (const PHYSFS_uint8 *) buf;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   395
    info->len = len;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   396
    info->pos = 0;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   397
    info->parent = NULL;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   398
    info->refcount = 1;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   399
    info->destruct = destruct;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   400
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   401
    memcpy(io, &__PHYSFS_memoryIoInterface, sizeof (*io));
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   402
    io->opaque = info;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   403
    return io;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   404
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   405
createMemoryIo_failed:
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   406
    if (info != NULL) allocator.Free(info);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   407
    if (io != NULL) allocator.Free(io);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   408
    return NULL;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   409
} /* __PHYSFS_createMemoryIo */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   410
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   411
1123
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   412
/* PHYSFS_Io implementation for i/o to a PHYSFS_File... */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   413
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   414
static PHYSFS_sint64 handleIo_read(PHYSFS_Io *io, void *buf, PHYSFS_uint64 len)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   415
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   416
    return PHYSFS_readBytes((PHYSFS_File *) io->opaque, buf, len);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   417
} /* handleIo_read */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   418
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   419
static PHYSFS_sint64 handleIo_write(PHYSFS_Io *io, const void *buffer,
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   420
                                    PHYSFS_uint64 len)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   421
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   422
    return PHYSFS_writeBytes((PHYSFS_File *) io->opaque, buffer, len);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   423
} /* handleIo_write */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   424
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   425
static int handleIo_seek(PHYSFS_Io *io, PHYSFS_uint64 offset)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   426
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   427
    return PHYSFS_seek((PHYSFS_File *) io->opaque, offset);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   428
} /* handleIo_seek */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   429
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   430
static PHYSFS_sint64 handleIo_tell(PHYSFS_Io *io)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   431
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   432
    return PHYSFS_tell((PHYSFS_File *) io->opaque);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   433
} /* handleIo_tell */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   434
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   435
static PHYSFS_sint64 handleIo_length(PHYSFS_Io *io)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   436
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   437
    return PHYSFS_fileLength((PHYSFS_File *) io->opaque);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   438
} /* handleIo_length */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   439
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   440
static PHYSFS_Io *handleIo_duplicate(PHYSFS_Io *io)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   441
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   442
    /*
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   443
     * There's no duplicate at the PHYSFS_File level, so we break the
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   444
     *  abstraction. We're allowed to: we're physfs.c!
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   445
     */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   446
    FileHandle *origfh = (FileHandle *) io->opaque;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   447
    FileHandle *newfh = (FileHandle *) allocator.Malloc(sizeof (FileHandle));
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   448
    PHYSFS_Io *retval = NULL;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   449
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   450
    GOTO_IF(!newfh, PHYSFS_ERR_OUT_OF_MEMORY, handleIo_dupe_failed);
1123
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   451
    memset(newfh, '\0', sizeof (*newfh));
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   452
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   453
    retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   454
    GOTO_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, handleIo_dupe_failed);
1123
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   455
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   456
#if 0  /* we don't buffer the duplicate, at least not at the moment. */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   457
    if (origfh->buffer != NULL)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   458
    {
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   459
        newfh->buffer = (PHYSFS_uint8 *) allocator.Malloc(origfh->bufsize);
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   460
        if (!newfh->buffer)
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   461
            GOTO(PHYSFS_ERR_OUT_OF_MEMORY, handleIo_dupe_failed);
1123
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   462
        newfh->bufsize = origfh->bufsize;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   463
    } /* if */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   464
#endif
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   465
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   466
    newfh->io = origfh->io->duplicate(origfh->io);
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   467
    GOTO_IF_ERRPASS(!newfh->io, handleIo_dupe_failed);
1123
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   468
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   469
    newfh->forReading = origfh->forReading;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   470
    newfh->dirHandle = origfh->dirHandle;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   471
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   472
    __PHYSFS_platformGrabMutex(stateLock);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   473
    if (newfh->forReading)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   474
    {
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   475
        newfh->next = openReadList;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   476
        openReadList = newfh;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   477
    } /* if */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   478
    else
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   479
    {
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   480
        newfh->next = openWriteList;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   481
        openWriteList = newfh;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   482
    } /* else */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   483
    __PHYSFS_platformReleaseMutex(stateLock);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   484
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   485
    memcpy(retval, io, sizeof (PHYSFS_Io));
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   486
    retval->opaque = newfh;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   487
    return retval;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   488
    
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   489
handleIo_dupe_failed:
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   490
    if (newfh)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   491
    {
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   492
        if (newfh->io != NULL) newfh->io->destroy(newfh->io);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   493
        if (newfh->buffer != NULL) allocator.Free(newfh->buffer);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   494
        allocator.Free(newfh);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   495
    } /* if */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   496
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   497
    return NULL;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   498
} /* handleIo_duplicate */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   499
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   500
static int handleIo_flush(PHYSFS_Io *io)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   501
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   502
    return PHYSFS_flush((PHYSFS_File *) io->opaque);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   503
} /* handleIo_flush */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   504
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   505
static void handleIo_destroy(PHYSFS_Io *io)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   506
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   507
    if (io->opaque != NULL)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   508
        PHYSFS_close((PHYSFS_File *) io->opaque);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   509
    allocator.Free(io);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   510
} /* handleIo_destroy */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   511
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   512
static const PHYSFS_Io __PHYSFS_handleIoInterface =
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   513
{
1280
bd174b99fa5b Add binary compatibility to PHYSFS_Io.
Ryan C. Gordon <icculus@icculus.org>
parents: 1279
diff changeset
   514
    CURRENT_PHYSFS_IO_API_VERSION, NULL,
1123
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   515
    handleIo_read,
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   516
    handleIo_write,
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   517
    handleIo_seek,
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   518
    handleIo_tell,
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   519
    handleIo_length,
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   520
    handleIo_duplicate,
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   521
    handleIo_flush,
1280
bd174b99fa5b Add binary compatibility to PHYSFS_Io.
Ryan C. Gordon <icculus@icculus.org>
parents: 1279
diff changeset
   522
    handleIo_destroy
1123
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   523
};
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   524
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   525
static PHYSFS_Io *__PHYSFS_createHandleIo(PHYSFS_File *f)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   526
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   527
    PHYSFS_Io *io = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   528
    BAIL_IF(!io, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
1123
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   529
    memcpy(io, &__PHYSFS_handleIoInterface, sizeof (*io));
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   530
    io->opaque = f;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   531
    return io;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   532
} /* __PHYSFS_createHandleIo */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   533
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   534
11
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
   535
/* functions ... */
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   536
657
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   537
typedef struct
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   538
{
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   539
    char **list;
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   540
    PHYSFS_uint32 size;
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   541
    PHYSFS_ErrorCode errcode;
657
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   542
} EnumStringListCallbackData;
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   543
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   544
static void enumStringListCallback(void *data, const char *str)
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   545
{
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   546
    void *ptr;
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   547
    char *newstr;
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   548
    EnumStringListCallbackData *pecd = (EnumStringListCallbackData *) data;
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   549
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   550
    if (pecd->errcode)
657
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   551
        return;
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   552
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 688
diff changeset
   553
    ptr = allocator.Realloc(pecd->list, (pecd->size + 2) * sizeof (char *));
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 688
diff changeset
   554
    newstr = (char *) allocator.Malloc(strlen(str) + 1);
657
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   555
    if (ptr != NULL)
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   556
        pecd->list = (char **) ptr;
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   557
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   558
    if ((ptr == NULL) || (newstr == NULL))
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   559
    {
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   560
        pecd->errcode = PHYSFS_ERR_OUT_OF_MEMORY;
657
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   561
        pecd->list[pecd->size] = NULL;
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   562
        PHYSFS_freeList(pecd->list);
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   563
        return;
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   564
    } /* if */
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   565
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   566
    strcpy(newstr, str);
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   567
    pecd->list[pecd->size] = newstr;
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   568
    pecd->size++;
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   569
} /* enumStringListCallback */
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   570
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   571
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   572
static char **doEnumStringList(void (*func)(PHYSFS_StringCallback, void *))
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   573
{
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   574
    EnumStringListCallbackData ecd;
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   575
    memset(&ecd, '\0', sizeof (ecd));
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 688
diff changeset
   576
    ecd.list = (char **) allocator.Malloc(sizeof (char *));
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   577
    BAIL_IF(!ecd.list, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
657
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   578
    func(enumStringListCallback, &ecd);
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   579
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   580
    if (ecd.errcode)
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   581
    {
1328
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   582
        PHYSFS_setErrorCode(ecd.errcode);
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   583
        return NULL;
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   584
    } /* if */
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   585
657
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   586
    ecd.list[ecd.size] = NULL;
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
   587
    return ecd.list;
657
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   588
} /* doEnumStringList */
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   589
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   590
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   591
static void __PHYSFS_bubble_sort(void *a, size_t lo, size_t hi,
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   592
                                 int (*cmpfn)(void *, size_t, size_t),
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   593
                                 void (*swapfn)(void *, size_t, size_t))
462
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   594
{
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   595
    size_t i;
462
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   596
    int sorted;
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   597
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   598
    do
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   599
    {
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   600
        sorted = 1;
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   601
        for (i = lo; i < hi; i++)
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   602
        {
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   603
            if (cmpfn(a, i, i + 1) > 0)
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   604
            {
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   605
                swapfn(a, i, i + 1);
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   606
                sorted = 0;
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   607
            } /* if */
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   608
        } /* for */
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   609
    } while (!sorted);
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   610
} /* __PHYSFS_bubble_sort */
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   611
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   612
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   613
static void __PHYSFS_quick_sort(void *a, size_t lo, size_t hi,
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   614
                         int (*cmpfn)(void *, size_t, size_t),
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   615
                         void (*swapfn)(void *, size_t, size_t))
462
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   616
{
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   617
    size_t i;
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   618
    size_t j;
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   619
    size_t v;
462
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   620
578
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   621
    if ((hi - lo) <= PHYSFS_QUICKSORT_THRESHOLD)
462
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   622
        __PHYSFS_bubble_sort(a, lo, hi, cmpfn, swapfn);
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   623
    else
578
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   624
    {
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   625
        i = (hi + lo) / 2;
462
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   626
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   627
        if (cmpfn(a, lo, i) > 0) swapfn(a, lo, i);
578
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   628
        if (cmpfn(a, lo, hi) > 0) swapfn(a, lo, hi);
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   629
        if (cmpfn(a, i, hi) > 0) swapfn(a, i, hi);
462
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   630
578
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   631
        j = hi - 1;
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   632
        swapfn(a, i, j);
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   633
        i = lo;
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   634
        v = j;
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   635
        while (1)
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   636
        {
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   637
            while(cmpfn(a, ++i, v) < 0) { /* do nothing */ }
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   638
            while(cmpfn(a, --j, v) > 0) { /* do nothing */ }
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   639
            if (j < i)
462
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   640
                break;
578
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   641
            swapfn(a, i, j);
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   642
        } /* while */
948
923323444178 Valgrind fix: avoid overlapping memcpy() in sorting routines (thanks, JLM!).
Ryan C. Gordon <icculus@icculus.org>
parents: 901
diff changeset
   643
        if (i != (hi-1))
923323444178 Valgrind fix: avoid overlapping memcpy() in sorting routines (thanks, JLM!).
Ryan C. Gordon <icculus@icculus.org>
parents: 901
diff changeset
   644
            swapfn(a, i, hi-1);
578
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   645
        __PHYSFS_quick_sort(a, lo, j, cmpfn, swapfn);
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   646
        __PHYSFS_quick_sort(a, i+1, hi, cmpfn, swapfn);
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   647
    } /* else */
462
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   648
} /* __PHYSFS_quick_sort */
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   649
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   650
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   651
void __PHYSFS_sort(void *entries, size_t max,
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   652
                   int (*cmpfn)(void *, size_t, size_t),
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   653
                   void (*swapfn)(void *, size_t, size_t))
462
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   654
{
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   655
    /*
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   656
     * Quicksort w/ Bubblesort fallback algorithm inspired by code from here:
1373
527ef3c6a2d6 HTTPS all the things.
Ryan C. Gordon <icculus@icculus.org>
parents: 1372
diff changeset
   657
     *   https://www.cs.ubc.ca/spider/harrison/Java/sorting-demo.html
462
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   658
     */
1286
662a7e180c48 Don't sort if there's nothing to do (prevents array underflow, too).
Ryan C. Gordon <icculus@icculus.org>
parents: 1283
diff changeset
   659
    if (max > 0)
662a7e180c48 Don't sort if there's nothing to do (prevents array underflow, too).
Ryan C. Gordon <icculus@icculus.org>
parents: 1283
diff changeset
   660
        __PHYSFS_quick_sort(entries, 0, max - 1, cmpfn, swapfn);
462
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   661
} /* __PHYSFS_sort */
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   662
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   663
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   664
static ErrState *findErrorForCurrentThread(void)
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   665
{
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   666
    ErrState *i;
1012
f254870dd7dd Attempt to clean up the thread ID mess in platform_unix ...
Ryan C. Gordon <icculus@icculus.org>
parents: 986
diff changeset
   667
    void *tid;
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   668
272
470430943851 Fixed a crashbug when calling PHYSFS_deinit() twice in a row.
Ryan C. Gordon <icculus@icculus.org>
parents: 242
diff changeset
   669
    if (errorLock != NULL)
193
830c165052a5 Doesn't grab mutex in __PHYSFS_setError() if PHYSFS_init() hasn't been called.
Ryan C. Gordon <icculus@icculus.org>
parents: 186
diff changeset
   670
        __PHYSFS_platformGrabMutex(errorLock);
830c165052a5 Doesn't grab mutex in __PHYSFS_setError() if PHYSFS_init() hasn't been called.
Ryan C. Gordon <icculus@icculus.org>
parents: 186
diff changeset
   671
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   672
    if (errorStates != NULL)
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   673
    {
163
fc2b8ee5b420 Approved zeph's comments, fixed a few of my screwups.
Ryan C. Gordon <icculus@icculus.org>
parents: 160
diff changeset
   674
        tid = __PHYSFS_platformGetThreadID();
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   675
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   676
        for (i = errorStates; i != NULL; i = i->next)
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   677
        {
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   678
            if (i->tid == tid)
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   679
            {
272
470430943851 Fixed a crashbug when calling PHYSFS_deinit() twice in a row.
Ryan C. Gordon <icculus@icculus.org>
parents: 242
diff changeset
   680
                if (errorLock != NULL)
470430943851 Fixed a crashbug when calling PHYSFS_deinit() twice in a row.
Ryan C. Gordon <icculus@icculus.org>
parents: 242
diff changeset
   681
                    __PHYSFS_platformReleaseMutex(errorLock);
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
   682
                return i;
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   683
            } /* if */
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   684
        } /* for */
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   685
    } /* if */
193
830c165052a5 Doesn't grab mutex in __PHYSFS_setError() if PHYSFS_init() hasn't been called.
Ryan C. Gordon <icculus@icculus.org>
parents: 186
diff changeset
   686
272
470430943851 Fixed a crashbug when calling PHYSFS_deinit() twice in a row.
Ryan C. Gordon <icculus@icculus.org>
parents: 242
diff changeset
   687
    if (errorLock != NULL)
193
830c165052a5 Doesn't grab mutex in __PHYSFS_setError() if PHYSFS_init() hasn't been called.
Ryan C. Gordon <icculus@icculus.org>
parents: 186
diff changeset
   688
        __PHYSFS_platformReleaseMutex(errorLock);
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   689
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
   690
    return NULL;   /* no error available. */
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   691
} /* findErrorForCurrentThread */
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   692
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   693
1327
998351d485d9 Cleaned out the "exists" nonsense in the stat() API.
Ryan C. Gordon <icculus@icculus.org>
parents: 1326
diff changeset
   694
/* this doesn't reset the error state. */
998351d485d9 Cleaned out the "exists" nonsense in the stat() API.
Ryan C. Gordon <icculus@icculus.org>
parents: 1326
diff changeset
   695
static inline PHYSFS_ErrorCode currentErrorCode(void)
998351d485d9 Cleaned out the "exists" nonsense in the stat() API.
Ryan C. Gordon <icculus@icculus.org>
parents: 1326
diff changeset
   696
{
998351d485d9 Cleaned out the "exists" nonsense in the stat() API.
Ryan C. Gordon <icculus@icculus.org>
parents: 1326
diff changeset
   697
    const ErrState *err = findErrorForCurrentThread();
998351d485d9 Cleaned out the "exists" nonsense in the stat() API.
Ryan C. Gordon <icculus@icculus.org>
parents: 1326
diff changeset
   698
    return err ? err->code : PHYSFS_ERR_OK;
998351d485d9 Cleaned out the "exists" nonsense in the stat() API.
Ryan C. Gordon <icculus@icculus.org>
parents: 1326
diff changeset
   699
} /* currentErrorCode */
998351d485d9 Cleaned out the "exists" nonsense in the stat() API.
Ryan C. Gordon <icculus@icculus.org>
parents: 1326
diff changeset
   700
998351d485d9 Cleaned out the "exists" nonsense in the stat() API.
Ryan C. Gordon <icculus@icculus.org>
parents: 1326
diff changeset
   701
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   702
PHYSFS_ErrorCode PHYSFS_getLastErrorCode(void)
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   703
{
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   704
    ErrState *err = findErrorForCurrentThread();
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   705
    const PHYSFS_ErrorCode retval = (err) ? err->code : PHYSFS_ERR_OK;
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   706
    if (err)
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   707
        err->code = PHYSFS_ERR_OK;
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   708
    return retval;
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   709
} /* PHYSFS_getLastErrorCode */
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   710
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   711
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   712
PHYSFS_DECL const char *PHYSFS_getErrorByCode(PHYSFS_ErrorCode code)
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   713
{
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   714
    switch (code)
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   715
    {
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   716
        case PHYSFS_ERR_OK: return "no error";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   717
        case PHYSFS_ERR_OTHER_ERROR: return "unknown error";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   718
        case PHYSFS_ERR_OUT_OF_MEMORY: return "out of memory";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   719
        case PHYSFS_ERR_NOT_INITIALIZED: return "not initialized";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   720
        case PHYSFS_ERR_IS_INITIALIZED: return "already initialized";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   721
        case PHYSFS_ERR_ARGV0_IS_NULL: return "argv[0] is NULL";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   722
        case PHYSFS_ERR_UNSUPPORTED: return "unsupported";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   723
        case PHYSFS_ERR_PAST_EOF: return "past end of file";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   724
        case PHYSFS_ERR_FILES_STILL_OPEN: return "files still open";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   725
        case PHYSFS_ERR_INVALID_ARGUMENT: return "invalid argument";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   726
        case PHYSFS_ERR_NOT_MOUNTED: return "not mounted";
1322
5476917b8ddf Allow application-supplied archivers.
Ryan C. Gordon <icculus@icculus.org>
parents: 1315
diff changeset
   727
        case PHYSFS_ERR_NOT_FOUND: return "not found";
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   728
        case PHYSFS_ERR_SYMLINK_FORBIDDEN: return "symlinks are forbidden";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   729
        case PHYSFS_ERR_NO_WRITE_DIR: return "write directory is not set";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   730
        case PHYSFS_ERR_OPEN_FOR_READING: return "file open for reading";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   731
        case PHYSFS_ERR_OPEN_FOR_WRITING: return "file open for writing";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   732
        case PHYSFS_ERR_NOT_A_FILE: return "not a file";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   733
        case PHYSFS_ERR_READ_ONLY: return "read-only filesystem";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   734
        case PHYSFS_ERR_CORRUPT: return "corrupted";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   735
        case PHYSFS_ERR_SYMLINK_LOOP: return "infinite symbolic link loop";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   736
        case PHYSFS_ERR_IO: return "i/o error";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   737
        case PHYSFS_ERR_PERMISSION: return "permission denied";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   738
        case PHYSFS_ERR_NO_SPACE: return "no space available for writing";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   739
        case PHYSFS_ERR_BAD_FILENAME: return "filename is illegal or insecure";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   740
        case PHYSFS_ERR_BUSY: return "tried to modify a file the OS needs";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   741
        case PHYSFS_ERR_DIR_NOT_EMPTY: return "directory isn't empty";
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   742
        case PHYSFS_ERR_OS_ERROR: return "OS reported an error";
1322
5476917b8ddf Allow application-supplied archivers.
Ryan C. Gordon <icculus@icculus.org>
parents: 1315
diff changeset
   743
        case PHYSFS_ERR_DUPLICATE: return "duplicate resource";
1383
1b6b14b5eebe Added support for password-protected .zip files.
Ryan C. Gordon <icculus@icculus.org>
parents: 1382
diff changeset
   744
        case PHYSFS_ERR_BAD_PASSWORD: return "bad password";
1559
aaee2b83291f Reworked enumeration to be more powerful.
Ryan C. Gordon <icculus@icculus.org>
parents: 1555
diff changeset
   745
        case PHYSFS_ERR_APP_CALLBACK: return "app callback reported error";
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   746
    } /* switch */
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   747
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   748
    return NULL;  /* don't know this error code. */
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   749
} /* PHYSFS_getErrorByCode */
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   750
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   751
1328
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   752
void PHYSFS_setErrorCode(PHYSFS_ErrorCode errcode)
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   753
{
1328
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   754
    ErrState *err;
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   755
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   756
    if (!errcode)
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   757
        return;
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   758
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   759
    err = findErrorForCurrentThread();
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   760
    if (err == NULL)
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   761
    {
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   762
        err = (ErrState *) allocator.Malloc(sizeof (ErrState));
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   763
        if (err == NULL)
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   764
            return;   /* uhh...? */
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   765
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   766
        memset(err, '\0', sizeof (ErrState));
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   767
        err->tid = __PHYSFS_platformGetThreadID();
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   768
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   769
        if (errorLock != NULL)
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   770
            __PHYSFS_platformGrabMutex(errorLock);
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   771
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   772
        err->next = errorStates;
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   773
        errorStates = err;
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   774
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   775
        if (errorLock != NULL)
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   776
            __PHYSFS_platformReleaseMutex(errorLock);
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   777
    } /* if */
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   778
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   779
    err->code = errcode;
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   780
} /* PHYSFS_setErrorCode */
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   781
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   782
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   783
const char *PHYSFS_getLastError(void)
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   784
{
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   785
    const PHYSFS_ErrorCode err = PHYSFS_getLastErrorCode();
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   786
    return (err) ? PHYSFS_getErrorByCode(err) : NULL;
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   787
} /* PHYSFS_getLastError */
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   788
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   789
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   790
/* MAKE SURE that errorLock is held before calling this! */
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   791
static void freeErrorStates(void)
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   792
{
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   793
    ErrState *i;
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   794
    ErrState *next;
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   795
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   796
    for (i = errorStates; i != NULL; i = next)
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   797
    {
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   798
        next = i->next;
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 688
diff changeset
   799
        allocator.Free(i);
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   800
    } /* for */
272
470430943851 Fixed a crashbug when calling PHYSFS_deinit() twice in a row.
Ryan C. Gordon <icculus@icculus.org>
parents: 242
diff changeset
   801
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   802
    errorStates = NULL;
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   803
} /* freeErrorStates */
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   804
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   805
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   806
void PHYSFS_getLinkedVersion(PHYSFS_Version *ver)
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   807
{
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   808
    if (ver != NULL)
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   809
    {
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   810
        ver->major = PHYSFS_VER_MAJOR;
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   811
        ver->minor = PHYSFS_VER_MINOR;
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   812
        ver->patch = PHYSFS_VER_PATCH;
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   813
    } /* if */
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   814
} /* PHYSFS_getLinkedVersion */
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   815
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   816
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   817
static const char *find_filename_extension(const char *fname)
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   818
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   819
    const char *retval = NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   820
    if (fname != NULL)
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   821
    {
1135
3b71a0c08665 Patched to compile on Windows.
Ryan C. Gordon <icculus@icculus.org>
parents: 1130
diff changeset
   822
        const char *p = strchr(fname, '.');
3b71a0c08665 Patched to compile on Windows.
Ryan C. Gordon <icculus@icculus.org>
parents: 1130
diff changeset
   823
        retval = p;
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   824
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   825
        while (p != NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   826
        {
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   827
            p = strchr(p + 1, '.');
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   828
            if (p != NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   829
                retval = p;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   830
        } /* while */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   831
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   832
        if (retval != NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   833
            retval++;  /* skip '.' */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   834
    } /* if */
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   835
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
   836
    return retval;
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   837
} /* find_filename_extension */
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   838
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   839
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   840
static DirHandle *tryOpenDir(PHYSFS_Io *io, const PHYSFS_Archiver *funcs,
1571
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   841
                             const char *d, int forWriting, int *_claimed)
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   842
{
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   843
    DirHandle *retval = NULL;
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   844
    void *opaque = NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   845
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   846
    if (io != NULL)
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   847
        BAIL_IF_ERRPASS(!io->seek(io, 0), NULL);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   848
1571
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   849
    opaque = funcs->openArchive(io, d, forWriting, _claimed);
1113
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   850
    if (opaque != NULL)
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   851
    {
1113
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   852
        retval = (DirHandle *) allocator.Malloc(sizeof (DirHandle));
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   853
        if (retval == NULL)
1270
f8d3f58561b1 Renamed PHYSFS_Archiver::dirClose() to PHYSFS_Archiver::closeArchive().
Ryan C. Gordon <icculus@icculus.org>
parents: 1268
diff changeset
   854
            funcs->closeArchive(opaque);
1113
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   855
        else
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   856
        {
1113
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   857
            memset(retval, '\0', sizeof (DirHandle));
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   858
            retval->mountPoint = NULL;
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   859
            retval->funcs = funcs;
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   860
            retval->opaque = opaque;
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   861
        } /* else */
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   862
    } /* if */
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   863
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
   864
    return retval;
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   865
} /* tryOpenDir */
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   866
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   867
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   868
static DirHandle *openDirectory(PHYSFS_Io *io, const char *d, int forWriting)
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
   869
{
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   870
    DirHandle *retval = NULL;
1456
2328964939fd Fixed compiler warnings on Visual Studio about const qualifiers.
Ryan C. Gordon <icculus@icculus.org>
parents: 1449
diff changeset
   871
    PHYSFS_Archiver **i;
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   872
    const char *ext;
1353
5ef6aca28421 Fixed resource leak when failing to mount a file that isn't an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 1347
diff changeset
   873
    int created_io = 0;
1571
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   874
    int claimed = 0;
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   875
    PHYSFS_ErrorCode errcode;
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
   876
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   877
    assert((io != NULL) || (d != NULL));
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   878
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   879
    if (io == NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   880
    {
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   881
        /* DIR gets first shot (unlike the rest, it doesn't deal with files). */
1571
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   882
        retval = tryOpenDir(io, &__PHYSFS_Archiver_DIR, d, forWriting, &claimed);
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   883
        if (retval || claimed)
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   884
            return retval;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   885
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   886
        io = __PHYSFS_createNativeIo(d, forWriting ? 'w' : 'r');
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   887
        BAIL_IF_ERRPASS(!io, 0);
1353
5ef6aca28421 Fixed resource leak when failing to mount a file that isn't an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 1347
diff changeset
   888
        created_io = 1;
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   889
    } /* if */
1113
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   890
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   891
    ext = find_filename_extension(d);
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   892
    if (ext != NULL)
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
   893
    {
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   894
        /* Look for archivers with matching file extensions first... */
1571
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   895
        for (i = archivers; (*i != NULL) && (retval == NULL) && !claimed; i++)
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   896
        {
1555
5495a0e50b5e utf8: big improvements to case-insensitive UTF-8 string compare.
Ryan C. Gordon <icculus@icculus.org>
parents: 1554
diff changeset
   897
            if (PHYSFS_utf8stricmp(ext, (*i)->info.extension) == 0)
1571
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   898
                retval = tryOpenDir(io, *i, d, forWriting, &claimed);
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   899
        } /* for */
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   900
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   901
        /* failing an exact file extension match, try all the others... */
1571
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   902
        for (i = archivers; (*i != NULL) && (retval == NULL) && !claimed; i++)
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   903
        {
1555
5495a0e50b5e utf8: big improvements to case-insensitive UTF-8 string compare.
Ryan C. Gordon <icculus@icculus.org>
parents: 1554
diff changeset
   904
            if (PHYSFS_utf8stricmp(ext, (*i)->info.extension) != 0)
1571
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   905
                retval = tryOpenDir(io, *i, d, forWriting, &claimed);
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   906
        } /* for */
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   907
    } /* if */
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   908
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   909
    else  /* no extension? Try them all. */
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   910
    {
1571
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   911
        for (i = archivers; (*i != NULL) && (retval == NULL) && !claimed; i++)
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   912
            retval = tryOpenDir(io, *i, d, forWriting, &claimed);
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   913
    } /* else */
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
   914
1571
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   915
    errcode = currentErrorCode();
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   916
1353
5ef6aca28421 Fixed resource leak when failing to mount a file that isn't an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 1347
diff changeset
   917
    if ((!retval) && (created_io))
5ef6aca28421 Fixed resource leak when failing to mount a file that isn't an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 1347
diff changeset
   918
        io->destroy(io);
5ef6aca28421 Fixed resource leak when failing to mount a file that isn't an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 1347
diff changeset
   919
1571
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   920
    BAIL_IF(!retval, claimed ? errcode : PHYSFS_ERR_UNSUPPORTED, NULL);
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
   921
    return retval;
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
   922
} /* openDirectory */
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
   923
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
   924
683
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   925
/*
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   926
 * Make a platform-independent path string sane. Doesn't actually check the
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   927
 *  file hierarchy, it just cleans up the string.
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   928
 *  (dst) must be a buffer at least as big as (src), as this is where the
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   929
 *  cleaned up string is deposited.
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   930
 * If there are illegal bits in the path (".." entries, etc) then we
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   931
 *  return zero and (dst) is undefined. Non-zero if the path was sanitized.
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   932
 */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   933
static int sanitizePlatformIndependentPath(const char *src, char *dst)
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   934
{
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   935
    char *prev;
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   936
    char ch;
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   937
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   938
    while (*src == '/')  /* skip initial '/' chars... */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   939
        src++;
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   940
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   941
    prev = dst;
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   942
    do
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   943
    {
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   944
        ch = *(src++);
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   945
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   946
        if ((ch == ':') || (ch == '\\'))  /* illegal chars in a physfs path. */
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   947
            BAIL(PHYSFS_ERR_BAD_FILENAME, 0);
683
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   948
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   949
        if (ch == '/')   /* path separator. */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   950
        {
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   951
            *dst = '\0';  /* "." and ".." are illegal pathnames. */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   952
            if ((strcmp(prev, ".") == 0) || (strcmp(prev, "..") == 0))
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   953
                BAIL(PHYSFS_ERR_BAD_FILENAME, 0);
683
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   954
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   955
            while (*src == '/')   /* chop out doubles... */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   956
                src++;
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   957
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   958
            if (*src == '\0') /* ends with a pathsep? */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   959
                break;  /* we're done, don't add final pathsep to dst. */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   960
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   961
            prev = dst + 1;
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   962
        } /* if */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   963
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   964
        *(dst++) = ch;
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   965
    } while (ch != '\0');
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   966
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
   967
    return 1;
683
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   968
} /* sanitizePlatformIndependentPath */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   969
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   970
687
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   971
/*
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   972
 * Figure out if (fname) is part of (h)'s mountpoint. (fname) must be an
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   973
 *  output from sanitizePlatformIndependentPath(), so that it is in a known
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   974
 *  state.
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   975
 *
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   976
 * This only finds legitimate segments of a mountpoint. If the mountpoint is
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   977
 *  "/a/b/c" and (fname) is "/a/b/c", "/", or "/a/b/c/d", then the results are
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   978
 *  all zero. "/a/b" will succeed, though.
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   979
 */
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   980
static int partOfMountPoint(DirHandle *h, char *fname)
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   981
{
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   982
    int rc;
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   983
    size_t len, mntpntlen;
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   984
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   985
    if (h->mountPoint == NULL)
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
   986
        return 0;
687
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   987
    else if (*fname == '\0')
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
   988
        return 1;
687
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   989
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   990
    len = strlen(fname);
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   991
    mntpntlen = strlen(h->mountPoint);
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   992
    if (len > mntpntlen)  /* can't be a subset of mountpoint. */
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
   993
        return 0;
687
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   994
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   995
    /* if true, must be not a match or a complete match, but not a subset. */
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   996
    if ((len + 1) == mntpntlen)
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
   997
        return 0;
687
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   998
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
   999
    rc = strncmp(fname, h->mountPoint, len); /* !!! FIXME: case insensitive? */
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1000
    if (rc != 0)
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
  1001
        return 0;  /* not a match. */
687
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1002
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1003
    /* make sure /a/b matches /a/b/ and not /a/bc ... */
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
  1004
    return h->mountPoint[len] == '/';
687
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1005
} /* partOfMountPoint */
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1006
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1007
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1008
static DirHandle *createDirHandle(PHYSFS_Io *io, const char *newDir,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1009
                                  const char *mountPoint, int forWriting)
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1010
{
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1011
    DirHandle *dirHandle = NULL;
852
9467e96abdf1 Replaced some Malloc and all the alloca() calls with __PHYSFS_smallAlloc(),
Ryan C. Gordon <icculus@icculus.org>
parents: 848
diff changeset
  1012
    char *tmpmntpnt = NULL;
683
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
  1013
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
  1014
    if (mountPoint != NULL)
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
  1015
    {
852
9467e96abdf1 Replaced some Malloc and all the alloca() calls with __PHYSFS_smallAlloc(),
Ryan C. Gordon <icculus@icculus.org>
parents: 848
diff changeset
  1016
        const size_t len = strlen(mountPoint) + 1;
9467e96abdf1 Replaced some Malloc and all the alloca() calls with __PHYSFS_smallAlloc(),
Ryan C. Gordon <icculus@icculus.org>
parents: 848
diff changeset
  1017
        tmpmntpnt = (char *) __PHYSFS_smallAlloc(len);
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
  1018
        GOTO_IF(!tmpmntpnt, PHYSFS_ERR_OUT_OF_MEMORY, badDirHandle);
852
9467e96abdf1 Replaced some Malloc and all the alloca() calls with __PHYSFS_smallAlloc(),
Ryan C. Gordon <icculus@icculus.org>
parents: 848
diff changeset
  1019
        if (!sanitizePlatformIndependentPath(mountPoint, tmpmntpnt))
683
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
  1020
            goto badDirHandle;
852
9467e96abdf1 Replaced some Malloc and all the alloca() calls with __PHYSFS_smallAlloc(),
Ryan C. Gordon <icculus@icculus.org>
parents: 848
diff changeset
  1021
        mountPoint = tmpmntpnt;  /* sanitized version. */
683
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
  1022
    } /* if */
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1023
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1024
    dirHandle = openDirectory(io, newDir, forWriting);
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
  1025
    GOTO_IF_ERRPASS(!dirHandle, badDirHandle);
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1026
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1027
    if (newDir == NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1028
        dirHandle->dirName = NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1029
    else
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1030
    {
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1031
        dirHandle->dirName = (char *) allocator.Malloc(strlen(newDir) + 1);
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
  1032
        if (!dirHandle->dirName)
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
  1033
            GOTO(PHYSFS_ERR_OUT_OF_MEMORY, badDirHandle);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1034
        strcpy(dirHandle->dirName, newDir);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1035
    } /* else */
679
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1036
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1037
    if ((mountPoint != NULL) && (*mountPoint != '\0'))
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1038
    {
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 688
diff changeset
  1039
        dirHandle->mountPoint = (char *)allocator.Malloc(strlen(mountPoint)+2);
1240
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
  1040
        if (!dirHandle->mountPoint)
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
  1041
            GOTO(PHYSFS_ERR_OUT_OF_MEMORY, badDirHandle);
679
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1042
        strcpy(dirHandle->mountPoint, mountPoint);
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1043
        strcat(dirHandle->mountPoint, "/");
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1044
    } /* if */
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1045
852
9467e96abdf1 Replaced some Malloc and all the alloca() calls with __PHYSFS_smallAlloc(),
Ryan C. Gordon <icculus@icculus.org>
parents: 848
diff changeset
  1046
    __PHYSFS_smallFree(tmpmntpnt);
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
  1047
    return dirHandle;
679
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1048
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1049
badDirHandle:
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1050
    if (dirHandle != NULL)
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1051
    {
1270
f8d3f58561b1 Renamed PHYSFS_Archiver::dirClose() to PHYSFS_Archiver::closeArchive().
Ryan C. Gordon <icculus@icculus.org>
parents: 1268
diff changeset
  1052
        dirHandle->funcs->closeArchive(dirHandle->opaque);
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 688
diff changeset
  1053
        allocator.Free(dirHandle->dirName);
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 688
diff changeset
  1054
        allocator.Free(dirHandle->mountPoint);
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 688
diff changeset
  1055
        allocator.Free(dirHandle);
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1056
    } /* if */
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1057
852
9467e96abdf1 Replaced some Malloc and all the alloca() calls with __PHYSFS_smallAlloc(),
Ryan C. Gordon <icculus@icculus.org>
parents: 848
diff changeset
  1058
    __PHYSFS_smallFree(tmpmntpnt);
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
  1059
    return NULL;
650
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
  1060
} /* createDirHandle */
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1061
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1062
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1063
/* MAKE SURE you've got the stateLock held before calling this! */
650
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
  1064
static int freeDirHandle(DirHandle *dh, FileHandle *openList)
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1065
{
650
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
  1066
    FileHandle *i;
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1067
650
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
  1068
    if (dh == NULL)
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
  1069
        return 1;
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1070
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1071
    for (i = openList; i != NULL; i = i->next)
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
  1072
        BAIL_IF(i->dirHandle == dh, PHYSFS_ERR_FILES_STILL_OPEN, 0);
774
916c2e81e77f 7zip support, written by Dennis Schridde, and heavily Ryanified by me.
Ryan C. Gordon <icculus@icculus.org>
parents: 758
diff changeset
  1073
1270
f8d3f58561b1 Renamed PHYSFS_Archiver::dirClose() to PHYSFS_Archiver::closeArchive().
Ryan C. Gordon <icculus@icculus.org>
parents: 1268
diff changeset
  1074
    dh->funcs->closeArchive(dh->opaque);
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 688
diff changeset
  1075
    allocator.Free(dh->dirName);
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 688
diff changeset
  1076
    allocator.Free(dh->mountPoint);
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 688
diff changeset
  1077
    allocator.Free(dh);
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
  1078
    return 1;
650
298b8bb26775 Did the same thing to FileHandles than I did to DirHandles, but this
Ryan C. Gordon <icculus@icculus.org>
parents: 648
diff changeset
  1079
} /* freeDirHandle */
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1080
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1081
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1082
static char *calculateBaseDir(const char *argv0)
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1083
{
1225
671d4ea47c13 Make __PHYSFS_platformDirSeparator into a single char.
Ryan C. Gordon <icculus@icculus.org>
parents: 1224
diff changeset
  1084
    const char dirsep = __PHYSFS_platformDirSeparator;
848
963d26edb39b Cleanups in calculateBaseDir.
Ryan C. Gordon <icculus@icculus.org>
parents: 845
diff changeset
  1085
    char *retval = NULL;
963d26edb39b Cleanups in calculateBaseDir.
Ryan C. Gordon <icculus@icculus.org>
parents: 845
diff changeset
  1086
    char *ptr = NULL;
23
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1087
848
963d26edb39b Cleanups in calculateBaseDir.
Ryan C. Gordon <icculus@icculus.org>
parents: 845
diff changeset
  1088
    /* Give the platform layer first shot at this. */
23
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1089
    retval = __PHYSFS_platformCalcBaseDir(argv0);
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1090
    if (retval != NULL)
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
  1091
        return retval;
23
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1092
848
963d26edb39b Cleanups in calculateBaseDir.
Ryan C. Gordon <icculus@icculus.org>
parents: 845
diff changeset
  1093
    /* We need argv0 to go on. */
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
  1094
    BAIL_IF(argv0 == NULL, PHYSFS_ERR_ARGV0_IS_NULL, NULL);
839
cbb9d603ca71 PHYSFS_init() should fail if argv0 is NULL and we can't do without it.
Ryan C. Gordon <icculus@icculus.org>
parents: 828
diff changeset
  1095
1225
671d4ea47c13 Make __PHYSFS_platformDirSeparator into a single char.
Ryan C. Gordon <icculus@icculus.org>
parents: 1224
diff changeset
  1096
    ptr = strrchr(argv0, dirsep);
23
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1097
    if (ptr != NULL)
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1098
    {
1264
03715ba4603d Make sure base dir always has a dirsep at the end of it.
Ryan C. Gordon <icculus@icculus.org>
parents: 1258
diff changeset
  1099
        const size_t size = ((size_t) (ptr - argv0)) + 1;
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 688
diff changeset
  1100
        retval = (char *) allocator.Malloc(size + 1);
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
  1101
        BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
23
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1102
        memcpy(retval, argv0, size);
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1103
        retval[size] = '\0';
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
  1104
        return retval;
23
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1105
    } /* if */
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1106
848
963d26edb39b Cleanups in calculateBaseDir.
Ryan C. Gordon <icculus@icculus.org>
parents: 845
diff changeset
  1107
    /* argv0 wasn't helpful. */
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
  1108
    BAIL(PHYSFS_ERR_INVALID_ARGUMENT, NULL);
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1109
} /* calculateBaseDir */
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1110
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1111
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1112
static int initializeMutexes(void)
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1113
{
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1114
    errorLock = __PHYSFS_platformCreateMutex();
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1115
    if (errorLock == NULL)
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1116
        goto initializeMutexes_failed;
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1117
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1118
    stateLock = __PHYSFS_platformCreateMutex();
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1119
    if (stateLock == NULL)
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1120
        goto initializeMutexes_failed;
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1121
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
  1122
    return 1;  /* success. */
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1123
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1124
initializeMutexes_failed:
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1125
    if (errorLock != NULL)
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1126
        __PHYSFS_platformDestroyMutex(errorLock);
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1127
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1128
    if (stateLock != NULL)
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1129
        __PHYSFS_platformDestroyMutex(stateLock);
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1130
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1131
    errorLock = stateLock = NULL;
1016
957c97389257 Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents: 1012
diff changeset
  1132
    return 0;  /* failed. */
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1133
} /* initializeMutexes */
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1134
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1135
1322
5476917b8ddf Allow application-supplied archivers.
Ryan C. Gordon <icculus@icculus.org>
parents: 1315
diff changeset
  1136
static int doRegisterArchiver(const PHYSFS_Archiver *_archiver);
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 634
diff changeset
  1137
1277
f6996bfaec19 Made archiver list dynamic, in preparation for external archivers.
Ryan C. Gordon <icculus&