misc/libphysfs/archiver_unpacked.c
author nemo
Mon, 30 Dec 2013 23:28:47 -0500
changeset 9892 5a0a7ef7af2d
parent 8524 a65e9bcf0a03
child 10017 de822cd3df3a
permissions -rw-r--r--
allow SDL 1.2 to at least do a 32767 map. We probably should add a TryDo somewhere to assert that limit on SDL 1.2 to avoid overflows. Ditto int version for SDL 2
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
 * High-level PhysicsFS archiver for simple unpacked file formats.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     3
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     4
 * This is a framework that basic archivers build on top of. It's for simple
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     5
 *  formats that can just hand back a list of files and the offsets of their
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     6
 *  uncompressed data. There are an alarming number of formats like this.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     7
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     8
 * RULES: Archive entries must be uncompressed, must not have separate subdir
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     9
 *  entries (but can have subdirs), must be case insensitive LOW ASCII
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    10
 *  filenames <= 56 bytes. No symlinks, etc. We can relax some of these rules
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    11
 *  as necessary.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    12
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    13
 * Please see the file LICENSE.txt in the source's root directory.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    14
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    15
 *  This file written by Ryan C. Gordon.
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
#define __PHYSICSFS_INTERNAL__
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    19
#include "physfs_internal.h"
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    20
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    21
typedef struct
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    22
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    23
    PHYSFS_Io *io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    24
    PHYSFS_uint32 entryCount;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    25
    UNPKentry *entries;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    26
} UNPKinfo;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    27
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    28
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    29
typedef struct
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    30
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    31
    PHYSFS_Io *io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    32
    UNPKentry *entry;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    33
    PHYSFS_uint32 curPos;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    34
} UNPKfileinfo;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    35
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    36
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    37
void UNPK_closeArchive(PHYSFS_Dir *opaque)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    38
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    39
    UNPKinfo *info = ((UNPKinfo *) opaque);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    40
    info->io->destroy(info->io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    41
    allocator.Free(info->entries);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    42
    allocator.Free(info);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    43
} /* UNPK_closeArchive */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    44
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    45
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    46
static PHYSFS_sint64 UNPK_read(PHYSFS_Io *io, void *buffer, PHYSFS_uint64 len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    47
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    48
    UNPKfileinfo *finfo = (UNPKfileinfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    49
    const UNPKentry *entry = finfo->entry;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    50
    const PHYSFS_uint64 bytesLeft = (PHYSFS_uint64)(entry->size-finfo->curPos);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    51
    PHYSFS_sint64 rc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    52
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    53
    if (bytesLeft < len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    54
        len = bytesLeft;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    55
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    56
    rc = finfo->io->read(finfo->io, buffer, len);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    57
    if (rc > 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    58
        finfo->curPos += (PHYSFS_uint32) rc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    59
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    60
    return rc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    61
} /* UNPK_read */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    62
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    63
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    64
static PHYSFS_sint64 UNPK_write(PHYSFS_Io *io, const void *b, PHYSFS_uint64 len)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    65
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    66
    BAIL_MACRO(PHYSFS_ERR_READ_ONLY, -1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    67
} /* UNPK_write */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    68
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    69
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    70
static PHYSFS_sint64 UNPK_tell(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    71
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    72
    return ((UNPKfileinfo *) io->opaque)->curPos;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    73
} /* UNPK_tell */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    74
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    75
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    76
static int UNPK_seek(PHYSFS_Io *io, PHYSFS_uint64 offset)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    77
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    78
    UNPKfileinfo *finfo = (UNPKfileinfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    79
    const UNPKentry *entry = finfo->entry;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    80
    int rc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    81
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    82
    BAIL_IF_MACRO(offset >= entry->size, PHYSFS_ERR_PAST_EOF, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    83
    rc = finfo->io->seek(finfo->io, entry->startPos + offset);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    84
    if (rc)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    85
        finfo->curPos = (PHYSFS_uint32) offset;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    86
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    87
    return rc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    88
} /* UNPK_seek */
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
static PHYSFS_sint64 UNPK_length(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    92
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    93
    const UNPKfileinfo *finfo = (UNPKfileinfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    94
    return ((PHYSFS_sint64) finfo->entry->size);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    95
} /* UNPK_length */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    96
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    97
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    98
static PHYSFS_Io *UNPK_duplicate(PHYSFS_Io *_io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    99
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   100
    UNPKfileinfo *origfinfo = (UNPKfileinfo *) _io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   101
    PHYSFS_Io *io = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   102
    PHYSFS_Io *retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   103
    UNPKfileinfo *finfo = (UNPKfileinfo *) allocator.Malloc(sizeof (UNPKfileinfo));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   104
    GOTO_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_duplicate_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   105
    GOTO_IF_MACRO(!finfo, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_duplicate_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   106
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   107
    io = origfinfo->io->duplicate(origfinfo->io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   108
    if (!io) goto UNPK_duplicate_failed;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   109
    finfo->io = io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   110
    finfo->entry = origfinfo->entry;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   111
    finfo->curPos = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   112
    memcpy(retval, _io, sizeof (PHYSFS_Io));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   113
    retval->opaque = finfo;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   114
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   115
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   116
UNPK_duplicate_failed:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   117
    if (finfo != NULL) allocator.Free(finfo);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   118
    if (retval != NULL) allocator.Free(retval);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   119
    if (io != NULL) io->destroy(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   120
    return NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   121
} /* UNPK_duplicate */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   122
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   123
static int UNPK_flush(PHYSFS_Io *io) { return 1;  /* no write support. */ }
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   124
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   125
static void UNPK_destroy(PHYSFS_Io *io)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   126
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   127
    UNPKfileinfo *finfo = (UNPKfileinfo *) io->opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   128
    finfo->io->destroy(finfo->io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   129
    allocator.Free(finfo);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   130
    allocator.Free(io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   131
} /* UNPK_destroy */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   132
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   133
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   134
static const PHYSFS_Io UNPK_Io =
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   135
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   136
    CURRENT_PHYSFS_IO_API_VERSION, NULL,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   137
    UNPK_read,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   138
    UNPK_write,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   139
    UNPK_seek,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   140
    UNPK_tell,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   141
    UNPK_length,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   142
    UNPK_duplicate,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   143
    UNPK_flush,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   144
    UNPK_destroy
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   145
};
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   146
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   147
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   148
static int entryCmp(void *_a, size_t one, size_t two)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   149
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   150
    if (one != two)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   151
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   152
        const UNPKentry *a = (const UNPKentry *) _a;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   153
        return __PHYSFS_stricmpASCII(a[one].name, a[two].name);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   154
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   155
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   156
    return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   157
} /* entryCmp */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   158
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   159
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   160
static void entrySwap(void *_a, size_t one, size_t two)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   161
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   162
    if (one != two)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   163
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   164
        UNPKentry tmp;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   165
        UNPKentry *first = &(((UNPKentry *) _a)[one]);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   166
        UNPKentry *second = &(((UNPKentry *) _a)[two]);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   167
        memcpy(&tmp, first, sizeof (UNPKentry));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   168
        memcpy(first, second, sizeof (UNPKentry));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   169
        memcpy(second, &tmp, sizeof (UNPKentry));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   170
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   171
} /* entrySwap */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   172
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   173
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   174
static PHYSFS_sint32 findStartOfDir(UNPKinfo *info, const char *path,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   175
                                    int stop_on_first_find)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   176
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   177
    PHYSFS_sint32 lo = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   178
    PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   179
    PHYSFS_sint32 middle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   180
    PHYSFS_uint32 dlen = (PHYSFS_uint32) strlen(path);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   181
    PHYSFS_sint32 retval = -1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   182
    const char *name;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   183
    int rc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   184
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   185
    if (*path == '\0')  /* root dir? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   186
        return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   187
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   188
    if ((dlen > 0) && (path[dlen - 1] == '/')) /* ignore trailing slash. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   189
        dlen--;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   190
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   191
    while (lo <= hi)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   192
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   193
        middle = lo + ((hi - lo) / 2);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   194
        name = info->entries[middle].name;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   195
        rc = __PHYSFS_strnicmpASCII(path, name, dlen);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   196
        if (rc == 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   197
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   198
            char ch = name[dlen];
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   199
            if (ch < '/') /* make sure this isn't just a substr match. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   200
                rc = -1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   201
            else if (ch > '/')
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   202
                rc = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   203
            else 
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   204
            {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   205
                if (stop_on_first_find) /* Just checking dir's existance? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   206
                    return middle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   207
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   208
                if (name[dlen + 1] == '\0') /* Skip initial dir entry. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   209
                    return (middle + 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   210
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   211
                /* there might be more entries earlier in the list. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   212
                retval = middle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   213
                hi = middle - 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   214
            } /* else */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   215
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   216
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   217
        if (rc > 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   218
            lo = middle + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   219
        else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   220
            hi = middle - 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   221
    } /* while */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   222
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   223
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   224
} /* findStartOfDir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   225
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   226
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   227
/*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   228
 * Moved to seperate function so we can use alloca then immediately throw
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   229
 *  away the allocated stack space...
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   230
 */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   231
static void doEnumCallback(PHYSFS_EnumFilesCallback cb, void *callbackdata,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   232
                           const char *odir, const char *str, PHYSFS_sint32 ln)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   233
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   234
    char *newstr = __PHYSFS_smallAlloc(ln + 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   235
    if (newstr == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   236
        return;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   237
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   238
    memcpy(newstr, str, ln);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   239
    newstr[ln] = '\0';
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   240
    cb(callbackdata, odir, newstr);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   241
    __PHYSFS_smallFree(newstr);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   242
} /* doEnumCallback */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   243
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   244
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   245
void UNPK_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   246
                         int omitSymLinks, PHYSFS_EnumFilesCallback cb,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   247
                         const char *origdir, void *callbackdata)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   248
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   249
    UNPKinfo *info = ((UNPKinfo *) opaque);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   250
    PHYSFS_sint32 dlen, dlen_inc, max, i;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   251
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   252
    i = findStartOfDir(info, dname, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   253
    if (i == -1)  /* no such directory. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   254
        return;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   255
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   256
    dlen = (PHYSFS_sint32) strlen(dname);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   257
    if ((dlen > 0) && (dname[dlen - 1] == '/')) /* ignore trailing slash. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   258
        dlen--;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   259
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   260
    dlen_inc = ((dlen > 0) ? 1 : 0) + dlen;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   261
    max = (PHYSFS_sint32) info->entryCount;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   262
    while (i < max)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   263
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   264
        char *add;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   265
        char *ptr;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   266
        PHYSFS_sint32 ln;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   267
        char *e = info->entries[i].name;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   268
        if ((dlen) &&
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   269
            ((__PHYSFS_strnicmpASCII(e, dname, dlen)) || (e[dlen] != '/')))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   270
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   271
            break;  /* past end of this dir; we're done. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   272
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   273
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   274
        add = e + dlen_inc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   275
        ptr = strchr(add, '/');
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   276
        ln = (PHYSFS_sint32) ((ptr) ? ptr-add : strlen(add));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   277
        doEnumCallback(cb, callbackdata, origdir, add, ln);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   278
        ln += dlen_inc;  /* point past entry to children... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   279
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   280
        /* increment counter and skip children of subdirs... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   281
        while ((++i < max) && (ptr != NULL))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   282
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   283
            char *e_new = info->entries[i].name;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   284
            if ((__PHYSFS_strnicmpASCII(e, e_new, ln) != 0) ||
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   285
                (e_new[ln] != '/'))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   286
            {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   287
                break;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   288
            } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   289
        } /* while */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   290
    } /* while */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   291
} /* UNPK_enumerateFiles */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   292
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   293
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   294
/*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   295
 * This will find the UNPKentry associated with a path in platform-independent
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   296
 *  notation. Directories don't have UNPKentries associated with them, but 
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   297
 *  (*isDir) will be set to non-zero if a dir was hit.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   298
 */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   299
static UNPKentry *findEntry(const UNPKinfo *info, const char *path, int *isDir)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   300
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   301
    UNPKentry *a = info->entries;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   302
    PHYSFS_sint32 pathlen = (PHYSFS_sint32) strlen(path);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   303
    PHYSFS_sint32 lo = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   304
    PHYSFS_sint32 hi = (PHYSFS_sint32) (info->entryCount - 1);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   305
    PHYSFS_sint32 middle;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   306
    const char *thispath = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   307
    int rc;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   308
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   309
    while (lo <= hi)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   310
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   311
        middle = lo + ((hi - lo) / 2);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   312
        thispath = a[middle].name;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   313
        rc = __PHYSFS_strnicmpASCII(path, thispath, pathlen);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   314
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   315
        if (rc > 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   316
            lo = middle + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   317
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   318
        else if (rc < 0)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   319
            hi = middle - 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   320
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   321
        else /* substring match...might be dir or entry or nothing. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   322
        {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   323
            if (isDir != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   324
            {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   325
                *isDir = (thispath[pathlen] == '/');
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   326
                if (*isDir)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   327
                    return NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   328
            } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   329
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   330
            if (thispath[pathlen] == '\0') /* found entry? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   331
                return &a[middle];
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   332
            /* adjust search params, try again. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   333
            else if (thispath[pathlen] > '/')
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   334
                hi = middle - 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   335
            else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   336
                lo = middle + 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   337
        } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   338
    } /* while */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   339
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   340
    if (isDir != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   341
        *isDir = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   342
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   343
    BAIL_MACRO(PHYSFS_ERR_NO_SUCH_PATH, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   344
} /* findEntry */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   345
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   346
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   347
PHYSFS_Io *UNPK_openRead(PHYSFS_Dir *opaque, const char *fnm, int *fileExists)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   348
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   349
    PHYSFS_Io *retval = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   350
    UNPKinfo *info = (UNPKinfo *) opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   351
    UNPKfileinfo *finfo = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   352
    int isdir = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   353
    UNPKentry *entry = findEntry(info, fnm, &isdir);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   354
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   355
    *fileExists = (entry != NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   356
    GOTO_IF_MACRO(isdir, PHYSFS_ERR_NOT_A_FILE, UNPK_openRead_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   357
    GOTO_IF_MACRO(!entry, ERRPASS, UNPK_openRead_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   358
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   359
    retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   360
    GOTO_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_openRead_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   361
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   362
    finfo = (UNPKfileinfo *) allocator.Malloc(sizeof (UNPKfileinfo));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   363
    GOTO_IF_MACRO(!finfo, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_openRead_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   364
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   365
    finfo->io = info->io->duplicate(info->io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   366
    GOTO_IF_MACRO(!finfo->io, ERRPASS, UNPK_openRead_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   367
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   368
    if (!finfo->io->seek(finfo->io, entry->startPos))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   369
        goto UNPK_openRead_failed;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   370
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   371
    finfo->curPos = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   372
    finfo->entry = entry;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   373
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   374
    memcpy(retval, &UNPK_Io, sizeof (*retval));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   375
    retval->opaque = finfo;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   376
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   377
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   378
UNPK_openRead_failed:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   379
    if (finfo != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   380
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   381
        if (finfo->io != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   382
            finfo->io->destroy(finfo->io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   383
        allocator.Free(finfo);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   384
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   385
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   386
    if (retval != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   387
        allocator.Free(retval);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   388
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   389
    return NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   390
} /* UNPK_openRead */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   391
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   392
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   393
PHYSFS_Io *UNPK_openWrite(PHYSFS_Dir *opaque, const char *name)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   394
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   395
    BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   396
} /* UNPK_openWrite */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   397
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   398
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   399
PHYSFS_Io *UNPK_openAppend(PHYSFS_Dir *opaque, const char *name)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   400
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   401
    BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   402
} /* UNPK_openAppend */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   403
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   404
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   405
int UNPK_remove(PHYSFS_Dir *opaque, const char *name)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   406
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   407
    BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   408
} /* UNPK_remove */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   409
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   410
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   411
int UNPK_mkdir(PHYSFS_Dir *opaque, const char *name)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   412
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   413
    BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   414
} /* UNPK_mkdir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   415
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   416
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   417
int UNPK_stat(PHYSFS_Dir *opaque, const char *filename,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   418
              int *exists, PHYSFS_Stat *stat)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   419
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   420
    int isDir = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   421
    const UNPKinfo *info = (const UNPKinfo *) opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   422
    const UNPKentry *entry = findEntry(info, filename, &isDir);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   423
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   424
    if (isDir)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   425
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   426
        *exists = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   427
        stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   428
        stat->filesize = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   429
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   430
    else if (entry != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   431
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   432
        *exists = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   433
        stat->filetype = PHYSFS_FILETYPE_REGULAR;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   434
        stat->filesize = entry->size;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   435
    } /* else if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   436
    else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   437
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   438
        *exists = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   439
        return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   440
    } /* else */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   441
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   442
    stat->modtime = -1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   443
    stat->createtime = -1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   444
    stat->accesstime = -1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   445
    stat->readonly = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   446
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   447
    return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   448
} /* UNPK_stat */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   449
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   450
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   451
PHYSFS_Dir *UNPK_openArchive(PHYSFS_Io *io, UNPKentry *e,
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   452
                             const PHYSFS_uint32 num)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   453
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   454
    UNPKinfo *info = (UNPKinfo *) allocator.Malloc(sizeof (UNPKinfo));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   455
    if (info == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   456
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   457
        allocator.Free(e);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   458
        BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   459
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   460
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   461
    __PHYSFS_sort(e, (size_t) num, entryCmp, entrySwap);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   462
    info->io = io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   463
    info->entryCount = num;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   464
    info->entries = e;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   465
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   466
    return info;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   467
} /* UNPK_openArchive */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   468
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   469
/* end of archiver_unpacked.c ... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   470