/* xoreos-tools - Tools to help with xoreos development
 *
 * xoreos-tools is the legal property of its developers, whose names
 * can be found in the AUTHORS file distributed with this source
 * distribution.
 *
 * xoreos-tools is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 3
 * of the License, or (at your option) any later version.
 *
 * xoreos-tools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with xoreos-tools. If not, see <http://www.gnu.org/licenses/>.
 */

/** @file
 *  Unit tests for our ERF file archive class.
 */

#include "gtest/gtest.h"

#include "src/common/error.h"
#include "src/common/hash.h"
#include "src/common/memreadstream.h"

#include "src/aurora/locstring.h"
#include "src/aurora/language.h"
#include "src/aurora/erffile.h"

/** Utility class to hold an ERF password by copying from a static array. */
class PasswordStore : public std::vector<byte> {
public:
	template<size_t N>
	PasswordStore(const byte (&array)[N]) : std::vector<byte>(array, array + N) {
	}
};

// Percy Bysshe Shelley's "Ozymandias"
static const char *kFileData =
	"I met a traveller from an antique land\n"
	"Who said: Two vast and trunkless legs of stone\n"
	"Stand in the desert. Near them, on the sand,\n"
	"Half sunk, a shattered visage lies, whose frown,\n"
	"And wrinkled lip, and sneer of cold command,\n"
	"Tell that its sculptor well those passions read\n"
	"Which yet survive, stamped on these lifeless things,\n"
	"The hand that mocked them and the heart that fed:\n"
	"And on the pedestal these words appear:\n"
	"'My name is Ozymandias, king of kings:\n"
	"Look on my works, ye Mighty, and despair!'\n"
	"Nothing beside remains. Round the decay\n"
	"Of that colossal wreck, boundless and bare\n"
	"The lone and level sands stretch far away.";

// --- ERF V1.0 ---

// Percy Bysshe Shelley's "Ozymandias", within an ERF V1.0 file
static const byte kERFFile10[] = {
	0x45,0x52,0x46,0x20,0x56,0x31,0x2E,0x30,0x01,0x00,0x00,0x00,0x18,0x00,0x00,0x00,
	0x01,0x00,0x00,0x00,0xA0,0x00,0x00,0x00,0xB8,0x00,0x00,0x00,0xD0,0x00,0x00,0x00,
	0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x78,0x6F,0x72,0x65,0x6F,0x73,0x20,0x75,
	0x6E,0x69,0x74,0x20,0x74,0x65,0x73,0x74,0x6F,0x7A,0x79,0x6D,0x61,0x6E,0x64,0x69,
	0x61,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,
	0xD8,0x00,0x00,0x00,0x6F,0x02,0x00,0x00,0x49,0x20,0x6D,0x65,0x74,0x20,0x61,0x20,
	0x74,0x72,0x61,0x76,0x65,0x6C,0x6C,0x65,0x72,0x20,0x66,0x72,0x6F,0x6D,0x20,0x61,
	0x6E,0x20,0x61,0x6E,0x74,0x69,0x71,0x75,0x65,0x20,0x6C,0x61,0x6E,0x64,0x0A,0x57,
	0x68,0x6F,0x20,0x73,0x61,0x69,0x64,0x3A,0x20,0x54,0x77,0x6F,0x20,0x76,0x61,0x73,
	0x74,0x20,0x61,0x6E,0x64,0x20,0x74,0x72,0x75,0x6E,0x6B,0x6C,0x65,0x73,0x73,0x20,
	0x6C,0x65,0x67,0x73,0x20,0x6F,0x66,0x20,0x73,0x74,0x6F,0x6E,0x65,0x0A,0x53,0x74,
	0x61,0x6E,0x64,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x64,0x65,0x73,0x65,0x72,
	0x74,0x2E,0x20,0x4E,0x65,0x61,0x72,0x20,0x74,0x68,0x65,0x6D,0x2C,0x20,0x6F,0x6E,
	0x20,0x74,0x68,0x65,0x20,0x73,0x61,0x6E,0x64,0x2C,0x0A,0x48,0x61,0x6C,0x66,0x20,
	0x73,0x75,0x6E,0x6B,0x2C,0x20,0x61,0x20,0x73,0x68,0x61,0x74,0x74,0x65,0x72,0x65,
	0x64,0x20,0x76,0x69,0x73,0x61,0x67,0x65,0x20,0x6C,0x69,0x65,0x73,0x2C,0x20,0x77,
	0x68,0x6F,0x73,0x65,0x20,0x66,0x72,0x6F,0x77,0x6E,0x2C,0x0A,0x41,0x6E,0x64,0x20,
	0x77,0x72,0x69,0x6E,0x6B,0x6C,0x65,0x64,0x20,0x6C,0x69,0x70,0x2C,0x20,0x61,0x6E,
	0x64,0x20,0x73,0x6E,0x65,0x65,0x72,0x20,0x6F,0x66,0x20,0x63,0x6F,0x6C,0x64,0x20,
	0x63,0x6F,0x6D,0x6D,0x61,0x6E,0x64,0x2C,0x0A,0x54,0x65,0x6C,0x6C,0x20,0x74,0x68,
	0x61,0x74,0x20,0x69,0x74,0x73,0x20,0x73,0x63,0x75,0x6C,0x70,0x74,0x6F,0x72,0x20,
	0x77,0x65,0x6C,0x6C,0x20,0x74,0x68,0x6F,0x73,0x65,0x20,0x70,0x61,0x73,0x73,0x69,
	0x6F,0x6E,0x73,0x20,0x72,0x65,0x61,0x64,0x0A,0x57,0x68,0x69,0x63,0x68,0x20,0x79,
	0x65,0x74,0x20,0x73,0x75,0x72,0x76,0x69,0x76,0x65,0x2C,0x20,0x73,0x74,0x61,0x6D,
	0x70,0x65,0x64,0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,0x73,0x65,0x20,0x6C,0x69,0x66,
	0x65,0x6C,0x65,0x73,0x73,0x20,0x74,0x68,0x69,0x6E,0x67,0x73,0x2C,0x0A,0x54,0x68,
	0x65,0x20,0x68,0x61,0x6E,0x64,0x20,0x74,0x68,0x61,0x74,0x20,0x6D,0x6F,0x63,0x6B,
	0x65,0x64,0x20,0x74,0x68,0x65,0x6D,0x20,0x61,0x6E,0x64,0x20,0x74,0x68,0x65,0x20,
	0x68,0x65,0x61,0x72,0x74,0x20,0x74,0x68,0x61,0x74,0x20,0x66,0x65,0x64,0x3A,0x0A,
	0x41,0x6E,0x64,0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,0x20,0x70,0x65,0x64,0x65,0x73,
	0x74,0x61,0x6C,0x20,0x74,0x68,0x65,0x73,0x65,0x20,0x77,0x6F,0x72,0x64,0x73,0x20,
	0x61,0x70,0x70,0x65,0x61,0x72,0x3A,0x0A,0x27,0x4D,0x79,0x20,0x6E,0x61,0x6D,0x65,
	0x20,0x69,0x73,0x20,0x4F,0x7A,0x79,0x6D,0x61,0x6E,0x64,0x69,0x61,0x73,0x2C,0x20,
	0x6B,0x69,0x6E,0x67,0x20,0x6F,0x66,0x20,0x6B,0x69,0x6E,0x67,0x73,0x3A,0x0A,0x4C,
	0x6F,0x6F,0x6B,0x20,0x6F,0x6E,0x20,0x6D,0x79,0x20,0x77,0x6F,0x72,0x6B,0x73,0x2C,
	0x20,0x79,0x65,0x20,0x4D,0x69,0x67,0x68,0x74,0x79,0x2C,0x20,0x61,0x6E,0x64,0x20,
	0x64,0x65,0x73,0x70,0x61,0x69,0x72,0x21,0x27,0x0A,0x4E,0x6F,0x74,0x68,0x69,0x6E,
	0x67,0x20,0x62,0x65,0x73,0x69,0x64,0x65,0x20,0x72,0x65,0x6D,0x61,0x69,0x6E,0x73,
	0x2E,0x20,0x52,0x6F,0x75,0x6E,0x64,0x20,0x74,0x68,0x65,0x20,0x64,0x65,0x63,0x61,
	0x79,0x0A,0x4F,0x66,0x20,0x74,0x68,0x61,0x74,0x20,0x63,0x6F,0x6C,0x6F,0x73,0x73,
	0x61,0x6C,0x20,0x77,0x72,0x65,0x63,0x6B,0x2C,0x20,0x62,0x6F,0x75,0x6E,0x64,0x6C,
	0x65,0x73,0x73,0x20,0x61,0x6E,0x64,0x20,0x62,0x61,0x72,0x65,0x0A,0x54,0x68,0x65,
	0x20,0x6C,0x6F,0x6E,0x65,0x20,0x61,0x6E,0x64,0x20,0x6C,0x65,0x76,0x65,0x6C,0x20,
	0x73,0x61,0x6E,0x64,0x73,0x20,0x73,0x74,0x72,0x65,0x74,0x63,0x68,0x20,0x66,0x61,
	0x72,0x20,0x61,0x77,0x61,0x79,0x2E
};

GTEST_TEST(ERFFile10, getNameHashAlgo) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile10));

	EXPECT_EQ(erf.getNameHashAlgo(), Common::kHashNone);
}

GTEST_TEST(ERFFile10, getBuildYear) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile10));

	EXPECT_EQ(erf.getBuildYear(), 2000);
}

GTEST_TEST(ERFFile10, getBuildDay) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile10));

	EXPECT_EQ(erf.getBuildDay(), 23);
}

GTEST_TEST(ERFFile10, getDescription) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile10));

	const Aurora::LocString &description = erf.getDescription();

	EXPECT_EQ(description.getID(), 0);
	EXPECT_STREQ(description.getString().c_str(), "xoreos unit test");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile10, getDescriptionStatic) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	Common::MemoryReadStream stream(kERFFile10);

	Aurora::LocString description = Aurora::ERFFile::getDescription(stream);

	EXPECT_EQ(description.getID(), 0);
	EXPECT_STREQ(description.getString().c_str(), "xoreos unit test");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile10, getResources) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile10));

	const Aurora::ERFFile::ResourceList &resources = erf.getResources();
	ASSERT_EQ(resources.size(), 1);

	const Aurora::ERFFile::Resource &resource = *resources.begin();

	EXPECT_STREQ(resource.name.c_str(), "ozymandias");
	EXPECT_EQ(resource.type, Aurora::kFileTypeTXT);
	EXPECT_EQ(resource.hash, 0);
	EXPECT_EQ(resource.index, 0);
}

GTEST_TEST(ERFFile10, getResourceSize) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile10));

	EXPECT_EQ(erf.getResourceSize(0), strlen(kFileData));

	EXPECT_THROW(erf.getResourceSize(1), Common::Exception);
}

GTEST_TEST(ERFFile10, findResourceHash) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile10));

	EXPECT_EQ(erf.findResource(0), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile10, findResourceName) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile10));

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeTXT), 0);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeBMP), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeBMP), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile10, getResource) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile10));

	Common::SeekableReadStream *file = erf.getResource(0);
	ASSERT_NE(file, static_cast<Common::SeekableReadStream *>(0));

	ASSERT_EQ(file->size(), strlen(kFileData));

	for (size_t i = 0; i < strlen(kFileData); i++)
		EXPECT_EQ(file->readByte(), kFileData[i]) << "At index " << i;

	delete file;
}

GTEST_TEST(ERFFile10, typeMOD) {
	static const byte kERF[] = {
		0x4D,0x4F,0x44,0x20,0x56,0x31,0x2E,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
	};

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERF));

	EXPECT_EQ(erf.getBuildDay(), 23);
	EXPECT_EQ(erf.getBuildYear(), 2000);

	EXPECT_EQ(erf.getResources().size(), 0);
}

GTEST_TEST(ERFFile10, typeHAK) {
	static const byte kERF[] = {
		0x48,0x41,0x4B,0x20,0x56,0x31,0x2E,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
	};

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERF));

	EXPECT_EQ(erf.getBuildDay(), 23);
	EXPECT_EQ(erf.getBuildYear(), 2000);

	EXPECT_EQ(erf.getResources().size(), 0);
}

GTEST_TEST(ERFFile10, typeSAV) {
	static const byte kERF[] = {
		0x53,0x41,0x56,0x20,0x56,0x31,0x2E,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
	};

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERF));

	EXPECT_EQ(erf.getBuildDay(), 23);
	EXPECT_EQ(erf.getBuildYear(), 2000);

	EXPECT_EQ(erf.getResources().size(), 0);
}

// --- ERF V1.1 (NWN, encrypted) ---

// Percy Bysshe Shelley's "Ozymandias", within an ERF V1.1 (NWN, encrypted) file
static const byte kERFFile11NWN[] = {
	0x45,0x52,0x46,0x20,0x56,0x31,0x2E,0x31,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
	0x2F,0x73,0x1C,0x91,0x5A,0xF8,0x0D,0x2E,0xA1,0x40,0xF1,0x78,0x9C,0xC1,0x6C,0x3A,
	0xBA,0x71,0xE4,0x49,0x18,0x4A,0x40,0xD6,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
	0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
	0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
	0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
	0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
	0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
	0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
	0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
	0xFF,0xDF,0x03,0xA5,0x6D,0x62,0x74,0x6C,0xAF,0x8A,0x53,0x12,0xF5,0x11,0xF2,0x80,
	0xF5,0x23,0x25,0x15,0xC7,0xE9,0x12,0xD8,0xA2,0x6B,0x2F,0xC9,0xF8,0x77,0xF4,0x9F,
	0xA5,0xCE,0x3A,0x47,0x6E,0x57,0xAC,0xBE,0xE6,0xA1,0xA4,0x45,0x01,0x04,0x73,0xCF,
	0xC5,0xA3,0xCB,0x3F,0x5E,0xE2,0x11,0x4B,0x7A,0x19,0x94,0xFC,0xD7,0xA0,0xE0,0x04,
	0xC1,0xD1,0xF8,0x1C,0x0B,0x75,0xCA,0x9D,0x31,0xFC,0xA6,0x48,0x07,0xBF,0x3B,0x73,
	0xB7,0x3C,0x3D,0x73,0x30,0x2F,0x97,0x7E,0xA6,0x41,0xC5,0xB9,0xFA,0x68,0x19,0x55,
	0x30,0x0D,0x15,0x22,0xBE,0x71,0x8A,0xE8,0xA2,0xC3,0xBF,0x54,0xD7,0x4D,0x85,0xC0,
	0x38,0xFE,0x50,0x65,0xDB,0x19,0x22,0xD2,0x31,0x22,0x8A,0xE9,0xEE,0x02,0xE3,0xDE,
	0x92,0x6C,0x4F,0x3F,0x66,0x35,0xBB,0x9C,0x68,0xE6,0x01,0xC4,0x9D,0x23,0xB2,0x43,
	0xDC,0x96,0x64,0x0D,0xC7,0xF4,0x56,0xF0,0x20,0x17,0x2D,0x72,0x12,0x4C,0x65,0x9C,
	0x36,0x87,0x98,0xA5,0x86,0xDF,0x2B,0x08,0x97,0x1A,0x1B,0xE1,0xC7,0x8C,0x3A,0x70,
	0x65,0xDD,0x64,0x5D,0x61,0xBB,0x9D,0x0A,0x32,0x0C,0x53,0xA4,0xED,0x23,0x95,0xB1,
	0xA5,0xA1,0x08,0xCD,0x75,0x02,0x4D,0xAF,0xDA,0x5C,0x18,0xD0,0xD2,0x4A,0xA2,0x00,
	0x8B,0x67,0xD9,0xD9,0x1C,0x13,0xAC,0x4A,0xBB,0xE8,0xEC,0x20,0x45,0x32,0xFE,0x03,
	0x12,0x43,0x2A,0x0A,0xC4,0x6C,0x55,0x15,0x4C,0xBA,0x3D,0x17,0x25,0x38,0x1C,0x6E,
	0xE1,0x1F,0x32,0x88,0x57,0x07,0x6A,0x76,0xE0,0x98,0xE1,0xBD,0x05,0xAA,0xF0,0x50,
	0x4C,0x28,0x6C,0xF7,0xF7,0xCF,0xE4,0xE2,0x49,0x54,0xCA,0x82,0x8B,0x69,0x66,0x01,
	0x1F,0x66,0x7C,0x47,0xB0,0x3A,0xFA,0xEA,0x05,0x6E,0x07,0x38,0xCF,0x01,0x66,0x11,
	0xF3,0x3A,0x10,0x8F,0x14,0xAB,0xD5,0x14,0xD9,0xA4,0x58,0x0B,0x52,0x41,0x89,0x68,
	0x5A,0x17,0x0E,0x76,0x08,0x68,0xAE,0x12,0x8D,0x50,0x0A,0xAF,0x9D,0x51,0x20,0x86,
	0x8D,0x14,0xA3,0x2A,0xEE,0x84,0x42,0x02,0x76,0x9E,0xCB,0xCB,0x18,0x64,0x7A,0xC0,
	0x82,0x43,0xE4,0xAC,0xBE,0xB9,0x40,0xA0,0x82,0x89,0x4E,0x81,0x68,0xD6,0x6C,0xFE,
	0x07,0x94,0x03,0xD5,0x0F,0x0A,0x46,0xA8,0x83,0x83,0x22,0xEC,0x53,0xB6,0x8B,0x02,
	0x82,0x10,0x39,0x40,0x86,0x96,0xDF,0x3A,0xCA,0x25,0x0F,0x6F,0x74,0x23,0x4F,0x45,
	0xB7,0xC1,0x1E,0x10,0x34,0x66,0x72,0xAE,0xA0,0x60,0x28,0xEC,0x60,0xAC,0xA2,0x7A,
	0xF2,0x10,0xDE,0x4C,0x53,0x7E,0x34,0xA4,0xBD,0x4D,0x2F,0x26,0xF4,0xF3,0x61,0xCA,
	0xAB,0x3D,0x98,0x03,0xAE,0x23,0xFE,0x9D,0x16,0x86,0xF5,0x9F,0x80,0x48,0x3D,0xE6,
	0xC9,0x4B,0x1D,0x3C,0x58,0x16,0xC4,0xC5,0xC0,0x8D,0x1F,0xC3,0xD0,0xD8,0xCC,0x11,
	0xE0,0x71,0x0A,0x44,0xAB,0x50,0xBF,0x79,0x12,0x4C,0xE1,0x2B,0xEB,0x31,0x6F,0x4D,
	0xF5,0x05,0xD9,0x2B,0x8C,0x02,0xBC,0xC9,0x57,0x7A,0xC8,0x29,0x2D,0x9A,0xFA,0x7F,
	0xF0,0xDD,0xC0,0x2F,0xAA,0xCD,0x50,0xE7,0xD1,0x89,0x11,0x69,0xA9,0xB8,0x04,0xC9,
	0xDF,0x04,0x65,0x9B,0xD7,0x72,0x14,0xFD,0x9D,0x6E,0xDF,0xC2,0x26,0x87,0xB4,0x05,
	0xF9,0x55,0xE8,0x0E,0xCF,0x43,0xB0,0x02,0xEA,0x7D,0x82,0x91,0x29,0x31,0xCA,0x02,
	0x73,0x8D,0x1F,0x8E,0x5F,0x2D,0x10,0xEB,0xE4,0x77,0x96,0xB9,0x6A,0x4E,0x13,0xAF,
	0x85,0x69,0x52,0xC4,0x0D,0xC4,0x38,0xFB,0x86,0xBD,0xA1,0x19,0xA1,0x3F,0xD7,0x92,
	0x0D,0x57,0x03,0xEE,0x25,0xF4,0x4E,0xAB,0x9A,0x86,0x53,0x26,0x0E,0x3D,0x48,0x7F,
	0x94,0xD8,0xAA,0x20,0x33,0x8E,0x12,0x16,0x7F,0xE4,0x64,0x8C,0x61,0x04,0xD8,0x3B,
	0xE1,0xF5,0x34,0xC3,0x50,0x19,0xE0,0x04,0xB4,0xBC,0x51,0xFB,0x0C,0x4F,0xF4,0x41,
	0xB7,0xAB,0xCD,0x30,0x7F,0x56,0xD5,0x8F,0x6B,0x4A,0x19,0xDE,0xD0,0x25,0xDB,0xFF,
	0xA2,0x46,0x44,0xBD,0x1E,0x21,0xF1,0x06,0xF1,0x24,0xA3,0x9B,0x43,0xAA,0x04,0x52,
	0x9E,0xC1,0xEE,0xF0,0x5C,0xE6,0x75,0xE1,0xE6,0x8C,0xC3,0xE5,0xAC,0xC7,0x75,0xE5
};

