diff --git a/include/athena/IStreamWriter.hpp b/include/athena/IStreamWriter.hpp
index afabd68..579b551 100644
--- a/include/athena/IStreamWriter.hpp
+++ b/include/athena/IStreamWriter.hpp
@@ -99,7 +99,7 @@ public:
* @param data The buffer to write
* @param length The amount to write
*/
- inline void writeBytes(const atInt8* data, atUint64 len) {writeUBytes((atUint8*)data, len);}
+ inline void writeBytes(const void* data, atUint64 len) {writeUBytes((atUint8*)data, len);}
/** @brief Writes an Int16 to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
diff --git a/include/athena/MemoryWriter.hpp b/include/athena/MemoryWriter.hpp
index ee757e2..2ad2c2a 100644
--- a/include/athena/MemoryWriter.hpp
+++ b/include/athena/MemoryWriter.hpp
@@ -23,12 +23,14 @@ class MemoryWriter : public IStreamWriter
{
public:
+ virtual ~MemoryWriter();
+
/*! \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, atUint64 length);
+ explicit MemoryWriter(atUint8* data, atUint64 length, bool takeOwnership = false);
/*! \brief Sets the buffers position relative to the specified position.
* It seeks relative to the current position by default.
@@ -54,23 +56,18 @@ public:
inline bool isOpen() const {return true;}
- /*! \brief Sets the buffer to the given one, deleting the current one.
- * BEWARE: As this deletes the current buffer it WILL cause a loss of data
- * if that was not the intent.
- * Once you pass the data to setData DO NOT delete the buffer
- * as Stream now owns the address, this is done to keep memory usage down.
+ /*! \brief Sets the buffer to the given one, deleting the current one if it owns it.
* \param data The new buffer.
* \param length The length of the new buffer.
+ * \param takeOwnership Whether the Stream now owns the buffer.
* \throw IOException
*/
- void setData(atUint8* data, atUint64 length);
+ void setData(atUint8* data, atUint64 length, bool takeOwnership = false);
/*! \brief Returns a copy of the current buffer.
* Changes to the copy do not affect the buffer so it's perfectly safe to
* directly edit the buffer and use setData to set the new information.
- * However once you pass the data to setData DO NOT delete the buffer
- * as Stream now owns the address, this is done to keep memory usage down.
* \return Uint8* The copy of the buffer.
*/
atUint8* data() const;
@@ -108,6 +105,7 @@ protected:
atUint8* m_data;
atUint64 m_length;
atUint64 m_position;
+ bool m_bufferOwned;
std::string m_filepath; //!< Path to the target file
};
diff --git a/src/athena/MemoryWriter.cpp b/src/athena/MemoryWriter.cpp
index 7b87502..d8fd6c0 100644
--- a/src/athena/MemoryWriter.cpp
+++ b/src/athena/MemoryWriter.cpp
@@ -14,10 +14,11 @@ namespace athena
namespace io
{
-MemoryWriter::MemoryWriter(atUint8* data, atUint64 length)
+MemoryWriter::MemoryWriter(atUint8* data, atUint64 length, bool takeOwnership)
: m_data((atUint8*)data),
m_length(length),
- m_position(0)
+ m_position(0),
+ m_bufferOwned(takeOwnership)
{
if (!data)
{
@@ -34,11 +35,20 @@ MemoryWriter::MemoryWriter(atUint8* data, atUint64 length)
}
}
+MemoryWriter::~MemoryWriter()
+{
+ if (m_bufferOwned)
+ delete m_data;
+ m_data = nullptr;
+ m_length = 0;
+}
+
MemoryCopyWriter::MemoryCopyWriter(atUint8* data, atUint64 length)
{
m_data = data;
m_length = length;
m_position = 0;
+ m_bufferOwned = false;
if (length == 0)
{
@@ -46,7 +56,6 @@ MemoryCopyWriter::MemoryCopyWriter(atUint8* data, atUint64 length)
setError();
return;
}
-
m_dataCopy.reset(new atUint8[length]);
m_data = m_dataCopy.get();
if (data)
@@ -54,13 +63,13 @@ MemoryCopyWriter::MemoryCopyWriter(atUint8* data, atUint64 length)
}
MemoryCopyWriter::MemoryCopyWriter(const std::string& filename)
- : MemoryWriter(NULL, 0)
{
m_filepath = filename;
m_length = 0x10;
m_position = 0;
m_dataCopy.reset(new atUint8[m_length]);
m_data = m_dataCopy.get();
+ m_bufferOwned = false;
if (!m_data)
{
@@ -68,16 +77,14 @@ MemoryCopyWriter::MemoryCopyWriter(const std::string& filename)
setError();
return;
}
-
- memset(m_data, 0, m_length);
}
void MemoryWriter::seek(atInt64 position, SeekOrigin origin)
{
switch (origin)
{
- case SeekOrigin::Begin:
- if (position < 0)
+ case SeekOrigin::Begin:
+ if (position < 0)
{
atError("Position outside stream bounds");
setError();
@@ -180,11 +187,15 @@ void MemoryCopyWriter::seek(atInt64 position, SeekOrigin origin)
}
}
-void MemoryWriter::setData(atUint8* data, atUint64 length)
+void MemoryWriter::setData(atUint8* data, atUint64 length, bool takeOwnership)
{
+ if (m_bufferOwned)
+ delete m_data;
+
m_data = (atUint8*)data;
m_length = length;
m_position = 0;
+ m_bufferOwned = takeOwnership;
}
void MemoryCopyWriter::setData(const atUint8* data, atUint64 length)
@@ -194,6 +205,7 @@ void MemoryCopyWriter::setData(const atUint8* data, atUint64 length)
memcpy(m_data, data, length);
m_length = length;
m_position = 0;
+ m_bufferOwned = false;
}
atUint8* MemoryWriter::data() const