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)