Merge pull request #25 from libAthena/smart-ptrs

Refactored readBytes() and readUBytes() to return std::unique_ptr
This commit is contained in:
Jack Andersen 2015-08-05 12:58:32 -10:00
commit 9ed090b126
17 changed files with 100 additions and 134 deletions

View File

@ -97,13 +97,13 @@ public:
* \brief setInventory * \brief setInventory
* \param inv * \param inv
*/ */
void setInventory(ALTTPInventory* inv); void setInventory(const ALTTPInventory& inv);
/*! /*!
* \brief inventory * \brief inventory
* \return * \return
*/ */
ALTTPInventory* inventory() const; const ALTTPInventory& inventory() const;
/*! /*!
* \brief setRupeeMax * \brief setRupeeMax
@ -641,7 +641,7 @@ public:
private: private:
std::vector<ALTTPRoomFlags*> m_roomFlags; std::vector<ALTTPRoomFlags*> m_roomFlags;
std::vector<ALTTPOverworldEvent*> m_overworldEvents; std::vector<ALTTPOverworldEvent*> m_overworldEvents;
ALTTPInventory* m_inventory; ALTTPInventory m_inventory;
atUint16 m_rupeeMax; atUint16 m_rupeeMax;
atUint16 m_rupeeCurrent; atUint16 m_rupeeCurrent;
ALTTPDungeonItemFlags m_compasses; ALTTPDungeonItemFlags m_compasses;

View File

@ -89,14 +89,23 @@ public:
* *
* \return Uint8* The buffer at the current position from the given length. * \return Uint8* The buffer at the current position from the given length.
*/ */
inline atInt8* readBytes(atUint64 length) inline std::unique_ptr<atInt8[]> readBytes(atUint64 length)
{atInt8* buf = new atInt8[length]; readUBytesToBuf(buf, length); return buf;} {
atInt8* buf = new atInt8[length];
readUBytesToBuf(buf, length);
return std::unique_ptr<atInt8[]>(buf);
}
/*! \brief Reads a byte at the current position and advances the current position. /*! \brief Reads a byte at the current position and advances the current position.
* *
* \return Int8* The buffer at the current position from the given length. * \return Int8* The buffer at the current position from the given length.
*/ */
inline atUint8* readUBytes(atUint64 length) {return (atUint8*)readBytes(length);} inline std::unique_ptr<atUint8[]> readUBytes(atUint64 length)
{
atUint8* buf = new atUint8[length];
readUBytesToBuf(buf, length);
return std::unique_ptr<atUint8[]>(buf);
}
inline atUint64 readBytesToBuf(void* buf, atUint64 len) {return readUBytesToBuf(buf, len);} inline atUint64 readBytesToBuf(void* buf, atUint64 len) {return readUBytesToBuf(buf, len);}
virtual atUint64 readUBytesToBuf(void* buf, atUint64 len)=0; virtual atUint64 readUBytesToBuf(void* buf, atUint64 len)=0;

View File

@ -9,7 +9,7 @@ namespace Athena
class MCSlot : public ZQuestFile class MCSlot : public ZQuestFile
{ {
public: public:
MCSlot(atUint8* data, atUint32 length); MCSlot(std::unique_ptr<atUint8[]>&& data, atUint32 length);
}; };
} // Athena } // Athena

View File

@ -34,7 +34,7 @@
Seeds Seeds
}; };
SkywardSwordQuest(atUint8* data, atUint32 len); SkywardSwordQuest(std::unique_ptr<atUint8[]>&& data, atUint32 len);
void setPlayerName(const std::string& name); void setPlayerName(const std::string& name);
std::string playerName() const; std::string playerName() const;
@ -56,7 +56,7 @@
std::string currentArea(); std::string currentArea();
std::string currentLocationCopy(); std::string currentLocationCopy();
void setSkipData(const atUint8* data); void setSkipData(std::unique_ptr<atUint8[]>&& data);
atUint8* skipData() const; atUint8* skipData() const;
@ -67,7 +67,7 @@
void setNew(bool isNew); void setNew(bool isNew);
bool isNew() const; bool isNew() const;
private: private:
atUint8* m_skipData; std::unique_ptr<atUint8[]> m_skipData;
}; };

View File

