Skip to content

Commit 3c13d3d

Browse files
Add POD archiver.
1 parent b545573 commit 3c13d3d

File tree

5 files changed

+152
-1
lines changed

5 files changed

+152
-1
lines changed

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ set(PHYSFS_SRCS
100100
src/physfs_archiver_iso9660.c
101101
src/physfs_archiver_vdf.c
102102
src/physfs_archiver_lec3d.c
103+
src/physfs_archiver_pod.c
103104
${PHYSFS_CPP_SRCS}
104105
${PHYSFS_M_SRCS}
105106
)
@@ -169,6 +170,11 @@ if(NOT PHYSFS_ARCHIVE_LECARCHIVES)
169170
add_definitions(-DPHYSFS_SUPPORTS_LECARCHIVES=0)
170171
endif()
171172

173+
option(PHYSFS_ARCHIVE_POD "Enable Terminal Reality POD Archive support" TRUE)
174+
if(NOT PHYSFS_ARCHIVE_POD)
175+
add_definitions(-DPHYSFS_SUPPORTS_POD=0)
176+
endif()
177+
172178

173179
option(PHYSFS_BUILD_STATIC "Build static library" TRUE)
174180
if(PHYSFS_BUILD_STATIC)
@@ -341,6 +347,7 @@ message_bool_option("SLB support" PHYSFS_ARCHIVE_SLB)
341347
message_bool_option("VDF support" PHYSFS_ARCHIVE_VDF)
342348
message_bool_option("ISO9660 support" PHYSFS_ARCHIVE_ISO9660)
343349
message_bool_option("GOB/LAB/LFD support" PHYSFS_ARCHIVE_LECARCHIVES)
350+
message_bool_option("POD support" PHYSFS_ARCHIVE_POD)
344351
message_bool_option("Build static library" PHYSFS_BUILD_STATIC)
345352
message_bool_option("Build shared library" PHYSFS_BUILD_SHARED)
346353
message_bool_option("Build stdio test program" PHYSFS_BUILD_TEST)

src/Makefile.os2

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ SRCS = physfs.c &
2727
physfs_archiver_iso9660.c &
2828
physfs_archiver_csm.c &
2929
physfs_archiver_vdf.c &
30-
physfs_archiver_lec3d.c
30+
physfs_archiver_lec3d.c &
31+
physfs_archiver_pod.c
3132

3233

3334
OBJS = $(SRCS:.c=.obj)

src/physfs.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,6 +1205,9 @@ static int initStaticArchivers(void)
12051205
REGISTER_STATIC_ARCHIVER(LFD)
12061206
REGISTER_STATIC_ARCHIVER(LAB)
12071207
#endif
1208+
#if PHYSFS_SUPPORTS_POD
1209+
REGISTER_STATIC_ARCHIVER(POD)
1210+
#endif
12081211

12091212
#undef REGISTER_STATIC_ARCHIVER
12101213

