misc/libphysfs/archiver_mvl.c
branchui-scaling
changeset 15283 c4fd2813b127
parent 13390 0135e64c6c66
parent 15279 7ab5cf405686
child 15663 d92eeb468dad
equal deleted inserted replaced
13390:0135e64c6c66 15283:c4fd2813b127
     1 /*
       
     2  * MVL support routines for PhysicsFS.
       
     3  *
       
     4  * This driver handles Descent II Movielib archives.
       
     5  *
       
     6  * The file format of MVL is quite easy...
       
     7  *
       
     8  *   //MVL File format - Written by Heiko Herrmann
       
     9  *   char sig[4] = {'D','M', 'V', 'L'}; // "DMVL"=Descent MoVie Library
       
    10  *
       
    11  *   int num_files; // the number of files in this MVL
       
    12  *
       
    13  *   struct {
       
    14  *    char file_name[13]; // Filename, padded to 13 bytes with 0s
       
    15  *    int file_size; // filesize in bytes
       
    16  *   }DIR_STRUCT[num_files];
       
    17  *
       
    18  *   struct {
       
    19  *    char data[file_size]; // The file data
       
    20  *   }FILE_STRUCT[num_files];
       
    21  *
       
    22  * (That info is from http://www.descent2.com/ddn/specs/mvl/)
       
    23  *
       
    24  * Please see the file LICENSE.txt in the source's root directory.
       
    25  *
       
    26  *  This file written by Bradley Bell.
       
    27  *  Based on grp.c by Ryan C. Gordon.
       
    28  */
       
    29 
       
    30 #define __PHYSICSFS_INTERNAL__
       
    31 #include "physfs_internal.h"
       
    32 
       
    33 #if PHYSFS_SUPPORTS_MVL
       
    34 
       
    35 static UNPKentry *mvlLoadEntries(PHYSFS_Io *io, PHYSFS_uint32 fileCount)
       
    36 {
       
    37     PHYSFS_uint32 location = 8;  /* sizeof sig. */
       
    38     UNPKentry *entries = NULL;
       
    39     UNPKentry *entry = NULL;
       
    40 
       
    41     entries = (UNPKentry *) allocator.Malloc(sizeof (UNPKentry) * fileCount);
       
    42     BAIL_IF_MACRO(entries == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
       
    43 
       
    44     location += (17 * fileCount);
       
    45 
       
    46     for (entry = entries; fileCount > 0; fileCount--, entry++)
       
    47     {
       
    48         if (!__PHYSFS_readAll(io, &entry->name, 13)) goto failed;
       
    49         if (!__PHYSFS_readAll(io, &entry->size, 4)) goto failed;
       
    50         entry->size = PHYSFS_swapULE32(entry->size);
       
    51         entry->startPos = location;
       
    52         location += entry->size;
       
    53     } /* for */
       
    54 
       
    55     return entries;
       
    56 
       
    57 failed:
       
    58     allocator.Free(entries);
       
    59     return NULL;
       
    60 } /* mvlLoadEntries */
       
    61 
       
    62 
       
    63 static void *MVL_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
       
    64 {
       
    65     PHYSFS_uint8 buf[4];
       
    66     PHYSFS_uint32 count = 0;
       
    67     UNPKentry *entries = NULL;
       
    68 
       
    69     assert(io != NULL);  /* shouldn't ever happen. */
       
    70     BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
       
    71     BAIL_IF_MACRO(!__PHYSFS_readAll(io, buf, 4), ERRPASS, NULL);
       
    72     BAIL_IF_MACRO(memcmp(buf, "DMVL", 4) != 0, PHYSFS_ERR_UNSUPPORTED, NULL);
       
    73     BAIL_IF_MACRO(!__PHYSFS_readAll(io, &count, sizeof(count)), ERRPASS, NULL);
       
    74 
       
    75     count = PHYSFS_swapULE32(count);
       
    76     entries = mvlLoadEntries(io, count);
       
    77     return (!entries) ? NULL : UNPK_openArchive(io, entries, count);
       
    78 } /* MVL_openArchive */
       
    79 
       
    80 
       
    81 const PHYSFS_Archiver __PHYSFS_Archiver_MVL =
       
    82 {
       
    83     CURRENT_PHYSFS_ARCHIVER_API_VERSION,
       
    84     {
       
    85         "MVL",
       
    86         "Descent II Movielib format",
       
    87         "Bradley Bell <btb@icculus.org>",
       
    88         "https://icculus.org/physfs/",
       
    89         0,  /* supportsSymlinks */
       
    90     },
       
    91     MVL_openArchive,
       
    92     UNPK_enumerateFiles,
       
    93     UNPK_openRead,
       
    94     UNPK_openWrite,
       
    95     UNPK_openAppend,
       
    96     UNPK_remove,
       
    97     UNPK_mkdir,
       
    98     UNPK_stat,
       
    99     UNPK_closeArchive
       
   100 };
       
   101 
       
   102 #endif  /* defined PHYSFS_SUPPORTS_MVL */
       
   103 
       
   104 /* end of archiver_mvl.c ... */
       
   105