misc/libphysfs/physfs.c
author nemo
Sun, 04 Jan 2015 00:44:14 -0500
branch0.9.21
changeset 10743 1d16c5414fee
parent 10017 de822cd3df3a
child 12213 bb5522e88ab2
permissions -rw-r--r--
Intent is to allow filtering by arbitrary flag combinations. This isn't actually working yet. No idea why. It seems it should. Tired though, so will look at it tomorrow.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     1
/**
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     2
 * PhysicsFS; a portable, flexible file i/o abstraction.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     3
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     4
 * Documentation is in physfs.h. It's verbose, honest.  :)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     5
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     6
 * Please see the file LICENSE.txt in the source's root directory.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     7
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     8
 *  This file written by Ryan C. Gordon.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     9
 */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    10
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    11
/* !!! FIXME: ERR_PAST_EOF shouldn't trigger for reads. Just return zero. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    12
/* !!! FIXME: use snprintf(), not sprintf(). */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    13
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    14
#define __PHYSICSFS_INTERNAL__
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    15
#include "physfs_internal.h"
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    16
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    17
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    18
typedef struct __PHYSFS_DIRHANDLE__
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    19
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    20
    void *opaque;  /* Instance data unique to the archiver. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    21
    char *dirName;  /* Path to archive in platform-dependent notation. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    22
    char *mountPoint; /* Mountpoint in virtual file tree. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    23
    const PHYSFS_Archiver *funcs;  /* Ptr to archiver info for this handle. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    24
    struct __PHYSFS_DIRHANDLE__ *next;  /* linked list stuff. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    25
} DirHandle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    26
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    27
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    28
typedef struct __PHYSFS_FILEHANDLE__
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    29
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    30
    PHYSFS_Io *io;  /* Instance data unique to the archiver for this file. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    31
    PHYSFS_uint8 forReading; /* Non-zero if reading, zero if write/append */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    32
    const DirHandle *dirHandle;  /* Archiver instance that created this */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    33
    PHYSFS_uint8 *buffer;  /* Buffer, if set (NULL otherwise). Don't touch! */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    34
    PHYSFS_uint32 bufsize;  /* Bufsize, if set (0 otherwise). Don't touch! */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    35
    PHYSFS_uint32 buffill;  /* Buffer fill size. Don't touch! */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    36
    PHYSFS_uint32 bufpos;  /* Buffer position. Don't touch! */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    37
    struct __PHYSFS_FILEHANDLE__ *next;  /* linked list stuff. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    38
} FileHandle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    39
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    40
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    41
typedef struct __PHYSFS_ERRSTATETYPE__
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    42
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    43
    void *tid;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    44
    PHYSFS_ErrorCode code;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    45
    struct __PHYSFS_ERRSTATETYPE__ *next;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    46
} ErrState;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    47
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    48
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    49
/* The various i/o drivers...some of these may not be compiled in. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    50
extern const PHYSFS_Archiver __PHYSFS_Archiver_ZIP;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    51
extern const PHYSFS_Archiver __PHYSFS_Archiver_LZMA;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    52
extern const PHYSFS_Archiver __PHYSFS_Archiver_GRP;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    53
extern const PHYSFS_Archiver __PHYSFS_Archiver_QPAK;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    54
extern const PHYSFS_Archiver __PHYSFS_Archiver_HOG;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    55
extern const PHYSFS_Archiver __PHYSFS_Archiver_MVL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    56
extern const PHYSFS_Archiver __PHYSFS_Archiver_WAD;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    57
extern const PHYSFS_Archiver __PHYSFS_Archiver_DIR;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    58
extern const PHYSFS_Archiver __PHYSFS_Archiver_ISO9660;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    59
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    60
static const PHYSFS_Archiver *staticArchivers[] =
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    61
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    62
#if PHYSFS_SUPPORTS_ZIP
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    63
    &__PHYSFS_Archiver_ZIP,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    64
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    65
#if PHYSFS_SUPPORTS_7Z
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    66
    &__PHYSFS_Archiver_LZMA,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    67
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    68
#if PHYSFS_SUPPORTS_GRP
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    69
    &__PHYSFS_Archiver_GRP,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    70
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    71
#if PHYSFS_SUPPORTS_QPAK
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    72
    &__PHYSFS_Archiver_QPAK,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    73
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    74
#if PHYSFS_SUPPORTS_HOG
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    75
    &__PHYSFS_Archiver_HOG,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    76
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    77
#if PHYSFS_SUPPORTS_MVL
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    78
    &__PHYSFS_Archiver_MVL,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    79
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    80
#if PHYSFS_SUPPORTS_WAD
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    81
    &__PHYSFS_Archiver_WAD,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    82
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    83
#if PHYSFS_SUPPORTS_ISO9660
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    84
    &__PHYSFS_Archiver_ISO9660,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    85
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    86
    NULL
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    87
};
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    88
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    89
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    90
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    91
/* General PhysicsFS state ... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    92
static int initialized = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    93
static ErrState *errorStates = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    94
static DirHandle *searchPath = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    95
static DirHandle *writeDir = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    96
static FileHandle *openWriteList = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    97
static FileHandle *openReadList = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    98
static char *baseDir = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    99
static char *userDir = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   100
static char *prefDir = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   101
static int allowSymLinks = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   102
static const PHYSFS_Archiver **archivers = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   103
static const PHYSFS_ArchiveInfo **archiveInfo = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   104
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   105
/* mutexes ... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   106
static void *errorLock = NULL;     /* protects error message list.        */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   107
static void *stateLock = NULL;     /* protects other PhysFS static state. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   108
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   109
/* allocator ... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   110
static int externalAllocator = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   111
PHYSFS_Allocator allocator;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   112
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   113
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   114
/* PHYSFS_Io implementation for i/o to physical filesystem... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   115
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   116
/* !!! FIXME: maybe refcount the paths in a string pool? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   117
typedef struct __PHYSFS_NativeIoInfo
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   118
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   119
    void *handle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   120
    const char *path;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   121
    int mode;   /* 'r', 'w', or 'a' */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   122
} NativeIoInfo;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   123
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   124
static PHYSFS_sint64 nativeIo_read(PHYSFS_Io *io, void *buf, PHYSFS_uint64 len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   125
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   126
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   127
    return __PHYSFS_platformRead(info->handle, buf, len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   128
} /* nativeIo_read */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   129
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   130
static PHYSFS_sint64 nativeIo_write(PHYSFS_Io *io, const void *buffer,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   131
                                    PHYSFS_uint64 len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   132
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   133
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   134
    return __PHYSFS_platformWrite(info->handle, buffer, len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   135
} /* nativeIo_write */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   136
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   137
static int nativeIo_seek(PHYSFS_Io *io, PHYSFS_uint64 offset)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   138
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   139
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   140
    return __PHYSFS_platformSeek(info->handle, offset);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   141
} /* nativeIo_seek */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   142
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   143
static PHYSFS_sint64 nativeIo_tell(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   144
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   145
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   146
    return __PHYSFS_platformTell(info->handle);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   147
} /* nativeIo_tell */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   148
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   149
static PHYSFS_sint64 nativeIo_length(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   150
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   151
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   152
    return __PHYSFS_platformFileLength(info->handle);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   153
} /* nativeIo_length */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   154
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   155
static PHYSFS_Io *nativeIo_duplicate(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   156
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   157
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   158
    return __PHYSFS_createNativeIo(info->path, info->mode);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   159
} /* nativeIo_duplicate */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   160
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   161
static int nativeIo_flush(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   162
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   163
    return __PHYSFS_platformFlush(io->opaque);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   164
} /* nativeIo_flush */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   165
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   166
static void nativeIo_destroy(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   167
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   168
    NativeIoInfo *info = (NativeIoInfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   169
    __PHYSFS_platformClose(info->handle);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   170
    allocator.Free((void *) info->path);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   171
    allocator.Free(info);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   172
    allocator.Free(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   173
} /* nativeIo_destroy */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   174
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   175
static const PHYSFS_Io __PHYSFS_nativeIoInterface =
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   176
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   177
    CURRENT_PHYSFS_IO_API_VERSION, NULL,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   178
    nativeIo_read,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   179
    nativeIo_write,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   180
    nativeIo_seek,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   181
    nativeIo_tell,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   182
    nativeIo_length,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   183
    nativeIo_duplicate,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   184
    nativeIo_flush,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   185
    nativeIo_destroy
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   186
};
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   187
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   188
PHYSFS_Io *__PHYSFS_createNativeIo(const char *path, const int mode)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   189
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   190
    PHYSFS_Io *io = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   191
    NativeIoInfo *info = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   192
    void *handle = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   193
    char *pathdup = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   194
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   195
    assert((mode == 'r') || (mode == 'w') || (mode == 'a'));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   196
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   197
    io = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   198
    GOTO_IF_MACRO(!io, PHYSFS_ERR_OUT_OF_MEMORY, createNativeIo_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   199
    info = (NativeIoInfo *) allocator.Malloc(sizeof (NativeIoInfo));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   200
    GOTO_IF_MACRO(!info, PHYSFS_ERR_OUT_OF_MEMORY, createNativeIo_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   201
    pathdup = (char *) allocator.Malloc(strlen(path) + 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   202
    GOTO_IF_MACRO(!pathdup, PHYSFS_ERR_OUT_OF_MEMORY, createNativeIo_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   203
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   204
    if (mode == 'r')
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   205
        handle = __PHYSFS_platformOpenRead(path);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   206
    else if (mode == 'w')
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   207
        handle = __PHYSFS_platformOpenWrite(path);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   208
    else if (mode == 'a')
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   209
        handle = __PHYSFS_platformOpenAppend(path);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   210
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   211
    GOTO_IF_MACRO(!handle, ERRPASS, createNativeIo_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   212
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   213
    strcpy(pathdup, path);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   214
    info->handle = handle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   215
    info->path = pathdup;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   216
    info->mode = mode;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   217
    memcpy(io, &__PHYSFS_nativeIoInterface, sizeof (*io));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   218
    io->opaque = info;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   219
    return io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   220
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   221
createNativeIo_failed:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   222
    if (handle != NULL) __PHYSFS_platformClose(handle);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   223
    if (pathdup != NULL) allocator.Free(pathdup);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   224
    if (info != NULL) allocator.Free(info);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   225
    if (io != NULL) allocator.Free(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   226
    return NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   227
} /* __PHYSFS_createNativeIo */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   228
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   229
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   230
/* PHYSFS_Io implementation for i/o to a memory buffer... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   231
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   232
typedef struct __PHYSFS_MemoryIoInfo
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   233
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   234
    const PHYSFS_uint8 *buf;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   235
    PHYSFS_uint64 len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   236
    PHYSFS_uint64 pos;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   237
    PHYSFS_Io *parent;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   238
    volatile PHYSFS_uint32 refcount;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   239
    void (*destruct)(void *);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   240
} MemoryIoInfo;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   241
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   242
static PHYSFS_sint64 memoryIo_read(PHYSFS_Io *io, void *buf, PHYSFS_uint64 len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   243
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   244
    MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   245
    const PHYSFS_uint64 avail = info->len - info->pos;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   246
    assert(avail <= info->len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   247
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   248
    if (avail == 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   249
        return 0;  /* we're at EOF; nothing to do. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   250
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   251
    if (len > avail)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   252
        len = avail;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   253
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   254
    memcpy(buf, info->buf + info->pos, (size_t) len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   255
    info->pos += len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   256
    return len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   257
} /* memoryIo_read */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   258
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   259
static PHYSFS_sint64 memoryIo_write(PHYSFS_Io *io, const void *buffer,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   260
                                    PHYSFS_uint64 len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   261
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   262
    BAIL_MACRO(PHYSFS_ERR_OPEN_FOR_READING, -1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   263
} /* memoryIo_write */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   264
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   265
static int memoryIo_seek(PHYSFS_Io *io, PHYSFS_uint64 offset)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   266
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   267
    MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   268
    BAIL_IF_MACRO(offset > info->len, PHYSFS_ERR_PAST_EOF, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   269
    info->pos = offset;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   270
    return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   271
} /* memoryIo_seek */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   272
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   273
static PHYSFS_sint64 memoryIo_tell(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   274
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   275
    const MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   276
    return (PHYSFS_sint64) info->pos;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   277
} /* memoryIo_tell */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   278
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   279
static PHYSFS_sint64 memoryIo_length(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   280
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   281
    const MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   282
    return (PHYSFS_sint64) info->len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   283
} /* memoryIo_length */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   284
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   285
static PHYSFS_Io *memoryIo_duplicate(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   286
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   287
    MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   288
    MemoryIoInfo *newinfo = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   289
    PHYSFS_Io *parent = info->parent;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   290
    PHYSFS_Io *retval = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   291
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   292
    /* avoid deep copies. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   293
    assert((!parent) || (!((MemoryIoInfo *) parent->opaque)->parent) );
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   294
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   295
    /* share the buffer between duplicates. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   296
    if (parent != NULL)  /* dup the parent, increment its refcount. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   297
        return parent->duplicate(parent);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   298
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   299
    /* we're the parent. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   300
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   301
    retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   302
    BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   303
    newinfo = (MemoryIoInfo *) allocator.Malloc(sizeof (MemoryIoInfo));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   304
    if (!newinfo)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   305
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   306
        allocator.Free(retval);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   307
        BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   308
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   309
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   310
    /* !!! FIXME: want lockless atomic increment. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   311
    __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   312
    info->refcount++;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   313
    __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   314
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   315
    memset(newinfo, '\0', sizeof (*info));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   316
    newinfo->buf = info->buf;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   317
    newinfo->len = info->len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   318
    newinfo->pos = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   319
    newinfo->parent = io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   320
    newinfo->refcount = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   321
    newinfo->destruct = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   322
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   323
    memcpy(retval, io, sizeof (*retval));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   324
    retval->opaque = newinfo;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   325
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   326
} /* memoryIo_duplicate */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   327
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   328
static int memoryIo_flush(PHYSFS_Io *io) { return 1;  /* it's read-only. */ }
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   329
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   330
static void memoryIo_destroy(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   331
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   332
    MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   333
    PHYSFS_Io *parent = info->parent;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   334
    int should_die = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   335
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   336
    if (parent != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   337
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   338
        assert(info->buf == ((MemoryIoInfo *) info->parent->opaque)->buf);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   339
        assert(info->len == ((MemoryIoInfo *) info->parent->opaque)->len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   340
        assert(info->refcount == 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   341
        assert(info->destruct == NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   342
        allocator.Free(info);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   343
        allocator.Free(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   344
        parent->destroy(parent);  /* decrements refcount. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   345
        return;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   346
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   347
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   348
    /* we _are_ the parent. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   349
    assert(info->refcount > 0);  /* even in a race, we hold a reference. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   350
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   351
    /* !!! FIXME: want lockless atomic decrement. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   352
    __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   353
    info->refcount--;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   354
    should_die = (info->refcount == 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   355
    __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   356
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   357
    if (should_die)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   358
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   359
        void (*destruct)(void *) = info->destruct;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   360
        void *buf = (void *) info->buf;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   361
        io->opaque = NULL;  /* kill this here in case of race. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   362
        allocator.Free(info);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   363
        allocator.Free(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   364
        if (destruct != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   365
            destruct(buf);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   366
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   367
} /* memoryIo_destroy */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   368
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   369
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   370
static const PHYSFS_Io __PHYSFS_memoryIoInterface =
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   371
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   372
    CURRENT_PHYSFS_IO_API_VERSION, NULL,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   373
    memoryIo_read,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   374
    memoryIo_write,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   375
    memoryIo_seek,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   376
    memoryIo_tell,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   377
    memoryIo_length,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   378
    memoryIo_duplicate,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   379
    memoryIo_flush,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   380
    memoryIo_destroy
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   381
};
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   382
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   383
PHYSFS_Io *__PHYSFS_createMemoryIo(const void *buf, PHYSFS_uint64 len,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   384
                                   void (*destruct)(void *))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   385
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   386
    PHYSFS_Io *io = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   387
    MemoryIoInfo *info = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   388
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   389
    io = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   390
    GOTO_IF_MACRO(!io, PHYSFS_ERR_OUT_OF_MEMORY, createMemoryIo_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   391
    info = (MemoryIoInfo *) allocator.Malloc(sizeof (MemoryIoInfo));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   392
    GOTO_IF_MACRO(!info, PHYSFS_ERR_OUT_OF_MEMORY, createMemoryIo_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   393
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   394
    memset(info, '\0', sizeof (*info));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   395
    info->buf = (const PHYSFS_uint8 *) buf;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   396
    info->len = len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   397
    info->pos = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   398
    info->parent = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   399
    info->refcount = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   400
    info->destruct = destruct;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   401
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   402
    memcpy(io, &__PHYSFS_memoryIoInterface, sizeof (*io));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   403
    io->opaque = info;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   404
    return io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   405
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   406
createMemoryIo_failed:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   407
    if (info != NULL) allocator.Free(info);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   408
    if (io != NULL) allocator.Free(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   409
    return NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   410
} /* __PHYSFS_createMemoryIo */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   411
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   412
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   413
/* PHYSFS_Io implementation for i/o to a PHYSFS_File... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   414
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   415
static PHYSFS_sint64 handleIo_read(PHYSFS_Io *io, void *buf, PHYSFS_uint64 len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   416
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   417
    return PHYSFS_readBytes((PHYSFS_File *) io->opaque, buf, len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   418
} /* handleIo_read */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   419
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   420
static PHYSFS_sint64 handleIo_write(PHYSFS_Io *io, const void *buffer,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   421
                                    PHYSFS_uint64 len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   422
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   423
    return PHYSFS_writeBytes((PHYSFS_File *) io->opaque, buffer, len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   424
} /* handleIo_write */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   425
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   426
static int handleIo_seek(PHYSFS_Io *io, PHYSFS_uint64 offset)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   427
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   428
    return PHYSFS_seek((PHYSFS_File *) io->opaque, offset);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   429
} /* handleIo_seek */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   430
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   431
static PHYSFS_sint64 handleIo_tell(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   432
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   433
    return PHYSFS_tell((PHYSFS_File *) io->opaque);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   434
} /* handleIo_tell */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   435
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   436
static PHYSFS_sint64 handleIo_length(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   437
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   438
    return PHYSFS_fileLength((PHYSFS_File *) io->opaque);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   439
} /* handleIo_length */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   440
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   441
static PHYSFS_Io *handleIo_duplicate(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   442
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   443
    /*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   444
     * There's no duplicate at the PHYSFS_File level, so we break the
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   445
     *  abstraction. We're allowed to: we're physfs.c!
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   446
     */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   447
    FileHandle *origfh = (FileHandle *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   448
    FileHandle *newfh = (FileHandle *) allocator.Malloc(sizeof (FileHandle));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   449
    PHYSFS_Io *retval = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   450
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   451
    GOTO_IF_MACRO(!newfh, PHYSFS_ERR_OUT_OF_MEMORY, handleIo_dupe_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   452
    memset(newfh, '\0', sizeof (*newfh));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   453
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   454
    retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   455
    GOTO_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, handleIo_dupe_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   456
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   457
#if 0  /* we don't buffer the duplicate, at least not at the moment. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   458
    if (origfh->buffer != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   459
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   460
        newfh->buffer = (PHYSFS_uint8 *) allocator.Malloc(origfh->bufsize);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   461
        if (!newfh->buffer)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   462
            GOTO_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, handleIo_dupe_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   463
        newfh->bufsize = origfh->bufsize;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   464
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   465
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   466
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   467
    newfh->io = origfh->io->duplicate(origfh->io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   468
    GOTO_IF_MACRO(!newfh->io, ERRPASS, handleIo_dupe_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   469
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   470
    newfh->forReading = origfh->forReading;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   471
    newfh->dirHandle = origfh->dirHandle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   472
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   473
    __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   474
    if (newfh->forReading)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   475
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   476
        newfh->next = openReadList;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   477
        openReadList = newfh;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   478
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   479
    else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   480
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   481
        newfh->next = openWriteList;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   482
        openWriteList = newfh;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   483
    } /* else */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   484
    __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   485
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   486
    memcpy(retval, io, sizeof (PHYSFS_Io));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   487
    retval->opaque = newfh;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   488
    return retval;
10017
de822cd3df3a fixwhitespace and dos2unix
koda
parents: 8524
diff changeset
   489
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   490
handleIo_dupe_failed:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   491
    if (newfh)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   492
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   493
        if (newfh->io != NULL) newfh->io->destroy(newfh->io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   494
        if (newfh->buffer != NULL) allocator.Free(newfh->buffer);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   495
        allocator.Free(newfh);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   496
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   497
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   498
    return NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   499
} /* handleIo_duplicate */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   500
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   501
static int handleIo_flush(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   502
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   503
    return PHYSFS_flush((PHYSFS_File *) io->opaque);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   504
} /* handleIo_flush */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   505
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   506
static void handleIo_destroy(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   507
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   508
    if (io->opaque != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   509
        PHYSFS_close((PHYSFS_File *) io->opaque);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   510
    allocator.Free(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   511
} /* handleIo_destroy */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   512
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   513
static const PHYSFS_Io __PHYSFS_handleIoInterface =
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   514
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   515
    CURRENT_PHYSFS_IO_API_VERSION, NULL,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   516
    handleIo_read,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   517
    handleIo_write,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   518
    handleIo_seek,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   519
    handleIo_tell,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   520
    handleIo_length,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   521
    handleIo_duplicate,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   522
    handleIo_flush,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   523
    handleIo_destroy
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   524
};
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   525
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   526
static PHYSFS_Io *__PHYSFS_createHandleIo(PHYSFS_File *f)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   527
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   528
    PHYSFS_Io *io = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   529
    BAIL_IF_MACRO(!io, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   530
    memcpy(io, &__PHYSFS_handleIoInterface, sizeof (*io));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   531
    io->opaque = f;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   532
    return io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   533
} /* __PHYSFS_createHandleIo */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   534
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   535
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   536
/* functions ... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   537
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   538
typedef struct
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   539
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   540
    char **list;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   541
    PHYSFS_uint32 size;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   542
    PHYSFS_ErrorCode errcode;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   543
} EnumStringListCallbackData;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   544
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   545
static void enumStringListCallback(void *data, const char *str)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   546
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   547
    void *ptr;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   548
    char *newstr;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   549
    EnumStringListCallbackData *pecd = (EnumStringListCallbackData *) data;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   550
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   551
    if (pecd->errcode)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   552
        return;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   553
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   554
    ptr = allocator.Realloc(pecd->list, (pecd->size + 2) * sizeof (char *));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   555
    newstr = (char *) allocator.Malloc(strlen(str) + 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   556
    if (ptr != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   557
        pecd->list = (char **) ptr;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   558
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   559
    if ((ptr == NULL) || (newstr == NULL))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   560
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   561
        pecd->errcode = PHYSFS_ERR_OUT_OF_MEMORY;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   562
        pecd->list[pecd->size] = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   563
        PHYSFS_freeList(pecd->list);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   564
        return;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   565
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   566
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   567
    strcpy(newstr, str);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   568
    pecd->list[pecd->size] = newstr;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   569
    pecd->size++;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   570
} /* enumStringListCallback */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   571
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   572
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   573
static char **doEnumStringList(void (*func)(PHYSFS_StringCallback, void *))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   574
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   575
    EnumStringListCallbackData ecd;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   576
    memset(&ecd, '\0', sizeof (ecd));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   577
    ecd.list = (char **) allocator.Malloc(sizeof (char *));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   578
    BAIL_IF_MACRO(!ecd.list, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   579
    func(enumStringListCallback, &ecd);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   580
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   581
    if (ecd.errcode)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   582
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   583
        __PHYSFS_setError(ecd.errcode);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   584
        return NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   585
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   586
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   587
    ecd.list[ecd.size] = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   588
    return ecd.list;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   589
} /* doEnumStringList */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   590
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   591
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   592
static void __PHYSFS_bubble_sort(void *a, size_t lo, size_t hi,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   593
                                 int (*cmpfn)(void *, size_t, size_t),
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   594
                                 void (*swapfn)(void *, size_t, size_t))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   595
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   596
    size_t i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   597
    int sorted;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   598
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   599
    do
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   600
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   601
        sorted = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   602
        for (i = lo; i < hi; i++)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   603
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   604
            if (cmpfn(a, i, i + 1) > 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   605
            {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   606
                swapfn(a, i, i + 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   607
                sorted = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   608
            } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   609
        } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   610
    } while (!sorted);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   611
} /* __PHYSFS_bubble_sort */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   612
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   613
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   614
static void __PHYSFS_quick_sort(void *a, size_t lo, size_t hi,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   615
                         int (*cmpfn)(void *, size_t, size_t),
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   616
                         void (*swapfn)(void *, size_t, size_t))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   617
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   618
    size_t i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   619
    size_t j;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   620
    size_t v;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   621
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   622
    if ((hi - lo) <= PHYSFS_QUICKSORT_THRESHOLD)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   623
        __PHYSFS_bubble_sort(a, lo, hi, cmpfn, swapfn);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   624
    else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   625
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   626
        i = (hi + lo) / 2;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   627
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   628
        if (cmpfn(a, lo, i) > 0) swapfn(a, lo, i);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   629
        if (cmpfn(a, lo, hi) > 0) swapfn(a, lo, hi);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   630
        if (cmpfn(a, i, hi) > 0) swapfn(a, i, hi);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   631
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   632
        j = hi - 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   633
        swapfn(a, i, j);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   634
        i = lo;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   635
        v = j;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   636
        while (1)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   637
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   638
            while(cmpfn(a, ++i, v) < 0) { /* do nothing */ }
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   639
            while(cmpfn(a, --j, v) > 0) { /* do nothing */ }
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   640
            if (j < i)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   641
                break;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   642
            swapfn(a, i, j);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   643
        } /* while */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   644
        if (i != (hi-1))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   645
            swapfn(a, i, hi-1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   646
        __PHYSFS_quick_sort(a, lo, j, cmpfn, swapfn);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   647
        __PHYSFS_quick_sort(a, i+1, hi, cmpfn, swapfn);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   648
    } /* else */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   649
} /* __PHYSFS_quick_sort */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   650
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   651
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   652
void __PHYSFS_sort(void *entries, size_t max,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   653
                   int (*cmpfn)(void *, size_t, size_t),
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   654
                   void (*swapfn)(void *, size_t, size_t))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   655
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   656
    /*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   657
     * Quicksort w/ Bubblesort fallback algorithm inspired by code from here:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   658
     *   http://www.cs.ubc.ca/spider/harrison/Java/sorting-demo.html
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   659
     */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   660
    if (max > 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   661
        __PHYSFS_quick_sort(entries, 0, max - 1, cmpfn, swapfn);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   662
} /* __PHYSFS_sort */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   663
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   664
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   665
static ErrState *findErrorForCurrentThread(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   666
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   667
    ErrState *i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   668
    void *tid;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   669
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   670
    if (errorLock != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   671
        __PHYSFS_platformGrabMutex(errorLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   672
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   673
    if (errorStates != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   674
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   675
        tid = __PHYSFS_platformGetThreadID();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   676
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   677
        for (i = errorStates; i != NULL; i = i->next)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   678
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   679
            if (i->tid == tid)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   680
            {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   681
                if (errorLock != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   682
                    __PHYSFS_platformReleaseMutex(errorLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   683
                return i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   684
            } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   685
        } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   686
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   687
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   688
    if (errorLock != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   689
        __PHYSFS_platformReleaseMutex(errorLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   690
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   691
    return NULL;   /* no error available. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   692
} /* findErrorForCurrentThread */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   693
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   694
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   695
void __PHYSFS_setError(const PHYSFS_ErrorCode errcode)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   696
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   697
    ErrState *err;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   698
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   699
    if (!errcode)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   700
        return;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   701
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   702
    err = findErrorForCurrentThread();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   703
    if (err == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   704
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   705
        err = (ErrState *) allocator.Malloc(sizeof (ErrState));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   706
        if (err == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   707
            return;   /* uhh...? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   708
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   709
        memset(err, '\0', sizeof (ErrState));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   710
        err->tid = __PHYSFS_platformGetThreadID();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   711
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   712
        if (errorLock != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   713
            __PHYSFS_platformGrabMutex(errorLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   714
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   715
        err->next = errorStates;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   716
        errorStates = err;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   717
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   718
        if (errorLock != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   719
            __PHYSFS_platformReleaseMutex(errorLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   720
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   721
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   722
    err->code = errcode;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   723
} /* __PHYSFS_setError */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   724
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   725
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   726
PHYSFS_ErrorCode PHYSFS_getLastErrorCode(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   727
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   728
    ErrState *err = findErrorForCurrentThread();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   729
    const PHYSFS_ErrorCode retval = (err) ? err->code : PHYSFS_ERR_OK;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   730
    if (err)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   731
        err->code = PHYSFS_ERR_OK;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   732
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   733
} /* PHYSFS_getLastErrorCode */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   734
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   735
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   736
PHYSFS_DECL const char *PHYSFS_getErrorByCode(PHYSFS_ErrorCode code)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   737
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   738
    switch (code)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   739
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   740
        case PHYSFS_ERR_OK: return "no error";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   741
        case PHYSFS_ERR_OTHER_ERROR: return "unknown error";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   742
        case PHYSFS_ERR_OUT_OF_MEMORY: return "out of memory";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   743
        case PHYSFS_ERR_NOT_INITIALIZED: return "not initialized";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   744
        case PHYSFS_ERR_IS_INITIALIZED: return "already initialized";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   745
        case PHYSFS_ERR_ARGV0_IS_NULL: return "argv[0] is NULL";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   746
        case PHYSFS_ERR_UNSUPPORTED: return "unsupported";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   747
        case PHYSFS_ERR_PAST_EOF: return "past end of file";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   748
        case PHYSFS_ERR_FILES_STILL_OPEN: return "files still open";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   749
        case PHYSFS_ERR_INVALID_ARGUMENT: return "invalid argument";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   750
        case PHYSFS_ERR_NOT_MOUNTED: return "not mounted";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   751
        case PHYSFS_ERR_NO_SUCH_PATH: return "no such path";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   752
        case PHYSFS_ERR_SYMLINK_FORBIDDEN: return "symlinks are forbidden";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   753
        case PHYSFS_ERR_NO_WRITE_DIR: return "write directory is not set";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   754
        case PHYSFS_ERR_OPEN_FOR_READING: return "file open for reading";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   755
        case PHYSFS_ERR_OPEN_FOR_WRITING: return "file open for writing";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   756
        case PHYSFS_ERR_NOT_A_FILE: return "not a file";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   757
        case PHYSFS_ERR_READ_ONLY: return "read-only filesystem";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   758
        case PHYSFS_ERR_CORRUPT: return "corrupted";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   759
        case PHYSFS_ERR_SYMLINK_LOOP: return "infinite symbolic link loop";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   760
        case PHYSFS_ERR_IO: return "i/o error";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   761
        case PHYSFS_ERR_PERMISSION: return "permission denied";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   762
        case PHYSFS_ERR_NO_SPACE: return "no space available for writing";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   763
        case PHYSFS_ERR_BAD_FILENAME: return "filename is illegal or insecure";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   764
        case PHYSFS_ERR_BUSY: return "tried to modify a file the OS needs";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   765
        case PHYSFS_ERR_DIR_NOT_EMPTY: return "directory isn't empty";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   766
        case PHYSFS_ERR_OS_ERROR: return "OS reported an error";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   767
    } /* switch */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   769
    return NULL;  /* don't know this error code. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   770
} /* PHYSFS_getErrorByCode */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   771
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   772
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   773
void PHYSFS_setErrorCode(PHYSFS_ErrorCode code)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   774
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   775
    __PHYSFS_setError(code);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   776
} /* PHYSFS_setErrorCode */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   777
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   778
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   779
const char *PHYSFS_getLastError(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   780
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   781
    const PHYSFS_ErrorCode err = PHYSFS_getLastErrorCode();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   782
    return (err) ? PHYSFS_getErrorByCode(err) : NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   783
} /* PHYSFS_getLastError */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   784
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   785
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   786
/* MAKE SURE that errorLock is held before calling this! */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   787
static void freeErrorStates(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   788
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   789
    ErrState *i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   790
    ErrState *next;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   791
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   792
    for (i = errorStates; i != NULL; i = next)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   793
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   794
        next = i->next;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   795
        allocator.Free(i);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   796
    } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   797
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   798
    errorStates = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   799
} /* freeErrorStates */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   800
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   801
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   802
void PHYSFS_getLinkedVersion(PHYSFS_Version *ver)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   803
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   804
    if (ver != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   805
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   806
        ver->major = PHYSFS_VER_MAJOR;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   807
        ver->minor = PHYSFS_VER_MINOR;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   808
        ver->patch = PHYSFS_VER_PATCH;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   809
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   810
} /* PHYSFS_getLinkedVersion */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   811
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   812
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   813
static const char *find_filename_extension(const char *fname)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   814
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   815
    const char *retval = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   816
    if (fname != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   817
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   818
        const char *p = strchr(fname, '.');
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   819
        retval = p;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   820
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   821
        while (p != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   822
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   823
            p = strchr(p + 1, '.');
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   824
            if (p != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   825
                retval = p;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   826
        } /* while */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   827
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   828
        if (retval != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   829
            retval++;  /* skip '.' */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   830
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   831
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   832
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   833
} /* find_filename_extension */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   834
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   835
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   836
static DirHandle *tryOpenDir(PHYSFS_Io *io, const PHYSFS_Archiver *funcs,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   837
                             const char *d, int forWriting)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   838
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   839
    DirHandle *retval = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   840
    void *opaque = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   841
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   842
    if (io != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   843
        BAIL_IF_MACRO(!io->seek(io, 0), ERRPASS, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   844
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   845
    opaque = funcs->openArchive(io, d, forWriting);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   846
    if (opaque != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   847
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   848
        retval = (DirHandle *) allocator.Malloc(sizeof (DirHandle));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   849
        if (retval == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   850
            funcs->closeArchive(opaque);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   851
        else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   852
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   853
            memset(retval, '\0', sizeof (DirHandle));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   854
            retval->mountPoint = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   855
            retval->funcs = funcs;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   856
            retval->opaque = opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   857
        } /* else */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   858
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   859
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   860
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   861
} /* tryOpenDir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   862
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   863
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   864
static DirHandle *openDirectory(PHYSFS_Io *io, const char *d, int forWriting)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   865
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   866
    DirHandle *retval = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   867
    const PHYSFS_Archiver **i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   868
    const char *ext;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   869
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   870
    assert((io != NULL) || (d != NULL));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   871
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   872
    if (io == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   873
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   874
        /* DIR gets first shot (unlike the rest, it doesn't deal with files). */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   875
        retval = tryOpenDir(io, &__PHYSFS_Archiver_DIR, d, forWriting);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   876
        if (retval != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   877
            return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   878
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   879
        io = __PHYSFS_createNativeIo(d, forWriting ? 'w' : 'r');
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   880
        BAIL_IF_MACRO(!io, ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   881
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   882
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   883
    ext = find_filename_extension(d);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   884
    if (ext != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   885
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   886
        /* Look for archivers with matching file extensions first... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   887
        for (i = archivers; (*i != NULL) && (retval == NULL); i++)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   888
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   889
            if (__PHYSFS_stricmpASCII(ext, (*i)->info.extension) == 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   890
                retval = tryOpenDir(io, *i, d, forWriting);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   891
        } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   892
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   893
        /* failing an exact file extension match, try all the others... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   894
        for (i = archivers; (*i != NULL) && (retval == NULL); i++)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   895
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   896
            if (__PHYSFS_stricmpASCII(ext, (*i)->info.extension) != 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   897
                retval = tryOpenDir(io, *i, d, forWriting);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   898
        } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   899
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   900
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   901
    else  /* no extension? Try them all. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   902
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   903
        for (i = archivers; (*i != NULL) && (retval == NULL); i++)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   904
            retval = tryOpenDir(io, *i, d, forWriting);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   905
    } /* else */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   906
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   907
    BAIL_IF_MACRO(!retval, PHYSFS_ERR_UNSUPPORTED, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   908
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   909
} /* openDirectory */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   910
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   911
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   912
/*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   913
 * Make a platform-independent path string sane. Doesn't actually check the
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   914
 *  file hierarchy, it just cleans up the string.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   915
 *  (dst) must be a buffer at least as big as (src), as this is where the
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   916
 *  cleaned up string is deposited.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   917
 * If there are illegal bits in the path (".." entries, etc) then we
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   918
 *  return zero and (dst) is undefined. Non-zero if the path was sanitized.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   919
 */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   920
static int sanitizePlatformIndependentPath(const char *src, char *dst)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   921
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   922
    char *prev;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   923
    char ch;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   924
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   925
    while (*src == '/')  /* skip initial '/' chars... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   926
        src++;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   927
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   928
    prev = dst;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   929
    do
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   930
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   931
        ch = *(src++);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   932
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   933
        if ((ch == ':') || (ch == '\\'))  /* illegal chars in a physfs path. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   934
            BAIL_MACRO(PHYSFS_ERR_BAD_FILENAME, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   935
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   936
        if (ch == '/')   /* path separator. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   937
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   938
            *dst = '\0';  /* "." and ".." are illegal pathnames. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   939
            if ((strcmp(prev, ".") == 0) || (strcmp(prev, "..") == 0))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   940
                BAIL_MACRO(PHYSFS_ERR_BAD_FILENAME, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   941
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   942
            while (*src == '/')   /* chop out doubles... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   943
                src++;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   944
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   945
            if (*src == '\0') /* ends with a pathsep? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   946
                break;  /* we're done, don't add final pathsep to dst. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   947
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   948
            prev = dst + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   949
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   950
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   951
        *(dst++) = ch;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   952
    } while (ch != '\0');
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   953
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   954
    return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   955
} /* sanitizePlatformIndependentPath */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   956
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   957
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   958
/*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   959
 * Figure out if (fname) is part of (h)'s mountpoint. (fname) must be an
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   960
 *  output from sanitizePlatformIndependentPath(), so that it is in a known
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   961
 *  state.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   962
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   963
 * This only finds legitimate segments of a mountpoint. If the mountpoint is
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   964
 *  "/a/b/c" and (fname) is "/a/b/c", "/", or "/a/b/c/d", then the results are
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   965
 *  all zero. "/a/b" will succeed, though.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   966
 */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   967
static int partOfMountPoint(DirHandle *h, char *fname)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   968
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   969
    /* !!! FIXME: This code feels gross. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   970
    int rc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   971
    size_t len, mntpntlen;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   972
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   973
    if (h->mountPoint == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   974
        return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   975
    else if (*fname == '\0')
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   976
        return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   977
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   978
    len = strlen(fname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   979
    mntpntlen = strlen(h->mountPoint);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   980
    if (len > mntpntlen)  /* can't be a subset of mountpoint. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   981
        return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   982
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   983
    /* if true, must be not a match or a complete match, but not a subset. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   984
    if ((len + 1) == mntpntlen)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   985
        return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   986
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   987
    rc = strncmp(fname, h->mountPoint, len); /* !!! FIXME: case insensitive? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   988
    if (rc != 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   989
        return 0;  /* not a match. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   990
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   991
    /* make sure /a/b matches /a/b/ and not /a/bc ... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   992
    return h->mountPoint[len] == '/';
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   993
} /* partOfMountPoint */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   994
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   995
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   996
static DirHandle *createDirHandle(PHYSFS_Io *io, const char *newDir,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   997
                                  const char *mountPoint, int forWriting)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   998
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   999
    DirHandle *dirHandle = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1000
    char *tmpmntpnt = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1001
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1002
    if (mountPoint != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1003
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1004
        const size_t len = strlen(mountPoint) + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1005
        tmpmntpnt = (char *) __PHYSFS_smallAlloc(len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1006
        GOTO_IF_MACRO(!tmpmntpnt, PHYSFS_ERR_OUT_OF_MEMORY, badDirHandle);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1007
        if (!sanitizePlatformIndependentPath(mountPoint, tmpmntpnt))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1008
            goto badDirHandle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1009
        mountPoint = tmpmntpnt;  /* sanitized version. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1010
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1011
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1012
    dirHandle = openDirectory(io, newDir, forWriting);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1013
    GOTO_IF_MACRO(!dirHandle, ERRPASS, badDirHandle);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1014
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1015
    if (newDir == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1016
        dirHandle->dirName = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1017
    else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1018
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1019
        dirHandle->dirName = (char *) allocator.Malloc(strlen(newDir) + 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1020
        if (!dirHandle->dirName)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1021
            GOTO_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, badDirHandle);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1022
        strcpy(dirHandle->dirName, newDir);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1023
    } /* else */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1024
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1025
    if ((mountPoint != NULL) && (*mountPoint != '\0'))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1026
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1027
        dirHandle->mountPoint = (char *)allocator.Malloc(strlen(mountPoint)+2);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1028
        if (!dirHandle->mountPoint)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1029
            GOTO_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, badDirHandle);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1030
        strcpy(dirHandle->mountPoint, mountPoint);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1031
        strcat(dirHandle->mountPoint, "/");
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1032
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1033
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1034
    __PHYSFS_smallFree(tmpmntpnt);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1035
    return dirHandle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1036
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1037
badDirHandle:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1038
    if (dirHandle != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1039
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1040
        dirHandle->funcs->closeArchive(dirHandle->opaque);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1041
        allocator.Free(dirHandle->dirName);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1042
        allocator.Free(dirHandle->mountPoint);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1043
        allocator.Free(dirHandle);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1044
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1045
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1046
    __PHYSFS_smallFree(tmpmntpnt);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1047
    return NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1048
} /* createDirHandle */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1049
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1050
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1051
/* MAKE SURE you've got the stateLock held before calling this! */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1052
static int freeDirHandle(DirHandle *dh, FileHandle *openList)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1053
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1054
    FileHandle *i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1055
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1056
    if (dh == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1057
        return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1058
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1059
    for (i = openList; i != NULL; i = i->next)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1060
        BAIL_IF_MACRO(i->dirHandle == dh, PHYSFS_ERR_FILES_STILL_OPEN, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1061
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1062
    dh->funcs->closeArchive(dh->opaque);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1063
    allocator.Free(dh->dirName);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1064
    allocator.Free(dh->mountPoint);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1065
    allocator.Free(dh);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1066
    return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1067
} /* freeDirHandle */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1068
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1069
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1070
static char *calculateBaseDir(const char *argv0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1071
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1072
    const char dirsep = __PHYSFS_platformDirSeparator;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1073
    char *retval = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1074
    char *ptr = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1075
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1076
    /* Give the platform layer first shot at this. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1077
    retval = __PHYSFS_platformCalcBaseDir(argv0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1078
    if (retval != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1079
        return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1080
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1081
    /* We need argv0 to go on. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1082
    BAIL_IF_MACRO(argv0 == NULL, PHYSFS_ERR_ARGV0_IS_NULL, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1083
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1084
    ptr = strrchr(argv0, dirsep);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1085
    if (ptr != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1086
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1087
        const size_t size = ((size_t) (ptr - argv0)) + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1088
        retval = (char *) allocator.Malloc(size + 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1089
        BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1090
        memcpy(retval, argv0, size);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1091
        retval[size] = '\0';
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1092
        return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1093
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1094
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1095
    /* argv0 wasn't helpful. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1096
    BAIL_MACRO(PHYSFS_ERR_INVALID_ARGUMENT, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1097
} /* calculateBaseDir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1098
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1099
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1100
static int initializeMutexes(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1101
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1102
    errorLock = __PHYSFS_platformCreateMutex();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1103
    if (errorLock == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1104
        goto initializeMutexes_failed;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1105
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1106
    stateLock = __PHYSFS_platformCreateMutex();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1107
    if (stateLock == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1108
        goto initializeMutexes_failed;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1109
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1110
    return 1;  /* success. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1111
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1112
initializeMutexes_failed:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1113
    if (errorLock != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1114
        __PHYSFS_platformDestroyMutex(errorLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1115
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1116
    if (stateLock != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1117
        __PHYSFS_platformDestroyMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1118
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1119
    errorLock = stateLock = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1120
    return 0;  /* failed. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1121
} /* initializeMutexes */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1122
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1123
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1124
static void setDefaultAllocator(void);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1125
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1126
static int initStaticArchivers(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1127
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1128
    const size_t numStaticArchivers = __PHYSFS_ARRAYLEN(staticArchivers);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1129
    const size_t len = numStaticArchivers * sizeof (void *);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1130
    size_t i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1131
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1132
    assert(numStaticArchivers > 0);  /* seriously, none at all?! */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1133
    assert(staticArchivers[numStaticArchivers - 1] == NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1134
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1135
    archiveInfo = (const PHYSFS_ArchiveInfo **) allocator.Malloc(len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1136
    BAIL_IF_MACRO(!archiveInfo, PHYSFS_ERR_OUT_OF_MEMORY, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1137
    archivers = (const PHYSFS_Archiver **) allocator.Malloc(len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1138
    BAIL_IF_MACRO(!archivers, PHYSFS_ERR_OUT_OF_MEMORY, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1139
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1140
    for (i = 0; i < numStaticArchivers - 1; i++)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1141
        archiveInfo[i] = &staticArchivers[i]->info;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1142
    archiveInfo[numStaticArchivers - 1] = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1143
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1144
    memcpy(archivers, staticArchivers, len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1145
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1146
    return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1147
} /* initStaticArchivers */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1148
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1149
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1150
static int doDeinit(void);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1151
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1152
int PHYSFS_init(const char *argv0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1153
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1154
    BAIL_IF_MACRO(initialized, PHYSFS_ERR_IS_INITIALIZED, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1155
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1156
    if (!externalAllocator)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1157
        setDefaultAllocator();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1158
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1159
    if ((allocator.Init != NULL) && (!allocator.Init())) return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1160
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1161
    if (!__PHYSFS_platformInit())
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1162
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1163
        if (allocator.Deinit != NULL) allocator.Deinit();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1164
        return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1165
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1166
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1167
    /* everything below here can be cleaned up safely by doDeinit(). */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1168
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1169
    if (!initializeMutexes()) goto initFailed;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1170
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1171
    baseDir = calculateBaseDir(argv0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1172
    if (!baseDir) goto initFailed;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1173
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1174
    userDir = __PHYSFS_platformCalcUserDir();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1175
    if (!userDir) goto initFailed;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1176
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1177
    /* Platform layer is required to append a dirsep. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1178
    assert(baseDir[strlen(baseDir) - 1] == __PHYSFS_platformDirSeparator);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1179
    assert(userDir[strlen(userDir) - 1] == __PHYSFS_platformDirSeparator);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1180
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1181
    if (!initStaticArchivers()) goto initFailed;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1182
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1183
    initialized = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1184
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1185
    /* This makes sure that the error subsystem is initialized. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1186
    __PHYSFS_setError(PHYSFS_getLastErrorCode());
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1187
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1188
    return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1189
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1190
initFailed:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1191
    doDeinit();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1192
    return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1193
} /* PHYSFS_init */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1194
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1195
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1196
/* MAKE SURE you hold stateLock before calling this! */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1197
static int closeFileHandleList(FileHandle **list)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1198
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1199
    FileHandle *i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1200
    FileHandle *next = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1201
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1202
    for (i = *list; i != NULL; i = next)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1203
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1204
        PHYSFS_Io *io = i->io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1205
        next = i->next;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1206
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1207
        if (!io->flush(io))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1208
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1209
            *list = i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1210
            return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1211
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1212
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1213
        io->destroy(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1214
        allocator.Free(i);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1215
    } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1216
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1217
    *list = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1218
    return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1219
} /* closeFileHandleList */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1220
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1221
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1222
/* MAKE SURE you hold the stateLock before calling this! */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1223
static void freeSearchPath(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1224
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1225
    DirHandle *i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1226
    DirHandle *next = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1227
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1228
    closeFileHandleList(&openReadList);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1229
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1230
    if (searchPath != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1231
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1232
        for (i = searchPath; i != NULL; i = next)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1233
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1234
            next = i->next;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1235
            freeDirHandle(i, openReadList);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1236
        } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1237
        searchPath = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1238
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1239
} /* freeSearchPath */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1240
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1241
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1242
static int doDeinit(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1243
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1244
    BAIL_IF_MACRO(!__PHYSFS_platformDeinit(), ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1245
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1246
    closeFileHandleList(&openWriteList);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1247
    BAIL_IF_MACRO(!PHYSFS_setWriteDir(NULL), PHYSFS_ERR_FILES_STILL_OPEN, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1248
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1249
    freeSearchPath();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1250
    freeErrorStates();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1251
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1252
    if (baseDir != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1253
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1254
        allocator.Free(baseDir);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1255
        baseDir = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1256
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1257
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1258
    if (userDir != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1259
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1260
        allocator.Free(userDir);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1261
        userDir = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1262
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1263
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1264
    if (prefDir != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1265
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1266
        allocator.Free(prefDir);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1267
        prefDir = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1268
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1269
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1270
    if (archiveInfo != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1271
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1272
        allocator.Free(archiveInfo);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1273
        archiveInfo = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1274
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1275
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1276
    if (archivers != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1277
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1278
        allocator.Free(archivers);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1279
        archivers = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1280
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1281
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1282
    allowSymLinks = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1283
    initialized = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1284
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1285
    if (errorLock) __PHYSFS_platformDestroyMutex(errorLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1286
    if (stateLock) __PHYSFS_platformDestroyMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1287
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1288
    if (allocator.Deinit != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1289
        allocator.Deinit();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1290
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1291
    errorLock = stateLock = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1292
    return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1293
} /* doDeinit */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1294
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1295
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1296
int PHYSFS_deinit(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1297
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1298
    BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1299
    return doDeinit();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1300
} /* PHYSFS_deinit */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1301
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1302
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1303
int PHYSFS_isInit(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1304
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1305
    return initialized;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1306
} /* PHYSFS_isInit */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1307
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1308
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1309
const PHYSFS_ArchiveInfo **PHYSFS_supportedArchiveTypes(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1310
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1311
    BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1312
    return archiveInfo;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1313
} /* PHYSFS_supportedArchiveTypes */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1314
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1315
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1316
void PHYSFS_freeList(void *list)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1317
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1318
    void **i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1319
    if (list != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1320
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1321
        for (i = (void **) list; *i != NULL; i++)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1322
            allocator.Free(*i);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1323
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1324
        allocator.Free(list);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1325
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1326
} /* PHYSFS_freeList */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1327
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1328
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1329
const char *PHYSFS_getDirSeparator(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1330
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1331
    static char retval[2] = { __PHYSFS_platformDirSeparator, '\0' };
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1332
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1333
} /* PHYSFS_getDirSeparator */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1334
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1335
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1336
char **PHYSFS_getCdRomDirs(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1337
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1338
    return doEnumStringList(__PHYSFS_platformDetectAvailableCDs);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1339
} /* PHYSFS_getCdRomDirs */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1340
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1341
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1342
void PHYSFS_getCdRomDirsCallback(PHYSFS_StringCallback callback, void *data)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1343
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1344
    __PHYSFS_platformDetectAvailableCDs(callback, data);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1345
} /* PHYSFS_getCdRomDirsCallback */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1346
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1347
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1348
const char *PHYSFS_getPrefDir(const char *org, const char *app)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1349
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1350
    const char dirsep = __PHYSFS_platformDirSeparator;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1351
    PHYSFS_Stat statbuf;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1352
    char *ptr = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1353
    char *endstr = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1354
    int exists = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1355
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1356
    BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1357
    BAIL_IF_MACRO(!org, PHYSFS_ERR_INVALID_ARGUMENT, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1358
    BAIL_IF_MACRO(*org == '\0', PHYSFS_ERR_INVALID_ARGUMENT, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1359
    BAIL_IF_MACRO(!app, PHYSFS_ERR_INVALID_ARGUMENT, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1360
    BAIL_IF_MACRO(*app == '\0', PHYSFS_ERR_INVALID_ARGUMENT, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1361
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1362
    allocator.Free(prefDir);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1363
    prefDir = __PHYSFS_platformCalcPrefDir(org, app);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1364
    BAIL_IF_MACRO(!prefDir, ERRPASS, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1365
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1366
    assert(strlen(prefDir) > 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1367
    endstr = prefDir + (strlen(prefDir) - 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1368
    assert(*endstr == dirsep);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1369
    *endstr = '\0';  /* mask out the final dirsep for now. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1370
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1371
    if (!__PHYSFS_platformStat(prefDir, &exists, &statbuf))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1372
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1373
        for (ptr = strchr(prefDir, dirsep); ptr; ptr = strchr(ptr+1, dirsep))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1374
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1375
            *ptr = '\0';
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1376
            __PHYSFS_platformMkDir(prefDir);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1377
            *ptr = dirsep;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1378
        } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1379
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1380
        if (!__PHYSFS_platformMkDir(prefDir))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1381
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1382
            allocator.Free(prefDir);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1383
            prefDir = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1384
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1385
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1386
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1387
    *endstr = dirsep;  /* readd the final dirsep. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1388
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1389
    return prefDir;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1390
} /* PHYSFS_getPrefDir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1391
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1392
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1393
const char *PHYSFS_getBaseDir(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1394
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1395
    return baseDir;   /* this is calculated in PHYSFS_init()... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1396
} /* PHYSFS_getBaseDir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1397
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1398
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1399
const char *__PHYSFS_getUserDir(void)  /* not deprecated internal version. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1400
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1401
    return userDir;   /* this is calculated in PHYSFS_init()... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1402
} /* __PHYSFS_getUserDir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1403
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1404
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1405
const char *PHYSFS_getUserDir(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1406
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1407
    return __PHYSFS_getUserDir();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1408
} /* PHYSFS_getUserDir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1409
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1410
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1411
const char *PHYSFS_getWriteDir(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1412
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1413
    const char *retval = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1414
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1415
    __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1416
    if (writeDir != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1417
        retval = writeDir->dirName;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1418
    __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1419
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1420
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1421
} /* PHYSFS_getWriteDir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1422
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1423
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1424
int PHYSFS_setWriteDir(const char *newDir)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1425
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1426
    int retval = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1427
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1428
    __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1429
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1430
    if (writeDir != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1431
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1432
        BAIL_IF_MACRO_MUTEX(!freeDirHandle(writeDir, openWriteList), ERRPASS,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1433
                            stateLock, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1434
        writeDir = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1435
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1436
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1437
    if (newDir != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1438
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1439
        /* !!! FIXME: PHYSFS_Io shouldn't be NULL */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1440
        writeDir = createDirHandle(NULL, newDir, NULL, 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1441
        retval = (writeDir != NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1442
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1443
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1444
    __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1445
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1446
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1447
} /* PHYSFS_setWriteDir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1448
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1449
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1450
static int doMount(PHYSFS_Io *io, const char *fname,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1451
                   const char *mountPoint, int appendToPath)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1452
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1453
    DirHandle *dh;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1454
    DirHandle *prev = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1455
    DirHandle *i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1456
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1457
    if (mountPoint == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1458
        mountPoint = "/";
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1459
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1460
    __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1461
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1462
    if (fname != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1463
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1464
        for (i = searchPath; i != NULL; i = i->next)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1465
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1466
            /* already in search path? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1467
            if ((i->dirName != NULL) && (strcmp(fname, i->dirName) == 0))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1468
                BAIL_MACRO_MUTEX(ERRPASS, stateLock, 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1469
            prev = i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1470
        } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1471
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1472
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1473
    dh = createDirHandle(io, fname, mountPoint, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1474
    BAIL_IF_MACRO_MUTEX(!dh, ERRPASS, stateLock, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1475
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1476
    if (appendToPath)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1477
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1478
        if (prev == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1479
            searchPath = dh;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1480
        else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1481
            prev->next = dh;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1482
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1483
    else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1484
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1485
        dh->next = searchPath;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1486
        searchPath = dh;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1487
    } /* else */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1488
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1489
    __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1490
    return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1491
} /* doMount */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1492
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1493
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1494
int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1495
                   const char *mountPoint, int appendToPath)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1496
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1497
    BAIL_IF_MACRO(!io, PHYSFS_ERR_INVALID_ARGUMENT, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1498
    BAIL_IF_MACRO(io->version != 0, PHYSFS_ERR_UNSUPPORTED, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1499
    return doMount(io, fname, mountPoint, appendToPath);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1500
} /* PHYSFS_mountIo */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1501
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1502
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1503
int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len, void (*del)(void *),
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1504
                       const char *fname, const char *mountPoint,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1505
                       int appendToPath)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1506
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1507
    int retval = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1508
    PHYSFS_Io *io = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1509
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1510
    BAIL_IF_MACRO(!buf, PHYSFS_ERR_INVALID_ARGUMENT, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1511
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1512
    io = __PHYSFS_createMemoryIo(buf, len, del);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1513
    BAIL_IF_MACRO(!io, ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1514
    retval = doMount(io, fname, mountPoint, appendToPath);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1515
    if (!retval)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1516
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1517
        /* docs say not to call (del) in case of failure, so cheat. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1518
        MemoryIoInfo *info = (MemoryIoInfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1519
        info->destruct = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1520
        io->destroy(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1521
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1522
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1523
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1524
} /* PHYSFS_mountMemory */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1525
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1526
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1527
int PHYSFS_mountHandle(PHYSFS_File *file, const char *fname,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1528
                       const char *mountPoint, int appendToPath)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1529
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1530
    int retval = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1531
    PHYSFS_Io *io = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1532
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1533
    BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_INVALID_ARGUMENT, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1534
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1535
    io = __PHYSFS_createHandleIo(file);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1536
    BAIL_IF_MACRO(!io, ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1537
    retval = doMount(io, fname, mountPoint, appendToPath);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1538
    if (!retval)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1539
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1540
        /* docs say not to destruct in case of failure, so cheat. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1541
        io->opaque = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1542
        io->destroy(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1543
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1544
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1545
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1546
} /* PHYSFS_mountHandle */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1547
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1548
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1549
int PHYSFS_mount(const char *newDir, const char *mountPoint, int appendToPath)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1550
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1551
    BAIL_IF_MACRO(!newDir, PHYSFS_ERR_INVALID_ARGUMENT, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1552
    return doMount(NULL, newDir, mountPoint, appendToPath);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1553
} /* PHYSFS_mount */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1554
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1555
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1556
int PHYSFS_addToSearchPath(const char *newDir, int appendToPath)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1557
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1558
    return doMount(NULL, newDir, NULL, appendToPath);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1559
} /* PHYSFS_addToSearchPath */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1560
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1561
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1562
int PHYSFS_removeFromSearchPath(const char *oldDir)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1563
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1564
    return PHYSFS_unmount(oldDir);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1565
} /* PHYSFS_removeFromSearchPath */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1566
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1567
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1568
int PHYSFS_unmount(const char *oldDir)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1569
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1570
    DirHandle *i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1571
    DirHandle *prev = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1572
    DirHandle *next = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1573
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1574
    BAIL_IF_MACRO(oldDir == NULL, PHYSFS_ERR_INVALID_ARGUMENT, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1575
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1576
    __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1577
    for (i = searchPath; i != NULL; i = i->next)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1578
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1579
        if (strcmp(i->dirName, oldDir) == 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1580
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1581
            next = i->next;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1582
            BAIL_IF_MACRO_MUTEX(!freeDirHandle(i, openReadList), ERRPASS,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1583
                                stateLock, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1584
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1585
            if (prev == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1586
                searchPath = next;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1587
            else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1588
                prev->next = next;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1589
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1590
            BAIL_MACRO_MUTEX(ERRPASS, stateLock, 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1591
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1592
        prev = i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1593
    } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1594
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1595
    BAIL_MACRO_MUTEX(PHYSFS_ERR_NOT_MOUNTED, stateLock, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1596
} /* PHYSFS_unmount */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1597
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1598
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1599
char **PHYSFS_getSearchPath(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1600
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1601
    return doEnumStringList(PHYSFS_getSearchPathCallback);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1602
} /* PHYSFS_getSearchPath */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1603
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1604
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1605
const char *PHYSFS_getMountPoint(const char *dir)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1606
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1607
    DirHandle *i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1608
    __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1609
    for (i = searchPath; i != NULL; i = i->next)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1610
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1611
        if (strcmp(i->dirName, dir) == 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1612
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1613
            const char *retval = ((i->mountPoint) ? i->mountPoint : "/");
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1614
            __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1615
            return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1616
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1617
    } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1618
    __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1619
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1620
    BAIL_MACRO(PHYSFS_ERR_NOT_MOUNTED, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1621
} /* PHYSFS_getMountPoint */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1622
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1623
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1624
void PHYSFS_getSearchPathCallback(PHYSFS_StringCallback callback, void *data)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1625
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1626
    DirHandle *i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1627
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1628
    __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1629
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1630
    for (i = searchPath; i != NULL; i = i->next)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1631
        callback(data, i->dirName);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1632
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1633
    __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1634
} /* PHYSFS_getSearchPathCallback */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1635
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1636
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1637
/* Split out to avoid stack allocation in a loop. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1638
static void setSaneCfgAddPath(const char *i, const size_t l, const char *dirsep,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1639
                              int archivesFirst)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1640
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1641
    const char *d = PHYSFS_getRealDir(i);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1642
    const size_t allocsize = strlen(d) + strlen(dirsep) + l + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1643
    char *str = (char *) __PHYSFS_smallAlloc(allocsize);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1644
    if (str != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1645
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1646
        sprintf(str, "%s%s%s", d, dirsep, i);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1647
        PHYSFS_mount(str, NULL, archivesFirst == 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1648
        __PHYSFS_smallFree(str);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1649
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1650
} /* setSaneCfgAddPath */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1651
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1652
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1653
int PHYSFS_setSaneConfig(const char *organization, const char *appName,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1654
                         const char *archiveExt, int includeCdRoms,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1655
                         int archivesFirst)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1656
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1657
    const char *dirsep = PHYSFS_getDirSeparator();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1658
    const char *basedir;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1659
    const char *prefdir;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1660
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1661
    BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1662
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1663
    prefdir = PHYSFS_getPrefDir(organization, appName);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1664
    BAIL_IF_MACRO(!prefdir, ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1665
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1666
    basedir = PHYSFS_getBaseDir();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1667
    BAIL_IF_MACRO(!basedir, ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1668
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1669
    BAIL_IF_MACRO(!PHYSFS_setWriteDir(prefdir), PHYSFS_ERR_NO_WRITE_DIR, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1670
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1671
    /* Put write dir first in search path... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1672
    PHYSFS_mount(prefdir, NULL, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1673
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1674
    /* Put base path on search path... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1675
    PHYSFS_mount(basedir, NULL, 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1676
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1677
    /* handle CD-ROMs... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1678
    if (includeCdRoms)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1679
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1680
        char **cds = PHYSFS_getCdRomDirs();
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1681
        char **i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1682
        for (i = cds; *i != NULL; i++)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1683
            PHYSFS_mount(*i, NULL, 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1684
        PHYSFS_freeList(cds);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1685
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1686
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1687
    /* Root out archives, and add them to search path... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1688
    if (archiveExt != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1689
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1690
        char **rc = PHYSFS_enumerateFiles("/");
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1691
        char **i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1692
        size_t extlen = strlen(archiveExt);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1693
        char *ext;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1694
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1695
        for (i = rc; *i != NULL; i++)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1696
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1697
            size_t l = strlen(*i);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1698
            if ((l > extlen) && ((*i)[l - extlen - 1] == '.'))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1699
            {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1700
                ext = (*i) + (l - extlen);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1701
                if (__PHYSFS_stricmpASCII(ext, archiveExt) == 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1702
                    setSaneCfgAddPath(*i, l, dirsep, archivesFirst);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1703
            } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1704
        } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1705
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1706
        PHYSFS_freeList(rc);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1707
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1708
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1709
    return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1710
} /* PHYSFS_setSaneConfig */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1711
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1712
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1713
void PHYSFS_permitSymbolicLinks(int allow)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1714
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1715
    allowSymLinks = allow;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1716
} /* PHYSFS_permitSymbolicLinks */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1717
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1718
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1719
int PHYSFS_symbolicLinksPermitted(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1720
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1721
    return allowSymLinks;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1722
} /* PHYSFS_symbolicLinksPermitted */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1723
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1724
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1725
/*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1726
 * Verify that (fname) (in platform-independent notation), in relation
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1727
 *  to (h) is secure. That means that each element of fname is checked
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1728
 *  for symlinks (if they aren't permitted). This also allows for quick
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1729
 *  rejection of files that exist outside an archive's mountpoint.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1730
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1731
 * With some exceptions (like PHYSFS_mkdir(), which builds multiple subdirs
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1732
 *  at a time), you should always pass zero for "allowMissing" for efficiency.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1733
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1734
 * (fname) must point to an output from sanitizePlatformIndependentPath(),
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1735
 *  since it will make sure that path names are in the right format for
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1736
 *  passing certain checks. It will also do checks for "insecure" pathnames
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1737
 *  like ".." which should be done once instead of once per archive. This also
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1738
 *  gives us license to treat (fname) as scratch space in this function.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1739
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1740
 * Returns non-zero if string is safe, zero if there's a security issue.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1741
 *  PHYSFS_getLastError() will specify what was wrong. (*fname) will be
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1742
 *  updated to point past any mount point elements so it is prepared to
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1743
 *  be used with the archiver directly.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1744
 */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1745
static int verifyPath(DirHandle *h, char **_fname, int allowMissing)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1746
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1747
    char *fname = *_fname;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1748
    int retval = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1749
    char *start;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1750
    char *end;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1751
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1752
    if (*fname == '\0')  /* quick rejection. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1753
        return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1754
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1755
    /* !!! FIXME: This codeblock sucks. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1756
    if (h->mountPoint != NULL)  /* NULL mountpoint means "/". */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1757
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1758
        size_t mntpntlen = strlen(h->mountPoint);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1759
        size_t len = strlen(fname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1760
        assert(mntpntlen > 1); /* root mount points should be NULL. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1761
        /* not under the mountpoint, so skip this archive. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1762
        BAIL_IF_MACRO(len < mntpntlen-1, PHYSFS_ERR_NO_SUCH_PATH, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1763
        /* !!! FIXME: Case insensitive? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1764
        retval = strncmp(h->mountPoint, fname, mntpntlen-1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1765
        BAIL_IF_MACRO(retval != 0, PHYSFS_ERR_NO_SUCH_PATH, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1766
        if (len > mntpntlen-1)  /* corner case... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1767
            BAIL_IF_MACRO(fname[mntpntlen-1]!='/', PHYSFS_ERR_NO_SUCH_PATH, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1768
        fname += mntpntlen-1;  /* move to start of actual archive path. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1769
        if (*fname == '/')
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1770
            fname++;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1771
        *_fname = fname;  /* skip mountpoint for later use. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1772
        retval = 1;  /* may be reset, below. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1773
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1774
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1775
    start = fname;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1776
    if (!allowSymLinks)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1777
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1778
        while (1)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1779
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1780
            PHYSFS_Stat statbuf;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1781
            int rc = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1782
            end = strchr(start, '/');
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1783
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1784
            if (end != NULL) *end = '\0';
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1785
            rc = h->funcs->stat(h->opaque, fname, &retval, &statbuf);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1786
            if (rc)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1787
                rc = (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1788
            if (end != NULL) *end = '/';
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1789
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1790
            /* insecure path (has a disallowed symlink in it)? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1791
            BAIL_IF_MACRO(rc, PHYSFS_ERR_SYMLINK_FORBIDDEN, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1792
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1793
            /* break out early if path element is missing. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1794
            if (!retval)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1795
            {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1796
                /*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1797
                 * We need to clear it if it's the last element of the path,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1798
                 *  since this might be a non-existant file we're opening
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1799
                 *  for writing...
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1800
                 */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1801
                if ((end == NULL) || (allowMissing))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1802
                    retval = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1803
                break;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1804
            } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1805
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1806
            if (end == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1807
                break;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1808
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1809
            start = end + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1810
        } /* while */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1811
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1812
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1813
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1814
} /* verifyPath */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1815
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1816
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1817
static int doMkdir(const char *_dname, char *dname)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1818
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1819
    DirHandle *h;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1820
    char *start;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1821
    char *end;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1822
    int retval = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1823
    int exists = 1;  /* force existance check on first path element. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1824
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1825
    BAIL_IF_MACRO(!sanitizePlatformIndependentPath(_dname, dname), ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1826
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1827
    __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1828
    BAIL_IF_MACRO_MUTEX(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, stateLock, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1829
    h = writeDir;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1830
    BAIL_IF_MACRO_MUTEX(!verifyPath(h, &dname, 1), ERRPASS, stateLock, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1831
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1832
    start = dname;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1833
    while (1)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1834
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1835
        end = strchr(start, '/');
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1836
        if (end != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1837
            *end = '\0';
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1838
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1839
        /* only check for existance if all parent dirs existed, too... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1840
        if (exists)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1841
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1842
            PHYSFS_Stat statbuf;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1843
            const int rc = h->funcs->stat(h->opaque, dname, &exists, &statbuf);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1844
            retval = ((rc) && (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1845
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1846
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1847
        if (!exists)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1848
            retval = h->funcs->mkdir(h->opaque, dname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1849
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1850
        if (!retval)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1851
            break;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1852
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1853
        if (end == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1854
            break;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1855
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1856
        *end = '/';
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1857
        start = end + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1858
    } /* while */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1859
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1860
    __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1861
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1862
} /* doMkdir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1863
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1864
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1865
int PHYSFS_mkdir(const char *_dname)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1866
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1867
    int retval = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1868
    char *dname;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1869
    size_t len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1870
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1871
    BAIL_IF_MACRO(!_dname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1872
    len = strlen(_dname) + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1873
    dname = (char *) __PHYSFS_smallAlloc(len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1874
    BAIL_IF_MACRO(!dname, PHYSFS_ERR_OUT_OF_MEMORY, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1875
    retval = doMkdir(_dname, dname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1876
    __PHYSFS_smallFree(dname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1877
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1878
} /* PHYSFS_mkdir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1879
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1880
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1881
static int doDelete(const char *_fname, char *fname)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1882
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1883
    int retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1884
    DirHandle *h;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1885
    BAIL_IF_MACRO(!sanitizePlatformIndependentPath(_fname, fname), ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1886
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1887
    __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1888
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1889
    BAIL_IF_MACRO_MUTEX(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, stateLock, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1890
    h = writeDir;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1891
    BAIL_IF_MACRO_MUTEX(!verifyPath(h, &fname, 0), ERRPASS, stateLock, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1892
    retval = h->funcs->remove(h->opaque, fname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1893
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1894
    __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1895
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1896
} /* doDelete */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1897
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1898
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1899
int PHYSFS_delete(const char *_fname)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1900
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1901
    int retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1902
    char *fname;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1903
    size_t len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1904
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1905
    BAIL_IF_MACRO(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1906
    len = strlen(_fname) + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1907
    fname = (char *) __PHYSFS_smallAlloc(len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1908
    BAIL_IF_MACRO(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1909
    retval = doDelete(_fname, fname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1910
    __PHYSFS_smallFree(fname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1911
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1912
} /* PHYSFS_delete */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1913
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1914
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1915
const char *PHYSFS_getRealDir(const char *_fname)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1916
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1917
    const char *retval = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1918
    char *fname = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1919
    size_t len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1920
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1921
    BAIL_IF_MACRO(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1922
    len = strlen(_fname) + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1923
    fname = __PHYSFS_smallAlloc(len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1924
    BAIL_IF_MACRO(!fname, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1925
    if (sanitizePlatformIndependentPath(_fname, fname))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1926
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1927
        DirHandle *i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1928
        __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1929
        for (i = searchPath; i != NULL; i = i->next)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1930
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1931
            char *arcfname = fname;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1932
            if (partOfMountPoint(i, arcfname))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1933
            {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1934
                retval = i->dirName;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1935
                break;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1936
            } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1937
            else if (verifyPath(i, &arcfname, 0))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1938
            {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1939
                PHYSFS_Stat statbuf;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1940
                int exists = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1941
                if (i->funcs->stat(i->opaque, arcfname, &exists, &statbuf))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1942
                {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1943
                    if (exists)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1944
                        retval = i->dirName;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1945
                    break;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1946
                } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1947
            } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1948
        } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1949
        __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1950
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1951
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1952
    __PHYSFS_smallFree(fname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1953
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1954
} /* PHYSFS_getRealDir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1955
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1956
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1957
static int locateInStringList(const char *str,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1958
                              char **list,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1959
                              PHYSFS_uint32 *pos)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1960
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1961
    PHYSFS_uint32 len = *pos;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1962
    PHYSFS_uint32 half_len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1963
    PHYSFS_uint32 lo = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1964
    PHYSFS_uint32 middle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1965
    int cmp;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1966
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1967
    while (len > 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1968
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1969
        half_len = len >> 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1970
        middle = lo + half_len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1971
        cmp = strcmp(list[middle], str);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1972
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1973
        if (cmp == 0)  /* it's in the list already. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1974
            return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1975
        else if (cmp > 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1976
            len = half_len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1977
        else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1978
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1979
            lo = middle + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1980
            len -= half_len + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1981
        } /* else */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1982
    } /* while */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1983
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1984
    *pos = lo;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1985
    return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1986
} /* locateInStringList */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1987
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1988
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1989
static void enumFilesCallback(void *data, const char *origdir, const char *str)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1990
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1991
    PHYSFS_uint32 pos;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1992
    void *ptr;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1993
    char *newstr;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1994
    EnumStringListCallbackData *pecd = (EnumStringListCallbackData *) data;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1995
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1996
    /*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1997
     * See if file is in the list already, and if not, insert it in there
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1998
     *  alphabetically...
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  1999
     */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2000
    pos = pecd->size;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2001
    if (locateInStringList(str, pecd->list, &pos))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2002
        return;  /* already in the list. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2003
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2004
    ptr = allocator.Realloc(pecd->list, (pecd->size + 2) * sizeof (char *));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2005
    newstr = (char *) allocator.Malloc(strlen(str) + 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2006
    if (ptr != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2007
        pecd->list = (char **) ptr;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2008
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2009
    if ((ptr == NULL) || (newstr == NULL))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2010
        return;  /* better luck next time. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2011
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2012
    strcpy(newstr, str);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2013
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2014
    if (pos != pecd->size)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2015
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2016
        memmove(&pecd->list[pos+1], &pecd->list[pos],
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2017
                 sizeof (char *) * ((pecd->size) - pos));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2018
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2019
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2020
    pecd->list[pos] = newstr;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2021
    pecd->size++;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2022
} /* enumFilesCallback */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2023
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2024
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2025
char **PHYSFS_enumerateFiles(const char *path)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2026
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2027
    EnumStringListCallbackData ecd;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2028
    memset(&ecd, '\0', sizeof (ecd));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2029
    ecd.list = (char **) allocator.Malloc(sizeof (char *));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2030
    BAIL_IF_MACRO(!ecd.list, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2031
    PHYSFS_enumerateFilesCallback(path, enumFilesCallback, &ecd);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2032
    ecd.list[ecd.size] = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2033
    return ecd.list;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2034
} /* PHYSFS_enumerateFiles */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2035
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2036
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2037
/*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2038
 * Broke out to seperate function so we can use stack allocation gratuitously.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2039
 */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2040
static void enumerateFromMountPoint(DirHandle *i, const char *arcfname,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2041
                                    PHYSFS_EnumFilesCallback callback,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2042
                                    const char *_fname, void *data)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2043
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2044
    const size_t len = strlen(arcfname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2045
    char *ptr = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2046
    char *end = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2047
    const size_t slen = strlen(i->mountPoint) + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2048
    char *mountPoint = (char *) __PHYSFS_smallAlloc(slen);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2049
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2050
    if (mountPoint == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2051
        return;  /* oh well. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2052
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2053
    strcpy(mountPoint, i->mountPoint);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2054
    ptr = mountPoint + ((len) ? len + 1 : 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2055
    end = strchr(ptr, '/');
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2056
    assert(end);  /* should always find a terminating '/'. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2057
    *end = '\0';
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2058
    callback(data, _fname, ptr);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2059
    __PHYSFS_smallFree(mountPoint);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2060
} /* enumerateFromMountPoint */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2061
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2062
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2063
/* !!! FIXME: this should report error conditions. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2064
void PHYSFS_enumerateFilesCallback(const char *_fname,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2065
                                   PHYSFS_EnumFilesCallback callback,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2066
                                   void *data)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2067
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2068
    size_t len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2069
    char *fname;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2070
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2071
    BAIL_IF_MACRO(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, ) /*0*/;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2072
    BAIL_IF_MACRO(!callback, PHYSFS_ERR_INVALID_ARGUMENT, ) /*0*/;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2073
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2074
    len = strlen(_fname) + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2075
    fname = (char *) __PHYSFS_smallAlloc(len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2076
    BAIL_IF_MACRO(!fname, PHYSFS_ERR_OUT_OF_MEMORY, ) /*0*/;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2077
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2078
    if (sanitizePlatformIndependentPath(_fname, fname))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2079
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2080
        DirHandle *i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2081
        int noSyms;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2082
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2083
        __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2084
        noSyms = !allowSymLinks;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2085
        for (i = searchPath; i != NULL; i = i->next)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2086
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2087
            char *arcfname = fname;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2088
            if (partOfMountPoint(i, arcfname))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2089
                enumerateFromMountPoint(i, arcfname, callback, _fname, data);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2090
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2091
            else if (verifyPath(i, &arcfname, 0))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2092
            {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2093
                i->funcs->enumerateFiles(i->opaque, arcfname, noSyms,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2094
                                         callback, _fname, data);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2095
            } /* else if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2096
        } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2097
        __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2098
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2099
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2100
    __PHYSFS_smallFree(fname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2101
} /* PHYSFS_enumerateFilesCallback */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2102
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2103
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2104
int PHYSFS_exists(const char *fname)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2105
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2106
    return (PHYSFS_getRealDir(fname) != NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2107
} /* PHYSFS_exists */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2108
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2109
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2110
PHYSFS_sint64 PHYSFS_getLastModTime(const char *fname)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2111
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2112
    PHYSFS_Stat statbuf;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2113
    BAIL_IF_MACRO(!PHYSFS_stat(fname, &statbuf), ERRPASS, -1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2114
    return statbuf.modtime;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2115
} /* PHYSFS_getLastModTime */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2116
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2117
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2118
int PHYSFS_isDirectory(const char *fname)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2119
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2120
    PHYSFS_Stat statbuf;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2121
    BAIL_IF_MACRO(!PHYSFS_stat(fname, &statbuf), ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2122
    return (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2123
} /* PHYSFS_isDirectory */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2124
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2125
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2126
int PHYSFS_isSymbolicLink(const char *fname)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2127
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2128
    PHYSFS_Stat statbuf;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2129
    BAIL_IF_MACRO(!PHYSFS_stat(fname, &statbuf), ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2130
    return (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2131
} /* PHYSFS_isSymbolicLink */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2132
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2133
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2134
static PHYSFS_File *doOpenWrite(const char *_fname, int appending)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2135
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2136
    FileHandle *fh = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2137
    size_t len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2138
    char *fname;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2139
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2140
    BAIL_IF_MACRO(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2141
    len = strlen(_fname) + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2142
    fname = (char *) __PHYSFS_smallAlloc(len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2143
    BAIL_IF_MACRO(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2144
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2145
    if (sanitizePlatformIndependentPath(_fname, fname))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2146
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2147
        PHYSFS_Io *io = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2148
        DirHandle *h = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2149
        const PHYSFS_Archiver *f;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2150
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2151
        __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2152
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2153
        GOTO_IF_MACRO(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, doOpenWriteEnd);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2154
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2155
        h = writeDir;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2156
        GOTO_IF_MACRO(!verifyPath(h, &fname, 0), ERRPASS, doOpenWriteEnd);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2157
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2158
        f = h->funcs;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2159
        if (appending)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2160
            io = f->openAppend(h->opaque, fname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2161
        else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2162
            io = f->openWrite(h->opaque, fname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2163
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2164
        GOTO_IF_MACRO(!io, ERRPASS, doOpenWriteEnd);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2165
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2166
        fh = (FileHandle *) allocator.Malloc(sizeof (FileHandle));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2167
        if (fh == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2168
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2169
            io->destroy(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2170
            GOTO_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, doOpenWriteEnd);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2171
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2172
        else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2173
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2174
            memset(fh, '\0', sizeof (FileHandle));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2175
            fh->io = io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2176
            fh->dirHandle = h;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2177
            fh->next = openWriteList;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2178
            openWriteList = fh;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2179
        } /* else */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2180
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2181
        doOpenWriteEnd:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2182
        __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2183
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2184
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2185
    __PHYSFS_smallFree(fname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2186
    return ((PHYSFS_File *) fh);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2187
} /* doOpenWrite */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2188
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2189
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2190
PHYSFS_File *PHYSFS_openWrite(const char *filename)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2191
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2192
    return doOpenWrite(filename, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2193
} /* PHYSFS_openWrite */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2194
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2195
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2196
PHYSFS_File *PHYSFS_openAppend(const char *filename)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2197
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2198
    return doOpenWrite(filename, 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2199
} /* PHYSFS_openAppend */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2200
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2201
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2202
PHYSFS_File *PHYSFS_openRead(const char *_fname)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2203
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2204
    FileHandle *fh = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2205
    char *fname;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2206
    size_t len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2207
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2208
    BAIL_IF_MACRO(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2209
    len = strlen(_fname) + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2210
    fname = (char *) __PHYSFS_smallAlloc(len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2211
    BAIL_IF_MACRO(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2212
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2213
    if (sanitizePlatformIndependentPath(_fname, fname))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2214
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2215
        int fileExists = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2216
        DirHandle *i = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2217
        PHYSFS_Io *io = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2218
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2219
        __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2220
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2221
        GOTO_IF_MACRO(!searchPath, PHYSFS_ERR_NO_SUCH_PATH, openReadEnd);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2222
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2223
        for (i = searchPath; (i != NULL) && (!fileExists); i = i->next)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2224
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2225
            char *arcfname = fname;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2226
            if (verifyPath(i, &arcfname, 0))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2227
            {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2228
                io = i->funcs->openRead(i->opaque, arcfname, &fileExists);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2229
                if (io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2230
                    break;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2231
            } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2232
        } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2233
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2234
        GOTO_IF_MACRO(!io, ERRPASS, openReadEnd);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2235
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2236
        fh = (FileHandle *) allocator.Malloc(sizeof (FileHandle));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2237
        if (fh == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2238
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2239
            io->destroy(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2240
            GOTO_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, openReadEnd);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2241
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2242
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2243
        memset(fh, '\0', sizeof (FileHandle));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2244
        fh->io = io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2245
        fh->forReading = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2246
        fh->dirHandle = i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2247
        fh->next = openReadList;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2248
        openReadList = fh;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2249
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2250
        openReadEnd:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2251
        __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2252
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2253
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2254
    __PHYSFS_smallFree(fname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2255
    return ((PHYSFS_File *) fh);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2256
} /* PHYSFS_openRead */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2257
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2258
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2259
static int closeHandleInOpenList(FileHandle **list, FileHandle *handle)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2260
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2261
    FileHandle *prev = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2262
    FileHandle *i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2263
    int rc = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2264
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2265
    for (i = *list; i != NULL; i = i->next)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2266
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2267
        if (i == handle)  /* handle is in this list? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2268
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2269
            PHYSFS_Io *io = handle->io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2270
            PHYSFS_uint8 *tmp = handle->buffer;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2271
            rc = PHYSFS_flush((PHYSFS_File *) handle);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2272
            if (!rc)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2273
                return -1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2274
            io->destroy(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2275
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2276
            if (tmp != NULL)  /* free any associated buffer. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2277
                allocator.Free(tmp);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2278
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2279
            if (prev == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2280
                *list = handle->next;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2281
            else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2282
                prev->next = handle->next;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2283
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2284
            allocator.Free(handle);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2285
            return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2286
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2287
        prev = i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2288
    } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2289
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2290
    return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2291
} /* closeHandleInOpenList */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2292
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2293
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2294
int PHYSFS_close(PHYSFS_File *_handle)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2295
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2296
    FileHandle *handle = (FileHandle *) _handle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2297
    int rc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2298
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2299
    __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2300
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2301
    /* -1 == close failure. 0 == not found. 1 == success. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2302
    rc = closeHandleInOpenList(&openReadList, handle);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2303
    BAIL_IF_MACRO_MUTEX(rc == -1, ERRPASS, stateLock, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2304
    if (!rc)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2305
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2306
        rc = closeHandleInOpenList(&openWriteList, handle);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2307
        BAIL_IF_MACRO_MUTEX(rc == -1, ERRPASS, stateLock, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2308
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2309
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2310
    __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2311
    BAIL_IF_MACRO(!rc, PHYSFS_ERR_INVALID_ARGUMENT, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2312
    return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2313
} /* PHYSFS_close */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2314
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2315
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2316
static PHYSFS_sint64 doBufferedRead(FileHandle *fh, void *buffer,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2317
                                    PHYSFS_uint64 len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2318
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2319
    PHYSFS_Io *io = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2320
    PHYSFS_sint64 retval = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2321
    PHYSFS_uint32 buffered = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2322
    PHYSFS_sint64 rc = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2323
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2324
    if (len == 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2325
        return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2326
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2327
    buffered = fh->buffill - fh->bufpos;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2328
    if (buffered >= len)  /* totally in the buffer, just copy and return! */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2329
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2330
        memcpy(buffer, fh->buffer + fh->bufpos, (size_t) len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2331
        fh->bufpos += (PHYSFS_uint32) len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2332
        return (PHYSFS_sint64) len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2333
    } /* else if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2334
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2335
    if (buffered > 0) /* partially in the buffer... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2336
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2337
        memcpy(buffer, fh->buffer + fh->bufpos, (size_t) buffered);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2338
        buffer = ((PHYSFS_uint8 *) buffer) + buffered;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2339
        len -= buffered;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2340
        retval = buffered;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2341
        fh->buffill = fh->bufpos = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2342
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2343
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2344
    /* if you got here, the buffer is drained and we still need bytes. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2345
    assert(len > 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2346
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2347
    io = fh->io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2348
    if (len >= fh->bufsize)  /* need more than the buffer takes. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2349
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2350
        /* leave buffer empty, go right to output instead. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2351
        rc = io->read(io, buffer, len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2352
        if (rc < 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2353
            return ((retval == 0) ? rc : retval);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2354
        return retval + rc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2355
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2356
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2357
    /* need less than buffer can take. Fill buffer. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2358
    rc = io->read(io, fh->buffer, fh->bufsize);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2359
    if (rc < 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2360
        return ((retval == 0) ? rc : retval);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2361
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2362
    assert(fh->bufpos == 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2363
    fh->buffill = (PHYSFS_uint32) rc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2364
    rc = doBufferedRead(fh, buffer, len);  /* go from the start, again. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2365
    if (rc < 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2366
        return ((retval == 0) ? rc : retval);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2367
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2368
    return retval + rc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2369
} /* doBufferedRead */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2370
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2371
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2372
PHYSFS_sint64 PHYSFS_read(PHYSFS_File *handle, void *buffer,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2373
                          PHYSFS_uint32 size, PHYSFS_uint32 count)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2374
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2375
    const PHYSFS_uint64 len = ((PHYSFS_uint64) size) * ((PHYSFS_uint64) count);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2376
    const PHYSFS_sint64 retval = PHYSFS_readBytes(handle, buffer, len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2377
    return ( (retval <= 0) ? retval : (retval / ((PHYSFS_sint64) size)) );
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2378
} /* PHYSFS_read */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2379
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2380
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2381
PHYSFS_sint64 PHYSFS_readBytes(PHYSFS_File *handle, void *buffer,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2382
                               PHYSFS_uint64 len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2383
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2384
    FileHandle *fh = (FileHandle *) handle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2385
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2386
#ifdef PHYSFS_NO_64BIT_SUPPORT
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2387
    const PHYSFS_uint64 maxlen = __PHYSFS_UI64(0x7FFFFFFF);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2388
#else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2389
    const PHYSFS_uint64 maxlen = __PHYSFS_UI64(0x7FFFFFFFFFFFFFFF);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2390
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2391
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2392
    if (!__PHYSFS_ui64FitsAddressSpace(len))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2393
        BAIL_MACRO(PHYSFS_ERR_INVALID_ARGUMENT, -1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2394
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2395
    BAIL_IF_MACRO(len > maxlen, PHYSFS_ERR_INVALID_ARGUMENT, -1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2396
    BAIL_IF_MACRO(!fh->forReading, PHYSFS_ERR_OPEN_FOR_WRITING, -1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2397
    BAIL_IF_MACRO(len == 0, ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2398
    if (fh->buffer)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2399
        return doBufferedRead(fh, buffer, len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2400
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2401
    return fh->io->read(fh->io, buffer, len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2402
} /* PHYSFS_readBytes */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2403
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2404
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2405
static PHYSFS_sint64 doBufferedWrite(PHYSFS_File *handle, const void *buffer,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2406
                                     PHYSFS_uint64 len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2407
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2408
    FileHandle *fh = (FileHandle *) handle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2409
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2410
    /* whole thing fits in the buffer? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2411
    if ( (((PHYSFS_uint64) fh->buffill) + len) < fh->bufsize )
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2412
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2413
        memcpy(fh->buffer + fh->buffill, buffer, (size_t) len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2414
        fh->buffill += (PHYSFS_uint32) len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2415
        return (PHYSFS_sint64) len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2416
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2417
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2418
    /* would overflow buffer. Flush and then write the new objects, too. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2419
    BAIL_IF_MACRO(!PHYSFS_flush(handle), ERRPASS, -1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2420
    return fh->io->write(fh->io, buffer, len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2421
} /* doBufferedWrite */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2422
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2423
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2424
PHYSFS_sint64 PHYSFS_write(PHYSFS_File *handle, const void *buffer,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2425
                           PHYSFS_uint32 size, PHYSFS_uint32 count)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2426
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2427
    const PHYSFS_uint64 len = ((PHYSFS_uint64) size) * ((PHYSFS_uint64) count);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2428
    const PHYSFS_sint64 retval = PHYSFS_writeBytes(handle, buffer, len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2429
    return ( (retval <= 0) ? retval : (retval / ((PHYSFS_sint64) size)) );
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2430
} /* PHYSFS_write */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2431
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2432
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2433
PHYSFS_sint64 PHYSFS_writeBytes(PHYSFS_File *handle, const void *buffer,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2434
                                PHYSFS_uint64 len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2435
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2436
    FileHandle *fh = (FileHandle *) handle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2437
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2438
#ifdef PHYSFS_NO_64BIT_SUPPORT
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2439
    const PHYSFS_uint64 maxlen = __PHYSFS_UI64(0x7FFFFFFF);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2440
#else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2441
    const PHYSFS_uint64 maxlen = __PHYSFS_UI64(0x7FFFFFFFFFFFFFFF);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2442
#endif
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2443
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2444
    if (!__PHYSFS_ui64FitsAddressSpace(len))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2445
        BAIL_MACRO(PHYSFS_ERR_INVALID_ARGUMENT, -1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2446
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2447
    BAIL_IF_MACRO(len > maxlen, PHYSFS_ERR_INVALID_ARGUMENT, -1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2448
    BAIL_IF_MACRO(fh->forReading, PHYSFS_ERR_OPEN_FOR_READING, -1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2449
    BAIL_IF_MACRO(len == 0, ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2450
    if (fh->buffer)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2451
        return doBufferedWrite(handle, buffer, len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2452
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2453
    return fh->io->write(fh->io, buffer, len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2454
} /* PHYSFS_write */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2455
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2456
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2457
int PHYSFS_eof(PHYSFS_File *handle)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2458
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2459
    FileHandle *fh = (FileHandle *) handle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2460
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2461
    if (!fh->forReading)  /* never EOF on files opened for write/append. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2462
        return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2463
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2464
    /* can't be eof if buffer isn't empty */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2465
    if (fh->bufpos == fh->buffill)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2466
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2467
        /* check the Io. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2468
        PHYSFS_Io *io = fh->io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2469
        const PHYSFS_sint64 pos = io->tell(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2470
        const PHYSFS_sint64 len = io->length(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2471
        if ((pos < 0) || (len < 0))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2472
            return 0;  /* beats me. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2473
        return (pos >= len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2474
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2475
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2476
    return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2477
} /* PHYSFS_eof */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2478
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2479
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2480
PHYSFS_sint64 PHYSFS_tell(PHYSFS_File *handle)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2481
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2482
    FileHandle *fh = (FileHandle *) handle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2483
    const PHYSFS_sint64 pos = fh->io->tell(fh->io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2484
    const PHYSFS_sint64 retval = fh->forReading ?
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2485
                                 (pos - fh->buffill) + fh->bufpos :
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2486
                                 (pos + fh->buffill);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2487
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2488
} /* PHYSFS_tell */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2489
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2490
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2491
int PHYSFS_seek(PHYSFS_File *handle, PHYSFS_uint64 pos)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2492
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2493
    FileHandle *fh = (FileHandle *) handle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2494
    BAIL_IF_MACRO(!PHYSFS_flush(handle), ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2495
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2496
    if (fh->buffer && fh->forReading)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2497
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2498
        /* avoid throwing away our precious buffer if seeking within it. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2499
        PHYSFS_sint64 offset = pos - PHYSFS_tell(handle);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2500
        if ( /* seeking within the already-buffered range? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2501
            ((offset >= 0) && (offset <= fh->buffill - fh->bufpos)) /* fwd */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2502
            || ((offset < 0) && (-offset <= fh->bufpos)) /* backward */ )
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2503
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2504
            fh->bufpos += (PHYSFS_uint32) offset;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2505
            return 1; /* successful seek */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2506
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2507
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2508
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2509
    /* we have to fall back to a 'raw' seek. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2510
    fh->buffill = fh->bufpos = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2511
    return fh->io->seek(fh->io, pos);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2512
} /* PHYSFS_seek */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2513
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2514
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2515
PHYSFS_sint64 PHYSFS_fileLength(PHYSFS_File *handle)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2516
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2517
    PHYSFS_Io *io = ((FileHandle *) handle)->io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2518
    return io->length(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2519
} /* PHYSFS_filelength */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2520
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2521
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2522
int PHYSFS_setBuffer(PHYSFS_File *handle, PHYSFS_uint64 _bufsize)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2523
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2524
    FileHandle *fh = (FileHandle *) handle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2525
    PHYSFS_uint32 bufsize;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2526
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2527
    /* !!! FIXME: actually, why use 32 bits here? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2528
    /*BAIL_IF_MACRO(_bufsize > 0xFFFFFFFF, "buffer must fit in 32-bits", 0);*/
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2529
    BAIL_IF_MACRO(_bufsize > 0xFFFFFFFF, PHYSFS_ERR_INVALID_ARGUMENT, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2530
    bufsize = (PHYSFS_uint32) _bufsize;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2531
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2532
    BAIL_IF_MACRO(!PHYSFS_flush(handle), ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2533
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2534
    /*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2535
     * For reads, we need to move the file pointer to where it would be
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2536
     *  if we weren't buffering, so that the next read will get the
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2537
     *  right chunk of stuff from the file. PHYSFS_flush() handles writes.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2538
     */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2539
    if ((fh->forReading) && (fh->buffill != fh->bufpos))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2540
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2541
        PHYSFS_uint64 pos;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2542
        const PHYSFS_sint64 curpos = fh->io->tell(fh->io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2543
        BAIL_IF_MACRO(curpos == -1, ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2544
        pos = ((curpos - fh->buffill) + fh->bufpos);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2545
        BAIL_IF_MACRO(!fh->io->seek(fh->io, pos), ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2546
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2547
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2548
    if (bufsize == 0)  /* delete existing buffer. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2549
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2550
        if (fh->buffer)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2551
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2552
            allocator.Free(fh->buffer);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2553
            fh->buffer = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2554
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2555
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2556
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2557
    else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2558
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2559
        PHYSFS_uint8 *newbuf;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2560
        newbuf = (PHYSFS_uint8 *) allocator.Realloc(fh->buffer, bufsize);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2561
        BAIL_IF_MACRO(!newbuf, PHYSFS_ERR_OUT_OF_MEMORY, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2562
        fh->buffer = newbuf;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2563
    } /* else */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2564
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2565
    fh->bufsize = bufsize;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2566
    fh->buffill = fh->bufpos = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2567
    return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2568
} /* PHYSFS_setBuffer */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2569
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2570
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2571
int PHYSFS_flush(PHYSFS_File *handle)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2572
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2573
    FileHandle *fh = (FileHandle *) handle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2574
    PHYSFS_Io *io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2575
    PHYSFS_sint64 rc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2576
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2577
    if ((fh->forReading) || (fh->bufpos == fh->buffill))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2578
        return 1;  /* open for read or buffer empty are successful no-ops. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2579
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2580
    /* dump buffer to disk. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2581
    io = fh->io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2582
    rc = io->write(io, fh->buffer + fh->bufpos, fh->buffill - fh->bufpos);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2583
    BAIL_IF_MACRO(rc <= 0, ERRPASS, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2584
    fh->bufpos = fh->buffill = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2585
    return io->flush(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2586
} /* PHYSFS_flush */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2587
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2588
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2589
int PHYSFS_stat(const char *_fname, PHYSFS_Stat *stat)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2590
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2591
    int retval = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2592
    char *fname;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2593
    size_t len;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2594
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2595
    BAIL_IF_MACRO(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, -1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2596
    BAIL_IF_MACRO(!stat, PHYSFS_ERR_INVALID_ARGUMENT, -1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2597
    len = strlen(_fname) + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2598
    fname = (char *) __PHYSFS_smallAlloc(len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2599
    BAIL_IF_MACRO(!fname, PHYSFS_ERR_OUT_OF_MEMORY, -1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2600
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2601
    /* set some sane defaults... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2602
    stat->filesize = -1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2603
    stat->modtime = -1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2604
    stat->createtime = -1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2605
    stat->accesstime = -1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2606
    stat->filetype = PHYSFS_FILETYPE_OTHER;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2607
    stat->readonly = 1;  /* !!! FIXME */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2608
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2609
    if (sanitizePlatformIndependentPath(_fname, fname))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2610
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2611
        if (*fname == '\0')
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2612
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2613
            stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2614
            stat->readonly = !writeDir; /* Writeable if we have a writeDir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2615
            retval = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2616
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2617
        else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2618
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2619
            DirHandle *i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2620
            int exists = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2621
            __PHYSFS_platformGrabMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2622
            for (i = searchPath; ((i != NULL) && (!exists)); i = i->next)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2623
            {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2624
                char *arcfname = fname;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2625
                exists = partOfMountPoint(i, arcfname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2626
                if (exists)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2627
                {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2628
                    stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2629
                    stat->readonly = 1;  /* !!! FIXME */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2630
                    retval = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2631
                } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2632
                else if (verifyPath(i, &arcfname, 0))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2633
                {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2634
                    /* !!! FIXME: this test is wrong and should be elsewhere. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2635
                    stat->readonly = !(writeDir &&
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2636
                                 (strcmp(writeDir->dirName, i->dirName) == 0));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2637
                    retval = i->funcs->stat(i->opaque, arcfname, &exists, stat);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2638
                } /* else if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2639
            } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2640
            __PHYSFS_platformReleaseMutex(stateLock);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2641
        } /* else */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2642
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2643
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2644
    __PHYSFS_smallFree(fname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2645
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2646
} /* PHYSFS_stat */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2647
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2648
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2649
int __PHYSFS_readAll(PHYSFS_Io *io, void *buf, const PHYSFS_uint64 len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2650
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2651
    return (io->read(io, buf, len) == len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2652
} /* __PHYSFS_readAll */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2653
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2654
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2655
void *__PHYSFS_initSmallAlloc(void *ptr, PHYSFS_uint64 len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2656
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2657
    void *useHeap = ((ptr == NULL) ? ((void *) 1) : ((void *) 0));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2658
    if (useHeap)  /* too large for stack allocation or alloca() failed. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2659
        ptr = allocator.Malloc(len+sizeof (void *));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2660
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2661
    if (ptr != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2662
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2663
        void **retval = (void **) ptr;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2664
        /*printf("%s alloc'd (%d) bytes at (%p).\n",
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2665
                useHeap ? "heap" : "stack", (int) len, ptr);*/
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2666
        *retval = useHeap;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2667
        return retval + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2668
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2669
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2670
    return NULL;  /* allocation failed. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2671
} /* __PHYSFS_initSmallAlloc */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2672
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2673
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2674
void __PHYSFS_smallFree(void *ptr)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2675
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2676
    if (ptr != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2677
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2678
        void **block = ((void **) ptr) - 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2679
        const int useHeap = (*block != 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2680
        if (useHeap)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2681
            allocator.Free(block);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2682
        /*printf("%s free'd (%p).\n", useHeap ? "heap" : "stack", block);*/
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2683
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2684
} /* __PHYSFS_smallFree */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2685
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2686
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2687
int PHYSFS_setAllocator(const PHYSFS_Allocator *a)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2688
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2689
    BAIL_IF_MACRO(initialized, PHYSFS_ERR_IS_INITIALIZED, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2690
    externalAllocator = (a != NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2691
    if (externalAllocator)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2692
        memcpy(&allocator, a, sizeof (PHYSFS_Allocator));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2693
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2694
    return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2695
} /* PHYSFS_setAllocator */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2696
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2697
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2698
const PHYSFS_Allocator *PHYSFS_getAllocator(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2699
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2700
    BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2701
    return &allocator;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2702
} /* PHYSFS_getAllocator */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2703
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2704
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2705
static void *mallocAllocatorMalloc(PHYSFS_uint64 s)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2706
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2707
    if (!__PHYSFS_ui64FitsAddressSpace(s))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2708
        BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2709
    #undef malloc
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2710
    return malloc((size_t) s);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2711
} /* mallocAllocatorMalloc */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2712
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2713
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2714
static void *mallocAllocatorRealloc(void *ptr, PHYSFS_uint64 s)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2715
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2716
    if (!__PHYSFS_ui64FitsAddressSpace(s))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2717
        BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2718
    #undef realloc
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2719
    return realloc(ptr, (size_t) s);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2720
} /* mallocAllocatorRealloc */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2721
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2722
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2723
static void mallocAllocatorFree(void *ptr)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2724
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2725
    #undef free
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2726
    free(ptr);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2727
} /* mallocAllocatorFree */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2728
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2729
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2730
static void setDefaultAllocator(void)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2731
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2732
    assert(!externalAllocator);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2733
    if (!__PHYSFS_platformSetDefaultAllocator(&allocator))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2734
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2735
        allocator.Init = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2736
        allocator.Deinit = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2737
        allocator.Malloc = mallocAllocatorMalloc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2738
        allocator.Realloc = mallocAllocatorRealloc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2739
        allocator.Free = mallocAllocatorFree;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2740
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2741
} /* setDefaultAllocator */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2742
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2743
/* end of physfs.c ... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
  2744