This commit is contained in:
Phillip Stephens 2015-10-16 00:17:47 -07:00
commit 340588db62
11 changed files with 1301 additions and 276 deletions

View File

@ -34,7 +34,12 @@ set(CLANG_INCLUDE_DIR ${LLVM_LIBRARY_DIRS}/clang/${LLVM_VERSION_STRING}/include
CACHE PATH "Clang include dir" FORCE)
if(UNIX)
list(APPEND PLAT_LIBS z pthread curses dl)
list(APPEND PLAT_LIBS z pthread curses)
if (APPLE)
list(APPEND PLAT_LIBS dl)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
list(APPEND PLAT_LIBS dl)
endif()
endif()
# Offer the user the choice of overriding the installation directories
@ -162,7 +167,8 @@ macro(atdna out)
# OSX Extra
elseif(APPLE)
list(APPEND extraargs -isysroot ${CMAKE_OSX_SYSROOT} -isysroot /)
list(APPEND extraargs -isysroot ${CMAKE_OSX_SYSROOT} -isysroot
${CMAKE_OSX_SYSROOT}/../../../../../Toolchains/XcodeDefault.xctoolchain)
endif()
# Make target

View File

@ -45,7 +45,8 @@ macro(atdna out)
# OSX Extra
elseif(APPLE)
list(APPEND extraargs -isysroot ${CMAKE_OSX_SYSROOT} -isysroot /)
list(APPEND extraargs -isysroot ${CMAKE_OSX_SYSROOT} -isysroot
${CMAKE_OSX_SYSROOT}/../../../../../Toolchains/XcodeDefault.xctoolchain)
endif()
# Make target

View File

@ -1,4 +1,5 @@
#include <stdio.h>
#include <iostream>
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInstance.h"
@ -218,15 +219,31 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
if (vType->isVectorType())
{
const clang::BuiltinType* eType = (clang::BuiltinType*)vType->getElementType().getTypePtr();
const uint64_t width = context.getTypeInfo(eType).Width;
if (!eType->isBuiltinType() || !eType->isFloatingPoint() ||
context.getTypeInfo(eType).Width != 32)
(width != 32 && width != 64))
continue;
if (vType->getNumElements() == 2)
{
if (width == 32)
return ATHENA_DNA_WRITER ".writeVec2f" + funcPrefix + "(" + fieldName + ");";
else if (width == 64)
return ATHENA_DNA_WRITER ".writeVec2d" + funcPrefix + "(" + fieldName + ");";
}
else if (vType->getNumElements() == 3)
{
if (width == 32)
return ATHENA_DNA_WRITER ".writeVec3f" + funcPrefix + "(" + fieldName + ");";
else if (width == 64)
return ATHENA_DNA_WRITER ".writeVec3d" + funcPrefix + "(" + fieldName + ");";
}
else if (vType->getNumElements() == 4)
{
if (width == 32)
return ATHENA_DNA_WRITER ".writeVec4f" + funcPrefix + "(" + fieldName + ");";
else if (width == 64)
return ATHENA_DNA_WRITER ".writeVec4d" + funcPrefix + "(" + fieldName + ");";
}
}
}
}
@ -323,15 +340,31 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
if (vType->isVectorType())
{
const clang::BuiltinType* eType = (clang::BuiltinType*)vType->getElementType().getTypePtr();
const uint64_t width = context.getTypeInfo(eType).Width;
if (!eType->isBuiltinType() || !eType->isFloatingPoint() ||
context.getTypeInfo(eType).Width != 32)
(width != 32 && width != 64))
continue;
if (vType->getNumElements() == 2)
{
if (width == 32)
return ATHENA_DNA_READER ".readVec2f" + funcPrefix + "()";
else if (width == 64)
return ATHENA_DNA_READER ".readVec2d" + funcPrefix + "()";
}
else if (vType->getNumElements() == 3)
{
if (width == 32)
return ATHENA_DNA_READER ".readVec3f" + funcPrefix + "()";
else if (width == 64)
return ATHENA_DNA_READER ".readVec3d" + funcPrefix + "()";
}
else if (vType->getNumElements() == 4)
{
if (width == 32)
return ATHENA_DNA_READER ".readVec4f" + funcPrefix + "()";
else if (width == 64)
return ATHENA_DNA_READER ".readVec4d" + funcPrefix + "()";
}
}
}
}
@ -436,15 +469,31 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
if (vType->isVectorType())
{
const clang::BuiltinType* eType = (clang::BuiltinType*)vType->getElementType().getTypePtr();
const uint64_t width = context.getTypeInfo(eType).Width;
if (!eType->isBuiltinType() || !eType->isFloatingPoint() ||
context.getTypeInfo(eType).Width != 32)
(width != 32 && width != 64))
continue;
if (vType->getNumElements() == 2)
{
if (width == 32)
return ATHENA_YAML_WRITER ".writeVec2f(\"" + bareFieldName + "\", " + fieldName + ");";
else if (width == 64)
return ATHENA_YAML_WRITER ".writeVec2d(\"" + bareFieldName + "\", " + fieldName + ");";
}
else if (vType->getNumElements() == 3)
{
if (width == 32)
return ATHENA_YAML_WRITER ".writeVec3f(\"" + bareFieldName + "\", " + fieldName + ");";
else if (width == 64)
return ATHENA_YAML_WRITER ".writeVec3d(\"" + bareFieldName + "\", " + fieldName + ");";
}
else if (vType->getNumElements() == 4)
{
if (width == 32)
return ATHENA_YAML_WRITER ".writeVec4f(\"" + bareFieldName + "\", " + fieldName + ");";
else if (width == 64)
return ATHENA_YAML_WRITER ".writeVec4d(\"" + bareFieldName + "\", " + fieldName + ");";
}
}
}
}
@ -541,15 +590,31 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
if (vType->isVectorType())
{
const clang::BuiltinType* eType = (clang::BuiltinType*)vType->getElementType().getTypePtr();
const uint64_t width = context.getTypeInfo(eType).Width;
if (!eType->isBuiltinType() || !eType->isFloatingPoint() ||
context.getTypeInfo(eType).Width != 32)
(width != 32 && width != 64))
continue;
if (vType->getNumElements() == 2)
{
if (width == 32)
return ATHENA_YAML_READER ".readVec2f(\"" + bareFieldName + "\")";
else if (width == 64)
return ATHENA_YAML_READER ".readVec2d(\"" + bareFieldName + "\")";
}
else if (vType->getNumElements() == 3)
{
if (width == 32)
return ATHENA_YAML_READER ".readVec3f(\"" + bareFieldName + "\")";
else if (width == 64)
return ATHENA_YAML_READER ".readVec3d(\"" + bareFieldName + "\")";
}
else if (vType->getNumElements() == 4)
{
if (width == 32)
return ATHENA_YAML_READER ".readVec4f(\"" + bareFieldName + "\")";
else if (width == 64)
return ATHENA_YAML_READER ".readVec4d(\"" + bareFieldName + "\")";
}
}
}
}
@ -1328,7 +1393,6 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
{
fileOut << " /* " << fieldName << " */\n"
" " << fieldName << (p ? ".write(" ATHENA_DNA_WRITER ");\n" : ".read(" ATHENA_DNA_READER ");\n");
break;
}
}
@ -1649,7 +1713,6 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
fileOut << " /* " << fieldName << " */\n"
" " ATHENA_YAML_WRITER ".enumerate(\"" << fieldNameBare << "\", " << fieldName << ");\n";
}
break;
}
}
@ -1667,6 +1730,7 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
fileOut << "}\n\n";
}
fileOut << "const char* " << decl->getQualifiedNameAsString() << "::DNAType()\n{\n return \"" << decl->getQualifiedNameAsString() << "\";\n}\n\n";
}
public:

View File

