mirror of https://github.com/libAthena/athena.git
First Commit
This commit is contained in:
commit
ad0505a501
|
@ -0,0 +1,3 @@
|
||||||
|
libZelda provides several basic classes that can be used to read from
|
||||||
|
and write to files, and memory, classes such as Stream, BinaryReader,
|
||||||
|
BinaryWriter, and the currently work in progress TextStream.
|
|
@ -0,0 +1,146 @@
|
||||||
|
#ifndef __BINARYREADER_HPP__
|
||||||
|
#define __BINARYREADER_HPP__
|
||||||
|
|
||||||
|
#include "Stream.hpp"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
/*! \class BinaryReader
|
||||||
|
*
|
||||||
|
* A Class for reading binary data from a file or memory stream,
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*! \brief This constructor takes an existing buffer to read from.
|
||||||
|
*
|
||||||
|
* \param data The existing buffer
|
||||||
|
* \param length The length of the existing buffer
|
||||||
|
*/
|
||||||
|
BinaryReader(const Uint8* data, Uint64 length);
|
||||||
|
/*! \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);
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Reads a Int16 and swaps to proper endianness depending on platform
|
||||||
|
* and Stream settings, and advances the current position
|
||||||
|
*
|
||||||
|
* \sa Endian
|
||||||
|
*
|
||||||
|
* \return Int16 The value at the current address
|
||||||
|
* \throw IOException when address is out of range
|
||||||
|
*/
|
||||||
|
Int16 readInt16();
|
||||||
|
|
||||||
|
/*! \brief Reads a Uint16 and swaps to proper endianness depending on platform
|
||||||
|
* and Stream settings, and advances the current position
|
||||||
|
*
|
||||||
|
* \sa Endian
|
||||||
|
*
|
||||||
|
* \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
|
||||||
|
* and Stream settings, and advances the current position
|
||||||
|
*
|
||||||
|
* \sa Endian
|
||||||
|
*
|
||||||
|
* \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
|
||||||
|
* and Stream settings, and advances the current position
|
||||||
|
*
|
||||||
|
* \sa Endian
|
||||||
|
*
|
||||||
|
* \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
|
||||||
|
* and Stream settings, and advances the current position
|
||||||
|
*
|
||||||
|
* \sa Endian
|
||||||
|
*
|
||||||
|
* \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
|
||||||
|
* and Stream settings, and advances the current position
|
||||||
|
*
|
||||||
|
* \sa Endian
|
||||||
|
*
|
||||||
|
* \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
|
||||||
|
* and Stream settings, and advances the current position
|
||||||
|
*
|
||||||
|
* \sa Endian
|
||||||
|
*
|
||||||
|
* \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
|
||||||
|
* and Stream settings, and advances the current position
|
||||||
|
*
|
||||||
|
* \sa Endian
|
||||||
|
*
|
||||||
|
* \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:
|
||||||
|
/*! \brief Overload of isOpenForWriting in Stream
|
||||||
|
*
|
||||||
|
* \return false
|
||||||
|
*/
|
||||||
|
bool isOpenForWriting();
|
||||||
|
/*! \brief Overload of writeByte in Stream
|
||||||
|
*
|
||||||
|
* \throw IOException
|
||||||
|
*/
|
||||||
|
void writeByte(Int8 byte);
|
||||||
|
/*! \brief Overload of writeBytes in Stream
|
||||||
|
*
|
||||||
|
* \throw IOException
|
||||||
|
*/
|
||||||
|
void writeBytes(Int8*, Int64);
|
||||||
|
std::string m_filename;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef __BINARYWRITER_HPP__
|
||||||
|
#define __BINARYWRITER_HPP__
|
||||||
|
|
||||||
|
#include "Stream.hpp"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class BinaryWriter : public Stream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BinaryWriter(const Uint8* data, Uint64 length);
|
||||||
|
BinaryWriter(const Stream& stream);
|
||||||
|
BinaryWriter(const std::string& filename);
|
||||||
|
void save(const std::string& filename="");
|
||||||
|
|
||||||
|
void writeInt16(Int16);
|
||||||
|
void writeUInt16(Uint16);
|
||||||
|
void writeInt32(Int32);
|
||||||
|
void writeUInt32(Uint32);
|
||||||
|
void writeInt64(Int64);
|
||||||
|
void writeUInt64(Uint64);
|
||||||
|
void writeFloat(float);
|
||||||
|
void writeDouble(double);
|
||||||
|
void writeBool(bool);
|
||||||
|
void writeUnicode(const std::string& str);
|
||||||
|
private:
|
||||||
|
Int8 readByte();
|
||||||
|
Int8* readBytes(Int64);
|
||||||
|
bool isOpenForReading();
|
||||||
|
std::string m_filename;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef __EXCEPTION_HPP__
|
||||||
|
#define __EXCEPTION_HPP__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Exception(const std::string& message) :
|
||||||
|
m_message(message)
|
||||||
|
{};
|
||||||
|
|
||||||
|
std::string message() const
|
||||||
|
{
|
||||||
|
return m_message;
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
std::string m_message;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef __FILENOTFOUNDEXCEPTION_HPP__
|
||||||
|
#define __FILENOTFOUNDEXCEPTION_HPP__
|
||||||
|
|
||||||
|
#include "Exception.hpp"
|
||||||
|
|
||||||
|
class FileNotFoundException : public Exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileNotFoundException(const std::string& filename) :
|
||||||
|
Exception("FileNotFoundException:\nCouldn't not find \"" + filename + "\", please check that it exists."),
|
||||||
|
m_filename(filename)
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string filename() const { return m_filename; }
|
||||||
|
private:
|
||||||
|
std::string m_filename;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef __FILESTREAM_HPP__
|
||||||
|
#define __FILESTREAM_HPP__
|
||||||
|
|
||||||
|
#include "Stream.hpp"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class FileStream : public Stream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum FileMode { Open, Create, OpenOrCreate = Open|Create, Truncate, Append };
|
||||||
|
enum AccessMode { ReadOnly, WriteOnly, ReadWrite };
|
||||||
|
FileStream(const std::string& filename, FileMode fileMode, AccessMode accessMode);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_filename;
|
||||||
|
FileMode m_filemode;
|
||||||
|
AccessMode m_accessmode;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef __IOEXCEPTION_HPP__
|
||||||
|
#define __IOEXCEPTION_HPP__
|
||||||
|
|
||||||
|
#include "Exception.hpp"
|
||||||
|
|
||||||
|
class IOException : public Exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IOException(const std::string& message) :
|
||||||
|
Exception("IOException: " + message)
|
||||||
|
{};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef __INVALID_OPERATION_EXCEPTION_HPP__
|
||||||
|
#define __INVALID_OPERATION_EXCEPTION_HPP__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <Exception.hpp>
|
||||||
|
|
||||||
|
class InvalidOperationException : public Exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InvalidOperationException(const std::string& error)
|
||||||
|
: Exception("InvalidOperationException:\n" + error)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif // __INVALID_OPERATION_EXCEPTION_HPP__
|
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef __MAINPAGE_HPP__
|
||||||
|
#define __MAINPAGE_HPP__
|
||||||
|
|
||||||
|
/*! \mainpage libZelda
|
||||||
|
* \section intro_sec Introduction to libZelda
|
||||||
|
* libZelda is an IO Library which is designed to be powerful, simple,
|
||||||
|
* and infinitely extensible. <br />
|
||||||
|
* <br />
|
||||||
|
* libZelda provides several basic classes that can be used to read from
|
||||||
|
* and write to files, and memory, classes such as Stream, BinaryReader, BinaryWriter,
|
||||||
|
* and the currently work in progress TextStream.
|
||||||
|
* \section example_sec BinaryWriter example
|
||||||
|
* \code
|
||||||
|
* #include "BinaryWriter.hpp"
|
||||||
|
* #include "FileNotFoundException.hpp"
|
||||||
|
* #include "Exception.hpp"
|
||||||
|
* int main()
|
||||||
|
* {
|
||||||
|
* try
|
||||||
|
* {
|
||||||
|
* BinaryWriter writer("test.bin");
|
||||||
|
* writer.writeByte('t');
|
||||||
|
* writer.writeInt32(123454321);
|
||||||
|
* writer.save();
|
||||||
|
* }
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
#endif // __MAINPAGE_HPP__
|
|
@ -0,0 +1,163 @@
|
||||||
|
#ifndef __STREAM_HPP__
|
||||||
|
#define __STREAM_HPP__
|
||||||
|
|
||||||
|
#include "Types.hpp"
|
||||||
|
|
||||||
|
/*! \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.
|
||||||
|
*/
|
||||||
|
class Stream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/*! \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.
|
||||||
|
*/
|
||||||
|
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 data 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);
|
||||||
|
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
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
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 />
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
|
/*! \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
|
||||||
|
* if that was not the intent.
|
||||||
|
* \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.
|
||||||
|
* \return Uint8* The copy of the buffer
|
||||||
|
*/
|
||||||
|
Uint8* data() const;
|
||||||
|
|
||||||
|
/*! \brief Returns the length of the Stream.
|
||||||
|
Int64 length();
|
||||||
|
Int64 position();
|
||||||
|
bool atEnd();
|
||||||
|
void setAutoResizing(bool val);
|
||||||
|
bool autoResizing() const;
|
||||||
|
|
||||||
|
virtual bool isOpenForReading();
|
||||||
|
virtual bool isOpenForWriting();
|
||||||
|
|
||||||
|
void setEndianess(Endian endian);
|
||||||
|
Endian endianness() const;
|
||||||
|
bool isBigEndian() const;
|
||||||
|
bool isLittleEndian() const;
|
||||||
|
protected:
|
||||||
|
Uint32 m_bitPosition;
|
||||||
|
Uint64 m_position;
|
||||||
|
Uint64 m_length;
|
||||||
|
Endian m_endian;
|
||||||
|
Uint8* m_data;
|
||||||
|
bool m_autoResize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __STREAM_HPP__
|
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef __TYPES_HPP__
|
||||||
|
#define __TYPES_HPP__
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
// 8 bits integer types
|
||||||
|
#if UCHAR_MAX == 0xFF
|
||||||
|
typedef signed char Int8;
|
||||||
|
typedef unsigned char Uint8;
|
||||||
|
#else
|
||||||
|
#error No 8 bits integer type for this platform
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 16 bits integer types
|
||||||
|
#if USHRT_MAX == 0xFFFF
|
||||||
|
typedef signed short Int16;
|
||||||
|
typedef unsigned short Uint16;
|
||||||
|
#elif UINT_MAX == 0xFFFF
|
||||||
|
typedef signed int Int16;
|
||||||
|
typedef unsigned int Uint16;
|
||||||
|
#elif ULONG_MAX == 0xFFFF
|
||||||
|
typedef signed long Int16;
|
||||||
|
typedef unsigned long Uint16;
|
||||||
|
#else
|
||||||
|
#error No 16 bits integer type for this platform
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 32 bits integer types
|
||||||
|
#if USHRT_MAX == 0xFFFFFFFF
|
||||||
|
typedef signed short Int32;
|
||||||
|
typedef unsigned short Uint32;
|
||||||
|
#elif UINT_MAX == 0xFFFFFFFF
|
||||||
|
typedef signed int Int32;
|
||||||
|
typedef unsigned int Uint32;
|
||||||
|
#elif ULONG_MAX == 0xFFFFFFFF
|
||||||
|
typedef signed long Int32;
|
||||||
|
typedef unsigned long Uint32;
|
||||||
|
#else
|
||||||
|
#error No 32 bits integer type for this platform
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef signed long long Int64;
|
||||||
|
typedef unsigned long long Uint64;
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,34 @@
|
||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include "utf8/checked.h"
|
||||||
|
#include "utf8/unchecked.h"
|
||||||
|
|
||||||
|
#endif // header guard
|
|
@ -0,0 +1,327 @@
|
||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace utf8
|
||||||
|
{
|
||||||
|
// Base for the exceptions that may be thrown from the library
|
||||||
|
class exception : public ::std::exception {
|
||||||
|
};
|
||||||
|
|
||||||
|
// Exceptions that may be thrown from the library functions.
|
||||||
|
class invalid_code_point : public exception {
|
||||||
|
uint32_t cp;
|
||||||
|
public:
|
||||||
|
invalid_code_point(uint32_t cp) : cp(cp) {}
|
||||||
|
virtual const char* what() const throw() { return "Invalid code point"; }
|
||||||
|
uint32_t code_point() const {return cp;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class invalid_utf8 : public exception {
|
||||||
|
uint8_t u8;
|
||||||
|
public:
|
||||||
|
invalid_utf8 (uint8_t u) : u8(u) {}
|
||||||
|
virtual const char* what() const throw() { return "Invalid UTF-8"; }
|
||||||
|
uint8_t utf8_octet() const {return u8;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class invalid_utf16 : public exception {
|
||||||
|
uint16_t u16;
|
||||||
|
public:
|
||||||
|
invalid_utf16 (uint16_t u) : u16(u) {}
|
||||||
|
virtual const char* what() const throw() { return "Invalid UTF-16"; }
|
||||||
|
uint16_t utf16_word() const {return u16;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class not_enough_room : public exception {
|
||||||
|
public:
|
||||||
|
virtual const char* what() const throw() { return "Not enough space"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The library API - functions intended to be called by the users
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
octet_iterator append(uint32_t cp, octet_iterator result)
|
||||||
|
{
|
||||||
|
if (!utf8::internal::is_code_point_valid(cp))
|
||||||
|
throw invalid_code_point(cp);
|
||||||
|
|
||||||
|
if (cp < 0x80) // one octet
|
||||||
|
*(result++) = static_cast<uint8_t>(cp);
|
||||||
|
else if (cp < 0x800) { // two octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else if (cp < 0x10000) { // three octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else { // four octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename output_iterator>
|
||||||
|
output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
octet_iterator sequence_start = start;
|
||||||
|
internal::utf_error err_code = utf8::internal::validate_next(start, end);
|
||||||
|
switch (err_code) {
|
||||||
|
case internal::UTF8_OK :
|
||||||
|
for (octet_iterator it = sequence_start; it != start; ++it)
|
||||||
|
*out++ = *it;
|
||||||
|
break;
|
||||||
|
case internal::NOT_ENOUGH_ROOM:
|
||||||
|
throw not_enough_room();
|
||||||
|
case internal::INVALID_LEAD:
|
||||||
|
utf8::append (replacement, out);
|
||||||
|
++start;
|
||||||
|
break;
|
||||||
|
case internal::INCOMPLETE_SEQUENCE:
|
||||||
|
case internal::OVERLONG_SEQUENCE:
|
||||||
|
case internal::INVALID_CODE_POINT:
|
||||||
|
utf8::append (replacement, out);
|
||||||
|
++start;
|
||||||
|
// just one replacement mark for the sequence
|
||||||
|
while (start != end && utf8::internal::is_trail(*start))
|
||||||
|
++start;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename output_iterator>
|
||||||
|
inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
|
||||||
|
{
|
||||||
|
static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
|
||||||
|
return utf8::replace_invalid(start, end, out, replacement_marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t next(octet_iterator& it, octet_iterator end)
|
||||||
|
{
|
||||||
|
uint32_t cp = 0;
|
||||||
|
internal::utf_error err_code = utf8::internal::validate_next(it, end, cp);
|
||||||
|
switch (err_code) {
|
||||||
|
case internal::UTF8_OK :
|
||||||
|
break;
|
||||||
|
case internal::NOT_ENOUGH_ROOM :
|
||||||
|
throw not_enough_room();
|
||||||
|
case internal::INVALID_LEAD :
|
||||||
|
case internal::INCOMPLETE_SEQUENCE :
|
||||||
|
case internal::OVERLONG_SEQUENCE :
|
||||||
|
throw invalid_utf8(*it);
|
||||||
|
case internal::INVALID_CODE_POINT :
|
||||||
|
throw invalid_code_point(cp);
|
||||||
|
}
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t peek_next(octet_iterator it, octet_iterator end)
|
||||||
|
{
|
||||||
|
return utf8::next(it, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t prior(octet_iterator& it, octet_iterator start)
|
||||||
|
{
|
||||||
|
// can't do much if it == start
|
||||||
|
if (it == start)
|
||||||
|
throw not_enough_room();
|
||||||
|
|
||||||
|
octet_iterator end = it;
|
||||||
|
// Go back until we hit either a lead octet or start
|
||||||
|
while (utf8::internal::is_trail(*(--it)))
|
||||||
|
if (it == start)
|
||||||
|
throw invalid_utf8(*it); // error - no lead byte in the sequence
|
||||||
|
return utf8::peek_next(it, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deprecated in versions that include "prior"
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t previous(octet_iterator& it, octet_iterator pass_start)
|
||||||
|
{
|
||||||
|
octet_iterator end = it;
|
||||||
|
while (utf8::internal::is_trail(*(--it)))
|
||||||
|
if (it == pass_start)
|
||||||
|
throw invalid_utf8(*it); // error - no lead byte in the sequence
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return utf8::next(temp, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename distance_type>
|
||||||
|
void advance (octet_iterator& it, distance_type n, octet_iterator end)
|
||||||
|
{
|
||||||
|
for (distance_type i = 0; i < n; ++i)
|
||||||
|
utf8::next(it, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type
|
||||||
|
distance (octet_iterator first, octet_iterator last)
|
||||||
|
{
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type dist;
|
||||||
|
for (dist = 0; first < last; ++dist)
|
||||||
|
utf8::next(first, last);
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
uint32_t cp = utf8::internal::mask16(*start++);
|
||||||
|
// Take care of surrogate pairs first
|
||||||
|
if (utf8::internal::is_lead_surrogate(cp)) {
|
||||||
|
if (start != end) {
|
||||||
|
uint32_t trail_surrogate = utf8::internal::mask16(*start++);
|
||||||
|
if (utf8::internal::is_trail_surrogate(trail_surrogate))
|
||||||
|
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
|
||||||
|
else
|
||||||
|
throw invalid_utf16(static_cast<uint16_t>(trail_surrogate));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw invalid_utf16(static_cast<uint16_t>(cp));
|
||||||
|
|
||||||
|
}
|
||||||
|
// Lone trail surrogate
|
||||||
|
else if (utf8::internal::is_trail_surrogate(cp))
|
||||||
|
throw invalid_utf16(static_cast<uint16_t>(cp));
|
||||||
|
|
||||||
|
result = utf8::append(cp, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
uint32_t cp = utf8::next(start, end);
|
||||||
|
if (cp > 0xffff) { //make a surrogate pair
|
||||||
|
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
|
||||||
|
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*result++ = static_cast<uint16_t>(cp);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end)
|
||||||
|
result = utf8::append(*(start++), result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end)
|
||||||
|
(*result++) = utf8::next(start, end);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The iterator class
|
||||||
|
template <typename octet_iterator>
|
||||||
|
class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
|
||||||
|
octet_iterator it;
|
||||||
|
octet_iterator range_start;
|
||||||
|
octet_iterator range_end;
|
||||||
|
public:
|
||||||
|
iterator () {};
|
||||||
|
explicit iterator (const octet_iterator& octet_it,
|
||||||
|
const octet_iterator& range_start,
|
||||||
|
const octet_iterator& range_end) :
|
||||||
|
it(octet_it), range_start(range_start), range_end(range_end)
|
||||||
|
{
|
||||||
|
if (it < range_start || it > range_end)
|
||||||
|
throw std::out_of_range("Invalid utf-8 iterator position");
|
||||||
|
}
|
||||||
|
// the default "big three" are OK
|
||||||
|
octet_iterator base () const { return it; }
|
||||||
|
uint32_t operator * () const
|
||||||
|
{
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return utf8::next(temp, range_end);
|
||||||
|
}
|
||||||
|
bool operator == (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
if (range_start != rhs.range_start || range_end != rhs.range_end)
|
||||||
|
throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
|
||||||
|
return (it == rhs.it);
|
||||||
|
}
|
||||||
|
bool operator != (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
return !(operator == (rhs));
|
||||||
|
}
|
||||||
|
iterator& operator ++ ()
|
||||||
|
{
|
||||||
|
utf8::next(it, range_end);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator ++ (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
utf8::next(it, range_end);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
iterator& operator -- ()
|
||||||
|
{
|
||||||
|
utf8::prior(it, range_start);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator -- (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
utf8::prior(it, range_start);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
}; // class iterator
|
||||||
|
|
||||||
|
} // namespace utf8
|
||||||
|
|
||||||
|
#endif //header guard
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,329 @@
|
||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace utf8
|
||||||
|
{
|
||||||
|
// The typedefs for 8-bit, 16-bit and 32-bit unsigned integers
|
||||||
|
// You may need to change them to match your system.
|
||||||
|
// These typedefs have the same names as ones from cstdint, or boost/cstdint
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
|
||||||
|
// Helper code - not intended to be directly called by the library users. May be changed at any time
|
||||||
|
namespace internal
|
||||||
|
{
|
||||||
|
// Unicode constants
|
||||||
|
// Leading (high) surrogates: 0xd800 - 0xdbff
|
||||||
|
// Trailing (low) surrogates: 0xdc00 - 0xdfff
|
||||||
|
const uint16_t LEAD_SURROGATE_MIN = 0xd800u;
|
||||||
|
const uint16_t LEAD_SURROGATE_MAX = 0xdbffu;
|
||||||
|
const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u;
|
||||||
|
const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu;
|
||||||
|
const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10);
|
||||||
|
const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN;
|
||||||
|
|
||||||
|
// Maximum valid value for a Unicode code point
|
||||||
|
const uint32_t CODE_POINT_MAX = 0x0010ffffu;
|
||||||
|
|
||||||
|
template<typename octet_type>
|
||||||
|
inline uint8_t mask8(octet_type oc)
|
||||||
|
{
|
||||||
|
return static_cast<uint8_t>(0xff & oc);
|
||||||
|
}
|
||||||
|
template<typename u16_type>
|
||||||
|
inline uint16_t mask16(u16_type oc)
|
||||||
|
{
|
||||||
|
return static_cast<uint16_t>(0xffff & oc);
|
||||||
|
}
|
||||||
|
template<typename octet_type>
|
||||||
|
inline bool is_trail(octet_type oc)
|
||||||
|
{
|
||||||
|
return ((utf8::internal::mask8(oc) >> 6) == 0x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16>
|
||||||
|
inline bool is_lead_surrogate(u16 cp)
|
||||||
|
{
|
||||||
|
return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16>
|
||||||
|
inline bool is_trail_surrogate(u16 cp)
|
||||||
|
{
|
||||||
|
return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16>
|
||||||
|
inline bool is_surrogate(u16 cp)
|
||||||
|
{
|
||||||
|
return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u32>
|
||||||
|
inline bool is_code_point_valid(u32 cp)
|
||||||
|
{
|
||||||
|
return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline typename std::iterator_traits<octet_iterator>::difference_type
|
||||||
|
sequence_length(octet_iterator lead_it)
|
||||||
|
{
|
||||||
|
uint8_t lead = utf8::internal::mask8(*lead_it);
|
||||||
|
if (lead < 0x80)
|
||||||
|
return 1;
|
||||||
|
else if ((lead >> 5) == 0x6)
|
||||||
|
return 2;
|
||||||
|
else if ((lead >> 4) == 0xe)
|
||||||
|
return 3;
|
||||||
|
else if ((lead >> 3) == 0x1e)
|
||||||
|
return 4;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_difference_type>
|
||||||
|
inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length)
|
||||||
|
{
|
||||||
|
if (cp < 0x80) {
|
||||||
|
if (length != 1)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (cp < 0x800) {
|
||||||
|
if (length != 2)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (cp < 0x10000) {
|
||||||
|
if (length != 3)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT};
|
||||||
|
|
||||||
|
/// Helper for get_sequence_x
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error increase_safely(octet_iterator& it, octet_iterator end)
|
||||||
|
{
|
||||||
|
if (++it == end)
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
if (!utf8::internal::is_trail(*it))
|
||||||
|
return INCOMPLETE_SEQUENCE;
|
||||||
|
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;}
|
||||||
|
|
||||||
|
/// get_sequence_x functions decode utf-8 sequences of the length x
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||||
|
{
|
||||||
|
if (it == end)
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
code_point = utf8::internal::mask8(*it);
|
||||||
|
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||||
|
{
|
||||||
|
if (it == end)
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
code_point = utf8::internal::mask8(*it);
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f);
|
||||||
|
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||||
|
{
|
||||||
|
if (it == end)
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
code_point = utf8::internal::mask8(*it);
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point += (*it) & 0x3f;
|
||||||
|
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||||
|
{
|
||||||
|
if (it == end)
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
code_point = utf8::internal::mask8(*it);
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point += (utf8::internal::mask8(*it) << 6) & 0xfff;
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point += (*it) & 0x3f;
|
||||||
|
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||||
|
{
|
||||||
|
// Save the original value of it so we can go back in case of failure
|
||||||
|
// Of course, it does not make much sense with i.e. stream iterators
|
||||||
|
octet_iterator original_it = it;
|
||||||
|
|
||||||
|
uint32_t cp = 0;
|
||||||
|
// Determine the sequence length based on the lead octet
|
||||||
|
typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type;
|
||||||
|
const octet_difference_type length = utf8::internal::sequence_length(it);
|
||||||
|
|
||||||
|
// Get trail octets and calculate the code point
|
||||||
|
utf_error err = UTF8_OK;
|
||||||
|
switch (length) {
|
||||||
|
case 0:
|
||||||
|
return INVALID_LEAD;
|
||||||
|
case 1:
|
||||||
|
err = utf8::internal::get_sequence_1(it, end, cp);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
err = utf8::internal::get_sequence_2(it, end, cp);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
err = utf8::internal::get_sequence_3(it, end, cp);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
err = utf8::internal::get_sequence_4(it, end, cp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == UTF8_OK) {
|
||||||
|
// Decoding succeeded. Now, security checks...
|
||||||
|
if (utf8::internal::is_code_point_valid(cp)) {
|
||||||
|
if (!utf8::internal::is_overlong_sequence(cp, length)){
|
||||||
|
// Passed! Return here.
|
||||||
|
code_point = cp;
|
||||||
|
++it;
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = OVERLONG_SEQUENCE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = INVALID_CODE_POINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failure branch - restore the original value of the iterator
|
||||||
|
it = original_it;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline utf_error validate_next(octet_iterator& it, octet_iterator end) {
|
||||||
|
uint32_t ignored;
|
||||||
|
return utf8::internal::validate_next(it, end, ignored);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
/// The library API - functions intended to be called by the users
|
||||||
|
|
||||||
|
// Byte order mark
|
||||||
|
const uint8_t bom[] = {0xef, 0xbb, 0xbf};
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
octet_iterator find_invalid(octet_iterator start, octet_iterator end)
|
||||||
|
{
|
||||||
|
octet_iterator result = start;
|
||||||
|
while (result != end) {
|
||||||
|
utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end);
|
||||||
|
if (err_code != internal::UTF8_OK)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline bool is_valid(octet_iterator start, octet_iterator end)
|
||||||
|
{
|
||||||
|
return (utf8::find_invalid(start, end) == end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline bool starts_with_bom (octet_iterator it, octet_iterator end)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) &&
|
||||||
|
((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) &&
|
||||||
|
((it != end) && (utf8::internal::mask8(*it)) == bom[2])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Deprecated in release 2.3
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline bool is_bom (octet_iterator it)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
(utf8::internal::mask8(*it++)) == bom[0] &&
|
||||||
|
(utf8::internal::mask8(*it++)) == bom[1] &&
|
||||||
|
(utf8::internal::mask8(*it)) == bom[2]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} // namespace utf8
|
||||||
|
|
||||||
|
#endif // header guard
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,228 @@
|
||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
namespace utf8
|
||||||
|
{
|
||||||
|
namespace unchecked
|
||||||
|
{
|
||||||
|
template <typename octet_iterator>
|
||||||
|
octet_iterator append(uint32_t cp, octet_iterator result)
|
||||||
|
{
|
||||||
|
if (cp < 0x80) // one octet
|
||||||
|
*(result++) = static_cast<uint8_t>(cp);
|
||||||
|
else if (cp < 0x800) { // two octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else if (cp < 0x10000) { // three octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else { // four octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)| 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t next(octet_iterator& it)
|
||||||
|
{
|
||||||
|
uint32_t cp = utf8::internal::mask8(*it);
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it);
|
||||||
|
switch (length) {
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
it++;
|
||||||
|
cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
++it;
|
||||||
|
cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
|
||||||
|
++it;
|
||||||
|
cp += (*it) & 0x3f;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
++it;
|
||||||
|
cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
|
||||||
|
++it;
|
||||||
|
cp += (utf8::internal::mask8(*it) << 6) & 0xfff;
|
||||||
|
++it;
|
||||||
|
cp += (*it) & 0x3f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t peek_next(octet_iterator it)
|
||||||
|
{
|
||||||
|
return utf8::unchecked::next(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t prior(octet_iterator& it)
|
||||||
|
{
|
||||||
|
while (utf8::internal::is_trail(*(--it))) ;
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return utf8::unchecked::next(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous)
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline uint32_t previous(octet_iterator& it)
|
||||||
|
{
|
||||||
|
return utf8::unchecked::prior(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename distance_type>
|
||||||
|
void advance (octet_iterator& it, distance_type n)
|
||||||
|
{
|
||||||
|
for (distance_type i = 0; i < n; ++i)
|
||||||
|
utf8::unchecked::next(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type
|
||||||
|
distance (octet_iterator first, octet_iterator last)
|
||||||
|
{
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type dist;
|
||||||
|
for (dist = 0; first < last; ++dist)
|
||||||
|
utf8::unchecked::next(first);
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
uint32_t cp = utf8::internal::mask16(*start++);
|
||||||
|
// Take care of surrogate pairs first
|
||||||
|
if (utf8::internal::is_lead_surrogate(cp)) {
|
||||||
|
uint32_t trail_surrogate = utf8::internal::mask16(*start++);
|
||||||
|
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
|
||||||
|
}
|
||||||
|
result = utf8::unchecked::append(cp, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start < end) {
|
||||||
|
uint32_t cp = utf8::unchecked::next(start);
|
||||||
|
if (cp > 0xffff) { //make a surrogate pair
|
||||||
|
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
|
||||||
|
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*result++ = static_cast<uint16_t>(cp);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end)
|
||||||
|
result = utf8::unchecked::append(*(start++), result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start < end)
|
||||||
|
(*result++) = utf8::unchecked::next(start);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The iterator class
|
||||||
|
template <typename octet_iterator>
|
||||||
|
class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
|
||||||
|
octet_iterator it;
|
||||||
|
public:
|
||||||
|
iterator () {};
|
||||||
|
explicit iterator (const octet_iterator& octet_it): it(octet_it) {}
|
||||||
|
// the default "big three" are OK
|
||||||
|
octet_iterator base () const { return it; }
|
||||||
|
uint32_t operator * () const
|
||||||
|
{
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return utf8::unchecked::next(temp);
|
||||||
|
}
|
||||||
|
bool operator == (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
return (it == rhs.it);
|
||||||
|
}
|
||||||
|
bool operator != (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
return !(operator == (rhs));
|
||||||
|
}
|
||||||
|
iterator& operator ++ ()
|
||||||
|
{
|
||||||
|
::std::advance(it, utf8::internal::sequence_length(it));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator ++ (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
::std::advance(it, utf8::internal::sequence_length(it));
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
iterator& operator -- ()
|
||||||
|
{
|
||||||
|
utf8::unchecked::prior(it);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator -- (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
utf8::unchecked::prior(it);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
}; // class iterator
|
||||||
|
|
||||||
|
} // namespace utf8::unchecked
|
||||||
|
} // namespace utf8
|
||||||
|
|
||||||
|
|
||||||
|
#endif // header guard
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef __UTILITY_H__
|
||||||
|
#define __UTILITY_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "Types.hpp"
|
||||||
|
|
||||||
|
bool isEmpty(Int8*, size_t);
|
||||||
|
|
||||||
|
unsigned short swapU16(unsigned short val );
|
||||||
|
short swap16 (short val );
|
||||||
|
unsigned int swapU32(unsigned int val);
|
||||||
|
int swap32 (int val );
|
||||||
|
long long swap64 (long long val);
|
||||||
|
|
||||||
|
float swapFloat(float val);
|
||||||
|
double swapDouble(double val);
|
||||||
|
|
||||||
|
bool isSystemBigEndian();
|
||||||
|
|
||||||
|
void fillRandom(Uint8 * rndArea, Uint8 count);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,95 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||||
|
<CodeBlocks_project_file>
|
||||||
|
<FileVersion major="1" minor="6" />
|
||||||
|
<Project>
|
||||||
|
<Option title="libzelda" />
|
||||||
|
<Option pch_mode="2" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Build>
|
||||||
|
<Target title="Debug Win32">
|
||||||
|
<Option platforms="Windows;" />
|
||||||
|
<Option output="lib/Win32/zelda-d" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option working_dir="" />
|
||||||
|
<Option object_output="obj/Debug/" />
|
||||||
|
<Option type="2" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Option createDefFile="1" />
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-g" />
|
||||||
|
</Compiler>
|
||||||
|
</Target>
|
||||||
|
<Target title="Release Win32">
|
||||||
|
<Option output="lib/Win32/zelda" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option working_dir="" />
|
||||||
|
<Option object_output="obj/Release/" />
|
||||||
|
<Option type="2" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Option createDefFile="1" />
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-O2" />
|
||||||
|
</Compiler>
|
||||||
|
<Linker>
|
||||||
|
<Add option="-s" />
|
||||||
|
</Linker>
|
||||||
|
</Target>
|
||||||
|
<Target title="Debug Wii">
|
||||||
|
<Option output="lib/Wii/zelda-d" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option working_dir="" />
|
||||||
|
<Option type="2" />
|
||||||
|
<Option compiler="devkitppc_wii" />
|
||||||
|
<Option createDefFile="1" />
|
||||||
|
</Target>
|
||||||
|
<Target title="Release Wii">
|
||||||
|
<Option output="lib/Wii/zelda" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option working_dir="" />
|
||||||
|
<Option type="2" />
|
||||||
|
<Option compiler="devkitppc_wii" />
|
||||||
|
<Option createDefFile="1" />
|
||||||
|
</Target>
|
||||||
|
<Target title="Debug Linux">
|
||||||
|
<Option platforms="Unix;" />
|
||||||
|
<Option output="lib/Linux/zelda-d" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option working_dir="" />
|
||||||
|
<Option type="2" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Option createDefFile="1" />
|
||||||
|
</Target>
|
||||||
|
<Target title="Release Linux">
|
||||||
|
<Option platforms="Unix;" />
|
||||||
|
<Option output="lib/Linux/zelda" prefix_auto="1" extension_auto="1" />
|
||||||
|
<Option working_dir="" />
|
||||||
|
<Option type="2" />
|
||||||
|
<Option compiler="gcc" />
|
||||||
|
<Option createDefFile="1" />
|
||||||
|
</Target>
|
||||||
|
</Build>
|
||||||
|
<Compiler>
|
||||||
|
<Add option="-std=c++11" />
|
||||||
|
<Add option="-Wall" />
|
||||||
|
<Add directory="include" />
|
||||||
|
</Compiler>
|
||||||
|
<Unit filename="include/BinaryReader.hpp" />
|
||||||
|
<Unit filename="include/BinaryWriter.hpp" />
|
||||||
|
<Unit filename="include/Exception.hpp" />
|
||||||
|
<Unit filename="include/FileNotFoundException.hpp" />
|
||||||
|
<Unit filename="include/IOException.hpp" />
|
||||||
|
<Unit filename="include/InvalidOperationException.hpp" />
|
||||||
|
<Unit filename="include/Stream.hpp" />
|
||||||
|
<Unit filename="include/Types.hpp" />
|
||||||
|
<Unit filename="include/utf8.h" />
|
||||||
|
<Unit filename="include/utf8/checked.h" />
|
||||||
|
<Unit filename="include/utf8/core.h" />
|
||||||
|
<Unit filename="include/utf8/unchecked.h" />
|
||||||
|
<Unit filename="include/utility.hpp" />
|
||||||
|
<Unit filename="src/BinaryReader.cpp" />
|
||||||
|
<Unit filename="src/BinaryWriter.cpp" />
|
||||||
|
<Unit filename="src/Stream.cpp" />
|
||||||
|
<Unit filename="src/utility.cpp" />
|
||||||
|
<Extensions>
|
||||||
|
<code_completion />
|
||||||
|
<envvars />
|
||||||
|
<debugger />
|
||||||
|
<lib_finder disable_auto="1" />
|
||||||
|
</Extensions>
|
||||||
|
</Project>
|
||||||
|
</CodeBlocks_project_file>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,80 @@
|
||||||
|
# depslib dependency file v1.0
|
||||||
|
1359172369 source:/home/antidote/trunk/save editor/libzelda/src/BinaryReader.cpp
|
||||||
|
"BinaryReader.hpp"
|
||||||
|
"IOException.hpp"
|
||||||
|
"FileNotFoundException.hpp"
|
||||||
|
"utility.hpp"
|
||||||
|
"utf8.h"
|
||||||
|
<stdio.h>
|
||||||
|
<stdlib.h>
|
||||||
|
<vector>
|
||||||
|
|
||||||
|
1359171705 /home/antidote/trunk/save editor/libzelda/include/BinaryReader.hpp
|
||||||
|
"Stream.hpp"
|
||||||
|
<string>
|
||||||
|
|
||||||
|
1358872986 /home/antidote/trunk/save editor/libzelda/include/Stream.hpp
|
||||||
|
"Types.hpp"
|
||||||
|
|
||||||
|
1358872986 /home/antidote/trunk/save editor/libzelda/include/Types.hpp
|
||||||
|
<limits.h>
|
||||||
|
|
||||||
|
1358872986 /home/antidote/trunk/save editor/libzelda/include/IOException.hpp
|
||||||
|
"Exception.hpp"
|
||||||
|
|
||||||
|
1358872986 /home/antidote/trunk/save editor/libzelda/include/Exception.hpp
|
||||||
|
<string>
|
||||||
|
|
||||||
|
1358872986 /home/antidote/trunk/save editor/libzelda/include/FileNotFoundException.hpp
|
||||||
|
"Exception.hpp"
|
||||||
|
|
||||||
|
1359171946 /home/antidote/trunk/save editor/libzelda/include/utility.hpp
|
||||||
|
<string>
|
||||||
|
"Types.hpp"
|
||||||
|
|
||||||
|
1358872986 /home/antidote/trunk/save editor/libzelda/include/utf8.h
|
||||||
|
"utf8/checked.h"
|
||||||
|
"utf8/unchecked.h"
|
||||||
|
|
||||||
|
1358872986 /home/antidote/trunk/save editor/libzelda/include/utf8/checked.h
|
||||||
|
"core.h"
|
||||||
|
<stdexcept>
|
||||||
|
|
||||||
|
1358872986 /home/antidote/trunk/save editor/libzelda/include/utf8/core.h
|
||||||
|
<iterator>
|
||||||
|
|
||||||
|
1358872986 /home/antidote/trunk/save editor/libzelda/include/utf8/unchecked.h
|
||||||
|
"core.h"
|
||||||
|
|
||||||
|
1359172754 source:/home/antidote/trunk/save editor/libzelda/src/BinaryWriter.cpp
|
||||||
|
"BinaryWriter.hpp"
|
||||||
|
"IOException.hpp"
|
||||||
|
"FileNotFoundException.hpp"
|
||||||
|
"utility.hpp"
|
||||||
|
"utf8.h"
|
||||||
|
<stdio.h>
|
||||||
|
<string.h>
|
||||||
|
<vector>
|
||||||
|
<iostream>
|
||||||
|
|
||||||
|
1358872986 /home/antidote/trunk/save editor/libzelda/include/BinaryWriter.hpp
|
||||||
|
"Stream.hpp"
|
||||||
|
<string>
|
||||||
|
|
||||||
|
1358872986 source:/home/antidote/trunk/save editor/libzelda/src/Stream.cpp
|
||||||
|
"Stream.hpp"
|
||||||
|
"IOException.hpp"
|
||||||
|
"InvalidOperationException.hpp"
|
||||||
|
<string.h>
|
||||||
|
<sstream>
|
||||||
|
|
||||||
|
1358872986 /home/antidote/trunk/save editor/libzelda/include/InvalidOperationException.hpp
|
||||||
|
<string>
|
||||||
|
<Exception.hpp>
|
||||||
|
|
||||||
|
1359219210 source:/home/antidote/trunk/save editor/libzelda/src/utility.cpp
|
||||||
|
"utility.hpp"
|
||||||
|
<iostream>
|
||||||
|
<string.h>
|
||||||
|
<stdlib.h>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||||
|
<CodeBlocks_layout_file>
|
||||||
|
<ActiveTarget name="Release Linux" />
|
||||||
|
<File name="src/BinaryReader.cpp" open="1" top="1" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||||
|
<Cursor>
|
||||||
|
<Cursor1 position="0" topLine="30" />
|
||||||
|
</Cursor>
|
||||||
|
</File>
|
||||||
|
</CodeBlocks_layout_file>
|
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
|
@ -0,0 +1,222 @@
|
||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="libzelda"
|
||||||
|
ProjectGUID="{3E0B05A1-DE7E-4EAE-86DF-2FB507E7F1AD}"
|
||||||
|
RootNamespace="libzelda"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="include"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
OutputFile="lib\Win32\zelda-d.lib"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="4"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="include"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLibrarianTool"
|
||||||
|
OutputFile="lib\Win32\zelda.lib"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\BinaryReader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\BinaryWriter.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\FileStream.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\Stream.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\utility.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\utility.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\BinaryReader.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\BinaryWriter.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\Exception.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\FileNotFoundException.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\FileStream.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\IOException.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\Stream.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\Types.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
|
@ -0,0 +1,238 @@
|
||||||
|
#include "BinaryReader.hpp"
|
||||||
|
#include "IOException.hpp"
|
||||||
|
#include "FileNotFoundException.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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_bitPosition(0),
|
||||||
|
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];
|
||||||
|
|
||||||
|
fread(m_data, 1, length, in);
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
utf8::utf16to8(tmp.begin(), tmp.end(), back_inserter(ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BinaryReader::isOpenForWriting()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,257 @@
|
||||||
|
#include "BinaryWriter.hpp"
|
||||||
|
#include "IOException.hpp"
|
||||||
|
#include "FileNotFoundException.hpp"
|
||||||
|
#include "utility.hpp"
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
BinaryWriter::BinaryWriter(const Uint8* data, Uint64 length)
|
||||||
|
: Stream(data, length)
|
||||||
|
{}
|
||||||
|
|
||||||
|
BinaryWriter::BinaryWriter(const Stream& stream) :
|
||||||
|
Stream(stream)
|
||||||
|
{}
|
||||||
|
|
||||||
|
BinaryWriter::BinaryWriter(const std::string& filename)
|
||||||
|
: m_filename(filename)
|
||||||
|
{
|
||||||
|
m_length = 0x10;
|
||||||
|
m_bitPosition = 0;
|
||||||
|
m_position = 0;
|
||||||
|
m_data = new Uint8[m_length];
|
||||||
|
if (!m_data)
|
||||||
|
throw IOException("Could not allocate memory!");
|
||||||
|
memset(m_data, 0, m_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinaryWriter::save(const std::string& filename)
|
||||||
|
{
|
||||||
|
if (filename.empty() && m_filename.empty())
|
||||||
|
throw Exception("InvalidOperationException: BinaryWriter::Save() -> No file specified, cannot save.");
|
||||||
|
|
||||||
|
if (!filename.empty())
|
||||||
|
m_filename = filename;
|
||||||
|
|
||||||
|
FILE* out = fopen(m_filename.c_str(), "wb");
|
||||||
|
if (!out)
|
||||||
|
throw FileNotFoundException(m_filename);
|
||||||
|
|
||||||
|
fwrite(m_data, 1, m_length, out);
|
||||||
|
fclose(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
Int8 BinaryWriter::readByte()
|
||||||
|
{
|
||||||
|
throw IOException("Stream not open for reading");
|
||||||
|
}
|
||||||
|
|
||||||
|
Int8* BinaryWriter::readBytes(Int64)
|
||||||
|
{
|
||||||
|
throw IOException("Stream not open for reading");
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinaryWriter::writeInt16(Int16 val)
|
||||||
|
{
|
||||||
|
if (m_bitPosition > 0)
|
||||||
|
{
|
||||||
|
m_bitPosition = 0;
|
||||||
|
m_position += sizeof(Uint8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_position + sizeof(Int16) > m_length && m_autoResize)
|
||||||
|
resize(m_position + sizeof(Int16));
|
||||||
|
else if (m_position > m_length)
|
||||||
|
throw IOException("BinaryWriter::WriteInt16() -> Position outside stream bounds");
|
||||||
|
|
||||||
|
if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian))
|
||||||
|
val = swap16(val);
|
||||||
|
|
||||||
|
*(Int16*)(m_data + m_position) = val;
|
||||||
|
m_position += sizeof(Int16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinaryWriter::writeUInt16(Uint16 val)
|
||||||
|
{
|
||||||
|
if (m_bitPosition > 0)
|
||||||
|
{
|
||||||
|
m_bitPosition = 0;
|
||||||
|
m_position += sizeof(Uint8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_position + sizeof(Uint16) > m_length && m_autoResize)
|
||||||
|
resize(m_position + sizeof(Uint16));
|
||||||
|
else if (m_position > m_length)
|
||||||
|
throw IOException("BinaryWriter::WriteUInt16() -> Position outside stream bounds");
|
||||||
|
|
||||||
|
|
||||||
|
if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian))
|
||||||
|
val = swapU16(val);
|
||||||
|
|
||||||
|
*(Uint16*)(m_data + m_position) = val;
|
||||||
|
m_position += sizeof(Uint16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinaryWriter::writeInt32(Int32 val)
|
||||||
|
{
|
||||||
|
if (m_bitPosition > 0)
|
||||||
|
{
|
||||||
|
m_bitPosition = 0;
|
||||||
|
m_position += sizeof(Uint8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_position + sizeof(Int32) > m_length && m_autoResize)
|
||||||
|
resize(m_position + sizeof(Int32));
|
||||||
|
else if (m_position > m_length)
|
||||||
|
throw IOException("BinaryWriter::WriteInt32() -> Position outside stream bounds");
|
||||||
|
|
||||||
|
if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian))
|
||||||
|
val = swap32(val);
|
||||||
|
|
||||||
|
*(Int32*)(m_data + m_position) = val;
|
||||||
|
m_position += sizeof(Int32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinaryWriter::writeUInt32(Uint32 val)
|
||||||
|
{
|
||||||
|
if (m_bitPosition > 0)
|
||||||
|
{
|
||||||
|
m_bitPosition = 0;
|
||||||
|
m_position += sizeof(Uint8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_position + sizeof(Uint32) > m_length && m_autoResize)
|
||||||
|
resize(m_position + sizeof(Uint32));
|
||||||
|
else if (m_position > m_length)
|
||||||
|
throw IOException("BinaryWriter::WriteUInt32() -> Position outside stream bounds");
|
||||||
|
|
||||||
|
if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian))
|
||||||
|
val = swap32(val);
|
||||||
|
|
||||||
|
*(Uint32*)(m_data + m_position) = val;
|
||||||
|
m_position += sizeof(Uint32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinaryWriter::writeInt64(Int64 val)
|
||||||
|
{
|
||||||
|
if (m_bitPosition > 0)
|
||||||
|
{
|
||||||
|
m_bitPosition = 0;
|
||||||
|
m_position += sizeof(Uint8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_position + sizeof(Int64) > m_length && m_autoResize)
|
||||||
|
resize(m_position + sizeof(Int64));
|
||||||
|
else if (m_position > m_length)
|
||||||
|
throw IOException("BinaryWriter::WriteInt64() -> Position outside stream bounds");
|
||||||
|
|
||||||
|
|
||||||
|
if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian))
|
||||||
|
val = swap64(val);
|
||||||
|
|
||||||
|
*(Int64*)(m_data + m_position) = val;
|
||||||
|
m_position += sizeof(Int64);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinaryWriter::writeUInt64(Uint64 val)
|
||||||
|
{
|
||||||
|
if (m_bitPosition > 0)
|
||||||
|
{
|
||||||
|
m_bitPosition = 0;
|
||||||
|
m_position += sizeof(Uint8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_position + sizeof(Uint64) > m_length && m_autoResize)
|
||||||
|
resize(m_position + sizeof(Uint64));
|
||||||
|
else if (m_position > m_length)
|
||||||
|
throw IOException("BinaryWriter::WriteUInt64() -> Position outside stream bounds");
|
||||||
|
|
||||||
|
if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian))
|
||||||
|
val = swap64(val);
|
||||||
|
|
||||||
|
*(Uint64*)(m_data + m_position) = val;
|
||||||
|
m_position += sizeof(Uint64);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinaryWriter::writeFloat(float val)
|
||||||
|
{
|
||||||
|
if (m_bitPosition > 0)
|
||||||
|
{
|
||||||
|
m_bitPosition = 0;
|
||||||
|
m_position += sizeof(Uint8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_position + sizeof(float) > m_length && m_autoResize)
|
||||||
|
resize(m_position + sizeof(float));
|
||||||
|
else if (m_position > m_length)
|
||||||
|
throw IOException("BinaryWriter::WriteFloat() -> Position outside stream bounds");
|
||||||
|
|
||||||
|
if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian))
|
||||||
|
val = swapFloat(val);
|
||||||
|
|
||||||
|
*(float*)(m_data + m_position) = val;
|
||||||
|
m_position += sizeof(float);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinaryWriter::writeDouble(double val)
|
||||||
|
{
|
||||||
|
if (m_bitPosition > 0)
|
||||||
|
{
|
||||||
|
m_bitPosition = 0;
|
||||||
|
m_position += sizeof(Uint8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_position + sizeof(double) > m_length && m_autoResize)
|
||||||
|
resize(m_position + sizeof(double));
|
||||||
|
else if (m_position > m_length)
|
||||||
|
throw IOException("BinaryWriter::WriteDouble() -> Position outside stream bounds");
|
||||||
|
|
||||||
|
if ((!isSystemBigEndian() && m_endian == Stream::BigEndian) || (isSystemBigEndian() && m_endian == Stream::LittleEndian))
|
||||||
|
val = swapDouble(val);
|
||||||
|
|
||||||
|
*(double*)(m_data + m_position)= val;
|
||||||
|
m_position += sizeof(double);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinaryWriter::writeBool(bool val)
|
||||||
|
{
|
||||||
|
if (m_bitPosition > 0)
|
||||||
|
{
|
||||||
|
m_bitPosition = 0;
|
||||||
|
m_position += sizeof(Uint8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_position + sizeof(bool) > m_length && m_autoResize)
|
||||||
|
resize(m_position + sizeof(bool));
|
||||||
|
else if (m_position > m_length)
|
||||||
|
throw IOException("BinaryWriter::WriteBool() -> Position outside stream bounds");
|
||||||
|
|
||||||
|
|
||||||
|
*(bool*)(m_data + m_position) = val;
|
||||||
|
m_position += sizeof(bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinaryWriter::writeUnicode(const std::string& str)
|
||||||
|
{
|
||||||
|
std::string tmpStr = "\xEF\xBB\xBF" + str;
|
||||||
|
|
||||||
|
std::vector<short> tmp;
|
||||||
|
|
||||||
|
utf8::utf8to16(tmpStr.begin(), tmpStr.end(), back_inserter(tmp));
|
||||||
|
|
||||||
|
for (Uint16 chr : tmp)
|
||||||
|
{
|
||||||
|
if (chr != 0xFEFF)
|
||||||
|
writeInt16(chr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BinaryWriter::isOpenForReading()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
#include "FileStream.hpp"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "FileNotFoundException.hpp"
|
||||||
|
#include "IOException.hpp"
|
||||||
|
|
||||||
|
FileStream::FileStream(const std::string& filename, FileMode fileMode, AccessMode accessMode) :
|
||||||
|
m_filename(filename),
|
||||||
|
m_filemode(fileMode),
|
||||||
|
m_accessmode(accessMode)
|
||||||
|
{
|
||||||
|
FILE* in;
|
||||||
|
int length;
|
||||||
|
in = fopen(filename.c_str(), "rb");
|
||||||
|
|
||||||
|
if (!in)
|
||||||
|
{
|
||||||
|
if((fileMode & Create) != Create)
|
||||||
|
throw FileNotFoundException(filename.c_str());
|
||||||
|
|
||||||
|
in = fopen(filename.c_str(), "w+b");
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(in, 0, SEEK_END);
|
||||||
|
length = ftell(in);
|
||||||
|
fseek(in, 0, SEEK_SET);
|
||||||
|
m_data = new Uint8[length];
|
||||||
|
|
||||||
|
fread(m_data, 1, length, in);
|
||||||
|
fclose(in);
|
||||||
|
printf("%i\n", length);
|
||||||
|
m_length = length;
|
||||||
|
m_position = 0;
|
||||||
|
}
|
|
@ -0,0 +1,290 @@
|
||||||
|
#include "Stream.hpp"
|
||||||
|
#include "IOException.hpp"
|
||||||
|
#include "InvalidOperationException.hpp"
|
||||||
|
#include <string.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
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: " + m_position);
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Stream::isOpenForWriting()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stream::setEndianess(Endian endian)
|
||||||
|
{
|
||||||
|
m_endian = endian;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream::Endian Stream::endianness() const
|
||||||
|
{
|
||||||
|
return m_endian;
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
#include "utility.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
bool isEmpty(Int8* buf, size_t size)
|
||||||
|
{
|
||||||
|
return buf[0] == 0 && !memcmp(buf, buf + 1, size - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short swapU16(unsigned short val )
|
||||||
|
{
|
||||||
|
return (val << 8) | (val >> 8 );
|
||||||
|
}
|
||||||
|
|
||||||
|
short swap16(short val )
|
||||||
|
{
|
||||||
|
return (val << 8) | ((val >> 8) & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int swapU32(unsigned int val)
|
||||||
|
{
|
||||||
|
val = (val & 0x0000FFFF) << 16 | (val & 0xFFFF0000) >> 16;
|
||||||
|
val = (val & 0x00FF00FF) << 8 | (val & 0xFF00FF00) >> 8;
|
||||||
|
return (Uint32)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
int swap32( int val )
|
||||||
|
{
|
||||||
|
val = (val & 0x0000FFFF) << 16 | (val & 0xFFFF0000) >> 16;
|
||||||
|
val = (val & 0x00FF00FF) << 8 | (val & 0xFF00FF00) >> 8;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long swap64(long long val)
|
||||||
|
{
|
||||||
|
return ((long long)((((long long)(val) & 0xFF00000000000000ULL) >> 56) |
|
||||||
|
(((long long)(val) & 0x00FF000000000000ULL) >> 40) |
|
||||||
|
(((long long)(val) & 0x0000FF0000000000ULL) >> 24) |
|
||||||
|
(((long long)(val) & 0x000000FF00000000ULL) >> 8) |
|
||||||
|
(((long long)(val) & 0x00000000FF000000ULL) << 8) |
|
||||||
|
(((long long)(val) & 0x0000000000FF0000ULL) << 24) |
|
||||||
|
(((long long)(val) & 0x000000000000FF00ULL) << 40) |
|
||||||
|
(((long long)(val) & 0x00000000000000FFULL) << 56)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSystemBigEndian()
|
||||||
|
{
|
||||||
|
char* test = (char*)"\xFE\xFF";
|
||||||
|
return (*(unsigned short*)test == 0xFEFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fillRandom(Uint8 * rndArea, Uint8 count)
|
||||||
|
{
|
||||||
|
for(Uint16 i = 0; i < count; i++)
|
||||||
|
rndArea[i]=rand();
|
||||||
|
}
|
||||||
|
|
||||||
|
float swapFloat(float val)
|
||||||
|
{
|
||||||
|
float retVal;
|
||||||
|
char* convFloat = (char*) &val;
|
||||||
|
char* retFloat = (char*) &retVal;
|
||||||
|
|
||||||
|
retFloat[0] = convFloat[3];
|
||||||
|
retFloat[1] = convFloat[2];
|
||||||
|
retFloat[2] = convFloat[1];
|
||||||
|
retFloat[3] = convFloat[0];
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
double swapDouble(double val)
|
||||||
|
{
|
||||||
|
double retVal;
|
||||||
|
char* convFloat = (char*) &val;
|
||||||
|
char* retFloat = (char*) &retVal;
|
||||||
|
|
||||||
|
retFloat[0] = convFloat[7];
|
||||||
|
retFloat[1] = convFloat[6];
|
||||||
|
retFloat[2] = convFloat[5];
|
||||||
|
retFloat[3] = convFloat[4];
|
||||||
|
retFloat[0] = convFloat[3];
|
||||||
|
retFloat[1] = convFloat[2];
|
||||||
|
retFloat[2] = convFloat[1];
|
||||||
|
retFloat[3] = convFloat[0];
|
||||||
|
|
||||||
|
return (double)((Uint64)retVal);
|
||||||
|
}
|
Loading…
Reference in New Issue