xoreos  0.0.5
erfwriter.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include <ctime>
26 
27 #include "src/aurora/erfwriter.h"
28 
29 namespace Aurora {
30 
31 static const uint32 kVersion10 = MKTAG('V', '1', '.', '0');
32 
34  LocString description) : _stream(stream), _currentFileCount(0), _fileCount(fileCount) {
35  if (version != kERFVersion10)
36  throw Common::Exception("Unsupported ERF version");
37 
38  stream.writeUint32BE(id);
39  stream.writeUint32BE(kVersion10);
40 
41  // Write Header
42  stream.writeUint32LE(description.getNumStrings()); // Language count
43  stream.writeUint32LE(description.getWrittenSize()); // Localized string size
44 
45  stream.writeUint32LE(_fileCount); // Entry Count
46 
47  // The size of the ERF header, which is immediately followed by the LocString table
48  static const uint32 kLocStringTableOffset = 160;
49 
50  _keyTableOffset = kLocStringTableOffset + description.getWrittenSize();
52 
53  stream.writeUint32LE(kLocStringTableOffset); // LocString offset
54  stream.writeUint32LE(_keyTableOffset); // Key List offset
55  stream.writeUint32LE(_resourceTableOffset); // Resource offset
56 
57  // Write the creation time of the file
58  std::time_t now = std::time(0);
59  std::tm *timepoint = std::localtime(&now);
60  stream.writeUint32LE(timepoint->tm_year);
61  stream.writeUint32LE(timepoint->tm_yday);
62 
63  // Write the description string reference
64  if (description.getNumStrings())
65  stream.writeUint32LE(description.getID());
66  else
67  stream.writeUint32LE(0);
68 
69  // Write 116 bytes of reserved header data
70  stream.writeZeros(116);
71 
72  // Write the Localized string table
73  description.writeLocString(stream);
74 
75  // Write the empty key list
76  stream.writeZeros(_fileCount * 24);
77 
78  // The offset to the resource table plus the size of the source table
80 
81  // Write the empty resource list
82  stream.writeZeros(8 * _fileCount);
83 }
84 
86 }
87 
88 void ERFWriter::add(const Common::UString &resRef, FileType resType, Common::ReadStream &stream) {
90  throw Common::Exception("More files added than expected");
91 
92  // Write the key table entry
94 
95  // Files without a type are put into ERF archives as the generic RES type
96  if (resType == kFileTypeNone)
97  resType = kFileTypeRES;
98 
99  /* Files with types above this line are not found in ERF archives.
100  * They have no real numerical type ID usable for ERF archives. */
101  if (resType >= kFileTypeMAXArchive)
102  resType = kFileTypeRES;
103 
104  // TODO: Handle file type aliases
105 
106  _stream.write(resRef.c_str(), MIN<size_t>(resRef.size(), 16));
107  _stream.writeZeros(16 - MIN<size_t>(resRef.size(), 16));
109  _stream.writeUint16LE(resType);
110  _stream.writeUint16LE(0); // Unused
111 
112  // Write the actual resource data
114  const size_t size = _stream.writeStream(stream);
115 
116  // Write the resource table entry
118 
120  _stream.writeUint32LE(size);
121 
122  // Advance data offset and file count
123  _offsetToResourceData += size;
124  _currentFileCount += 1;
125 }
126 
127 } // End of namespace Aurora
#define MKTAG(a0, a1, a2, a3)
A wrapper macro used around four character constants, like &#39;DATA&#39;, to ensure portability.
Definition: endianness.h:140
Generic interface for a readable data stream.
Definition: readstream.h:64
A class holding an UTF-8 string.
Definition: ustring.h:48
A localized string.
Definition: locstring.h:43
uint32 _currentFileCount
Definition: erfwriter.h:62
uint32 getID() const
Return the string ID / StrRef.
Definition: locstring.cpp:66
uint32 getWrittenSize(bool withNullTerminate=false) const
Get the size, the string table will consume after being written.
Definition: locstring.cpp:179
static const uint32 kVersion10
Definition: erfwriter.cpp:31
Generic GFF.
Definition: types.h:58
uint32 _resourceTableOffset
Definition: erfwriter.h:66
uint32 _fileCount
Definition: erfwriter.h:63
virtual size_t seek(ptrdiff_t offset, Origin whence=kOriginBegin)=0
Sets the stream position indicator for the stream.
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
ERFWriter(uint32 id, uint32 fileCount, Common::SeekableWriteStream &stream, Version version=kERFVersion10, LocString description=LocString())
Create an ERF writer by writing the header to the stream and reserve fileCount places in the key and ...
Definition: erfwriter.cpp:33
Writing BioWare&#39;s ERFs (encapsulated resource file).
The upper limit for numerical type IDs found in archives.
Definition: types.h:212
void writeUint16LE(uint16 value)
Definition: writestream.h:98
StackException Exception
Definition: error.h:59
virtual size_t write(const void *dataPtr, size_t dataSize)=0
Write data into the stream.
uint32 getNumStrings() const
Get the number of strings.
Definition: locstring.cpp:62
uint32 _keyTableOffset
Definition: erfwriter.h:65
Common::SeekableWriteStream & _stream
Definition: erfwriter.h:60
size_t size() const
Return the size of the string, in characters.
Definition: ustring.cpp:241
uint32_t uint32
Definition: types.h:204
size_t writeStream(ReadStream &stream, size_t n)
Copy n bytes of the given stream into the stream.
Definition: writestream.cpp:72
FileType
Various file types used by the Aurora engine and found in archives.
Definition: types.h:56
void add(const Common::UString &resRef, FileType resType, Common::ReadStream &stream)
Add a new stream to this archive to be packed.
Definition: erfwriter.cpp:88
void writeUint32BE(uint32 value)
Definition: writestream.h:122
FORCEINLINE void writeZeros(size_t n)
Write n zeros to the stream.
Definition: writestream.h:143
uint32 _offsetToResourceData
Definition: erfwriter.h:64
void writeUint32LE(uint32 value)
Definition: writestream.h:104
void writeLocString(Common::WriteStream &stream, bool withNullTerminate=false) const
Write the LocString to a write stream.
Definition: locstring.cpp:193