static const byte kERF11NWNPassword[] = {
	0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x09, 0x87, 0x65, 0x43, 0x21
};

GTEST_TEST(ERFFile11NWN, getNameHashAlgo) {
	PasswordStore password(kERF11NWNPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN), password);

	EXPECT_EQ(erf.getNameHashAlgo(), Common::kHashNone);
}

GTEST_TEST(ERFFile11NWN, getBuildYear) {
	PasswordStore password(kERF11NWNPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN), password);

	EXPECT_EQ(erf.getBuildYear(), 2000);
}

GTEST_TEST(ERFFile11NWN, getBuildDay) {
	PasswordStore password(kERF11NWNPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN), password);

	EXPECT_EQ(erf.getBuildDay(), 23);
}

GTEST_TEST(ERFFile11NWN, getDescription) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	PasswordStore password(kERF11NWNPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN), password);

	const Aurora::LocString &description = erf.getDescription();

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile11NWN, getDescriptionStatic) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	Common::MemoryReadStream stream(kERFFile11NWN);

	Aurora::LocString description = Aurora::ERFFile::getDescription(stream);

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile11NWN, getResources) {
	PasswordStore password(kERF11NWNPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN), password);

	const Aurora::ERFFile::ResourceList &resources = erf.getResources();
	ASSERT_EQ(resources.size(), 1);

	const Aurora::ERFFile::Resource &resource = *resources.begin();

	EXPECT_STREQ(resource.name.c_str(), "ozymandias");
	EXPECT_EQ(resource.type, Aurora::kFileTypeTXT);
	EXPECT_EQ(resource.hash, 0);
	EXPECT_EQ(resource.index, 0);
}

GTEST_TEST(ERFFile11NWN, getResourceSize) {
	PasswordStore password(kERF11NWNPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN), password);

	EXPECT_EQ(erf.getResourceSize(0), strlen(kFileData));

	EXPECT_THROW(erf.getResourceSize(1), Common::Exception);
}

GTEST_TEST(ERFFile11NWN, findResourceHash) {
	PasswordStore password(kERF11NWNPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN), password);

	EXPECT_EQ(erf.findResource(0), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile11NWN, findResourceName) {
	PasswordStore password(kERF11NWNPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN), password);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeTXT), 0);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeBMP), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeBMP), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile11NWN, getResource) {
	PasswordStore password(kERF11NWNPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN), password);

	Common::SeekableReadStream *file = erf.getResource(0);
	ASSERT_NE(file, static_cast<Common::SeekableReadStream *>(0));

	ASSERT_EQ(file->size(), strlen(kFileData));

	for (size_t i = 0; i < strlen(kFileData); i++)
		EXPECT_EQ(file->readByte(), kFileData[i]) << "At index " << i;

	delete file;
}

GTEST_TEST(ERFFile11NWN, typeMOD) {
	static const byte kERF[] = {
		0x4D,0x4F,0x44,0x20,0x56,0x31,0x2E,0x31,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0x81,0x9B,0xEF,0x97,0xED,0x59,0x92,0x51,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xBA,0x71,0xE4,0x49,0x18,0x4A,0x40,0xD6,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA
	};

	PasswordStore password(kERF11NWNPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERF), password);

	EXPECT_EQ(erf.getBuildDay(), 23);
	EXPECT_EQ(erf.getBuildYear(), 2000);

	EXPECT_EQ(erf.getResources().size(), 0);
}

GTEST_TEST(ERFFile11NWN, typeHAK) {
	static const byte kERF[] = {
		0x48,0x41,0x4B,0x20,0x56,0x31,0x2E,0x31,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0x81,0x9B,0xEF,0x97,0xED,0x59,0x92,0x51,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xBA,0x71,0xE4,0x49,0x18,0x4A,0x40,0xD6,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA
	};

	PasswordStore password(kERF11NWNPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERF), password);

	EXPECT_EQ(erf.getBuildDay(), 23);
	EXPECT_EQ(erf.getBuildYear(), 2000);

	EXPECT_EQ(erf.getResources().size(), 0);
}

GTEST_TEST(ERFFile11NWN, typeSAV) {
	static const byte kERF[] = {
		0x53,0x41,0x56,0x20,0x56,0x31,0x2E,0x31,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0x81,0x9B,0xEF,0x97,0xED,0x59,0x92,0x51,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xBA,0x71,0xE4,0x49,0x18,0x4A,0x40,0xD6,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,
		0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA,0xD5,0x8A,0x94,0xF2,0x3C,0x53,0x13,0xAA
	};

	PasswordStore password(kERF11NWNPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERF), password);

	EXPECT_EQ(erf.getBuildDay(), 23);
	EXPECT_EQ(erf.getBuildYear(), 2000);

	EXPECT_EQ(erf.getResources().size(), 0);
}

// --- ERF V1.1 (NWN2) ---

// Percy Bysshe Shelley's "Ozymandias", within an ERF V1.1 (NWN2) file
static const byte kERFFile11NWN2[] = {
	0x45,0x52,0x46,0x20,0x56,0x31,0x2E,0x31,0x01,0x00,0x00,0x00,0x18,0x00,0x00,0x00,
	0x01,0x00,0x00,0x00,0xA0,0x00,0x00,0x00,0xB8,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,
	0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x78,0x6F,0x72,0x65,0x6F,0x73,0x20,0x75,
	0x6E,0x69,0x74,0x20,0x74,0x65,0x73,0x74,0x6F,0x7A,0x79,0x6D,0x61,0x6E,0x64,0x69,
	0x61,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,
	0xE8,0x00,0x00,0x00,0x6F,0x02,0x00,0x00,0x49,0x20,0x6D,0x65,0x74,0x20,0x61,0x20,
	0x74,0x72,0x61,0x76,0x65,0x6C,0x6C,0x65,0x72,0x20,0x66,0x72,0x6F,0x6D,0x20,0x61,
	0x6E,0x20,0x61,0x6E,0x74,0x69,0x71,0x75,0x65,0x20,0x6C,0x61,0x6E,0x64,0x0A,0x57,
	0x68,0x6F,0x20,0x73,0x61,0x69,0x64,0x3A,0x20,0x54,0x77,0x6F,0x20,0x76,0x61,0x73,
	0x74,0x20,0x61,0x6E,0x64,0x20,0x74,0x72,0x75,0x6E,0x6B,0x6C,0x65,0x73,0x73,0x20,
	0x6C,0x65,0x67,0x73,0x20,0x6F,0x66,0x20,0x73,0x74,0x6F,0x6E,0x65,0x0A,0x53,0x74,
	0x61,0x6E,0x64,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x64,0x65,0x73,0x65,0x72,
	0x74,0x2E,0x20,0x4E,0x65,0x61,0x72,0x20,0x74,0x68,0x65,0x6D,0x2C,0x20,0x6F,0x6E,
	0x20,0x74,0x68,0x65,0x20,0x73,0x61,0x6E,0x64,0x2C,0x0A,0x48,0x61,0x6C,0x66,0x20,
	0x73,0x75,0x6E,0x6B,0x2C,0x20,0x61,0x20,0x73,0x68,0x61,0x74,0x74,0x65,0x72,0x65,
	0x64,0x20,0x76,0x69,0x73,0x61,0x67,0x65,0x20,0x6C,0x69,0x65,0x73,0x2C,0x20,0x77,
	0x68,0x6F,0x73,0x65,0x20,0x66,0x72,0x6F,0x77,0x6E,0x2C,0x0A,0x41,0x6E,0x64,0x20,
	0x77,0x72,0x69,0x6E,0x6B,0x6C,0x65,0x64,0x20,0x6C,0x69,0x70,0x2C,0x20,0x61,0x6E,
	0x64,0x20,0x73,0x6E,0x65,0x65,0x72,0x20,0x6F,0x66,0x20,0x63,0x6F,0x6C,0x64,0x20,
	0x63,0x6F,0x6D,0x6D,0x61,0x6E,0x64,0x2C,0x0A,0x54,0x65,0x6C,0x6C,0x20,0x74,0x68,
	0x61,0x74,0x20,0x69,0x74,0x73,0x20,0x73,0x63,0x75,0x6C,0x70,0x74,0x6F,0x72,0x20,
	0x77,0x65,0x6C,0x6C,0x20,0x74,0x68,0x6F,0x73,0x65,0x20,0x70,0x61,0x73,0x73,0x69,
	0x6F,0x6E,0x73,0x20,0x72,0x65,0x61,0x64,0x0A,0x57,0x68,0x69,0x63,0x68,0x20,0x79,
	0x65,0x74,0x20,0x73,0x75,0x72,0x76,0x69,0x76,0x65,0x2C,0x20,0x73,0x74,0x61,0x6D,
	0x70,0x65,0x64,0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,0x73,0x65,0x20,0x6C,0x69,0x66,
	0x65,0x6C,0x65,0x73,0x73,0x20,0x74,0x68,0x69,0x6E,0x67,0x73,0x2C,0x0A,0x54,0x68,
	0x65,0x20,0x68,0x61,0x6E,0x64,0x20,0x74,0x68,0x61,0x74,0x20,0x6D,0x6F,0x63,0x6B,
	0x65,0x64,0x20,0x74,0x68,0x65,0x6D,0x20,0x61,0x6E,0x64,0x20,0x74,0x68,0x65,0x20,
	0x68,0x65,0x61,0x72,0x74,0x20,0x74,0x68,0x61,0x74,0x20,0x66,0x65,0x64,0x3A,0x0A,
	0x41,0x6E,0x64,0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,0x20,0x70,0x65,0x64,0x65,0x73,
	0x74,0x61,0x6C,0x20,0x74,0x68,0x65,0x73,0x65,0x20,0x77,0x6F,0x72,0x64,0x73,0x20,
	0x61,0x70,0x70,0x65,0x61,0x72,0x3A,0x0A,0x27,0x4D,0x79,0x20,0x6E,0x61,0x6D,0x65,
	0x20,0x69,0x73,0x20,0x4F,0x7A,0x79,0x6D,0x61,0x6E,0x64,0x69,0x61,0x73,0x2C,0x20,
	0x6B,0x69,0x6E,0x67,0x20,0x6F,0x66,0x20,0x6B,0x69,0x6E,0x67,0x73,0x3A,0x0A,0x4C,
	0x6F,0x6F,0x6B,0x20,0x6F,0x6E,0x20,0x6D,0x79,0x20,0x77,0x6F,0x72,0x6B,0x73,0x2C,
	0x20,0x79,0x65,0x20,0x4D,0x69,0x67,0x68,0x74,0x79,0x2C,0x20,0x61,0x6E,0x64,0x20,
	0x64,0x65,0x73,0x70,0x61,0x69,0x72,0x21,0x27,0x0A,0x4E,0x6F,0x74,0x68,0x69,0x6E,
	0x67,0x20,0x62,0x65,0x73,0x69,0x64,0x65,0x20,0x72,0x65,0x6D,0x61,0x69,0x6E,0x73,
	0x2E,0x20,0x52,0x6F,0x75,0x6E,0x64,0x20,0x74,0x68,0x65,0x20,0x64,0x65,0x63,0x61,
	0x79,0x0A,0x4F,0x66,0x20,0x74,0x68,0x61,0x74,0x20,0x63,0x6F,0x6C,0x6F,0x73,0x73,
	0x61,0x6C,0x20,0x77,0x72,0x65,0x63,0x6B,0x2C,0x20,0x62,0x6F,0x75,0x6E,0x64,0x6C,
	0x65,0x73,0x73,0x20,0x61,0x6E,0x64,0x20,0x62,0x61,0x72,0x65,0x0A,0x54,0x68,0x65,
	0x20,0x6C,0x6F,0x6E,0x65,0x20,0x61,0x6E,0x64,0x20,0x6C,0x65,0x76,0x65,0x6C,0x20,
	0x73,0x61,0x6E,0x64,0x73,0x20,0x73,0x74,0x72,0x65,0x74,0x63,0x68,0x20,0x66,0x61,
	0x72,0x20,0x61,0x77,0x61,0x79,0x2E
};

GTEST_TEST(ERFFile11NWN2, getNameHashAlgo) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN2));

	EXPECT_EQ(erf.getNameHashAlgo(), Common::kHashNone);
}

GTEST_TEST(ERFFile11NWN2, getBuildYear) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN2));

	EXPECT_EQ(erf.getBuildYear(), 2000);
}

GTEST_TEST(ERFFile11NWN2, getBuildDay) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN2));

	EXPECT_EQ(erf.getBuildDay(), 23);
}

GTEST_TEST(ERFFile11NWN2, getDescription) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN2));

	const Aurora::LocString &description = erf.getDescription();

	EXPECT_EQ(description.getID(), 0);
	EXPECT_STREQ(description.getString().c_str(), "xoreos unit test");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile11NWN2, getDescriptionStatic) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	Common::MemoryReadStream stream(kERFFile11NWN2);

	Aurora::LocString description = Aurora::ERFFile::getDescription(stream);

	EXPECT_EQ(description.getID(), 0);
	EXPECT_STREQ(description.getString().c_str(), "xoreos unit test");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile11NWN2, getResources) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN2));

	const Aurora::ERFFile::ResourceList &resources = erf.getResources();
	ASSERT_EQ(resources.size(), 1);

	const Aurora::ERFFile::Resource &resource = *resources.begin();

	EXPECT_STREQ(resource.name.c_str(), "ozymandias");
	EXPECT_EQ(resource.type, Aurora::kFileTypeTXT);
	EXPECT_EQ(resource.hash, 0);
	EXPECT_EQ(resource.index, 0);
}

GTEST_TEST(ERFFile11NWN2, getResourceSize) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN2));

	EXPECT_EQ(erf.getResourceSize(0), strlen(kFileData));

	EXPECT_THROW(erf.getResourceSize(1), Common::Exception);
}

GTEST_TEST(ERFFile11NWN2, findResourceHash) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN2));

	EXPECT_EQ(erf.findResource(0), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile11NWN2, findResourceName) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN2));

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeTXT), 0);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeBMP), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeBMP), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile11NWN2, getResource) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile11NWN2));

	Common::SeekableReadStream *file = erf.getResource(0);
	ASSERT_NE(file, static_cast<Common::SeekableReadStream *>(0));

	ASSERT_EQ(file->size(), strlen(kFileData));

	for (size_t i = 0; i < strlen(kFileData); i++)
		EXPECT_EQ(file->readByte(), kFileData[i]) << "At index " << i;

	delete file;
}

GTEST_TEST(ERFFile11NWN2, typeMOD) {
	static const byte kERF[] = {
		0x4D,0x4F,0x44,0x20,0x56,0x31,0x2E,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
	};

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERF));

	EXPECT_EQ(erf.getBuildDay(), 23);
	EXPECT_EQ(erf.getBuildYear(), 2000);

	EXPECT_EQ(erf.getResources().size(), 0);
}

GTEST_TEST(ERFFile11NWN2, typeHAK) {
	static const byte kERF[] = {
		0x48,0x41,0x4B,0x20,0x56,0x31,0x2E,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
	};

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERF));

	EXPECT_EQ(erf.getBuildDay(), 23);
	EXPECT_EQ(erf.getBuildYear(), 2000);

	EXPECT_EQ(erf.getResources().size(), 0);
}

GTEST_TEST(ERFFile11NWN2, typeSAV) {
	static const byte kERF[] = {
		0x53,0x41,0x56,0x20,0x56,0x31,0x2E,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
	};

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERF));

	EXPECT_EQ(erf.getBuildDay(), 23);
	EXPECT_EQ(erf.getBuildYear(), 2000);

	EXPECT_EQ(erf.getResources().size(), 0);
}