@ -34,6 +34,7 @@ struct WStringAsString;
/**
* @brief Base DNA class used against 'atdna'
* @tparam DNAE Default-endianness for contained DNA values
*
* Athena bundles a build-tool called 'atdna'. This tool functions
* just like the 'clang' compiler, except it emits a full .cpp implementation
@ -43,36 +44,88 @@ struct WStringAsString;
template <Endian DNAE>
struct DNA
{
/**
* @brief Common virtual read function for all DNA types
*/
virtual void read(IStreamReader&)=0;
/**
* @brief Common virtual write function for all DNA types
*/
virtual void write(IStreamWriter&) const=0;
/**
* @brief Template type signaling atdna to capture the value where it's used
* @tparam T The type of the value. Can be any numeric type or atVec* type
* @tparam VE Endianness of the value
*/
template <typename T, Endian VE = DNAE>
using Value = T;
/**
* @brief Template type wrapping std::vector and signaling atdna to manipulate it where it's used
* @tparam T The type of contained elements. Can be any numeric type, atVec* type, or another DNA subclass
* @tparam cntVar C++ expression wrapped in DNA_COUNT macro to determine number of elements for vector
* @tparam VE Endianness of the contained values
*/
template <typename T, size_t cntVar, Endian VE = DNAE>
using Vector = std::vector<T>;
/**
* @brief Template type wrapping std::unique_ptr<atUint8[]> and signaling atdna to read a
* raw byte-buffer where it's used
* @tparam sizeVar C++ expression wrapped in DNA_COUNT macro to determine number of bytes for buffer
*/
template <size_t sizeVar>
using Buffer = struct Athena::io::Buffer<sizeVar, DNAE>;
/**
* @brief Template type wrapping std::string and signaling atdna to read string data where it's used
* @tparam sizeVar C++ expression wrapped in DNA_COUNT macro to determine number of characters for string
* -1 literal indicates null-terminated string
*/
template <atInt32 sizeVar = -1>
using String = struct Athena::io::String<sizeVar, DNAE>;
/**
* @brief Template type wrapping std::wstring and signaling atdna to read wstring data where it's used
* @tparam sizeVar C++ expression wrapped in DNA_COUNT macro to determine number of characters for wstring
* -1 literal indicates null-terminated wstring
*/
template <atInt32 sizeVar = -1, Endian VE = DNAE>
using WString = struct Athena::io::WString<sizeVar, VE>;
/**
* @brief Template type wrapping std::string and signaling atdna to read wstring data where it's used
* @tparam sizeVar C++ expression wrapped in DNA_COUNT macro to determine number of characters for string
* -1 literal indicates null-terminated string
*/
template <atInt32 sizeVar = -1>
using WStringAsString = struct Athena::io::WStringAsString<sizeVar, DNAE>;
/**
* @brief Meta Template signaling atdna to insert a stream seek where it's used
* @tparam offset C++ expression wrapped in DNA_COUNT macro to determine number of bytes to seek
* @tparam direction SeekOrigin to seek relative to
*/
template <off_t offset, SeekOrigin direction>
struct Seek {};
/**
* @brief Meta Template signaling atdna to insert an aligning stream seek where it's used
* @tparam align Number of bytes to align to
*/
template <size_t align>
struct Align {};
/**
* @brief Meta Template preventing atdna from emitting read/write implementations
*/
struct Delete {};
};
/**
* @brief Concrete buffer type used by DNA::Buffer
*/
template <size_t sizeVar, Endian VE>
struct Buffer : public DNA<VE>, public std::unique_ptr<atUint8[]>
{
@ -88,6 +141,9 @@ struct Buffer : public DNA<VE>, public std::unique_ptr<atUint8[]>
}
};
/**
* @brief Concrete string type used by DNA::String
*/
template <atInt32 sizeVar, Endian VE>
struct String : public DNA<VE>, public std::string
{
@ -102,6 +158,9 @@ struct String : public DNA<VE>, public std::string
{this->swap(__str); return *this;}
};
/**
* @brief Concrete wstring type used by DNA::WString
*/
template <atInt32 sizeVar, Endian VE>
struct WString : public DNA<VE>, public std::wstring
{
@ -122,6 +181,9 @@ struct WString : public DNA<VE>, public std::wstring
{this->swap(__str); return *this;}
};
/**
* @brief Concrete converting-wstring type used by DNA::WStringAsString
*/
template <atInt32 sizeVar, Endian VE>
struct WStringAsString : public DNA<VE>, public std::string
{

View File

@ -263,7 +263,14 @@ inline RETURNTYPE NodeToVec(const YAMLNode* node)
{
YAMLNode* snode = it->get();
if (snode->m_type == YAML_SCALAR_NODE)
{
if (std::is_same<RETURNTYPE, atVec2d>::value ||
std::is_same<RETURNTYPE, atVec3d>::value ||
std::is_same<RETURNTYPE, atVec4d>::value)
retval.vec[i] = NodeToVal<double>(snode);
else
retval.vec[i] = NodeToVal<float>(snode);
}
else
retval.vec[i] = 0.0;
}
@ -336,6 +343,72 @@ inline std::unique_ptr<YAMLNode> ValToNode(const atVec4f& val)
return std::unique_ptr<YAMLNode>(ret);
}
template <>
inline atVec2d NodeToVal(const YAMLNode* node)
{
return NodeToVec<atVec2d>(node);
}
template <>
inline std::unique_ptr<YAMLNode> ValToNode(const atVec2d& val)
{
YAMLNode* ret = new YAMLNode(YAML_SEQUENCE_NODE);
ret->m_seqChildren.reserve(2);
for (size_t i=0 ; i<2 ; ++i)
{
char str[64];
snprintf(str, 64, "%f", val.vec[i]);
YAMLNode* comp = new YAMLNode(YAML_SCALAR_NODE);
comp->m_scalarString = str;
ret->m_seqChildren.emplace_back(comp);
}
return std::unique_ptr<YAMLNode>(ret);
}
template <>
inline atVec3d NodeToVal(const YAMLNode* node)
{
return NodeToVec<atVec3d>(node);
}
template <>
inline std::unique_ptr<YAMLNode> ValToNode(const atVec3d& val)
{
YAMLNode* ret = new YAMLNode(YAML_SEQUENCE_NODE);
ret->m_seqChildren.reserve(3);
for (size_t i=0 ; i<3 ; ++i)
{
char str[64];
snprintf(str, 64, "%f", val.vec[i]);
YAMLNode* comp = new YAMLNode(YAML_SCALAR_NODE);
comp->m_scalarString = str;
ret->m_seqChildren.emplace_back(comp);
}
return std::unique_ptr<YAMLNode>(ret);
}
template <>
inline atVec4d NodeToVal(const YAMLNode* node)
{
return NodeToVec<atVec4d>(node);
}
template <>
inline std::unique_ptr<YAMLNode> ValToNode(const atVec4d& val)
{
YAMLNode* ret = new YAMLNode(YAML_SEQUENCE_NODE);
ret->m_seqChildren.reserve(4);
for (size_t i=0 ; i<4 ; ++i)
{
char str[64];
snprintf(str, 64, "%f", val.vec[i]);
YAMLNode* comp = new YAMLNode(YAML_SCALAR_NODE);
comp->m_scalarString = str;
ret->m_seqChildren.emplace_back(comp);
}
return std::unique_ptr<YAMLNode>(ret);
}
template <>
inline std::unique_ptr<atUint8[]> NodeToVal(const YAMLNode* node)
{
@ -426,6 +499,7 @@ class YAMLDocReader
std::vector<int> m_seqTrackerStack;
static std::unique_ptr<YAMLNode> ParseEvents(yaml_parser_t* doc);
public:
static bool ValidateClassType(yaml_parser_t* doc, const char* expectedType);
inline const YAMLNode* getRootNode() const {return m_rootNode.get();}
bool read(yaml_parser_t* doc)
{
@ -527,7 +601,7 @@ public:
vector.reserve(count);
enterSubVector(name);
for (size_t i=0 ; i<count ; ++i)
vector.emplace_back(readVal<T>(name));
vector.push_back(readVal<T>(name));
leaveSubVector();
}
@ -642,12 +716,26 @@ public:
{
return readVal<atVec3f>(name);
}
inline atVec4f readVec4f(const char* name)
{
return readVal<atVec4f>(name);
}
inline atVec2d readVec2d(const char* name)
{
return readVal<atVec2d>(name);
}
inline atVec3d readVec3d(const char* name)
{
return readVal<atVec3d>(name);
}
inline atVec4d readVec4d(const char* name)
{
return readVal<atVec4d>(name);
}
inline std::unique_ptr<atUint8[]> readUBytes(const char* name)
{
return readVal<std::unique_ptr<atUint8[]>>(name);
@ -671,9 +759,15 @@ class YAMLDocWriter
std::vector<YAMLNode*> m_subStack;
static bool RecursiveFinish(yaml_emitter_t* doc, const YAMLNode& node);
public:
YAMLDocWriter() : m_rootNode(YAML_MAPPING_NODE)
YAMLDocWriter(const char* classType) : m_rootNode(YAML_MAPPING_NODE)
{
m_subStack.emplace_back(&m_rootNode);
if (classType)
{
YAMLNode* classVal = new YAMLNode(YAML_SCALAR_NODE);
classVal->m_scalarString.assign(classType);
m_rootNode.m_mapChildren.emplace_back("DNAType", std::unique_ptr<YAMLNode>(classVal));
}
}
void enterSubRecord(const char* name)
@ -744,7 +838,10 @@ public:
typename std::enable_if<!std::is_arithmetic<T>::value &&
!std::is_same<T, atVec2f>::value &&
!std::is_same<T, atVec3f>::value &&
!std::is_same<T, atVec4f>::value>::type* = 0)
!std::is_same<T, atVec4f>::value &&
!std::is_same<T, atVec2d>::value &&
!std::is_same<T, atVec3d>::value &&
!std::is_same<T, atVec4d>::value>::type* = 0)
{
enterSubVector(name);
for (const T& item : vector)
@ -761,7 +858,10 @@ public:
typename std::enable_if<std::is_arithmetic<T>::value ||
std::is_same<T, atVec2f>::value ||
std::is_same<T, atVec3f>::value ||
std::is_same<T, atVec4f>::value>::type* = 0)
std::is_same<T, atVec4f>::value ||
std::is_same<T, atVec2d>::value ||
std::is_same<T, atVec3d>::value ||
std::is_same<T, atVec4d>::value>::type* = 0)
{
enterSubVector(name);
for (T item : vector)
@ -891,6 +991,21 @@ public:
writeVal<atVec4f>(name, val);
}
inline void writeVec2d(const char* name, const atVec2d& val)
{
writeVal<atVec2d>(name, val);
}
inline void writeVec3d(const char* name, const atVec3d& val)
{
writeVal<atVec3d>(name, val);
}
inline void writeVec4d(const char* name, const atVec4d& val)
{
writeVal<atVec4d>(name, val);
}
inline void writeUBytes(const char* name, const std::unique_ptr<atUint8[]>& val, size_t byteCount)
{
writeVal<const std::unique_ptr<atUint8[]>&>(name, val, byteCount);
@ -936,6 +1051,8 @@ struct DNAYaml : DNA<DNAE>
{
virtual void toYAML(YAMLDocWriter& out) const=0;
virtual void fromYAML(YAMLDocReader& in)=0;
static const char* DNAType() {return nullptr;}
virtual const char* DNATypeV() const {return nullptr;}
template <size_t sizeVar>
using Buffer = struct Athena::io::BufferYaml<sizeVar, DNAE>;
@ -970,7 +1087,7 @@ struct DNAYaml : DNA<DNAE>
return std::string();
}
{
YAMLDocWriter docWriter;
YAMLDocWriter docWriter(DNATypeV());
toYAML(docWriter);
if (!docWriter.finish(&emitter))
{
@ -1013,6 +1130,22 @@ struct DNAYaml : DNA<DNAE>
return true;
}
template<class DNASubtype>
static bool ValidateFromYAMLString(const std::string& str)
{
yaml_parser_t parser;
if (!yaml_parser_initialize(&parser))
{
HandleYAMLParserError(&parser);
return false;
}
YAMLStdStringReaderState reader(str);
yaml_parser_set_input(&parser, (yaml_read_handler_t*)YAMLStdStringReader, &reader);
bool retval = YAMLDocReader::ValidateClassType(&parser, DNASubtype::DNAType());
yaml_parser_delete(&parser);
return retval;
}
bool toYAMLFile(FILE* fout) const
{
yaml_emitter_t emitter;
@ -1033,7 +1166,7 @@ struct DNAYaml : DNA<DNAE>
return false;
}
{
YAMLDocWriter docWriter;
YAMLDocWriter docWriter(DNATypeV());
toYAML(docWriter);
if (!docWriter.finish(&emitter))
{
@ -1074,6 +1207,23 @@ struct DNAYaml : DNA<DNAE>
yaml_parser_delete(&parser);
return true;
}
template<class DNASubtype>
static bool ValidateFromYAMLFile(FILE* fin)
{
yaml_parser_t parser;
if (!yaml_parser_initialize(&parser))
{
HandleYAMLParserError(&parser);
return false;
}
long pos = ftell(fin);
yaml_parser_set_input_file(&parser, fin);
bool retval = YAMLDocReader::ValidateClassType(&parser, DNASubtype::DNAType());
fseek(fin, pos, SEEK_SET);
yaml_parser_delete(&parser);
return retval;
}
};
template <size_t sizeVar, Endian VE>
@ -1160,11 +1310,15 @@ struct WStringAsStringYaml : public DNAYaml<VE>, public std::string
DECL_DNA \
void fromYAML(Athena::io::YAMLDocReader&); \
void toYAML(Athena::io::YAMLDocWriter&) const; \
static const char* DNAType(); \
const char* DNATypeV() const {return DNAType();} \
/** Macro to automatically declare YAML read/write methods with client-code's definition */
#define DECL_EXPLICIT_YAML \
void fromYAML(Athena::io::YAMLDocReader&); \
void toYAML(Athena::io::YAMLDocWriter&) const; \
static const char* DNAType(); \
const char* DNATypeV() const {return DNAType();} \
}
}

