summaryrefslogtreecommitdiff
path: root/thirdparty/assimp/code/FIReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/assimp/code/FIReader.cpp')
-rw-r--r--thirdparty/assimp/code/FIReader.cpp1834
1 files changed, 0 insertions, 1834 deletions
diff --git a/thirdparty/assimp/code/FIReader.cpp b/thirdparty/assimp/code/FIReader.cpp
deleted file mode 100644
index 2116316ca3..0000000000
--- a/thirdparty/assimp/code/FIReader.cpp
+++ /dev/null
@@ -1,1834 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-/// \file FIReader.cpp
-/// \brief Reader for Fast Infoset encoded binary XML files.
-/// \date 2017
-/// \author Patrick Daehne
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "FIReader.hpp"
-#include <assimp/StringUtils.h>
-
-// Workaround for issue #1361
-// https://github.com/assimp/assimp/issues/1361
-#ifdef __ANDROID__
-# define _GLIBCXX_USE_C99 1
-#endif
-
-#include <assimp/Exceptional.h>
-#include <assimp/IOStream.hpp>
-#include <assimp/types.h>
-#include <assimp/MemoryIOWrapper.h>
-#include <assimp/irrXMLWrapper.h>
-#include "../contrib/utf8cpp/source/utf8.h"
-#include <assimp/fast_atof.h>
-#include <stack>
-#include <map>
-#include <iostream>
-#include <sstream>
-#include <iomanip>
-
-namespace Assimp {
-
-static const std::string parseErrorMessage = "Fast Infoset parse error";
-
-static const char *xmlDeclarations[] = {
- "<?xml encoding='finf'?>",
- "<?xml encoding='finf' standalone='yes'?>",
- "<?xml encoding='finf' standalone='no'?>",
- "<?xml version='1.0' encoding='finf'?>",
- "<?xml version='1.0' encoding='finf' standalone='yes'?>",
- "<?xml version='1.0' encoding='finf' standalone='no'?>",
- "<?xml version='1.1' encoding='finf'?>",
- "<?xml version='1.1' encoding='finf' standalone='yes'?>",
- "<?xml version='1.1' encoding='finf' standalone='no'?>"
-};
-
-static size_t parseMagic(const uint8_t *data, const uint8_t *dataEnd) {
- if (dataEnd - data < 4) {
- return 0;
- }
- uint32_t magic = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- switch (magic) {
- case 0xe0000001:
- return 4;
- case 0x3c3f786d: // "<?xm"
- {
- size_t xmlDeclarationsLength = sizeof(xmlDeclarations) / sizeof(xmlDeclarations[0]);
- for (size_t i = 0; i < xmlDeclarationsLength; ++i) {
- auto xmlDeclaration = xmlDeclarations[i];
- ptrdiff_t xmlDeclarationLength = strlen(xmlDeclaration);
- if ((dataEnd - data >= xmlDeclarationLength) && (memcmp(xmlDeclaration, data, xmlDeclarationLength) == 0)) {
- data += xmlDeclarationLength;
- if (dataEnd - data < 4) {
- return 0;
- }
- magic = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- return magic == 0xe0000001 ? xmlDeclarationLength + 4 : 0;
- }
- }
- return 0;
- }
- default:
- return 0;
- }
-}
-
-static std::string parseUTF8String(const uint8_t *data, size_t len) {
- return std::string((char*)data, len);
-}
-
-static std::string parseUTF16String(const uint8_t *data, size_t len) {
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- size_t numShorts = len / 2;
- std::vector<short> utf16;
- utf16.reserve(numShorts);
- for (size_t i = 0; i < numShorts; ++i) {
- short v = (data[0] << 8) | data[1];
- utf16.push_back(v);
- data += 2;
- }
- std::string result;
- utf8::utf16to8(utf16.begin(), utf16.end(), back_inserter(result));
- return result;
-}
-
-struct FIStringValueImpl: public FIStringValue {
- inline FIStringValueImpl(std::string &&value_) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ { return value; }
-};
-
-std::shared_ptr<FIStringValue> FIStringValue::create(std::string &&value) {
- return std::make_shared<FIStringValueImpl>(std::move(value));
-}
-
-struct FIHexValueImpl: public FIHexValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIHexValueImpl(std::vector<uint8_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- os << std::hex << std::uppercase << std::setfill('0');
- std::for_each(value.begin(), value.end(), [&](uint8_t c) { os << std::setw(2) << static_cast<int>(c); });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIHexValue> FIHexValue::create(std::vector<uint8_t> &&value) {
- return std::make_shared<FIHexValueImpl>(std::move(value));
-}
-
-struct FIBase64ValueImpl: public FIBase64Value {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIBase64ValueImpl(std::vector<uint8_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- uint8_t c1 = 0, c2;
- int imod3 = 0;
- std::vector<uint8_t>::size_type valueSize = value.size();
- for (std::vector<uint8_t>::size_type i = 0; i < valueSize; ++i) {
- c2 = value[i];
- switch (imod3) {
- case 0:
- os << basis_64[c2 >> 2];
- imod3 = 1;
- break;
- case 1:
- os << basis_64[((c1 & 0x03) << 4) | ((c2 & 0xf0) >> 4)];
- imod3 = 2;
- break;
- case 2:
- os << basis_64[((c1 & 0x0f) << 2) | ((c2 & 0xc0) >> 6)] << basis_64[c2 & 0x3f];
- imod3 = 0;
- break;
- }
- c1 = c2;
- }
- switch (imod3) {
- case 1:
- os << basis_64[(c1 & 0x03) << 4] << "==";
- break;
- case 2:
- os << basis_64[(c1 & 0x0f) << 2] << '=';
- break;
- }
- strValue = os.str();
- }
- return strValue;
- };
- static const char basis_64[];
-};
-
-const char FIBase64ValueImpl::basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-std::shared_ptr<FIBase64Value> FIBase64Value::create(std::vector<uint8_t> &&value) {
- return std::make_shared<FIBase64ValueImpl>(std::move(value));
-}
-
-struct FIShortValueImpl: public FIShortValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIShortValueImpl(std::vector<int16_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](int16_t s) { if (++n > 1) os << ' '; os << s; });
- strValue = os.str();
- }
- return strValue;
- }
-};
-
-std::shared_ptr<FIShortValue> FIShortValue::create(std::vector<int16_t> &&value) {
- return std::make_shared<FIShortValueImpl>(std::move(value));
-}
-
-struct FIIntValueImpl: public FIIntValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIIntValueImpl(std::vector<int32_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](int32_t i) { if (++n > 1) os << ' '; os << i; });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIIntValue> FIIntValue::create(std::vector<int32_t> &&value) {
- return std::make_shared<FIIntValueImpl>(std::move(value));
-}
-
-struct FILongValueImpl: public FILongValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FILongValueImpl(std::vector<int64_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](int64_t l) { if (++n > 1) os << ' '; os << l; });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FILongValue> FILongValue::create(std::vector<int64_t> &&value) {
- return std::make_shared<FILongValueImpl>(std::move(value));
-}
-
-struct FIBoolValueImpl: public FIBoolValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIBoolValueImpl(std::vector<bool> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- os << std::boolalpha;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](bool b) { if (++n > 1) os << ' '; os << b; });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIBoolValue> FIBoolValue::create(std::vector<bool> &&value) {
- return std::make_shared<FIBoolValueImpl>(std::move(value));
-}
-
-struct FIFloatValueImpl: public FIFloatValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIFloatValueImpl(std::vector<float> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](float f) { if (++n > 1) os << ' '; os << f; });
- strValue = os.str();
- }
- return strValue;
- }
-};
-
-std::shared_ptr<FIFloatValue> FIFloatValue::create(std::vector<float> &&value) {
- return std::make_shared<FIFloatValueImpl>(std::move(value));
-}
-
-struct FIDoubleValueImpl: public FIDoubleValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIDoubleValueImpl(std::vector<double> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](double d) { if (++n > 1) os << ' '; os << d; });
- strValue = os.str();
- }
- return strValue;
- }
-};
-
-std::shared_ptr<FIDoubleValue> FIDoubleValue::create(std::vector<double> &&value) {
- return std::make_shared<FIDoubleValueImpl>(std::move(value));
-}
-
-struct FIUUIDValueImpl: public FIUUIDValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIUUIDValueImpl(std::vector<uint8_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- os << std::hex << std::uppercase << std::setfill('0');
- std::vector<uint8_t>::size_type valueSize = value.size();
- for (std::vector<uint8_t>::size_type i = 0; i < valueSize; ++i) {
- switch (i & 15) {
- case 0:
- if (i > 0) {
- os << ' ';
- }
- os << std::setw(2) << static_cast<int>(value[i]);
- break;
- case 4:
- case 6:
- case 8:
- case 10:
- os << '-';
- // intentionally fall through!
- case 1:
- case 2:
- case 3:
- case 5:
- case 7:
- case 9:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- os << std::setw(2) << static_cast<int>(value[i]);
- break;
- }
- }
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIUUIDValue> FIUUIDValue::create(std::vector<uint8_t> &&value) {
- return std::make_shared<FIUUIDValueImpl>(std::move(value));
-}
-
-struct FICDATAValueImpl: public FICDATAValue {
- inline FICDATAValueImpl(std::string &&value_) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ { return value; }
-};
-
-std::shared_ptr<FICDATAValue> FICDATAValue::create(std::string &&value) {
- return std::make_shared<FICDATAValueImpl>(std::move(value));
-}
-
-struct FIHexDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- return FIHexValue::create(std::vector<uint8_t>(data, data + len));
- }
-};
-
-struct FIBase64Decoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- return FIBase64Value::create(std::vector<uint8_t>(data, data + len));
- }
-};
-
-struct FIShortDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<int16_t> value;
- size_t numShorts = len / 2;
- value.reserve(numShorts);
- for (size_t i = 0; i < numShorts; ++i) {
- int16_t v = (data[0] << 8) | data[1];
- value.push_back(v);
- data += 2;
- }
- return FIShortValue::create(std::move(value));
- }
-};
-
-struct FIIntDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 3) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<int32_t> value;
- size_t numInts = len / 4;
- value.reserve(numInts);
- for (size_t i = 0; i < numInts; ++i) {
- int32_t v = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- value.push_back(v);
- data += 4;
- }
- return FIIntValue::create(std::move(value));
- }
-};
-
-struct FILongDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 7) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<int64_t> value;
- size_t numLongs = len / 8;
- value.reserve(numLongs);
- for (size_t i = 0; i < numLongs; ++i) {
- int64_t b0 = data[0], b1 = data[1], b2 = data[2], b3 = data[3], b4 = data[4], b5 = data[5], b6 = data[6], b7 = data[7];
- int64_t v = (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
- value.push_back(v);
- data += 8;
- }
- return FILongValue::create(std::move(value));
- }
-};
-
-struct FIBoolDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<bool> value;
- uint8_t b = *data++;
- size_t unusedBits = b >> 4;
- size_t numBools = (len * 8) - 4 - unusedBits;
- value.reserve(numBools);
- uint8_t mask = 1 << 3;
- for (size_t i = 0; i < numBools; ++i) {
- if (!mask) {
- mask = 1 << 7;
- b = *data++;
- }
- value.push_back((b & mask) != 0);
- }
- return FIBoolValue::create(std::move(value));
- }
-};
-
-struct FIFloatDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 3) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<float> value;
- size_t numFloats = len / 4;
- value.reserve(numFloats);
- for (size_t i = 0; i < numFloats; ++i) {
- int v = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- float f;
- memcpy(&f, &v, 4);
- value.push_back(f);
- data += 4;
- }
- return FIFloatValue::create(std::move(value));
- }
-};
-
-struct FIDoubleDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 7) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<double> value;
- size_t numDoubles = len / 8;
- value.reserve(numDoubles);
- for (size_t i = 0; i < numDoubles; ++i) {
- long long b0 = data[0], b1 = data[1], b2 = data[2], b3 = data[3], b4 = data[4], b5 = data[5], b6 = data[6], b7 = data[7];
- long long v = (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
- double f;
- memcpy(&f, &v, 8);
- value.push_back(f);
- data += 8;
- }
- return FIDoubleValue::create(std::move(value));
- }
-};
-
-struct FIUUIDDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 15) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return FIUUIDValue::create(std::vector<uint8_t>(data, data + len));
- }
-};
-
-struct FICDATADecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- return FICDATAValue::create(parseUTF8String(data, len));
- }
-};
-
-class CFIReaderImpl: public FIReader {
-public:
-
- CFIReaderImpl(std::unique_ptr<uint8_t[]> data_, size_t size):
- data(std::move(data_)), dataP(data.get()), dataEnd(data.get() + size), currentNodeType(irr::io::EXN_NONE),
- emptyElement(false), headerPending(true), terminatorPending(false)
- {}
-
- virtual ~CFIReaderImpl() {}
-
- virtual bool read() /*override*/ {
- if (headerPending) {
- headerPending = false;
- parseHeader();
- }
- if (terminatorPending) {
- terminatorPending = false;
- if (elementStack.empty()) {
- return false;
- }
- else {
- nodeName = elementStack.top();
- elementStack.pop();
- currentNodeType = nodeName.empty() ? irr::io::EXN_UNKNOWN : irr::io::EXN_ELEMENT_END;
- return true;
- }
- }
- if (dataP >= dataEnd) {
- return false;
- }
- uint8_t b = *dataP;
- if (b < 0x80) { // Element (C.2.11.2, C.3.7.2)
- // C.3
- parseElement();
- return true;
- }
- else if (b < 0xc0) { // Characters (C.3.7.5)
- // C.7
- auto chars = parseNonIdentifyingStringOrIndex3(vocabulary.charactersTable);
- nodeName = chars->toString();
- currentNodeType = irr::io::EXN_TEXT;
- return true;
- }
- else if (b < 0xe0) {
- if ((b & 0xfc) == 0xc4) { // DTD (C.2.11.5)
- // C.9
- ++dataP;
- if (b & 0x02) {
- /*const std::string &systemID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- if (b & 0x01) {
- /*const std::string &publicID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- elementStack.push(EmptyString);
- currentNodeType = irr::io::EXN_UNKNOWN;
- return true;
- }
- else if ((b & 0xfc) == 0xc8) { // Unexpanded entity reference (C.3.7.4)
- // C.6
- ++dataP;
- /*const std::string &name =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- if (b & 0x02) {
- /*const std::string &systemID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- if (b & 0x01) {
- /*const std::string &publicID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- currentNodeType = irr::io::EXN_UNKNOWN;
- return true;
- }
- }
- else if (b < 0xf0) {
- if (b == 0xe1) { // Processing instruction (C.2.11.3, C.3.7.3)
- // C.5
- ++dataP;
- /*const std::string &target =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::shared_ptr<const FIValue> data =*/ parseNonIdentifyingStringOrIndex1(vocabulary.otherStringTable);
- currentNodeType = irr::io::EXN_UNKNOWN;
- return true;
- }
- else if (b == 0xe2) { // Comment (C.2.11.4, C.3.7.6)
- // C.8
- ++dataP;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::shared_ptr<const FIValue> comment = parseNonIdentifyingStringOrIndex1(vocabulary.otherStringTable);
- nodeName = comment->toString();
- currentNodeType = irr::io::EXN_COMMENT;
- return true;
- }
- }
- else { // Terminator (C.2.12, C.3.8)
- ++dataP;
- if (b == 0xff) {
- terminatorPending = true;
- }
- if (elementStack.empty()) {
- return false;
- }
- else {
- nodeName = elementStack.top();
- elementStack.pop();
- currentNodeType = nodeName.empty() ? irr::io::EXN_UNKNOWN : irr::io::EXN_ELEMENT_END;
- return true;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- virtual irr::io::EXML_NODE getNodeType() const /*override*/ {
- return currentNodeType;
- }
-
- virtual int getAttributeCount() const /*override*/ {
- return static_cast<int>(attributes.size());
- }
-
- virtual const char* getAttributeName(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return nullptr;
- }
- return attributes[idx].name.c_str();
- }
-
- virtual const char* getAttributeValue(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return nullptr;
- }
- return attributes[idx].value->toString().c_str();
- }
-
- virtual const char* getAttributeValue(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return nullptr;
- }
- return attr->value->toString().c_str();
- }
-
- virtual const char* getAttributeValueSafe(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return EmptyString.c_str();
- }
- return attr->value->toString().c_str();
- }
-
- virtual int getAttributeValueAsInt(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return 0;
- }
- std::shared_ptr<const FIIntValue> intValue = std::dynamic_pointer_cast<const FIIntValue>(attr->value);
- if (intValue) {
- return intValue->value.size() == 1 ? intValue->value.front() : 0;
- }
- return atoi(attr->value->toString().c_str());
- }
-
- virtual int getAttributeValueAsInt(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return 0;
- }
- std::shared_ptr<const FIIntValue> intValue = std::dynamic_pointer_cast<const FIIntValue>(attributes[idx].value);
- if (intValue) {
- return intValue->value.size() == 1 ? intValue->value.front() : 0;
- }
- return atoi(attributes[idx].value->toString().c_str());
- }
-
- virtual float getAttributeValueAsFloat(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return 0;
- }
- std::shared_ptr<const FIFloatValue> floatValue = std::dynamic_pointer_cast<const FIFloatValue>(attr->value);
- if (floatValue) {
- return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
- }
-
- return fast_atof(attr->value->toString().c_str());
- }
-
- virtual float getAttributeValueAsFloat(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return 0;
- }
- std::shared_ptr<const FIFloatValue> floatValue = std::dynamic_pointer_cast<const FIFloatValue>(attributes[idx].value);
- if (floatValue) {
- return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
- }
- return fast_atof(attributes[idx].value->toString().c_str());
- }
-
- virtual const char* getNodeName() const /*override*/ {
- return nodeName.c_str();
- }
-
- virtual const char* getNodeData() const /*override*/ {
- return nodeName.c_str();
- }
-
- virtual bool isEmptyElement() const /*override*/ {
- return emptyElement;
- }
-
- virtual irr::io::ETEXT_FORMAT getSourceFormat() const /*override*/ {
- return irr::io::ETF_UTF8;
- }
-
- virtual irr::io::ETEXT_FORMAT getParserFormat() const /*override*/ {
- return irr::io::ETF_UTF8;
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return nullptr;
- }
- return attributes[idx].value;
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return nullptr;
- }
- return attr->value;
- }
-
- virtual void registerDecoder(const std::string &algorithmUri, std::unique_ptr<FIDecoder> decoder) /*override*/ {
- decoderMap[algorithmUri] = std::move(decoder);
- }
-
- virtual void registerVocabulary(const std::string &vocabularyUri, const FIVocabulary *vocabulary) /*override*/ {
- vocabularyMap[vocabularyUri] = vocabulary;
- }
-
-private:
-
- struct QName {
- std::string prefix;
- std::string uri;
- std::string name;
- inline QName() {}
- inline QName(const FIQName &qname): prefix(qname.prefix ? qname.prefix : ""), uri(qname.uri ? qname.uri : ""), name(qname.name) {}
- };
-
- struct Attribute {
- QName qname;
- std::string name;
- std::shared_ptr<const FIValue> value;
- };
-
- struct Vocabulary {
- std::vector<std::string> restrictedAlphabetTable;
- std::vector<std::string> encodingAlgorithmTable;
- std::vector<std::string> prefixTable;
- std::vector<std::string> namespaceNameTable;
- std::vector<std::string> localNameTable;
- std::vector<std::string> otherNCNameTable;
- std::vector<std::string> otherURITable;
- std::vector<std::shared_ptr<const FIValue>> attributeValueTable;
- std::vector<std::shared_ptr<const FIValue>> charactersTable;
- std::vector<std::shared_ptr<const FIValue>> otherStringTable;
- std::vector<QName> elementNameTable;
- std::vector<QName> attributeNameTable;
- Vocabulary() {
- prefixTable.push_back("xml");
- namespaceNameTable.push_back("http://www.w3.org/XML/1998/namespace");
- }
- };
-
- const Attribute* getAttributeByName(const char* name) const {
- if (!name) {
- return 0;
- }
- std::string n = name;
- for (int i=0; i<(int)attributes.size(); ++i) {
- if (attributes[i].name == n) {
- return &attributes[i];
- }
- }
- return 0;
- }
-
- size_t parseInt2() { // C.25
- uint8_t b = *dataP++;
- if (!(b & 0x40)) { // x0...... (C.25.2)
- return b & 0x3f;
- }
- else if ((b & 0x60) == 0x40) { // x10..... ........ (C.25.3)
- if (dataEnd - dataP > 0) {
- return (((b & 0x1f) << 8) | *dataP++) + 0x40;
- }
- }
- else if ((b & 0x70) == 0x60) { // x110.... ........ ........ (C.25.4)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x0f) << 16) | (dataP[0] << 8) | dataP[1]) + 0x2040;
- dataP += 2;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseInt3() { // C.27
- uint8_t b = *dataP++;
- if (!(b & 0x20)) { // xx0..... (C.27.2)
- return b & 0x1f;
- }
- else if ((b & 0x38) == 0x20) { // xx100... ........ (C.27.3)
- if (dataEnd - dataP > 0) {
- return (((b & 0x07) << 8) | *dataP++) + 0x20;
- }
- }
- else if ((b & 0x38) == 0x28) { // xx101... ........ ........ (C.27.4)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x07) << 16) | (dataP[0] << 8) | dataP[1]) + 0x820;
- dataP += 2;
- return result;
- }
- }
- else if ((b & 0x3f) == 0x30) { // xx110000 0000.... ........ ........ (C.27.5)
- if ((dataEnd - dataP > 2) && !(dataP[0] & 0xf0)) {
- size_t result = (((dataP[0] & 0x0f) << 16) | (dataP[1] << 8) | dataP[2]) + 0x80820;
- dataP += 3;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseInt4() { // C.28
- uint8_t b = *dataP++;
- if (!(b & 0x10)) { // xxx0.... (C.28.2)
- return b & 0x0f;
- }
- else if ((b & 0x1c) == 0x10) { // xxx100.. ........ (C.28.3)
- if (dataEnd - dataP > 0) {
- return (((b & 0x03) << 8) | *dataP++) + 0x10;
- }
- }
- else if ((b & 0x1c) == 0x14) { // xxx101.. ........ ........ (C.28.4)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x03) << 16) | (dataP[0] << 8) | dataP[1]) + 0x410;
- dataP += 2;
- return result;
- }
- }
- else if ((b & 0x1f) == 0x18) { // xxx11000 0000.... ........ ........ (C.28.5)
- if ((dataEnd - dataP > 2) && !(dataP[0] & 0xf0)) {
- size_t result = (((dataP[0] & 0x0f) << 16) | (dataP[1] << 8) | dataP[2]) + 0x40410;
- dataP += 3;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseSequenceLen() { // C.21
- if (dataEnd - dataP > 0) {
- uint8_t b = *dataP++;
- if (b < 0x80) { // 0....... (C.21.2)
- return b;
- }
- else if ((b & 0xf0) == 0x80) { // 1000.... ........ ........ (C.21.3)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x0f) << 16) | (dataP[0] << 8) | dataP[1]) + 0x80;
- dataP += 2;
- return result;
- }
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- std::string parseNonEmptyOctetString2() { // C.22
- // Parse the length of the string
- uint8_t b = *dataP++ & 0x7f;
- size_t len;
- if (!(b & 0x40)) { // x0...... (C.22.3.1)
- len = b + 1;
- }
- else if (b == 0x40) { // x1000000 ........ (C.22.3.2)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- len = *dataP++ + 0x41;
- }
- else if (b == 0x60) { // x1100000 ........ ........ ........ ........ (C.22.3.3)
- if (dataEnd - dataP < 4) {
- throw DeadlyImportError(parseErrorMessage);
- }
- len = ((dataP[0] << 24) | (dataP[1] << 16) | (dataP[2] << 8) | dataP[3]) + 0x141;
- dataP += 4;
- }
- else {
- throw DeadlyImportError(parseErrorMessage);
- }
-
- // Parse the string (C.22.4)
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::string s = parseUTF8String(dataP, len);
- dataP += len;
-
- return s;
- }
-
- size_t parseNonEmptyOctetString5Length() { // C.23
- // Parse the length of the string
- size_t b = *dataP++ & 0x0f;
- if (!(b & 0x08)) { // xxxx0... (C.23.3.1)
- return b + 1;
- }
- else if (b == 0x08) { // xxxx1000 ........ (C.23.3.2)
- if (dataEnd - dataP > 0) {
- return *dataP++ + 0x09;
- }
- }
- else if (b == 0x0c) { // xxxx1100 ........ ........ ........ ........ (C.23.3.3)
- if (dataEnd - dataP > 3) {
- size_t result = ((dataP[0] << 24) | (dataP[1] << 16) | (dataP[2] << 8) | dataP[3]) + 0x109;
- dataP += 4;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseNonEmptyOctetString7Length() { // C.24
- // Parse the length of the string
- size_t b = *dataP++ & 0x03;
- if (!(b & 0x02)) { // xxxxxx0. (C.24.3.1)
- return b + 1;
- }
- else if (b == 0x02) { // xxxxxx10 ........ (C.24.3.2)
- if (dataEnd - dataP > 0) {
- return *dataP++ + 0x3;
- }
- }
- else if (b == 0x03) { // xxxxxx11 ........ ........ ........ ........ (C.24.3.3)
- if (dataEnd - dataP > 3) {
- size_t result = ((dataP[0] << 24) | (dataP[1] << 16) | (dataP[2] << 8) | dataP[3]) + 0x103;
- dataP += 4;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- std::shared_ptr<const FIValue> parseEncodedData(size_t index, size_t len) {
- if (index < 32) {
- FIDecoder *decoder = defaultDecoder[index];
- if (!decoder) {
- throw DeadlyImportError("Invalid encoding algorithm index " + to_string(index));
- }
- return decoder->decode(dataP, len);
- }
- else {
- if (index - 32 >= vocabulary.encodingAlgorithmTable.size()) {
- throw DeadlyImportError("Invalid encoding algorithm index " + to_string(index));
- }
- std::string uri = vocabulary.encodingAlgorithmTable[index - 32];
- auto it = decoderMap.find(uri);
- if (it == decoderMap.end()) {
- throw DeadlyImportError("Unsupported encoding algorithm " + uri);
- }
- else {
- return it->second->decode(dataP, len);
- }
- }
- }
-
- std::shared_ptr<const FIValue> parseRestrictedAlphabet(size_t index, size_t len) {
- std::string alphabet;
- if (index < 16) {
- switch (index) {
- case 0: // numeric
- alphabet = "0123456789-+.e ";
- break;
- case 1: // date and time
- alphabet = "0123456789-:TZ ";
- break;
- default:
- throw DeadlyImportError("Invalid restricted alphabet index " + to_string(index));
- }
- }
- else {
- if (index - 16 >= vocabulary.restrictedAlphabetTable.size()) {
- throw DeadlyImportError("Invalid restricted alphabet index " + to_string(index));
- }
- alphabet = vocabulary.restrictedAlphabetTable[index - 16];
- }
- std::vector<uint32_t> alphabetUTF32;
- utf8::utf8to32(alphabet.begin(), alphabet.end(), back_inserter(alphabetUTF32));
- std::string::size_type alphabetLength = alphabetUTF32.size();
- if (alphabetLength < 2) {
- throw DeadlyImportError("Invalid restricted alphabet length " + to_string(alphabetLength));
- }
- std::string::size_type bitsPerCharacter = 1;
- while ((1ull << bitsPerCharacter) <= alphabetLength) {
- ++bitsPerCharacter;
- }
- size_t bitsAvail = 0;
- uint8_t mask = (1 << bitsPerCharacter) - 1;
- uint32_t bits = 0;
- std::string s;
- for (size_t i = 0; i < len; ++i) {
- bits = (bits << 8) | dataP[i];
- bitsAvail += 8;
- while (bitsAvail >= bitsPerCharacter) {
- bitsAvail -= bitsPerCharacter;
- size_t charIndex = (bits >> bitsAvail) & mask;
- if (charIndex < alphabetLength) {
- s.push_back(alphabetUTF32[charIndex]);
- }
- else if (charIndex != mask) {
- throw DeadlyImportError(parseErrorMessage);
- }
- }
- }
- return FIStringValue::create(std::move(s));
- }
-
- std::shared_ptr<const FIValue> parseEncodedCharacterString3() { // C.19
- std::shared_ptr<const FIValue> result;
- size_t len;
- uint8_t b = *dataP;
- if (b & 0x20) {
- ++dataP;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- size_t index = ((b & 0x0f) << 4) | ((*dataP & 0xf0) >> 4); // C.29
- len = parseNonEmptyOctetString5Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x10) {
- // encoding algorithm (C.19.3.4)
- result = parseEncodedData(index, len);
- }
- else {
- // Restricted alphabet (C.19.3.3)
- result = parseRestrictedAlphabet(index, len);
- }
- }
- else {
- len = parseNonEmptyOctetString5Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x10) {
- // UTF-16 (C.19.3.2)
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result = FIStringValue::create(parseUTF16String(dataP, len));
- }
- else {
- // UTF-8 (C.19.3.1)
- result = FIStringValue::create(parseUTF8String(dataP, len));
- }
- }
- dataP += len;
- return result;
- }
-
- std::shared_ptr<const FIValue> parseEncodedCharacterString5() { // C.20
- std::shared_ptr<const FIValue> result;
- size_t len;
- uint8_t b = *dataP;
- if (b & 0x08) {
- ++dataP;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- size_t index = ((b & 0x03) << 6) | ((*dataP & 0xfc) >> 2); /* C.29 */
- len = parseNonEmptyOctetString7Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x04) {
- // encoding algorithm (C.20.3.4)
- result = parseEncodedData(index, len);
- }
- else {
- // Restricted alphabet (C.20.3.3)
- result = parseRestrictedAlphabet(index, len);
- }
- }
- else {
- len = parseNonEmptyOctetString7Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x04) {
- // UTF-16 (C.20.3.2)
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result = FIStringValue::create(parseUTF16String(dataP, len));
- }
- else {
- // UTF-8 (C.20.3.1)
- result = FIStringValue::create(parseUTF8String(dataP, len));
- }
- }
- dataP += len;
- return result;
- }
-
- const std::string &parseIdentifyingStringOrIndex(std::vector<std::string> &stringTable) { // C.13
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b = *dataP;
- if (b & 0x80) {
- // We have an index (C.13.4)
- size_t index = parseInt2();
- if (index >= stringTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return stringTable[index];
- }
- else {
- // We have a string (C.13.3)
- stringTable.push_back(parseNonEmptyOctetString2());
- return stringTable.back();
- }
- }
-
- QName parseNameSurrogate() { // C.16
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b = *dataP++;
- if (b & 0xfc) { // Padding '000000' C.2.5.5
- throw DeadlyImportError(parseErrorMessage);
- }
- QName result;
- size_t index;
- if (b & 0x02) { // prefix (C.16.3)
- if ((dataEnd - dataP < 1) || (*dataP & 0x80)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- index = parseInt2();
- if (index >= vocabulary.prefixTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result.prefix = vocabulary.prefixTable[index];
- }
- if (b & 0x01) { // namespace-name (C.16.4)
- if ((dataEnd - dataP < 1) || (*dataP & 0x80)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- index = parseInt2();
- if (index >= vocabulary.namespaceNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result.uri = vocabulary.namespaceNameTable[index];
- }
- // local-name
- if ((dataEnd - dataP < 1) || (*dataP & 0x80)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- index = parseInt2();
- if (index >= vocabulary.localNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result.name = vocabulary.localNameTable[index];
- return result;
- }
-
- const QName &parseQualifiedNameOrIndex2(std::vector<QName> &qNameTable) { // C.17
- uint8_t b = *dataP;
- if ((b & 0x7c) == 0x78) { // x11110..
- // We have a literal (C.17.3)
- ++dataP;
- QName result;
- // prefix (C.17.3.1)
- result.prefix = b & 0x02 ? parseIdentifyingStringOrIndex(vocabulary.prefixTable) : std::string();
- // namespace-name (C.17.3.1)
- result.uri = b & 0x01 ? parseIdentifyingStringOrIndex(vocabulary.namespaceNameTable) : std::string();
- // local-name
- result.name = parseIdentifyingStringOrIndex(vocabulary.localNameTable);
- qNameTable.push_back(result);
- return qNameTable.back();
- }
- else {
- // We have an index (C.17.4)
- size_t index = parseInt2();
- if (index >= qNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return qNameTable[index];
- }
- }
-
- const QName &parseQualifiedNameOrIndex3(std::vector<QName> &qNameTable) { // C.18
- uint8_t b = *dataP;
- if ((b & 0x3c) == 0x3c) { // xx1111..
- // We have a literal (C.18.3)
- ++dataP;
- QName result;
- // prefix (C.18.3.1)
- result.prefix = b & 0x02 ? parseIdentifyingStringOrIndex(vocabulary.prefixTable) : std::string();
- // namespace-name (C.18.3.1)
- result.uri = b & 0x01 ? parseIdentifyingStringOrIndex(vocabulary.namespaceNameTable) : std::string();
- // local-name
- result.name = parseIdentifyingStringOrIndex(vocabulary.localNameTable);
- qNameTable.push_back(result);
- return qNameTable.back();
- }
- else {
- // We have an index (C.18.4)
- size_t index = parseInt3();
- if (index >= qNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return qNameTable[index];
- }
- }
-
- std::shared_ptr<const FIValue> parseNonIdentifyingStringOrIndex1(std::vector<std::shared_ptr<const FIValue>> &valueTable) { // C.14
- uint8_t b = *dataP;
- if (b == 0xff) { // C.26.2
- // empty string
- ++dataP;
- return EmptyFIString;
- }
- else if (b & 0x80) { // C.14.4
- // We have an index
- size_t index = parseInt2();
- if (index >= valueTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return valueTable[index];
- }
- else { // C.14.3
- // We have a literal
- std::shared_ptr<const FIValue> result = parseEncodedCharacterString3();
- if (b & 0x40) { // C.14.3.1
- valueTable.push_back(result);
- }
- return result;
- }
- }
-
- std::shared_ptr<const FIValue> parseNonIdentifyingStringOrIndex3(std::vector<std::shared_ptr<const FIValue>> &valueTable) { // C.15
- uint8_t b = *dataP;
- if (b & 0x20) { // C.15.4
- // We have an index
- size_t index = parseInt4();
- if (index >= valueTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return valueTable[index];
- }
- else { // C.15.3
- // We have a literal
- std::shared_ptr<const FIValue> result = parseEncodedCharacterString5();
- if (b & 0x10) { // C.15.3.1
- valueTable.push_back(result);
- }
- return result;
- }
- }
-
- void parseElement() {
- // C.3
-
- attributes.clear();
-
- uint8_t b = *dataP;
- bool hasAttributes = (b & 0x40) != 0; // C.3.3
- if ((b & 0x3f) == 0x38) { // C.3.4.1
- // Parse namespaces
- ++dataP;
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- b = *dataP++;
- if (b == 0xf0) { // C.3.4.3
- break;
- }
- if ((b & 0xfc) != 0xcc) { // C.3.4.2
- throw DeadlyImportError(parseErrorMessage);
- }
- // C.12
- Attribute attr;
- attr.qname.prefix = "xmlns";
- attr.qname.name = b & 0x02 ? parseIdentifyingStringOrIndex(vocabulary.prefixTable) : std::string();
- attr.qname.uri = b & 0x01 ? parseIdentifyingStringOrIndex(vocabulary.namespaceNameTable) : std::string();
- attr.name = attr.qname.name.empty() ? "xmlns" : "xmlns:" + attr.qname.name;
- attr.value = FIStringValue::create(std::string(attr.qname.uri));
- attributes.push_back(attr);
- }
- if ((dataEnd - dataP < 1) || (*dataP & 0xc0)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- }
-
- // Parse Element name (C.3.5)
- const QName &elemName = parseQualifiedNameOrIndex3(vocabulary.elementNameTable);
- nodeName = elemName.prefix.empty() ? elemName.name : elemName.prefix + ':' + elemName.name;
-
- if (hasAttributes) {
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- b = *dataP;
- if (b < 0x80) { // C.3.6.1
- // C.4
- Attribute attr;
- attr.qname = parseQualifiedNameOrIndex2(vocabulary.attributeNameTable);
- attr.name = attr.qname.prefix.empty() ? attr.qname.name : attr.qname.prefix + ':' + attr.qname.name;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- attr.value = parseNonIdentifyingStringOrIndex1(vocabulary.attributeValueTable);
- attributes.push_back(attr);
- }
- else {
- if ((b & 0xf0) != 0xf0) { // C.3.6.2
- throw DeadlyImportError(parseErrorMessage);
- }
- emptyElement = b == 0xff; // C.3.6.2, C.3.8
- ++dataP;
- break;
- }
- }
- }
- else {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- b = *dataP;
- switch (b) {
- case 0xff:
- terminatorPending = true;
- // Intentionally fall through
- case 0xf0:
- emptyElement = true;
- ++dataP;
- break;
- default:
- emptyElement = false;
- }
- }
- if (!emptyElement) {
- elementStack.push(nodeName);
- }
-
- currentNodeType = irr::io::EXN_ELEMENT;
- }
-
- void parseHeader() {
- // Parse header (C.1.3)
- size_t magicSize = parseMagic(dataP, dataEnd);
- if (!magicSize) {
- throw DeadlyImportError(parseErrorMessage);
- }
- dataP += magicSize;
- // C.2.3
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b = *dataP++;
- if (b & 0x40) {
- // Parse additional data (C.2.4)
- size_t len = parseSequenceLen();
- for (size_t i = 0; i < len; ++i) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::string id =*/ parseNonEmptyOctetString2();
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::string data =*/ parseNonEmptyOctetString2();
- }
- }
- if (b & 0x20) {
- // Parse initial vocabulary (C.2.5)
- if (dataEnd - dataP < 2) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint16_t b1 = (dataP[0] << 8) | dataP[1];
- dataP += 2;
- if (b1 & 0x1000) {
- // External vocabulary (C.2.5.2)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::string uri = parseNonEmptyOctetString2();
- auto it = vocabularyMap.find(uri);
- if (it == vocabularyMap.end()) {
- throw DeadlyImportError("Unknown vocabulary " + uri);
- }
- const FIVocabulary *externalVocabulary = it->second;
- if (externalVocabulary->restrictedAlphabetTable) {
- std::copy(externalVocabulary->restrictedAlphabetTable, externalVocabulary->restrictedAlphabetTable + externalVocabulary->restrictedAlphabetTableSize, std::back_inserter(vocabulary.restrictedAlphabetTable));
- }
- if (externalVocabulary->encodingAlgorithmTable) {
- std::copy(externalVocabulary->encodingAlgorithmTable, externalVocabulary->encodingAlgorithmTable + externalVocabulary->encodingAlgorithmTableSize, std::back_inserter(vocabulary.encodingAlgorithmTable));
- }
- if (externalVocabulary->prefixTable) {
- std::copy(externalVocabulary->prefixTable, externalVocabulary->prefixTable + externalVocabulary->prefixTableSize, std::back_inserter(vocabulary.prefixTable));
- }
- if (externalVocabulary->namespaceNameTable) {
- std::copy(externalVocabulary->namespaceNameTable, externalVocabulary->namespaceNameTable + externalVocabulary->namespaceNameTableSize, std::back_inserter(vocabulary.namespaceNameTable));
- }
- if (externalVocabulary->localNameTable) {
- std::copy(externalVocabulary->localNameTable, externalVocabulary->localNameTable + externalVocabulary->localNameTableSize, std::back_inserter(vocabulary.localNameTable));
- }
- if (externalVocabulary->otherNCNameTable) {
- std::copy(externalVocabulary->otherNCNameTable, externalVocabulary->otherNCNameTable + externalVocabulary->otherNCNameTableSize, std::back_inserter(vocabulary.otherNCNameTable));
- }
- if (externalVocabulary->otherURITable) {
- std::copy(externalVocabulary->otherURITable, externalVocabulary->otherURITable + externalVocabulary->otherURITableSize, std::back_inserter(vocabulary.otherURITable));
- }
- if (externalVocabulary->attributeValueTable) {
- std::copy(externalVocabulary->attributeValueTable, externalVocabulary->attributeValueTable + externalVocabulary->attributeValueTableSize, std::back_inserter(vocabulary.attributeValueTable));
- }
- if (externalVocabulary->charactersTable) {
- std::copy(externalVocabulary->charactersTable, externalVocabulary->charactersTable + externalVocabulary->charactersTableSize, std::back_inserter(vocabulary.charactersTable));
- }
- if (externalVocabulary->otherStringTable) {
- std::copy(externalVocabulary->otherStringTable, externalVocabulary->otherStringTable + externalVocabulary->otherStringTableSize, std::back_inserter(vocabulary.otherStringTable));
- }
- if (externalVocabulary->elementNameTable) {
- std::copy(externalVocabulary->elementNameTable, externalVocabulary->elementNameTable + externalVocabulary->elementNameTableSize, std::back_inserter(vocabulary.elementNameTable));
- }
- if (externalVocabulary->attributeNameTable) {
- std::copy(externalVocabulary->attributeNameTable, externalVocabulary->attributeNameTable + externalVocabulary->attributeNameTableSize, std::back_inserter(vocabulary.attributeNameTable));
- }
- }
- if (b1 & 0x0800) {
- // Parse restricted alphabets (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.restrictedAlphabetTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0400) {
- // Parse encoding algorithms (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.encodingAlgorithmTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0200) {
- // Parse prefixes (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.prefixTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0100) {
- // Parse namespace names (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.namespaceNameTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0080) {
- // Parse local names (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.localNameTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0040) {
- // Parse other ncnames (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.otherNCNameTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0020) {
- // Parse other uris (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.otherURITable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0010) {
- // Parse attribute values (C.2.5.4)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.attributeValueTable.push_back(parseEncodedCharacterString3());
- }
- }
- if (b1 & 0x0008) {
- // Parse content character chunks (C.2.5.4)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.charactersTable.push_back(parseEncodedCharacterString3());
- }
- }
- if (b1 & 0x0004) {
- // Parse other strings (C.2.5.4)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.otherStringTable.push_back(parseEncodedCharacterString3());
- }
- }
- if (b1 & 0x0002) {
- // Parse element name surrogates (C.2.5.5)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- vocabulary.elementNameTable.push_back(parseNameSurrogate());
- }
- }
- if (b1 & 0x0001) {
- // Parse attribute name surrogates (C.2.5.5)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- vocabulary.attributeNameTable.push_back(parseNameSurrogate());
- }
- }
- }
- if (b & 0x10) {
- // Parse notations (C.2.6)
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b1 = *dataP++;
- if (b1 == 0xf0) {
- break;
- }
- if ((b1 & 0xfc) != 0xc0) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /* C.11 */
- /*const std::string &name =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- if (b1 & 0x02) {
- /*const std::string &systemId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- if (b1 & 0x01) {
- /*const std::string &publicId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- }
- }
- if (b & 0x08) {
- // Parse unparsed entities (C.2.7)
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b1 = *dataP++;
- if (b1 == 0xf0) {
- break;
- }
- if ((b1 & 0xfe) != 0xd0) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /* C.10 */
- /*const std::string &name =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- /*const std::string &systemId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- if (b1 & 0x01) {
- /*const std::string &publicId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- /*const std::string &notationName =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- }
- }
- if (b & 0x04) {
- // Parse character encoding scheme (C.2.8)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::string characterEncodingScheme =*/ parseNonEmptyOctetString2();
- }
- if (b & 0x02) {
- // Parse standalone flag (C.2.9)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b1 = *dataP++;
- if (b1 & 0xfe) {
- throw DeadlyImportError(parseErrorMessage);
- }
- //bool standalone = b1 & 0x01;
- }
- if (b & 0x01) {
- // Parse version (C.2.10)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::shared_ptr<const FIValue> version =*/ parseNonIdentifyingStringOrIndex1(vocabulary.otherStringTable);
- }
- }
-
- std::unique_ptr<uint8_t[]> data;
- uint8_t *dataP, *dataEnd;
- irr::io::EXML_NODE currentNodeType;
- bool emptyElement;
- bool headerPending;
- bool terminatorPending;
- Vocabulary vocabulary;
- std::vector<Attribute> attributes;
- std::stack<std::string> elementStack;
- std::string nodeName;
- std::map<std::string, std::unique_ptr<FIDecoder>> decoderMap;
- std::map<std::string, const FIVocabulary*> vocabularyMap;
-
- static const std::string EmptyString;
- static std::shared_ptr<const FIValue> EmptyFIString;
-
- static FIHexDecoder hexDecoder;
- static FIBase64Decoder base64Decoder;
- static FIShortDecoder shortDecoder;
- static FIIntDecoder intDecoder;
- static FILongDecoder longDecoder;
- static FIBoolDecoder boolDecoder;
- static FIFloatDecoder floatDecoder;
- static FIDoubleDecoder doubleDecoder;
- static FIUUIDDecoder uuidDecoder;
- static FICDATADecoder cdataDecoder;
- static FIDecoder *defaultDecoder[32];
-};
-
-const std::string CFIReaderImpl::EmptyString;
-std::shared_ptr<const FIValue> CFIReaderImpl::EmptyFIString = FIStringValue::create(std::string());
-
-FIHexDecoder CFIReaderImpl::hexDecoder;
-FIBase64Decoder CFIReaderImpl::base64Decoder;
-FIShortDecoder CFIReaderImpl::shortDecoder;
-FIIntDecoder CFIReaderImpl::intDecoder;
-FILongDecoder CFIReaderImpl::longDecoder;
-FIBoolDecoder CFIReaderImpl::boolDecoder;
-FIFloatDecoder CFIReaderImpl::floatDecoder;
-FIDoubleDecoder CFIReaderImpl::doubleDecoder;
-FIUUIDDecoder CFIReaderImpl::uuidDecoder;
-FICDATADecoder CFIReaderImpl::cdataDecoder;
-
-FIDecoder *CFIReaderImpl::defaultDecoder[32] = {
- &hexDecoder,
- &base64Decoder,
- &shortDecoder,
- &intDecoder,
- &longDecoder,
- &boolDecoder,
- &floatDecoder,
- &doubleDecoder,
- &uuidDecoder,
- &cdataDecoder
-};
-
-class CXMLReaderImpl : public FIReader
-{
-public:
-
- //! Constructor
- CXMLReaderImpl(std::unique_ptr<irr::io::IIrrXMLReader<char, irr::io::IXMLBase>> reader_)
- : reader(std::move(reader_))
- {}
-
- virtual ~CXMLReaderImpl() {}
-
- virtual bool read() /*override*/ {
- return reader->read();
- }
-
- virtual irr::io::EXML_NODE getNodeType() const /*override*/ {
- return reader->getNodeType();
- }
-
- virtual int getAttributeCount() const /*override*/ {
- return reader->getAttributeCount();
- }
-
- virtual const char* getAttributeName(int idx) const /*override*/ {
- return reader->getAttributeName(idx);
- }
-
- virtual const char* getAttributeValue(int idx) const /*override*/ {
- return reader->getAttributeValue(idx);
- }
-
- virtual const char* getAttributeValue(const char* name) const /*override*/ {
- return reader->getAttributeValue(name);
- }
-
- virtual const char* getAttributeValueSafe(const char* name) const /*override*/ {
- return reader->getAttributeValueSafe(name);
- }
-
- virtual int getAttributeValueAsInt(const char* name) const /*override*/ {
- return reader->getAttributeValueAsInt(name);
- }
-
- virtual int getAttributeValueAsInt(int idx) const /*override*/ {
- return reader->getAttributeValueAsInt(idx);
- }
-
- virtual float getAttributeValueAsFloat(const char* name) const /*override*/ {
- return reader->getAttributeValueAsFloat(name);
- }
-
- virtual float getAttributeValueAsFloat(int idx) const /*override*/ {
- return reader->getAttributeValueAsFloat(idx);
- }
-
- virtual const char* getNodeName() const /*override*/ {
- return reader->getNodeName();
- }
-
- virtual const char* getNodeData() const /*override*/ {
- return reader->getNodeData();
- }
-
- virtual bool isEmptyElement() const /*override*/ {
- return reader->isEmptyElement();
- }
-
- virtual irr::io::ETEXT_FORMAT getSourceFormat() const /*override*/ {
- return reader->getSourceFormat();
- }
-
- virtual irr::io::ETEXT_FORMAT getParserFormat() const /*override*/ {
- return reader->getParserFormat();
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int /*idx*/) const /*override*/ {
- return nullptr;
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char* /*name*/) const /*override*/ {
- return nullptr;
- }
-
- virtual void registerDecoder(const std::string & /*algorithmUri*/, std::unique_ptr<FIDecoder> /*decoder*/) /*override*/ {}
-
-
- virtual void registerVocabulary(const std::string &/*vocabularyUri*/, const FIVocabulary * /*vocabulary*/) /*override*/ {}
-
-private:
-
- std::unique_ptr<irr::io::IIrrXMLReader<char, irr::io::IXMLBase>> reader;
-};
-
-static std::unique_ptr<uint8_t[]> readFile(IOStream *stream, size_t &size, bool &isFI) {
- size = stream->FileSize();
- std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>(new uint8_t[size]);
- if (stream->Read(data.get(), size, 1) != 1) {
- size = 0;
- data.reset();
- }
- isFI = parseMagic(data.get(), data.get() + size) > 0;
- return data;
-}
-
-std::unique_ptr<FIReader> FIReader::create(IOStream *stream)
-{
- size_t size;
- bool isFI;
- auto data = readFile(stream, size, isFI);
- if (isFI) {
- return std::unique_ptr<FIReader>(new CFIReaderImpl(std::move(data), size));
- }
- else {
- auto memios = std::unique_ptr<MemoryIOStream>(new MemoryIOStream(data.release(), size, true));
- auto callback = std::unique_ptr<CIrrXML_IOStreamReader>(new CIrrXML_IOStreamReader(memios.get()));
- return std::unique_ptr<FIReader>(new CXMLReaderImpl(std::unique_ptr<irr::io::IIrrXMLReader<char, irr::io::IXMLBase>>(createIrrXMLReader(callback.get()))));
- }
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER