src/physfs.c
author Ryan C. Gordon <icculus@icculus.org>
Sun, 17 May 2020 01:41:52 -0400
changeset 1691 c66c9326b05d
parent 1683 89e8d39420cd
child 1692 acdcf93d1f9b
permissions -rw-r--r--
7z: Make error handling a little more robust.
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. */
1649
9edc8d92bc61 Added PHYSFS_setRoot().
Ryan C. Gordon <icculus@icculus.org>
parents: 1643
diff changeset
    49
    char *root;  /* subdirectory of archiver to use as root of archive (NULL for actual root) */
9edc8d92bc61 Added PHYSFS_setRoot().
Ryan C. Gordon <icculus@icculus.org>
parents: 1643
diff changeset
    50
    size_t rootlen;  /* subdirectory of archiver to use as root of archive (NULL for actual root) */
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
    51
    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
    52
    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
    53
} 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
    54
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
    55
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
    56
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
    57
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
    58
    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
    59
    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
    60
    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
    61
    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
    62
    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
    63
    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
    64
    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
    65
    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
    66
} FileHandle;
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
    67
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
    68
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
    69
typedef struct __PHYSFS_ERRSTATETYPE__
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    70
{
1012
f254870dd7dd Attempt to clean up the thread ID mess in platform_unix ...
Ryan C. Gordon <icculus@icculus.org>
parents: 986
diff changeset
    71
    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
    72
    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
    73
    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
    74
} ErrState;
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
    75
11
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    76
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    77
/* General PhysicsFS state ... */
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    78
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
    79
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
    80
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
    81
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
    82
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
    83
static FileHandle *openReadList = NULL;
11
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    84
static char *baseDir = NULL;
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    85
static char *userDir = NULL;
1242
1e6db80d2393 Added PHYSFS_getPrefDir().
Ryan C. Gordon <icculus@icculus.org>
parents: 1240
diff changeset
    86
static char *prefDir = NULL;
11
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    87
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
    88
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
    89
static PHYSFS_ArchiveInfo **archiveInfo = NULL;
1322
5476917b8ddf Allow application-supplied archivers.
Ryan C. Gordon <icculus@icculus.org>
parents: 1315
diff changeset
    90
static volatile size_t numArchivers = 0;
1652
357f25632ea0 Fixed some compiler warnings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1650
diff changeset
    91
static size_t longest_root = 0;
11
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
    92
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
    93
/* mutexes ... */
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
    94
static void *errorLock = NULL;     /* protects error message list.        */
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
    95
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
    96
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 634
diff changeset
    97
/* allocator ... */
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 634
diff changeset
    98
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
    99
PHYSFS_Allocator allocator;
644
1cb5533d369c Initial structure for replacable allocator work.
Ryan C. Gordon <icculus@icculus.org>
parents: 634
diff changeset
   100
11
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
   101
