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