mirror of https://github.com/libAthena/athena.git
* Fix bug in BinaryReader where it wasn't correctly reading in all the data
This commit is contained in:
parent
8adb9c0e98
commit
1e2065b352
|
@ -12,11 +12,11 @@
|
|||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
|
||||
#ifndef __BINARYREADER_HPP__
|
||||
#define __BINARYREADER_HPP__
|
||||
|
||||
#include "Stream.hpp"
|
||||
#include <string>
|
||||
#ifndef __BINARYREADER_HPP__
|
||||
#define __BINARYREADER_HPP__
|
||||
|
||||
#include "Stream.hpp"
|
||||
#include <string>
|
||||
|
||||
/*! \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
|
||||
|
|
|
@ -13,36 +13,37 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
#ifndef __EXCEPTION_HPP__
|
||||
#define __EXCEPTION_HPP__
|
||||
|
||||
#include <string>
|
||||
#ifndef __EXCEPTION_HPP__
|
||||
#define __EXCEPTION_HPP__
|
||||
|
||||
#include <string>
|
||||
|
||||
/*! \class Exception
|
||||
* \brief The baseclass for all Exceptions.
|
||||
*
|
||||
* <b>Do Not</b> 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
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
#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 @@
|
|||
* <br />
|
||||
* It is <b>NOT</b> appropriate to use <b>throw new</b> 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
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
#ifndef __INVALID_OPERATION_EXCEPTION_HPP__
|
||||
#define __INVALID_OPERATION_EXCEPTION_HPP__
|
||||
|
||||
#include <string>
|
||||
#include <Exception.hpp>
|
||||
#ifndef __INVALID_OPERATION_EXCEPTION_HPP__
|
||||
#define __INVALID_OPERATION_EXCEPTION_HPP__
|
||||
|
||||
#include <string>
|
||||
#include <Exception.hpp>
|
||||
|
||||
/*! \class InvalidOperationException
|
||||
* \brief An excpeption thrown on Invalid Operations calls.
|
||||
|
@ -27,16 +27,16 @@
|
|||
* <br />
|
||||
* It is <b>NOT</b> appropriate to use <b>throw new</b> 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__
|
||||
|
|
|
@ -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: <a href="http://animewaterfall.deviantart.com/art/Chibi-Zelda-331611090">AnimeWaterFall</a> on Deviantart
|
||||
*/
|
||||
#endif // __MAINPAGE_HPP__
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
|
||||
#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 @@
|
|||
* <br />
|
||||
* Stream can also be used by itself though it's not advised as it's not feature filled.<br />
|
||||
* 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.<br />
|
||||
|
@ -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.<br />
|
||||
* 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.<br />
|
||||
* <b>BEWARE:</b> 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__
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -28,3 +28,6 @@ SOURCES += \
|
|||
src/BinaryWriter.cpp \
|
||||
src/BinaryReader.cpp
|
||||
|
||||
system("exec doxygen libzelda.conf")
|
||||
system("cd doc/latex && make")
|
||||
system("cd ../../")
|
||||
|
|
|
@ -13,43 +13,43 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
#include "BinaryReader.hpp"
|
||||
#include "IOException.hpp"
|
||||
#include "FileNotFoundException.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "utf8.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "BinaryReader.hpp"
|
||||
#include "IOException.hpp"
|
||||
#include "FileNotFoundException.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "utf8.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
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 <iostream>
|
||||
|
||||
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<short> 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<short> 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;
|
||||
}
|
||||
|
||||
|
|
576
src/Stream.cpp
576
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 <http://www.gnu.org/licenses/>
|
||||
|
||||
#include "Stream.hpp"
|
||||
#include "IOException.hpp"
|
||||
#include "InvalidOperationException.hpp"
|
||||
#include <string.h>
|
||||
#include <sstream>
|
||||
#include "Stream.hpp"
|
||||
#include "IOException.hpp"
|
||||
#include "InvalidOperationException.hpp"
|
||||
#include <string.h>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue