xoreos  0.0.5
rimfile.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 <cassert>
26 
27 #include "src/common/util.h"
28 #include "src/common/strutil.h"
30 #include "src/common/error.h"
31 #include "src/common/encoding.h"
32 
33 #include "src/aurora/rimfile.h"
34 
35 static const uint32 kRIMID = MKTAG('R', 'I', 'M', ' ');
36 static const uint32 kVersion1 = MKTAG('V', '1', '.', '0');
37 
38 namespace Aurora {
39 
41  assert(_rim);
42 
43  load(*_rim);
44 }
45 
47 }
48 
50  readHeader(rim);
51 
52  if (_id != kRIMID)
53  throw Common::Exception("Not a RIM file (%s)", Common::debugTag(_id).c_str());
54 
55  if (_version != kVersion1)
56  throw Common::Exception("Unsupported RIM file version %s", Common::debugTag(_version).c_str());
57 
58  rim.skip(4); // Reserved
59  uint32 resCount = rim.readUint32LE(); // Number of resources in the RIM
60  uint32 offResList = rim.readUint32LE(); // Offset to the resource list
61 
62  _resources.resize(resCount);
63  _iResources.resize(resCount);
64 
65  try {
66 
67  // Read the resource list
68  readResList(rim, offResList);
69 
70  } catch (Common::Exception &e) {
71  e.add("Failed reading RIM file");
72  throw;
73  }
74 
75 }
76 
78  rim.seek(offset);
79 
80  uint32 index = 0;
81  ResourceList::iterator res = _resources.begin();
82  IResourceList::iterator iRes = _iResources.begin();
83  for (; (res != _resources.end()) && (iRes != _iResources.end()); ++index, ++res, ++iRes) {
84  res->name = Common::readStringFixed(rim, Common::kEncodingASCII, 16);
85  res->type = (FileType) rim.readUint16LE();
86  res->index = index;
87  rim.skip(4 + 2); // Resource ID + Reserved
88  iRes->offset = rim.readUint32LE();
89  iRes->size = rim.readUint32LE();
90  }
91 }
92 
94  return _resources;
95 }
96 
98  if (index >= _iResources.size())
99  throw Common::Exception("Resource index out of range (%u/%u)", index, (uint)_iResources.size());
100 
101  return _iResources[index];
102 }
103 
105  return getIResource(index).size;
106 }
107 
109  const IResource &res = getIResource(index);
110 
111  if (tryNoCopy)
112  return new Common::SeekableSubReadStream(_rim.get(), res.offset, res.offset + res.size);
113 
114  _rim->seek(res.offset);
115 
116  return _rim->readStream(res.size);
117 }
118 
119 } // 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
uint16 readUint16LE()
Read an unsigned 16-bit word stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:122
void add(const char *s,...) GCC_PRINTF(2
Definition: error.cpp:58
Common::SeekableReadStream * getResource(uint32 index, bool tryNoCopy=false) const
Return a stream of the resource&#39;s contents.
Definition: rimfile.cpp:108
uint32 readUint32LE()
Read an unsigned 32-bit word stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:133
ResourceList _resources
External list of resource names and types.
Definition: rimfile.h:88
virtual size_t seek(ptrdiff_t offset, Origin whence=kOriginBegin)=0
Sets the stream position indicator for the stream.
void readResList(Common::SeekableReadStream &rim, uint32 offset)
Definition: rimfile.cpp:77
Handling BioWare&#39;s RIMs (resource archives).
const IResource & getIResource(uint32 index) const
Definition: rimfile.cpp:97
static const uint32 kVersion1
Definition: rimfile.cpp:36
Implementing the reading stream interfaces for plain memory blocks.
uint32 getResourceSize(uint32 index) const
Return the size of a resource.
Definition: rimfile.cpp:104
uint32 offset
The offset of the resource within the RIM.
Definition: rimfile.h:79
Utility templates and functions for working with strings and streams.
Exception that provides a stack of explanations.
Definition: error.h:36
static void readHeader(Common::ReadStream &stream, uint32 &id, uint32 &version, bool &utf16le)
Read the header out of a stream.
Definition: aurorafile.cpp:53
Basic exceptions to throw.
Utility templates and functions.
std::list< Resource > ResourceList
Definition: archive.h:57
Internal resource information.
Definition: rimfile.h:78
virtual size_t skip(ptrdiff_t offset)
Skip the specified number of bytes, adding that offset to the current position in the stream...
Definition: readstream.h:317
Utility functions for working with differing string encodings.
uint32 _id
The file&#39;s ID.
Definition: aurorafile.h:77
StackException Exception
Definition: error.h:59
uint32 _version
The file&#39;s version.
Definition: aurorafile.h:78
const ResourceList & getResources() const
Return the list of resources.
Definition: rimfile.cpp:93
Plain, unextended ASCII (7bit clean).
Definition: encoding.h:40
PointerType get() const
Returns the plain pointer value.
Definition: scopedptr.h:96
static const uint32 kRIMID
Definition: rimfile.cpp:35
IResourceList _iResources
Internal list of resource offsets and sizes.
Definition: rimfile.h:91
uint32_t uint32
Definition: types.h:204
UString debugTag(uint32 tag, bool trim)
Create an elaborate string from an integer tag, for debugging purposes.
Definition: strutil.cpp:117
Common::ScopedPtr< Common::SeekableReadStream > _rim
Definition: rimfile.h:85
FileType
Various file types used by the Aurora engine and found in archives.
Definition: types.h:56
UString readStringFixed(SeekableReadStream &stream, Encoding encoding, size_t length)
Read length bytes as a string with the given encoding out of a stream.
Definition: encoding.cpp:297
SeekableSubReadStream provides access to a SeekableReadStream restricted to the range [begin...
Definition: readstream.h:359
RIMFile(Common::SeekableReadStream *rim)
Take over this stream and read a RIM file out of it.
Definition: rimfile.cpp:40
Interface for a seekable & readable data stream.
Definition: readstream.h:265
uint32 size
The resource&#39;s size.
Definition: rimfile.h:80
unsigned int uint
Definition: types.h:211
void load(Common::SeekableReadStream &rim)
Definition: rimfile.cpp:49