@ -17,6 +17,7 @@
#ifndef WIIIMAGE_HPP #ifndef WIIIMAGE_HPP
#define WIIIMAGE_HPP #define WIIIMAGE_HPP
#include <memory>
#include "Athena/Types.hpp" #include "Athena/Types.hpp"
namespace Athena namespace Athena
@ -38,12 +39,7 @@ public:
* \param height * \param height
* \param data * \param data
*/ */
WiiImage(atUint32 width, atUint32 height, atUint8* data); WiiImage(atUint32 width, atUint32 height, std::unique_ptr<atUint8[]>&& data);
/*!
* \brief ~WiiImage
*/
~WiiImage();
/*! /*!
* \brief setWidth * \brief setWidth
@ -90,7 +86,7 @@ public:
private: private:
atUint32 m_width; atUint32 m_width;
atUint32 m_height; atUint32 m_height;
atUint8* m_data; std::unique_ptr<atUint8[]> m_data;
}; };
} // zelda } // zelda

View File

@ -21,6 +21,7 @@
#include "Athena/Global.hpp" #include "Athena/Global.hpp"
#include <string> #include <string>
#include <vector> #include <vector>
#include <memory>
#define ZQUEST_VERSION_CHECK(major, minor, revision) \ #define ZQUEST_VERSION_CHECK(major, minor, revision) \
(major | (minor << 8) | (revision << 16)) (major | (minor << 8) | (revision << 16))
@ -98,8 +99,7 @@ public:
* \param data * \param data
* \param length * \param length
*/ */
ZQuestFile(Game game, Endian endian, atUint8* data, atUint32 length, const std::string& gameString = std::string()); ZQuestFile(Game game, Endian endian, std::unique_ptr<atUint8[]>&& data, atUint32 length, const std::string& gameString = std::string());
~ZQuestFile();
/*! /*!
* \brief setGame * \brief setGame
@ -130,7 +130,7 @@ public:
* \param data The data to assign * \param data The data to assign
* \param length The length of the data * \param length The length of the data
*/ */
void setData(atUint8* data, atUint32 length); void setData(std::unique_ptr<atUint8[]>&& data, atUint32 length);
/*! /*!
* \brief data * \brief data
@ -156,7 +156,7 @@ protected:
Game m_game; Game m_game;
std::string m_gameString; std::string m_gameString;
Endian m_endian; Endian m_endian;
atUint8* m_data; std::unique_ptr<atUint8[]> m_data;
atUint32 m_length; atUint32 m_length;
// Game strings support // Game strings support

View File

@ -68,7 +68,7 @@ ALTTPFile* ALTTPFileReader::readFile()
quest->setOverworldEvents(owEvents); quest->setOverworldEvents(owEvents);
quest->setInventory((ALTTPInventory*)base::readBytes(sizeof(ALTTPInventory))); quest->setInventory(*(ALTTPInventory*)base::readBytes(sizeof(ALTTPInventory)).get());
quest->setRupeeMax(base::readUint16()); quest->setRupeeMax(base::readUint16());
quest->setRupeeCurrent(base::readUint16()); quest->setRupeeCurrent(base::readUint16());
quest->setCompasses(readDungeonFlags()); quest->setCompasses(readDungeonFlags());
@ -109,8 +109,8 @@ ALTTPFile* ALTTPFileReader::readFile()
abilities.Read = (abilitiesByte >> 6) & 1; abilities.Read = (abilitiesByte >> 6) & 1;
abilities.Unknown2 = (abilitiesByte >> 7) & 1; abilities.Unknown2 = (abilitiesByte >> 7) & 1;
quest->setAbilityFlags(abilities); quest->setAbilityFlags(abilities);
quest->setCrystals((ALTTPCrystals&)*base::readBytes(sizeof(ALTTPCrystals))); quest->setCrystals(*(ALTTPCrystals*)base::readBytes(sizeof(ALTTPCrystals)).get());
quest->setMagicUsage((ALTTPMagicUsage&)*base::readBytes(sizeof(ALTTPMagicUsage))); quest->setMagicUsage(*(ALTTPMagicUsage*)base::readBytes(sizeof(ALTTPMagicUsage)).get());
j = 0x10; j = 0x10;
@ -122,11 +122,11 @@ ALTTPFile* ALTTPFileReader::readFile()
quest->setDungeonKeys(dungeonKeys); quest->setDungeonKeys(dungeonKeys);
base::seek(0x039); base::seek(0x039);
quest->setProgressIndicator((ALTTPProgressIndicator)base::readByte()); quest->setProgressIndicator((ALTTPProgressIndicator)base::readByte());
quest->setProgressFlags1((ALTTPProgressFlags1&)*base::readBytes(sizeof(ALTTPProgressFlags1))); quest->setProgressFlags1(*(ALTTPProgressFlags1*)base::readBytes(sizeof(ALTTPProgressFlags1)).get());
quest->setMapIcon((ALTTPMapIcon)base::readByte()); quest->setMapIcon((ALTTPMapIcon)base::readByte());
quest->setStartLocation((ALTTPStartLocation)base::readByte()); quest->setStartLocation((ALTTPStartLocation)base::readByte());
quest->setProgressFlags2((ALTTPProgressFlags2&)*base::readBytes(sizeof(ALTTPProgressFlags2))); quest->setProgressFlags2(*(ALTTPProgressFlags2*)base::readBytes(sizeof(ALTTPProgressFlags2)).get());
quest->setLightDarkWorldIndicator((ALTTPLightDarkWorldIndicator&)*base::readBytes(1)); quest->setLightDarkWorldIndicator(*(ALTTPLightDarkWorldIndicator*)base::readBytes(1).get());
base::seek(1); base::seek(1);
quest->setTagAlong((ALTTPTagAlong)base::readByte()); quest->setTagAlong((ALTTPTagAlong)base::readByte());

View File

@ -56,7 +56,7 @@ void ALTTPFileWriter::writeFile(ALTTPFile* file)
writeOverworldEvent(quest->overworldEvent(j)); writeOverworldEvent(quest->overworldEvent(j));
} }
base::writeBytes((atInt8*)quest->inventory(), sizeof(ALTTPInventory)); base::writeBytes((atInt8*)&quest->inventory(), sizeof(ALTTPInventory));
base::writeUint16(quest->rupeeMax()); base::writeUint16(quest->rupeeMax());
base::writeUint16(quest->rupeeCurrent()); base::writeUint16(quest->rupeeCurrent());
writeDungeonItems(quest->compasses()); writeDungeonItems(quest->compasses());

View File

@ -79,12 +79,12 @@ ALTTPOverworldEvent* ALTTPQuest::overworldEvent(atUint32 id) const
return m_overworldEvents[id]; return m_overworldEvents[id];
} }
void ALTTPQuest::setInventory(ALTTPInventory* inv) void ALTTPQuest::setInventory(const ALTTPInventory& inv)
{ {
m_inventory = inv; m_inventory = inv;
} }
ALTTPInventory* ALTTPQuest::inventory() const const ALTTPInventory& ALTTPQuest::inventory() const
{ {
return m_inventory; return m_inventory;
} }

View File

@ -122,8 +122,7 @@ std::unique_ptr<YAMLNode> YAMLDocReader::ParseEvents(yaml_parser_t* doc)
if (nodeStack.empty()) if (nodeStack.empty())
{ {
atWarning("YAML parser stack empty; skipping scalar node"); atWarning("YAML parser stack empty; skipping scalar node");
yaml_event_delete(&event); break;
continue;
} }
std::unique_ptr<YAMLNode> newScalar(new YAMLNode(YAML_SCALAR_NODE)); std::unique_ptr<YAMLNode> newScalar(new YAMLNode(YAML_SCALAR_NODE));
newScalar->m_scalarString.assign((char*)event.data.scalar.value, event.data.scalar.length); newScalar->m_scalarString.assign((char*)event.data.scalar.value, event.data.scalar.length);
@ -236,7 +235,7 @@ bool YAMLDocWriter::RecursiveFinish(yaml_emitter_t* doc, const YAMLNode& node)
goto err; goto err;
for (const auto& item : node.m_seqChildren) for (const auto& item : node.m_seqChildren)
{ {
if (!RecursiveFinish(doc, *item.get())) if (!RecursiveFinish(doc, *item))
goto err; goto err;
} }
if (!yaml_sequence_end_event_initialize(&event) || if (!yaml_sequence_end_event_initialize(&event) ||
@ -252,7 +251,7 @@ bool YAMLDocWriter::RecursiveFinish(yaml_emitter_t* doc, const YAMLNode& node)
{ {
if (!EmitKeyScalar(doc, item.first.c_str())) if (!EmitKeyScalar(doc, item.first.c_str()))
goto err; goto err;
if (!RecursiveFinish(doc, *item.second.get())) if (!RecursiveFinish(doc, *item.second))
goto err; goto err;
} }
event.type = YAML_MAPPING_END_EVENT; event.type = YAML_MAPPING_END_EVENT;

View File

@ -3,8 +3,8 @@
namespace Athena namespace Athena
{ {
MCSlot::MCSlot(atUint8* data, atUint32 length) MCSlot::MCSlot(std::unique_ptr<atUint8[]>&& data, atUint32 length)
: ZQuestFile(ZQuestFile::MC, Endian::LittleEndian, data, length) : ZQuestFile(ZQuestFile::MC, Endian::LittleEndian, std::move(data), length)
{ {
} }

View File

@ -71,7 +71,7 @@ SkywardSwordFile* SkywardSwordFileReader::read()
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
SkywardSwordQuest* q = new SkywardSwordQuest((atUint8*)base::readBytes(0x53C0), 0x53C0); SkywardSwordQuest* q = new SkywardSwordQuest(base::readUBytes(0x53C0), 0x53C0);
atUint64 pos = base::position(); atUint64 pos = base::position();
// seek to the skip data for this particular quest // seek to the skip data for this particular quest
base::seek(0xFB60 + (i * 0x24), SeekOrigin::Begin); base::seek(0xFB60 + (i * 0x24), SeekOrigin::Begin);

View File

@ -54,26 +54,19 @@ union AmmoValues
atUint32 value; atUint32 value;
}; };
SkywardSwordQuest::SkywardSwordQuest(atUint8* data, atUint32 len) SkywardSwordQuest::SkywardSwordQuest(std::unique_ptr<atUint8[]>&& data, atUint32 len)
: ZQuestFile(ZQuestFile::SS, Endian::BigEndian, data, len), : ZQuestFile(ZQuestFile::SS, Endian::BigEndian, std::move(data), len)
m_skipData(nullptr)
{ {
} }
void SkywardSwordQuest::setSkipData(const atUint8* data) void SkywardSwordQuest::setSkipData(std::unique_ptr<atUint8[]>&& data)
{ {
if (m_skipData) m_skipData = std::move(data);
{
delete[] m_skipData;
m_skipData = nullptr;
}
m_skipData = (atUint8*)data;
} }
atUint8* SkywardSwordQuest::skipData() const atUint8* SkywardSwordQuest::skipData() const
{ {
return m_skipData; return m_skipData.get();
} }
void SkywardSwordQuest::setPlayerName(const std::string& name) void SkywardSwordQuest::setPlayerName(const std::string& name)
@ -86,7 +79,7 @@ void SkywardSwordQuest::setPlayerName(const std::string& name)
for (atUint32 i = 0; i < 8; i++) for (atUint32 i = 0; i < 8; i++)
{ {
atUint16& c = *(atUint16*)(m_data + priv::NAME_OFFSET + (i * 2)); atUint16& c = *(atUint16*)(m_data.get() + priv::NAME_OFFSET + (i * 2));
if (i >= val.size()) if (i >= val.size())
{ {
@ -105,7 +98,7 @@ std::string SkywardSwordQuest::playerName() const
for (atUint32 i = 0; i < 8; i++) for (atUint32 i = 0; i < 8; i++)
{ {
atUint16 c = *(atUint16*)(m_data + priv::NAME_OFFSET + (i * 2)); atUint16 c = *(atUint16*)(m_data.get() + priv::NAME_OFFSET + (i * 2));
if (c == 0) if (c == 0)
break; break;
@ -120,20 +113,20 @@ std::string SkywardSwordQuest::playerName() const
void SkywardSwordQuest::setRupeeCount(atUint16 value) void SkywardSwordQuest::setRupeeCount(atUint16 value)
{ {
atUint16& tmp = *(atUint16*)(m_data + priv::RUPEE_COUNT_OFFSET); atUint16& tmp = *(atUint16*)(m_data.get() + priv::RUPEE_COUNT_OFFSET);
tmp = value; tmp = value;
utility::BigUint16(tmp); utility::BigUint16(tmp);
} }
atUint16 SkywardSwordQuest::rupeeCount() atUint16 SkywardSwordQuest::rupeeCount()
{ {
atUint16 ret = *(atUint16*)(m_data + priv::RUPEE_COUNT_OFFSET); atUint16 ret = *(atUint16*)(m_data.get() + priv::RUPEE_COUNT_OFFSET);
return utility::BigUint16(ret); return utility::BigUint16(ret);
} }
void SkywardSwordQuest::setAmmoCount(SkywardSwordQuest::AmmoType type, atUint32 count) void SkywardSwordQuest::setAmmoCount(SkywardSwordQuest::AmmoType type, atUint32 count)
{ {
AmmoValues& values = *(AmmoValues*)(m_data + priv::AMMO_COUNT_OFFSET); AmmoValues& values = *(AmmoValues*)(m_data.get() + priv::AMMO_COUNT_OFFSET);
utility::BigUint32(values.value); utility::BigUint32(values.value);
switch (type) switch (type)
@ -156,7 +149,7 @@ void SkywardSwordQuest::setAmmoCount(SkywardSwordQuest::AmmoType type, atUint32
atUint32 SkywardSwordQuest::ammoCount(AmmoType type) atUint32 SkywardSwordQuest::ammoCount(AmmoType type)
{ {
AmmoValues values = *(AmmoValues*)(m_data + priv::AMMO_COUNT_OFFSET); AmmoValues values = *(AmmoValues*)(m_data.get() + priv::AMMO_COUNT_OFFSET);
utility::BigUint32(values.value); utility::BigUint32(values.value);
switch (type) switch (type)
@ -177,12 +170,12 @@ atUint32 SkywardSwordQuest::ammoCount(AmmoType type)
void SkywardSwordQuest::setMaxHP(atUint16 val) void SkywardSwordQuest::setMaxHP(atUint16 val)
{ {
*(atUint16*)(m_data + priv::MAX_HP_OFFSET) = utility::BigUint16(val); *(atUint16*)(m_data.get() + priv::MAX_HP_OFFSET) = utility::BigUint16(val);
} }
atUint16 SkywardSwordQuest::maxHP() atUint16 SkywardSwordQuest::maxHP()
{ {
atUint16 ret = *(atUint16*)(m_data + priv::MAX_HP_OFFSET); atUint16 ret = *(atUint16*)(m_data.get() + priv::MAX_HP_OFFSET);
return utility::BigUint16(ret); return utility::BigUint16(ret);
} }
@ -193,12 +186,12 @@ float SkywardSwordQuest::maxHearts()
void SkywardSwordQuest::setSpawnHP(atUint16 val) void SkywardSwordQuest::setSpawnHP(atUint16 val)
{ {
*(atUint16*)(m_data + priv::SPAWN_HP_OFFSET) = utility::BigUint16(val); *(atUint16*)(m_data.get() + priv::SPAWN_HP_OFFSET) = utility::BigUint16(val);
} }
atUint16 SkywardSwordQuest::spawnHP() atUint16 SkywardSwordQuest::spawnHP()
{ {
atUint16 ret = *(atUint16*)(m_data + priv::SPAWN_HP_OFFSET); atUint16 ret = *(atUint16*)(m_data.get() + priv::SPAWN_HP_OFFSET);
return utility::BigUint16(ret); return utility::BigUint16(ret);
} }
@ -209,12 +202,12 @@ float SkywardSwordQuest::spawnHearts()
void SkywardSwordQuest::setCurrentHP(atUint16 val) void SkywardSwordQuest::setCurrentHP(atUint16 val)
{ {
*(atUint16*)(m_data + priv::CURRENT_HP_OFFSET) = utility::BigUint16(val); *(atUint16*)(m_data.get() + priv::CURRENT_HP_OFFSET) = utility::BigUint16(val);
} }
atUint16 SkywardSwordQuest::currentHP() atUint16 SkywardSwordQuest::currentHP()
{ {
atUint16 ret = *(atUint16*)(m_data + priv::CURRENT_HP_OFFSET); atUint16 ret = *(atUint16*)(m_data.get() + priv::CURRENT_HP_OFFSET);
return utility::BigUint16(ret); return utility::BigUint16(ret);
} }
@ -225,22 +218,22 @@ float SkywardSwordQuest::currentHearts()
std::string SkywardSwordQuest::currentLocation() std::string SkywardSwordQuest::currentLocation()
{ {
return std::string((char*)m_data + priv::CURRENT_LOCATION_OFFSET); return std::string((char*)m_data.get() + priv::CURRENT_LOCATION_OFFSET);
} }
std::string SkywardSwordQuest::currentArea() std::string SkywardSwordQuest::currentArea()
{ {
return std::string((char*)m_data + priv::CURRENT_AREA_OFFSET); return std::string((char*)m_data.get() + priv::CURRENT_AREA_OFFSET);
} }
std::string SkywardSwordQuest::currentLocationCopy() std::string SkywardSwordQuest::currentLocationCopy()
{ {
return std::string((char*)m_data + priv::CURRENT_LOCATION_COPY_OFFSET); return std::string((char*)m_data.get() + priv::CURRENT_LOCATION_COPY_OFFSET);
} }
atUint32 SkywardSwordQuest::slotChecksum() atUint32 SkywardSwordQuest::slotChecksum()
{ {
atUint32 ret = *(atUint32*)(m_data + priv::CHECKSUM_OFFSET); atUint32 ret = *(atUint32*)(m_data.get() + priv::CHECKSUM_OFFSET);
utility::BigUint32(ret); utility::BigUint32(ret);
return ret; return ret;
@ -248,7 +241,7 @@ atUint32 SkywardSwordQuest::slotChecksum()
atUint32 SkywardSwordQuest::skipChecksum() atUint32 SkywardSwordQuest::skipChecksum()
{ {
atUint32 ret = *(atUint32*)(m_skipData + priv::SKIP_CHECKSUM_OFFSET); atUint32 ret = *(atUint32*)(m_skipData.get() + priv::SKIP_CHECKSUM_OFFSET);
utility::BigUint32(ret); utility::BigUint32(ret);
return ret; return ret;
@ -256,23 +249,23 @@ atUint32 SkywardSwordQuest::skipChecksum()
void SkywardSwordQuest::fixChecksums() void SkywardSwordQuest::fixChecksums()
{ {
atUint32 checksum = Checksums::crc32(m_data, priv::CHECKSUM_OFFSET); atUint32 checksum = Checksums::crc32(m_data.get(), priv::CHECKSUM_OFFSET);
utility::BigUint32(checksum); utility::BigUint32(checksum);
*(atUint32*)(m_data + priv::CHECKSUM_OFFSET) = checksum; *(atUint32*)(m_data.get() + priv::CHECKSUM_OFFSET) = checksum;
checksum = Checksums::crc32(m_skipData, priv::SKIP_CHECKSUM_OFFSET); checksum = Checksums::crc32(m_skipData.get(), priv::SKIP_CHECKSUM_OFFSET);
utility::BigUint32(checksum); utility::BigUint32(checksum);
*(atUint32*)(m_skipData + priv::SKIP_CHECKSUM_OFFSET) = checksum; *(atUint32*)(m_skipData.get() + priv::SKIP_CHECKSUM_OFFSET) = checksum;
} }
void SkywardSwordQuest::setNew(bool isNew) void SkywardSwordQuest::setNew(bool isNew)
{ {
*(bool*)(m_data + priv::ISNEW_OFFSET) = isNew; *(bool*)(m_data.get() + priv::ISNEW_OFFSET) = isNew;
} }
bool SkywardSwordQuest::isNew() const bool SkywardSwordQuest::isNew() const
{ {
return *(bool*)(m_data + priv::ISNEW_OFFSET); return *(bool*)(m_data.get() + priv::ISNEW_OFFSET);
} }
} // zelda } // zelda

View File

@ -22,24 +22,16 @@
namespace Athena namespace Athena
{ {
WiiImage::WiiImage(atUint32 width, atUint32 height, atUint8* data) : WiiImage::WiiImage(atUint32 width, atUint32 height, std::unique_ptr<atUint8[]>&& data) :
m_width(width), m_width(width),
m_height(height), m_height(height),
m_data(data) m_data(std::move(data))
{ {
} }
WiiImage::~WiiImage()
{
if (m_data)
delete[] m_data;
m_data = NULL;
}
atUint8* WiiImage::data() atUint8* WiiImage::data()
{ {
return m_data; return m_data.get();
} }
atUint32 WiiImage::width() const atUint32 WiiImage::width() const
@ -72,7 +64,7 @@ atUint8* WiiImage::toRGBA()
{ {
for (x = x1; x < (x1 + 4); x++) for (x = x1; x < (x1 + 4); x++)
{ {
atUint16 oldpixel = *(atUint16*)(m_data + ((iv++) * 2)); atUint16 oldpixel = *(atUint16*)(m_data.get() + ((iv++) * 2));
//if((x >= m_width) || (y >= m_height)) //if((x >= m_width) || (y >= m_height))
// continue; // continue;
oldpixel = utility::swapU16(oldpixel); oldpixel = utility::swapU16(oldpixel);

View File

@ -125,7 +125,7 @@ WiiBanner* WiiSaveReader::readBanner()
{ {
atUint8* dec = new atUint8[0xF0C0]; atUint8* dec = new atUint8[0xF0C0];
memset(dec, 0, 0xF0C0); memset(dec, 0, 0xF0C0);
atUint8* data = (atUint8*)base::readBytes(0xF0C0); std::unique_ptr<atUint8[]> data = base::readUBytes(0xF0C0);
atUint8* oldData = base::data(); atUint8* oldData = base::data();
atUint64 oldPos = base::position(); atUint64 oldPos = base::position();
atUint64 oldLen = base::length(); atUint64 oldLen = base::length();
@ -140,7 +140,7 @@ WiiBanner* WiiSaveReader::readBanner()
std::cout << "Decrypting: banner.bin..."; std::cout << "Decrypting: banner.bin...";
std::unique_ptr<IAES> aes = NewAES(); std::unique_ptr<IAES> aes = NewAES();
aes->setKey(SD_KEY); aes->setKey(SD_KEY);
aes->decrypt(tmpIV, data, dec, 0xF0C0); aes->decrypt(tmpIV, data.get(), dec, 0xF0C0);
std::cout << "done" << std::endl; std::cout << "done" << std::endl;
memset(md5, 0, 16); memset(md5, 0, 16);
@ -260,10 +260,10 @@ WiiBanner* WiiSaveReader::readBanner()
WiiImage* WiiSaveReader::readImage(atUint32 width, atUint32 height) WiiImage* WiiSaveReader::readImage(atUint32 width, atUint32 height)
{ {
atUint8* image = (atUint8*)base::readBytes(width * height * 2); std::unique_ptr<atUint8[]> image = base::readUBytes(width * height * 2);
if (!utility::isEmpty((atInt8*)image, width * height * 2)) if (!utility::isEmpty((atInt8*)image.get(), width * height * 2))
return new WiiImage(width, height, image); return new WiiImage(width, height, std::move(image));
return NULL; return NULL;
} }
@ -276,7 +276,6 @@ WiiFile* WiiSaveReader::readFile()
atUint8 attributes; atUint8 attributes;
atUint8 type; atUint8 type;
std::string name; std::string name;
atUint8* filedata;
WiiFile* ret; WiiFile* ret;
atUint32 magic = base::readUint32(); atUint32 magic = base::readUint32();
@ -291,27 +290,26 @@ WiiFile* WiiSaveReader::readFile()
permissions = base::readByte(); permissions = base::readByte();
attributes = base::readByte(); attributes = base::readByte();
type = (WiiFile::Type)base::readByte(); type = (WiiFile::Type)base::readByte();
name = std::string((const char*)base::readBytes(0x45)); name = std::string((const char*)base::readBytes(0x45).get());
ret = new WiiFile(std::string(name)); ret = new WiiFile(std::string(name));
ret->setPermissions(permissions); ret->setPermissions(permissions);
ret->setAttributes(attributes); ret->setAttributes(attributes);
ret->setType((WiiFile::Type)type); ret->setType((WiiFile::Type)type);
atUint8* iv = (atUint8*)base::readBytes(0x10); std::unique_ptr<atUint8[]> iv = base::readUBytes(0x10);
base::seek(0x20); base::seek(0x20);
if (type == WiiFile::File) if (type == WiiFile::File)
{ {
// Read file data // Read file data
int roundedLen = (fileLen + 63) & ~63; int roundedLen = (fileLen + 63) & ~63;
filedata = (atUint8*)base::readBytes(roundedLen); std::unique_ptr<atUint8[]> filedata = base::readUBytes(roundedLen);
// Decrypt file // Decrypt file
std::cout << "Decrypting: " << ret->filename() << "..."; std::cout << "Decrypting: " << ret->filename() << "...";
atUint8* decData = new atUint8[roundedLen]; atUint8* decData = new atUint8[roundedLen];
std::unique_ptr<IAES> aes = NewAES(); std::unique_ptr<IAES> aes = NewAES();
aes->setKey(SD_KEY); aes->setKey(SD_KEY);
aes->decrypt(iv, filedata, decData, roundedLen); aes->decrypt(iv.get(), filedata.get(), decData, roundedLen);
delete filedata;
ret->setData(decData); ret->setData(decData);
ret->setLength(fileLen); ret->setLength(fileLen);
std::cout << "done" << std::endl; std::cout << "done" << std::endl;
@ -325,18 +323,18 @@ void WiiSaveReader::readCerts(atUint32 totalSize)
{ {
std::cout << "Reading certs..." << std::endl; std::cout << "Reading certs..." << std::endl;
atUint32 dataSize = totalSize - 0x340; atUint32 dataSize = totalSize - 0x340;
atUint8* sig = (atUint8*)base::readBytes(0x40); std::unique_ptr<atUint8[]> sig = base::readUBytes(0x40);
atUint8* ngCert = (atUint8*)base::readBytes(0x180); std::unique_ptr<atUint8[]> ngCert = base::readUBytes(0x180);
atUint8* apCert = (atUint8*)base::readBytes(0x180); std::unique_ptr<atUint8[]> apCert = base::readUBytes(0x180);
base::seek(0xF0C0, SeekOrigin::Begin); base::seek(0xF0C0, SeekOrigin::Begin);
atUint8* data = (atUint8*)base::readBytes(dataSize); std::unique_ptr<atUint8[]> data = base::readUBytes(dataSize);
atUint8* hash; atUint8* hash;
hash = getSha1(data, dataSize); hash = getSha1(data.get(), dataSize);
atUint8* hash2 = getSha1(hash, 20); atUint8* hash2 = getSha1(hash, 20);
std::cout << "validating..." << std::endl; std::cout << "validating..." << std::endl;
std::cout << (check_ec(ngCert, apCert, sig, hash2) ? "ok" : "invalid") << "..."; std::cout << (check_ec(ngCert.get(), apCert.get(), sig.get(), hash2) ? "ok" : "invalid") << "...";
std::cout << "done" << std::endl; std::cout << "done" << std::endl;
} }

View File

@ -56,17 +56,16 @@ const atUint32 ZQuestFile::Magic = 'Z' | ('Q' << 8) | ('S' << 16) | (('0' + ZQ
ZQuestFile::ZQuestFile() ZQuestFile::ZQuestFile()
: m_game(NoGame), : m_game(NoGame),
m_endian(Endian::LittleEndian), m_endian(Endian::LittleEndian),
m_data(NULL),
m_length(0) m_length(0)
{ {
initGameStrings(); initGameStrings();
} }
ZQuestFile::ZQuestFile(ZQuestFile::Game game, Endian endian, atUint8* data, atUint32 length, const std::string& gameString) ZQuestFile::ZQuestFile(ZQuestFile::Game game, Endian endian, std::unique_ptr<atUint8[]>&& data, atUint32 length, const std::string& gameString)
: m_game(game), : m_game(game),
m_gameString(gameString), m_gameString(gameString),
m_endian(endian), m_endian(endian),
m_data(data), m_data(std::move(data)),
m_length(length) m_length(length)
{ {
initGameStrings(); initGameStrings();
@ -75,13 +74,6 @@ ZQuestFile::ZQuestFile(ZQuestFile::Game game, Endian endian, atUint8* data, atUi
m_gameString = GameStrings[m_game]; m_gameString = GameStrings[m_game];
} }
ZQuestFile::~ZQuestFile()
{
delete[] m_data;
m_data = NULL;
m_length = 0;
}
void ZQuestFile::setGame(ZQuestFile::Game game) void ZQuestFile::setGame(ZQuestFile::Game game)
{ {
m_game = game; m_game = game;
@ -107,24 +99,15 @@ Endian ZQuestFile::endian() const
return m_endian; return m_endian;
} }
void ZQuestFile::setData(atUint8* data, atUint32 length) void ZQuestFile::setData(std::unique_ptr<atUint8[]>&& data, atUint32 length)
{ {
// ensure we're not overwritting our data without freeing first m_data = std::move(data);
// or assigning unnecessisarily m_length = length;
if (!m_data || m_data != data)
{
delete[] m_data;
m_data = new atUint8[length];
// Why is this memcpy needed?
// I get SIGABRT without it, need to research
memcpy(m_data, data, length);
m_length = length;
}
} }
atUint8* ZQuestFile::data() const atUint8* ZQuestFile::data() const
{ {
return m_data; return m_data.get();
} }

View File

@ -45,7 +45,6 @@ ZQuestFile* ZQuestFileReader::read()
std::string gameString; std::string gameString;
atUint16 BOM; atUint16 BOM;
atUint32 checksum = 0; atUint32 checksum = 0;
atUint8* data;
magic = base::readUint32(); magic = base::readUint32();
@ -68,7 +67,7 @@ ZQuestFile* ZQuestFileReader::read()
if (version >= ZQUEST_VERSION_CHECK(2, 0, 0)) if (version >= ZQUEST_VERSION_CHECK(2, 0, 0))
{ {
gameString = std::string((const char*)base::readBytes(0x0A), 0x0A); gameString = std::string((const char*)base::readBytes(0x0A).get(), 0x0A);
for (size_t i = 0; i < ZQuestFile::gameStringList().size(); i++) for (size_t i = 0; i < ZQuestFile::gameStringList().size(); i++)
{ {
@ -90,13 +89,12 @@ ZQuestFile* ZQuestFileReader::read()
base::seek(0x0A); base::seek(0x0A);
} }
data = (atUint8*)base::readBytes(compressedLen); // compressedLen is always the total file size std::unique_ptr<atUint8[]> data = base::readUBytes(compressedLen); // compressedLen is always the total file size
if (version >= ZQUEST_VERSION_CHECK(2, 0, 0)) if (version >= ZQUEST_VERSION_CHECK(2, 0, 0))
{ {
if (checksum != Athena::Checksums::crc32(data, compressedLen)) if (checksum != Athena::Checksums::crc32(data.get(), compressedLen))
{ {
delete[] data;
atError("Checksum mismatch, data corrupt"); atError("Checksum mismatch, data corrupt");
return nullptr; return nullptr;
} }
@ -110,21 +108,19 @@ ZQuestFile* ZQuestFileReader::read()
if (compressedLen != uncompressedLen) if (compressedLen != uncompressedLen)
{ {
atUint8* dst = new atUint8[uncompressedLen]; atUint8* dst = new atUint8[uncompressedLen];
atUint32 dstLen = io::Compression::decompressZlib(data, compressedLen, dst, uncompressedLen); atUint32 dstLen = io::Compression::decompressZlib(data.get(), compressedLen, dst, uncompressedLen);
if (dstLen != uncompressedLen) if (dstLen != uncompressedLen)
{ {
delete[] dst; delete[] dst;
delete[] data;
atError("Error decompressing data"); atError("Error decompressing data");
return nullptr; return nullptr;
} }
delete[] data; data.reset(dst);
data = dst;
} }
return new ZQuestFile(game, BOM == 0xFEFF ? Endian::BigEndian : Endian::LittleEndian, data, uncompressedLen, gameString); return new ZQuestFile(game, BOM == 0xFEFF ? Endian::BigEndian : Endian::LittleEndian, std::move(data), uncompressedLen, gameString);
} }
} // io } // io