diff --git a/atdna/CMakeLists.txt b/atdna/CMakeLists.txt index 844b2bd..ac53c7a 100644 --- a/atdna/CMakeLists.txt +++ b/atdna/CMakeLists.txt @@ -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 diff --git a/atdna/atdnaConfig.cmake.in b/atdna/atdnaConfig.cmake.in index 0acd5fb..d73e53c 100644 --- a/atdna/atdnaConfig.cmake.in +++ b/atdna/atdnaConfig.cmake.in @@ -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 diff --git a/atdna/main.cpp b/atdna/main.cpp index 5674d1d..df27aa2 100644 --- a/atdna/main.cpp +++ b/atdna/main.cpp @@ -1,4 +1,5 @@ #include +#include #include "clang/AST/ASTConsumer.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Frontend/CompilerInstance.h" @@ -218,15 +219,31 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor 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) - return ATHENA_DNA_WRITER ".writeVec2f" + funcPrefix + "(" + fieldName + ");"; + { + 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) - return ATHENA_DNA_WRITER ".writeVec3f" + funcPrefix + "(" + fieldName + ");"; + { + 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) - return ATHENA_DNA_WRITER ".writeVec4f" + funcPrefix + "(" + fieldName + ");"; + { + 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 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) - return ATHENA_DNA_READER ".readVec2f" + funcPrefix + "()"; + { + if (width == 32) + return ATHENA_DNA_READER ".readVec2f" + funcPrefix + "()"; + else if (width == 64) + return ATHENA_DNA_READER ".readVec2d" + funcPrefix + "()"; + } else if (vType->getNumElements() == 3) - return ATHENA_DNA_READER ".readVec3f" + funcPrefix + "()"; + { + if (width == 32) + return ATHENA_DNA_READER ".readVec3f" + funcPrefix + "()"; + else if (width == 64) + return ATHENA_DNA_READER ".readVec3d" + funcPrefix + "()"; + } else if (vType->getNumElements() == 4) - return ATHENA_DNA_READER ".readVec4f" + funcPrefix + "()"; + { + 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 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) - return ATHENA_YAML_WRITER ".writeVec2f(\"" + bareFieldName + "\", " + fieldName + ");"; + { + 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) - return ATHENA_YAML_WRITER ".writeVec3f(\"" + bareFieldName + "\", " + fieldName + ");"; + { + 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) - return ATHENA_YAML_WRITER ".writeVec4f(\"" + bareFieldName + "\", " + fieldName + ");"; + { + 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 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) - return ATHENA_YAML_READER ".readVec2f(\"" + bareFieldName + "\")"; + { + if (width == 32) + return ATHENA_YAML_READER ".readVec2f(\"" + bareFieldName + "\")"; + else if (width == 64) + return ATHENA_YAML_READER ".readVec2d(\"" + bareFieldName + "\")"; + } else if (vType->getNumElements() == 3) - return ATHENA_YAML_READER ".readVec3f(\"" + bareFieldName + "\")"; + { + if (width == 32) + return ATHENA_YAML_READER ".readVec3f(\"" + bareFieldName + "\")"; + else if (width == 64) + return ATHENA_YAML_READER ".readVec3d(\"" + bareFieldName + "\")"; + } else if (vType->getNumElements() == 4) - return ATHENA_YAML_READER ".readVec4f(\"" + bareFieldName + "\")"; + { + 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 { 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 fileOut << " /* " << fieldName << " */\n" " " ATHENA_YAML_WRITER ".enumerate(\"" << fieldNameBare << "\", " << fieldName << ");\n"; } - break; } } @@ -1667,6 +1730,7 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor fileOut << "}\n\n"; } + fileOut << "const char* " << decl->getQualifiedNameAsString() << "::DNAType()\n{\n return \"" << decl->getQualifiedNameAsString() << "\";\n}\n\n"; } public: diff --git a/include/Athena/DNA.hpp b/include/Athena/DNA.hpp index 5383b99..85dd91f 100644 --- a/include/Athena/DNA.hpp +++ b/include/Athena/DNA.hpp @@ -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 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 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 using Vector = std::vector; + /** + * @brief Template type wrapping std::unique_ptr 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 using Buffer = struct Athena::io::Buffer; + /** + * @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 using String = struct Athena::io::String; + /** + * @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 using WString = struct Athena::io::WString; + /** + * @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 using WStringAsString = struct Athena::io::WStringAsString; + /** + * @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 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 struct Align {}; + /** + * @brief Meta Template preventing atdna from emitting read/write implementations + */ struct Delete {}; }; +/** + * @brief Concrete buffer type used by DNA::Buffer + */ template struct Buffer : public DNA, public std::unique_ptr { @@ -88,6 +141,9 @@ struct Buffer : public DNA, public std::unique_ptr } }; +/** + * @brief Concrete string type used by DNA::String + */ template struct String : public DNA, public std::string { @@ -102,6 +158,9 @@ struct String : public DNA, public std::string {this->swap(__str); return *this;} }; +/** + * @brief Concrete wstring type used by DNA::WString + */ template struct WString : public DNA, public std::wstring { @@ -122,6 +181,9 @@ struct WString : public DNA, public std::wstring {this->swap(__str); return *this;} }; +/** + * @brief Concrete converting-wstring type used by DNA::WStringAsString + */ template struct WStringAsString : public DNA, public std::string { diff --git a/include/Athena/DNAYaml.hpp b/include/Athena/DNAYaml.hpp index a360bad..6294ae3 100644 --- a/include/Athena/DNAYaml.hpp +++ b/include/Athena/DNAYaml.hpp @@ -263,7 +263,14 @@ inline RETURNTYPE NodeToVec(const YAMLNode* node) { YAMLNode* snode = it->get(); if (snode->m_type == YAML_SCALAR_NODE) - retval.vec[i] = NodeToVal(snode); + { + if (std::is_same::value || + std::is_same::value || + std::is_same::value) + retval.vec[i] = NodeToVal(snode); + else + retval.vec[i] = NodeToVal(snode); + } else retval.vec[i] = 0.0; } @@ -336,6 +343,72 @@ inline std::unique_ptr ValToNode(const atVec4f& val) return std::unique_ptr(ret); } +template <> +inline atVec2d NodeToVal(const YAMLNode* node) +{ + return NodeToVec(node); +} + +template <> +inline std::unique_ptr 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(ret); +} + +template <> +inline atVec3d NodeToVal(const YAMLNode* node) +{ + return NodeToVec(node); +} + +template <> +inline std::unique_ptr 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(ret); +} + +template <> +inline atVec4d NodeToVal(const YAMLNode* node) +{ + return NodeToVec(node); +} + +template <> +inline std::unique_ptr 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(ret); +} + template <> inline std::unique_ptr NodeToVal(const YAMLNode* node) { @@ -426,6 +499,7 @@ class YAMLDocReader std::vector m_seqTrackerStack; static std::unique_ptr 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(name)); + vector.push_back(readVal(name)); leaveSubVector(); } @@ -642,12 +716,26 @@ public: { return readVal(name); } - inline atVec4f readVec4f(const char* name) { return readVal(name); } + inline atVec2d readVec2d(const char* name) + { + return readVal(name); + } + + inline atVec3d readVec3d(const char* name) + { + return readVal(name); + } + + inline atVec4d readVec4d(const char* name) + { + return readVal(name); + } + inline std::unique_ptr readUBytes(const char* name) { return readVal>(name); @@ -671,9 +759,15 @@ class YAMLDocWriter std::vector 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(classVal)); + } } void enterSubRecord(const char* name) @@ -744,7 +838,10 @@ public: typename std::enable_if::value && !std::is_same::value && !std::is_same::value && - !std::is_same::value>::type* = 0) + !std::is_same::value && + !std::is_same::value && + !std::is_same::value && + !std::is_same::value>::type* = 0) { enterSubVector(name); for (const T& item : vector) @@ -761,7 +858,10 @@ public: typename std::enable_if::value || std::is_same::value || std::is_same::value || - std::is_same::value>::type* = 0) + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value>::type* = 0) { enterSubVector(name); for (T item : vector) @@ -891,6 +991,21 @@ public: writeVal(name, val); } + inline void writeVec2d(const char* name, const atVec2d& val) + { + writeVal(name, val); + } + + inline void writeVec3d(const char* name, const atVec3d& val) + { + writeVal(name, val); + } + + inline void writeVec4d(const char* name, const atVec4d& val) + { + writeVal(name, val); + } + inline void writeUBytes(const char* name, const std::unique_ptr& val, size_t byteCount) { writeVal&>(name, val, byteCount); @@ -936,6 +1051,8 @@ struct DNAYaml : DNA { 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 using Buffer = struct Athena::io::BufferYaml; @@ -970,7 +1087,7 @@ struct DNAYaml : DNA return std::string(); } { - YAMLDocWriter docWriter; + YAMLDocWriter docWriter(DNATypeV()); toYAML(docWriter); if (!docWriter.finish(&emitter)) { @@ -1013,6 +1130,22 @@ struct DNAYaml : DNA return true; } + template + 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 return false; } { - YAMLDocWriter docWriter; + YAMLDocWriter docWriter(DNATypeV()); toYAML(docWriter); if (!docWriter.finish(&emitter)) { @@ -1074,6 +1207,23 @@ struct DNAYaml : DNA yaml_parser_delete(&parser); return true; } + + template + 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 @@ -1160,11 +1310,15 @@ struct WStringAsStringYaml : public DNAYaml, 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();} \ } } diff --git a/include/Athena/Global.hpp b/include/Athena/Global.hpp index bba4a9e..9659c12 100644 --- a/include/Athena/Global.hpp +++ b/include/Athena/Global.hpp @@ -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 -class Vector2D -{ -public: - T x; - T y; - - Vector2D() - : x(0), - y(0) - { - } - - Vector2D(T x, T y) - : x(x), - y(y) - { - } -}; - -typedef Vector2D Vector2Di; -typedef Vector2D 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, ...); diff --git a/include/Athena/IStreamReader.hpp b/include/Athena/IStreamReader.hpp index 2175244..b29801b 100644 --- a/include/Athena/IStreamReader.hpp +++ b/include/Athena/IStreamReader.hpp @@ -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.
+ /** @brief Sets the buffers position relative to the specified position.
* 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.
+ /** @brief Sets the buffers position relative to the next 32-byte aligned position.
*/ 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 inline atInt8 readVal(typename std::enable_if::value>::type* = 0) {return readByte();} + template + inline atInt8 readValLittle(typename std::enable_if::value>::type* = 0) + {return readByte();} + template + inline atInt8 readValBig(typename std::enable_if::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 inline atUint8 readVal(typename std::enable_if::value>::type* = 0) {return readUByte();} + template + inline atUint8 readValLittle(typename std::enable_if::value>::type* = 0) + {return readUByte();} + template + inline atUint8 readValBig(typename std::enable_if::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 readBytes(atUint64 length) { @@ -103,9 +115,9 @@ public: return std::unique_ptr(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 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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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::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 inline bool readVal(typename std::enable_if::value>::type* = 0) {return readBool();} + template + inline bool readValLittle(typename std::enable_if::value>::type* = 0) + {return readBool();} + template + inline bool readValBig(typename std::enable_if::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::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::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::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::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::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::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::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::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::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 + inline atVec2d readVal(typename std::enable_if::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 + inline atVec2d readValLittle(typename std::enable_if::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 + inline atVec2d readValBig(typename std::enable_if::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 + inline atVec3d readVal(typename std::enable_if::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 + inline atVec3d readValLittle(typename std::enable_if::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 + inline atVec3d readValBig(typename std::enable_if::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 + inline atVec4d readVal(typename std::enable_if::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 + inline atVec4d readValLittle(typename std::enable_if::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 + inline atVec4d readValBig(typename std::enable_if::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::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::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::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::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 void enumerate(std::vector& vector, size_t count, typename std::enable_if::value || @@ -807,9 +1128,16 @@ public: vector.clear(); vector.reserve(count); for (size_t i=0 ; i()); + vector.push_back(readVal()); } + /** @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 void enumerateLittle(std::vector& vector, size_t count, typename std::enable_if::value || @@ -820,9 +1148,16 @@ public: vector.clear(); vector.reserve(count); for (size_t i=0 ; i()); + vector.push_back(readValLittle()); } + /** @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 void enumerateBig(std::vector& vector, size_t count, typename std::enable_if::value || @@ -833,9 +1168,14 @@ public: vector.clear(); vector.reserve(count); for (size_t i=0 ; i()); + vector.push_back(readValBig()); } + /** @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 void enumerate(std::vector& vector, size_t count, typename std::enable_if::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 void enumerate(std::vector& vector, size_t count, std::function readf) { @@ -867,6 +1214,12 @@ public: protected: Endian m_endian; }; +template +IStreamReader& operator>>(IStreamReader& lhs, T& rhs) +{ + rhs = lhs.readVal(rhs); + return lhs; +} } } #endif // ISTREAMREADER diff --git a/include/Athena/IStreamWriter.hpp b/include/Athena/IStreamWriter.hpp index 133c892..a4e9a2d 100644 --- a/include/Athena/IStreamWriter.hpp +++ b/include/Athena/IStreamWriter.hpp @@ -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.
+ /** @brief Sets the buffers position relative to the specified position.
* 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.
+ /** @brief Sets the buffers position relative to the next 32-byte aligned position.
*/ 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 void enumerate(const std::vector& vector, typename std::enable_if::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 void enumerateLittle(const std::vector& vector, typename std::enable_if::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 void enumerateBig(const std::vector& vector, typename std::enable_if::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 void enumerate(const std::vector& vector, typename std::enable_if::value && @@ -759,6 +1064,13 @@ public: protected: Endian m_endian; }; + +template +IStreamWriter& operator<<(IStreamWriter& lhs, const T& rhs) +{ + lhs.writeVal(rhs); + return lhs; +} } } #endif // STREAMWRITER_HPP diff --git a/include/Athena/Types.hpp b/include/Athena/Types.hpp index d7f26fe..1278acb 100644 --- a/include/Athena/Types.hpp +++ b/include/Athena/Types.hpp @@ -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 diff --git a/src/Athena/DNAYaml.cpp b/src/Athena/DNAYaml.cpp index 7b83a7d..48c1fb4 100644 --- a/src/Athena/DNAYaml.cpp +++ b/src/Athena/DNAYaml.cpp @@ -169,6 +169,76 @@ std::unique_ptr YAMLDocReader::ParseEvents(yaml_parser_t* doc) return std::unique_ptr(); } +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(event.data.scalar.value))) + { + yaml_event_delete(&event); + return true; + } + yaml_event_delete(&event); + return false; + } + if (!strcmp("DNAType", reinterpret_cast(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; diff --git a/src/Athena/SpritePart.cpp b/src/Athena/SpritePart.cpp index eae94d6..f4dae05 100644 --- a/src/Athena/SpritePart.cpp +++ b/src/Athena/SpritePart.cpp @@ -185,4 +185,3 @@ SpriteFrame* SpritePart::root() const } } } -#endif // ATHENA_NO_SAKURA