// --- ERF V2.0 ---

// Percy Bysshe Shelley's "Ozymandias", within an ERF V2.0 file
static const byte kERFFile20[] = {
	0x45,0x00,0x52,0x00,0x46,0x00,0x20,0x00,0x56,0x00,0x32,0x00,0x2E,0x00,0x30,0x00,
	0x01,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
	0x6F,0x00,0x7A,0x00,0x79,0x00,0x6D,0x00,0x61,0x00,0x6E,0x00,0x64,0x00,0x69,0x00,
	0x61,0x00,0x73,0x00,0x2E,0x00,0x74,0x00,0x78,0x00,0x74,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x68,0x00,0x00,0x00,0x6F,0x02,0x00,0x00,0x49,0x20,0x6D,0x65,0x74,0x20,0x61,0x20,
	0x74,0x72,0x61,0x76,0x65,0x6C,0x6C,0x65,0x72,0x20,0x66,0x72,0x6F,0x6D,0x20,0x61,
	0x6E,0x20,0x61,0x6E,0x74,0x69,0x71,0x75,0x65,0x20,0x6C,0x61,0x6E,0x64,0x0A,0x57,
	0x68,0x6F,0x20,0x73,0x61,0x69,0x64,0x3A,0x20,0x54,0x77,0x6F,0x20,0x76,0x61,0x73,
	0x74,0x20,0x61,0x6E,0x64,0x20,0x74,0x72,0x75,0x6E,0x6B,0x6C,0x65,0x73,0x73,0x20,
	0x6C,0x65,0x67,0x73,0x20,0x6F,0x66,0x20,0x73,0x74,0x6F,0x6E,0x65,0x0A,0x53,0x74,
	0x61,0x6E,0x64,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x64,0x65,0x73,0x65,0x72,
	0x74,0x2E,0x20,0x4E,0x65,0x61,0x72,0x20,0x74,0x68,0x65,0x6D,0x2C,0x20,0x6F,0x6E,
	0x20,0x74,0x68,0x65,0x20,0x73,0x61,0x6E,0x64,0x2C,0x0A,0x48,0x61,0x6C,0x66,0x20,
	0x73,0x75,0x6E,0x6B,0x2C,0x20,0x61,0x20,0x73,0x68,0x61,0x74,0x74,0x65,0x72,0x65,
	0x64,0x20,0x76,0x69,0x73,0x61,0x67,0x65,0x20,0x6C,0x69,0x65,0x73,0x2C,0x20,0x77,
	0x68,0x6F,0x73,0x65,0x20,0x66,0x72,0x6F,0x77,0x6E,0x2C,0x0A,0x41,0x6E,0x64,0x20,
	0x77,0x72,0x69,0x6E,0x6B,0x6C,0x65,0x64,0x20,0x6C,0x69,0x70,0x2C,0x20,0x61,0x6E,
	0x64,0x20,0x73,0x6E,0x65,0x65,0x72,0x20,0x6F,0x66,0x20,0x63,0x6F,0x6C,0x64,0x20,
	0x63,0x6F,0x6D,0x6D,0x61,0x6E,0x64,0x2C,0x0A,0x54,0x65,0x6C,0x6C,0x20,0x74,0x68,
	0x61,0x74,0x20,0x69,0x74,0x73,0x20,0x73,0x63,0x75,0x6C,0x70,0x74,0x6F,0x72,0x20,
	0x77,0x65,0x6C,0x6C,0x20,0x74,0x68,0x6F,0x73,0x65,0x20,0x70,0x61,0x73,0x73,0x69,
	0x6F,0x6E,0x73,0x20,0x72,0x65,0x61,0x64,0x0A,0x57,0x68,0x69,0x63,0x68,0x20,0x79,
	0x65,0x74,0x20,0x73,0x75,0x72,0x76,0x69,0x76,0x65,0x2C,0x20,0x73,0x74,0x61,0x6D,
	0x70,0x65,0x64,0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,0x73,0x65,0x20,0x6C,0x69,0x66,
	0x65,0x6C,0x65,0x73,0x73,0x20,0x74,0x68,0x69,0x6E,0x67,0x73,0x2C,0x0A,0x54,0x68,
	0x65,0x20,0x68,0x61,0x6E,0x64,0x20,0x74,0x68,0x61,0x74,0x20,0x6D,0x6F,0x63,0x6B,
	0x65,0x64,0x20,0x74,0x68,0x65,0x6D,0x20,0x61,0x6E,0x64,0x20,0x74,0x68,0x65,0x20,
	0x68,0x65,0x61,0x72,0x74,0x20,0x74,0x68,0x61,0x74,0x20,0x66,0x65,0x64,0x3A,0x0A,
	0x41,0x6E,0x64,0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,0x20,0x70,0x65,0x64,0x65,0x73,
	0x74,0x61,0x6C,0x20,0x74,0x68,0x65,0x73,0x65,0x20,0x77,0x6F,0x72,0x64,0x73,0x20,
	0x61,0x70,0x70,0x65,0x61,0x72,0x3A,0x0A,0x27,0x4D,0x79,0x20,0x6E,0x61,0x6D,0x65,
	0x20,0x69,0x73,0x20,0x4F,0x7A,0x79,0x6D,0x61,0x6E,0x64,0x69,0x61,0x73,0x2C,0x20,
	0x6B,0x69,0x6E,0x67,0x20,0x6F,0x66,0x20,0x6B,0x69,0x6E,0x67,0x73,0x3A,0x0A,0x4C,
	0x6F,0x6F,0x6B,0x20,0x6F,0x6E,0x20,0x6D,0x79,0x20,0x77,0x6F,0x72,0x6B,0x73,0x2C,
	0x20,0x79,0x65,0x20,0x4D,0x69,0x67,0x68,0x74,0x79,0x2C,0x20,0x61,0x6E,0x64,0x20,
	0x64,0x65,0x73,0x70,0x61,0x69,0x72,0x21,0x27,0x0A,0x4E,0x6F,0x74,0x68,0x69,0x6E,
	0x67,0x20,0x62,0x65,0x73,0x69,0x64,0x65,0x20,0x72,0x65,0x6D,0x61,0x69,0x6E,0x73,
	0x2E,0x20,0x52,0x6F,0x75,0x6E,0x64,0x20,0x74,0x68,0x65,0x20,0x64,0x65,0x63,0x61,
	0x79,0x0A,0x4F,0x66,0x20,0x74,0x68,0x61,0x74,0x20,0x63,0x6F,0x6C,0x6F,0x73,0x73,
	0x61,0x6C,0x20,0x77,0x72,0x65,0x63,0x6B,0x2C,0x20,0x62,0x6F,0x75,0x6E,0x64,0x6C,
	0x65,0x73,0x73,0x20,0x61,0x6E,0x64,0x20,0x62,0x61,0x72,0x65,0x0A,0x54,0x68,0x65,
	0x20,0x6C,0x6F,0x6E,0x65,0x20,0x61,0x6E,0x64,0x20,0x6C,0x65,0x76,0x65,0x6C,0x20,
	0x73,0x61,0x6E,0x64,0x73,0x20,0x73,0x74,0x72,0x65,0x74,0x63,0x68,0x20,0x66,0x61,
	0x72,0x20,0x61,0x77,0x61,0x79,0x2E
};

GTEST_TEST(ERFFile20, getNameHashAlgo) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile20));

	EXPECT_EQ(erf.getNameHashAlgo(), Common::kHashNone);
}

GTEST_TEST(ERFFile20, getBuildYear) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile20));

	EXPECT_EQ(erf.getBuildYear(), 2000);
}

GTEST_TEST(ERFFile20, getBuildDay) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile20));

	EXPECT_EQ(erf.getBuildDay(), 23);
}

GTEST_TEST(ERFFile20, getDescription) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile20));

	const Aurora::LocString &description = erf.getDescription();

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile20, getDescriptionStatic) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	Common::MemoryReadStream stream(kERFFile20);

	Aurora::LocString description = Aurora::ERFFile::getDescription(stream);

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile20, getResources) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile20));

	const Aurora::ERFFile::ResourceList &resources = erf.getResources();
	ASSERT_EQ(resources.size(), 1);

	const Aurora::ERFFile::Resource &resource = *resources.begin();

	EXPECT_STREQ(resource.name.c_str(), "ozymandias");
	EXPECT_EQ(resource.type, Aurora::kFileTypeTXT);
	EXPECT_EQ(resource.hash, 0);
	EXPECT_EQ(resource.index, 0);
}

GTEST_TEST(ERFFile20, getResourceSize) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile20));

	EXPECT_EQ(erf.getResourceSize(0), strlen(kFileData));

	EXPECT_THROW(erf.getResourceSize(1), Common::Exception);
}

GTEST_TEST(ERFFile20, findResourceHash) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile20));

	EXPECT_EQ(erf.findResource(0), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile20, findResourceName) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile20));

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeTXT), 0);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeBMP), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeBMP), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile20, getResource) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile20));

	Common::SeekableReadStream *file = erf.getResource(0);
	ASSERT_NE(file, static_cast<Common::SeekableReadStream *>(0));

	ASSERT_EQ(file->size(), strlen(kFileData));

	for (size_t i = 0; i < strlen(kFileData); i++)
		EXPECT_EQ(file->readByte(), kFileData[i]) << "At index " << i;

	delete file;
}

GTEST_TEST(ERFFile20, typeMOD) {
	static const byte kERF[] = {
		0x4D,0x00,0x4F,0x00,0x44,0x00,0x20,0x00,0x56,0x00,0x32,0x00,0x2E,0x00,0x30,0x00,
		0x00,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF
	};

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERF));

	EXPECT_EQ(erf.getBuildDay(), 23);
	EXPECT_EQ(erf.getBuildYear(), 2000);

	EXPECT_EQ(erf.getResources().size(), 0);
}

GTEST_TEST(ERFFile20, typeHAK) {
	static const byte kERF[] = {
		0x48,0x00,0x41,0x00,0x4B,0x00,0x20,0x00,0x56,0x00,0x32,0x00,0x2E,0x00,0x30,0x00,
		0x00,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF
	};

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERF));

	EXPECT_EQ(erf.getBuildDay(), 23);
	EXPECT_EQ(erf.getBuildYear(), 2000);

	EXPECT_EQ(erf.getResources().size(), 0);
}

GTEST_TEST(ERFFile20, typeSAV) {
	static const byte kERF[] = {
		0x53,0x00,0x41,0x00,0x56,0x00,0x20,0x00,0x56,0x00,0x32,0x00,0x2E,0x00,0x30,0x00,
		0x00,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF
	};

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERF));

	EXPECT_EQ(erf.getBuildDay(), 23);
	EXPECT_EQ(erf.getBuildYear(), 2000);

	EXPECT_EQ(erf.getResources().size(), 0);
}

// --- ERF V2.2 (plain) ---

// Percy Bysshe Shelley's "Ozymandias", within an ERF V2.2 (plain) file
static const byte kERFFile22Plain[] = {
	0x45,0x00,0x52,0x00,0x46,0x00,0x20,0x00,0x56,0x00,0x32,0x00,0x2E,0x00,0x32,0x00,
	0x01,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6F,0x00,0x7A,0x00,0x79,0x00,0x6D,0x00,
	0x61,0x00,0x6E,0x00,0x64,0x00,0x69,0x00,0x61,0x00,0x73,0x00,0x2E,0x00,0x74,0x00,
	0x78,0x00,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x6F,0x02,0x00,0x00,
	0x6F,0x02,0x00,0x00,0x49,0x20,0x6D,0x65,0x74,0x20,0x61,0x20,0x74,0x72,0x61,0x76,
	0x65,0x6C,0x6C,0x65,0x72,0x20,0x66,0x72,0x6F,0x6D,0x20,0x61,0x6E,0x20,0x61,0x6E,
	0x74,0x69,0x71,0x75,0x65,0x20,0x6C,0x61,0x6E,0x64,0x0A,0x57,0x68,0x6F,0x20,0x73,
	0x61,0x69,0x64,0x3A,0x20,0x54,0x77,0x6F,0x20,0x76,0x61,0x73,0x74,0x20,0x61,0x6E,
	0x64,0x20,0x74,0x72,0x75,0x6E,0x6B,0x6C,0x65,0x73,0x73,0x20,0x6C,0x65,0x67,0x73,
	0x20,0x6F,0x66,0x20,0x73,0x74,0x6F,0x6E,0x65,0x0A,0x53,0x74,0x61,0x6E,0x64,0x20,
	0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x64,0x65,0x73,0x65,0x72,0x74,0x2E,0x20,0x4E,
	0x65,0x61,0x72,0x20,0x74,0x68,0x65,0x6D,0x2C,0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,
	0x20,0x73,0x61,0x6E,0x64,0x2C,0x0A,0x48,0x61,0x6C,0x66,0x20,0x73,0x75,0x6E,0x6B,
	0x2C,0x20,0x61,0x20,0x73,0x68,0x61,0x74,0x74,0x65,0x72,0x65,0x64,0x20,0x76,0x69,
	0x73,0x61,0x67,0x65,0x20,0x6C,0x69,0x65,0x73,0x2C,0x20,0x77,0x68,0x6F,0x73,0x65,
	0x20,0x66,0x72,0x6F,0x77,0x6E,0x2C,0x0A,0x41,0x6E,0x64,0x20,0x77,0x72,0x69,0x6E,
	0x6B,0x6C,0x65,0x64,0x20,0x6C,0x69,0x70,0x2C,0x20,0x61,0x6E,0x64,0x20,0x73,0x6E,
	0x65,0x65,0x72,0x20,0x6F,0x66,0x20,0x63,0x6F,0x6C,0x64,0x20,0x63,0x6F,0x6D,0x6D,
	0x61,0x6E,0x64,0x2C,0x0A,0x54,0x65,0x6C,0x6C,0x20,0x74,0x68,0x61,0x74,0x20,0x69,
	0x74,0x73,0x20,0x73,0x63,0x75,0x6C,0x70,0x74,0x6F,0x72,0x20,0x77,0x65,0x6C,0x6C,
	0x20,0x74,0x68,0x6F,0x73,0x65,0x20,0x70,0x61,0x73,0x73,0x69,0x6F,0x6E,0x73,0x20,
	0x72,0x65,0x61,0x64,0x0A,0x57,0x68,0x69,0x63,0x68,0x20,0x79,0x65,0x74,0x20,0x73,
	0x75,0x72,0x76,0x69,0x76,0x65,0x2C,0x20,0x73,0x74,0x61,0x6D,0x70,0x65,0x64,0x20,
	0x6F,0x6E,0x20,0x74,0x68,0x65,0x73,0x65,0x20,0x6C,0x69,0x66,0x65,0x6C,0x65,0x73,
	0x73,0x20,0x74,0x68,0x69,0x6E,0x67,0x73,0x2C,0x0A,0x54,0x68,0x65,0x20,0x68,0x61,
	0x6E,0x64,0x20,0x74,0x68,0x61,0x74,0x20,0x6D,0x6F,0x63,0x6B,0x65,0x64,0x20,0x74,
	0x68,0x65,0x6D,0x20,0x61,0x6E,0x64,0x20,0x74,0x68,0x65,0x20,0x68,0x65,0x61,0x72,
	0x74,0x20,0x74,0x68,0x61,0x74,0x20,0x66,0x65,0x64,0x3A,0x0A,0x41,0x6E,0x64,0x20,
	0x6F,0x6E,0x20,0x74,0x68,0x65,0x20,0x70,0x65,0x64,0x65,0x73,0x74,0x61,0x6C,0x20,
	0x74,0x68,0x65,0x73,0x65,0x20,0x77,0x6F,0x72,0x64,0x73,0x20,0x61,0x70,0x70,0x65,
	0x61,0x72,0x3A,0x0A,0x27,0x4D,0x79,0x20,0x6E,0x61,0x6D,0x65,0x20,0x69,0x73,0x20,
	0x4F,0x7A,0x79,0x6D,0x61,0x6E,0x64,0x69,0x61,0x73,0x2C,0x20,0x6B,0x69,0x6E,0x67,
	0x20,0x6F,0x66,0x20,0x6B,0x69,0x6E,0x67,0x73,0x3A,0x0A,0x4C,0x6F,0x6F,0x6B,0x20,
	0x6F,0x6E,0x20,0x6D,0x79,0x20,0x77,0x6F,0x72,0x6B,0x73,0x2C,0x20,0x79,0x65,0x20,
	0x4D,0x69,0x67,0x68,0x74,0x79,0x2C,0x20,0x61,0x6E,0x64,0x20,0x64,0x65,0x73,0x70,
	0x61,0x69,0x72,0x21,0x27,0x0A,0x4E,0x6F,0x74,0x68,0x69,0x6E,0x67,0x20,0x62,0x65,
	0x73,0x69,0x64,0x65,0x20,0x72,0x65,0x6D,0x61,0x69,0x6E,0x73,0x2E,0x20,0x52,0x6F,
	0x75,0x6E,0x64,0x20,0x74,0x68,0x65,0x20,0x64,0x65,0x63,0x61,0x79,0x0A,0x4F,0x66,
	0x20,0x74,0x68,0x61,0x74,0x20,0x63,0x6F,0x6C,0x6F,0x73,0x73,0x61,0x6C,0x20,0x77,
	0x72,0x65,0x63,0x6B,0x2C,0x20,0x62,0x6F,0x75,0x6E,0x64,0x6C,0x65,0x73,0x73,0x20,
	0x61,0x6E,0x64,0x20,0x62,0x61,0x72,0x65,0x0A,0x54,0x68,0x65,0x20,0x6C,0x6F,0x6E,
	0x65,0x20,0x61,0x6E,0x64,0x20,0x6C,0x65,0x76,0x65,0x6C,0x20,0x73,0x61,0x6E,0x64,
	0x73,0x20,0x73,0x74,0x72,0x65,0x74,0x63,0x68,0x20,0x66,0x61,0x72,0x20,0x61,0x77,
	0x61,0x79,0x2E
};

GTEST_TEST(ERFFile22Plain, getNameHashAlgo) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22Plain));

	EXPECT_EQ(erf.getNameHashAlgo(), Common::kHashNone);
}