View File

@ -47,6 +47,11 @@ typedef struct stat stat64_t;
#define stat64 stat
#elif _WIN32
typedef struct _stat64 stat64_t;
#elif __FreeBSD__
typedef struct stat stat64_t;
#define stat64 stat
#define fseeko64 fseeko
#define ftello64 ftello
#else
typedef struct stat64 stat64_t;
#endif
@ -82,34 +87,6 @@ enum Endian
LittleEndian,
BigEndian
};
#ifndef ATHENA_NO_SAKURA
namespace Sakura
{
template <typename T>
class Vector2D
{
public:
T x;
T y;
Vector2D()
: x(0),
y(0)
{
}
Vector2D(T x, T y)
: x(x),
y(y)
{
}
};
typedef Vector2D<int> Vector2Di;
typedef Vector2D<float> Vector2Df;
} // Sakura
#endif // ATHENA_NO_SAKURA
} // Athena
typedef void (*atEXCEPTION_HANDLER)(const Athena::error::Level& level, const char* file, const char* function, int line, const char* fmt, ...);

View File

@ -15,86 +15,98 @@ class IStreamReader : public IStream
public:
virtual ~IStreamReader() {}
/*! \brief Sets the Endianness of the stream
/** @brief Sets the Endianness of the stream
*
* \param endian The Endianness to set \sa Endian
* @param endian The Endianness to set
*/
inline void setEndian(Endian endian)
{m_endian = endian;}
/*! \brief Returns the current Endianness of the stream
/** @brief Returns the current Endianness of the stream
*
* \return Endian The current Stream Endianness
* @return The current Stream Endianness
*/
inline Endian endian() const
{return m_endian;}
/*! \brief Returns whether the stream is BigEndian
/** @brief Returns whether the stream is BigEndian
*
* \return bool True for BigEndian; False for LittleEndian
* @return bool True for BigEndian; False for LittleEndian
*/
inline bool isBigEndian() const
{return (m_endian == Endian::BigEndian);}
/*! \brief Returns whether the stream is LittleEndian
/** @brief Returns whether the stream is LittleEndian
*
* \return bool True for LittleEndian; False for BigEndian
* @return True for LittleEndian; False for BigEndian
*/
inline bool isLittleEndian()const
{return (m_endian == Endian::LittleEndian);}
/*! \brief Sets the buffers position relative to the specified position.<br />
/** @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
* @param position where in the buffer to seek
* @param origin The Origin to seek relative to
*/
virtual void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current)=0;
/*! \brief Sets the buffers position relative to the next 32-byte aligned position.<br />
/** @brief Sets the buffers position relative to the next 32-byte aligned position.<br />
*/
inline void seekAlign32() {seek(ROUND_UP_32(position()), SeekOrigin::Begin);}
/*! \brief Returns whether or not the stream is at the end.
/** @brief Returns whether or not the stream is at the end.
*
* \return bool True if at end; False otherwise.
* @return True if at end; False otherwise.
*/
inline bool atEnd() const
{return position() >= length();}
/*! \brief Returns the current position in the stream.
/** @brief Returns the current position in the stream.
*
* \return Int64 The current position in the stream.
* @return The current position in the stream.
*/
virtual atUint64 position() const=0;
/*! \brief Returns whether or not the stream is at the end.
/** @brief Returns whether or not the stream is at the end.
*
* \return bool True if at end; False otherwise.
* @return True if at end; False otherwise.
*/
virtual atUint64 length() const=0;
/*! \brief Reads a byte at the current position and advances the current position
/** @brief Reads a byte at the current position and advances the current position
*
* \return Int8 The value at the current position
* @return The value at the current position
*/
inline atInt8 readByte() {atInt8 val; readUBytesToBuf(&val, 1); return val;}
template <class T>
inline atInt8 readVal(typename std::enable_if<std::is_same<T, atInt8>::value>::type* = 0)
{return readByte();}
template <class T>
inline atInt8 readValLittle(typename std::enable_if<std::is_same<T, atInt8>::value>::type* = 0)
{return readByte();}
template <class T>
inline atInt8 readValBig(typename std::enable_if<std::is_same<T, atInt8>::value>::type* = 0)
{return readByte();}
/*! \brief Reads a byte at the current position and advances the current position
/** @brief Reads a byte at the current position and advances the current position
*
* \return Uint8 The value at the current position
* @return The value at the current position
*/
inline atUint8 readUByte() {return readByte();}
template <class T>
inline atUint8 readVal(typename std::enable_if<std::is_same<T, atUint8>::value>::type* = 0)
{return readUByte();}
template <class T>
inline atUint8 readValLittle(typename std::enable_if<std::is_same<T, atUint8>::value>::type* = 0)
{return readUByte();}
template <class T>
inline atUint8 readValBig(typename std::enable_if<std::is_same<T, atUint8>::value>::type* = 0)
{return readUByte();}
/*! \brief Reads a byte at the current position and advances the current position.
/** @brief Reads a byte at the current position and advances the current position.
*
* \return Uint8* The buffer at the current position from the given length.
* @return The buffer at the current position from the given length.
*/
inline std::unique_ptr<atInt8[]> readBytes(atUint64 length)
{
@ -103,9 +115,9 @@ public:
return std::unique_ptr<atInt8[]>(buf);
}
/*! \brief Reads a byte at the current position and advances the current position.
/** @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.
* @return The buffer at the current position from the given length.
*/
inline std::unique_ptr<atUint8[]> readUBytes(atUint64 length)
{
@ -117,13 +129,10 @@ public:
inline atUint64 readBytesToBuf(void* buf, atUint64 len) {return readUBytesToBuf(buf, len);}
virtual atUint64 readUBytesToBuf(void* buf, atUint64 len)=0;
/*! \brief Reads a Int16 and swaps to proper endianness depending on platform
* and Stream settings, and advances the current position
/** @brief Reads a Int16 and swaps to endianness specified by setEndian depending on platform
* and advances the current position
*
* \sa Endian
*
* \return Int16 The value at the current address
* \throw IOException when address is out of range
* @return The value at the current address
*/
inline atInt16 readInt16()
{
@ -135,6 +144,11 @@ public:
inline atInt16 readVal(typename std::enable_if<std::is_same<T, atInt16>::value>::type* = 0)
{return readInt16();}
/** @brief Reads a Int16 and swaps against little endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atInt16 readInt16Little()
{
atInt16 val;
@ -145,6 +159,11 @@ public:
inline atInt16 readValLittle(typename std::enable_if<std::is_same<T, atInt16>::value>::type* = 0)
{return readInt16Little();}
/** @brief Reads a Int16 and swaps against big endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atInt16 readInt16Big()
{
atInt16 val;
@ -155,13 +174,10 @@ public:
inline atInt16 readValBig(typename std::enable_if<std::is_same<T, atInt16>::value>::type* = 0)
{return readInt16Big();}
/*! \brief Reads a Uint16 and swaps to proper endianness depending on platform
* and Stream settings, and advances the current position
/** @brief Reads a Uint16 and swaps to endianness specified by setEndian depending on platform
* and advances the current position
*
* \sa Endian
*
* \return Uint16 The value at the current address
* \throw IOException when address is out of range
* @return The value at the current address
*/
inline atUint16 readUint16()
{return readInt16();}
@ -169,6 +185,11 @@ public:
inline atUint16 readVal(typename std::enable_if<std::is_same<T, atUint16>::value>::type* = 0)
{return readUint16();}
/** @brief Reads a Uint16 and swaps against little endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atUint16 readUint16Little()
{
atUint16 val;
@ -179,6 +200,11 @@ public:
inline atUint16 readValLittle(typename std::enable_if<std::is_same<T, atUint16>::value>::type* = 0)
{return readUint16Little();}
/** @brief Reads a Uint16 and swaps against big endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atUint16 readUint16Big()
{
atUint16 val;
@ -189,13 +215,10 @@ public:
inline atUint16 readValBig(typename std::enable_if<std::is_same<T, atUint16>::value>::type* = 0)
{return readUint16Big();}
/*! \brief Reads a Int32 and swaps to proper endianness depending on platform
* and Stream settings, and advances the current position
/** @brief Reads a Int32 and swaps to endianness specified by setEndian depending on platform
* and advances the current position
*
* \sa Endian
*
* \return Int32 The value at the current address
* \throw IOException when address is out of range
* @return The value at the current address
*/
inline atInt32 readInt32()
{
@ -207,6 +230,11 @@ public:
inline atInt32 readVal(typename std::enable_if<std::is_same<T, atInt32>::value>::type* = 0)
{return readInt32();}
/** @brief Reads a Int32 and swaps against little endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atInt32 readInt32Little()
{
atInt32 val;
@ -217,6 +245,11 @@ public:
inline atInt32 readValLittle(typename std::enable_if<std::is_same<T, atInt32>::value>::type* = 0)
{return readInt32Little();}
/** @brief Reads a Int32 and swaps against big endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atInt32 readInt32Big()
{
atInt32 val;
@ -227,13 +260,10 @@ public:
inline atInt32 readValBig(typename std::enable_if<std::is_same<T, atInt32>::value>::type* = 0)
{return readInt32Big();}
/*! \brief Reads a Uint32 and swaps to proper endianness depending on platform
* and Stream settings, and advances the current position
/** @brief Reads a Uint32 and swaps to endianness specified by setEndian depending on platform
* and advances the current position
*
* \sa Endian
*
* \return Uint32 The value at the current address
* \throw IOException when address is out of range
* @return The value at the current address
*/
inline atUint32 readUint32()
{return readInt32();}
@ -241,6 +271,11 @@ public:
inline atUint32 readVal(typename std::enable_if<std::is_same<T, atUint32>::value>::type* = 0)
{return readUint32();}
/** @brief Reads a Uint32 and swaps against little endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atUint32 readUint32Little()
{
atUint32 val;
@ -251,6 +286,11 @@ public:
inline atInt32 readValLittle(typename std::enable_if<std::is_same<T, atUint32>::value>::type* = 0)
{return readUint32Little();}
/** @brief Reads a Uint32 and swaps against big endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atUint32 readUint32Big()
{
atUint32 val;
@ -261,13 +301,10 @@ public:
inline atUint32 readValBig(typename std::enable_if<std::is_same<T, atUint32>::value>::type* = 0)
{return readUint32Big();}
/*! \brief Reads a Int64 and swaps to proper endianness depending on platform
* and Stream settings, and advances the current position
/** @brief Reads a Int64 and swaps to endianness specified by setEndian depending on platform
* and advances the current position
*
* \sa Endian
*
* \return Int64 The value at the current address
* \throw IOException when address is out of range
* @return The value at the current address
*/
inline atInt64 readInt64()
{
@ -279,6 +316,11 @@ public:
inline atInt64 readVal(typename std::enable_if<std::is_same<T, atInt64>::value>::type* = 0)
{return readInt64();}
/** @brief Reads a Int64 and swaps against little endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atInt64 readInt64Little()
{
atInt64 val;
@ -289,6 +331,11 @@ public:
inline atInt64 readValLittle(typename std::enable_if<std::is_same<T, atInt64>::value>::type* = 0)
{return readInt64Little();}
/** @brief Reads a Int64 and swaps against big endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atInt64 readInt64Big()
{
atInt64 val;
@ -299,13 +346,10 @@ public:
inline atInt64 readValBig(typename std::enable_if<std::is_same<T, atInt64>::value>::type* = 0)
{return readInt64Big();}
/*! \brief Reads a Uint64 and swaps to proper endianness depending on platform
* and Stream settings, and advances the current position
/** @brief Reads a Uint64 and swaps to endianness specified by setEndian depending on platform
* and advances the current position
*
* \sa Endian
*
* \return Uint64 The value at the current address
* \throw IOException when address is out of range
* @return The value at the current address
*/
inline atUint64 readUint64()
{return readInt64();}
@ -313,6 +357,11 @@ public:
inline atUint64 readVal(typename std::enable_if<std::is_same<T, atUint64>::value>::type* = 0)
{return readUint64();}
/** @brief Reads a Uint64 and swaps against little endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atUint64 readUint64Little()
{
atUint64 val;
@ -323,6 +372,11 @@ public:
inline atUint64 readValLittle(typename std::enable_if<std::is_same<T, atUint64>::value>::type* = 0)
{return readUint64Little();}
/** @brief Reads a Uint64 and swaps against big endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atUint64 readUint64Big()
{
atUint64 val;
@ -333,13 +387,10 @@ public:
inline atUint64 readValBig(typename std::enable_if<std::is_same<T, atUint64>::value>::type* = 0)
{return readUint64Big();}
/*! \brief Reads a float and swaps to proper endianness depending on platform
* and Stream settings, and advances the current position
/** @brief Reads a float and swaps to endianness specified by setEndian depending on platform
* and advances the current position
*
* \sa Endian
*
* \return float The value at the current address
* \throw IOException when address is out of range
* @return The value at the current address
*/
inline float readFloat()
{
@ -351,6 +402,11 @@ public:
inline float readVal(typename std::enable_if<std::is_same<T, float>::value>::type* = 0)
{return readFloat();}
/** @brief Reads a float and swaps against little endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline float readFloatLittle()
{
float val;
@ -361,6 +417,11 @@ public:
inline float readValLittle(typename std::enable_if<std::is_same<T, float>::value>::type* = 0)
{return readFloatLittle();}
/** @brief Reads a float and swaps against big endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline float readFloatBig()
{
float val;
@ -371,13 +432,10 @@ public:
inline float readValBig(typename std::enable_if<std::is_same<T, float>::value>::type* = 0)
{return readFloatBig();}
/*! \brief Reads a double and swaps to proper endianness depending on platform
* and Stream settings, and advances the current position
/** @brief Reads a double and swaps to endianness specified by setEndian depending on platform
* and advances the current position
*
* \sa Endian
*
* \return double The value at the current address
* \throw IOException when address is out of range
* @return The value at the current address
*/
inline double readDouble()
{
@ -389,6 +447,11 @@ public:
inline double readVal(typename std::enable_if<std::is_same<T, double>::value>::type* = 0)
{return readDouble();}
/** @brief Reads a double and swaps against little endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline double readDoubleLittle()
{
double val;
@ -399,6 +462,11 @@ public:
inline double readValLittle(typename std::enable_if<std::is_same<T, double>::value>::type* = 0)
{return readDoubleLittle();}
/** @brief Reads a double and swaps against big endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline double readDoubleBig()
{
double val;
@ -409,10 +477,9 @@ public:
inline double readValBig(typename std::enable_if<std::is_same<T, double>::value>::type* = 0)
{return readDoubleBig();}
/*! \brief Reads a bool and advances the current position
/** @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
* @return The value at the current address
*/
inline bool readBool()
{
@ -423,11 +490,17 @@ public:
template <class T>
inline bool readVal(typename std::enable_if<std::is_same<T, bool>::value>::type* = 0)
{return readBool();}
template <class T>
inline bool readValLittle(typename std::enable_if<std::is_same<T, bool>::value>::type* = 0)
{return readBool();}
template <class T>
inline bool readValBig(typename std::enable_if<std::is_same<T, bool>::value>::type* = 0)
{return readBool();}
/*! \brief Reads an atVec2f (8 bytes) and advances the current position
/** @brief Reads an atVec2f (8 bytes), swaps to endianness specified by setEndian depending on platform
* and advances the current position
*
* \return atVec2f The value at the current address
* \throw IOException when address is out of range
* @return The value at the current address
*/
inline atVec2f readVec2f()
{
@ -449,6 +522,11 @@ public:
inline atVec2f readVal(typename std::enable_if<std::is_same<T, atVec2f>::value>::type* = 0)
{return readVec2f();}
/** @brief Reads an atVec2f (8 bytes), swaps against little endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atVec2f readVec2fLittle()
{
atVec2f val;
@ -461,6 +539,11 @@ public:
inline atVec2f readValLittle(typename std::enable_if<std::is_same<T, atVec2f>::value>::type* = 0)
{return readVec2fLittle();}
/** @brief Reads an atVec2f (8 bytes), swaps against big endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atVec2f readVec2fBig()
{
atVec2f val;
@ -473,10 +556,10 @@ public:
inline atVec2f readValBig(typename std::enable_if<std::is_same<T, atVec2f>::value>::type* = 0)
{return readVec2fBig();}
/*! \brief Reads an atVec3f (12 bytes) and advances the current position
/** @brief Reads an atVec3f (12 bytes), swaps to endianness specified by setEndian depending on platform
* and advances the current position
*
* \return atVec3f The value at the current address
* \throw IOException when address is out of range
* @return The value at the current address
*/
inline atVec3f readVec3f()
{
@ -500,6 +583,11 @@ public:
inline atVec3f readVal(typename std::enable_if<std::is_same<T, atVec3f>::value>::type* = 0)
{return readVec3f();}
/** @brief Reads an atVec3f (12 bytes), swaps against little endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atVec3f readVec3fLittle()
{
atVec3f val;
@ -513,6 +601,11 @@ public:
inline atVec3f readValLittle(typename std::enable_if<std::is_same<T, atVec3f>::value>::type* = 0)
{return readVec3fLittle();}
/** @brief Reads an atVec3f (12 bytes), swaps against big endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atVec3f readVec3fBig()
{
atVec3f val;
@ -526,10 +619,10 @@ public:
inline atVec3f readValBig(typename std::enable_if<std::is_same<T, atVec3f>::value>::type* = 0)
{return readVec3fBig();}
/*! \brief Reads an atVec4f (16 bytes) and advances the current position
/** @brief Reads an atVec4f (16 bytes), swaps to endianness specified by setEndian depending on platform
* and advances the current position
*
* \return atVec4f The value at the current address
* \throw IOException when address is out of range
* @return The value at the current address
*/
inline atVec4f readVec4f()
{
@ -555,6 +648,11 @@ public:
inline atVec4f readVal(typename std::enable_if<std::is_same<T, atVec4f>::value>::type* = 0)
{return readVec4f();}
/** @brief Reads an atVec4f (16 bytes), swaps against little endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atVec4f readVec4fLittle()
{
atVec4f val;
@ -569,6 +667,11 @@ public:
inline atVec4f readValLittle(typename std::enable_if<std::is_same<T, atVec4f>::value>::type* = 0)
{return readVec4fLittle();}
/** @brief Reads an atVec4f (16 bytes), swaps against big endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atVec4f readVec4fBig()
{
atVec4f val;
@ -583,11 +686,200 @@ public:
inline atVec4f readValBig(typename std::enable_if<std::is_same<T, atVec4f>::value>::type* = 0)
{return readVec4fBig();}
/*! \brief Reads a wide-char string, converts to UTF8 and advances the position in the file
/** @brief Reads an atVec2d (16 bytes), swaps to endianness specified by setEndian depending on platform
* and advances the current position
*
* \param fixedLen If non-negative, this is a fixed-length string read
* \return std::string The value at the current address
* \throw IOException when address is out of range
* @return The value at the current address
*/
inline atVec2d readVec2d()
{
atVec2d val;
readUBytesToBuf(&val, 16);
if (m_endian == BigEndian)
{
utility::BigDouble(val.vec[0]);
utility::BigDouble(val.vec[1]);
}
else
{
utility::LittleDouble(val.vec[0]);
utility::LittleDouble(val.vec[1]);
}
return val;
}
template <class T>
inline atVec2d readVal(typename std::enable_if<std::is_same<T, atVec2d>::value>::type* = 0)
{return readVec2d();}
/** @brief Reads an atVec2d (16 bytes), swaps against little endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atVec2d readVec2dLittle()
{
atVec2d val;
readUBytesToBuf(&val, 16);
utility::LittleDouble(val.vec[0]);
utility::LittleDouble(val.vec[1]);
return val;
}
template <class T>
inline atVec2d readValLittle(typename std::enable_if<std::is_same<T, atVec2d>::value>::type* = 0)
{return readVec2dLittle();}
/** @brief Reads an atVec2d (16 bytes), swaps against big endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atVec2d readVec2dBig()
{
atVec2d val;
readUBytesToBuf(&val, 16);
utility::BigDouble(val.vec[0]);
utility::BigDouble(val.vec[1]);
return val;
}
template <class T>
inline atVec2d readValBig(typename std::enable_if<std::is_same<T, atVec2d>::value>::type* = 0)
{return readVec2dBig();}
/** @brief Reads an atVec3d (24 bytes), swaps to endianness specified by setEndian depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atVec3d readVec3d()
{
atVec3d val;
readUBytesToBuf(&val, 24);
if (m_endian == BigEndian)
{
utility::BigDouble(val.vec[0]);
utility::BigDouble(val.vec[1]);
utility::BigDouble(val.vec[2]);
}
else
{
utility::LittleDouble(val.vec[0]);
utility::LittleDouble(val.vec[1]);
utility::LittleDouble(val.vec[2]);
}
return val;
}
template <class T>
inline atVec3d readVal(typename std::enable_if<std::is_same<T, atVec3d>::value>::type* = 0)
{return readVec3d();}
/** @brief Reads an atVec3d (24 bytes), swaps against little endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atVec3d readVec3dLittle()
{
atVec3d val;
readUBytesToBuf(&val, 24);
utility::LittleDouble(val.vec[0]);
utility::LittleDouble(val.vec[1]);
utility::LittleDouble(val.vec[2]);
return val;
}
template <class T>
inline atVec3d readValLittle(typename std::enable_if<std::is_same<T, atVec3d>::value>::type* = 0)
{return readVec3dLittle();}
/** @brief Reads an atVec3d (24 bytes), swaps against big endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atVec3d readVec3dBig()
{
atVec3d val;
readUBytesToBuf(&val, 24);
utility::BigDouble(val.vec[0]);
utility::BigDouble(val.vec[1]);
utility::BigDouble(val.vec[2]);
return val;
}
template <class T>
inline atVec3d readValBig(typename std::enable_if<std::is_same<T, atVec3d>::value>::type* = 0)
{return readVec3dBig();}
/** @brief Reads an atVec4d (32 bytes), swaps to endianness specified by setEndian depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atVec4d readVec4d()
{
atVec4d val;
readUBytesToBuf(&val, 32);
if (m_endian == BigEndian)
{
utility::BigDouble(val.vec[0]);
utility::BigDouble(val.vec[1]);
utility::BigDouble(val.vec[2]);
utility::BigDouble(val.vec[3]);
}
else
{
utility::LittleDouble(val.vec[0]);
utility::LittleDouble(val.vec[1]);
utility::LittleDouble(val.vec[2]);
utility::LittleDouble(val.vec[3]);
}
return val;
}
template <class T>
inline atVec4d readVal(typename std::enable_if<std::is_same<T, atVec4d>::value>::type* = 0)
{return readVec4d();}
/** @brief Reads an atVec4d (32 bytes), swaps against little endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atVec4d readVec4dLittle()
{
atVec4d val;
readUBytesToBuf(&val, 32);
utility::LittleDouble(val.vec[0]);
utility::LittleDouble(val.vec[1]);
utility::LittleDouble(val.vec[2]);
utility::LittleDouble(val.vec[3]);
return val;
}
template <class T>
inline atVec4d readValLittle(typename std::enable_if<std::is_same<T, atVec4d>::value>::type* = 0)
{return readVec4dLittle();}
/** @brief Reads an atVec4d (32 bytes), swaps against big endianness depending on platform
* and advances the current position
*
* @return The value at the current address
*/
inline atVec4d readVec4dBig()
{
atVec4d val;
readUBytesToBuf(&val, 32);
utility::BigDouble(val.vec[0]);
utility::BigDouble(val.vec[1]);
utility::BigDouble(val.vec[2]);
utility::BigDouble(val.vec[3]);
return val;
}
template <class T>
inline atVec4d readValBig(typename std::enable_if<std::is_same<T, atVec4d>::value>::type* = 0)
{return readVec4dBig();}
/** @brief Reads a wide-char string (using endianness from setEndian),
* converts to UTF8 and advances the position in the file
*
* @param fixedLen If non-negative, this is a fixed-length string read
* @return The read string
*/
inline std::string readWStringAsString(atInt32 fixedLen = -1)
{
@ -621,6 +913,12 @@ public:
return retval;
}
/** @brief Reads a wide-char string (against little-endian),
* converts to UTF8 and advances the position in the file
*
* @param fixedLen If non-negative, this is a fixed-length string read
* @return The read string
*/
inline std::string readWStringAsStringLittle(atInt32 fixedLen = -1)
{
std::string retval;
@ -653,6 +951,12 @@ public:
return retval;
}
/** @brief Reads a wide-char string (against big-endian),
* converts to UTF8 and advances the position in the file
*
* @param fixedLen If non-negative, this is a fixed-length string read
* @return The read string
*/
inline std::string readWStringAsStringBig(atInt32 fixedLen = -1)
{
std::string retval;
@ -685,11 +989,10 @@ public:
return retval;
}
/*! \brief Reads a string and advances the position in the file
/** @brief Reads a string and advances the position in the file
*
* \param fixedLen If non-negative, this is a fixed-length string read
* \return std::string The value at the current address
* \throw IOException when address is out of range
* @param fixedLen If non-negative, this is a fixed-length string read
* @return The read string
*/
inline std::string readString(atInt32 fixedLen = -1)
{
@ -716,11 +1019,10 @@ public:
inline std::string readVal(typename std::enable_if<std::is_same<T, std::string>::value>::type* = 0)
{return readString();}
/*! \brief Reads a wstring and advances the position in the file
/** @brief Reads a wstring and advances the position in the file
*
* \param fixedLen If non-negative, this is a fixed-length string read
* \return std::wstring The value at the current address
* \throw IOException when address is out of range
* @param fixedLen If non-negative, this is a fixed-length string read
* @return The read wstring
*/
inline std::wstring readWString(atInt32 fixedLen = -1)
{
@ -747,6 +1049,12 @@ public:
inline std::wstring readVal(typename std::enable_if<std::is_same<T, std::wstring>::value>::type* = 0)
{return readWString();}
/** @brief Reads a wstring assuming little-endian characters
* and advances the position in the file
*
* @param fixedLen If non-negative, this is a fixed-length string read
* @return The read wstring
*/
inline std::wstring readWStringLittle(atInt32 fixedLen = -1)
{
std::wstring ret;
@ -772,6 +1080,12 @@ public:
inline std::wstring readValLittle(typename std::enable_if<std::is_same<T, std::wstring>::value>::type* = 0)
{return readWStringLittle();}
/** @brief Reads a wstring assuming big-endian characters
* and advances the position in the file
*
* @param fixedLen If non-negative, this is a fixed-length string read
* @return The read wstring
*/
inline std::wstring readWStringBig(atInt32 fixedLen = -1)
{
std::wstring ret;
@ -797,6 +1111,13 @@ public:
inline std::wstring readValBig(typename std::enable_if<std::is_same<T, std::wstring>::value>::type* = 0)
{return readWStringBig();}
/** @brief Performs automatic std::vector enumeration reads using numeric type T
*
* @param vector The std::vector to clear and populate using read data
* @param count The number of elements to read into vector
*
* Endianness is set with setEndian
*/
template<class T>
void enumerate(std::vector<T>& vector, size_t count,
typename std::enable_if<std::is_arithmetic<T>::value ||
@ -807,9 +1128,16 @@ public:
vector.clear();
vector.reserve(count);
for (size_t i=0 ; i<count ; ++i)
vector.emplace_back(readVal<T>());
vector.push_back(readVal<T>());
}
/** @brief Performs automatic std::vector enumeration reads using numeric type T
*
* @param vector The std::vector to clear and populate using read data
* @param count The number of elements to read into vector
*
* Endianness is little
*/
template<class T>
void enumerateLittle(std::vector<T>& vector, size_t count,
typename std::enable_if<std::is_arithmetic<T>::value ||
@ -820,9 +1148,16 @@ public:
vector.clear();
vector.reserve(count);
for (size_t i=0 ; i<count ; ++i)
vector.emplace_back(readValLittle<T>());
vector.push_back(readValLittle<T>());
}
/** @brief Performs automatic std::vector enumeration reads using numeric type T
*
* @param vector The std::vector to clear and populate using read data
* @param count The number of elements to read into vector
*
* Endianness is big
*/
template<class T>
void enumerateBig(std::vector<T>& vector, size_t count,
typename std::enable_if<std::is_arithmetic<T>::value ||
@ -833,9 +1168,14 @@ public:
vector.clear();
vector.reserve(count);
for (size_t i=0 ; i<count ; ++i)
vector.emplace_back(readValBig<T>());
vector.push_back(readValBig<T>());
}
/** @brief Performs automatic std::vector enumeration reads using non-numeric type T
*
* @param vector The std::vector to clear and populate using read data
* @param count The number of elements to read into vector
*/
template<class T>
void enumerate(std::vector<T>& vector, size_t count,
typename std::enable_if<!std::is_arithmetic<T>::value &&
@ -852,6 +1192,13 @@ public:
}
}
/** @brief Performs lambda-assisted std::vector enumeration reads using type T
*
* @param vector The std::vector to clear and populate using read data
* @param count The number of elements to read into vector
* @param readf Function (e.g. a lambda) that reads *one* element and
* assigns the value through the second argument
*/
template<class T>
void enumerate(std::vector<T>& vector, size_t count, std::function<void(IStreamReader&, T&)> readf)
{
@ -867,6 +1214,12 @@ public:
protected:
Endian m_endian;
};
template <typename T>
IStreamReader& operator>>(IStreamReader& lhs, T& rhs)
{
rhs = lhs.readVal<T>(rhs);
return lhs;
}
}
}
#endif // ISTREAMREADER

View File

@ -12,97 +12,99 @@ class IStreamWriter : public IStream
{
public:
virtual ~IStreamWriter() {}
/*! \brief Sets the Endianness of the stream
/** @brief Sets the Endianness of the stream
*
* \param endian The Endianness to set \sa Endian
* @param endian The Endianness to set
*/
inline void setEndian(Endian endian)
{m_endian = endian;}
/*! \brief Returns the current Endianness of the stream
/** @brief Returns the current Endianness of the stream
*
* \return Endian The current Stream Endianness
* @return The current Stream Endianness
*/
inline Endian endian() const
{return m_endian;}
/*! \brief Returns whether the stream is BigEndian
/** @brief Returns whether the stream is BigEndian
*
* \return bool True for BigEndian; False for LittleEndian
* @return True for BigEndian; False for LittleEndian
*/
inline bool isBigEndian() const
{return (m_endian == Endian::BigEndian);}
/*! \brief Returns whether the stream is LittleEndian
/** @brief Returns whether the stream is LittleEndian
*
* \return bool True for LittleEndian; False for BigEndian
* @return True for LittleEndian; False for BigEndian
*/
inline bool isLittleEndian() const
{return (m_endian == Endian::LittleEndian);}
/*! \brief Sets the buffers position relative to the specified position.<br />
/** @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
* @param position where in the buffer to seek
* @param origin The location to seek relative to
*/
virtual void seek(atInt64 pos, SeekOrigin origin = SeekOrigin::Current)=0;
/*! \brief Sets the buffers position relative to the next 32-byte aligned position.<br />
/** @brief Sets the buffers position relative to the next 32-byte aligned position.<br />
*/
inline void seekAlign32() {seek(ROUND_UP_32(position()), SeekOrigin::Begin);}
/*! \brief Returns whether or not the stream is at the end.
/** @brief Returns whether or not the stream is at the end.
*
* \return bool True if at end; False otherwise.
* @return True if at end; False otherwise.
*/
inline bool atEnd() const {return position() >= length();}
/*! \brief Returns the current position in the stream.
/** @brief Returns the current position in the stream.
*
* \return Int64 The current position in the stream.
* @return The current position in the stream.
*/
virtual atUint64 position() const=0;
/*! \brief Returns whether or not the stream is at the end.
/** @brief Returns whether or not the stream is at the end.
*
* \return bool True if at end; False otherwise.
* @return True if at end; False otherwise.
*/
virtual atUint64 length() const=0;
/*! \brief Writes a byte at the current position and advances the position by one byte.
* \param byte The value to write
/** @brief Writes a byte at the current position and advances the position by one byte.
* @param val The value to write
*/
inline void writeUByte(atUint8 val) {writeUBytes(&val, 1);}
inline void writeVal(atUint8 val) {return writeUByte(val);}
inline void writeVal(atUint8 val) {writeUByte(val);}
inline void writeValLittle(atUint8 val) {writeUByte(val);}
inline void writeValBig(atUint8 val) {writeUByte(val);}
/*! \brief Writes a byte at the current position and advances the position by one byte.
* \param byte The value to write
* \throw IOException
/** @brief Writes a byte at the current position and advances the position by one byte.
* @param val The value to write
*/
inline void writeByte(atInt8 val) {writeUByte(val);}
inline void writeVal(atInt8 val) {return writeByte(val);}
inline void writeVal(atInt8 val) {writeByte(val);}
inline void writeValLittle(atInt8 val) {writeByte(val);}
inline void writeValBig(atInt8 val) {writeByte(val);}
/*! \brief Writes the given buffer with the specified length, buffers can be bigger than the length
/** @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
* @param data The buffer to write
* @param length The amount to write
*/
virtual void writeUBytes(const atUint8* data, atUint64 len)=0;
/*! \brief Writes the given buffer with the specified length, buffers can be bigger than the length
/** @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
* @param data The buffer to write
* @param length The amount to write
*/
inline void writeBytes(const atInt8* data, atUint64 len) {writeUBytes((atUint8*)data, len);}
/*! \brief Writes an Int16 to the buffer and advances the buffer.
/** @brief Writes an Int16 to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* \sa Endian
* \param val The value to write to the buffer
* @param val The value to write to the buffer
*/
inline void writeInt16(atInt16 val)
{
@ -112,42 +114,60 @@ public:
utility::LittleInt16(val);
writeUBytes((atUint8*)&val, 2);
}
inline void writeVal(atInt16 val) {return writeInt16(val);}
inline void writeVal(atInt16 val) {writeInt16(val);}
/** @brief Writes an Int16 to the buffer and advances the buffer.
* It also swaps the bytes against little depending on the platform.
*
* @param val The value to write to the buffer
*/
inline void writeInt16Little(atInt16 val)
{
utility::LittleInt16(val);
writeUBytes((atUint8*)&val, 2);
}
inline void writeValLittle(atInt16 val) {return writeInt16Little(val);}
inline void writeValLittle(atInt16 val) {writeInt16Little(val);}
/** @brief Writes an Int16 to the buffer and advances the buffer.
* It also swaps the bytes against big depending on the platform.
*
* @param val The value to write to the buffer
*/
inline void writeInt16Big(atInt16 val)
{
utility::BigInt16(val);
writeUBytes((atUint8*)&val, 2);
}
inline void writeValBig(atInt16 val) {return writeInt16Big(val);}
inline void writeValBig(atInt16 val) {writeInt16Big(val);}
/*! \brief Writes an Uint16 to the buffer and advances the buffer.
/** @brief Writes an Uint16 to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings
*
* \sa Endian
* \param val The value to write to the buffer
* @param val The value to write to the buffer
*/
inline void writeUint16(atUint16 val) {writeInt16(val);}
inline void writeVal(atUint16 val) {return writeUint16(val);}
inline void writeVal(atUint16 val) {writeUint16(val);}
/** @brief Writes an Uint16 to the buffer and advances the buffer.
* It also swaps the bytes against little depending on the platform
*
* @param val The value to write to the buffer
*/
inline void writeUint16Little(atUint16 val) {writeInt16Little(val);}
inline void writeValLittle(atUint16 val) {return writeUint16Little(val);}
inline void writeValLittle(atUint16 val) {writeUint16Little(val);}
/** @brief Writes an Uint16 to the buffer and advances the buffer.
* It also swaps the bytes against big depending on the platform
*
* @param val The value to write to the buffer
*/
inline void writeUint16Big(atUint16 val) {writeInt16Big(val);}
inline void writeValBig(atUint16 val) {return writeUint16Big(val);}
inline void writeValBig(atUint16 val) {writeUint16Big(val);}
/*! \brief Writes an Int32 to the buffer and advances the buffer.
/** @brief Writes an Int32 to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* \sa Endian
* \param val The value to write to the buffer
* @param val The value to write to the buffer
*/
inline void writeInt32(atInt32 val)
{
@ -157,42 +177,60 @@ public:
utility::LittleInt32(val);
writeUBytes((atUint8*)&val, 4);
}
inline void writeVal(atInt32 val) {return writeInt32(val);}
inline void writeVal(atInt32 val) {writeInt32(val);}
/** @brief Writes an Int32 to the buffer and advances the buffer.
* It also swaps the bytes against little depending on the platform.
*
* @param val The value to write to the buffer
*/
inline void writeInt32Little(atInt32 val)
{
utility::LittleInt32(val);
writeUBytes((atUint8*)&val, 4);
}
inline void writeValLittle(atInt32 val) {return writeInt32Little(val);}
inline void writeValLittle(atInt32 val) {writeInt32Little(val);}
/** @brief Writes an Int32 to the buffer and advances the buffer.
* It also swaps the bytes against big depending on the platform.
*
* @param val The value to write to the buffer
*/
inline void writeInt32Big(atInt32 val)
{
utility::BigInt32(val);
writeUBytes((atUint8*)&val, 4);
}
inline void writeValBig(atInt32 val) {return writeInt32Big(val);}
inline void writeValBig(atInt32 val) {writeInt32Big(val);}
/*! \brief Writes an Uint32 to the buffer and advances the buffer.
/** @brief Writes an Uint32 to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* \sa Endian
* \param val The value to write to the buffer
* @param val The value to write to the buffer
*/
inline void writeUint32(atUint32 val) {writeInt32(val);}
inline void writeVal(atUint32 val) {return writeUint32(val);}
inline void writeVal(atUint32 val) {writeUint32(val);}
/** @brief Writes an Uint32 to the buffer and advances the buffer.
* It also swaps the bytes against little depending on the platform.
*
* @param val The value to write to the buffer
*/
inline void writeUint32Little(atUint32 val) {writeInt32Little(val);}
inline void writeValLittle(atUint32 val) {return writeUint32Little(val);}
inline void writeValLittle(atUint32 val) {writeUint32Little(val);}
/** @brief Writes an Uint32 to the buffer and advances the buffer.
* It also swaps the bytes against big depending on the platform.
*
* @param val The value to write to the buffer
*/
inline void writeUint32Big(atUint32 val) {writeInt32Big(val);}
inline void writeValBig(atUint32 val) {return writeUint32Big(val);}
inline void writeValBig(atUint32 val) {writeUint32Big(val);}
/*! \brief Writes an Int64 to the buffer and advances the buffer.
/** @brief Writes an Int64 to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* \sa Endian
* \param val The value to write to the buffer
* @param val The value to write to the buffer
*/
inline void writeInt64(atInt64 val)
{
@ -202,42 +240,60 @@ public:
utility::LittleInt64(val);
writeUBytes((atUint8*)&val, 8);
}
inline void writeVal(atInt64 val) {return writeInt64(val);}
inline void writeVal(atInt64 val) {writeInt64(val);}
/** @brief Writes an Int64 to the buffer and advances the buffer.
* It also swaps the bytes against little depending on the platform.
*
* @param val The value to write to the buffer
*/
inline void writeInt64Little(atInt64 val)
{
utility::LittleInt64(val);
writeUBytes((atUint8*)&val, 8);
}
inline void writeValLittle(atInt64 val) {return writeInt64Little(val);}
inline void writeValLittle(atInt64 val) {writeInt64Little(val);}
/** @brief Writes an Int64 to the buffer and advances the buffer.
* It also swaps the bytes against big depending on the platform.
*
* @param val The value to write to the buffer
*/
inline void writeInt64Big(atInt64 val)
{
utility::BigInt64(val);
writeUBytes((atUint8*)&val, 8);
}
inline void writeValBig(atInt64 val) {return writeInt64Big(val);}
inline void writeValBig(atInt64 val) {writeInt64Big(val);}
/*! \brief Writes an Uint64 to the buffer and advances the buffer.
/** @brief Writes an Uint64 to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* \sa Endian
* \param val The value to write to the buffer
* @param val The value to write to the buffer
*/
inline void writeUint64(atUint64 val) {writeInt64(val);}
inline void writeVal(atUint64 val) {return writeUint64(val);}
inline void writeVal(atUint64 val) {writeUint64(val);}
/** @brief Writes an Uint64 to the buffer and advances the buffer.
* It also swaps the bytes against little depending on the platform.
*
* @param val The value to write to the buffer
*/
inline void writeUint64Little(atUint64 val) {writeInt64Little(val);}
inline void writeValLittle(atUint64 val) {return writeUint64Little(val);}
inline void writeValLittle(atUint64 val) {writeUint64Little(val);}
/** @brief Writes an Uint64 to the buffer and advances the buffer.
* It also swaps the bytes against big depending on the platform.
*
* @param val The value to write to the buffer
*/
inline void writeUint64Big(atUint64 val) {writeInt64Big(val);}
inline void writeValBig(atUint64 val) {return writeUint64Big(val);}
inline void writeValBig(atUint64 val) {writeUint64Big(val);}
/*! \brief Writes an float to the buffer and advances the buffer.
/** @brief Writes an float to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* \sa Endian
* \param val The value to write to the buffer
* @param val The value to write to the buffer
*/
inline void writeFloat(float val)
{
@ -247,27 +303,36 @@ public:
utility::LittleFloat(val);
writeUBytes((atUint8*)&val, 4);
}
inline void writeVal(float val) {return writeFloat(val);}
inline void writeVal(float val) {writeFloat(val);}
/** @brief Writes an float to the buffer and advances the buffer.
* It also swaps the bytes against little depending on the platform.
*
* @param val The value to write to the buffer
*/
inline void writeFloatLittle(float val)
{
utility::LittleFloat(val);
writeUBytes((atUint8*)&val, 4);
}
inline void writeValLittle(float val) {return writeFloatLittle(val);}
inline void writeValLittle(float val) {writeFloatLittle(val);}
/** @brief Writes an float to the buffer and advances the buffer.
* It also swaps the bytes against big depending on the platform.
*
* @param val The value to write to the buffer
*/
inline void writeFloatBig(float val)
{
utility::BigFloat(val);
writeUBytes((atUint8*)&val, 4);
}
inline void writeValBig(float val) {return writeFloatBig(val);}
inline void writeValBig(float val) {writeFloatBig(val);}
/*! \brief Writes an double to the buffer and advances the buffer.
/** @brief Writes an double to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* \sa Endian
* \param val The value to write to the buffer
* @param val The value to write to the buffer
*/
inline void writeDouble(double val)
{
@ -277,36 +342,46 @@ public:
utility::LittleDouble(val);
writeUBytes((atUint8*)&val, 8);
}
inline void writeVal(double val) {return writeDouble(val);}
inline void writeVal(double val) {writeDouble(val);}
/** @brief Writes an double to the buffer and advances the buffer.
* It also swaps the bytes against little depending on the platform.
*
* @param val The value to write to the buffer
*/
inline void writeDoubleLittle(double val)
{
utility::LittleDouble(val);
writeUBytes((atUint8*)&val, 8);
}
inline void writeValLittle(double val) {return writeDoubleLittle(val);}
inline void writeValLittle(double val) {writeDoubleLittle(val);}
/** @brief Writes an double to the buffer and advances the buffer.
* It also swaps the bytes against big depending on the platform.
*
* @param val The value to write to the buffer
*/
inline void writeDoubleBig(double val)
{
utility::BigDouble(val);
writeUBytes((atUint8*)&val, 8);
}
inline void writeValBig(double val) {return writeDoubleBig(val);}
inline void writeValBig(double val) {writeDoubleBig(val);}
/*! \brief Writes an bool to the buffer and advances the buffer.
/** @brief Writes an bool to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* \sa Endian
* \param val The value to write to the buffer
* @param val The value to write to the buffer
*/
inline void writeBool(bool val) {writeUBytes((atUint8*)&val, 1);}
inline void writeVal(bool val) {return writeBool(val);}
inline void writeVal(bool val) {writeBool(val);}
inline void writeValLittle(bool val) {writeBool(val);}
inline void writeValBig(bool val) {writeBool(val);}
/*! \brief Writes an atVec2f (8 bytes) to the buffer and advances the buffer.
/** @brief Writes an atVec2f (8 bytes) to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* \sa Endian
* \param vec The value to write to the buffer
* @param vec The value to write to the buffer
*/
inline void writeVec2f(atVec2f vec)
{
@ -322,29 +397,38 @@ public:
}
writeUBytes((atUint8*)&vec, 8);
}
inline void writeVal(atVec2f val) {return writeVec2f(val);}
inline void writeVal(atVec2f val) {writeVec2f(val);}
/** @brief Writes an atVec2f (8 bytes) to the buffer and advances the buffer.
* It also swaps the bytes against little depending on the platform.
*
* @param vec The value to write to the buffer
*/
inline void writeVec2fLittle(atVec2f vec)
{
utility::LittleFloat(vec.vec[0]);
utility::LittleFloat(vec.vec[1]);
writeUBytes((atUint8*)&vec, 8);
}
inline void writeValLittle(atVec2f val) {return writeVec2fLittle(val);}
inline void writeValLittle(atVec2f val) {writeVec2fLittle(val);}
/** @brief Writes an atVec2f (8 bytes) to the buffer and advances the buffer.
* It also swaps the bytes against big depending on the platform.
*
* @param vec The value to write to the buffer
*/
inline void writeVec2fBig(atVec2f vec)
{
utility::BigFloat(vec.vec[0]);
utility::BigFloat(vec.vec[1]);
writeUBytes((atUint8*)&vec, 8);
}
inline void writeValBig(atVec2f val) {return writeVec2fBig(val);}
inline void writeValBig(atVec2f val) {writeVec2fBig(val);}
/*! \brief Writes an atVec3f (12 bytes) to the buffer and advances the buffer.
/** @brief Writes an atVec3f (12 bytes) to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* \sa Endian
* \param vec The value to write to the buffer
* @param vec The value to write to the buffer
*/
inline void writeVec3f(atVec3f vec)
{
@ -362,8 +446,13 @@ public:
}
writeUBytes((atUint8*)&vec, 12);
}
inline void writeVal(atVec3f val) {return writeVec3f(val);}
inline void writeVal(atVec3f val) {writeVec3f(val);}
/** @brief Writes an atVec3f (12 bytes) to the buffer and advances the buffer.
* It also swaps the bytes against little depending on the platform.
*
* @param vec The value to write to the buffer
*/
inline void writeVec3fLittle(atVec3f vec)
{
utility::LittleFloat(vec.vec[0]);
@ -371,8 +460,13 @@ public:
utility::LittleFloat(vec.vec[2]);
writeUBytes((atUint8*)&vec, 12);
}
inline void writeValLittle(atVec3f val) {return writeVec3fLittle(val);}
inline void writeValLittle(atVec3f val) {writeVec3fLittle(val);}
/** @brief Writes an atVec3f (12 bytes) to the buffer and advances the buffer.
* It also swaps the bytes against big depending on the platform.
*
* @param vec The value to write to the buffer
*/
inline void writeVec3fBig(atVec3f vec)
{
utility::BigFloat(vec.vec[0]);
@ -380,13 +474,12 @@ public:
utility::BigFloat(vec.vec[2]);
writeUBytes((atUint8*)&vec, 12);
}
inline void writeValBig(atVec3f val) {return writeVec3fBig(val);}
inline void writeValBig(atVec3f val) {writeVec3fBig(val);}
/*! \brief Writes an atVec4f (16 bytes) to the buffer and advances the buffer.
/** @brief Writes an atVec4f (16 bytes) to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* \sa Endian
* \param vec The value to write to the buffer
* @param vec The value to write to the buffer
*/
inline void writeVec4f(atVec4f vec)
{
@ -406,8 +499,13 @@ public:
}
writeUBytes((atUint8*)&vec, 16);
}
inline void writeVal(atVec4f val) {return writeVec4f(val);}
inline void writeVal(atVec4f val) {writeVec4f(val);}
/** @brief Writes an atVec4f (16 bytes) to the buffer and advances the buffer.
* It also swaps the bytes against little depending on the platform.
*
* @param vec The value to write to the buffer
*/
inline void writeVec4fLittle(atVec4f vec)
{
utility::LittleFloat(vec.vec[0]);
@ -416,8 +514,13 @@ public:
utility::LittleFloat(vec.vec[3]);
writeUBytes((atUint8*)&vec, 16);
}
inline void writeValLittle(atVec4f val) {return writeVec4fLittle(val);}
inline void writeValLittle(atVec4f val) {writeVec4fLittle(val);}
/** @brief Writes an atVec4f (16 bytes) to the buffer and advances the buffer.
* It also swaps the bytes against big depending on the platform.
*
* @param vec The value to write to the buffer
*/
inline void writeVec4fBig(atVec4f vec)
{
utility::BigFloat(vec.vec[0]);
@ -426,14 +529,168 @@ public:
utility::BigFloat(vec.vec[3]);
writeUBytes((atUint8*)&vec, 16);
}
inline void writeValBig(atVec4f val) {return writeVec4fBig(val);}
inline void writeValBig(atVec4f val) {writeVec4fBig(val);}
/*! \brief Converts a UTF8 string to a wide-char string in the buffer and advances the buffer.
/** @brief Writes an atVec2d (16 bytes) to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* \sa Endian
* \param str The string to write to the buffer
* \param fixedLen If not -1, the number of characters to zero-fill string to
* @param vec The value to write to the buffer
*/
inline void writeVec2d(atVec2d vec)
{
if (m_endian == BigEndian)
{
utility::BigDouble(vec.vec[0]);
utility::BigDouble(vec.vec[1]);
}
else
{
utility::LittleDouble(vec.vec[0]);
utility::LittleDouble(vec.vec[1]);
}
writeUBytes((atUint8*)&vec, 16);
}
inline void writeVal(atVec2d val) {writeVec2d(val);}
/** @brief Writes an atVec2d (16 bytes) to the buffer and advances the buffer.
* It also swaps the bytes against little depending on the platform.
*
* @param vec The value to write to the buffer
*/
inline void writeVec2dLittle(atVec2d vec)
{
utility::LittleDouble(vec.vec[0]);
utility::LittleDouble(vec.vec[1]);
writeUBytes((atUint8*)&vec, 16);
}
inline void writeValLittle(atVec2d val) {writeVec2dLittle(val);}
/** @brief Writes an atVec2d (16 bytes) to the buffer and advances the buffer.
* It also swaps the bytes against big depending on the platform.
*
* @param vec The value to write to the buffer
*/
inline void writeVec2dBig(atVec2d vec)
{
utility::BigDouble(vec.vec[0]);
utility::BigDouble(vec.vec[1]);
writeUBytes((atUint8*)&vec, 16);
}
inline void writeValBig(atVec2d val) {writeVec2dBig(val);}
/** @brief Writes an atVec3d (24 bytes) to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* @param vec The value to write to the buffer
*/
inline void writeVec3d(atVec3d vec)
{
if (m_endian == BigEndian)
{
utility::BigDouble(vec.vec[0]);
utility::BigDouble(vec.vec[1]);
utility::BigDouble(vec.vec[2]);
}
else
{
utility::LittleDouble(vec.vec[0]);
utility::LittleDouble(vec.vec[1]);
utility::LittleDouble(vec.vec[2]);
}
writeUBytes((atUint8*)&vec, 24);
}
inline void writeVal(atVec3d val) {writeVec3d(val);}
/** @brief Writes an atVec3d (24 bytes) to the buffer and advances the buffer.
* It also swaps the bytes against little depending on the platform.
*
* @param vec The value to write to the buffer
*/
inline void writeVec3dLittle(atVec3d vec)
{
utility::LittleDouble(vec.vec[0]);
utility::LittleDouble(vec.vec[1]);
utility::LittleDouble(vec.vec[2]);
writeUBytes((atUint8*)&vec, 24);
}
inline void writeValLittle(atVec3d val) {writeVec3dLittle(val);}
/** @brief Writes an atVec3d (24 bytes) to the buffer and advances the buffer.
* It also swaps the bytes against big depending on the platform.
*
* @param vec The value to write to the buffer
*/
inline void writeVec3dBig(atVec3d vec)
{
utility::BigDouble(vec.vec[0]);
utility::BigDouble(vec.vec[1]);
utility::BigDouble(vec.vec[2]);
writeUBytes((atUint8*)&vec, 24);
}
inline void writeValBig(atVec3d val) {writeVec3dBig(val);}
/** @brief Writes an atVec4d (32 bytes) to the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* @param vec The value to write to the buffer
*/
inline void writeVec4d(atVec4d vec)
{
if (m_endian == BigEndian)
{
utility::BigDouble(vec.vec[0]);
utility::BigDouble(vec.vec[1]);
utility::BigDouble(vec.vec[2]);
utility::BigDouble(vec.vec[3]);
}
else
{
utility::LittleDouble(vec.vec[0]);
utility::LittleDouble(vec.vec[1]);
utility::LittleDouble(vec.vec[2]);
utility::LittleDouble(vec.vec[3]);
}
writeUBytes((atUint8*)&vec, 32);
}
inline void writeVal(atVec4d val) {writeVec4d(val);}
/** @brief Writes an atVec4d (32 bytes) to the buffer and advances the buffer.
* It also swaps the bytes against little depending on the platform.
*
* @param vec The value to write to the buffer
*/
inline void writeVec4dLittle(atVec4d vec)
{
utility::LittleDouble(vec.vec[0]);
utility::LittleDouble(vec.vec[1]);
utility::LittleDouble(vec.vec[2]);
utility::LittleDouble(vec.vec[3]);
writeUBytes((atUint8*)&vec, 32);
}
inline void writeValLittle(atVec4d val) {writeVec4dLittle(val);}
/** @brief Writes an atVec4d (32 bytes) to the buffer and advances the buffer.
* It also swaps the bytes against big depending on the platform.
*
* @param vec The value to write to the buffer
*/
inline void writeVec4dBig(atVec4d vec)
{
utility::BigDouble(vec.vec[0]);
utility::BigDouble(vec.vec[1]);
utility::BigDouble(vec.vec[2]);
utility::BigDouble(vec.vec[3]);
writeUBytes((atUint8*)&vec, 32);
}
inline void writeValBig(atVec4d val) {writeVec4dBig(val);}
/** @brief Converts a UTF8 string to a wide-char string in the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* @param str The string to write to the buffer
* @param fixedLen If not -1, the number of characters to zero-fill string to
*
* Endianness is set with setEndian
*/
inline void writeStringAsWString(const std::string& str, atInt32 fixedLen = -1)
{
@ -483,6 +740,14 @@ public:
}
}
/** @brief Converts a UTF8 string to a wide-char string in the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* @param str The string to write to the buffer
* @param fixedLen If not -1, the number of characters to zero-fill string to
*
* Endianness is little
*/
inline void writeStringAsWStringLittle(const std::string& str, atInt32 fixedLen = -1)
{
std::string tmpStr = "\xEF\xBB\xBF" + str;
@ -531,6 +796,14 @@ public:
}
}
/** @brief Converts a UTF8 string to a wide-char string in the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings.
*
* @param str The string to write to the buffer
* @param fixedLen If not -1, the number of characters to zero-fill string to
*
* Endianness is big
*/
inline void writeStringAsWStringBig(const std::string& str, atInt32 fixedLen = -1)
{
std::string tmpStr = "\xEF\xBB\xBF" + str;
@ -579,11 +852,10 @@ public:
}
}
/*! \brief Writes an string to the buffer and advances the buffer.
/** @brief Writes an string to the buffer and advances the buffer.
*
* \sa Endian
* \param str The string to write to the buffer
* \param fixedLen If not -1, the number of characters to zero-fill string to
* @param str The string to write to the buffer
* @param fixedLen If not -1, the number of characters to zero-fill string to
*/
inline void writeString(const std::string& str, atInt32 fixedLen = -1)
{
@ -612,13 +884,14 @@ public:
}
}
}
inline void writeVal(const std::string& val) {return writeString(val);}
inline void writeVal(const std::string& val) {writeString(val);}
/*! \brief Writes an wstring to the buffer and advances the buffer.
/** @brief Writes an wstring to the buffer and advances the buffer.
*
* \sa Endian
* \param str The string to write to the buffer
* \param fixedLen If not -1, the number of characters to zero-fill string to
* @param str The string to write to the buffer
* @param fixedLen If not -1, the number of characters to zero-fill string to
*
* Endianness is set with setEndian
*/
inline void writeWString(const std::wstring& str, atInt32 fixedLen = -1)
{
@ -647,8 +920,15 @@ public:
}
}
}
inline void writeVal(const std::wstring& val) {return writeWString(val);}
inline void writeVal(const std::wstring& val) {writeWString(val);}
/** @brief Writes an wstring to the buffer and advances the buffer.
*
* @param str The string to write to the buffer
* @param fixedLen If not -1, the number of characters to zero-fill string to
*
* Endianness is little
*/
inline void writeWStringLittle(const std::wstring& str, atInt32 fixedLen = -1)
{
if (fixedLen < 0)
@ -676,8 +956,15 @@ public:
}
}
}
inline void writeValLittle(const std::wstring& val) {return writeWStringLittle(val);}
inline void writeValLittle(const std::wstring& val) {writeWStringLittle(val);}
/** @brief Writes an wstring to the buffer and advances the buffer.
*
* @param str The string to write to the buffer
* @param fixedLen If not -1, the number of characters to zero-fill string to
*
* Endianness is big
*/
inline void writeWStringBig(const std::wstring& str, atInt32 fixedLen = -1)
{
if (fixedLen < 0)
@ -705,13 +992,18 @@ public:
}
}
}
inline void writeValBig(const std::wstring& val) {return writeWStringBig(val);}
inline void writeValBig(const std::wstring& val) {writeWStringBig(val);}
inline void fill(atUint8 val, atUint64 length)
{for (atUint64 l=0 ; l<length ; ++l) writeUBytes(&val, 1);}
inline void fill(atInt8 val, atUint64 length)
{fill((atUint8)val, length);}
/** @brief Performs automatic std::vector enumeration writes using numeric type T
* @param vector The std::vector read from when writing data
*
* Endianness is set with setEndian
*/
template <class T>
void enumerate(const std::vector<T>& vector,
typename std::enable_if<std::is_arithmetic<T>::value ||
@ -723,6 +1015,11 @@ public:
writeVal(item);
}
/** @brief Performs automatic std::vector enumeration writes using numeric type T
* @param vector The std::vector read from when writing data
*
* Endianness is little
*/
template <class T>
void enumerateLittle(const std::vector<T>& vector,
typename std::enable_if<std::is_arithmetic<T>::value ||
@ -734,6 +1031,11 @@ public:
writeValLittle(item);
}
/** @brief Performs automatic std::vector enumeration writes using numeric type T
* @param vector The std::vector read from when writing data
*
* Endianness is big
*/
template <class T>
void enumerateBig(const std::vector<T>& vector,
typename std::enable_if<std::is_arithmetic<T>::value ||
@ -745,6 +1047,9 @@ public:
writeValBig(item);
}
/** @brief Performs automatic std::vector enumeration writes using non-numeric type T
* @param vector The std::vector read from when writing data
*/
template <class T>
void enumerate(const std::vector<T>& vector,
typename std::enable_if<!std::is_arithmetic<T>::value &&
@ -759,6 +1064,13 @@ public:
protected:
Endian m_endian;
};
template <typename T>
IStreamWriter& operator<<(IStreamWriter& lhs, const T& rhs)
{
lhs.writeVal(rhs);
return lhs;
}
}
}
#endif // STREAMWRITER_HPP