src/physfs_archiver_pod.c

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* POD support routines for PhysicsFS.
3+
*
4+
* This driver handles Terminal Velocity POD archives.
5+
*
6+
* The POD format is as follows:
7+
*
8+
* While there is no known signature, the file starts with an
9+
* unsigned 32-bit integer with the file count, followed by
10+
* an 80-character, null-padded string with a description of
11+
* the pod file. The file entries follow, and are as such:
12+
*
13+
* struct {
14+
* char file_path[32]; // Full file path, IE: "ART\VGA.ACT"
15+
* uint32_t file_size; // filesize in bytes
16+
* uint32_t offset; // The offset of the data.
17+
* } fileEntry_t; // Once per file. The file data itself is at offset after all entries.
18+
*
19+
* (This info is from: https://moddingwiki.shikadi.net/wiki/POD_Format)
20+
*
21+
* There are other POD file formats, but they haven't been implemented yet.
22+
*
23+
* Please see the file LICENSE.txt in the source's root directory.
24+
*
25+
* This file written by Jordon Moss.
26+
*/
27+
28+
#define __PHYSICSFS_INTERNAL__
29+
#include "physfs_internal.h"
30+
31+
#if PHYSFS_SUPPORTS_POD
32+
33+
static int readui32(PHYSFS_Io *io, PHYSFS_uint32 *val)
34+
{
35+
PHYSFS_uint32 v;
36+
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &v, sizeof (v)), 0);
37+
*val = PHYSFS_swapULE32(v);
38+
return 1;
39+
} /* readui32 */
40+
41+
static void replaceChar(char* str, char oldChar, char newChar)
42+
{
43+
int i = 0;
44+
while (str[i] != '\0')
45+
{ // Iterate until the null terminator is found
46+
if (str[i] == oldChar)
47+
{
48+
str[i] = newChar; // Replace the character
49+
}
50+
i++;
51+
}
52+
}
53+
54+
static int pod1LoadEntries(PHYSFS_Io *io, void *arc)
55+
{
56+
PHYSFS_uint32 numfiles;
57+
PHYSFS_uint32 i;
58+
59+
BAIL_IF_ERRPASS(!readui32(io, &numfiles), 0);
60+
BAIL_IF_ERRPASS(!io->seek(io, 84), 0); /* skip past description */
61+
62+
for (i = 0; i < numfiles; i++) {
63+
char name[33];
64+
PHYSFS_uint32 size;
65+
PHYSFS_uint32 offset;
66+
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, name, 32), 0);
67+
BAIL_IF_ERRPASS(!readui32(io, &size), 0);
68+
BAIL_IF_ERRPASS(!readui32(io, &offset), 0);
69+
name[32] = '\0'; /* just in case */
70+
71+
replaceChar(name, '\\', '/');
72+
73+
BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, -1, -1, offset, size), 0);
74+
}
75+
76+
return 1;
77+
} /* pod1LoadEntries */
78+
79+
80+
static void *POD_openArchive(PHYSFS_Io *io, const char *name,
81+
int forWriting, int *claimed)
82+
{
83+
void *unpkarc = NULL;
84+
PHYSFS_uint32 dummy;
85+
char description[80];
86+
87+
assert(io != NULL); /* shouldn't ever happen. */
88+
BAIL_IF(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
89+
90+
BAIL_IF_ERRPASS(!readui32(io, &dummy), 0);
91+
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, description, 80), NULL);
92+
if ((description[0] == 0) || (description[79] != 0)) // Check if we're lacking a description or last char isn't a null terminator.
93+
return NULL;
94+
95+
io->seek(io, 0);
96+
97+
*claimed = 1;
98+
99+
unpkarc = UNPK_openArchive(io, 0, 1);
100+
BAIL_IF_ERRPASS(!unpkarc, NULL);
101+
102+
if (!(pod1LoadEntries(io, unpkarc)))
103+
{
104+
UNPK_abandonArchive(unpkarc);
105+
return NULL;
106+
} /* if */
107+
108+
return unpkarc;
109+
} /* POD_openArchive */
110+
111+
112+
const PHYSFS_Archiver __PHYSFS_Archiver_POD =
113+
{
114+
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
115+
{
116+
"POD",
117+
"Terminal Reality POD file format",
118+
"Jordon Moss <mossj32@gmail.com>",
119+
"https://icculus.org/physfs/",
120+
0, /* supportsSymlinks */
121+
},
122+
POD_openArchive,
123+
UNPK_enumerate,
124+
UNPK_openRead,
125+
UNPK_openWrite,
126+
UNPK_openAppend,
127+
UNPK_remove,
128+
UNPK_mkdir,
129+
UNPK_stat,
130+
UNPK_closeArchive
131+
};
132+
133+
#endif /* defined PHYSFS_SUPPORTS_POD */
134+
135+
/* end of physfs_archiver_pod.c ... */
136+

src/physfs_internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ extern const PHYSFS_Archiver __PHYSFS_Archiver_VDF;
9595
extern const PHYSFS_Archiver __PHYSFS_Archiver_GOB;
9696
extern const PHYSFS_Archiver __PHYSFS_Archiver_LFD;
9797
extern const PHYSFS_Archiver __PHYSFS_Archiver_LAB;
98+
extern const PHYSFS_Archiver __PHYSFS_Archiver_POD;
9899

99100
/* a real C99-compliant snprintf() is in Visual Studio 2015,
100101
but just use this everywhere for binary compatibility. */
@@ -227,6 +228,9 @@ void __PHYSFS_smallFree(void *ptr);
227228
#ifndef PHYSFS_SUPPORTS_LECARCHIVES
228229
#define PHYSFS_SUPPORTS_LECARCHIVES PHYSFS_SUPPORTS_DEFAULT
229230
#endif
231+
#ifndef PHYSFS_SUPPORTS_POD
232+
#define PHYSFS_SUPPORTS_POD PHYSFS_SUPPORTS_DEFAULT
233+
#endif
230234

231235

232236
#if PHYSFS_SUPPORTS_7Z

0 commit comments

Comments
 (0)