GTEST_TEST(ERFFile22Plain, getBuildYear) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22Plain));

	EXPECT_EQ(erf.getBuildYear(), 2000);
}

GTEST_TEST(ERFFile22Plain, getBuildDay) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22Plain));

	EXPECT_EQ(erf.getBuildDay(), 23);
}

GTEST_TEST(ERFFile22Plain, getDescription) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22Plain));

	const Aurora::LocString &description = erf.getDescription();

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile22Plain, getDescriptionStatic) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	Common::MemoryReadStream stream(kERFFile22Plain);

	Aurora::LocString description = Aurora::ERFFile::getDescription(stream);

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile22Plain, getResources) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22Plain));

	const Aurora::ERFFile::ResourceList &resources = erf.getResources();
	ASSERT_EQ(resources.size(), 1);

	const Aurora::ERFFile::Resource &resource = *resources.begin();

	EXPECT_STREQ(resource.name.c_str(), "ozymandias");
	EXPECT_EQ(resource.type, Aurora::kFileTypeTXT);
	EXPECT_EQ(resource.hash, 0);
	EXPECT_EQ(resource.index, 0);
}

GTEST_TEST(ERFFile22Plain, getResourceSize) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22Plain));

	EXPECT_EQ(erf.getResourceSize(0), strlen(kFileData));

	EXPECT_THROW(erf.getResourceSize(1), Common::Exception);
}

GTEST_TEST(ERFFile22Plain, findResourceHash) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22Plain));

	EXPECT_EQ(erf.findResource(0), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile22Plain, findResourceName) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22Plain));

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeTXT), 0);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeBMP), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeBMP), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile22Plain, getResource) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22Plain));

	Common::SeekableReadStream *file = erf.getResource(0);
	ASSERT_NE(file, static_cast<Common::SeekableReadStream *>(0));

	ASSERT_EQ(file->size(), strlen(kFileData));

	for (size_t i = 0; i < strlen(kFileData); i++)
		EXPECT_EQ(file->readByte(), kFileData[i]) << "At index " << i;

	delete file;
}

// --- ERF V2.2 (DEFLATE, with header) ---

// Percy Bysshe Shelley's "Ozymandias", within an ERF V2.2 (DEFLATE, with header) file
static const byte kERFFile22DH[] = {
	0x45,0x00,0x52,0x00,0x46,0x00,0x20,0x00,0x56,0x00,0x32,0x00,0x2E,0x00,0x32,0x00,
	0x01,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
	0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6F,0x00,0x7A,0x00,0x79,0x00,0x6D,0x00,
	0x61,0x00,0x6E,0x00,0x64,0x00,0x69,0x00,0x61,0x00,0x73,0x00,0x2E,0x00,0x74,0x00,
	0x78,0x00,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x78,0x01,0x00,0x00,
	0x6F,0x02,0x00,0x00,0xF0,0x2D,0x52,0xC9,0x6E,0xA4,0x30,0x10,0xBD,0xF3,0x15,0x95,
	0x53,0x2E,0xA8,0x3F,0xA0,0x6F,0x73,0x9B,0x48,0x59,0xA4,0x24,0xD2,0x9C,0xAB,0x71,
	0xD1,0x58,0xD8,0x2E,0xC6,0x65,0x40,0xE4,0xEB,0xF3,0x6C,0x5A,0x42,0x20,0xD5,0xF2,
	0xB6,0xE2,0x85,0xA2,0x14,0x62,0x2A,0x99,0x37,0x09,0x41,0x32,0x8D,0x59,0x23,0x71,
	0xC2,0x53,0xFC,0xFF,0x55,0x28,0x70,0x72,0xDD,0xBF,0x49,0xC9,0xD8,0xBB,0x2B,0x7D,
	0xEF,0x4A,0x1B,0x1B,0x76,0x92,0xC3,0xD6,0x9A,0xE6,0x20,0x66,0x14,0xE4,0x6E,0xA4,
	0x23,0x59,0xD1,0x24,0xDD,0x57,0xA9,0x5D,0x9F,0xA8,0x4C,0x42,0x4E,0x4C,0x72,0xB9,
	0xD0,0xBB,0x70,0xAE,0x85,0xD8,0x93,0x9E,0x1D,0xC3,0x54,0xDF,0xFD,0xE5,0x80,0x3D,
	0x00,0xF5,0xD0,0x61,0x13,0x97,0x22,0x59,0x1C,0x6D,0xDE,0xF8,0x0E,0x7A,0x2F,0xD6,
	0xD3,0x3E,0xA9,0x49,0x95,0xB6,0xA7,0xBE,0xFB,0x03,0xEC,0x3D,0xFB,0xCA,0xEC,0xD0,
	0x5F,0xFA,0xA6,0xC5,0x92,0x40,0x3D,0x24,0x0C,0x1A,0x1C,0x5E,0x31,0x36,0xF4,0x6F,
	0xB8,0x02,0x19,0x17,0xF2,0xC5,0xC8,0x86,0x35,0x2C,0x45,0x33,0xED,0x67,0xB9,0xA2,
	0x2E,0x6C,0xE6,0x35,0x19,0x65,0xE1,0xEA,0xD4,0x0F,0x13,0x1D,0x08,0xC5,0xD6,0xBC,
	0xF9,0x4D,0x7A,0x78,0xE2,0xB8,0x80,0xEA,0x54,0x6D,0x55,0xD3,0x28,0xCD,0x75,0x99,
	0x7C,0xBA,0x1B,0x48,0x60,0x66,0x6A,0x81,0x54,0xA2,0xA8,0xC3,0x2C,0xAE,0x59,0x3D,
	0x53,0xAA,0x5D,0x98,0x2F,0x67,0x7B,0x14,0x77,0x6D,0x1E,0x1E,0x29,0x00,0x5A,0x40,
	0x11,0x1E,0xE0,0xBB,0x66,0x67,0xC4,0xCB,0x82,0x8D,0x6B,0xF7,0xFC,0x76,0x50,0xE2,
	0x28,0xE4,0x8D,0x3E,0x7E,0x8E,0xEA,0xC9,0x33,0x02,0x99,0x41,0x5C,0xCD,0xD6,0xAF,
	0x5D,0xBB,0x57,0xD5,0xB9,0xE2,0xC5,0xA3,0xEE,0xCF,0x18,0x38,0x84,0xDE,0xFC,0x7D,
	0x2A,0xC7,0x99,0x0E,0x28,0x16,0xF6,0xF9,0xE9,0xB9,0x7B,0xD7,0xA6,0x9A,0x6E,0x62,
	0xDE,0x09,0x4C,0x47,0xF6,0xC9,0x2E,0xF4,0xA9,0xEB,0x43,0xAB,0x93,0x81,0x8F,0xEE,
	0x63,0x3C,0xE5,0x22,0x4E,0x35,0x83,0xBC,0x3D,0xCB,0x80,0x1B,0xDD,0xEA,0x5C,0x73,
	0x5F,0x71,0x6F,0x9C,0xA5,0xD9,0x0F,0xB8,0x7B,0xAB,0x04,0xC1,0x8F,0xD4,0x4E,0x8B,
	0xB8,0x4B,0x96,0x82,0x38,0x47,0x5C,0x9E,0x77,0x3E,0x2E,0xBF
};

GTEST_TEST(ERFFile22DeflateHeader, getNameHashAlgo) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DH));

	EXPECT_EQ(erf.getNameHashAlgo(), Common::kHashNone);
}

GTEST_TEST(ERFFile22DeflateHeader, getBuildYear) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DH));

	EXPECT_EQ(erf.getBuildYear(), 2000);
}

GTEST_TEST(ERFFile22DeflateHeader, getBuildDay) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DH));

	EXPECT_EQ(erf.getBuildDay(), 23);
}

GTEST_TEST(ERFFile22DeflateHeader, getDescription) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DH));

	const Aurora::LocString &description = erf.getDescription();

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile22DeflateHeader, getDescriptionStatic) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	Common::MemoryReadStream stream(kERFFile22DH);

	Aurora::LocString description = Aurora::ERFFile::getDescription(stream);

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile22DeflateHeader, getResources) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DH));

	const Aurora::ERFFile::ResourceList &resources = erf.getResources();
	ASSERT_EQ(resources.size(), 1);

	const Aurora::ERFFile::Resource &resource = *resources.begin();

	EXPECT_STREQ(resource.name.c_str(), "ozymandias");
	EXPECT_EQ(resource.type, Aurora::kFileTypeTXT);
	EXPECT_EQ(resource.hash, 0);
	EXPECT_EQ(resource.index, 0);
}

GTEST_TEST(ERFFile22DeflateHeader, getResourceSize) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DH));

	EXPECT_EQ(erf.getResourceSize(0), strlen(kFileData));

	EXPECT_THROW(erf.getResourceSize(1), Common::Exception);
}

GTEST_TEST(ERFFile22DeflateHeader, findResourceHash) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DH));

	EXPECT_EQ(erf.findResource(0), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile22DeflateHeader, findResourceName) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DH));

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeTXT), 0);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeBMP), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeBMP), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile22DeflateHeader, getResource) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DH));

	Common::SeekableReadStream *file = erf.getResource(0);
	ASSERT_NE(file, static_cast<Common::SeekableReadStream *>(0));

	ASSERT_EQ(file->size(), strlen(kFileData));

	for (size_t i = 0; i < strlen(kFileData); i++)
		EXPECT_EQ(file->readByte(), kFileData[i]) << "At index " << i;

	delete file;
}

// --- ERF V2.2 (DEFLATE, raw) ---

// Percy Bysshe Shelley's "Ozymandias", within an ERF V2.2 (DEFLATE, raw) file
static const byte kERFFile22DR[] = {
	0x45,0x00,0x52,0x00,0x46,0x00,0x20,0x00,0x56,0x00,0x32,0x00,0x2E,0x00,0x32,0x00,
	0x01,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
	0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6F,0x00,0x7A,0x00,0x79,0x00,0x6D,0x00,
	0x61,0x00,0x6E,0x00,0x64,0x00,0x69,0x00,0x61,0x00,0x73,0x00,0x2E,0x00,0x74,0x00,
	0x78,0x00,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x77,0x01,0x00,0x00,
	0x6F,0x02,0x00,0x00,0x2D,0x52,0xC9,0x6E,0xA4,0x30,0x10,0xBD,0xF3,0x15,0x95,0x53,
	0x2E,0xA8,0x3F,0xA0,0x6F,0x73,0x9B,0x48,0x59,0xA4,0x24,0xD2,0x9C,0xAB,0x71,0xD1,
	0x58,0xD8,0x2E,0xC6,0x65,0x40,0xE4,0xEB,0xF3,0x6C,0x5A,0x42,0x20,0xD5,0xF2,0xB6,
	0xE2,0x85,0xA2,0x14,0x62,0x2A,0x99,0x37,0x09,0x41,0x32,0x8D,0x59,0x23,0x71,0xC2,
	0x53,0xFC,0xFF,0x55,0x28,0x70,0x72,0xDD,0xBF,0x49,0xC9,0xD8,0xBB,0x2B,0x7D,0xEF,
	0x4A,0x1B,0x1B,0x76,0x92,0xC3,0xD6,0x9A,0xE6,0x20,0x66,0x14,0xE4,0x6E,0xA4,0x23,
	0x59,0xD1,0x24,0xDD,0x57,0xA9,0x5D,0x9F,0xA8,0x4C,0x42,0x4E,0x4C,0x72,0xB9,0xD0,
	0xBB,0x70,0xAE,0x85,0xD8,0x93,0x9E,0x1D,0xC3,0x54,0xDF,0xFD,0xE5,0x80,0x3D,0x00,
	0xF5,0xD0,0x61,0x13,0x97,0x22,0x59,0x1C,0x6D,0xDE,0xF8,0x0E,0x7A,0x2F,0xD6,0xD3,
	0x3E,0xA9,0x49,0x95,0xB6,0xA7,0xBE,0xFB,0x03,0xEC,0x3D,0xFB,0xCA,0xEC,0xD0,0x5F,
	0xFA,0xA6,0xC5,0x92,0x40,0x3D,0x24,0x0C,0x1A,0x1C,0x5E,0x31,0x36,0xF4,0x6F,0xB8,
	0x02,0x19,0x17,0xF2,0xC5,0xC8,0x86,0x35,0x2C,0x45,0x33,0xED,0x67,0xB9,0xA2,0x2E,
	0x6C,0xE6,0x35,0x19,0x65,0xE1,0xEA,0xD4,0x0F,0x13,0x1D,0x08,0xC5,0xD6,0xBC,0xF9,
	0x4D,0x7A,0x78,0xE2,0xB8,0x80,0xEA,0x54,0x6D,0x55,0xD3,0x28,0xCD,0x75,0x99,0x7C,
	0xBA,0x1B,0x48,0x60,0x66,0x6A,0x81,0x54,0xA2,0xA8,0xC3,0x2C,0xAE,0x59,0x3D,0x53,
	0xAA,0x5D,0x98,0x2F,0x67,0x7B,0x14,0x77,0x6D,0x1E,0x1E,0x29,0x00,0x5A,0x40,0x11,
	0x1E,0xE0,0xBB,0x66,0x67,0xC4,0xCB,0x82,0x8D,0x6B,0xF7,0xFC,0x76,0x50,0xE2,0x28,
	0xE4,0x8D,0x3E,0x7E,0x8E,0xEA,0xC9,0x33,0x02,0x99,0x41,0x5C,0xCD,0xD6,0xAF,0x5D,
	0xBB,0x57,0xD5,0xB9,0xE2,0xC5,0xA3,0xEE,0xCF,0x18,0x38,0x84,0xDE,0xFC,0x7D,0x2A,
	0xC7,0x99,0x0E,0x28,0x16,0xF6,0xF9,0xE9,0xB9,0x7B,0xD7,0xA6,0x9A,0x6E,0x62,0xDE,
	0x09,0x4C,0x47,0xF6,0xC9,0x2E,0xF4,0xA9,0xEB,0x43,0xAB,0x93,0x81,0x8F,0xEE,0x63,
	0x3C,0xE5,0x22,0x4E,0x35,0x83,0xBC,0x3D,0xCB,0x80,0x1B,0xDD,0xEA,0x5C,0x73,0x5F,
	0x71,0x6F,0x9C,0xA5,0xD9,0x0F,0xB8,0x7B,0xAB,0x04,0xC1,0x8F,0xD4,0x4E,0x8B,0xB8,
	0x4B,0x96,0x82,0x38,0x47,0x5C,0x9E,0x77,0x3E,0x2E,0xBF
};

GTEST_TEST(ERFFile22DeflateRaw, getNameHashAlgo) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DR));

	EXPECT_EQ(erf.getNameHashAlgo(), Common::kHashNone);
}

GTEST_TEST(ERFFile22DeflateRaw, getBuildYear) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DR));

	EXPECT_EQ(erf.getBuildYear(), 2000);
}

GTEST_TEST(ERFFile22DeflateRaw, getBuildDay) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DR));

	EXPECT_EQ(erf.getBuildDay(), 23);
}

GTEST_TEST(ERFFile22DeflateRaw, getDescription) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DR));

	const Aurora::LocString &description = erf.getDescription();

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile22DeflateRaw, getDescriptionStatic) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	Common::MemoryReadStream stream(kERFFile22DR);

	Aurora::LocString description = Aurora::ERFFile::getDescription(stream);

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile22DeflateRaw, getResources) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DR));

	const Aurora::ERFFile::ResourceList &resources = erf.getResources();
	ASSERT_EQ(resources.size(), 1);

	const Aurora::ERFFile::Resource &resource = *resources.begin();

	EXPECT_STREQ(resource.name.c_str(), "ozymandias");
	EXPECT_EQ(resource.type, Aurora::kFileTypeTXT);
	EXPECT_EQ(resource.hash, 0);
	EXPECT_EQ(resource.index, 0);
}

GTEST_TEST(ERFFile22DeflateRaw, getResourceSize) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DR));

	EXPECT_EQ(erf.getResourceSize(0), strlen(kFileData));

	EXPECT_THROW(erf.getResourceSize(1), Common::Exception);
}

GTEST_TEST(ERFFile22DeflateRaw, findResourceHash) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DR));

	EXPECT_EQ(erf.findResource(0), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile22DeflateRaw, findResourceName) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DR));

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeTXT), 0);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeBMP), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeBMP), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile22DeflateRaw, getResource) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22DR));

	Common::SeekableReadStream *file = erf.getResource(0);
	ASSERT_NE(file, static_cast<Common::SeekableReadStream *>(0));

	ASSERT_EQ(file->size(), strlen(kFileData));

	for (size_t i = 0; i < strlen(kFileData); i++)
		EXPECT_EQ(file->readByte(), kFileData[i]) << "At index " << i;

	delete file;
}

// --- ERF V2.2 (Blowfish) ---