View File

@ -96,6 +96,33 @@ typedef union alignas(16)
float vec[4];
} atVec4f;
typedef union alignas(16)
{
#if __SSE__
__m128d mVec128;
AT_ALIGNED_ALLOCATOR
#endif
double vec[2];
} atVec2d;
typedef union alignas(16)
{
#if __SSE__
__m128d mVec128[2];
AT_ALIGNED_ALLOCATOR
#endif
double vec[3];
} atVec3d;
typedef union alignas(16)
{
#if __SSE__
__m128d mVec128[2];
AT_ALIGNED_ALLOCATOR
#endif
double vec[4];
} atVec4d;
#ifndef NULL
#ifdef __cplusplus

View File

@ -169,6 +169,76 @@ std::unique_ptr<YAMLNode> YAMLDocReader::ParseEvents(yaml_parser_t* doc)
return std::unique_ptr<YAMLNode>();
}
bool YAMLDocReader::ValidateClassType(yaml_parser_t* doc, const char* expectedType)
{
if (!expectedType)
return false;
yaml_event_t event;
if (!yaml_parser_parse(doc, &event))
{
HandleYAMLParserError(doc);
return false;
}
int result;
int mappingLevel = 0;
bool inDNA = false;
for (result = yaml_parser_parse(doc, &event);
event.type != YAML_STREAM_END_EVENT;
result = yaml_parser_parse(doc, &event))
{
if (!result)
{
HandleYAMLParserError(doc);
return false;
}
switch (event.type)
{
case YAML_SCALAR_EVENT:
{
if (mappingLevel == 1)
{
if (inDNA)
{
if (!strcmp(expectedType, reinterpret_cast<const char*>(event.data.scalar.value)))
{
yaml_event_delete(&event);
return true;
}
yaml_event_delete(&event);
return false;
}
if (!strcmp("DNAType", reinterpret_cast<const char*>(event.data.scalar.value)))
inDNA = true;
}
break;
}
case YAML_MAPPING_START_EVENT:
{
++mappingLevel;
inDNA = false;
break;
}
case YAML_MAPPING_END_EVENT:
{
--mappingLevel;
inDNA = false;
break;
}
case YAML_DOCUMENT_END_EVENT:
{
yaml_event_delete(&event);
return false;
}
default:
break;
}
yaml_event_delete(&event);
}
return false;
}
static inline bool EmitKeyScalar(yaml_emitter_t* doc, const char* val)
{
yaml_event_t event;

View File

@ -185,4 +185,3 @@ SpriteFrame* SpritePart::root() const
}
}
}
#endif // ATHENA_NO_SAKURA