1538
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   102
#ifdef PHYSFS_NEED_ATOMIC_OP_FALLBACK
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   103
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
   104
{
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   105
    int retval;
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   106
    __PHYSFS_platformGrabMutex(stateLock);
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   107
    retval = *ptrval;
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   108
    *ptrval = retval + val;
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   109
    __PHYSFS_platformReleaseMutex(stateLock);
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   110
    return retval;
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   111
} /* __PHYSFS_atomicAdd */
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   112
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   113
int __PHYSFS_ATOMIC_INCR(int *ptrval)
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
    return __PHYSFS_atomicAdd(ptrval, 1);
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   116
} /* __PHYSFS_ATOMIC_INCR */
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   117
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   118
int __PHYSFS_ATOMIC_DECR(int *ptrval)
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   119
{
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   120
    return __PHYSFS_atomicAdd(ptrval, -1);
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   121
} /* __PHYSFS_ATOMIC_DECR */
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   122
#endif
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   123
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   124
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   125
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   126
/* 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
   127
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   128
/* !!! 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
   129
typedef struct __PHYSFS_NativeIoInfo
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   130
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   131
    void *handle;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   132
    const char *path;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   133
    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
   134
} NativeIoInfo;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   135
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   136
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
   137
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   138
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   139
    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
   140
} /* nativeIo_read */
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
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
   143
                                    PHYSFS_uint64 len)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   144
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   145
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   146
    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
   147
} /* nativeIo_write */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   148
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   149
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
   150
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   151
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   152
    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
   153
} /* nativeIo_seek */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   154
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   155
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
   156
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   157
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   158
    return __PHYSFS_platformTell(info->handle);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   159
} /* nativeIo_tell */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   160
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   161
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
   162
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   163
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   164
    return __PHYSFS_platformFileLength(info->handle);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   165
} /* nativeIo_length */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   166
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   167
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
   168
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   169
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   170
    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
   171
} /* nativeIo_duplicate */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   172
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   173
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
   174
{
1603
5f309b0956c0 Fixed PHYSFS_flush().
Ryan C. Gordon <icculus@icculus.org>
parents: 1591
diff changeset
   175
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
5f309b0956c0 Fixed PHYSFS_flush().
Ryan C. Gordon <icculus@icculus.org>
parents: 1591
diff changeset
   176
    return __PHYSFS_platformFlush(info->handle);
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   177
} /* nativeIo_flush */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   178
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   179
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
   180
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   181
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   182
    __PHYSFS_platformClose(info->handle);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   183
    allocator.Free((void *) info->path);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   184
    allocator.Free(info);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   185
    allocator.Free(io);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   186
} /* nativeIo_destroy */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   187
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   188
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
   189
{
1280
bd174b99fa5b Add binary compatibility to PHYSFS_Io.
Ryan C. Gordon <icculus@icculus.org>
parents: 1279
diff changeset
   190
    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
   191
    nativeIo_read,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   192
    nativeIo_write,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   193
    nativeIo_seek,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   194
    nativeIo_tell,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   195
    nativeIo_length,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   196
    nativeIo_duplicate,
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   197
    nativeIo_flush,
1280
bd174b99fa5b Add binary compatibility to PHYSFS_Io.
Ryan C. Gordon <icculus@icculus.org>
parents: 1279
diff changeset
   198
    nativeIo_destroy
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   199
};
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   200
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   201
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
   202
{
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   203
    PHYSFS_Io *io = NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   204
    NativeIoInfo *info = NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   205
    void *handle = NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   206
    char *pathdup = NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   207
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   208
    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
   209
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   210
    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
   211
    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
   212
    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
   213
    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
   214
    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
   215
    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
   216
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   217
    if (mode == 'r')
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   218
        handle = __PHYSFS_platformOpenRead(path);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   219
    else if (mode == 'w')
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   220
        handle = __PHYSFS_platformOpenWrite(path);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   221
    else if (mode == 'a')
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   222
        handle = __PHYSFS_platformOpenAppend(path);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   223
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   224
    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
   225
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   226
    strcpy(pathdup, path);
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   227
    info->handle = handle;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   228
    info->path = pathdup;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   229
    info->mode = mode;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   230
    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
   231
    io->opaque = info;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   232
    return io;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   233
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   234
createNativeIo_failed:
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   235
    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
   236
    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
   237
    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
   238
    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
   239
    return NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   240
} /* __PHYSFS_createNativeIo */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   241
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   242
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   243
/* PHYSFS_Io implementation for i/o to a memory buffer... */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   244
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   245
typedef struct __PHYSFS_MemoryIoInfo
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   246
{
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   247
    const PHYSFS_uint8 *buf;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   248
    PHYSFS_uint64 len;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   249
    PHYSFS_uint64 pos;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   250
    PHYSFS_Io *parent;
1546
f42ba130a039 Fixed compiler warnings on GCC.
Ryan C. Gordon <icculus@icculus.org>
parents: 1545
diff changeset
   251
    int refcount;
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   252
    void (*destruct)(void *);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   253
} MemoryIoInfo;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   254
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   255
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
   256
{
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   257
    MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   258
    const PHYSFS_uint64 avail = info->len - info->pos;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   259
    assert(avail <= info->len);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   260
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   261
    if (avail == 0)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   262
        return 0;  /* we're at EOF; nothing to do. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   263
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   264
    if (len > avail)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   265
        len = avail;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   266
1208
3edcb015089a Fixed some compiler warnings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1204
diff changeset
   267
    memcpy(buf, info->buf + info->pos, (size_t) len);
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   268
    info->pos += len;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   269
    return len;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   270
} /* memoryIo_read */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   271
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   272
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
   273
                                    PHYSFS_uint64 len)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   274
{
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   275
    BAIL(PHYSFS_ERR_OPEN_FOR_READING, -1);
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   276
} /* memoryIo_write */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   277
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   278
static int memoryIo_seek(PHYSFS_Io *io, PHYSFS_uint64 offset)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   279
{
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   280
    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
   281
    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
   282
    info->pos = offset;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   283
    return 1;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   284
} /* memoryIo_seek */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   285
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   286
static PHYSFS_sint64 memoryIo_tell(PHYSFS_Io *io)
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
    const MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   289
    return (PHYSFS_sint64) info->pos;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   290
} /* memoryIo_tell */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   291
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   292
static PHYSFS_sint64 memoryIo_length(PHYSFS_Io *io)
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
    const MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   295
    return (PHYSFS_sint64) info->len;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   296
} /* memoryIo_length */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   297
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   298
static PHYSFS_Io *memoryIo_duplicate(PHYSFS_Io *io)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   299
{
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   300
    MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   301
    MemoryIoInfo *newinfo = NULL;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   302
    PHYSFS_Io *parent = info->parent;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   303
    PHYSFS_Io *retval = NULL;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   304
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   305
    /* avoid deep copies. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   306
    assert((!parent) || (!((MemoryIoInfo *) parent->opaque)->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
    /* share the buffer between duplicates. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   309
    if (parent != NULL)  /* dup the parent, increment its refcount. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   310
        return parent->duplicate(parent);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   311
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   312
    /* we're the parent. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   313
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   314
    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
   315
    BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   316
    newinfo = (MemoryIoInfo *) allocator.Malloc(sizeof (MemoryIoInfo));
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   317
    if (!newinfo)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   318
    {
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   319
        allocator.Free(retval);
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   320
        BAIL(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   321
    } /* if */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   322
1538
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   323
    __PHYSFS_ATOMIC_INCR(&info->refcount);
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   324
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   325
    memset(newinfo, '\0', sizeof (*info));
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   326
    newinfo->buf = info->buf;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   327
    newinfo->len = info->len;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   328
    newinfo->pos = 0;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   329
    newinfo->parent = io;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   330
    newinfo->refcount = 0;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   331
    newinfo->destruct = NULL;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   332
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   333
    memcpy(retval, io, sizeof (*retval));
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   334
    retval->opaque = newinfo;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   335
    return retval;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   336
} /* memoryIo_duplicate */
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
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
   339
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   340
static void memoryIo_destroy(PHYSFS_Io *io)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   341
{
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   342
    MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   343
    PHYSFS_Io *parent = info->parent;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   344
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   345
    if (parent != NULL)
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   346
    {
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   347
        assert(info->buf == ((MemoryIoInfo *) info->parent->opaque)->buf);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   348
        assert(info->len == ((MemoryIoInfo *) info->parent->opaque)->len);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   349
        assert(info->refcount == 0);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   350
        assert(info->destruct == NULL);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   351
        allocator.Free(info);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   352
        allocator.Free(io);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   353
        parent->destroy(parent);  /* decrements refcount. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   354
        return;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   355
    } /* if */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   356
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   357
    /* we _are_ the parent. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   358
    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
   359
1538
81c73124d651 Add basic atomic operations for refcounting, etc.
Ryan C. Gordon <icculus@icculus.org>
parents: 1536
diff changeset
   360
    if (__PHYSFS_ATOMIC_DECR(&info->refcount) == 0)
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   361
    {
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   362
        void (*destruct)(void *) = info->destruct;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   363
        void *buf = (void *) info->buf;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   364
        io->opaque = NULL;  /* kill this here in case of race. */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   365
        allocator.Free(info);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   366
        allocator.Free(io);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   367
        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
   368
            destruct(buf);
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   369
    } /* if */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   370
} /* memoryIo_destroy */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   371
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   372
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   373
static const PHYSFS_Io __PHYSFS_memoryIoInterface =
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   374
{
1280
bd174b99fa5b Add binary compatibility to PHYSFS_Io.
Ryan C. Gordon <icculus@icculus.org>
parents: 1279
diff changeset
   375
    CURRENT_PHYSFS_IO_API_VERSION, NULL,
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   376
    memoryIo_read,
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   377
    memoryIo_write,
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   378
    memoryIo_seek,
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   379
    memoryIo_tell,
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   380
    memoryIo_length,
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   381
    memoryIo_duplicate,
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   382
    memoryIo_flush,
1280
bd174b99fa5b Add binary compatibility to PHYSFS_Io.
Ryan C. Gordon <icculus@icculus.org>
parents: 1279
diff changeset
   383
    memoryIo_destroy
1120
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
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   386
PHYSFS_Io *__PHYSFS_createMemoryIo(const void *buf, PHYSFS_uint64 len,
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   387
                                   void (*destruct)(void *))
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   388
{
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   389
    PHYSFS_Io *io = NULL;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   390
    MemoryIoInfo *info = NULL;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   391
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   392
    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
   393
    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
   394
    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
   395
    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
   396
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   397
    memset(info, '\0', sizeof (*info));
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   398
    info->buf = (const PHYSFS_uint8 *) buf;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   399
    info->len = len;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   400
    info->pos = 0;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   401
    info->parent = NULL;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   402
    info->refcount = 1;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   403
    info->destruct = destruct;
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
    memcpy(io, &__PHYSFS_memoryIoInterface, sizeof (*io));
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   406
    io->opaque = info;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   407
    return io;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   408
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   409
createMemoryIo_failed:
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   410
    if (info != NULL) allocator.Free(info);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   411
    if (io != NULL) allocator.Free(io);
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   412
    return NULL;
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   413
} /* __PHYSFS_createMemoryIo */
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   414
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   415
1123
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   416
/* 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
   417
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   418
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
   419
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   420
    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
   421
} /* handleIo_read */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   422
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   423
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
   424
                                    PHYSFS_uint64 len)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   425
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   426
    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
   427
} /* handleIo_write */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   428
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   429
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
   430
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   431
    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
   432
} /* handleIo_seek */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   433
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   434
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
   435
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   436
    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
   437
} /* handleIo_tell */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   438
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   439
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
   440
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   441
    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
   442
} /* handleIo_length */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   443
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   444
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
   445
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   446
    /*
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   447
     * 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
   448
     *  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
   449
     */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   450
    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
   451
    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
   452
    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
   453
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   454
    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
   455
    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
   456
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   457
    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
   458
    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
   459
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   460
#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
   461
    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
   462
    {
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   463
        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
   464
        if (!newfh->buffer)
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   465
            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
   466
        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
   467
    } /* if */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   468