// Percy Bysshe Shelley's "Ozymandias", within an ERF V2.2 (Blowfish) file
static const byte kERFFile22B[] = {
	0x45,0x00,0x52,0x00,0x46,0x00,0x20,0x00,0x56,0x00,0x32,0x00,0x2E,0x00,0x32,0x00,
	0x01,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
	0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x86,0x22,0x37,0xF7,0x01,0xDD,0x26,
	0xBC,0x89,0xBB,0x79,0x06,0x95,0x0B,0x3A,0x6F,0x00,0x7A,0x00,0x79,0x00,0x6D,0x00,
	0x61,0x00,0x6E,0x00,0x64,0x00,0x69,0x00,0x61,0x00,0x73,0x00,0x2E,0x00,0x74,0x00,
	0x78,0x00,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x70,0x02,0x00,0x00,
	0x6F,0x02,0x00,0x00,0x11,0xB9,0x95,0x02,0xB3,0x10,0xED,0x65,0xB5,0xC1,0xAB,0x27,
	0x60,0xA9,0x98,0x56,0x65,0x3B,0x14,0xCC,0x88,0x98,0x0C,0xF9,0xB0,0xB7,0x03,0xFC,
	0x07,0x9C,0x3C,0x65,0x4C,0x42,0xB0,0x0C,0xC4,0x9F,0x5A,0x89,0x54,0xCC,0xE9,0x2B,
	0x04,0xB6,0xB6,0xF6,0x41,0x46,0xBC,0xFE,0x42,0x85,0x9D,0x2F,0x25,0x03,0x52,0x70,
	0x42,0xB3,0x3A,0xD5,0x85,0x05,0xA8,0x23,0xB4,0xC5,0x54,0xEC,0x88,0x7C,0xE6,0xA1,
	0x8D,0xDE,0x5F,0x4A,0x07,0x7F,0x7E,0xA3,0xEA,0x50,0x7E,0xDF,0xA4,0x30,0x76,0x8E,
	0x6F,0xC5,0x96,0xE4,0xF9,0x38,0xB8,0x59,0xAD,0x7B,0x32,0x5F,0x41,0x45,0x74,0x04,
	0xF0,0x72,0x18,0xAB,0x76,0x0E,0x0C,0x70,0x5C,0x1F,0x39,0xA5,0xB7,0x2B,0xFF,0xCB,
	0x22,0x61,0xB0,0xD4,0x28,0xA4,0x05,0x25,0x0E,0x00,0x16,0xAB,0xD4,0xBE,0xE4,0xFA,
	0xEA,0x4C,0x27,0x01,0xD8,0xA1,0x56,0xAC,0xBF,0x35,0x54,0x08,0x07,0x78,0x88,0x4D,
	0xAF,0x60,0x93,0xD4,0xFB,0xE5,0xA1,0xE2,0xD7,0xA1,0x02,0x98,0xD9,0x1F,0x9C,0x1E,
	0xF5,0x18,0xA5,0xF3,0xD2,0x12,0x29,0x52,0x7F,0x62,0x46,0xC4,0x07,0x29,0x7E,0xB3,
	0x2F,0x16,0xB9,0xDC,0xE5,0x47,0x06,0xA6,0xE5,0x3B,0xC4,0xA7,0x14,0xFE,0x2A,0x36,
	0x53,0x7F,0x04,0xFA,0x3F,0x04,0xF8,0x69,0x8F,0xF1,0x99,0x03,0x36,0xDC,0x46,0xC2,
	0x3C,0xEC,0x1E,0x7A,0x51,0xD0,0x2D,0xC8,0x10,0x81,0x56,0xDF,0x78,0xD2,0xBA,0xB7,
	0x1C,0xD2,0x38,0xC9,0x31,0x8D,0xDD,0xE4,0x45,0xFC,0x72,0x3F,0xE5,0x5A,0xD1,0x43,
	0x3E,0x0B,0xEC,0x11,0x1C,0xE9,0x8C,0xDA,0xFD,0x84,0xE6,0x01,0x23,0x33,0x29,0x04,
	0xC1,0x7D,0x8E,0xDC,0xB5,0xC5,0xEF,0x25,0x03,0x06,0xBC,0xE9,0xEE,0xA1,0x0A,0x0F,
	0xCA,0x1E,0x2A,0xB5,0x70,0x76,0x84,0xDF,0xE6,0x50,0x96,0xEB,0xAA,0x2B,0x09,0xB9,
	0xDC,0x76,0x96,0xAB,0x01,0xAC,0x6D,0x41,0x35,0xD3,0x97,0x17,0x70,0xD7,0xB2,0x31,
	0xA7,0x31,0x59,0xB0,0x78,0x96,0xDE,0x8A,0x93,0xEA,0x19,0xD9,0x62,0x3B,0x25,0xA0,
	0x8B,0xE2,0x7F,0x9D,0xC2,0xF5,0x59,0x30,0x71,0xEE,0x7B,0x1C,0x21,0x9A,0xD5,0x60,
	0x81,0x54,0xBD,0x8F,0x1F,0x5C,0x7B,0xD5,0x2C,0x8C,0x0B,0xAC,0xF1,0xD6,0x1B,0xF9,
	0x14,0xBB,0x44,0x3D,0x5D,0x64,0xE8,0x9C,0x02,0x1F,0xF7,0xA8,0x5C,0x40,0x19,0x60,
	0x92,0x6F,0xA4,0x5A,0x36,0x10,0x9C,0x2C,0xFE,0xBB,0x38,0x5E,0xA3,0xAD,0x51,0xC5,
	0x93,0xB9,0x1E,0xA2,0x07,0x38,0x4E,0x02,0x74,0x9A,0x8D,0xA9,0x81,0x26,0xC6,0x50,
	0xFF,0xD7,0x0F,0x99,0x96,0x81,0x06,0x6E,0x18,0x0F,0x4E,0xB6,0xC4,0x1D,0x84,0x7F,
	0xD4,0x8C,0x2B,0xDF,0x67,0x8B,0xC8,0xA9,0xF8,0xE1,0xC1,0x01,0x49,0x49,0xD7,0x8E,
	0x45,0xAA,0x82,0xFB,0xE0,0xEC,0x00,0x9A,0xD1,0x66,0x7D,0x19,0xA8,0xAE,0x2E,0x03,
	0x84,0xCF,0x85,0x8B,0x46,0xDF,0xB2,0xD7,0xA4,0x23,0xD1,0x18,0x91,0x98,0x34,0xA5,
	0xC5,0x94,0x55,0x07,0x04,0xD4,0xF5,0x2C,0x62,0xB0,0xEF,0x75,0x16,0xB6,0x23,0x8F,
	0x90,0xC7,0x6E,0xA4,0x99,0x5F,0x94,0x1C,0xC0,0xC0,0xEA,0xF4,0x10,0x88,0x1C,0xEB,
	0xD0,0x50,0x8D,0x0D,0x02,0x94,0x4A,0x5A,0x46,0xF8,0x40,0x9F,0xCB,0x80,0xA1,0xC9,
	0x17,0xDE,0x2F,0x83,0x48,0x29,0xF9,0x91,0x4F,0x2B,0x6E,0x4E,0x4E,0xB9,0x44,0x01,
	0xD1,0xF3,0x54,0x4E,0xD8,0x54,0xF5,0xC2,0x12,0x47,0xE4,0x1D,0x28,0x3E,0x18,0x1E,
	0x30,0x46,0x35,0x32,0x32,0x62,0x18,0x68,0xA1,0x70,0x60,0x92,0xF0,0x2B,0xB1,0x43,
	0x3D,0x13,0x87,0x06,0x4E,0x79,0xD5,0x0B,0x54,0x1E,0x7F,0xB4,0x9F,0x96,0x1E,0x40,
	0xC5,0xBB,0x69,0xAD,0xD3,0x88,0x38,0x00,0xE8,0x33,0xDF,0x12,0xC6,0x91,0xF5,0xF7,
	0x51,0xBF,0xB3,0xF9,0x12,0xC9,0x66,0x57,0x86,0x1A,0x92,0xBC,0x15,0xCD,0x3C,0xBC,
	0x35,0x06,0xC2,0x83,
};

static const byte kERF22BPassword[] = { 0x32,0x33,0x34,0x32,0x35 };

GTEST_TEST(ERFFile22Blowfish, getNameHashAlgo) {
	PasswordStore password(kERF22BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22B), password);

	EXPECT_EQ(erf.getNameHashAlgo(), Common::kHashNone);
}

GTEST_TEST(ERFFile22Blowfish, getBuildYear) {
	PasswordStore password(kERF22BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22B), password);

	EXPECT_EQ(erf.getBuildYear(), 2000);
}

GTEST_TEST(ERFFile22Blowfish, getBuildDay) {
	PasswordStore password(kERF22BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22B), password);

	EXPECT_EQ(erf.getBuildDay(), 23);
}

GTEST_TEST(ERFFile22Blowfish, getDescription) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	PasswordStore password(kERF22BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22B), password);

	const Aurora::LocString &description = erf.getDescription();

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile22Blowfish, getDescriptionStatic) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	Common::MemoryReadStream stream(kERFFile22B);

	Aurora::LocString description = Aurora::ERFFile::getDescription(stream);

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile22Blowfish, getResources) {
	PasswordStore password(kERF22BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22B), password);

	const Aurora::ERFFile::ResourceList &resources = erf.getResources();
	ASSERT_EQ(resources.size(), 1);

	const Aurora::ERFFile::Resource &resource = *resources.begin();

	EXPECT_STREQ(resource.name.c_str(), "ozymandias");
	EXPECT_EQ(resource.type, Aurora::kFileTypeTXT);
	EXPECT_EQ(resource.hash, 0);
	EXPECT_EQ(resource.index, 0);
}

GTEST_TEST(ERFFile22Blowfish, getResourceSize) {
	PasswordStore password(kERF22BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22B), password);

	EXPECT_EQ(erf.getResourceSize(0), strlen(kFileData));

	EXPECT_THROW(erf.getResourceSize(1), Common::Exception);
}

GTEST_TEST(ERFFile22Blowfish, findResourceHash) {
	PasswordStore password(kERF22BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22B), password);

	EXPECT_EQ(erf.findResource(0), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile22Blowfish, findResourceName) {
	PasswordStore password(kERF22BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22B), password);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeTXT), 0);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeBMP), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeBMP), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile22Blowfish, getResource) {
	PasswordStore password(kERF22BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22B), password);

	Common::SeekableReadStream *file = erf.getResource(0);
	ASSERT_NE(file, static_cast<Common::SeekableReadStream *>(0));

	ASSERT_EQ(file->size(), strlen(kFileData));

	for (size_t i = 0; i < strlen(kFileData); i++)
		EXPECT_EQ(file->readByte(), kFileData[i]) << "At index " << i;

	delete file;
}

// --- ERF V2.2 (Blowfish + raw DEFLATE) ---

// Percy Bysshe Shelley's "Ozymandias", within an ERF V2.2 (Blowfish + raw DEFLATE) file
static const byte kERFFile22BDR[] = {
	0x45,0x00,0x52,0x00,0x46,0x00,0x20,0x00,0x56,0x00,0x32,0x00,0x2E,0x00,0x32,0x00,
	0x01,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
	0x20,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x38,0x86,0x22,0x37,0xF7,0x01,0xDD,0x26,
	0xBC,0x89,0xBB,0x79,0x06,0x95,0x0B,0x3A,0x6F,0x00,0x7A,0x00,0x79,0x00,0x6D,0x00,
	0x61,0x00,0x6E,0x00,0x64,0x00,0x69,0x00,0x61,0x00,0x73,0x00,0x2E,0x00,0x74,0x00,
	0x78,0x00,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x78,0x01,0x00,0x00,
	0x6F,0x02,0x00,0x00,0x6B,0x95,0x6B,0xDA,0xCC,0x20,0x24,0xA9,0xB4,0x14,0x40,0xED,
	0xA5,0xAE,0x5C,0x5D,0x37,0x14,0xFE,0x30,0x6E,0x81,0x1B,0x71,0xBC,0xA4,0xE3,0xAA,
	0x3B,0x98,0x06,0x3A,0xE0,0xAD,0x0F,0x41,0x2E,0x58,0x00,0xC7,0xF7,0xDC,0xF0,0x6C,
	0x26,0x09,0xA9,0xDF,0xE6,0x68,0x33,0xA0,0x57,0x73,0xC8,0x41,0xB5,0x54,0xCA,0x55,
	0x59,0x19,0xB2,0x8D,0x59,0x06,0x30,0x59,0xBD,0xC0,0xC4,0x65,0xF0,0x34,0x4A,0xF4,
	0xD6,0x1A,0x21,0x9E,0x72,0x1E,0xB6,0x65,0x2E,0xDF,0xFF,0xB5,0x3E,0x79,0x2B,0xCD,
	0x52,0x40,0x46,0x8D,0x6A,0x57,0x9A,0xF1,0xEA,0x56,0x2A,0x12,0x81,0xEC,0x6C,0x11,
	0x20,0x2A,0x03,0x9D,0x0E,0xA7,0xD8,0xFA,0xF7,0xF9,0x70,0x66,0x12,0xFE,0x6B,0x6D,
	0xAD,0x71,0x6A,0x12,0x23,0xC9,0xCF,0x9F,0xB7,0xD3,0x3E,0x1C,0xD5,0xD6,0xEE,0x11,
	0xA1,0x9A,0x6A,0x17,0x62,0x6B,0x81,0xCA,0x23,0xAC,0x72,0x90,0xA1,0x89,0x20,0xDC,
	0x33,0x6E,0x0B,0x65,0x8C,0xD3,0x94,0x23,0x15,0x78,0x55,0x3A,0xEF,0xFA,0x8F,0xE1,
	0x2C,0x59,0x39,0x21,0xA5,0x58,0xE8,0xE3,0xDC,0xC1,0xED,0x54,0x69,0x28,0xCA,0xAC,
	0xBD,0xFD,0x4B,0x51,0x11,0xD1,0x70,0xB9,0x8E,0xAA,0xF5,0x70,0x99,0xEB,0xA1,0xFF,
	0xDA,0x9A,0xC5,0x0B,0x5E,0x04,0xC3,0x48,0xE8,0x4F,0x27,0xE8,0x80,0x1E,0xF3,0x04,
	0xFF,0xF7,0xA9,0x42,0x7E,0xDF,0x0B,0xCE,0xAC,0x8B,0x0A,0x63,0xF2,0x92,0x70,0xAD,
	0xD9,0xC7,0x1B,0x7A,0xD2,0x41,0x3E,0x06,0x2A,0x5B,0xC5,0x3E,0xDA,0x2B,0x7F,0x00,
	0xB4,0x07,0x97,0x3E,0x97,0x3D,0xEC,0x61,0xBE,0x32,0xB7,0x12,0x1B,0x75,0x75,0xDB,
	0xCD,0x79,0x13,0x14,0xDC,0xA4,0xEB,0xC4,0x10,0x72,0x41,0xB9,0x70,0xDF,0x65,0x55,
	0x3E,0x6E,0xE8,0xB7,0xA6,0xAB,0xDA,0x78,0x5C,0xEF,0xA7,0x19,0x2C,0x78,0x4E,0x9F,
	0xD9,0x73,0x4E,0x35,0xF1,0xF3,0xB9,0xEF,0xA4,0x2C,0x8E,0x5C,0xBA,0x5B,0xEF,0x30,
	0xB2,0x84,0x7F,0x3C,0xE1,0x15,0x12,0x65,0x31,0x29,0x87,0x25,0x64,0x2C,0xA8,0xBD,
	0xA5,0x2B,0x81,0x39,0xBD,0x96,0x16,0xA7,0x3B,0x7A,0xCC,0x55,0x7C,0x7A,0xA7,0xD3,
	0x7A,0x20,0x1E,0xEB,0x5D,0x74,0x17,0x08,0x5C,0x2E,0x1E,0x2A,0xAF,0xAC,0x8E,0xB9,
	0x9E,0xA7,0x39,0xA9,0x94,0xDD,0xD4,0x71,0x54,0x88,0x00,0xE9
};

static const byte kERF22BDRPassword[] = { 0x32,0x33,0x34,0x32,0x35 };

GTEST_TEST(ERFFile22BlowfishDeflateRaw, getNameHashAlgo) {
	PasswordStore password(kERF22BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22BDR), password);

	EXPECT_EQ(erf.getNameHashAlgo(), Common::kHashNone);
}

GTEST_TEST(ERFFile22BlowfishDeflateRaw, getBuildYear) {
	PasswordStore password(kERF22BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22BDR), password);

	EXPECT_EQ(erf.getBuildYear(), 2000);
}

GTEST_TEST(ERFFile22BlowfishDeflateRaw, getBuildDay) {
	PasswordStore password(kERF22BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22BDR), password);

	EXPECT_EQ(erf.getBuildDay(), 23);
}

GTEST_TEST(ERFFile22BlowfishDeflateRaw, getDescription) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	PasswordStore password(kERF22BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22BDR), password);

	const Aurora::LocString &description = erf.getDescription();

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile22BlowfishDeflateRaw, getDescriptionStatic) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	Common::MemoryReadStream stream(kERFFile22BDR);

	Aurora::LocString description = Aurora::ERFFile::getDescription(stream);

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile22BlowfishDeflateRaw, getResources) {
	PasswordStore password(kERF22BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22BDR), password);

	const Aurora::ERFFile::ResourceList &resources = erf.getResources();
	ASSERT_EQ(resources.size(), 1);

	const Aurora::ERFFile::Resource &resource = *resources.begin();

	EXPECT_STREQ(resource.name.c_str(), "ozymandias");
	EXPECT_EQ(resource.type, Aurora::kFileTypeTXT);
	EXPECT_EQ(resource.hash, 0);
	EXPECT_EQ(resource.index, 0);
}

GTEST_TEST(ERFFile22BlowfishDeflateRaw, getResourceSize) {
	PasswordStore password(kERF22BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22BDR), password);

	EXPECT_EQ(erf.getResourceSize(0), strlen(kFileData));

	EXPECT_THROW(erf.getResourceSize(1), Common::Exception);
}

GTEST_TEST(ERFFile22BlowfishDeflateRaw, findResourceHash) {
	PasswordStore password(kERF22BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22BDR), password);

	EXPECT_EQ(erf.findResource(0), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile22BlowfishDeflateRaw, findResourceName) {
	PasswordStore password(kERF22BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22BDR), password);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeTXT), 0);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeBMP), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeBMP), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile22BlowfishDeflateRaw, getResource) {
	PasswordStore password(kERF22BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile22BDR), password);

	Common::SeekableReadStream *file = erf.getResource(0);
	ASSERT_NE(file, static_cast<Common::SeekableReadStream *>(0));

	ASSERT_EQ(file->size(), strlen(kFileData));

	for (size_t i = 0; i < strlen(kFileData); i++)
		EXPECT_EQ(file->readByte(), kFileData[i]) << "At index " << i;

	delete file;
}

// --- ERF V3.0 (plain) ---

