From 1e2065b352b33bfadd51316b5b0e7ac00a1c336f Mon Sep 17 00:00:00 2001 From: Antidote Date: Tue, 29 Jan 2013 13:46:05 -0800 Subject: [PATCH] * Fix bug in BinaryReader where it wasn't correctly reading in all the data --- include/BinaryReader.hpp | 54 +-- include/Exception.hpp | 43 +- include/FileNotFoundException.hpp | 38 +- include/InvalidOperationException.hpp | 30 +- include/Mainpage.hpp | 29 +- include/Stream.hpp | 85 ++-- libzelda.conf | 2 +- libzelda.pro | 3 + src/BinaryReader.cpp | 452 ++++++++++---------- src/Stream.cpp | 576 +++++++++++++------------- 10 files changed, 672 insertions(+), 640 deletions(-) diff --git a/include/BinaryReader.hpp b/include/BinaryReader.hpp index 460d3d9..ff782f6 100644 --- a/include/BinaryReader.hpp +++ b/include/BinaryReader.hpp @@ -12,11 +12,11 @@ // // You should have received a copy of the GNU General Public License // along with libZelda. If not, see -#ifndef __BINARYREADER_HPP__ -#define __BINARYREADER_HPP__ - -#include "Stream.hpp" -#include +#ifndef __BINARYREADER_HPP__ +#define __BINARYREADER_HPP__ + +#include "Stream.hpp" +#include /*! \class BinaryReader * \brief A Stream class for reading binary data @@ -25,9 +25,9 @@ * all work is done using a memory buffer, and not read directly from the disk * this allows for fast, flexible code as well as the ability to quickly modify data * \sa Stream - */ -class BinaryReader : public Stream -{ + */ +class BinaryReader : public Stream +{ public: /*! \brief This constructor takes an existing buffer to read from. * @@ -38,12 +38,12 @@ public: /*! \brief This constructor takes an existing Stream to read from. * * \param stream The stream to read data from - */ + */ BinaryReader(const Stream& stream); /*! \brief This constructor creates an instance from a file on disk. * * \param filename The file to create the stream from - */ + */ BinaryReader(const std::string& filename); @@ -64,7 +64,7 @@ public: * * \return Uint16 The value at the current address * \throw IOException when address is out of range - */ + */ Uint16 readUInt16(); /*! \brief Reads a Int32 and swaps to proper endianness depending on platform @@ -74,7 +74,7 @@ public: * * \return Int32 The value at the current address * \throw IOException when address is out of range - */ + */ Int32 readInt32(); /*! \brief Reads a Uint32 and swaps to proper endianness depending on platform @@ -84,7 +84,7 @@ public: * * \return Uint32 The value at the current address * \throw IOException when address is out of range - */ + */ Uint32 readUInt32(); /*! \brief Reads a Int64 and swaps to proper endianness depending on platform @@ -94,7 +94,7 @@ public: * * \return Int64 The value at the current address * \throw IOException when address is out of range - */ + */ Int64 readInt64(); /*! \brief Reads a Uint64 and swaps to proper endianness depending on platform @@ -104,7 +104,7 @@ public: * * \return Uint64 The value at the current address * \throw IOException when address is out of range - */ + */ Uint64 readUInt64(); /*! \brief Reads a float and swaps to proper endianness depending on platform @@ -114,7 +114,7 @@ public: * * \return float The value at the current address * \throw IOException when address is out of range - */ + */ float readFloat(); /*! \brief Reads a double and swaps to proper endianness depending on platform @@ -124,26 +124,26 @@ public: * * \return double The value at the current address * \throw IOException when address is out of range - */ + */ double readDouble(); /*! \brief Reads a bool and advances the current position * * \return bool The value at the current address * \throw IOException when address is out of range - */ + */ bool readBool(); /*! \brief Reads a Unicode string and advances the position in the file * * \return std::string The value at the current address * \throw IOException when address is out of range - */ + */ std::string readUnicode(); -private: +protected: /*! \brief Overload of isOpenForWriting in Stream * * \return false - */ + */ bool isOpenForWriting(); /*! \brief Overload of writeByte in Stream * @@ -153,9 +153,9 @@ private: /*! \brief Overload of writeBytes in Stream * * \throw IOException - */ - void writeBytes(Int8*, Int64); - std::string m_filename; -}; - -#endif + */ + void writeBytes(Int8*, Int64); + std::string m_filename; +}; + +#endif diff --git a/include/Exception.hpp b/include/Exception.hpp index 74011b5..6481cf5 100644 --- a/include/Exception.hpp +++ b/include/Exception.hpp @@ -13,36 +13,37 @@ // You should have received a copy of the GNU General Public License // along with libZelda. If not, see -#ifndef __EXCEPTION_HPP__ -#define __EXCEPTION_HPP__ - -#include +#ifndef __EXCEPTION_HPP__ +#define __EXCEPTION_HPP__ + +#include /*! \class Exception * \brief The baseclass for all Exceptions. * * Do Not use Exception directly, instead create an appropriate * Exception class and inherit from this baseclass. - */ -class Exception -{ + */ +class Exception +{ public: /*! \brief The constructor for an Exception * \param message The error message to throw - */ - Exception(const std::string& message) : - m_message(message) - {}; + */ + inline Exception(const std::string& message) : + m_message(message) + { + }; /*! \brief Returns the Error message of the exception * \return std::string The error message - */ - std::string message() const - { - return m_message; - }; -protected: - std::string m_message; -}; - -#endif + */ + inline std::string message() const + { + return m_message; + }; +protected: + std::string m_message; +}; + +#endif diff --git a/include/FileNotFoundException.hpp b/include/FileNotFoundException.hpp index 04e0df2..c0c09c9 100644 --- a/include/FileNotFoundException.hpp +++ b/include/FileNotFoundException.hpp @@ -13,10 +13,10 @@ // You should have received a copy of the GNU General Public License // along with libZelda. If not, see -#ifndef __FILENOTFOUNDEXCEPTION_HPP__ -#define __FILENOTFOUNDEXCEPTION_HPP__ - -#include "Exception.hpp" +#ifndef __FILENOTFOUNDEXCEPTION_HPP__ +#define __FILENOTFOUNDEXCEPTION_HPP__ + +#include "Exception.hpp" /*! \class FileNotFoundException * \brief An excpeption thrown when a file could not be found at the given path. @@ -25,24 +25,24 @@ *
* It is NOT appropriate to use throw new so avoid doing so, * keeping things on the stack as much as possible is very important for speed. - */ -class FileNotFoundException : public Exception -{ + */ +class FileNotFoundException : public Exception +{ public: /*! \brief The constructor for an FileNotFoundException * \param filename The path of the offending file. - */ - FileNotFoundException(const std::string& filename) : - Exception("FileNotFoundException:\nCouldn't not find \"" + filename + "\", please check that it exists."), - m_filename(filename) - {} + */ + inline FileNotFoundException(const std::string& filename) : + Exception("FileNotFoundException:\nCouldn't not find \"" + filename + "\", please check that it exists."), + m_filename(filename) + {} /*! \brief Returns the path of the offending file. * \return std::string The filename of the file including the path. - */ - std::string filename() const { return m_filename; } -private: - std::string m_filename; -}; - -#endif + */ + inline std::string filename() const { return m_filename; } +private: + std::string m_filename; +}; + +#endif diff --git a/include/InvalidOperationException.hpp b/include/InvalidOperationException.hpp index ce5f753..0591e93 100644 --- a/include/InvalidOperationException.hpp +++ b/include/InvalidOperationException.hpp @@ -13,11 +13,11 @@ // You should have received a copy of the GNU General Public License // along with libZelda. If not, see -#ifndef __INVALID_OPERATION_EXCEPTION_HPP__ -#define __INVALID_OPERATION_EXCEPTION_HPP__ - -#include -#include +#ifndef __INVALID_OPERATION_EXCEPTION_HPP__ +#define __INVALID_OPERATION_EXCEPTION_HPP__ + +#include +#include /*! \class InvalidOperationException * \brief An excpeption thrown on Invalid Operations calls. @@ -27,16 +27,16 @@ *
* It is NOT appropriate to use throw new so avoid doing so, * keeping things on the stack as much as possible is very important for speed. - */ -class InvalidOperationException : public Exception -{ + */ +class InvalidOperationException : public Exception +{ public: /*! \brief The constructor for an InvalidOperationException * \param error The error message to throw - */ - InvalidOperationException(const std::string& error) - : Exception("InvalidOperationException:\n" + error) - { - } -}; -#endif // __INVALID_OPERATION_EXCEPTION_HPP__ + */ + inline InvalidOperationException(const std::string& error) + : Exception("InvalidOperationException:\n" + error) + { + } +}; +#endif // __INVALID_OPERATION_EXCEPTION_HPP__ diff --git a/include/Mainpage.hpp b/include/Mainpage.hpp index c02798c..7a6f930 100644 --- a/include/Mainpage.hpp +++ b/include/Mainpage.hpp @@ -37,7 +37,34 @@ * return 0; * } * \endcode + * \section example_sec BinaryReader example + * \code + * #include "BinaryReader.hpp" + * #include "FileNotFoundException.hpp" + * #include "Exception.hpp" + * int main() + * { + * try + * { + * BinaryReader writer("test.bin"); + * std::cout << reader.readByte() << std::endl; + * std::cout << reader.readInt32() << std::endl; + * } + * catch (FileNotFoundException e) + * { + * std::cout << e.message() << std::endl; + * } + * catch (Exception e) + * { + * std::cout << e.message() << std::endl; + * } + * catch(...) + * { + * } + * return 0; + * } + * \endcode * \section Credits - * Chibi Zelda: AnimeWaterFall on Deviantart + * Chibi Zelda: AnimeWaterFall on Deviantart */ #endif // __MAINPAGE_HPP__ diff --git a/include/Stream.hpp b/include/Stream.hpp index b82b044..2935e19 100644 --- a/include/Stream.hpp +++ b/include/Stream.hpp @@ -12,10 +12,10 @@ // // You should have received a copy of the GNU General Public License // along with libZelda. If not, see -#ifndef __STREAM_HPP__ -#define __STREAM_HPP__ - -#include "Types.hpp" +#ifndef __STREAM_HPP__ +#define __STREAM_HPP__ + +#include "Types.hpp" /*! \class Stream * \brief Stream is the main class all streams inherit from @@ -28,10 +28,11 @@ *
* Stream can also be used by itself though it's not advised as it's not feature filled.
* It's highly suggested to use of the more advanced Streams such as BinaryReader. - */ -class Stream -{ + */ +class Stream +{ public: + //! \brief Default buffer block size. static const Uint32 BLOCKSZ; /*! \enum Endian @@ -47,50 +48,50 @@ public: /*! \enum SeekOrigin * \brief Specifies how to seek in a stream. - */ + */ enum SeekOrigin { Beginning = 0, //!< Tells the Stream to seek from the Beginning of the buffer. Current, //!< Tells the Stream to seek from the Current position of the buffer. End //!< Tells the Stream to seek from the End of the buffer. - }; + }; /*! \brief The default constructor - */ + */ Stream(); /*! \brief This constructor takes an existing buffer to read from. * * \param bytes The existing buffer * \param length The length of the existing buffer - */ + */ Stream(const Uint8* bytes, Uint64 length); /*! \brief This constructor creates a buffer from the given length. * * \param length The length of the existing buffer - */ + */ Stream(Int64 length); /*! \brief This constructor takes an existing Stream to read from. * * \param stream The stream to read data from - */ + */ Stream(Stream* stream); /*! \brief The destructor cleans up memory and sets everything back * to the default settings. - */ - virtual ~Stream(); + */ + virtual ~Stream(); /*! \brief Writes a bit at the current position and advances the position by one bit. * \param val the value to write * \throw IOException - */ + */ virtual void writeBit(bool val); /*! \brief Writes a byte at the current position and advances the position by one byte. * \param byte The value to write * \throw IOException - */ + */ virtual void writeByte(Int8 byte); /*! \brief Writes the given buffer with the specified length, buffers can be bigger than the length @@ -99,27 +100,27 @@ public: * \param data The buffer to write * \param length The amount to write * \throw IOException - */ + */ virtual void writeBytes(Int8* data, Int64 length); /*! \brief Reads a bit at the current position and advances the current position * * \return bool The value at the current position * \throw IOException - */ + */ virtual bool readBit(); /*! \brief Reads a byte at the current position and advances the current position * * \return Int8 The value at the current position * \throw IOException - */ + */ virtual Int8 readByte(); /*! \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. * \throw IOException - */ + */ virtual Int8* readBytes(Int64 length); /*! \brief Sets the buffers position relative to the specified position.
@@ -127,15 +128,15 @@ public: * \param position where in the buffer to seek * \param origin The Origin to seek \sa SeekOrigin * \throw IOException - */ + */ void seek(Int64 position, SeekOrigin origin = Current); /*! \brief Resizes the buffer to the given length.
* The new size must be greater than the current length to avoid loss of data. * \param newSize The amount to resize by. * \throw IOException - */ - void resize(Uint64 newSize); + */ + void resize(Uint64 newSize); /*! \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 @@ -161,44 +162,44 @@ public: /*! \brief Returns the length of the Stream. * * \return Int64 The length of the stream. - */ + */ Int64 length(); /*! \brief Returns the current position in the stream. * * \return Int64 The current position in the stream. - */ + */ Int64 position(); /*! \brief Returns whether or not the stream is at the end. * * \return bool True if at end; False otherwise. - */ + */ bool atEnd(); /*! \brief Sets whether the Stream resizes when the at the end of the buffer. * * \param val True for resizing; False for no resizing. - */ + */ void setAutoResizing(bool val); /*! \brief Retuns whether or not the Stream currenty autoresizes. * * \return True for resizing; False otherwise. - */ - bool autoResizing() const; + */ + bool autoResizing() const; /*! \brief Retuns whether or not the Stream is open for reading. * * \return True if open for reading; False otherwise. - */ + */ virtual bool isOpenForReading() const; /*! \brief Retuns whether or not the Stream is open for writing * * \return True if open for writing; False otherwise. - */ + */ virtual bool isOpenForWriting() const; /*! \brief Sets the Endianss of the stream @@ -225,14 +226,14 @@ public: * \return bool True for LittleEndian; False for BigEndian */ bool isLittleEndian() const; - -protected: - Uint32 m_bitPosition; //!< The current position in the current byte - Uint64 m_position; //!< The current position in the Stream + +protected: + Uint32 m_bitPosition; //!< The current position in the current byte + Uint64 m_position; //!< The current position in the Stream Uint64 m_length; //!< The length of the Stream - Endian m_endian; //!< The Endianess of the Stream - Uint8* m_data; //!< The Stream buffer - bool m_autoResize; //!< Whether the stream is autoresizing -}; - -#endif // __STREAM_HPP__ + Endian m_endian; //!< The Endianess of the Stream + Uint8* m_data; //!< The Stream buffer + bool m_autoResize; //!< Whether the stream is autoresizing +}; + +#endif // __STREAM_HPP__ diff --git a/libzelda.conf b/libzelda.conf index 4a23c5c..2f24f3f 100644 --- a/libzelda.conf +++ b/libzelda.conf @@ -1319,7 +1319,7 @@ MAKEINDEX_CMD_NAME = makeindex # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. -COMPACT_LATEX = NO +COMPACT_LATEX = YES # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and diff --git a/libzelda.pro b/libzelda.pro index c40db3f..9453c34 100644 --- a/libzelda.pro +++ b/libzelda.pro @@ -28,3 +28,6 @@ SOURCES += \ src/BinaryWriter.cpp \ src/BinaryReader.cpp +system("exec doxygen libzelda.conf") +system("cd doc/latex && make") +system("cd ../../") diff --git a/src/BinaryReader.cpp b/src/BinaryReader.cpp index 716fb29..6914fff 100644 --- a/src/BinaryReader.cpp +++ b/src/BinaryReader.cpp @@ -13,43 +13,43 @@ // You should have received a copy of the GNU General Public License // along with libZelda. If not, see -#include "BinaryReader.hpp" -#include "IOException.hpp" -#include "FileNotFoundException.hpp" -#include "utility.hpp" -#include "utf8.h" - -#include -#include +#include "BinaryReader.hpp" +#include "IOException.hpp" +#include "FileNotFoundException.hpp" +#include "utility.hpp" +#include "utf8.h" + +#include +#include #include -#include - -BinaryReader::BinaryReader(const Stream& stream) : - Stream(stream) -{ - Stream::setAutoResizing(false); -} - -BinaryReader::BinaryReader(const Uint8* data, Uint64 length) : - Stream(data, length) -{ - Stream::setAutoResizing(false); -} - -BinaryReader::BinaryReader(const std::string& filename) - : m_filename(filename) +#include + +BinaryReader::BinaryReader(const Stream& stream) : + Stream(stream) { - Stream::setAutoResizing(false); - FILE* in; - int length; - in = fopen(filename.c_str(), "rb"); - - if (!in) - throw FileNotFoundException(filename); - - fseek(in, 0, SEEK_END); - length = ftell(in); - fseek(in, 0, SEEK_SET); + Stream::setAutoResizing(false); +} + +BinaryReader::BinaryReader(const Uint8* data, Uint64 length) : + Stream(data, length) +{ + Stream::setAutoResizing(false); +} + +BinaryReader::BinaryReader(const std::string& filename) + : m_filename(filename) +{ + Stream::setAutoResizing(false); + FILE* in; + int length; + in = fopen(filename.c_str(), "rb"); + + if (!in) + throw FileNotFoundException(filename); + + fseek(in, 0, SEEK_END); + length = ftell(in); + fseek(in, 0, SEEK_SET); m_data = new Uint8[length]; Uint32 done = 0; @@ -68,203 +68,203 @@ BinaryReader::BinaryReader(const std::string& filename) done += blocksize; std::cout << "Read " << done << " bytes" << std::endl; - }while (done < m_length); - - fclose(in); - m_length = length; - m_position = 0; - m_bitPosition = 0; -} - -void BinaryReader::writeByte(Int8) -{ - throw IOException("BinaryReader::writeByte() -> Stream not open for writing"); -} - -void BinaryReader::writeBytes(Int8*, Int64) -{ - throw IOException("BinaryReader::writeBytes() -> Stream not open for writing"); -} - - -Int16 BinaryReader::readInt16() -{ - if (m_bitPosition > 0) - { - m_bitPosition = 0; - m_position += sizeof(Uint8); - } - - if (m_position + sizeof(Int16) > m_length) - throw IOException("BinaryReader::readInt16() -> Position outside stream bounds"); - Int16 ret = *(Int16*)(m_data + m_position); - m_position += 2; - - if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) - ret = swap16(ret); - return ret; -} - -Uint16 BinaryReader::readUInt16() -{ - if (m_bitPosition > 0) - { - m_bitPosition = 0; - m_position += sizeof(Uint8); - } - if (m_position + sizeof(Uint16) > m_length) - throw IOException("BinaryReader::readUint16() -> Position outside stream bounds"); - Uint16 ret = *(Uint16*)(m_data + m_position); - m_position += 2; - - if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) - ret = swapU16(ret); - - return ret; -} - -Int32 BinaryReader::readInt32() -{ - if (m_bitPosition > 0) - { - m_bitPosition = 0; - m_position += sizeof(Uint8); - } - if (m_position + sizeof(Int32) > m_length) - throw IOException("BinaryReader::readUint32() -> Position outside stream bounds"); - Int32 ret = *(Int32*)(m_data + m_position); - m_position += 4; - - if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) - ret = swap32(ret); - return ret; -} - -Uint32 BinaryReader::readUInt32() -{ - if (m_bitPosition > 0) - { - m_bitPosition = 0; - m_position += sizeof(Uint8); - } - if (m_position + sizeof(Uint32) > m_length) - throw IOException("BinaryReader::readUint32() -> Position outside stream bounds"); - - Uint32 ret = *(Uint32*)(m_data + m_position); - m_position += 4; - - if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) - ret = swapU32(ret); - return ret; -} - -Int64 BinaryReader::readInt64() -{ - if (m_bitPosition > 0) - { - m_bitPosition = 0; - m_position += sizeof(Uint8); - } - if (m_position + sizeof(Int64) > m_length) - throw IOException("BinaryReader::readInt64() -> Position outside stream bounds"); - - Int64 ret = *(Int64*)(m_data + m_position); - m_position += 8; - - if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) - ret = swap64(ret); - return ret; -} - -Uint64 BinaryReader::readUInt64() -{ - if (m_bitPosition > 0) - { - m_bitPosition = 0; - m_position += sizeof(Uint8); - } - if (m_position + sizeof(Uint64) > m_length) - throw IOException("BinaryReader::readUInt64() -> Position outside stream bounds"); - Uint64 ret = *(Uint64*)(m_data + m_position); - m_position += 8; - - if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) - ret = swap64(ret); - return ret; -} - -float BinaryReader::readFloat() -{ - if (m_bitPosition > 0) - { - m_bitPosition = 0; - m_position += sizeof(Uint8); - } - if (m_position + sizeof(float) > m_length) - throw IOException("BinaryReader::readFloat() -> Position outside stream bounds"); - - float ret = *(float*)(m_data + m_position); + }while (done < length); + + fclose(in); + m_length = length; + m_position = 0; + m_bitPosition = 0; +} + +void BinaryReader::writeByte(Int8) +{ + throw IOException("BinaryReader::writeByte() -> Stream not open for writing"); +} + +void BinaryReader::writeBytes(Int8*, Int64) +{ + throw IOException("BinaryReader::writeBytes() -> Stream not open for writing"); +} + + +Int16 BinaryReader::readInt16() +{ + if (m_bitPosition > 0) + { + m_bitPosition = 0; + m_position += sizeof(Uint8); + } + + if (m_position + sizeof(Int16) > m_length) + throw IOException("BinaryReader::readInt16() -> Position outside stream bounds"); + Int16 ret = *(Int16*)(m_data + m_position); + m_position += 2; + + if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) + ret = swap16(ret); + return ret; +} + +Uint16 BinaryReader::readUInt16() +{ + if (m_bitPosition > 0) + { + m_bitPosition = 0; + m_position += sizeof(Uint8); + } + if (m_position + sizeof(Uint16) > m_length) + throw IOException("BinaryReader::readUint16() -> Position outside stream bounds"); + Uint16 ret = *(Uint16*)(m_data + m_position); + m_position += 2; + + if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) + ret = swapU16(ret); + + return ret; +} + +Int32 BinaryReader::readInt32() +{ + if (m_bitPosition > 0) + { + m_bitPosition = 0; + m_position += sizeof(Uint8); + } + if (m_position + sizeof(Int32) > m_length) + throw IOException("BinaryReader::readUint32() -> Position outside stream bounds"); + Int32 ret = *(Int32*)(m_data + m_position); m_position += 4; - if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) - ret = swapFloat(ret); - return ret; -} - -double BinaryReader::readDouble() -{ - if (m_bitPosition > 0) - { - m_bitPosition = 0; - m_position += sizeof(Uint8); - } - if (m_position + sizeof(double) > m_length) - throw IOException("BinaryReader::readDouble() -> Position outside stream bounds"); - - double ret = *(double*)(m_data + m_position); - m_position += 8; - - if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) - ret = swapDouble(ret); - - return ret; -} - -bool BinaryReader::readBool() -{ - if (m_bitPosition > 0) - { - m_bitPosition = 0; - m_position += sizeof(Uint8); - } - if (m_position + sizeof(bool) > m_length) - throw IOException("BinaryReader::readBool() -> Position outside stream bounds"); - - bool ret = *(bool*)(m_data + m_position); - m_position += 1; - return ret; -} - -std::string BinaryReader::readUnicode() -{ - std::string ret; - std::vector tmp; + if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) + ret = swap32(ret); + return ret; +} + +Uint32 BinaryReader::readUInt32() +{ + if (m_bitPosition > 0) + { + m_bitPosition = 0; + m_position += sizeof(Uint8); + } + if (m_position + sizeof(Uint32) > m_length) + throw IOException("BinaryReader::readUint32() -> Position outside stream bounds"); + + Uint32 ret = *(Uint32*)(m_data + m_position); + m_position += 4; + + if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) + ret = swapU32(ret); + return ret; +} + +Int64 BinaryReader::readInt64() +{ + if (m_bitPosition > 0) + { + m_bitPosition = 0; + m_position += sizeof(Uint8); + } + if (m_position + sizeof(Int64) > m_length) + throw IOException("BinaryReader::readInt64() -> Position outside stream bounds"); + + Int64 ret = *(Int64*)(m_data + m_position); + m_position += 8; + + if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) + ret = swap64(ret); + return ret; +} + +Uint64 BinaryReader::readUInt64() +{ + if (m_bitPosition > 0) + { + m_bitPosition = 0; + m_position += sizeof(Uint8); + } + if (m_position + sizeof(Uint64) > m_length) + throw IOException("BinaryReader::readUInt64() -> Position outside stream bounds"); + Uint64 ret = *(Uint64*)(m_data + m_position); + m_position += 8; + + if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) + ret = swap64(ret); + return ret; +} + +float BinaryReader::readFloat() +{ + if (m_bitPosition > 0) + { + m_bitPosition = 0; + m_position += sizeof(Uint8); + } + if (m_position + sizeof(float) > m_length) + throw IOException("BinaryReader::readFloat() -> Position outside stream bounds"); + + float ret = *(float*)(m_data + m_position); + m_position += 4; + + if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) + ret = swapFloat(ret); + return ret; +} + +double BinaryReader::readDouble() +{ + if (m_bitPosition > 0) + { + m_bitPosition = 0; + m_position += sizeof(Uint8); + } + if (m_position + sizeof(double) > m_length) + throw IOException("BinaryReader::readDouble() -> Position outside stream bounds"); + + double ret = *(double*)(m_data + m_position); + m_position += 8; + + if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian)) + ret = swapDouble(ret); + + return ret; +} + +bool BinaryReader::readBool() +{ + if (m_bitPosition > 0) + { + m_bitPosition = 0; + m_position += sizeof(Uint8); + } + if (m_position + sizeof(bool) > m_length) + throw IOException("BinaryReader::readBool() -> Position outside stream bounds"); + + bool ret = *(bool*)(m_data + m_position); + m_position += 1; + return ret; +} + +std::string BinaryReader::readUnicode() +{ + std::string ret; + std::vector tmp; for(;;) { short chr = readUInt16(); if (chr) tmp.push_back(chr); - else - break; + else + break; }; - - utf8::utf16to8(tmp.begin(), tmp.end(), back_inserter(ret)); - return ret; -} - -bool BinaryReader::isOpenForWriting() -{ - return false; -} - + + utf8::utf16to8(tmp.begin(), tmp.end(), back_inserter(ret)); + return ret; +} + +bool BinaryReader::isOpenForWriting() +{ + return false; +} + diff --git a/src/Stream.cpp b/src/Stream.cpp index c946b7b..506b15e 100644 --- a/src/Stream.cpp +++ b/src/Stream.cpp @@ -13,296 +13,296 @@ // You should have received a copy of the GNU General Public License // along with libZelda. If not, see -#include "Stream.hpp" -#include "IOException.hpp" -#include "InvalidOperationException.hpp" -#include -#include +#include "Stream.hpp" +#include "IOException.hpp" +#include "InvalidOperationException.hpp" +#include +#include const Uint32 Stream::BLOCKSZ = 512; - -Stream::Stream() : - m_bitPosition(0), - m_position(0), - m_length(0), - m_endian(Stream::LittleEndian), - m_data(NULL), - m_autoResize(true) -{} - -Stream::Stream(const Uint8* data, Uint64 length) : - m_bitPosition(0), - m_position(0), - m_endian(Stream::LittleEndian), - m_autoResize(true) -{ - if (length <= 0) - throw InvalidOperationException("Length cannot be <= to 0"); - - m_length = length; - if (data) - m_data = (Uint8*)data; - else - { - m_data = new Uint8[m_length]; - memset(m_data, 0, m_length); - } -} - -Stream::Stream(Int64 length) : - m_bitPosition(0), - m_position(0), - m_length(length) -{ - m_data = new Uint8[m_length]; - memset(m_data, 0, m_length); -} - -Stream::Stream(Stream* stream) -{ - if (m_data) - delete[] m_data; - - m_data = stream->m_data; - m_position = stream->m_position; - m_length = stream->m_length; -} - -Stream::~Stream() -{ - if (m_data) - delete[] m_data; - - m_data = NULL; - m_position = 0; - m_length = 0; - m_endian = LittleEndian; - m_autoResize = false; -} - -void Stream::writeBit(bool val) -{ - if (m_position + sizeof(Uint8) > m_length && m_autoResize) - resize(m_position + sizeof(Uint8)); - else if (m_position > m_length) - throw IOException("Stream::writeBit() -> Position outside stream bounds"); - *(Uint8*)(m_data + m_position) |= ((Uint32)val << m_bitPosition); - m_bitPosition++; - if (m_bitPosition > 7) - { - m_bitPosition = 0; - m_position += sizeof(Uint8); - } -} - -void Stream::writeByte(Int8 byte) -{ - if (m_bitPosition > 0) - { - m_bitPosition = 0; - m_position += sizeof(Uint8); - } - if (m_position + 1 > m_length && m_autoResize) - resize(m_position + 1); - else if (m_position > m_length) - throw IOException("Stream::writeByte() -> Position outside stream bounds"); - - *(Int8*)(m_data + m_position) = byte; - m_position++; -} - -void Stream::writeBytes(Int8* data, Int64 length) -{ - if (m_bitPosition > 0) - { - m_bitPosition = 0; - m_position += sizeof(Uint8); - } - - if (!data) - throw InvalidOperationException("BinaryWriter::writeBytes() -> data cannnot be NULL"); - if (m_position + length > m_length && m_autoResize) - resize(m_position + length); - else if (m_position > m_length) - throw IOException("BinaryWriter::writeBytes() -> Position outside stream bounds"); - - - memcpy((Int8*)(m_data + m_position), data, length); - - m_position += length; -} - -bool Stream::readBit() -{ - if (m_position + sizeof(Uint8) > m_length && m_autoResize) - resize(m_position + sizeof(Uint8)); - else if (m_position > m_length) - throw IOException("BinaryWriter::WriteInt16() -> Position outside stream bounds"); +Stream::Stream() : + m_bitPosition(0), + m_position(0), + m_length(0), + m_endian(Stream::LittleEndian), + m_data(NULL), + m_autoResize(true) +{} - bool ret = (*(Uint8*)(m_data + m_position) & (1 << m_bitPosition)); - - m_bitPosition++; - if (m_bitPosition > 7) - { - m_bitPosition = 0; - m_position += sizeof(Uint8); - } - - return ret; -} - -Int8 Stream::readByte() -{ - if (m_bitPosition > 0) - { - m_bitPosition = 0; - m_position += sizeof(Uint8); - } - if (m_position + 1 > m_length) - throw IOException("Position passed stream bounds"); - - return *(Int8*)(m_data + m_position++); -} - -Int8* Stream::readBytes(Int64 length) -{ - if (m_bitPosition > 0) - { - m_bitPosition = 0; - m_position += sizeof(Uint8); - } - - if (m_position + length > m_length) - throw IOException("Position passed stream bounds: " + m_position); - - Int8* ret = new Int8[length]; - memcpy(ret, (const Int8*)(m_data + m_position), length); - m_position += length; - return ret; -} - -void Stream::seek(Int64 position, SeekOrigin origin) -{ - switch (origin) - { - case Beginning: - if ((position < 0 || (Uint32)position > m_length) && !m_autoResize) - { - std::stringstream ss; - ss << position; - throw IOException("Stream::seek() Beginnning -> Position outside stream bounds: " + ss.str()); - } - if ((Uint64)position > m_length) - this->resize(position); - m_position = position; - break; - case Current: - if (((m_position + position) < 0 || (m_position + position) > m_length) && !m_autoResize) - { - std::stringstream ss; - ss << (m_position + position); - throw IOException("Stream::seek() Current -> Position outside stream bounds: " + ss.str()); - } - else if ((m_position + position) > m_length) - this->resize(m_position + position); - - m_position += position; - break; - case End: - if (((m_length - position < 0) || (m_length - position) > m_length) && !m_autoResize) - { - std::stringstream ss; - ss << std::hex << "0x" << (m_length - position); - throw IOException("Stream::seek() End -> Position outside stream bounds " + ss.str()); - } - else if ((m_length - position) > m_length) - this->resize(m_length - position); - - m_position = m_length - position; - break; - } -} - -void Stream::resize(Uint64 newSize) -{ - if (newSize < m_length) - throw InvalidOperationException("Stream::Resize() -> New size cannot be less to the old size."); - - // Allocate and copy new buffer - Uint8* newArray = new Uint8[newSize]; - memset(newArray, 0, newSize); - - memcpy(newArray, m_data, m_length); - - // Delete the old one - delete[] m_data; - - // Swap the pointer and size out for the new ones. - m_data = newArray; - m_length = newSize; -} - -void Stream::setData(const Uint8* data, Uint64 length) -{ - if (m_data) - delete[] m_data; - - m_data = (Uint8*)data; - m_length = length; - m_position = 0; -} - -Uint8* Stream::data() const -{ - Uint8* ret = new Uint8[m_length]; - memset(ret, 0, m_length); - memcpy(ret, m_data, m_length); - return ret; -} - -Int64 Stream::length() -{ - return m_length; -} - -Int64 Stream::position() -{ - return m_position; -} - -bool Stream::atEnd() -{ - return m_position >= m_length; -} - -void Stream::setAutoResizing(bool val) -{ - m_autoResize = val; -} - -bool Stream::autoResizing() const -{ - return m_autoResize; -} - -bool Stream::isOpenForReading() const -{ - return true; -} - -bool Stream::isOpenForWriting() const -{ - return true; -} - -void Stream::setEndianess(Endian endian) -{ - m_endian = endian; -} - -Stream::Endian Stream::endianness() const -{ - return m_endian; -} +Stream::Stream(const Uint8* data, Uint64 length) : + m_bitPosition(0), + m_position(0), + m_endian(Stream::LittleEndian), + m_autoResize(true) +{ + if (length <= 0) + throw InvalidOperationException("Length cannot be <= to 0"); + + m_length = length; + if (data) + m_data = (Uint8*)data; + else + { + m_data = new Uint8[m_length]; + memset(m_data, 0, m_length); + } +} + +Stream::Stream(Int64 length) : + m_bitPosition(0), + m_position(0), + m_length(length) +{ + m_data = new Uint8[m_length]; + memset(m_data, 0, m_length); +} + +Stream::Stream(Stream* stream) +{ + if (m_data) + delete[] m_data; + + m_data = stream->m_data; + m_position = stream->m_position; + m_length = stream->m_length; +} + +Stream::~Stream() +{ + if (m_data) + delete[] m_data; + + m_data = NULL; + m_position = 0; + m_length = 0; + m_endian = LittleEndian; + m_autoResize = false; +} + +void Stream::writeBit(bool val) +{ + if (m_position + sizeof(Uint8) > m_length && m_autoResize) + resize(m_position + sizeof(Uint8)); + else if (m_position > m_length) + throw IOException("Stream::writeBit() -> Position outside stream bounds"); + + *(Uint8*)(m_data + m_position) |= ((Uint32)val << m_bitPosition); + m_bitPosition++; + if (m_bitPosition > 7) + { + m_bitPosition = 0; + m_position += sizeof(Uint8); + } +} + +void Stream::writeByte(Int8 byte) +{ + if (m_bitPosition > 0) + { + m_bitPosition = 0; + m_position += sizeof(Uint8); + } + if (m_position + 1 > m_length && m_autoResize) + resize(m_position + 1); + else if (m_position > m_length) + throw IOException("Stream::writeByte() -> Position outside stream bounds"); + + *(Int8*)(m_data + m_position) = byte; + m_position++; +} + +void Stream::writeBytes(Int8* data, Int64 length) +{ + if (m_bitPosition > 0) + { + m_bitPosition = 0; + m_position += sizeof(Uint8); + } + + if (!data) + throw InvalidOperationException("BinaryWriter::writeBytes() -> data cannnot be NULL"); + if (m_position + length > m_length && m_autoResize) + resize(m_position + length); + else if (m_position > m_length) + throw IOException("BinaryWriter::writeBytes() -> Position outside stream bounds"); + + + memcpy((Int8*)(m_data + m_position), data, length); + + m_position += length; +} + +bool Stream::readBit() +{ + if (m_position + sizeof(Uint8) > m_length && m_autoResize) + resize(m_position + sizeof(Uint8)); + else if (m_position > m_length) + throw IOException("BinaryWriter::WriteInt16() -> Position outside stream bounds"); + + bool ret = (*(Uint8*)(m_data + m_position) & (1 << m_bitPosition)); + + m_bitPosition++; + if (m_bitPosition > 7) + { + m_bitPosition = 0; + m_position += sizeof(Uint8); + } + + return ret; +} + +Int8 Stream::readByte() +{ + if (m_bitPosition > 0) + { + m_bitPosition = 0; + m_position += sizeof(Uint8); + } + if (m_position + 1 > m_length) + throw IOException("Position passed stream bounds"); + + return *(Int8*)(m_data + m_position++); +} + +Int8* Stream::readBytes(Int64 length) +{ + if (m_bitPosition > 0) + { + m_bitPosition = 0; + m_position += sizeof(Uint8); + } + + if (m_position + length > m_length) + throw IOException("Position passed stream bounds: " + m_position); + + Int8* ret = new Int8[length]; + memcpy(ret, (const Int8*)(m_data + m_position), length); + m_position += length; + return ret; +} + +void Stream::seek(Int64 position, SeekOrigin origin) +{ + switch (origin) + { + case Beginning: + if ((position < 0 || (Int64)position > (Int64)m_length) && !m_autoResize) + { + std::stringstream ss; + ss << position; + throw IOException("Stream::seek() Beginnning -> Position outside stream bounds: " + ss.str()); + } + if ((Uint64)position > m_length) + this->resize(position); + m_position = position; + break; + case Current: + if ((((Int64)m_position + position) < 0 || (m_position + position) > m_length) && !m_autoResize) + { + std::stringstream ss; + ss << (m_position + position); + throw IOException("Stream::seek() Current -> Position outside stream bounds: " + ss.str()); + } + else if ((m_position + position) > m_length) + this->resize(m_position + position); + + m_position += position; + break; + case End: + if ((((Int64)m_length - position < 0) || (m_length - position) > m_length) && !m_autoResize) + { + std::stringstream ss; + ss << std::hex << "0x" << (m_length - position); + throw IOException("Stream::seek() End -> Position outside stream bounds " + ss.str()); + } + else if ((m_length - position) > m_length) + this->resize(m_length - position); + + m_position = m_length - position; + break; + } +} + +void Stream::resize(Uint64 newSize) +{ + if (newSize < m_length) + throw InvalidOperationException("Stream::Resize() -> New size cannot be less to the old size."); + + // Allocate and copy new buffer + Uint8* newArray = new Uint8[newSize]; + memset(newArray, 0, newSize); + + memcpy(newArray, m_data, m_length); + + // Delete the old one + delete[] m_data; + + // Swap the pointer and size out for the new ones. + m_data = newArray; + m_length = newSize; +} + +void Stream::setData(const Uint8* data, Uint64 length) +{ + if (m_data) + delete[] m_data; + + m_data = (Uint8*)data; + m_length = length; + m_position = 0; +} + +Uint8* Stream::data() const +{ + Uint8* ret = new Uint8[m_length]; + memset(ret, 0, m_length); + memcpy(ret, m_data, m_length); + return ret; +} + +Int64 Stream::length() +{ + return m_length; +} + +Int64 Stream::position() +{ + return m_position; +} + +bool Stream::atEnd() +{ + return m_position >= m_length; +} + +void Stream::setAutoResizing(bool val) +{ + m_autoResize = val; +} + +bool Stream::autoResizing() const +{ + return m_autoResize; +} + +bool Stream::isOpenForReading() const +{ + return true; +} + +bool Stream::isOpenForWriting() const +{ + return true; +} + +void Stream::setEndianess(Endian endian) +{ + m_endian = endian; +} + +Stream::Endian Stream::endianness() const +{ + return m_endian; +}