Skip to content

Commit

Permalink
AURORA: Use ScopedPtr/ScopedArray in our archive classes
Browse files Browse the repository at this point in the history
  • Loading branch information
DrMcCoy committed Oct 29, 2016
1 parent 9daedcc commit 18bc30c
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 146 deletions.
16 changes: 4 additions & 12 deletions src/aurora/biffile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,10 @@ namespace Aurora {
BIFFile::BIFFile(Common::SeekableReadStream *bif) : _bif(bif) {
assert(_bif);

try {
load(*_bif);
} catch (...) {
delete _bif;
throw;
}
load(*_bif);
}

BIFFile::~BIFFile() {
delete _bif;
}

void BIFFile::load(Common::SeekableReadStream &bif) {
Expand Down Expand Up @@ -109,14 +103,12 @@ Common::SeekableReadStream *BIFFile::getResource(uint32 index) const {

_bif->seek(res.offset);

Common::SeekableReadStream *resStream = _bif->readStream(res.size);
Common::ScopedPtr<Common::SeekableReadStream> resStream(_bif->readStream(res.size));

if (!resStream || (((uint32) resStream->size()) != res.size)) {
delete resStream;
if (!resStream || (((uint32) resStream->size()) != res.size))
throw Common::Exception(Common::kReadError);
}

return resStream;
return resStream.release();
}

} // End of namespace Aurora
3 changes: 2 additions & 1 deletion src/aurora/biffile.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define AURORA_BIFFILE_H

#include "src/common/types.h"
#include "src/common/scopedptr.h"

#include "src/aurora/types.h"
#include "src/aurora/aurorafile.h"
Expand Down Expand Up @@ -69,7 +70,7 @@ class BIFFile : public AuroraFile, public KEYDataFile {
Common::SeekableReadStream *getResource(uint32 index) const;

private:
Common::SeekableReadStream *_bif;
Common::ScopedPtr<Common::SeekableReadStream> _bif;

void load(Common::SeekableReadStream &bif);

Expand Down
39 changes: 10 additions & 29 deletions src/aurora/bzffile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,10 @@ namespace Aurora {
BZFFile::BZFFile(Common::SeekableReadStream *bzf) : _bzf(bzf) {
assert(_bzf);

try {
load(*_bzf);
} catch (...) {
delete _bzf;
throw;
}
load(*_bzf);
}

BZFFile::~BZFFile() {
delete _bzf;
}

void BZFFile::load(Common::SeekableReadStream &bzf) {
Expand Down Expand Up @@ -111,22 +105,11 @@ Common::SeekableReadStream *BZFFile::getResource(uint32 index) const {

_bzf->seek(res.offset);

byte *compressedData = new byte[res.packedSize];

Common::SeekableReadStream *resStream = 0;
try {
if (_bzf->read(compressedData, res.packedSize) != res.packedSize)
throw Common::Exception(Common::kReadError);

resStream = decompress(compressedData, res.packedSize, res.size);
Common::ScopedArray<byte> compressedData(new byte[res.packedSize]);
if (_bzf->read(compressedData.get(), res.packedSize) != res.packedSize)
throw Common::Exception(Common::kReadError);

} catch (...) {
delete[] compressedData;
throw;
}

delete[] compressedData;
return resStream;
return decompress(compressedData.get(), res.packedSize, res.size);
}

Common::SeekableReadStream *BZFFile::decompress(byte *compressedData, uint32 packedSize, uint32 unpackedSize) const {
Expand All @@ -150,25 +133,23 @@ Common::SeekableReadStream *BZFFile::decompress(byte *compressedData, uint32 pac
compressedData += propsSize;
packedSize -= propsSize;

byte *uncompressedData = new byte[unpackedSize];
Common::ScopedArray<byte> uncompressedData(new byte[unpackedSize]);
size_t posIn = 0, posOut = 0;

lzma_ret decodeRet = lzma_raw_buffer_decode(filters, 0,
compressedData , &posIn , packedSize,
uncompressedData, &posOut, unpackedSize);
compressedData , &posIn , packedSize,
uncompressedData.get(), &posOut, unpackedSize);

/* Ignore LZMA_DATA_ERROR and LZMA_BUF_ERROR thrown from the uncompressor.
* LZMA data in BZF may or may not contain an end marker.
* - If there is no end marker, LZMA_BUF_ERROR is thrown
* - If there is an end marker, LZMA_DATA_ERROR is thrown because we already
* know the size of the uncompressed data
*/
if ((decodeRet != LZMA_OK) && (decodeRet != LZMA_DATA_ERROR) && (decodeRet != LZMA_BUF_ERROR)) {
delete[] uncompressedData;
if ((decodeRet != LZMA_OK) && (decodeRet != LZMA_DATA_ERROR) && (decodeRet != LZMA_BUF_ERROR))
throw Common::Exception("Failed to uncompress LZMA data: %d", (int) decodeRet);
}

return new Common::MemoryReadStream(uncompressedData, unpackedSize, true);
return new Common::MemoryReadStream(uncompressedData.release(), unpackedSize, true);
}

} // End of namespace Aurora
3 changes: 2 additions & 1 deletion src/aurora/bzffile.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#define AURORA_BZFFILE_H

#include "src/common/types.h"
#include "src/common/scopedptr.h"

#include "src/aurora/types.h"
#include "src/aurora/aurorafile.h"
Expand All @@ -53,7 +54,7 @@ class BZFFile : public AuroraFile, public KEYDataFile {
Common::SeekableReadStream *getResource(uint32 index) const;

private:
Common::SeekableReadStream *_bzf;
Common::ScopedPtr<Common::SeekableReadStream> _bzf;

void load(Common::SeekableReadStream &bzf);

Expand Down
120 changes: 40 additions & 80 deletions src/aurora/erffile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,11 @@ static const byte kNWNPremiumKeys[][kNWNPremiumKeyLength] = {
};


ERFFile::ERFHeader::ERFHeader() : stringTable(0) {
ERFFile::ERFHeader::ERFHeader() {
clear();
}

ERFFile::ERFHeader::~ERFHeader() {
delete[] stringTable;
}

void ERFFile::ERFHeader::clear() {
Expand Down Expand Up @@ -124,9 +123,8 @@ void ERFFile::ERFHeader::clear() {
}

void ERFFile::ERFHeader::clearStringTable() {
delete[] stringTable;
stringTable.reset();

stringTable = 0;
stringTableSize = 0;
}

Expand All @@ -153,16 +151,10 @@ ERFFile::ERFFile(Common::SeekableReadStream *erf, const std::vector<byte> &passw

assert(_erf);

try {
load();
} catch (...) {
delete _erf;
throw;
}
load();
}

ERFFile::~ERFFile() {
delete _erf;
}

void ERFFile::verifyVersion(uint32 id, uint32 version, bool utf16le) {
Expand Down Expand Up @@ -217,19 +209,12 @@ void ERFFile::verifyPasswordDigest() {
buffer[i] = i;

Common::MemoryReadStream bufferStream(buffer, sizeof(buffer));
Common::SeekableReadStream *bufferEncrypted = Common::encryptBlowfishEBC(bufferStream, _password);

try {
Common::ScopedPtr<Common::SeekableReadStream>
bufferEncrypted(Common::encryptBlowfishEBC(bufferStream, _password));

if (!Common::compareMD5Digest(*bufferEncrypted, _header.passwordDigest))
throw Common::Exception("Password digest does not match");

} catch (...) {
delete bufferEncrypted;
throw;
}
if (!Common::compareMD5Digest(*bufferEncrypted, _header.passwordDigest))
throw Common::Exception("Password digest does not match");

delete bufferEncrypted;
return;
}

Expand All @@ -239,18 +224,10 @@ void ERFFile::verifyPasswordDigest() {
bool ERFFile::decryptNWNPremiumHeader(Common::SeekableReadStream &erf, ERFHeader &header,
const std::vector<byte> &password) {

Common::SeekableReadStream *decryptERF = decrypt(erf, erf.pos(), 152, kEncryptionBlowfishNWN, password);
Common::ScopedPtr<Common::SeekableReadStream>
decryptERF(decrypt(erf, erf.pos(), 152, kEncryptionBlowfishNWN, password));

try {

readV11Header(*decryptERF, header);

} catch (...) {
delete decryptERF;
throw;
}

delete decryptERF;
readV11Header(*decryptERF, header);

return header.isSensible(erf.size());
}
Expand Down Expand Up @@ -326,10 +303,7 @@ void ERFFile::decryptNWNPremium() {

_erf->seek(0);

Common::SeekableReadStream *decryptERF = decrypt(*_erf, kEncryptionBlowfishNWN, _password);

delete _erf;
_erf = decryptERF;
_erf.reset(decrypt(*_erf, kEncryptionBlowfishNWN, _password));

_header.encryption = kEncryptionNone;
}
Expand Down Expand Up @@ -426,8 +400,8 @@ void ERFFile::readV30Header(Common::SeekableReadStream &erf, ERFHeader &header,
if (erf.read(&header.passwordDigest[0], Common::kMD5Length) != Common::kMD5Length)
throw Common::Exception(Common::kReadError);

header.stringTable = new char[header.stringTableSize];
if (erf.read(header.stringTable, header.stringTableSize) != header.stringTableSize) {
header.stringTable.reset(new char[header.stringTableSize]);
if (erf.read(header.stringTable.get(), header.stringTableSize) != header.stringTableSize) {
header.clearStringTable();
throw Common::Exception("Failed to read ERF string table");
}
Expand Down Expand Up @@ -636,7 +610,7 @@ void ERFFile::readV30ResList(Common::SeekableReadStream &erf, const ERFHeader &h
if ((uint32)nameOffset >= header.stringTableSize)
throw Common::Exception("Invalid ERF string table offset");

Common::UString name = header.stringTable + nameOffset;
Common::UString name = header.stringTable.get() + nameOffset;
res->name = TypeMan.setFileType(name, kFileTypeNone);
res->type = TypeMan.getFileType(name);
}
Expand Down Expand Up @@ -689,7 +663,7 @@ Common::SeekableReadStream *ERFFile::getResource(uint32 index, bool tryNoCopy) c
const IResource &res = getIResource(index);

if (tryNoCopy && (_header.encryption == kEncryptionNone) && (_header.compression == kCompressionNone))
return new Common::SeekableSubReadStream(_erf, res.offset, res.offset + res.packedSize);
return new Common::SeekableSubReadStream(_erf.get(), res.offset, res.offset + res.packedSize);

_erf->seek(res.offset);

Expand Down Expand Up @@ -722,17 +696,9 @@ Common::MemoryReadStream *ERFFile::decrypt(Common::SeekableReadStream *cryptStre

assert(cryptStream);

Common::MemoryReadStream *decryptStream = 0;

try {
decryptStream = decrypt(*cryptStream, encryption, password);
} catch (...) {
delete cryptStream;
throw;
}
Common::ScopedPtr<Common::SeekableReadStream> stream(cryptStream);

delete cryptStream;
return decryptStream;
return decrypt(*stream, encryption, password);
}

Common::SeekableReadStream *ERFFile::decrypt(Common::SeekableReadStream &erf, size_t pos, size_t size,
Expand All @@ -749,63 +715,57 @@ Common::SeekableReadStream *ERFFile::decrypt(Common::SeekableReadStream &erf, si

Common::SeekableReadStream *ERFFile::decompress(Common::MemoryReadStream *packedStream,
uint32 unpackedSize) const {

Common::ScopedPtr<Common::MemoryReadStream> stream(packedStream);

switch (_header.compression) {
case kCompressionNone:
if (packedStream->size() == unpackedSize)
return packedStream;
if (stream->size() == unpackedSize)
return stream.release();

return new Common::SeekableSubReadStream(packedStream, 0, unpackedSize, true);
return new Common::SeekableSubReadStream(stream.release(), 0, unpackedSize, true);

case kCompressionBioWareZlib:
return decompressBiowareZlib(packedStream, unpackedSize);
return decompressBiowareZlib(stream.release(), unpackedSize);

case kCompressionHeaderlessZlib:
return decompressHeaderlessZlib(packedStream, unpackedSize);
return decompressHeaderlessZlib(stream.release(), unpackedSize);

default:
delete packedStream;
throw Common::Exception("Invalid ERF compression %u", (uint) _header.compression);
break;
}

throw Common::Exception("Invalid ERF compression %u", (uint) _header.compression);
}

Common::SeekableReadStream *ERFFile::decompressBiowareZlib(Common::MemoryReadStream *packedStream,
uint32 unpackedSize) const {

/* Decompress using raw inflate. An extra one byte header specifies the window size. */

const byte * const compressedData = packedStream->getData();
const uint32 packedSize = packedStream->size();
assert(packedStream);

Common::SeekableReadStream *stream = 0;
try {
stream = decompressZlib(compressedData + 1, packedSize - 1, unpackedSize, *compressedData >> 4);
} catch (...) {
delete packedStream;
throw;
}
Common::ScopedPtr<Common::MemoryReadStream> stream(packedStream);

delete packedStream;
return stream;
const byte * const compressedData = stream->getData();
const uint32 packedSize = stream->size();

return decompressZlib(compressedData + 1, packedSize - 1, unpackedSize, *compressedData >> 4);
}

Common::SeekableReadStream *ERFFile::decompressHeaderlessZlib(Common::MemoryReadStream *packedStream,
uint32 unpackedSize) const {

/* Decompress using raw inflate. Use the default maximum window size (15). */

const byte * const compressedData = packedStream->getData();
const uint32 packedSize = packedStream->size();
assert(packedStream);

Common::SeekableReadStream *stream = 0;
try {
stream = decompressZlib(compressedData, packedSize, unpackedSize, Common::kWindowBitsMax);
} catch (...) {
delete packedStream;
throw;
}
Common::ScopedPtr<Common::MemoryReadStream> stream(packedStream);

const byte * const compressedData = stream->getData();
const uint32 packedSize = stream->size();

delete packedStream;
return stream;
return decompressZlib(compressedData, packedSize, unpackedSize, Common::kWindowBitsMax);
}

Common::SeekableReadStream *ERFFile::decompressZlib(const byte *compressedData, uint32 packedSize,
Expand Down

0 comments on commit 18bc30c

Please sign in to comment.