// Percy Bysshe Shelley's "Ozymandias", within an ERF V3.0 (plain) file
static const byte kERFFile30Plain[] = {
	0x45,0x00,0x52,0x00,0x46,0x00,0x20,0x00,0x56,0x00,0x33,0x00,0x2E,0x00,0x30,0x00,
	0x0F,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x6F,0x7A,0x79,0x6D,0x61,0x6E,0x64,0x69,0x61,0x73,0x2E,0x74,0x78,0x74,0x00,0x00,
	0x00,0x00,0x00,0xEA,0x54,0xB9,0xC3,0xF9,0x70,0x3C,0x67,0x5F,0xAB,0x6C,0x2B,0x5B,
	0x00,0x00,0x00,0x6F,0x02,0x00,0x00,0x6F,0x02,0x00,0x00,0x49,0x20,0x6D,0x65,0x74,
	0x20,0x61,0x20,0x74,0x72,0x61,0x76,0x65,0x6C,0x6C,0x65,0x72,0x20,0x66,0x72,0x6F,
	0x6D,0x20,0x61,0x6E,0x20,0x61,0x6E,0x74,0x69,0x71,0x75,0x65,0x20,0x6C,0x61,0x6E,
	0x64,0x0A,0x57,0x68,0x6F,0x20,0x73,0x61,0x69,0x64,0x3A,0x20,0x54,0x77,0x6F,0x20,
	0x76,0x61,0x73,0x74,0x20,0x61,0x6E,0x64,0x20,0x74,0x72,0x75,0x6E,0x6B,0x6C,0x65,
	0x73,0x73,0x20,0x6C,0x65,0x67,0x73,0x20,0x6F,0x66,0x20,0x73,0x74,0x6F,0x6E,0x65,
	0x0A,0x53,0x74,0x61,0x6E,0x64,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x64,0x65,
	0x73,0x65,0x72,0x74,0x2E,0x20,0x4E,0x65,0x61,0x72,0x20,0x74,0x68,0x65,0x6D,0x2C,
	0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,0x20,0x73,0x61,0x6E,0x64,0x2C,0x0A,0x48,0x61,
	0x6C,0x66,0x20,0x73,0x75,0x6E,0x6B,0x2C,0x20,0x61,0x20,0x73,0x68,0x61,0x74,0x74,
	0x65,0x72,0x65,0x64,0x20,0x76,0x69,0x73,0x61,0x67,0x65,0x20,0x6C,0x69,0x65,0x73,
	0x2C,0x20,0x77,0x68,0x6F,0x73,0x65,0x20,0x66,0x72,0x6F,0x77,0x6E,0x2C,0x0A,0x41,
	0x6E,0x64,0x20,0x77,0x72,0x69,0x6E,0x6B,0x6C,0x65,0x64,0x20,0x6C,0x69,0x70,0x2C,
	0x20,0x61,0x6E,0x64,0x20,0x73,0x6E,0x65,0x65,0x72,0x20,0x6F,0x66,0x20,0x63,0x6F,
	0x6C,0x64,0x20,0x63,0x6F,0x6D,0x6D,0x61,0x6E,0x64,0x2C,0x0A,0x54,0x65,0x6C,0x6C,
	0x20,0x74,0x68,0x61,0x74,0x20,0x69,0x74,0x73,0x20,0x73,0x63,0x75,0x6C,0x70,0x74,
	0x6F,0x72,0x20,0x77,0x65,0x6C,0x6C,0x20,0x74,0x68,0x6F,0x73,0x65,0x20,0x70,0x61,
	0x73,0x73,0x69,0x6F,0x6E,0x73,0x20,0x72,0x65,0x61,0x64,0x0A,0x57,0x68,0x69,0x63,
	0x68,0x20,0x79,0x65,0x74,0x20,0x73,0x75,0x72,0x76,0x69,0x76,0x65,0x2C,0x20,0x73,
	0x74,0x61,0x6D,0x70,0x65,0x64,0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,0x73,0x65,0x20,
	0x6C,0x69,0x66,0x65,0x6C,0x65,0x73,0x73,0x20,0x74,0x68,0x69,0x6E,0x67,0x73,0x2C,
	0x0A,0x54,0x68,0x65,0x20,0x68,0x61,0x6E,0x64,0x20,0x74,0x68,0x61,0x74,0x20,0x6D,
	0x6F,0x63,0x6B,0x65,0x64,0x20,0x74,0x68,0x65,0x6D,0x20,0x61,0x6E,0x64,0x20,0x74,
	0x68,0x65,0x20,0x68,0x65,0x61,0x72,0x74,0x20,0x74,0x68,0x61,0x74,0x20,0x66,0x65,
	0x64,0x3A,0x0A,0x41,0x6E,0x64,0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,0x20,0x70,0x65,
	0x64,0x65,0x73,0x74,0x61,0x6C,0x20,0x74,0x68,0x65,0x73,0x65,0x20,0x77,0x6F,0x72,
	0x64,0x73,0x20,0x61,0x70,0x70,0x65,0x61,0x72,0x3A,0x0A,0x27,0x4D,0x79,0x20,0x6E,
	0x61,0x6D,0x65,0x20,0x69,0x73,0x20,0x4F,0x7A,0x79,0x6D,0x61,0x6E,0x64,0x69,0x61,
	0x73,0x2C,0x20,0x6B,0x69,0x6E,0x67,0x20,0x6F,0x66,0x20,0x6B,0x69,0x6E,0x67,0x73,
	0x3A,0x0A,0x4C,0x6F,0x6F,0x6B,0x20,0x6F,0x6E,0x20,0x6D,0x79,0x20,0x77,0x6F,0x72,
	0x6B,0x73,0x2C,0x20,0x79,0x65,0x20,0x4D,0x69,0x67,0x68,0x74,0x79,0x2C,0x20,0x61,
	0x6E,0x64,0x20,0x64,0x65,0x73,0x70,0x61,0x69,0x72,0x21,0x27,0x0A,0x4E,0x6F,0x74,
	0x68,0x69,0x6E,0x67,0x20,0x62,0x65,0x73,0x69,0x64,0x65,0x20,0x72,0x65,0x6D,0x61,
	0x69,0x6E,0x73,0x2E,0x20,0x52,0x6F,0x75,0x6E,0x64,0x20,0x74,0x68,0x65,0x20,0x64,
	0x65,0x63,0x61,0x79,0x0A,0x4F,0x66,0x20,0x74,0x68,0x61,0x74,0x20,0x63,0x6F,0x6C,
	0x6F,0x73,0x73,0x61,0x6C,0x20,0x77,0x72,0x65,0x63,0x6B,0x2C,0x20,0x62,0x6F,0x75,
	0x6E,0x64,0x6C,0x65,0x73,0x73,0x20,0x61,0x6E,0x64,0x20,0x62,0x61,0x72,0x65,0x0A,
	0x54,0x68,0x65,0x20,0x6C,0x6F,0x6E,0x65,0x20,0x61,0x6E,0x64,0x20,0x6C,0x65,0x76,
	0x65,0x6C,0x20,0x73,0x61,0x6E,0x64,0x73,0x20,0x73,0x74,0x72,0x65,0x74,0x63,0x68,
	0x20,0x66,0x61,0x72,0x20,0x61,0x77,0x61,0x79,0x2E
};

GTEST_TEST(ERFFile30Plain, getNameHashAlgo) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30Plain));

	EXPECT_EQ(erf.getNameHashAlgo(), Common::kHashFNV64);
}

GTEST_TEST(ERFFile30Plain, getBuildYear) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30Plain));

	EXPECT_EQ(erf.getBuildYear(), 0);
}

GTEST_TEST(ERFFile30Plain, getBuildDay) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30Plain));

	EXPECT_EQ(erf.getBuildDay(), 0);
}

GTEST_TEST(ERFFile30Plain, getDescription) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30Plain));

	const Aurora::LocString &description = erf.getDescription();

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile30Plain, getDescriptionStatic) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	Common::MemoryReadStream stream(kERFFile30Plain);

	Aurora::LocString description = Aurora::ERFFile::getDescription(stream);

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile30Plain, getResources) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30Plain));

	const Aurora::ERFFile::ResourceList &resources = erf.getResources();
	ASSERT_EQ(resources.size(), 1);

	const Aurora::ERFFile::Resource &resource = *resources.begin();

	EXPECT_STREQ(resource.name.c_str(), "ozymandias");
	EXPECT_EQ(resource.type, Aurora::kFileTypeTXT);
	EXPECT_EQ(resource.hash, Common::hashString("ozymandias.txt", Common::kHashFNV64));
	EXPECT_EQ(resource.index, 0);
}

GTEST_TEST(ERFFile30Plain, getResourceSize) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30Plain));

	EXPECT_EQ(erf.getResourceSize(0), strlen(kFileData));

	EXPECT_THROW(erf.getResourceSize(1), Common::Exception);
}

GTEST_TEST(ERFFile30Plain, findResourceHash) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30Plain));

	EXPECT_EQ(erf.findResource(Common::hashString("ozymandias.txt", Common::kHashFNV64)), 0);

	EXPECT_EQ(erf.findResource(0), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile30Plain, findResourceName) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30Plain));

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeTXT), 0);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeBMP), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeBMP), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile30Plain, getResource) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30Plain));

	Common::SeekableReadStream *file = erf.getResource(0);
	ASSERT_NE(file, static_cast<Common::SeekableReadStream *>(0));

	ASSERT_EQ(file->size(), strlen(kFileData));

	for (size_t i = 0; i < strlen(kFileData); i++)
		EXPECT_EQ(file->readByte(), kFileData[i]) << "At index " << i;

	delete file;
}

// --- ERF V3.0 (without filenames) ---

// Percy Bysshe Shelley's "Ozymandias", within an ERF V3.0 (without filenames) file
static const byte kERFFile30NoFilenames[] = {
	0x45,0x00,0x52,0x00,0x46,0x00,0x20,0x00,0x56,0x00,0x33,0x00,0x2E,0x00,0x30,0x00,
	0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0xFF,0xFF,0xFF,0xFF,0xEA,0x54,0xB9,0xC3,0xF9,0x70,0x3C,0x67,0x5F,0xAB,0x6C,0x2B,
	0x4C,0x00,0x00,0x00,0x6F,0x02,0x00,0x00,0x6F,0x02,0x00,0x00,0x49,0x20,0x6D,0x65,
	0x74,0x20,0x61,0x20,0x74,0x72,0x61,0x76,0x65,0x6C,0x6C,0x65,0x72,0x20,0x66,0x72,
	0x6F,0x6D,0x20,0x61,0x6E,0x20,0x61,0x6E,0x74,0x69,0x71,0x75,0x65,0x20,0x6C,0x61,
	0x6E,0x64,0x0A,0x57,0x68,0x6F,0x20,0x73,0x61,0x69,0x64,0x3A,0x20,0x54,0x77,0x6F,
	0x20,0x76,0x61,0x73,0x74,0x20,0x61,0x6E,0x64,0x20,0x74,0x72,0x75,0x6E,0x6B,0x6C,
	0x65,0x73,0x73,0x20,0x6C,0x65,0x67,0x73,0x20,0x6F,0x66,0x20,0x73,0x74,0x6F,0x6E,
	0x65,0x0A,0x53,0x74,0x61,0x6E,0x64,0x20,0x69,0x6E,0x20,0x74,0x68,0x65,0x20,0x64,
	0x65,0x73,0x65,0x72,0x74,0x2E,0x20,0x4E,0x65,0x61,0x72,0x20,0x74,0x68,0x65,0x6D,
	0x2C,0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,0x20,0x73,0x61,0x6E,0x64,0x2C,0x0A,0x48,
	0x61,0x6C,0x66,0x20,0x73,0x75,0x6E,0x6B,0x2C,0x20,0x61,0x20,0x73,0x68,0x61,0x74,
	0x74,0x65,0x72,0x65,0x64,0x20,0x76,0x69,0x73,0x61,0x67,0x65,0x20,0x6C,0x69,0x65,
	0x73,0x2C,0x20,0x77,0x68,0x6F,0x73,0x65,0x20,0x66,0x72,0x6F,0x77,0x6E,0x2C,0x0A,
	0x41,0x6E,0x64,0x20,0x77,0x72,0x69,0x6E,0x6B,0x6C,0x65,0x64,0x20,0x6C,0x69,0x70,
	0x2C,0x20,0x61,0x6E,0x64,0x20,0x73,0x6E,0x65,0x65,0x72,0x20,0x6F,0x66,0x20,0x63,
	0x6F,0x6C,0x64,0x20,0x63,0x6F,0x6D,0x6D,0x61,0x6E,0x64,0x2C,0x0A,0x54,0x65,0x6C,
	0x6C,0x20,0x74,0x68,0x61,0x74,0x20,0x69,0x74,0x73,0x20,0x73,0x63,0x75,0x6C,0x70,
	0x74,0x6F,0x72,0x20,0x77,0x65,0x6C,0x6C,0x20,0x74,0x68,0x6F,0x73,0x65,0x20,0x70,
	0x61,0x73,0x73,0x69,0x6F,0x6E,0x73,0x20,0x72,0x65,0x61,0x64,0x0A,0x57,0x68,0x69,
	0x63,0x68,0x20,0x79,0x65,0x74,0x20,0x73,0x75,0x72,0x76,0x69,0x76,0x65,0x2C,0x20,
	0x73,0x74,0x61,0x6D,0x70,0x65,0x64,0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,0x73,0x65,
	0x20,0x6C,0x69,0x66,0x65,0x6C,0x65,0x73,0x73,0x20,0x74,0x68,0x69,0x6E,0x67,0x73,
	0x2C,0x0A,0x54,0x68,0x65,0x20,0x68,0x61,0x6E,0x64,0x20,0x74,0x68,0x61,0x74,0x20,
	0x6D,0x6F,0x63,0x6B,0x65,0x64,0x20,0x74,0x68,0x65,0x6D,0x20,0x61,0x6E,0x64,0x20,
	0x74,0x68,0x65,0x20,0x68,0x65,0x61,0x72,0x74,0x20,0x74,0x68,0x61,0x74,0x20,0x66,
	0x65,0x64,0x3A,0x0A,0x41,0x6E,0x64,0x20,0x6F,0x6E,0x20,0x74,0x68,0x65,0x20,0x70,
	0x65,0x64,0x65,0x73,0x74,0x61,0x6C,0x20,0x74,0x68,0x65,0x73,0x65,0x20,0x77,0x6F,
	0x72,0x64,0x73,0x20,0x61,0x70,0x70,0x65,0x61,0x72,0x3A,0x0A,0x27,0x4D,0x79,0x20,
	0x6E,0x61,0x6D,0x65,0x20,0x69,0x73,0x20,0x4F,0x7A,0x79,0x6D,0x61,0x6E,0x64,0x69,
	0x61,0x73,0x2C,0x20,0x6B,0x69,0x6E,0x67,0x20,0x6F,0x66,0x20,0x6B,0x69,0x6E,0x67,
	0x73,0x3A,0x0A,0x4C,0x6F,0x6F,0x6B,0x20,0x6F,0x6E,0x20,0x6D,0x79,0x20,0x77,0x6F,
	0x72,0x6B,0x73,0x2C,0x20,0x79,0x65,0x20,0x4D,0x69,0x67,0x68,0x74,0x79,0x2C,0x20,
	0x61,0x6E,0x64,0x20,0x64,0x65,0x73,0x70,0x61,0x69,0x72,0x21,0x27,0x0A,0x4E,0x6F,
	0x74,0x68,0x69,0x6E,0x67,0x20,0x62,0x65,0x73,0x69,0x64,0x65,0x20,0x72,0x65,0x6D,
	0x61,0x69,0x6E,0x73,0x2E,0x20,0x52,0x6F,0x75,0x6E,0x64,0x20,0x74,0x68,0x65,0x20,
	0x64,0x65,0x63,0x61,0x79,0x0A,0x4F,0x66,0x20,0x74,0x68,0x61,0x74,0x20,0x63,0x6F,
	0x6C,0x6F,0x73,0x73,0x61,0x6C,0x20,0x77,0x72,0x65,0x63,0x6B,0x2C,0x20,0x62,0x6F,
	0x75,0x6E,0x64,0x6C,0x65,0x73,0x73,0x20,0x61,0x6E,0x64,0x20,0x62,0x61,0x72,0x65,
	0x0A,0x54,0x68,0x65,0x20,0x6C,0x6F,0x6E,0x65,0x20,0x61,0x6E,0x64,0x20,0x6C,0x65,
	0x76,0x65,0x6C,0x20,0x73,0x61,0x6E,0x64,0x73,0x20,0x73,0x74,0x72,0x65,0x74,0x63,
	0x68,0x20,0x66,0x61,0x72,0x20,0x61,0x77,0x61,0x79,0x2E
};

GTEST_TEST(ERFFile30NoFilenames, getNameHashAlgo) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30NoFilenames));

	EXPECT_EQ(erf.getNameHashAlgo(), Common::kHashFNV64);
}

GTEST_TEST(ERFFile30NoFilenames, getBuildYear) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30NoFilenames));

	EXPECT_EQ(erf.getBuildYear(), 0);
}

GTEST_TEST(ERFFile30NoFilenames, getBuildDay) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30NoFilenames));

	EXPECT_EQ(erf.getBuildDay(), 0);
}

GTEST_TEST(ERFFile30NoFilenames, getDescription) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30NoFilenames));

	const Aurora::LocString &description = erf.getDescription();

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile30NoFilenames, getDescriptionStatic) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	Common::MemoryReadStream stream(kERFFile30NoFilenames);

	Aurora::LocString description = Aurora::ERFFile::getDescription(stream);

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile30NoFilenames, getResources) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30NoFilenames));

	const Aurora::ERFFile::ResourceList &resources = erf.getResources();
	ASSERT_EQ(resources.size(), 1);

	const Aurora::ERFFile::Resource &resource = *resources.begin();

	EXPECT_STREQ(resource.name.c_str(), "");
	EXPECT_EQ(resource.type, Aurora::kFileTypeTXT);
	EXPECT_EQ(resource.hash, Common::hashString("ozymandias.txt", Common::kHashFNV64));
	EXPECT_EQ(resource.index, 0);
}

GTEST_TEST(ERFFile30NoFilenames, getResourceSize) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30NoFilenames));

	EXPECT_EQ(erf.getResourceSize(0), strlen(kFileData));

	EXPECT_THROW(erf.getResourceSize(1), Common::Exception);
}

