diff --git a/include/Athena/FileReader.hpp b/include/Athena/FileReader.hpp index cdd7703..c671153 100644 --- a/include/Athena/FileReader.hpp +++ b/include/Athena/FileReader.hpp @@ -40,6 +40,7 @@ public: bool isOpen() const; bool save(); void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current); + inline void seekAlign32() {seek(ROUND_UP_32(position()), SeekOrigin::Begin);} bool atEnd() const; atUint64 position() const; atUint64 length() const; @@ -51,6 +52,8 @@ public: atInt8 readByte(); atUint8* readUBytes(atUint64 len); atInt8* readBytes(atUint64 len); + atUint64 readBytesToBuf(void* buf, atUint64 len) {return readUBytesToBuf(buf, len);} + atUint64 readUBytesToBuf(void* buf, atUint64 len); atUint16 readUint16(); atInt16 readInt16(); atUint32 readUint32(); diff --git a/include/Athena/FileWriter.hpp b/include/Athena/FileWriter.hpp index a5d43e4..49f3445 100644 --- a/include/Athena/FileWriter.hpp +++ b/include/Athena/FileWriter.hpp @@ -37,6 +37,7 @@ public: bool isOpen() const; bool save(); void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current); + inline void seekAlign32() {seek(ROUND_UP_32(position()), SeekOrigin::Begin);} bool atEnd() const; atUint64 position() const; atUint64 length() const; diff --git a/include/Athena/Global.hpp b/include/Athena/Global.hpp index 58d1a53..5c3c5ae 100644 --- a/include/Athena/Global.hpp +++ b/include/Athena/Global.hpp @@ -59,6 +59,9 @@ #define BLOCKSZ 512 #endif +#define ROUND_UP_32(val) (((val) + 31) & ~31) +#define ROUND_UP_16(val) (((val) + 15) & ~15) + namespace Athena { enum class SeekOrigin diff --git a/include/Athena/IStreamReader.hpp b/include/Athena/IStreamReader.hpp index 8c0f940..de1fb3c 100644 --- a/include/Athena/IStreamReader.hpp +++ b/include/Athena/IStreamReader.hpp @@ -17,6 +17,7 @@ public: virtual bool isLittleEndian()const= 0; virtual bool isOpen() const= 0; virtual void seek(atInt64, SeekOrigin)=0; + virtual void seekAlign32()=0; virtual bool atEnd() const= 0; virtual atUint64 position() const= 0; virtual atUint64 length() const= 0; @@ -26,6 +27,8 @@ public: virtual atInt8 readByte()=0; virtual atUint8* readUBytes(atUint64)=0; virtual atInt8* readBytes(atUint64)=0; + virtual atUint64 readUBytesToBuf(void*, atUint64)=0; + virtual atUint64 readBytesToBuf(void*, atUint64)=0; virtual atUint16 readUint16()=0; virtual atInt16 readInt16()=0; virtual atUint32 readUint32()=0; diff --git a/include/Athena/IStreamWriter.hpp b/include/Athena/IStreamWriter.hpp index 0e24e0b..bdc2712 100644 --- a/include/Athena/IStreamWriter.hpp +++ b/include/Athena/IStreamWriter.hpp @@ -17,6 +17,7 @@ public: virtual bool isLittleEndian()const= 0; virtual bool isOpen() const= 0; virtual void seek(atInt64, SeekOrigin)=0; + virtual void seekAlign32()=0; virtual bool atEnd() const= 0; virtual atUint64 position() const= 0; virtual atUint64 length() const= 0; diff --git a/include/Athena/MemoryReader.hpp b/include/Athena/MemoryReader.hpp index 90d23dd..7737429 100644 --- a/include/Athena/MemoryReader.hpp +++ b/include/Athena/MemoryReader.hpp @@ -87,6 +87,9 @@ public: */ void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current); + /*! \brief Sets the buffers position relative to the next 32-byte aligned position.
+ */ + inline void seekAlign32() {seek(ROUND_UP_32(m_position), SeekOrigin::Begin);} /*! \brief Returns whether or not the stream is at the end. * @@ -167,13 +170,16 @@ public: * * \return Uint8* The buffer at the current position from the given length. */ - atInt8* readBytes(atUint64 length); + inline atInt8* readBytes(atUint64 length) {return (atInt8*)readUBytes(length);} /*! \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. */ atUint8* readUBytes(atUint64 length); + + atUint64 readBytesToBuf(void* buf, atUint64 len) {return readUBytesToBuf(buf, len);} + atUint64 readUBytesToBuf(void* buf, atUint64 len); /*! \brief Reads a Int16 and swaps to proper endianness depending on platform * and Stream settings, and advances the current position diff --git a/include/Athena/MemoryWriter.hpp b/include/Athena/MemoryWriter.hpp index e8001cb..a1e563b 100644 --- a/include/Athena/MemoryWriter.hpp +++ b/include/Athena/MemoryWriter.hpp @@ -87,6 +87,10 @@ public: * \param origin The Origin to seek \sa SeekOrigin */ void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current); + + /*! \brief Sets the buffers position relative to the next 32-byte aligned position.
+ */ + inline void seekAlign32() {seek(ROUND_UP_32(m_position), SeekOrigin::Begin);} /*! \brief Returns whether or not the stream is at the end. diff --git a/src/Athena/FileReader.cpp b/src/Athena/FileReader.cpp index 0a9fc79..593b175 100644 --- a/src/Athena/FileReader.cpp +++ b/src/Athena/FileReader.cpp @@ -185,6 +185,14 @@ atUint8* FileReader::readUBytes(atUint64 len) fread(val, 1, len, m_fileHandle); return val; } + +atUint64 FileReader::readUBytesToBuf(void* buf, atUint64 len) +{ + if (!isOpen()) + THROW_INVALID_OPERATION_EXCEPTION("File not open for reading"); + m_bitValid = false; + return fread(buf, 1, len, m_fileHandle); +} atInt8* FileReader::readBytes(atUint64 len) { diff --git a/src/Athena/MemoryReader.cpp b/src/Athena/MemoryReader.cpp index 6e86efd..7c49464 100644 --- a/src/Athena/MemoryReader.cpp +++ b/src/Athena/MemoryReader.cpp @@ -224,11 +224,6 @@ atUint8 MemoryReader::readUByte() return *(atUint8*)(m_data + m_position++); } -atInt8* MemoryReader::readBytes(atUint64 length) -{ - return (atInt8*)readUBytes(length); -} - atUint8* MemoryReader::readUBytes(atUint64 length) { if (!m_data) @@ -250,7 +245,26 @@ atUint8* MemoryReader::readUBytes(atUint64 length) m_position += length; return ret; } - + +atUint64 MemoryReader::readUBytesToBuf(void* buf, atUint64 length) +{ + if (!m_data) + loadData(); + + if (m_bitPosition > 0) + { + m_bitPosition = 0; + m_position += sizeof(atUint8); + } + + if (m_position + length > m_length) + THROW_IO_EXCEPTION("Position %0.16X outside stream bounds ", m_position); + + memcpy(buf, (const atUint8*)(m_data + m_position), length); + m_position += length; + return length; +} + atInt16 MemoryReader::readInt16() { if (!m_data)