#ifndef MEMORYWRITER_HPP #define MEMORYWRITER_HPP #include "Athena/IStreamWriter.hpp" #include #include namespace Athena { namespace io { /*! \class MemoryWriter * \brief A Stream class for writing data to a memory position * * A Class for writing binary data to a file or memory stream, * all work is done using a memory buffer, and not written directly to the disk * this allows for fast, flexible code as well as the ability to quickly modify data * \sa Stream */ class MemoryWriter : public IStreamWriter { public: /*! \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); /*! \brief Sets the buffers position relative to the specified position.
* It seeks relative to the current position by default. * \param position where in the buffer to seek * \param origin The Origin to seek \sa SeekOrigin */ void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current); /*! \brief Returns the current position in the stream. * * \return Int64 The current position in the stream. */ inline atUint64 position() const {return m_position;} /*! \brief Returns whether or not the stream is at the end. * * \return bool True if at end; False otherwise. */ inline atUint64 length() const {return m_length;} 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. * \param data The new buffer. * \param length The length of the new buffer. * \throw IOException */ void setData(atUint8* data, atUint64 length); /*! \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; /*! \brief Sets the target file * * \param filepath The path to write to. */ inline void setFilepath(const std::string& filepath) {m_filepath = filepath;} /*! \brief * Returns the target file */ inline std::string filepath() const {return m_filepath;} /*! \brief Saves the file to the specified file. * * \param filename If not empty, the filename to save to */ void save(const std::string& filename = ""); /*! \brief Writes the given buffer with the specified length, buffers can be bigger than the length * however it's undefined behavior to try and write a buffer which is smaller than the given length. * * \param data The buffer to write * \param length The amount to write */ void writeUBytes(const atUint8* data, atUint64 len); protected: MemoryWriter() {} atUint8* m_data; atUint64 m_length; atUint64 m_position; std::string m_filepath; //!< Path to the target file }; 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=nullptr, atUint64 length=0x10); /*! \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); /*! \brief Sets the buffers position relative to the specified position.
* It seeks relative to the current position by default. * \param position where in the buffer to seek * \param origin The Origin to seek \sa SeekOrigin */ void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current); /*! \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. * \param data The new buffer. * \param length The length of the new buffer. * \throw IOException */ void setData(const atUint8* data, atUint64 length); /*! \brief Writes the given buffer with the specified length, buffers can be bigger than the length * however it's undefined behavior to try and write a buffer which is smaller than the given length. * * \param data The buffer to write * \param length The amount to write */ void writeUBytes(const atUint8* data, atUint64 len); protected: std::unique_ptr m_dataCopy; private: void resize(atUint64 newSize); }; } } #ifndef MEMORYWRITER_BASE #define MEMORYWRITER_BASE() \ 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