#endif
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   469
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   470
    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
   471
    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
   472
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   473
    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
   474
    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
   475
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   476
    __PHYSFS_platformGrabMutex(stateLock);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   477
    if (newfh->forReading)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   478
    {
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   479
        newfh->next = openReadList;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   480
        openReadList = newfh;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   481
    } /* if */
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
    {
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   484
        newfh->next = openWriteList;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   485
        openWriteList = newfh;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   486
    } /* else */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   487
    __PHYSFS_platformReleaseMutex(stateLock);
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
    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
   490
    retval->opaque = newfh;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   491
    return retval;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   492
    
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   493
handleIo_dupe_failed:
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   494
    if (newfh)
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   495
    {
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   496
        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
   497
        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
   498
        allocator.Free(newfh);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   499
    } /* if */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   500
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   501
    return NULL;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   502
} /* handleIo_duplicate */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   503
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   504
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
   505
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   506
    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
   507
} /* handleIo_flush */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   508
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   509
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
   510
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   511
    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
   512
        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
   513
    allocator.Free(io);
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   514
} /* handleIo_destroy */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   515
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   516
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
   517
{
1280
bd174b99fa5b Add binary compatibility to PHYSFS_Io.
Ryan C. Gordon <icculus@icculus.org>
parents: 1279
diff changeset
   518
    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
   519
    handleIo_read,
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   520
    handleIo_write,
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   521
    handleIo_seek,
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   522
    handleIo_tell,
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   523
    handleIo_length,
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   524
    handleIo_duplicate,
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   525
    handleIo_flush,
1280
bd174b99fa5b Add binary compatibility to PHYSFS_Io.
Ryan C. Gordon <icculus@icculus.org>
parents: 1279
diff changeset
   526
    handleIo_destroy
1123
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   527
};
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   528
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   529
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
   530
{
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   531
    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
   532
    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
   533
    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
   534
    io->opaque = f;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   535
    return io;
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   536
} /* __PHYSFS_createHandleIo */
6fdff9f9758d Added PHYSFS_mountHandle(). Now you can do archives-in-archives!
Ryan C. Gordon <icculus@icculus.org>
parents: 1122
diff changeset
   537
1120
67e5e23425a0 Added PHYSFS_mountMemory().
Ryan C. Gordon <icculus@icculus.org>
parents: 1119
diff changeset
   538
