2013-01-27 01:19:49 +00:00
|
|
|
// This file is part of libZelda.
|
|
|
|
//
|
|
|
|
// libZelda is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// libZelda is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with libZelda. If not, see <http://www.gnu.org/licenses/>
|
2013-01-29 21:46:05 +00:00
|
|
|
#ifndef __STREAM_HPP__
|
|
|
|
#define __STREAM_HPP__
|
|
|
|
|
|
|
|
#include "Types.hpp"
|
2013-01-26 20:19:24 +00:00
|
|
|
|
|
|
|
/*! \class Stream
|
|
|
|
* \brief Stream is the main class all streams inherit from
|
|
|
|
*
|
|
|
|
* The Stream class contains the memory buffer, buffer size, and current position.<br />
|
|
|
|
* It provides basic functionality such as reading or writing bits and bytes
|
|
|
|
* The user has the ability to specify the Endianness of the Stream as well
|
|
|
|
* And all inheriting classes are required to take that into account to be accepted
|
|
|
|
* as a valid stream. <br />
|
|
|
|
* <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.
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
|
|
|
class Stream
|
|
|
|
{
|
2013-01-26 20:19:24 +00:00
|
|
|
public:
|
2013-01-29 21:46:05 +00:00
|
|
|
//! \brief Default buffer block size.
|
2013-01-27 00:13:19 +00:00
|
|
|
static const Uint32 BLOCKSZ;
|
2013-01-26 20:19:24 +00:00
|
|
|
|
|
|
|
/*! \enum Endian
|
|
|
|
* \brief Allows the user to specify the Endianness of the stream buffer.<br />
|
|
|
|
* The proper actions are automatically taken depending on platform and
|
|
|
|
* buffer settings
|
|
|
|
*/
|
|
|
|
enum Endian
|
|
|
|
{
|
|
|
|
LittleEndian, //!< Specifies that the Stream is Little Endian (LSB)
|
|
|
|
BigEndian //!< Specifies that the Stream is Big Endian (MSB)
|
|
|
|
};
|
|
|
|
|
|
|
|
/*! \enum SeekOrigin
|
|
|
|
* \brief Specifies how to seek in a stream.
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-26 20:19:24 +00:00
|
|
|
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.
|
2013-01-29 21:46:05 +00:00
|
|
|
};
|
2013-01-26 20:19:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*! \brief The default constructor
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-26 20:19:24 +00:00
|
|
|
Stream();
|
|
|
|
/*! \brief This constructor takes an existing buffer to read from.
|
|
|
|
*
|
2013-01-27 00:13:19 +00:00
|
|
|
* \param bytes The existing buffer
|
2013-01-26 20:19:24 +00:00
|
|
|
* \param length The length of the existing buffer
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-26 20:19:24 +00:00
|
|
|
Stream(const Uint8* bytes, Uint64 length);
|
|
|
|
/*! \brief This constructor creates a buffer from the given length.
|
|
|
|
*
|
|
|
|
* \param length The length of the existing buffer
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-26 20:19:24 +00:00
|
|
|
Stream(Int64 length);
|
|
|
|
/*! \brief This constructor takes an existing Stream to read from.
|
|
|
|
*
|
|
|
|
* \param stream The stream to read data from
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-27 01:19:49 +00:00
|
|
|
Stream(Stream* stream);
|
|
|
|
|
|
|
|
/*! \brief The destructor cleans up memory and sets everything back
|
|
|
|
* to the default settings.
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
|
|
|
virtual ~Stream();
|
2013-01-26 20:19:24 +00:00
|
|
|
|
|
|
|
/*! \brief Writes a bit at the current position and advances the position by one bit.
|
|
|
|
* \param val the value to write
|
|
|
|
* \throw IOException
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-26 20:19:24 +00:00
|
|
|
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
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-26 20:19:24 +00:00
|
|
|
virtual void writeByte(Int8 byte);
|
|
|
|
|
|
|
|
/*! \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
|
|
|
|
* \throw IOException
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-26 20:19:24 +00:00
|
|
|
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
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-26 20:19:24 +00:00
|
|
|
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
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-26 20:19:24 +00:00
|
|
|
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
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-26 20:19:24 +00:00
|
|
|
virtual Int8* readBytes(Int64 length);
|
|
|
|
|
|
|
|
/*! \brief Sets the buffers position relative to the specified position.<br />
|
|
|
|
* 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
|
|
|
|
* \throw IOException
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-26 20:19:24 +00:00
|
|
|
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
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
|
|
|
void resize(Uint64 newSize);
|
2013-01-26 20:19:24 +00:00
|
|
|
|
|
|
|
/*! \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
|
2013-01-27 00:13:19 +00:00
|
|
|
* if that was not the intent.<br />
|
|
|
|
* Once you pass the data to setData <b>DO NOT</b> delete the buffer
|
|
|
|
* as Stream now owns the address, this is done to keep memory usage down.
|
2013-01-26 20:19:24 +00:00
|
|
|
* \param data The new buffer.
|
|
|
|
* \param length The length of the new buffer.
|
|
|
|
* \throw IOException
|
|
|
|
*/
|
|
|
|
void setData(const Uint8* data, Uint64 length);
|
|
|
|
|
|
|
|
|
|
|
|
/*! \brief Returns a copy of the current buffer.<br />
|
|
|
|
* 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.<br />
|
|
|
|
* However once you pass the data to setData <b>DO NOT</b> delete the buffer
|
|
|
|
* as Stream now owns the address, this is done to keep memory usage down.
|
2013-01-27 00:13:19 +00:00
|
|
|
* \return Uint8* The copy of the buffer.
|
2013-01-26 20:19:24 +00:00
|
|
|
*/
|
|
|
|
Uint8* data() const;
|
|
|
|
|
2013-01-27 00:13:19 +00:00
|
|
|
/*! \brief Returns the length of the Stream.
|
|
|
|
*
|
|
|
|
* \return Int64 The length of the stream.
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-27 00:13:19 +00:00
|
|
|
Int64 length();
|
|
|
|
|
|
|
|
/*! \brief Returns the current position in the stream.
|
|
|
|
*
|
|
|
|
* \return Int64 The current position in the stream.
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-27 00:13:19 +00:00
|
|
|
Int64 position();
|
|
|
|
|
|
|
|
/*! \brief Returns whether or not the stream is at the end.
|
|
|
|
*
|
|
|
|
* \return bool True if at end; False otherwise.
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-27 00:13:19 +00:00
|
|
|
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.
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-27 00:13:19 +00:00
|
|
|
void setAutoResizing(bool val);
|
|
|
|
|
|
|
|
/*! \brief Retuns whether or not the Stream currenty autoresizes.
|
|
|
|
*
|
|
|
|
* \return True for resizing; False otherwise.
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
|
|
|
bool autoResizing() const;
|
2013-01-27 00:13:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*! \brief Retuns whether or not the Stream is open for reading.
|
|
|
|
*
|
|
|
|
* \return True if open for reading; False otherwise.
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-27 20:28:59 +00:00
|
|
|
virtual bool isOpenForReading() const;
|
2013-01-27 00:13:19 +00:00
|
|
|
|
|
|
|
/*! \brief Retuns whether or not the Stream is open for writing
|
|
|
|
*
|
|
|
|
* \return True if open for writing; False otherwise.
|
2013-01-29 21:46:05 +00:00
|
|
|
*/
|
2013-01-27 20:28:59 +00:00
|
|
|
virtual bool isOpenForWriting() const;
|
2013-01-26 20:19:24 +00:00
|
|
|
|
2013-01-27 00:13:19 +00:00
|
|
|
/*! \brief Sets the Endianss of the stream
|
|
|
|
*
|
|
|
|
* \param endian The Endianess to set \sa Endian
|
|
|
|
*/
|
2013-01-26 20:19:24 +00:00
|
|
|
void setEndianess(Endian endian);
|
2013-01-27 00:13:19 +00:00
|
|
|
|
|
|
|
/*! \brief Returns the current Endianness of the stream
|
|
|
|
*
|
|
|
|
* \return Endian The current Stream Endianess
|
|
|
|
*/
|
2013-01-26 20:19:24 +00:00
|
|
|
Endian endianness() const;
|
2013-01-27 00:13:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*! \brief Returns whether the stream is BigEndian
|
|
|
|
*
|
|
|
|
* \return bool True for BigEndian; False for LittleEndian
|
|
|
|
*/
|
2013-01-26 20:19:24 +00:00
|
|
|
bool isBigEndian() const;
|
2013-01-27 00:13:19 +00:00
|
|
|
|
|
|
|
/*! \brief Returns whether the stream is LittleEndian
|
|
|
|
*
|
|
|
|
* \return bool True for LittleEndian; False for BigEndian
|
|
|
|
*/
|
|
|
|
bool isLittleEndian() const;
|
2013-01-29 21:46:05 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
Uint32 m_bitPosition; //!< The current position in the current byte
|
|
|
|
Uint64 m_position; //!< The current position in the Stream
|
2013-01-27 00:13:19 +00:00
|
|
|
Uint64 m_length; //!< The length of the Stream
|
2013-01-29 21:46:05 +00:00
|
|
|
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__
|