Skip to content

Latest commit

 

History

History
135 lines (108 loc) · 3.98 KB

physfs_archiver_slb.c

File metadata and controls

135 lines (108 loc) · 3.98 KB
 
Nov 12, 2012
Nov 12, 2012
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
* SLB support routines for PhysicsFS.
*
* This driver handles SLB archives ("slab files"). This uncompressed format
* is used in I-War / Independence War and Independence War: Defiance.
*
* The format begins with four zero bytes (version?), the file count and the
* location of the table of contents. Each ToC entry contains a 64-byte buffer
* containing a zero-terminated filename, the offset of the data, and its size.
* All the filenames begin with the separator character '\'.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Aleksi Nurmi, based on the GRP archiver by
* Ryan C. Gordon.
*/
#define __PHYSICSFS_INTERNAL__
#include "physfs_internal.h"
#if PHYSFS_SUPPORTS_SLB
Jul 16, 2017
Jul 16, 2017
23
static int slbLoadEntries(PHYSFS_Io *io, const PHYSFS_uint32 count, void *arc)
Nov 12, 2012
Nov 12, 2012
24
{
Jul 16, 2017
Jul 16, 2017
25
26
PHYSFS_uint32 i;
for (i = 0; i < count; i++)
Nov 12, 2012
Nov 12, 2012
27
{
Jul 22, 2017
Jul 22, 2017
28
PHYSFS_uint32 pos;
Jul 16, 2017
Jul 16, 2017
29
30
31
PHYSFS_uint32 size;
char name[64];
char backslash;
Nov 12, 2012
Nov 12, 2012
32
33
34
char *ptr;
/* don't include the '\' in the beginning */
Jul 16, 2017
Jul 16, 2017
35
36
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &backslash, 1), 0);
BAIL_IF(backslash != '\\', PHYSFS_ERR_CORRUPT, 0);
Nov 12, 2012
Nov 12, 2012
37
38
/* read the rest of the buffer, 63 bytes */
Jul 16, 2017
Jul 16, 2017
39
40
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &name, 63), 0);
name[63] = '\0'; /* in case the name lacks the null terminator */
Nov 12, 2012
Nov 12, 2012
41
42
/* convert backslashes */
Jul 16, 2017
Jul 16, 2017
43
for (ptr = name; *ptr; ptr++)
Nov 12, 2012
Nov 12, 2012
44
45
46
47
48
{
if (*ptr == '\\')
*ptr = '/';
} /* for */
Jul 22, 2017
Jul 22, 2017
49
50
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &pos, 4), 0);
pos = PHYSFS_swapULE32(pos);
Nov 12, 2012
Nov 12, 2012
51
Jul 16, 2017
Jul 16, 2017
52
53
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &size, 4), 0);
size = PHYSFS_swapULE32(size);
Nov 12, 2012
Nov 12, 2012
54
Jul 22, 2017
Jul 22, 2017
55
BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, -1, -1, pos, size), 0);
Jul 16, 2017
Jul 16, 2017
56
} /* for */
Nov 12, 2012
Nov 12, 2012
57
Jul 16, 2017
Jul 16, 2017
58
return 1;
Nov 12, 2012
Nov 12, 2012
59
60
61
} /* slbLoadEntries */
Aug 14, 2017
Aug 14, 2017
62
63
static void *SLB_openArchive(PHYSFS_Io *io, const char *name,
int forWriting, int *claimed)
Nov 12, 2012
Nov 12, 2012
64
65
{
PHYSFS_uint32 version;
Jul 16, 2017
Jul 16, 2017
66
67
68
PHYSFS_uint32 count;
PHYSFS_uint32 tocPos;
void *unpkarc;
Nov 12, 2012
Nov 12, 2012
69
Jul 20, 2017
Jul 20, 2017
70
71
72
73
74
75
76
/* There's no identifier on an SLB file, so we assume it's _not_ if the
file count or tocPos is zero. Beyond that, we'll assume it's
bogus/corrupt if the entries' filenames don't start with '\' or the
tocPos is past the end of the file (seek will fail). This probably
covers all meaningful cases where we would accidentally accept a non-SLB
file with this archiver. */
Nov 12, 2012
Nov 12, 2012
77
78
assert(io != NULL); /* shouldn't ever happen. */
Jul 6, 2017
Jul 6, 2017
79
BAIL_IF(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
Nov 12, 2012
Nov 12, 2012
80
Jul 16, 2017
Jul 16, 2017
81
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &version, sizeof (version)), NULL);
Nov 12, 2012
Nov 12, 2012
82
version = PHYSFS_swapULE32(version);
Jul 6, 2017
Jul 6, 2017
83
BAIL_IF(version != 0, PHYSFS_ERR_UNSUPPORTED, NULL);
Nov 12, 2012
Nov 12, 2012
84
Jul 16, 2017
Jul 16, 2017
85
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &count, sizeof (count)), NULL);
Nov 12, 2012
Nov 12, 2012
86
count = PHYSFS_swapULE32(count);
Jul 20, 2017
Jul 20, 2017
87
BAIL_IF(!count, PHYSFS_ERR_UNSUPPORTED, NULL);
Nov 12, 2012
Nov 12, 2012
88
89
/* offset of the table of contents */
Jul 16, 2017
Jul 16, 2017
90
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &tocPos, sizeof (tocPos)), NULL);
Nov 12, 2012
Nov 12, 2012
91
tocPos = PHYSFS_swapULE32(tocPos);
Jul 20, 2017
Jul 20, 2017
92
BAIL_IF(!tocPos, PHYSFS_ERR_UNSUPPORTED, NULL);
Nov 12, 2012
Nov 12, 2012
93
94
/* seek to the table of contents */
Jul 6, 2017
Jul 6, 2017
95
BAIL_IF_ERRPASS(!io->seek(io, tocPos), NULL);
Nov 12, 2012
Nov 12, 2012
96
Jul 21, 2017
Jul 21, 2017
97
unpkarc = UNPK_openArchive(io);
Jul 16, 2017
Jul 16, 2017
98
BAIL_IF_ERRPASS(!unpkarc, NULL);
Nov 12, 2012
Nov 12, 2012
99
Jul 16, 2017
Jul 16, 2017
100
101
if (!slbLoadEntries(io, count, unpkarc))
{
Jul 21, 2017
Jul 21, 2017
102
UNPK_abandonArchive(unpkarc);
Jul 16, 2017
Jul 16, 2017
103
104
105
return NULL;
} /* if */
Aug 14, 2017
Aug 14, 2017
106
107
*claimed = 1; /* oh well. */
Jul 16, 2017
Jul 16, 2017
108
return unpkarc;
Nov 12, 2012
Nov 12, 2012
109
110
111
112
113
} /* SLB_openArchive */
const PHYSFS_Archiver __PHYSFS_Archiver_SLB =
{
Nov 28, 2012
Nov 28, 2012
114
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
Nov 12, 2012
Nov 12, 2012
115
116
117
118
{
"SLB",
"I-War / Independence War Slab file",
"Aleksi Nurmi <aleksi.nurmi@gmail.com>",
Feb 25, 2016
Feb 25, 2016
119
"https://bitbucket.org/ahnurmi/",
Nov 30, 2012
Nov 30, 2012
120
0, /* supportsSymlinks */
Nov 12, 2012
Nov 12, 2012
121
},
Nov 30, 2012
Nov 30, 2012
122
SLB_openArchive,
Aug 12, 2017
Aug 12, 2017
123
UNPK_enumerate,
Nov 30, 2012
Nov 30, 2012
124
125
126
127
128
UNPK_openRead,
UNPK_openWrite,
UNPK_openAppend,
UNPK_remove,
UNPK_mkdir,
Nov 30, 2012
Nov 30, 2012
129
130
UNPK_stat,
UNPK_closeArchive
Nov 12, 2012
Nov 12, 2012
131
132
133
};
#endif /* defined PHYSFS_SUPPORTS_SLB */
Nov 27, 2012
Nov 27, 2012
134
Jul 22, 2017
Jul 22, 2017
135
/* end of physfs_archiver_slb.c ... */