11
677e01f5109e Progress toward complete implementation continues...
Ryan C. Gordon <icculus@icculus.org>
parents: 7
diff changeset
   539
/* functions ... */
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   540
657
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   541
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
   542
{
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   543
    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
   544
    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
   545
    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
   546
} EnumStringListCallbackData;
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   547
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   548
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
   549
{
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   550
    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
   551
    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
   552
    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
   553
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
   554
    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
   555
        return;
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   556
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 688
diff changeset
   557
    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
   558
    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
   559
    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
   560
        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
   561
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   562
    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
   563
    {
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
   564
        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
   565
        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
   566
        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
   567
        return;
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   568
    } /* if */
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   569
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   570
    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
   571
    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
   572
    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
   573
} /* enumStringListCallback */
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   574
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   575
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   576
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
   577
{
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   578
    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
   579
    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
   580
    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
   581
    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
   582
    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
   583
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 (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
   585
    {
1328
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   586
        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
   587
        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
   588
    } /* 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
   589
657
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   590
    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
   591
    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
   592
} /* doEnumStringList */
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   593
dad3b5c307a9 Added callback APIs and ripped up the internals everywhere to use them.
Ryan C. Gordon <icculus@icculus.org>
parents: 654
diff changeset
   594
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   595
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
   596
                                 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
   597
                                 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
   598
{
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   599
    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
   600
    int sorted;
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   601
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   602
    do
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   603
    {
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   604
        sorted = 1;
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   605
        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
   606
        {
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   607
            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
   608
            {
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   609
                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
   610
                sorted = 0;
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   611
            } /* if */
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   612
        } /* for */
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   613
    } while (!sorted);
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   614
} /* __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
   615
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
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
   618
                         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
   619
                         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
   620
{
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   621
    size_t i;
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   622
    size_t j;
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   623
    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
   624
578
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   625
    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
   626
        __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
   627
    else
578
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   628
    {
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   629
        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
   630
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   631
        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
   632
        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
   633
        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
   634
578
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   635
        j = hi - 1;
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   636
        swapfn(a, i, j);
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   637
        i = lo;
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   638
        v = j;
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   639
        while (1)
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   640
        {
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   641
            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
   642
            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
   643
            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
   644
                break;
578
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   645
            swapfn(a, i, j);
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   646
        } /* while */
948
923323444178 Valgrind fix: avoid overlapping memcpy() in sorting routines (thanks, JLM!).
Ryan C. Gordon <icculus@icculus.org>
parents: 901
diff changeset
   647
        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
   648
            swapfn(a, i, hi-1);
578
bff1af8455ca Tabs-to-spaces patch by James Turk.
Ryan C. Gordon <icculus@icculus.org>
parents: 576
diff changeset
   649
        __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
   650
        __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
   651
    } /* else */
462
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   652
} /* __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
   653
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   654
1283
8bcc48d243df Added Zip64 support to the .zip archiver.
Ryan C. Gordon <icculus@icculus.org>
parents: 1281
diff changeset
   655
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
   656
                   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
   657
                   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
   658
{
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   659
    /*
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   660
     * 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
   661
     *   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
   662
     */
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
   663
    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
   664
        __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
   665
} /* __PHYSFS_sort */
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   666
83c60189bc21 Made sorting more generic, moved it here. Added sort profiling code.
Ryan C. Gordon <icculus@icculus.org>
parents: 453
diff changeset
   667
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
   668
static ErrState *findErrorForCurrentThread(void)
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   669
{
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
   670
    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
   671
    void *tid;
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   672
272
470430943851 Fixed a crashbug when calling PHYSFS_deinit() twice in a row.
Ryan C. Gordon <icculus@icculus.org>
parents: 242
diff changeset
   673
    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
   674
        __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
   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
    if (errorStates != NULL)
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   677
    {
163
fc2b8ee5b420 Approved zeph's comments, fixed a few of my screwups.
Ryan C. Gordon <icculus@icculus.org>
parents: 160
diff changeset
   678
        tid = __PHYSFS_platformGetThreadID();
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   679
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
   680
        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
   681
        {
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   682
            if (i->tid == tid)
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   683
            {
272
470430943851 Fixed a crashbug when calling PHYSFS_deinit() twice in a row.
Ryan C. Gordon <icculus@icculus.org>
parents: 242
diff changeset
   684
                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
   685
                    __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
   686
                return i;
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   687
            } /* if */
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   688
        } /* for */
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   689
    } /* 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
   690
272
470430943851 Fixed a crashbug when calling PHYSFS_deinit() twice in a row.
Ryan C. Gordon <icculus@icculus.org>
parents: 242
diff changeset
   691
    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
   692
        __PHYSFS_platformReleaseMutex(errorLock);
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   693
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
   694
    return NULL;   /* no error available. */
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   695
} /* findErrorForCurrentThread */
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   696
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   697
1327
998351d485d9 Cleaned out the "exists" nonsense in the stat() API.
Ryan C. Gordon <icculus@icculus.org>
parents: 1326
diff changeset
   698
/* 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
   699
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
   700
{
998351d485d9 Cleaned out the "exists" nonsense in the stat() API.
Ryan C. Gordon <icculus@icculus.org>
parents: 1326
diff changeset
   701
    const ErrState *err = findErrorForCurrentThread();
998351d485d9 Cleaned out the "exists" nonsense in the stat() API.
Ryan C. Gordon <icculus@icculus.org>
parents: 1326
diff changeset
   702
    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
   703
} /* currentErrorCode */
998351d485d9 Cleaned out the "exists" nonsense in the stat() API.
Ryan C. Gordon <icculus@icculus.org>
parents: 1326
diff changeset
   704
