misc/libphysfs/archiver_grp.c
author nemo
Sun, 04 Jan 2015 00:44:14 -0500
branch0.9.21
changeset 10743 1d16c5414fee
parent 8524 a65e9bcf0a03
child 12213 bb5522e88ab2
permissions -rw-r--r--
Intent is to allow filtering by arbitrary flag combinations. This isn't actually working yet. No idea why. It seems it should. Tired though, so will look at it tomorrow.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7768
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     1
/*
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     2
 * GRP support routines for PhysicsFS.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     3
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     4
 * This driver handles BUILD engine archives ("groupfiles"). This format
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     5
 *  (but not this driver) was put together by Ken Silverman.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     6
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     7
 * The format is simple enough. In Ken's words:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     8
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
     9
 *    What's the .GRP file format?
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    10
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    11
 *     The ".grp" file format is just a collection of a lot of files stored
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    12
 *     into 1 big one. I tried to make the format as simple as possible: The
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    13
 *     first 12 bytes contains my name, "KenSilverman". The next 4 bytes is
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    14
 *     the number of files that were compacted into the group file. Then for
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    15
 *     each file, there is a 16 byte structure, where the first 12 bytes are
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    16
 *     the filename, and the last 4 bytes are the file's size. The rest of
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    17
 *     the group file is just the raw data packed one after the other in the
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    18
 *     same order as the list of files.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    19
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    20
 * (That info is from http://www.advsys.net/ken/build.htm ...)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    21
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    22
 * Please see the file LICENSE.txt in the source's root directory.
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    23
 *
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    24
 *  This file written by Ryan C. Gordon.
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
#define __PHYSICSFS_INTERNAL__
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    28
#include "physfs_internal.h"
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    29
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    30
#if PHYSFS_SUPPORTS_GRP
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    31
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    32
static UNPKentry *grpLoadEntries(PHYSFS_Io *io, PHYSFS_uint32 fileCount)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    33
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    34
    PHYSFS_uint32 location = 16;  /* sizeof sig. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    35
    UNPKentry *entries = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    36
    UNPKentry *entry = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    37
    char *ptr = NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    38
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    39
    entries = (UNPKentry *) allocator.Malloc(sizeof (UNPKentry) * fileCount);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    40
    BAIL_IF_MACRO(entries == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    41
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    42
    location += (16 * fileCount);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    43
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    44
    for (entry = entries; fileCount > 0; fileCount--, entry++)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    45
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    46
        GOTO_IF_MACRO(!__PHYSFS_readAll(io, &entry->name, 12), ERRPASS, failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    47
        GOTO_IF_MACRO(!__PHYSFS_readAll(io, &entry->size, 4), ERRPASS, failed);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    48
        entry->name[12] = '\0';  /* name isn't null-terminated in file. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    49
        if ((ptr = strchr(entry->name, ' ')) != NULL)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    50
            *ptr = '\0';  /* trim extra spaces. */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    51
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 = location;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    54
        location += entry->size;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    55
    } /* for */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    56
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    57
    return entries;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    58
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    59
failed:
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    60
    allocator.Free(entries);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    61
    return NULL;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    62
} /* grpLoadEntries */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    63
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    64
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    65
static void *GRP_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    66
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    67
    PHYSFS_uint8 buf[12];
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    68
    PHYSFS_uint32 count = 0;
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    69
    UNPKentry *entries = NULL;
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, buf, sizeof (buf)), ERRPASS, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    76
    if (memcmp(buf, "KenSilverman", sizeof (buf)) != 0)
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, &count, sizeof(count)), ERRPASS, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    80
    count = PHYSFS_swapULE32(count);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    81
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    82
    entries = grpLoadEntries(io, count);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    83
    BAIL_IF_MACRO(!entries, ERRPASS, NULL);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    84
    return UNPK_openArchive(io, entries, count);
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    85
} /* GRP_openArchive */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    86
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    87
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    88
const PHYSFS_Archiver __PHYSFS_Archiver_GRP =
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    89
{
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    90
    {
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    91
        "GRP",
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    92
        "Build engine Groupfile format",
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    93
        "Ryan C. Gordon <icculus@icculus.org>",
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    94
        "http://icculus.org/physfs/",
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    95
    },
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    96
    GRP_openArchive,        /* openArchive() method    */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    97
    UNPK_enumerateFiles,    /* enumerateFiles() method */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    98
    UNPK_openRead,          /* openRead() method       */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
    99
    UNPK_openWrite,         /* openWrite() method      */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   100
    UNPK_openAppend,        /* openAppend() method     */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   101
    UNPK_remove,            /* remove() method         */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   102
    UNPK_mkdir,             /* mkdir() method          */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   103
    UNPK_closeArchive,      /* closeArchive() method   */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   104
    UNPK_stat               /* stat() method           */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   105
};
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   106
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   107
#endif  /* defined PHYSFS_SUPPORTS_GRP */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   108
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   109
/* end of grp.c ... */
13e2037ebc79 Try using PhysicsFS.
unc0rr
parents:
diff changeset
   110