GTEST_TEST(ERFFile30NoFilenames, findResourceHash) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30NoFilenames));

	EXPECT_EQ(erf.findResource(Common::hashString("ozymandias.txt", Common::kHashFNV64)), 0);

	EXPECT_EQ(erf.findResource(0), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile30NoFilenames, findResourceName) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30NoFilenames));

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeBMP), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeBMP), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile30NoFilenames, getResource) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30NoFilenames));

	Common::SeekableReadStream *file = erf.getResource(0);
	ASSERT_NE(file, static_cast<Common::SeekableReadStream *>(0));

	ASSERT_EQ(file->size(), strlen(kFileData));

	for (size_t i = 0; i < strlen(kFileData); i++)
		EXPECT_EQ(file->readByte(), kFileData[i]) << "At index " << i;

	delete file;
}

// --- ERF V3.0 (DEFLATE, with header) ---

// Percy Bysshe Shelley's "Ozymandias", within an ERF V3.0 (DEFLATE, with header) file
static const byte kERFFile30DH[] = {
	0x45,0x00,0x52,0x00,0x46,0x00,0x20,0x00,0x56,0x00,0x33,0x00,0x2E,0x00,0x30,0x00,
	0x0F,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x6F,0x7A,0x79,0x6D,0x61,0x6E,0x64,0x69,0x61,0x73,0x2E,0x74,0x78,0x74,0x00,0x00,
	0x00,0x00,0x00,0xEA,0x54,0xB9,0xC3,0xF9,0x70,0x3C,0x67,0x5F,0xAB,0x6C,0x2B,0x5B,
	0x00,0x00,0x00,0x78,0x01,0x00,0x00,0x6F,0x02,0x00,0x00,0xF0,0x2D,0x52,0xC9,0x6E,
	0xA4,0x30,0x10,0xBD,0xF3,0x15,0x95,0x53,0x2E,0xA8,0x3F,0xA0,0x6F,0x73,0x9B,0x48,
	0x59,0xA4,0x24,0xD2,0x9C,0xAB,0x71,0xD1,0x58,0xD8,0x2E,0xC6,0x65,0x40,0xE4,0xEB,
	0xF3,0x6C,0x5A,0x42,0x20,0xD5,0xF2,0xB6,0xE2,0x85,0xA2,0x14,0x62,0x2A,0x99,0x37,
	0x09,0x41,0x32,0x8D,0x59,0x23,0x71,0xC2,0x53,0xFC,0xFF,0x55,0x28,0x70,0x72,0xDD,
	0xBF,0x49,0xC9,0xD8,0xBB,0x2B,0x7D,0xEF,0x4A,0x1B,0x1B,0x76,0x92,0xC3,0xD6,0x9A,
	0xE6,0x20,0x66,0x14,0xE4,0x6E,0xA4,0x23,0x59,0xD1,0x24,0xDD,0x57,0xA9,0x5D,0x9F,
	0xA8,0x4C,0x42,0x4E,0x4C,0x72,0xB9,0xD0,0xBB,0x70,0xAE,0x85,0xD8,0x93,0x9E,0x1D,
	0xC3,0x54,0xDF,0xFD,0xE5,0x80,0x3D,0x00,0xF5,0xD0,0x61,0x13,0x97,0x22,0x59,0x1C,
	0x6D,0xDE,0xF8,0x0E,0x7A,0x2F,0xD6,0xD3,0x3E,0xA9,0x49,0x95,0xB6,0xA7,0xBE,0xFB,
	0x03,0xEC,0x3D,0xFB,0xCA,0xEC,0xD0,0x5F,0xFA,0xA6,0xC5,0x92,0x40,0x3D,0x24,0x0C,
	0x1A,0x1C,0x5E,0x31,0x36,0xF4,0x6F,0xB8,0x02,0x19,0x17,0xF2,0xC5,0xC8,0x86,0x35,
	0x2C,0x45,0x33,0xED,0x67,0xB9,0xA2,0x2E,0x6C,0xE6,0x35,0x19,0x65,0xE1,0xEA,0xD4,
	0x0F,0x13,0x1D,0x08,0xC5,0xD6,0xBC,0xF9,0x4D,0x7A,0x78,0xE2,0xB8,0x80,0xEA,0x54,
	0x6D,0x55,0xD3,0x28,0xCD,0x75,0x99,0x7C,0xBA,0x1B,0x48,0x60,0x66,0x6A,0x81,0x54,
	0xA2,0xA8,0xC3,0x2C,0xAE,0x59,0x3D,0x53,0xAA,0x5D,0x98,0x2F,0x67,0x7B,0x14,0x77,
	0x6D,0x1E,0x1E,0x29,0x00,0x5A,0x40,0x11,0x1E,0xE0,0xBB,0x66,0x67,0xC4,0xCB,0x82,
	0x8D,0x6B,0xF7,0xFC,0x76,0x50,0xE2,0x28,0xE4,0x8D,0x3E,0x7E,0x8E,0xEA,0xC9,0x33,
	0x02,0x99,0x41,0x5C,0xCD,0xD6,0xAF,0x5D,0xBB,0x57,0xD5,0xB9,0xE2,0xC5,0xA3,0xEE,
	0xCF,0x18,0x38,0x84,0xDE,0xFC,0x7D,0x2A,0xC7,0x99,0x0E,0x28,0x16,0xF6,0xF9,0xE9,
	0xB9,0x7B,0xD7,0xA6,0x9A,0x6E,0x62,0xDE,0x09,0x4C,0x47,0xF6,0xC9,0x2E,0xF4,0xA9,
	0xEB,0x43,0xAB,0x93,0x81,0x8F,0xEE,0x63,0x3C,0xE5,0x22,0x4E,0x35,0x83,0xBC,0x3D,
	0xCB,0x80,0x1B,0xDD,0xEA,0x5C,0x73,0x5F,0x71,0x6F,0x9C,0xA5,0xD9,0x0F,0xB8,0x7B,
	0xAB,0x04,0xC1,0x8F,0xD4,0x4E,0x8B,0xB8,0x4B,0x96,0x82,0x38,0x47,0x5C,0x9E,0x77,
	0x3E,0x2E,0xBF
};

GTEST_TEST(ERFFile30DeflateHeader, getNameHashAlgo) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DH));

	EXPECT_EQ(erf.getNameHashAlgo(), Common::kHashFNV64);
}

GTEST_TEST(ERFFile30DeflateHeader, getBuildYear) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DH));

	EXPECT_EQ(erf.getBuildYear(), 0);
}

GTEST_TEST(ERFFile30DeflateHeader, getBuildDay) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DH));

	EXPECT_EQ(erf.getBuildDay(), 0);
}

GTEST_TEST(ERFFile30DeflateHeader, getDescription) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DH));

	const Aurora::LocString &description = erf.getDescription();

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile30DeflateHeader, getDescriptionStatic) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	Common::MemoryReadStream stream(kERFFile30DH);

	Aurora::LocString description = Aurora::ERFFile::getDescription(stream);

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile30DeflateHeader, getResources) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DH));

	const Aurora::ERFFile::ResourceList &resources = erf.getResources();
	ASSERT_EQ(resources.size(), 1);

	const Aurora::ERFFile::Resource &resource = *resources.begin();

	EXPECT_STREQ(resource.name.c_str(), "ozymandias");
	EXPECT_EQ(resource.type, Aurora::kFileTypeTXT);
	EXPECT_EQ(resource.hash, Common::hashString("ozymandias.txt", Common::kHashFNV64));
	EXPECT_EQ(resource.index, 0);
}

GTEST_TEST(ERFFile30DeflateHeader, getResourceSize) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DH));

	EXPECT_EQ(erf.getResourceSize(0), strlen(kFileData));

	EXPECT_THROW(erf.getResourceSize(1), Common::Exception);
}

GTEST_TEST(ERFFile30DeflateHeader, findResourceHash) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DH));

	EXPECT_EQ(erf.findResource(Common::hashString("ozymandias.txt", Common::kHashFNV64)), 0);

	EXPECT_EQ(erf.findResource(0), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile30DeflateHeader, findResourceName) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DH));

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeTXT), 0);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeBMP), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeBMP), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile30DeflateHeader, getResource) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DH));

	Common::SeekableReadStream *file = erf.getResource(0);
	ASSERT_NE(file, static_cast<Common::SeekableReadStream *>(0));

	ASSERT_EQ(file->size(), strlen(kFileData));

	for (size_t i = 0; i < strlen(kFileData); i++)
		EXPECT_EQ(file->readByte(), kFileData[i]) << "At index " << i;

	delete file;
}

// --- ERF V3.0 (DEFLATE, raw) ---

// Percy Bysshe Shelley's "Ozymandias", within an ERF V3.0 (DEFLATE, raw) file
static const byte kERFFile30DR[] = {
	0x45,0x00,0x52,0x00,0x46,0x00,0x20,0x00,0x56,0x00,0x33,0x00,0x2E,0x00,0x30,0x00,
	0x0F,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x6F,0x7A,0x79,0x6D,0x61,0x6E,0x64,0x69,0x61,0x73,0x2E,0x74,0x78,0x74,0x00,0x00,
	0x00,0x00,0x00,0xEA,0x54,0xB9,0xC3,0xF9,0x70,0x3C,0x67,0x5F,0xAB,0x6C,0x2B,0x5B,
	0x00,0x00,0x00,0x77,0x01,0x00,0x00,0x6F,0x02,0x00,0x00,0x2D,0x52,0xC9,0x6E,0xA4,
	0x30,0x10,0xBD,0xF3,0x15,0x95,0x53,0x2E,0xA8,0x3F,0xA0,0x6F,0x73,0x9B,0x48,0x59,
	0xA4,0x24,0xD2,0x9C,0xAB,0x71,0xD1,0x58,0xD8,0x2E,0xC6,0x65,0x40,0xE4,0xEB,0xF3,
	0x6C,0x5A,0x42,0x20,0xD5,0xF2,0xB6,0xE2,0x85,0xA2,0x14,0x62,0x2A,0x99,0x37,0x09,
	0x41,0x32,0x8D,0x59,0x23,0x71,0xC2,0x53,0xFC,0xFF,0x55,0x28,0x70,0x72,0xDD,0xBF,
	0x49,0xC9,0xD8,0xBB,0x2B,0x7D,0xEF,0x4A,0x1B,0x1B,0x76,0x92,0xC3,0xD6,0x9A,0xE6,
	0x20,0x66,0x14,0xE4,0x6E,0xA4,0x23,0x59,0xD1,0x24,0xDD,0x57,0xA9,0x5D,0x9F,0xA8,
	0x4C,0x42,0x4E,0x4C,0x72,0xB9,0xD0,0xBB,0x70,0xAE,0x85,0xD8,0x93,0x9E,0x1D,0xC3,
	0x54,0xDF,0xFD,0xE5,0x80,0x3D,0x00,0xF5,0xD0,0x61,0x13,0x97,0x22,0x59,0x1C,0x6D,
	0xDE,0xF8,0x0E,0x7A,0x2F,0xD6,0xD3,0x3E,0xA9,0x49,0x95,0xB6,0xA7,0xBE,0xFB,0x03,
	0xEC,0x3D,0xFB,0xCA,0xEC,0xD0,0x5F,0xFA,0xA6,0xC5,0x92,0x40,0x3D,0x24,0x0C,0x1A,
	0x1C,0x5E,0x31,0x36,0xF4,0x6F,0xB8,0x02,0x19,0x17,0xF2,0xC5,0xC8,0x86,0x35,0x2C,
	0x45,0x33,0xED,0x67,0xB9,0xA2,0x2E,0x6C,0xE6,0x35,0x19,0x65,0xE1,0xEA,0xD4,0x0F,
	0x13,0x1D,0x08,0xC5,0xD6,0xBC,0xF9,0x4D,0x7A,0x78,0xE2,0xB8,0x80,0xEA,0x54,0x6D,
	0x55,0xD3,0x28,0xCD,0x75,0x99,0x7C,0xBA,0x1B,0x48,0x60,0x66,0x6A,0x81,0x54,0xA2,
	0xA8,0xC3,0x2C,0xAE,0x59,0x3D,0x53,0xAA,0x5D,0x98,0x2F,0x67,0x7B,0x14,0x77,0x6D,
	0x1E,0x1E,0x29,0x00,0x5A,0x40,0x11,0x1E,0xE0,0xBB,0x66,0x67,0xC4,0xCB,0x82,0x8D,
	0x6B,0xF7,0xFC,0x76,0x50,0xE2,0x28,0xE4,0x8D,0x3E,0x7E,0x8E,0xEA,0xC9,0x33,0x02,
	0x99,0x41,0x5C,0xCD,0xD6,0xAF,0x5D,0xBB,0x57,0xD5,0xB9,0xE2,0xC5,0xA3,0xEE,0xCF,
	0x18,0x38,0x84,0xDE,0xFC,0x7D,0x2A,0xC7,0x99,0x0E,0x28,0x16,0xF6,0xF9,0xE9,0xB9,
	0x7B,0xD7,0xA6,0x9A,0x6E,0x62,0xDE,0x09,0x4C,0x47,0xF6,0xC9,0x2E,0xF4,0xA9,0xEB,
	0x43,0xAB,0x93,0x81,0x8F,0xEE,0x63,0x3C,0xE5,0x22,0x4E,0x35,0x83,0xBC,0x3D,0xCB,
	0x80,0x1B,0xDD,0xEA,0x5C,0x73,0x5F,0x71,0x6F,0x9C,0xA5,0xD9,0x0F,0xB8,0x7B,0xAB,
	0x04,0xC1,0x8F,0xD4,0x4E,0x8B,0xB8,0x4B,0x96,0x82,0x38,0x47,0x5C,0x9E,0x77,0x3E,
	0x2E,0xBF
};

GTEST_TEST(ERFFile30DeflateRaw, getNameHashAlgo) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DR));

	EXPECT_EQ(erf.getNameHashAlgo(), Common::kHashFNV64);
}

GTEST_TEST(ERFFile30DeflateRaw, getBuildYear) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DR));

	EXPECT_EQ(erf.getBuildYear(), 0);
}

GTEST_TEST(ERFFile30DeflateRaw, getBuildDay) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DR));

	EXPECT_EQ(erf.getBuildDay(), 0);
}

GTEST_TEST(ERFFile30DeflateRaw, getDescription) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DR));

	const Aurora::LocString &description = erf.getDescription();

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile30DeflateRaw, getDescriptionStatic) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	Common::MemoryReadStream stream(kERFFile30DR);

	Aurora::LocString description = Aurora::ERFFile::getDescription(stream);

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile30DeflateRaw, getResources) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DR));

	const Aurora::ERFFile::ResourceList &resources = erf.getResources();
	ASSERT_EQ(resources.size(), 1);

	const Aurora::ERFFile::Resource &resource = *resources.begin();

	EXPECT_STREQ(resource.name.c_str(), "ozymandias");
	EXPECT_EQ(resource.type, Aurora::kFileTypeTXT);
	EXPECT_EQ(resource.hash, Common::hashString("ozymandias.txt", Common::kHashFNV64));
	EXPECT_EQ(resource.index, 0);
}

GTEST_TEST(ERFFile30DeflateRaw, getResourceSize) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DR));

	EXPECT_EQ(erf.getResourceSize(0), strlen(kFileData));

	EXPECT_THROW(erf.getResourceSize(1), Common::Exception);
}

GTEST_TEST(ERFFile30DeflateRaw, findResourceHash) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DR));

	EXPECT_EQ(erf.findResource(Common::hashString("ozymandias.txt", Common::kHashFNV64)), 0);

	EXPECT_EQ(erf.findResource(0), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile30DeflateRaw, findResourceName) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DR));

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeTXT), 0);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeBMP), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeBMP), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile30DeflateRaw, getResource) {
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30DR));

	Common::SeekableReadStream *file = erf.getResource(0);
	ASSERT_NE(file, static_cast<Common::SeekableReadStream *>(0));

	ASSERT_EQ(file->size(), strlen(kFileData));

	for (size_t i = 0; i < strlen(kFileData); i++)
		EXPECT_EQ(file->readByte(), kFileData[i]) << "At index " << i;

	delete file;
}

// --- ERF V3.0 (Blowfish) ---