998351d485d9 Cleaned out the "exists" nonsense in the stat() API.
Ryan C. Gordon <icculus@icculus.org>
parents: 1326
diff changeset
   705
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
   706
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
   707
{
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
    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
   709
    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
   710
    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
   711
        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
   712
    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
   713
} /* 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
   714
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
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
   717
{
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
    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
   719
    {
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_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
   721
        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
   722
        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
   723
        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
   724
        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
   725
        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
   726
        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
   727
        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
   728
        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
   729
        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
   730
        case PHYSFS_ERR_NOT_MOUNTED: return "not mounted";
1322
5476917b8ddf Allow application-supplied archivers.
Ryan C. Gordon <icculus@icculus.org>
parents: 1315
diff changeset
   731
        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
   732
        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
   733
        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
   734
        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
   735
        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
   736
        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
   737
        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
   738
        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
   739
        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
   740
        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
   741
        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
   742
        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
   743
        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
   744
        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
   745
        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
   746
        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
   747
        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
   748
        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
   749
        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
   750
    } /* 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
   751
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   752
    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
   753
} /* 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
   754
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   755
1328
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   756
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
   757
{
1328
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   758
    ErrState *err;
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   759
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   760
    if (!errcode)
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   761
        return;
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   762
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   763
    err = findErrorForCurrentThread();
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   764
    if (err == NULL)
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
        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
   767
        if (err == NULL)
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   768
            return;   /* uhh...? */
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   769
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   770
        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
   771
        err->tid = __PHYSFS_platformGetThreadID();
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   772
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   773
        if (errorLock != NULL)
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   774
            __PHYSFS_platformGrabMutex(errorLock);
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   775
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   776
        err->next = errorStates;
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   777
        errorStates = err;
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
        if (errorLock != NULL)
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   780
            __PHYSFS_platformReleaseMutex(errorLock);
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   781
    } /* if */
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   782
a5314f07614a Remove __PHYSFS_setError(), use the new public API instead.
Ryan C. Gordon <icculus@icculus.org>
parents: 1327
diff changeset
   783
    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
   784
} /* 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
   785
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
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   787
const char *PHYSFS_getLastError(void)
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   788
{
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
   789
    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
   790
    return (err) ? PHYSFS_getErrorByCode(err) : NULL;
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   791
} /* PHYSFS_getLastError */
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   792
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   793
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   794
/* 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
   795
static void freeErrorStates(void)
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   796
{
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
   797
    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
   798
    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
   799
22d4d1bd4e21 Reworked the error reporting API. Now we use error codes instead of strings.
Ryan C. Gordon <icculus@icculus.org>
parents: 1239
diff changeset
   800
    for (i = errorStates; i != NULL; i = next)
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   801
    {
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   802
        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
   803
        allocator.Free(i);
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   804
    } /* for */
272
470430943851 Fixed a crashbug when calling PHYSFS_deinit() twice in a row.
Ryan C. Gordon <icculus@icculus.org>
parents: 242
diff changeset
   805
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
   806
    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
   807
} /* freeErrorStates */
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   808
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
   809
