/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------

Copyright (c) 2006-2017, 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 "StringUtils.h"

// Workaround for issue #1361
// https://github.com/assimp/assimp/issues/1361
#ifdef __ANDROID__
#  define _GLIBCXX_USE_C99 1
#endif

#include "Exceptional.h"
#include <assimp/IOStream.hpp>
#include <assimp/types.h>
#include "MemoryIOWrapper.h"
#include "irrXMLWrapper.h"
#include "../contrib/utf8cpp/source/utf8.h"
#include "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
