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
35static int mvlLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count, void *arc)
36{
37 PHYSFS_uint32 pos = 8 + (17 * count); /* past sig+metadata. */
38 PHYSFS_uint32 i;
39
40 for (i = 0; i < count; i++)
41 {
42 PHYSFS_uint32 size;
43 char name[13];
44 BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, name, 13), 0);
45 BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &size, 4), 0);
46 name[12] = '\0'; /* just in case. */
47 size = PHYSFS_swapULE32(size);
48 BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, -1, -1, pos, size), 0);
49 pos += size;
50 } /* for */
51
52 return 1;
53} /* mvlLoadEntries */
54
55
56static void *MVL_openArchive(PHYSFS_Io *io, const char *name,
57 int forWriting, int *claimed)
58{
59 PHYSFS_uint8 buf[4];
60 PHYSFS_uint32 count = 0;
61 void *unpkarc;
62
63 assert(io != NULL); /* shouldn't ever happen. */
64 BAIL_IF(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
65 BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, buf, 4), NULL);
66 BAIL_IF(memcmp(buf, "DMVL", 4) != 0, PHYSFS_ERR_UNSUPPORTED, NULL);
67
68 *claimed = 1;
69
70 BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &count, sizeof(count)), NULL);
71 count = PHYSFS_swapULE32(count);
72
73 unpkarc = UNPK_openArchive(io, 0, 1);
74 BAIL_IF_ERRPASS(!unpkarc, NULL);
75
76 if (!mvlLoadEntries(io, count, unpkarc))
77 {
78 UNPK_abandonArchive(unpkarc);
79 return NULL;
80 } /* if */
81
82 return unpkarc;
83} /* MVL_openArchive */
84
85
86const PHYSFS_Archiver __PHYSFS_Archiver_MVL =
87{
88 CURRENT_PHYSFS_ARCHIVER_API_VERSION,
89 {
90 "MVL",
91 "Descent II Movielib format",
92 "Bradley Bell <btb@icculus.org>",
93 "https://icculus.org/physfs/",
94 0, /* supportsSymlinks */
95 },
96 MVL_openArchive,
97 UNPK_enumerate,
98 UNPK_openRead,
99 UNPK_openWrite,
100 UNPK_openAppend,
101 UNPK_remove,
102 UNPK_mkdir,
103 UNPK_stat,
104 UNPK_closeArchive
105};
106
107#endif /* defined PHYSFS_SUPPORTS_MVL */
108
109/* end of physfs_archiver_mvl.c ... */
110
111