5
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   810
void PHYSFS_getLinkedVersion(PHYSFS_Version *ver)
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   811
{
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   812
    if (ver != NULL)
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   813
    {
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   814
        ver->major = PHYSFS_VER_MAJOR;
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   815
        ver->minor = PHYSFS_VER_MINOR;
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   816
        ver->patch = PHYSFS_VER_PATCH;
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   817
    } /* if */
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   818
} /* PHYSFS_getLinkedVersion */
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   819
055ddaaabf85 Initial add; not yet completely implemented.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
   820
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   821
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
   822
{
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   823
    const char *retval = NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   824
    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
   825
    {
1135
3b71a0c08665 Patched to compile on Windows.
Ryan C. Gordon <icculus@icculus.org>
parents: 1130
diff changeset
   826
        const char *p = strchr(fname, '.');
3b71a0c08665 Patched to compile on Windows.
Ryan C. Gordon <icculus@icculus.org>
parents: 1130
diff changeset
   827
        retval = p;
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   828
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   829
        while (p != NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   830
        {
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   831
            p = strchr(p + 1, '.');
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   832
            if (p != NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   833
                retval = p;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   834
        } /* while */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   835
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   836
        if (retval != NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   837
            retval++;  /* skip '.' */
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   838
    } /* if */
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   839
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
   840
    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
   841
} /* 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
   842
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   843
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   844
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
   845
                             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
   846
{
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   847
    DirHandle *retval = NULL;
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   848
    void *opaque = NULL;
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   849
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   850
    if (io != NULL)
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
   851
        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
   852
1571
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   853
    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
   854
    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
   855
    {
1113
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   856
        retval = (DirHandle *) allocator.Malloc(sizeof (DirHandle));
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   857
        if (retval == NULL)
1270
f8d3f58561b1 Renamed PHYSFS_Archiver::dirClose() to PHYSFS_Archiver::closeArchive().
Ryan C. Gordon <icculus@icculus.org>
parents: 1268
diff changeset
   858
            funcs->closeArchive(opaque);
1113
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   859
        else
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   860
        {
1113
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   861
            memset(retval, '\0', sizeof (DirHandle));
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   862
            retval->mountPoint = NULL;
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   863
            retval->funcs = funcs;
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   864
            retval->opaque = opaque;
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   865
        } /* else */
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   866
    } /* if */
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   867
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
   868
    return retval;
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   869
} /* tryOpenDir */
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   870
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   871
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   872
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
   873
{
648
5c993684b8f2 Cleaned up archiver interface to not deal with DirHandles anymore,
Ryan C. Gordon <icculus@icculus.org>
parents: 644
diff changeset
   874
    DirHandle *retval = NULL;
1456
2328964939fd Fixed compiler warnings on Visual Studio about const qualifiers.
Ryan C. Gordon <icculus@icculus.org>
parents: 1449
diff changeset
   875
    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
   876
    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
   877
    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
   878
    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
   879
    PHYSFS_ErrorCode errcode;
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
   880
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   881
    assert((io != NULL) || (d != NULL));
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   882
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   883
    if (io == NULL)
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   884
    {
1643
2653b3bc19c9 PHYSFS_setWriteDir() shouldn't create an empty file if the dir doesn't exist.
Ryan C. Gordon <icculus@icculus.org>
parents: 1625
diff changeset
   885
        /* file doesn't exist, etc? Just fail out. */
2653b3bc19c9 PHYSFS_setWriteDir() shouldn't create an empty file if the dir doesn't exist.
Ryan C. Gordon <icculus@icculus.org>
parents: 1625
diff changeset
   886
        PHYSFS_Stat statbuf;
2653b3bc19c9 PHYSFS_setWriteDir() shouldn't create an empty file if the dir doesn't exist.
Ryan C. Gordon <icculus@icculus.org>
parents: 1625
diff changeset
   887
        BAIL_IF_ERRPASS(!__PHYSFS_platformStat(d, &statbuf, 1), NULL);
2653b3bc19c9 PHYSFS_setWriteDir() shouldn't create an empty file if the dir doesn't exist.
Ryan C. Gordon <icculus@icculus.org>
parents: 1625
diff changeset
   888
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   889
        /* DIR gets first shot (unlike the rest, it doesn't deal with files). */
1643
2653b3bc19c9 PHYSFS_setWriteDir() shouldn't create an empty file if the dir doesn't exist.
Ryan C. Gordon <icculus@icculus.org>
parents: 1625
diff changeset
   890
        if (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY)
2653b3bc19c9 PHYSFS_setWriteDir() shouldn't create an empty file if the dir doesn't exist.
Ryan C. Gordon <icculus@icculus.org>
parents: 1625
diff changeset
   891
        {
2653b3bc19c9 PHYSFS_setWriteDir() shouldn't create an empty file if the dir doesn't exist.
Ryan C. Gordon <icculus@icculus.org>
parents: 1625
diff changeset
   892
            retval = tryOpenDir(io, &__PHYSFS_Archiver_DIR, d, forWriting, &claimed);
2653b3bc19c9 PHYSFS_setWriteDir() shouldn't create an empty file if the dir doesn't exist.
Ryan C. Gordon <icculus@icculus.org>
parents: 1625
diff changeset
   893
            if (retval || claimed)
2653b3bc19c9 PHYSFS_setWriteDir() shouldn't create an empty file if the dir doesn't exist.
Ryan C. Gordon <icculus@icculus.org>
parents: 1625
diff changeset
   894
                return retval;
2653b3bc19c9 PHYSFS_setWriteDir() shouldn't create an empty file if the dir doesn't exist.
Ryan C. Gordon <icculus@icculus.org>
parents: 1625
diff changeset
   895
        } /* if */
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   896
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   897
        io = __PHYSFS_createNativeIo(d, forWriting ? 'w' : 'r');
1643
2653b3bc19c9 PHYSFS_setWriteDir() shouldn't create an empty file if the dir doesn't exist.
Ryan C. Gordon <icculus@icculus.org>
parents: 1625
diff changeset
   898
        BAIL_IF_ERRPASS(!io, NULL);
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
   899
        created_io = 1;
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
   900
    } /* if */
1113
2136d64bd1ad Removed PHYSFS_Archiver's isArchive() method.
Ryan C. Gordon <icculus@icculus.org>
parents: 1112
diff changeset
   901
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   902
    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
   903
    if (ext != NULL)
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
   904
    {
398
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   905
        /* 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
   906
        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
   907
        {
1555
5495a0e50b5e utf8: big improvements to case-insensitive UTF-8 string compare.
Ryan C. Gordon <icculus@icculus.org>
parents: 1554
diff changeset
   908
            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
   909
                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
   910
        } /* for */
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   911
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   912
        /* 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
   913
        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
   914
        {
1555
5495a0e50b5e utf8: big improvements to case-insensitive UTF-8 string compare.
Ryan C. Gordon <icculus@icculus.org>
parents: 1554
diff changeset
   915
            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
   916
                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
   917
        } /* for */
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   918
    } /* if */
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   919
aa1e763b09ae Archivers with matching file extensions get first shot at an archive.
Ryan C. Gordon <icculus@icculus.org>
parents: 393
diff changeset
   920
    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
   921
    {
1571
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   922
        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
   923
            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
   924
    } /* else */
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
   925
1571
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   926
    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
   927
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
   928
    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
   929
        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
   930
1571
fbd9698219c1 Archivers can now specify whether an archive definitely was intended for them.
Ryan C. Gordon <icculus@icculus.org>
parents: 1567
diff changeset
   931
    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
   932
    return retval;
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
   933
} /* openDirectory */
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
   934
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
   935
683
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   936
/*
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   937
 * 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
   938
 *  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
   939
 *  (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
   940
 *  cleaned up string is deposited.
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   941
 * 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
   942
 *  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
   943
 */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   944
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
   945
{
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   946
    char *prev;
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   947
    char ch;
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
    while (*src == '/')  /* skip initial '/' chars... */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   950
        src++;
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   951
1625
b6d25a1927c2 Catch access to paths that are just "." or ".." without any path separator.
Ryan C. Gordon <icculus@icculus.org>
parents: 1620
diff changeset
   952
    /* Make sure the entire string isn't "." or ".." */
b6d25a1927c2 Catch access to paths that are just "." or ".." without any path separator.
Ryan C. Gordon <icculus@icculus.org>
parents: 1620
diff changeset
   953
    if ((strcmp(src, ".") == 0) || (strcmp(src, "..") == 0))
b6d25a1927c2 Catch access to paths that are just "." or ".." without any path separator.
Ryan C. Gordon <icculus@icculus.org>
parents: 1620
diff changeset
   954
        BAIL(PHYSFS_ERR_BAD_FILENAME, 0);
b6d25a1927c2 Catch access to paths that are just "." or ".." without any path separator.
Ryan C. Gordon <icculus@icculus.org>
parents: 1620
diff changeset
   955
683
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   956
    prev = dst;
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   957
    do
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   958
    {
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   959
        ch = *(src++);
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
        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
   962
            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
   963
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   964
        if (ch == '/')   /* path separator. */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   965
        {
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   966
            *dst = '\0';  /* "." and ".." are illegal pathnames. */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   967
            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
   968
                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
   969
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   970
            while (*src == '/')   /* chop out doubles... */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   971
                src++;
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   972
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   973
            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
   974
                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
   975
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   976
            prev = dst + 1;
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   977
        } /* if */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   978
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   979
        *(dst++) = ch;
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   980
    } while (ch != '\0');
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   981
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
   982
    return 1;
683
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   983
} /* sanitizePlatformIndependentPath */
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   984
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
   985
1649
9edc8d92bc61 Added PHYSFS_setRoot().
Ryan C. Gordon <icculus@icculus.org>
parents: 1643
diff changeset
   986
static inline size_t dirHandleRootLen(const DirHandle *h)
9edc8d92bc61 Added PHYSFS_setRoot().
Ryan C. Gordon <icculus@icculus.org>
parents: 1643
diff changeset
   987
{
9edc8d92bc61 Added PHYSFS_setRoot().
Ryan C. Gordon <icculus@icculus.org>
parents: 1643
diff changeset
   988
    return h ? h->rootlen : 0;
9edc8d92bc61 Added PHYSFS_setRoot().
Ryan C. Gordon <icculus@icculus.org>
parents: 1643
diff changeset
   989
} /* dirHandleRootLen */
9edc8d92bc61 Added PHYSFS_setRoot().
Ryan C. Gordon <icculus@icculus.org>
parents: 1643
diff changeset
   990
9edc8d92bc61 Added PHYSFS_setRoot().
Ryan C. Gordon <icculus@icculus.org>
parents: 1643
diff changeset
   991
static inline int sanitizePlatformIndependentPathWithRoot(const DirHandle *h, const char *src, char *dst)
9edc8d92bc61 Added PHYSFS_setRoot().
Ryan C. Gordon <icculus@icculus.org>
parents: 1643
diff changeset
   992
{
9edc8d92bc61 Added PHYSFS_setRoot().
Ryan C. Gordon <icculus@icculus.org>
parents: 1643
diff changeset
   993
    return sanitizePlatformIndependentPath(src, dst + dirHandleRootLen(h));
9edc8d92bc61 Added PHYSFS_setRoot().
Ryan C. Gordon <icculus@icculus.org>
parents: 1643
diff changeset
   994
} /* sanitizePlatformIndependentPathWithRoot */
9edc8d92bc61 Added PHYSFS_setRoot().
Ryan C. Gordon <icculus@icculus.org>
parents: 1643
diff changeset
   995
9edc8d92bc61 Added PHYSFS_setRoot().
Ryan C. Gordon <icculus@icculus.org>
parents: 1643
diff changeset
   996
9edc8d92bc61 Added PHYSFS_setRoot().
Ryan C. Gordon <icculus@icculus.org>
parents: 1643
diff changeset
   997
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
 * 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
  1000
 *  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
  1001
 *  state.
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
 * 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
  1004
 *  "/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
  1005
 *  all zero. "/a/b" will succeed, though.
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
static int partOfMountPoint(DirHandle *h, char *fname)
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1008
{
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1009
    int rc;
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1010
    size_t len, mntpntlen;
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1011
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1012
    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
  1013
        return 0;
687
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1014
    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
  1015
        return 1;
687
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1016
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1017
    len = strlen(fname);
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1018
    mntpntlen = strlen(h->mountPoint);
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1019
    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
  1020
        return 0;
687
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1021
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1022
    /* 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
  1023
    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
  1024
        return 0;
687
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1025
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1026
    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
  1027
    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
  1028
        return 0;  /* not a match. */
687
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1029
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1030
    /* 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
  1031
    return h->mountPoint[len] == '/';
687
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1032
} /* partOfMountPoint */
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1033
f76dffa43fa2 More mountpoint work and other cleanups.
Ryan C. Gordon <icculus@icculus.org>
parents: 685
diff changeset
  1034
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1035
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
  1036
                                  const char *mountPoint, int forWriting)
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1037
{
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1038
    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
  1039
    char *tmpmntpnt = NULL;
683
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
  1040
1618
0bbfaf6c5508 Don't allow NULL filenames to be mounted.
Ryan C. Gordon <icculus@icculus.org>
parents: 1605
diff changeset
  1041
    assert(newDir != NULL);  /* should have caught this higher up. */
0bbfaf6c5508 Don't allow NULL filenames to be mounted.
Ryan C. Gordon <icculus@icculus.org>
parents: 1605
diff changeset
  1042
683
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
  1043
    if (mountPoint != NULL)
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
  1044
    {
852
9467e96abdf1 Replaced some Malloc and all the alloca() calls with __PHYSFS_smallAlloc(),
Ryan C. Gordon <icculus@icculus.org>
parents: 848
diff changeset
  1045
        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
  1046
        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
  1047
        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
  1048
        if (!sanitizePlatformIndependentPath(mountPoint, tmpmntpnt))
683
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
  1049
            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
  1050
        mountPoint = tmpmntpnt;  /* sanitized version. */
683
e724adb731df Split off sanitizePlatformIndependentPath() from verifySecurity(), which makes
Ryan C. Gordon <icculus@icculus.org>
parents: 679
diff changeset
  1051
    } /* if */
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1052
1118
2e09fc635fdd Abstracted file i/o into PHYSFS_Io interface.
Ryan C. Gordon <icculus@icculus.org>
parents: 1113
diff changeset
  1053
    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
  1054
    GOTO_IF_ERRPASS(!dirHandle, badDirHandle);
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1055
1618
0bbfaf6c5508 Don't allow NULL filenames to be mounted.
Ryan C. Gordon <icculus@icculus.org>
parents: 1605
diff changeset
  1056
    dirHandle->dirName = (char *) allocator.Malloc(strlen(newDir) + 1);
0bbfaf6c5508 Don't allow NULL filenames to be mounted.
Ryan C. Gordon <icculus@icculus.org>
parents: 1605
diff changeset
  1057
    GOTO_IF(!dirHandle->dirName, PHYSFS_ERR_OUT_OF_MEMORY, badDirHandle);
0bbfaf6c5508 Don't allow NULL filenames to be mounted.
Ryan C. Gordon <icculus@icculus.org>
parents: 1605
diff changeset
  1058
    strcpy(dirHandle->dirName, newDir);
679
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1059
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1060
    if ((mountPoint != NULL) && (*mountPoint != '\0'))
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1061
    {
691
71d9affe0d8a All memory management now goes through allocation hooks instead of directly to
Ryan C. Gordon <icculus@icculus.org>
parents: 688
diff changeset
  1062
        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
  1063
        if (!dirHandle->mountPoint)
1402
c5a5dadb901d Cleanup BAIL_* and GOTO_* macros to be less cluttered.
Ryan C. Gordon <icculus@icculus.org>
parents: 1398
diff changeset
  1064
            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
  1065
        strcpy(dirHandle->mountPoint, mountPoint);
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1066
        strcat(dirHandle->mountPoint, "/");
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1067
    } /* if */
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1068
852
9467e96abdf1 Replaced some Malloc and all the alloca() calls with __PHYSFS_smallAlloc(),
Ryan C. Gordon <icculus@icculus.org>
parents: 848
diff changeset
  1069
    __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
  1070
    return dirHandle;
679
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1071
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1072
badDirHandle:
ae75b5548364 First chunk of PHYSFS_mount() implementation. Incomplete!
Ryan C. Gordon <icculus@icculus.org>
parents: 668
diff changeset
  1073
    if (dirHandle != NULL)
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1074
    {
1270
f8d3f58561b1 Renamed PHYSFS_Archiver::dirClose() to PHYSFS_Archiver::closeArchive().
Ryan C. Gordon <icculus@icculus.org>
parents: 1268
diff changeset
  1075
        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
  1076
        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
  1077
        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
  1078
        allocator.Free(dirHandle);
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1079
    } /* if */
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1080
852
9467e96abdf1 Replaced some Malloc and all the alloca() calls with __PHYSFS_smallAlloc(),
Ryan C. Gordon <icculus@icculus.org>
parents: 848
diff changeset
  1081
    __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
  1082
    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
  1083
} /* createDirHandle */
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1084
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1085
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1086
/* 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
  1087
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
  1088
{
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
  1089
    FileHandle *i;
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1090
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
  1091
    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
  1092
        return 1;
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1093
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1094
    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
  1095
        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
  1096
1270
f8d3f58561b1 Renamed PHYSFS_Archiver::dirClose() to PHYSFS_Archiver::closeArchive().
Ryan C. Gordon <icculus@icculus.org>
parents: 1268
diff changeset
  1097
    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
  1098
    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
  1099
    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
  1100
    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
  1101
    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
  1102
} /* freeDirHandle */
15
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1103
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1104
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1105
static char *calculateBaseDir(const char *argv0)
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1106
{
1225
671d4ea47c13 Make __PHYSFS_platformDirSeparator into a single char.
Ryan C. Gordon <icculus@icculus.org>
parents: 1224
diff changeset
  1107
    const char dirsep = __PHYSFS_platformDirSeparator;
848
963d26edb39b Cleanups in calculateBaseDir.
Ryan C. Gordon <icculus@icculus.org>
parents: 845
diff changeset
  1108
    char *retval = NULL;
963d26edb39b Cleanups in calculateBaseDir.
Ryan C. Gordon <icculus@icculus.org>
parents: 845
diff changeset
  1109
    char *ptr = NULL;
23
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1110
848
963d26edb39b Cleanups in calculateBaseDir.
Ryan C. Gordon <icculus@icculus.org>
parents: 845
diff changeset
  1111
    /* 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
  1112
    retval = __PHYSFS_platformCalcBaseDir(argv0);
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1113
    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
  1114
        return retval;
23
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1115
848
963d26edb39b Cleanups in calculateBaseDir.
Ryan C. Gordon <icculus@icculus.org>
parents: 845
diff changeset
  1116
    /* 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
  1117
    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
  1118
1225
671d4ea47c13 Make __PHYSFS_platformDirSeparator into a single char.
Ryan C. Gordon <icculus@icculus.org>
parents: 1224
diff changeset
  1119
    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
  1120
    if (ptr != NULL)
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1121
    {
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
  1122
        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
  1123
        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
  1124
        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
  1125
        memcpy(retval, argv0, size);
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1126
        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
  1127
        return retval;
23
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1128
    } /* if */
bd6ba9c8717c Initial debugging: dropped PhysicsFS routines into the Build engine,
Ryan C. Gordon <icculus@icculus.org>
parents: 22
diff changeset
  1129
848
963d26edb39b Cleanups in calculateBaseDir.
Ryan C. Gordon <icculus@icculus.org>
parents: 845
diff changeset
  1130
    /* 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
  1131
    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
  1132
} /* calculateBaseDir */
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1133
418eacc97ac8 Tons of updates. Mostly implemented. Mostly compiling.
Ryan C. Gordon <icculus@icculus.org>
parents: 12
diff changeset
  1134
145
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1135
static int initializeMutexes(void)
d6385584f6c4 First shot at thread-safety.
Ryan C. Gordon <icculus@icculus.org>
parents: 132
diff changeset
  1136
{