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