misc/libphysfs/archiver_qpak.c
author Wuzzy <almikes@aol.com>
Sat, 23 Sep 2017 19:49:41 +0200
changeset 12503 7442bb330d38
parent 12213 bb5522e88ab2
permissions -rw-r--r--
More random names: angel, morbid, pokemon-like, viking, darth vader, stormtrooper, war-themed
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
 * QPAK support routines for PhysicsFS.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     3
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     4
 *  This archiver handles the archive format utilized by Quake 1 and 2.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     5
 *  Quake3-based games use the PkZip/Info-Zip format (which our zip.c
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     6
 *  archiver handles).
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     7
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     8
 *  ========================================================================
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     9
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    10
 *  This format info (in more detail) comes from:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    11
 *     http://debian.fmi.uni-sofia.bg/~sergei/cgsr/docs/pak.txt
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    12
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    13
 *  Quake PAK Format
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    14
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    15
 *  Header
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    16
 *   (4 bytes)  signature = 'PACK'
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    17
 *   (4 bytes)  directory offset
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    18
 *   (4 bytes)  directory length
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    19
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    20
 *  Directory
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    21
 *   (56 bytes) file name
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    22
 *   (4 bytes)  file position
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    23
 *   (4 bytes)  file length
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    24
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    25
 *  ========================================================================
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    26
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    27
 * Please see the file LICENSE.txt in the source's root directory.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    28
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    29
 *  This file written by Ryan C. Gordon.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    30
 */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    31
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    32
#define __PHYSICSFS_INTERNAL__
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    33
#include "physfs_internal.h"
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    34
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    35
#if PHYSFS_SUPPORTS_QPAK
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    36
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    37
#define QPAK_SIG 0x4B434150   /* "PACK" in ASCII. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    38
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    39
static UNPKentry *qpakLoadEntries(PHYSFS_Io *io, PHYSFS_uint32 fileCount)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    40
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    41
    UNPKentry *entries = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    42
    UNPKentry *entry = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    43
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    44
    entries = (UNPKentry *) allocator.Malloc(sizeof (UNPKentry) * fileCount);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    45
    BAIL_IF_MACRO(entries == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    46
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    47
    for (entry = entries; fileCount > 0; fileCount--, entry++)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    48
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    49
        if (!__PHYSFS_readAll(io, &entry->name, 56)) goto failed;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    50
        if (!__PHYSFS_readAll(io, &entry->startPos, 4)) goto failed;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    51
        if (!__PHYSFS_readAll(io, &entry->size, 4)) goto failed;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    52
        entry->size = PHYSFS_swapULE32(entry->size);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    53
        entry->startPos = PHYSFS_swapULE32(entry->startPos);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    54
    } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    55
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    56
    return entries;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    57
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    58
failed:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    59
    allocator.Free(entries);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    60
    return NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    61
} /* qpakLoadEntries */
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 void *QPAK_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    65
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    66
    UNPKentry *entries = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    67
    PHYSFS_uint32 val = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    68
    PHYSFS_uint32 pos = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    69
    PHYSFS_uint32 count = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    70
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    71
    assert(io != NULL);  /* shouldn't ever happen. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    72
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    73
    BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    74
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    75
    BAIL_IF_MACRO(!__PHYSFS_readAll(io, &val, 4), ERRPASS, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    76
    if (PHYSFS_swapULE32(val) != QPAK_SIG)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    77
        BAIL_MACRO(PHYSFS_ERR_UNSUPPORTED, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    78
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    79
    BAIL_IF_MACRO(!__PHYSFS_readAll(io, &val, 4), ERRPASS, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    80
    pos = PHYSFS_swapULE32(val);  /* directory table offset. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    81
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    82
    BAIL_IF_MACRO(!__PHYSFS_readAll(io, &val, 4), ERRPASS, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    83
    count = PHYSFS_swapULE32(val);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    84
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    85
    /* corrupted archive? */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    86
    BAIL_IF_MACRO((count % 64) != 0, PHYSFS_ERR_CORRUPT, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    87
    count /= 64;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    88
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    89
    BAIL_IF_MACRO(!io->seek(io, pos), ERRPASS, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    90
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    91
    entries = qpakLoadEntries(io, count);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    92
    BAIL_IF_MACRO(!entries, ERRPASS, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    93
    return UNPK_openArchive(io, entries, count);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    94
} /* QPAK_openArchive */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    95
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    96
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    97
const PHYSFS_Archiver __PHYSFS_Archiver_QPAK =
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    98
{
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: 8524
diff changeset
    99
    CURRENT_PHYSFS_ARCHIVER_API_VERSION,
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   100
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   101
        "PAK",
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   102
        "Quake I/II format",
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   103
        "Ryan C. Gordon <icculus@icculus.org>",
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: 8524
diff changeset
   104
        "https://icculus.org/physfs/",
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: 8524
diff changeset
   105
        0,  /* supportsSymlinks */
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   106
    },
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: 8524
diff changeset
   107
    QPAK_openArchive,
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: 8524
diff changeset
   108
    UNPK_enumerateFiles,
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: 8524
diff changeset
   109
    UNPK_openRead,
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: 8524
diff changeset
   110
    UNPK_openWrite,
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: 8524
diff changeset
   111
    UNPK_openAppend,
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: 8524
diff changeset
   112
    UNPK_remove,
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: 8524
diff changeset
   113
    UNPK_mkdir,
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: 8524
diff changeset
   114
    UNPK_stat,
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: 8524
diff changeset
   115
    UNPK_closeArchive
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   116
};
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   117
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   118
#endif  /* defined PHYSFS_SUPPORTS_QPAK */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   119
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: 8524
diff changeset
   120
/* end of archiver_qpak.c ... */
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   121