misc/libphysfs/archiver_unpacked.c
author Wuzzy <Wuzzy2@mail.ru>
Tue, 31 Jul 2018 22:40:23 +0200
changeset 13581 9c8749bb0d06
parent 12213 bb5522e88ab2
permissions -rw-r--r--
Clean up Tumbler captions a bit
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
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
    10
 *  filenames <= 64 bytes. No symlinks, etc. We can relax some of these rules
7768
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
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
    37
void UNPK_closeArchive(void *opaque)
7768
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;
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   203
            else 
7768
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
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   245
void UNPK_enumerateFiles(void *opaque, const char *dname,
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   246
                         PHYSFS_EnumFilesCallback cb,
7768
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
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   296
 *  notation. Directories don't have UNPKentries associated with them, but 
7768
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
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   343
    BAIL_MACRO(PHYSFS_ERR_NOT_FOUND, NULL);
7768
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
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   347
PHYSFS_Io *UNPK_openRead(void *opaque, const char *name)
7768
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;
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   353
    UNPKentry *entry = findEntry(info, name, &isdir);
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   354
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   355
    GOTO_IF_MACRO(isdir, PHYSFS_ERR_NOT_A_FILE, UNPK_openRead_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   356
    GOTO_IF_MACRO(!entry, ERRPASS, UNPK_openRead_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   357
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   358
    retval = (PHYSFS_Io *) allocator.Malloc(sizeof (PHYSFS_Io));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   359
    GOTO_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_openRead_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   360
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   361
    finfo = (UNPKfileinfo *) allocator.Malloc(sizeof (UNPKfileinfo));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   362
    GOTO_IF_MACRO(!finfo, PHYSFS_ERR_OUT_OF_MEMORY, UNPK_openRead_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   363
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   364
    finfo->io = info->io->duplicate(info->io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   365
    GOTO_IF_MACRO(!finfo->io, ERRPASS, UNPK_openRead_failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   366
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   367
    if (!finfo->io->seek(finfo->io, entry->startPos))
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   368
        goto UNPK_openRead_failed;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   369
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   370
    finfo->curPos = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   371
    finfo->entry = entry;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   372
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   373
    memcpy(retval, &UNPK_Io, sizeof (*retval));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   374
    retval->opaque = finfo;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   375
    return retval;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   376
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   377
UNPK_openRead_failed:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   378
    if (finfo != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   379
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   380
        if (finfo->io != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   381
            finfo->io->destroy(finfo->io);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   382
        allocator.Free(finfo);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   383
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   384
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   385
    if (retval != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   386
        allocator.Free(retval);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   387
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   388
    return NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   389
} /* UNPK_openRead */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   390
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   391
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   392
PHYSFS_Io *UNPK_openWrite(void *opaque, const char *name)
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   393
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   394
    BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   395
} /* UNPK_openWrite */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   396
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   397
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   398
PHYSFS_Io *UNPK_openAppend(void *opaque, const char *name)
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   399
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   400
    BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   401
} /* UNPK_openAppend */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   402
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   403
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   404
int UNPK_remove(void *opaque, const char *name)
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   405
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   406
    BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   407
} /* UNPK_remove */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   408
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   409
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   410
int UNPK_mkdir(void *opaque, const char *name)
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   411
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   412
    BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   413
} /* UNPK_mkdir */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   414
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   415
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   416
int UNPK_stat(void *opaque, const char *filename, PHYSFS_Stat *stat)
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   417
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   418
    int isDir = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   419
    const UNPKinfo *info = (const UNPKinfo *) opaque;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   420
    const UNPKentry *entry = findEntry(info, filename, &isDir);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   421
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   422
    if (isDir)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   423
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   424
        stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   425
        stat->filesize = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   426
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   427
    else if (entry != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   428
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   429
        stat->filetype = PHYSFS_FILETYPE_REGULAR;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   430
        stat->filesize = entry->size;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   431
    } /* else if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   432
    else
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   433
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   434
        return 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   435
    } /* else */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   436
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   437
    stat->modtime = -1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   438
    stat->createtime = -1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   439
    stat->accesstime = -1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   440
    stat->readonly = 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   441
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   442
    return 1;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   443
} /* UNPK_stat */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   444
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   445
12213
bb5522e88ab2 bulk copy of latest physfs to our misc/libphysfs since this seems to fix an off-by-1 error reliably hit in readln read of 1 byte probably introduced in the addition of the buffered read. Whether this is excessive or whether libphysfs should even be maintained by us is another matter. But at least we shouldn't crash
nemo
parents: 10017
diff changeset
   446
void *UNPK_openArchive(PHYSFS_Io *io, UNPKentry *e, const PHYSFS_uint32 num)
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   447
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   448
    UNPKinfo *info = (UNPKinfo *) allocator.Malloc(sizeof (UNPKinfo));
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   449
    if (info == NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   450
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   451
        allocator.Free(e);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   452
        BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   453
    } /* if */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   454
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   455
    __PHYSFS_sort(e, (size_t) num, entryCmp, entrySwap);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   456
    info->io = io;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   457
    info->entryCount = num;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   458
    info->entries = e;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   459
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   460
    return info;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   461
} /* UNPK_openArchive */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   462
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   463
/* end of archiver_unpacked.c ... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   464