// Percy Bysshe Shelley's "Ozymandias", within an ERF V3.0 (Blowfish) file
static const byte kERFFile30B[] = {
	0x45,0x00,0x52,0x00,0x46,0x00,0x20,0x00,0x56,0x00,0x33,0x00,0x2E,0x00,0x30,0x00,
	0x0F,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x6A,0xF7,0xEF,0xA2,0x07,0x16,0x81,0x73,0xEE,0x69,0xE2,0x34,0x35,0x50,0x7C,0xE9,
	0x6F,0x7A,0x79,0x6D,0x61,0x6E,0x64,0x69,0x61,0x73,0x2E,0x74,0x78,0x74,0x00,0x00,
	0x00,0x00,0x00,0xEA,0x54,0xB9,0xC3,0xF9,0x70,0x3C,0x67,0x5F,0xAB,0x6C,0x2B,0x5B,
	0x00,0x00,0x00,0x70,0x02,0x00,0x00,0x6F,0x02,0x00,0x00,0x2F,0x42,0x87,0xE4,0x78,
	0x45,0xC3,0x21,0x5F,0xB5,0x72,0xD3,0x36,0x4A,0xED,0xE9,0xF9,0x3D,0x78,0xEE,0xDD,
	0xAE,0x5E,0xBB,0x8D,0x5F,0x48,0x0D,0x68,0x0F,0xC1,0x0C,0x3B,0x3E,0x98,0x7F,0xD9,
	0xFC,0x7B,0xF6,0xF7,0xC3,0x7A,0x1E,0xCE,0x01,0xE8,0xA3,0x78,0xBA,0x88,0x03,0x6C,
	0xC6,0xC0,0x52,0xF8,0x45,0x62,0xD6,0x2C,0x60,0xFF,0x50,0xEA,0x97,0xEF,0xCD,0x43,
	0x40,0x65,0x9B,0x1D,0x30,0xD7,0x03,0x89,0x16,0xB1,0x26,0x4A,0xA5,0x6A,0x05,0xD2,
	0x02,0x31,0x18,0xA5,0x35,0x29,0x7C,0x3C,0xF4,0xF2,0x7E,0xF6,0x8C,0xFD,0xC0,0x74,
	0x70,0x26,0x01,0xCD,0x6A,0x24,0xF6,0xB5,0x4A,0xD5,0xE3,0x33,0xFC,0xB5,0x3F,0xF7,
	0x50,0x63,0x12,0xFC,0xA6,0x6C,0x7D,0xD3,0x3F,0x6C,0x6E,0x35,0x34,0xA3,0xE3,0x56,
	0xC9,0x7E,0xB5,0x94,0x86,0xFF,0x9E,0xF3,0xFF,0xA2,0xCA,0x8E,0xD7,0x39,0x5D,0xB6,
	0xB1,0x9D,0x7A,0x0D,0x7C,0x56,0x5C,0x6C,0xCB,0x77,0x34,0x52,0x93,0x8B,0x63,0x1E,
	0x45,0x83,0x7F,0x5B,0xB6,0xDE,0x3A,0xF5,0x48,0x29,0xED,0x45,0x6E,0x06,0x8F,0x5E,
	0x18,0x99,0x5A,0x3F,0xAE,0x39,0xF4,0x6E,0x7A,0xF3,0x89,0xF2,0xB2,0x19,0x04,0x9F,
	0x55,0x63,0xAD,0xDD,0xEC,0xC7,0x81,0x30,0x8C,0x9B,0x4B,0xD5,0x1E,0x40,0xFD,0x74,
	0x32,0xA0,0x32,0x8D,0xAA,0x74,0xD5,0xDA,0x71,0x42,0xD9,0xAD,0x4D,0xF2,0xF5,0xC6,
	0xC7,0x9F,0x8E,0x5A,0xB2,0xE6,0xE7,0x6A,0xFF,0x41,0xDF,0xC1,0x2E,0x4D,0xC6,0xF2,
	0x63,0x58,0x2E,0x8E,0x23,0x50,0xE5,0xA7,0x01,0xCD,0xEE,0x56,0x98,0x1C,0x39,0xB4,
	0xF0,0x69,0xCB,0x50,0x6C,0x7C,0x3B,0x70,0xEF,0xDC,0x06,0xDE,0x3E,0x39,0xF4,0xD0,
	0x24,0x02,0x25,0xAB,0x4F,0x06,0x1E,0x98,0x65,0x1E,0x0F,0x26,0x94,0xD4,0x2E,0x7F,
	0x47,0x00,0xE4,0xBE,0xBF,0xD5,0x1D,0xE4,0x61,0x8E,0x59,0xB5,0xB0,0xDD,0x17,0x75,
	0xD4,0x31,0x9D,0x03,0xDF,0xB9,0xCA,0x97,0xBF,0x65,0x3F,0x29,0x0C,0x30,0x6A,0x8C,
	0xFC,0x63,0x5B,0xB5,0x04,0x47,0xB1,0x98,0xD1,0xE0,0x63,0x84,0xAE,0x08,0xF1,0xC2,
	0x98,0xB1,0x81,0x5A,0xA6,0x22,0x2F,0x8F,0x78,0x6B,0x71,0xBC,0xF9,0xF1,0x56,0x2D,
	0x52,0xC0,0x64,0x19,0xFB,0x03,0xFF,0x3C,0xC5,0x2A,0x82,0x15,0xFB,0xBF,0x4F,0x4E,
	0x0C,0x17,0xE1,0x83,0x16,0x58,0xCE,0xB4,0x73,0x50,0x03,0x4C,0x79,0xEB,0x4C,0x84,
	0x30,0xE3,0x22,0x63,0xC5,0x14,0xEB,0x58,0x28,0x20,0xA7,0xD7,0x79,0x8C,0x2D,0x93,
	0xF2,0x84,0x46,0xCB,0x68,0x8A,0xFE,0x4E,0x86,0x4F,0xE5,0xF1,0x40,0xE1,0x83,0x5F,
	0x66,0x91,0xDE,0xBD,0xD6,0xD2,0xF9,0xB2,0xAF,0x1B,0x60,0x1C,0xBA,0xB7,0xB4,0x4C,
	0x21,0x05,0x43,0x41,0x64,0xEB,0x06,0x96,0x33,0x07,0xE0,0xA7,0xCE,0xC4,0x9D,0x8A,
	0xFB,0xF3,0xB4,0x4B,0x89,0x76,0xE0,0x97,0xB8,0xE7,0xD4,0xE3,0xD8,0x7B,0xF5,0x78,
	0x8E,0x66,0x73,0x85,0x48,0x8B,0xE7,0x37,0x96,0x57,0xD6,0x8A,0xA2,0x47,0x64,0x9E,
	0x31,0x61,0xBD,0x56,0x0E,0x8C,0x0B,0x09,0xFF,0xF0,0xC6,0x03,0x3F,0x06,0x22,0x05,
	0xCD,0xEE,0x03,0x08,0xB7,0x00,0x61,0x53,0x76,0x3C,0x29,0x2B,0xFB,0xD2,0x6A,0x34,
	0x9F,0x85,0xEC,0xE6,0xFC,0xCB,0x7E,0xBC,0x7E,0xB9,0x78,0x3C,0xE9,0xA0,0x05,0xB6,
	0x58,0x9A,0xC5,0x9D,0x57,0x69,0x40,0xA1,0xEF,0x51,0x40,0x38,0x09,0x4C,0x2E,0x4E,
	0xE2,0xF0,0xD7,0x99,0x74,0x11,0x9F,0x91,0x72,0x36,0x71,0x08,0xC7,0x61,0x4B,0xFD,
	0x9D,0xDA,0x4E,0xBC,0x02,0x1F,0x3E,0xB8,0xBA,0x83,0x1F,0xE3,0x32,0x04,0x2F,0x96,
	0xDD,0x1C,0xF4,0x77,0x41,0x0C,0x05,0x59,0x5A,0x74,0xEC,0x8C,0x74,0x91,0x55,0x93,
	0xE0,0x09,0x6D,0xD6,0x8A,0x27,0xBD,0x7C,0xF1,0xA9,0x8F,0xE2,0xC9,0x48,0xBD,0x27,
	0xE0,0x2F,0xB0,0x69,0xB7,0xF2,0x9D,0xE5,0x16,0x8A,0xF6
};

static const byte kERF30BPassword[] = { 0x32,0x33,0x34,0x32,0x35 };

GTEST_TEST(ERFFile30Blowfish, getNameHashAlgo) {
	PasswordStore password(kERF30BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30B), password);

	EXPECT_EQ(erf.getNameHashAlgo(), Common::kHashFNV64);
}

GTEST_TEST(ERFFile30Blowfish, getBuildYear) {
	PasswordStore password(kERF30BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30B), password);

	EXPECT_EQ(erf.getBuildYear(), 0);
}

GTEST_TEST(ERFFile30Blowfish, getBuildDay) {
	PasswordStore password(kERF30BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30B), password);

	EXPECT_EQ(erf.getBuildDay(), 0);
}

GTEST_TEST(ERFFile30Blowfish, getDescription) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	PasswordStore password(kERF30BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30B), password);

	const Aurora::LocString &description = erf.getDescription();

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile30Blowfish, getDescriptionStatic) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	Common::MemoryReadStream stream(kERFFile30B);

	Aurora::LocString description = Aurora::ERFFile::getDescription(stream);

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile30Blowfish, getResources) {
	PasswordStore password(kERF30BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30B), password);

	const Aurora::ERFFile::ResourceList &resources = erf.getResources();
	ASSERT_EQ(resources.size(), 1);

	const Aurora::ERFFile::Resource &resource = *resources.begin();

	EXPECT_STREQ(resource.name.c_str(), "ozymandias");
	EXPECT_EQ(resource.type, Aurora::kFileTypeTXT);
	EXPECT_EQ(resource.hash, Common::hashString("ozymandias.txt", Common::kHashFNV64));
	EXPECT_EQ(resource.index, 0);
}

GTEST_TEST(ERFFile30Blowfish, getResourceSize) {
	PasswordStore password(kERF30BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30B), password);

	EXPECT_EQ(erf.getResourceSize(0), strlen(kFileData));

	EXPECT_THROW(erf.getResourceSize(1), Common::Exception);
}

GTEST_TEST(ERFFile30Blowfish, findResourceHash) {
	PasswordStore password(kERF30BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30B), password);

	EXPECT_EQ(erf.findResource(Common::hashString("ozymandias.txt", Common::kHashFNV64)), 0);

	EXPECT_EQ(erf.findResource(0), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile30Blowfish, findResourceName) {
	PasswordStore password(kERF30BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30B), password);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeTXT), 0);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeBMP), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeBMP), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile30Blowfish, getResource) {
	PasswordStore password(kERF30BPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30B), password);

	Common::SeekableReadStream *file = erf.getResource(0);
	ASSERT_NE(file, static_cast<Common::SeekableReadStream *>(0));

	ASSERT_EQ(file->size(), strlen(kFileData));

	for (size_t i = 0; i < strlen(kFileData); i++)
		EXPECT_EQ(file->readByte(), kFileData[i]) << "At index " << i;

	delete file;
}

// --- ERF V3.0 (Blowfish + raw DEFLATE) ---

// Percy Bysshe Shelley's "Ozymandias", within an ERF V3.0 (Blowfish + raw DEFLATE) file
static const byte kERFFile30BDR[] = {
	0x45,0x00,0x52,0x00,0x46,0x00,0x20,0x00,0x56,0x00,0x33,0x00,0x2E,0x00,0x30,0x00,
	0x0F,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x30,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,
	0x6A,0xF7,0xEF,0xA2,0x07,0x16,0x81,0x73,0xEE,0x69,0xE2,0x34,0x35,0x50,0x7C,0xE9,
	0x6F,0x7A,0x79,0x6D,0x61,0x6E,0x64,0x69,0x61,0x73,0x2E,0x74,0x78,0x74,0x00,0x00,
	0x00,0x00,0x00,0xEA,0x54,0xB9,0xC3,0xF9,0x70,0x3C,0x67,0x5F,0xAB,0x6C,0x2B,0x5B,
	0x00,0x00,0x00,0x78,0x01,0x00,0x00,0x6F,0x02,0x00,0x00,0x78,0x4E,0x55,0xA2,0xE4,
	0xAD,0x5E,0x9B,0xC8,0xA6,0x0F,0x31,0x0D,0xA6,0xF6,0xC4,0xD5,0x73,0xCA,0xE0,0x63,
	0x36,0xB0,0x89,0xAD,0x57,0x1F,0xAD,0xE8,0x69,0x49,0x6B,0x09,0x64,0x11,0xB9,0xBC,
	0xFB,0x67,0x37,0x89,0x69,0x40,0xC7,0x17,0x3B,0xAE,0x86,0x0B,0xC1,0xC4,0x10,0x25,
	0xE9,0x98,0x80,0xEB,0x5F,0x86,0xA9,0x3D,0x06,0x24,0x7B,0x01,0x48,0x8D,0xAF,0x7F,
	0x5F,0xB9,0x04,0xC2,0x89,0x35,0xA6,0xD8,0x3D,0xFD,0x13,0xEF,0x9A,0x1F,0xD2,0x4A,
	0x91,0x1C,0xEF,0x02,0x7C,0x1A,0xAE,0x55,0xFF,0x71,0x4F,0xD3,0xA3,0xDE,0x0D,0xDE,
	0x24,0xC4,0x95,0xF3,0x86,0x1A,0x77,0xC1,0xCA,0x15,0xFB,0x89,0xB8,0xD3,0x95,0xB2,
	0xC0,0x06,0xEC,0xB7,0x24,0x4C,0x42,0x55,0x94,0x90,0x2F,0x02,0x8B,0xA3,0xE1,0x65,
	0x0E,0x45,0xD2,0xB6,0x37,0xAF,0xD0,0x80,0x0A,0x4B,0xEA,0x42,0x3D,0x39,0x56,0xA9,
	0x94,0x2E,0xF1,0xD0,0x3B,0xF8,0xA3,0xF9,0x23,0x7D,0xC6,0xF7,0x4C,0x8B,0x9E,0x27,
	0x4A,0x2D,0xC1,0x93,0x27,0x09,0x96,0xF4,0x8B,0xF4,0xAB,0x2B,0xD4,0xF9,0x7D,0x12,
	0xB0,0x36,0xB0,0xB5,0x61,0x30,0xDA,0xF3,0x15,0x06,0x0B,0x80,0x47,0xA6,0xEF,0x71,
	0x4A,0x04,0x50,0x68,0x25,0xE7,0x01,0xE7,0x8B,0x3D,0xD9,0x7E,0xC5,0x8C,0xDA,0x48,
	0x86,0x29,0xD1,0x31,0x28,0x47,0xBB,0xB5,0x16,0x8B,0x47,0x20,0xCF,0xD8,0x84,0x70,
	0xD1,0xF6,0x84,0x86,0xDC,0xE7,0xCA,0x64,0xBB,0x24,0xAC,0x19,0x83,0x3B,0x3D,0xBC,
	0xB5,0x46,0xD1,0x6E,0xBE,0x2F,0xB0,0x21,0xCA,0xB5,0xC0,0x9E,0xF0,0xE9,0x4A,0x1A,
	0x73,0xA6,0x62,0xB2,0x08,0xC4,0x2D,0x25,0x4A,0xA0,0x66,0x64,0x84,0x9F,0x2D,0xCE,
	0xA7,0x88,0x4F,0x4D,0x50,0x88,0x15,0x0B,0x5F,0x11,0xDB,0x05,0x36,0x43,0xF5,0x71,
	0xF8,0x4D,0x39,0xEE,0xEB,0xFB,0xF3,0x8E,0xB9,0x2A,0x5F,0x34,0xDD,0xCB,0x36,0x58,
	0xE4,0xB3,0xD7,0x38,0x72,0x69,0x60,0x37,0xC6,0x18,0xF5,0xD2,0x33,0x69,0xC0,0xAC,
	0x22,0xC5,0xD9,0x03,0x63,0x3B,0x32,0x83,0x4D,0x0B,0xF5,0x34,0xEF,0xB4,0xEC,0xF6,
	0xF4,0xD3,0x6F,0x14,0x23,0xDE,0x1D,0x5A,0x46,0x57,0xD0,0x37,0xB7,0xB0,0x68,0xF6,
	0xBF,0x41,0x6F,0xAE,0x4C,0x5F,0xC4,0x7E,0x27,0x47,0xA5,0xE6,0x91,0x07,0x8B,0x7A,
	0xB5,0x15,0x3E
};

static const byte kERF30BDRPassword[] = { 0x32,0x33,0x34,0x32,0x35 };

GTEST_TEST(ERFFile30BlowfishDeflateRaw, getNameHashAlgo) {
	PasswordStore password(kERF30BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30BDR), password);

	EXPECT_EQ(erf.getNameHashAlgo(), Common::kHashFNV64);
}

GTEST_TEST(ERFFile30BlowfishDeflateRaw, getBuildYear) {
	PasswordStore password(kERF30BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30BDR), password);

	EXPECT_EQ(erf.getBuildYear(), 0);
}

GTEST_TEST(ERFFile30BlowfishDeflateRaw, getBuildDay) {
	PasswordStore password(kERF30BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30BDR), password);

	EXPECT_EQ(erf.getBuildDay(), 0);
}

GTEST_TEST(ERFFile30BlowfishDeflateRaw, getDescription) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	PasswordStore password(kERF30BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30BDR), password);

	const Aurora::LocString &description = erf.getDescription();

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile30BlowfishDeflateRaw, getDescriptionStatic) {
	LangMan.addLanguage(Aurora::kLanguageEnglish, 0, Common::kEncodingUTF8);

	Common::MemoryReadStream stream(kERFFile30BDR);

	Aurora::LocString description = Aurora::ERFFile::getDescription(stream);

	EXPECT_EQ(description.getID(), Aurora::kStrRefInvalid);
	EXPECT_STREQ(description.getString().c_str(), "");

	Aurora::LanguageManager::destroy();
}

GTEST_TEST(ERFFile30BlowfishDeflateRaw, getResources) {
	PasswordStore password(kERF30BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30BDR), password);

	const Aurora::ERFFile::ResourceList &resources = erf.getResources();
	ASSERT_EQ(resources.size(), 1);

	const Aurora::ERFFile::Resource &resource = *resources.begin();

	EXPECT_STREQ(resource.name.c_str(), "ozymandias");
	EXPECT_EQ(resource.type, Aurora::kFileTypeTXT);
	EXPECT_EQ(resource.hash, Common::hashString("ozymandias.txt", Common::kHashFNV64));
	EXPECT_EQ(resource.index, 0);
}

GTEST_TEST(ERFFile30BlowfishDeflateRaw, getResourceSize) {
	PasswordStore password(kERF30BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30BDR), password);

	EXPECT_EQ(erf.getResourceSize(0), strlen(kFileData));

	EXPECT_THROW(erf.getResourceSize(1), Common::Exception);
}

GTEST_TEST(ERFFile30BlowfishDeflateRaw, findResourceHash) {
	PasswordStore password(kERF30BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30BDR), password);

	EXPECT_EQ(erf.findResource(Common::hashString("ozymandias.txt", Common::kHashFNV64)), 0);

	EXPECT_EQ(erf.findResource(0), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile30BlowfishDeflateRaw, findResourceName) {
	PasswordStore password(kERF30BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30BDR), password);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeTXT), 0);

	EXPECT_EQ(erf.findResource("ozymandias", Aurora::kFileTypeBMP), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeTXT), 0xFFFFFFFF);
	EXPECT_EQ(erf.findResource("nope"      , Aurora::kFileTypeBMP), 0xFFFFFFFF);
}

GTEST_TEST(ERFFile30BlowfishDeflateRaw, getResource) {
	PasswordStore password(kERF30BDRPassword);
	const Aurora::ERFFile erf(new Common::MemoryReadStream(kERFFile30BDR), password);

	Common::SeekableReadStream *file = erf.getResource(0);
	ASSERT_NE(file, static_cast<Common::SeekableReadStream *>(0));

	ASSERT_EQ(file->size(), strlen(kFileData));

	for (size_t i = 0; i < strlen(kFileData); i++)
		EXPECT_EQ(file->readByte(), kFileData[i]) << "At index " << i;

	delete file;
}
