mirror of https://github.com/libAthena/athena.git
added buffer-copying subclass to MemoryReader/Writer
This commit is contained in:
parent
8a397a1622
commit
ec38ba088e
|
@ -35,9 +35,9 @@ namespace io
|
|||
* all work is done using a memory buffer, and not read directly from the disk.
|
||||
* \sa BinaryReader
|
||||
*/
|
||||
class ALTTPFileReader : protected MemoryReader
|
||||
class ALTTPFileReader : protected MemoryCopyReader
|
||||
{
|
||||
MEMORYREADER_BASE();
|
||||
MEMORYCOPYREADER_BASE();
|
||||
|
||||
public:
|
||||
/*! \brief This constructor takes an existing buffer to read from.
|
||||
|
|
|
@ -34,9 +34,9 @@ namespace io
|
|||
* all work is done using a memory buffer, and not written directly to the disk.
|
||||
* \sa BinaryReader
|
||||
*/
|
||||
class ALTTPFileWriter : protected MemoryWriter
|
||||
class ALTTPFileWriter : protected MemoryCopyWriter
|
||||
{
|
||||
MEMORYWRITER_BASE();
|
||||
MEMORYCOPYWRITER_BASE();
|
||||
|
||||
public:
|
||||
/*! \brief This constructor takes an existing buffer to write to.
|
||||
|
|
|
@ -34,9 +34,9 @@ namespace io
|
|||
* all work is done using a memory buffer, and not read directly from the disk.
|
||||
* \sa BinaryReader
|
||||
*/
|
||||
class MCFileReader : public MemoryReader
|
||||
class MCFileReader : public MemoryCopyReader
|
||||
{
|
||||
MEMORYREADER_BASE();
|
||||
MEMORYCOPYREADER_BASE();
|
||||
public:
|
||||
/*!
|
||||
* \brief This constructor takes an existing buffer to read from.
|
||||
|
|
|
@ -35,9 +35,9 @@ namespace io
|
|||
* all work is done using a memory buffer, and not written directly from the disk.
|
||||
* \sa BinaryWriter
|
||||
*/
|
||||
class MCFileWriter : protected MemoryWriter
|
||||
class MCFileWriter : protected MemoryCopyWriter
|
||||
{
|
||||
MEMORYWRITER_BASE();
|
||||
MEMORYCOPYWRITER_BASE();
|
||||
public:
|
||||
/*!
|
||||
* \brief This constructor takes an existing buffer to write to.
|
||||
|
|
|
@ -20,21 +20,13 @@ namespace io
|
|||
class MemoryReader : public IStreamReader
|
||||
{
|
||||
public:
|
||||
~MemoryReader();
|
||||
|
||||
/*! \brief This constructor takes an existing buffer to read from.
|
||||
/*! \brief This constructor references an existing buffer to read from.
|
||||
*
|
||||
* \param data The existing buffer
|
||||
* \param length The length of the existing buffer
|
||||
*/
|
||||
MemoryReader(const atUint8* data, atUint64 length);
|
||||
|
||||
/*! \brief This constructor creates an instance from a file on disk.
|
||||
*
|
||||
* \param filename The file to create the stream from
|
||||
*/
|
||||
MemoryReader(const std::string& filename);
|
||||
|
||||
/*! \brief Sets the buffers position relative to the specified position.<br />
|
||||
* It seeks relative to the current position by default.
|
||||
* \param position where in the buffer to seek
|
||||
|
@ -78,14 +70,44 @@ public:
|
|||
*/
|
||||
atUint8* data() const;
|
||||
|
||||
/*! \brief Reads a specified number of bytes to user-allocated buffer
|
||||
* \param buf User-allocated buffer pointer
|
||||
* \param len Length to read
|
||||
* \return Number of bytes read
|
||||
*/
|
||||
atUint64 readUBytesToBuf(void* buf, atUint64 len);
|
||||
|
||||
protected:
|
||||
const atUint8* m_data;
|
||||
atUint64 m_length;
|
||||
atUint64 m_position;
|
||||
};
|
||||
|
||||
class MemoryCopyReader : public MemoryReader
|
||||
{
|
||||
public:
|
||||
/*! \brief This constructor copies an existing buffer to read from.
|
||||
*
|
||||
* \param data The existing buffer
|
||||
* \param length The length of the existing buffer
|
||||
*/
|
||||
MemoryCopyReader(const atUint8* data, atUint64 length);
|
||||
|
||||
/*! \brief This constructor creates an instance from a file on disk.
|
||||
*
|
||||
* \param filename The file to create the stream from
|
||||
*/
|
||||
MemoryCopyReader(const std::string& filename)
|
||||
: MemoryReader(NULL, 0),
|
||||
m_filepath(filename)
|
||||
{loadData();}
|
||||
|
||||
void setData(const atUint8* data, atUint64 length);
|
||||
|
||||
protected:
|
||||
void loadData();
|
||||
atUint8* m_data;
|
||||
atUint64 m_length;
|
||||
std::unique_ptr<atUint8[]> m_dataCopy;
|
||||
std::string m_filepath; //!< Path to the target file
|
||||
atUint64 m_position;
|
||||
};
|
||||
|
||||
} // io
|
||||
|
@ -98,4 +120,11 @@ private: \
|
|||
|
||||
#endif // MEMORYREADER_BASE
|
||||
|
||||
#ifndef MEMORYCOPYREADER_BASE
|
||||
#define MEMORYCOPYREADER_BASE() \
|
||||
private: \
|
||||
typedef Athena::io::MemoryCopyReader base
|
||||
|
||||
#endif // MEMORYCOPYREADER_BASE
|
||||
|
||||
#endif // MEMORYREADER_HPP
|
||||
|
|
|
@ -21,22 +21,14 @@ namespace io
|
|||
class MemoryWriter : public IStreamWriter
|
||||
{
|
||||
public:
|
||||
~MemoryWriter();
|
||||
|
||||
/*! \brief This constructor takes an existing buffer to write to.
|
||||
/*! \brief This constructor references an existing buffer to write to in-place.
|
||||
*
|
||||
* \param data The existing buffer
|
||||
* \param length The length of the existing buffer
|
||||
*/
|
||||
explicit MemoryWriter(atUint8* data = nullptr, atUint64 length = 0x10);
|
||||
|
||||
/*! \brief This constructor creates an instance from a file on disk.
|
||||
*
|
||||
* \param filename The file to create the stream from
|
||||
*/
|
||||
MemoryWriter(const std::string& filename, std::function<void(int)> progressFun = nullptr);
|
||||
|
||||
|
||||
/*! \brief Sets the buffers position relative to the specified position.<br />
|
||||
* It seeks relative to the current position by default.
|
||||
* \param position where in the buffer to seek
|
||||
|
@ -70,7 +62,7 @@ public:
|
|||
* \param length The length of the new buffer.
|
||||
* \throw IOException
|
||||
*/
|
||||
void setData(const atUint8* data, atUint64 length);
|
||||
void setData(atUint8* data, atUint64 length);
|
||||
|
||||
|
||||
/*! \brief Returns a copy of the current buffer.<br />
|
||||
|
@ -113,11 +105,35 @@ public:
|
|||
protected:
|
||||
atUint8* m_data;
|
||||
atUint64 m_length;
|
||||
std::string m_filepath; //!< Path to the target file
|
||||
atUint64 m_position;
|
||||
std::string m_filepath; //!< Path to the target file
|
||||
private:
|
||||
void resize(atUint64 newSize);
|
||||
};
|
||||
|
||||
class MemoryCopyWriter : public MemoryWriter
|
||||
{
|
||||
public:
|
||||
|
||||
/*! \brief This constructor copies an existing buffer to write to.
|
||||
*
|
||||
* \param data The existing buffer
|
||||
* \param length The length of the existing buffer
|
||||
*/
|
||||
explicit MemoryCopyWriter(atUint8* data, atUint64 length);
|
||||
|
||||
/*! \brief This constructor creates an instance from a file on disk.
|
||||
*
|
||||
* \param filename The file to create the stream from
|
||||
*/
|
||||
MemoryCopyWriter(const std::string& filename);
|
||||
|
||||
void setData(const atUint8* data, atUint64 length);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<atUint8[]> m_dataCopy;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,4 +142,11 @@ private:
|
|||
private: \
|
||||
typedef Athena::io::MemoryWriter base
|
||||
#endif // BINARYWRITER_BASE
|
||||
|
||||
#ifndef MEMORYCOPYWRITER_BASE
|
||||
#define MEMORYCOPYWRITER_BASE() \
|
||||
private: \
|
||||
typedef Athena::io::MemoryCopyWriter base
|
||||
#endif // BINARYWRITER_BASE
|
||||
|
||||
#endif // MEMORYWRITER_HPP
|
||||
|
|
|
@ -24,9 +24,9 @@ namespace Athena
|
|||
class SkywardSwordFile;
|
||||
namespace io
|
||||
{
|
||||
class SkywardSwordFileReader : public MemoryReader
|
||||
class SkywardSwordFileReader : public MemoryCopyReader
|
||||
{
|
||||
MEMORYREADER_BASE();
|
||||
MEMORYCOPYREADER_BASE();
|
||||
public:
|
||||
|
||||
SkywardSwordFileReader(atUint8* data, atUint64 length);
|
||||
|
|
|
@ -26,9 +26,9 @@ class SkywardSwordFile;
|
|||
namespace io
|
||||
{
|
||||
|
||||
class SkywardSwordFileWriter : public MemoryWriter
|
||||
class SkywardSwordFileWriter : public MemoryCopyWriter
|
||||
{
|
||||
MEMORYWRITER_BASE();
|
||||
MEMORYCOPYWRITER_BASE();
|
||||
public:
|
||||
SkywardSwordFileWriter(atUint8* data, atUint64 len);
|
||||
SkywardSwordFileWriter(const std::string& filename);
|
||||
|
|
|
@ -29,9 +29,9 @@ class SpriteFile;
|
|||
namespace io
|
||||
{
|
||||
|
||||
class SpriteFileReader : public MemoryReader
|
||||
class SpriteFileReader : public MemoryCopyReader
|
||||
{
|
||||
MEMORYREADER_BASE();
|
||||
MEMORYCOPYREADER_BASE();
|
||||
public:
|
||||
SpriteFileReader(atUint8* data, atUint64 length);
|
||||
SpriteFileReader(const std::string& filepath);
|
||||
|
|
|
@ -29,9 +29,9 @@ class SpriteFile;
|
|||
namespace io
|
||||
{
|
||||
|
||||
class SpriteFileWriter : public MemoryWriter
|
||||
class SpriteFileWriter : public MemoryCopyWriter
|
||||
{
|
||||
MEMORYWRITER_BASE();
|
||||
MEMORYCOPYWRITER_BASE();
|
||||
public:
|
||||
SpriteFileWriter(atUint8* data, atUint64 length);
|
||||
|
||||
|
|
|
@ -37,9 +37,9 @@ namespace io
|
|||
* all work is done using a memory buffer, and not read directly from the disk.
|
||||
* \sa BinaryReader
|
||||
*/
|
||||
class WiiSaveReader : protected MemoryReader
|
||||
class WiiSaveReader : protected MemoryCopyReader
|
||||
{
|
||||
MEMORYREADER_BASE();
|
||||
MEMORYCOPYREADER_BASE();
|
||||
public:
|
||||
/*! \brief This constructor takes an existing buffer to read from.
|
||||
*
|
||||
|
|
|
@ -36,9 +36,9 @@ namespace io
|
|||
* all work is done using a memory buffer, and not written directly to the disk.
|
||||
* \sa BinaryReader
|
||||
*/
|
||||
class WiiSaveWriter : protected MemoryWriter
|
||||
class WiiSaveWriter : protected MemoryCopyWriter
|
||||
{
|
||||
MEMORYWRITER_BASE();
|
||||
MEMORYCOPYWRITER_BASE();
|
||||
public:
|
||||
/*! \brief This constructor creates an instance from a file on disk.
|
||||
*
|
||||
|
|
|
@ -29,9 +29,9 @@ namespace io
|
|||
/*!
|
||||
* \brief The ZQuestFileReader class
|
||||
*/
|
||||
class ZQuestFileReader : protected MemoryReader
|
||||
class ZQuestFileReader : protected MemoryCopyReader
|
||||
{
|
||||
MEMORYREADER_BASE();
|
||||
MEMORYCOPYREADER_BASE();
|
||||
|
||||
public:
|
||||
/*!
|
||||
|
|
|
@ -29,9 +29,9 @@ namespace io
|
|||
/*!
|
||||
* \brief The ZQuestFileWriter class
|
||||
*/
|
||||
class ZQuestFileWriter : protected MemoryWriter
|
||||
class ZQuestFileWriter : protected MemoryCopyWriter
|
||||
{
|
||||
MEMORYWRITER_BASE();
|
||||
MEMORYCOPYWRITER_BASE();
|
||||
|
||||
public:
|
||||
/*!
|
||||
|
|
|
@ -39,7 +39,7 @@ MCFile* MCFileReader::readFile()
|
|||
base::m_position = 0;
|
||||
|
||||
if (isScrambled)
|
||||
MCFile::unscramble(base::m_data, base::m_length);
|
||||
MCFile::unscramble(base::m_dataCopy.get(), base::m_length);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,8 @@ namespace Athena
|
|||
namespace io
|
||||
{
|
||||
MemoryReader::MemoryReader(const atUint8* data, atUint64 length)
|
||||
: m_length(length),
|
||||
: m_data(data),
|
||||
m_length(length),
|
||||
m_position(0)
|
||||
{
|
||||
if (!data)
|
||||
|
@ -27,24 +28,20 @@ MemoryReader::MemoryReader(const atUint8* data, atUint64 length)
|
|||
|
||||
if (length == 0)
|
||||
THROW_INVALID_OPERATION_EXCEPTION("length cannot be 0");
|
||||
|
||||
m_data = new atUint8[m_length];
|
||||
memcpy(m_data, data, m_length);
|
||||
}
|
||||
|
||||
MemoryReader::MemoryReader(const std::string& filename)
|
||||
: m_data(NULL),
|
||||
m_length(0),
|
||||
m_filepath(filename),
|
||||
m_position(0)
|
||||
MemoryCopyReader::MemoryCopyReader(const atUint8* data, atUint64 length)
|
||||
: MemoryReader(data, length)
|
||||
{
|
||||
loadData();
|
||||
}
|
||||
if (!data)
|
||||
THROW_INVALID_DATA_EXCEPTION("data cannot be NULL");
|
||||
|
||||
MemoryReader::~MemoryReader()
|
||||
{
|
||||
delete[] m_data;
|
||||
m_data = NULL;
|
||||
if (length == 0)
|
||||
THROW_INVALID_OPERATION_EXCEPTION("length cannot be 0");
|
||||
|
||||
m_dataCopy.reset(new atUint8[m_length]);
|
||||
m_data = m_dataCopy.get();
|
||||
memcpy(m_dataCopy.get(), data, m_length);
|
||||
}
|
||||
|
||||
void MemoryReader::seek(atInt64 position, SeekOrigin origin)
|
||||
|
@ -76,14 +73,20 @@ void MemoryReader::seek(atInt64 position, SeekOrigin origin)
|
|||
|
||||
void MemoryReader::setData(const atUint8* data, atUint64 length)
|
||||
{
|
||||
if (m_data)
|
||||
delete[] m_data;
|
||||
|
||||
m_data = (atUint8*)data;
|
||||
m_length = length;
|
||||
m_position = 0;
|
||||
}
|
||||
|
||||
void MemoryCopyReader::setData(const atUint8* data, atUint64 length)
|
||||
{
|
||||
m_dataCopy.reset(new atUint8[length]);
|
||||
m_data = m_dataCopy.get();
|
||||
memcpy(m_dataCopy.get(), data, length);
|
||||
m_length = length;
|
||||
m_position = 0;
|
||||
}
|
||||
|
||||
atUint8* MemoryReader::data() const
|
||||
{
|
||||
atUint8* ret = new atUint8[m_length];
|
||||
|
@ -94,9 +97,6 @@ atUint8* MemoryReader::data() const
|
|||
|
||||
atUint64 MemoryReader::readUBytesToBuf(void* buf, atUint64 length)
|
||||
{
|
||||
if (!m_data)
|
||||
loadData();
|
||||
|
||||
if (m_position + length > m_length)
|
||||
THROW_IO_EXCEPTION_RETURN(0, "Position %0.8X outside stream bounds ", m_position);
|
||||
|
||||
|
@ -105,7 +105,7 @@ atUint64 MemoryReader::readUBytesToBuf(void* buf, atUint64 length)
|
|||
return length;
|
||||
}
|
||||
|
||||
void MemoryReader::loadData()
|
||||
void MemoryCopyReader::loadData()
|
||||
{
|
||||
FILE* in;
|
||||
atUint64 length;
|
||||
|
@ -117,7 +117,8 @@ void MemoryReader::loadData()
|
|||
rewind(in);
|
||||
|
||||
length = utility::fileSize(m_filepath);
|
||||
m_data = new atUint8[length];
|
||||
m_dataCopy.reset(new atUint8[length]);
|
||||
m_data = m_dataCopy.get();
|
||||
|
||||
atUint64 done = 0;
|
||||
atUint64 blocksize = BLOCKSZ;
|
||||
|
@ -127,7 +128,7 @@ void MemoryReader::loadData()
|
|||
if (blocksize > length - done)
|
||||
blocksize = length - done;
|
||||
|
||||
atInt64 ret = fread(m_data + done, 1, blocksize, in);
|
||||
atInt64 ret = fread(m_dataCopy.get() + done, 1, blocksize, in);
|
||||
|
||||
if (ret < 0)
|
||||
THROW_IO_EXCEPTION("Error reading data from disk");
|
||||
|
|
|
@ -23,18 +23,33 @@ MemoryWriter::MemoryWriter(atUint8* data, atUint64 length)
|
|||
m_length(length),
|
||||
m_position(0)
|
||||
{
|
||||
if (!m_data && m_length > 0)
|
||||
m_data = new atUint8[m_length];
|
||||
if (!data)
|
||||
THROW_INVALID_DATA_EXCEPTION("data cannot be NULL");
|
||||
|
||||
if (length == 0)
|
||||
THROW_INVALID_OPERATION_EXCEPTION("length cannot be 0");
|
||||
}
|
||||
|
||||
MemoryWriter::MemoryWriter(const std::string& filename, std::function<void(int)> progressFun)
|
||||
: m_length(0),
|
||||
m_filepath(filename),
|
||||
m_position(0)
|
||||
MemoryCopyWriter::MemoryCopyWriter(atUint8* data, atUint64 length)
|
||||
: MemoryWriter(data, length)
|
||||
{
|
||||
if (length == 0)
|
||||
THROW_INVALID_OPERATION_EXCEPTION("length cannot be 0");
|
||||
|
||||
m_dataCopy.reset(new atUint8[length]);
|
||||
m_data = m_dataCopy.get();
|
||||
if (data)
|
||||
memcpy(m_data, data, length);
|
||||
}
|
||||
|
||||
MemoryCopyWriter::MemoryCopyWriter(const std::string& filename)
|
||||
: MemoryWriter(NULL, 0)
|
||||
{
|
||||
m_filepath = filename;
|
||||
m_length = 0x10;
|
||||
m_position = 0;
|
||||
m_data = new atUint8[m_length];
|
||||
m_dataCopy.reset(new atUint8[m_length]);
|
||||
m_data = m_dataCopy.get();
|
||||
|
||||
if (!m_data)
|
||||
THROW_IO_EXCEPTION("Could not allocate memory!");
|
||||
|
@ -42,12 +57,6 @@ MemoryWriter::MemoryWriter(const std::string& filename, std::function<void(int)>
|
|||
memset(m_data, 0, m_length);
|
||||
}
|
||||
|
||||
MemoryWriter::~MemoryWriter()
|
||||
{
|
||||
delete[] m_data;
|
||||
m_data = nullptr;
|
||||
}
|
||||
|
||||
void MemoryWriter::seek(atInt64 position, SeekOrigin origin)
|
||||
{
|
||||
switch (origin)
|
||||
|
@ -84,16 +93,22 @@ void MemoryWriter::seek(atInt64 position, SeekOrigin origin)
|
|||
}
|
||||
}
|
||||
|
||||
void MemoryWriter::setData(const atUint8* data, atUint64 length)
|
||||
void MemoryWriter::setData(atUint8* data, atUint64 length)
|
||||
{
|
||||
if (m_data)
|
||||
delete[] m_data;
|
||||
|
||||
m_data = (atUint8*)data;
|
||||
m_length = length;
|
||||
m_position = 0;
|
||||
}
|
||||
|
||||
void MemoryCopyWriter::setData(const atUint8* data, atUint64 length)
|
||||
{
|
||||
m_dataCopy.reset(new atUint8[length]);
|
||||
m_data = m_dataCopy.get();
|
||||
memcpy(m_data, data, length);
|
||||
m_length = length;
|
||||
m_position = 0;
|
||||
}
|
||||
|
||||
atUint8* MemoryWriter::data() const
|
||||
{
|
||||
atUint8* ret = new atUint8[m_length];
|
||||
|
@ -105,9 +120,6 @@ atUint8* MemoryWriter::data() const
|
|||
|
||||
void MemoryWriter::save(const std::string& filename)
|
||||
{
|
||||
if (!isOpen())
|
||||
THROW_INVALID_OPERATION_EXCEPTION("File not open for writing");
|
||||
|
||||
if (filename.empty() && m_filepath.empty())
|
||||
THROW_INVALID_OPERATION_EXCEPTION("No file specified, cannot save.");
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ atUint32 LZType10::compress(const atUint8* src, atUint8** dstBuf, atUint32 srcLe
|
|||
atUint32 encodeSize = (srcLength << 8) | (0x10);
|
||||
encodeSize = Athena::utility::LittleUint32(encodeSize); //File size needs to be written as little endian always
|
||||
|
||||
Athena::io::MemoryWriter outbuf("tmp");
|
||||
Athena::io::MemoryCopyWriter outbuf("tmp");
|
||||
outbuf.writeUint32(encodeSize);
|
||||
|
||||
atUint8* ptrStart = (atUint8*)src;
|
||||
|
|
|
@ -13,7 +13,7 @@ LZType11::LZType11(atInt32 minimumOffset, atInt32 slidingWindow, atInt32 minimum
|
|||
|
||||
atUint32 LZType11::compress(const atUint8* src, atUint8** dst, atUint32 srcLength)
|
||||
{
|
||||
Athena::io::MemoryWriter outbuff("tmp");
|
||||
Athena::io::MemoryCopyWriter outbuff("tmp");
|
||||
|
||||
if (srcLength > 0xFFFFFF) // If length is greater than 24 bits or 16 Megs
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue