Skip to content

Latest commit

 

History

History
132 lines (106 loc) · 3.92 KB

archiver_slb.c

File metadata and controls

132 lines (106 loc) · 3.92 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 16, 2017
Jul 16, 2017
28
29
30
31
PHYSFS_uint32 location;
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 16, 2017
Jul 16, 2017
49
50
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &location, 4), 0);
location = PHYSFS_swapULE32(location);
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 16, 2017
Jul 16, 2017
55
56
BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, location, size), 0);
} /* 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
62
63
64
} /* slbLoadEntries */
static void *SLB_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
{
PHYSFS_uint32 version;
Jul 16, 2017
Jul 16, 2017
65
66
67
PHYSFS_uint32 count;
PHYSFS_uint32 tocPos;
void *unpkarc;
Nov 12, 2012
Nov 12, 2012
68
Jul 20, 2017
Jul 20, 2017
69
70
71
72
73
74
75
/* 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
76
77
assert(io != NULL); /* shouldn't ever happen. */
Jul 6, 2017
Jul 6, 2017
78
BAIL_IF(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
Nov 12, 2012
Nov 12, 2012
79
Jul 16, 2017
Jul 16, 2017
80
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &version, sizeof (version)), NULL);
Nov 12, 2012
Nov 12, 2012
81
version = PHYSFS_swapULE32(version);
Jul 6, 2017
Jul 6, 2017
82
BAIL_IF(version != 0, PHYSFS_ERR_UNSUPPORTED, NULL);
Nov 12, 2012
Nov 12, 2012
83
Jul 16, 2017
Jul 16, 2017
84
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &count, sizeof (count)), NULL);
Nov 12, 2012
Nov 12, 2012
85
count = PHYSFS_swapULE32(count);
Jul 20, 2017
Jul 20, 2017
86
BAIL_IF(!count, PHYSFS_ERR_UNSUPPORTED, NULL);
Nov 12, 2012
Nov 12, 2012
87
88
/* offset of the table of contents */
Jul 16, 2017
Jul 16, 2017
89
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &tocPos, sizeof (tocPos)), NULL);
Nov 12, 2012
Nov 12, 2012
90
tocPos = PHYSFS_swapULE32(tocPos);
Jul 20, 2017
Jul 20, 2017
91
BAIL_IF(!tocPos, PHYSFS_ERR_UNSUPPORTED, NULL);
Nov 12, 2012
Nov 12, 2012
92
93
/* seek to the table of contents */
Jul 6, 2017
Jul 6, 2017
94
BAIL_IF_ERRPASS(!io->seek(io, tocPos), NULL);
Nov 12, 2012
Nov 12, 2012
95
Jul 21, 2017
Jul 21, 2017
96
unpkarc = UNPK_openArchive(io);
Jul 16, 2017
Jul 16, 2017
97
BAIL_IF_ERRPASS(!unpkarc, NULL);
Nov 12, 2012
Nov 12, 2012
98
Jul 16, 2017
Jul 16, 2017
99
100
101
102
103
104
105
if (!slbLoadEntries(io, count, unpkarc))
{
UNPK_closeArchive(unpkarc);
return NULL;
} /* if */
return unpkarc;
Nov 12, 2012
Nov 12, 2012
106
107
108
109
110
} /* SLB_openArchive */
const PHYSFS_Archiver __PHYSFS_Archiver_SLB =
{
Nov 28, 2012
Nov 28, 2012
111
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
Nov 12, 2012
Nov 12, 2012
112
113
114
115
{
"SLB",
"I-War / Independence War Slab file",
"Aleksi Nurmi <aleksi.nurmi@gmail.com>",
Feb 25, 2016
Feb 25, 2016
116
"https://bitbucket.org/ahnurmi/",
Nov 30, 2012
Nov 30, 2012
117
0, /* supportsSymlinks */
Nov 12, 2012
Nov 12, 2012
118
},
Nov 30, 2012
Nov 30, 2012
119
120
121
122
123
124
125
SLB_openArchive,
UNPK_enumerateFiles,
UNPK_openRead,
UNPK_openWrite,
UNPK_openAppend,
UNPK_remove,
UNPK_mkdir,
Nov 30, 2012
Nov 30, 2012
126
127
UNPK_stat,
UNPK_closeArchive
Nov 12, 2012
Nov 12, 2012
128
129
130
};
#endif /* defined PHYSFS_SUPPORTS_SLB */
Nov 27, 2012
Nov 27, 2012
131
132
/* end of archiver_slb.c ... */