summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/assimp/contrib/irrXML/CXMLReaderImpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/assimp/contrib/irrXML/CXMLReaderImpl.h')
-rw-r--r--src/3rdparty/assimp/contrib/irrXML/CXMLReaderImpl.h809
1 files changed, 0 insertions, 809 deletions
diff --git a/src/3rdparty/assimp/contrib/irrXML/CXMLReaderImpl.h b/src/3rdparty/assimp/contrib/irrXML/CXMLReaderImpl.h
deleted file mode 100644
index 63b700dc1..000000000
--- a/src/3rdparty/assimp/contrib/irrXML/CXMLReaderImpl.h
+++ /dev/null
@@ -1,809 +0,0 @@
-// Copyright (C) 2002-2005 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine" and the "irrXML" project.
-// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h
-
-#ifndef __ICXML_READER_IMPL_H_INCLUDED__
-#define __ICXML_READER_IMPL_H_INCLUDED__
-
-#include "irrXML.h"
-#include "irrString.h"
-#include "irrArray.h"
-
-using namespace Assimp;
-
-#ifdef _DEBUG
-#define IRR_DEBUGPRINT(x) printf((x));
-#else // _DEBUG
-#define IRR_DEBUGPRINT(x)
-#endif // _DEBUG
-
-
-namespace irr
-{
-namespace io
-{
-
-
-//! implementation of the IrrXMLReader
-template<class char_type, class superclass>
-class CXMLReaderImpl : public IIrrXMLReader<char_type, superclass>
-{
-public:
-
- //! Constructor
- CXMLReaderImpl(IFileReadCallBack* callback, bool deleteCallBack = true)
- : TextData(0), P(0), TextBegin(0), TextSize(0), CurrentNodeType(EXN_NONE),
- SourceFormat(ETF_ASCII), TargetFormat(ETF_ASCII)
- {
- if (!callback)
- return;
-
- storeTargetFormat();
-
- // read whole xml file
-
- readFile(callback);
-
- // clean up
-
- if (deleteCallBack)
- delete callback;
-
- // create list with special characters
-
- createSpecialCharacterList();
-
- // set pointer to text begin
- P = TextBegin;
- }
-
-
- //! Destructor
- virtual ~CXMLReaderImpl()
- {
- delete [] TextData;
- }
-
-
- //! Reads forward to the next xml node.
- //! \return Returns false, if there was no further node.
- virtual bool read()
- {
- // if not end reached, parse the node
- if (P && (unsigned int)(P - TextBegin) < TextSize - 1 && *P != 0)
- {
- parseCurrentNode();
- return true;
- }
-
- _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
- return false;
- }
-
-
- //! Returns the type of the current XML node.
- virtual EXML_NODE getNodeType() const
- {
- return CurrentNodeType;
- }
-
-
- //! Returns attribute count of the current XML node.
- virtual int getAttributeCount() const
- {
- return Attributes.size();
- }
-
-
- //! Returns name of an attribute.
- virtual const char_type* getAttributeName(int idx) const
- {
- if (idx < 0 || idx >= (int)Attributes.size())
- return 0;
-
- return Attributes[idx].Name.c_str();
- }
-
-
- //! Returns the value of an attribute.
- virtual const char_type* getAttributeValue(int idx) const
- {
- if (idx < 0 || idx >= (int)Attributes.size())
- return 0;
-
- return Attributes[idx].Value.c_str();
- }
-
-
- //! Returns the value of an attribute.
- virtual const char_type* getAttributeValue(const char_type* name) const
- {
- const SAttribute* attr = getAttributeByName(name);
- if (!attr)
- return 0;
-
- return attr->Value.c_str();
- }
-
-
- //! Returns the value of an attribute
- virtual const char_type* getAttributeValueSafe(const char_type* name) const
- {
- const SAttribute* attr = getAttributeByName(name);
- if (!attr)
- return EmptyString.c_str();
-
- return attr->Value.c_str();
- }
-
-
-
- //! Returns the value of an attribute as integer.
- int getAttributeValueAsInt(const char_type* name) const
- {
- return (int)getAttributeValueAsFloat(name);
- }
-
-
- //! Returns the value of an attribute as integer.
- int getAttributeValueAsInt(int idx) const
- {
- return (int)getAttributeValueAsFloat(idx);
- }
-
-
- //! Returns the value of an attribute as float.
- float getAttributeValueAsFloat(const char_type* name) const
- {
- const SAttribute* attr = getAttributeByName(name);
- if (!attr)
- return 0;
-
- core::stringc c = attr->Value.c_str();
- return fast_atof(c.c_str());
- }
-
-
- //! Returns the value of an attribute as float.
- float getAttributeValueAsFloat(int idx) const
- {
- const char_type* attrvalue = getAttributeValue(idx);
- if (!attrvalue)
- return 0;
-
- core::stringc c = attrvalue;
- return fast_atof(c.c_str());
- }
-
-
- //! Returns the name of the current node.
- virtual const char_type* getNodeName() const
- {
- return NodeName.c_str();
- }
-
-
- //! Returns data of the current node.
- virtual const char_type* getNodeData() const
- {
- return NodeName.c_str();
- }
-
-
- //! Returns if an element is an empty element, like <foo />
- virtual bool isEmptyElement() const
- {
- return IsEmptyElement;
- }
-
- //! Returns format of the source xml file.
- virtual ETEXT_FORMAT getSourceFormat() const
- {
- return SourceFormat;
- }
-
- //! Returns format of the strings returned by the parser.
- virtual ETEXT_FORMAT getParserFormat() const
- {
- return TargetFormat;
- }
-
-private:
-
- // Reads the current xml node
- void parseCurrentNode()
- {
- char_type* start = P;
-
- // move forward until '<' found
- while(*P != L'<' && *P)
- ++P;
-
- if (!*P)
- return;
-
- if (P - start > 0)
- {
- // we found some text, store it
- if (setText(start, P))
- return;
- }
-
- ++P;
-
- // based on current token, parse and report next element
- switch(*P)
- {
- case L'/':
- parseClosingXMLElement();
- break;
- case L'?':
- ignoreDefinition();
- break;
- case L'!':
- if (!parseCDATA())
- parseComment();
- break;
- default:
- parseOpeningXMLElement();
- break;
- }
- }
-
-
- //! sets the state that text was found. Returns true if set should be set
- bool setText(char_type* start, char_type* end)
- {
- // check if text is more than 2 characters, and if not, check if there is
- // only white space, so that this text won't be reported
- if (end - start < 3)
- {
- char_type* p = start;
- for(; p != end; ++p)
- if (!isWhiteSpace(*p))
- break;
-
- if (p == end)
- return false;
- }
-
- // set current text to the parsed text, and replace xml special characters
- core::string<char_type> s(start, (int)(end - start));
- NodeName = replaceSpecialCharacters(s);
-
- // current XML node type is text
- CurrentNodeType = EXN_TEXT;
-
- return true;
- }
-
-
-
- //! ignores an xml definition like <?xml something />
- void ignoreDefinition()
- {
- CurrentNodeType = EXN_UNKNOWN;
-
- // move until end marked with '>' reached
- while(*P != L'>')
- ++P;
-
- ++P;
- }
-
-
- //! parses a comment
- void parseComment()
- {
- CurrentNodeType = EXN_COMMENT;
- P += 1;
-
- char_type *pCommentBegin = P;
-
- int count = 1;
-
- // move until end of comment reached
- while(count)
- {
- if (*P == L'>')
- --count;
- else
- if (*P == L'<')
- ++count;
-
- ++P;
- }
-
- P -= 3;
- NodeName = core::string<char_type>(pCommentBegin+2, (int)(P - pCommentBegin-2));
- P += 3;
- }
-
-
- //! parses an opening xml element and reads attributes
- void parseOpeningXMLElement()
- {
- CurrentNodeType = EXN_ELEMENT;
- IsEmptyElement = false;
- Attributes.clear();
-
- // find name
- const char_type* startName = P;
-
- // find end of element
- while(*P != L'>' && !isWhiteSpace(*P))
- ++P;
-
- const char_type* endName = P;
-
- // find Attributes
- while(*P != L'>')
- {
- if (isWhiteSpace(*P))
- ++P;
- else
- {
- if (*P != L'/')
- {
- // we've got an attribute
-
- // read the attribute names
- const char_type* attributeNameBegin = P;
-
- while(!isWhiteSpace(*P) && *P != L'=')
- ++P;
-
- const char_type* attributeNameEnd = P;
- ++P;
-
- // read the attribute value
- // check for quotes and single quotes, thx to murphy
- while( (*P != L'\"') && (*P != L'\'') && *P)
- ++P;
-
- if (!*P) // malformatted xml file
- return;
-
- const char_type attributeQuoteChar = *P;
-
- ++P;
- const char_type* attributeValueBegin = P;
-
- while(*P != attributeQuoteChar && *P)
- ++P;
-
- if (!*P) // malformatted xml file
- return;
-
- const char_type* attributeValueEnd = P;
- ++P;
-
- SAttribute attr;
- attr.Name = core::string<char_type>(attributeNameBegin,
- (int)(attributeNameEnd - attributeNameBegin));
-
- core::string<char_type> s(attributeValueBegin,
- (int)(attributeValueEnd - attributeValueBegin));
-
- attr.Value = replaceSpecialCharacters(s);
- Attributes.push_back(attr);
- }
- else
- {
- // tag is closed directly
- ++P;
- IsEmptyElement = true;
- break;
- }
- }
- }
-
- // check if this tag is closing directly
- if (endName > startName && *(endName-1) == L'/')
- {
- // directly closing tag
- IsEmptyElement = true;
- endName--;
- }
-
- NodeName = core::string<char_type>(startName, (int)(endName - startName));
-
- ++P;
- }
-
-
- //! parses an closing xml tag
- void parseClosingXMLElement()
- {
- CurrentNodeType = EXN_ELEMENT_END;
- IsEmptyElement = false;
- Attributes.clear();
-
- ++P;
- const char_type* pBeginClose = P;
-
- while(*P != L'>')
- ++P;
-
- // remove trailing whitespace, if any
- while( isspace( P[-1]))
- --P;
-
- NodeName = core::string<char_type>(pBeginClose, (int)(P - pBeginClose));
- ++P;
- }
-
- //! parses a possible CDATA section, returns false if begin was not a CDATA section
- bool parseCDATA()
- {
- if (*(P+1) != L'[')
- return false;
-
- CurrentNodeType = EXN_CDATA;
-
- // skip '<![CDATA['
- int count=0;
- while( *P && count<8 )
- {
- ++P;
- ++count;
- }
-
- if (!*P)
- return true;
-
- char_type *cDataBegin = P;
- char_type *cDataEnd = 0;
-
- // find end of CDATA
- while(*P && !cDataEnd)
- {
- if (*P == L'>' &&
- (*(P-1) == L']') &&
- (*(P-2) == L']'))
- {
- cDataEnd = P - 2;
- }
-
- ++P;
- }
-
- if ( cDataEnd )
- NodeName = core::string<char_type>(cDataBegin, (int)(cDataEnd - cDataBegin));
- else
- NodeName = "";
-
- return true;
- }
-
-
- // structure for storing attribute-name pairs
- struct SAttribute
- {
- core::string<char_type> Name;
- core::string<char_type> Value;
- };
-
- // finds a current attribute by name, returns 0 if not found
- const SAttribute* getAttributeByName(const char_type* name) const
- {
- if (!name)
- return 0;
-
- core::string<char_type> n = name;
-
- for (int i=0; i<(int)Attributes.size(); ++i)
- if (Attributes[i].Name == n)
- return &Attributes[i];
-
- return 0;
- }
-
- // replaces xml special characters in a string and creates a new one
- core::string<char_type> replaceSpecialCharacters(
- core::string<char_type>& origstr)
- {
- int pos = origstr.findFirst(L'&');
- int oldPos = 0;
-
- if (pos == -1)
- return origstr;
-
- core::string<char_type> newstr;
-
- while(pos != -1 && pos < origstr.size()-2)
- {
- // check if it is one of the special characters
-
- int specialChar = -1;
- for (int i=0; i<(int)SpecialCharacters.size(); ++i)
- {
- const char_type* p = &origstr.c_str()[pos]+1;
-
- if (equalsn(&SpecialCharacters[i][1], p, SpecialCharacters[i].size()-1))
- {
- specialChar = i;
- break;
- }
- }
-
- if (specialChar != -1)
- {
- newstr.append(origstr.subString(oldPos, pos - oldPos));
- newstr.append(SpecialCharacters[specialChar][0]);
- pos += SpecialCharacters[specialChar].size();
- }
- else
- {
- newstr.append(origstr.subString(oldPos, pos - oldPos + 1));
- pos += 1;
- }
-
- // find next &
- oldPos = pos;
- pos = origstr.findNext(L'&', pos);
- }
-
- if (oldPos < origstr.size()-1)
- newstr.append(origstr.subString(oldPos, origstr.size()-oldPos));
-
- return newstr;
- }
-
-
-
- //! reads the xml file and converts it into the wanted character format.
- bool readFile(IFileReadCallBack* callback)
- {
- int size = callback->getSize();
- size += 4; // We need two terminating 0's at the end.
- // For ASCII we need 1 0's, for UTF-16 2, for UTF-32 4.
-
- char* data8 = new char[size];
-
- if (!callback->read(data8, size-4))
- {
- delete [] data8;
- return false;
- }
-
- // add zeros at end
-
- data8[size-1] = 0;
- data8[size-2] = 0;
- data8[size-3] = 0;
- data8[size-4] = 0;
-
- char16* data16 = reinterpret_cast<char16*>(data8);
- char32* data32 = reinterpret_cast<char32*>(data8);
-
- // now we need to convert the data to the desired target format
- // based on the byte order mark.
-
- const unsigned char UTF8[] = {0xEF, 0xBB, 0xBF}; // 0xEFBBBF;
- const int UTF16_BE = 0xFFFE;
- const int UTF16_LE = 0xFEFF;
- const int UTF32_BE = 0xFFFE0000;
- const int UTF32_LE = 0x0000FEFF;
-
- // check source for all utf versions and convert to target data format
-
- if (size >= 4 && data32[0] == (char32)UTF32_BE)
- {
- // UTF-32, big endian
- SourceFormat = ETF_UTF32_BE;
- convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header
- }
- else
- if (size >= 4 && data32[0] == (char32)UTF32_LE)
- {
- // UTF-32, little endian
- SourceFormat = ETF_UTF32_LE;
- convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header
- }
- else
- if (size >= 2 && data16[0] == UTF16_BE)
- {
- // UTF-16, big endian
- SourceFormat = ETF_UTF16_BE;
- convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header
- }
- else
- if (size >= 2 && data16[0] == UTF16_LE)
- {
- // UTF-16, little endian
- SourceFormat = ETF_UTF16_LE;
- convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header
- }
- else
- if (size >= 3 && data8[0] == UTF8[0] && data8[1] == UTF8[1] && data8[2] == UTF8[2])
- {
- // UTF-8
- SourceFormat = ETF_UTF8;
- convertTextData(data8+3, data8, size); // data8+3 because we need to skip the header
- }
- else
- {
- // ASCII
- SourceFormat = ETF_ASCII;
- convertTextData(data8, data8, size);
- }
-
- return true;
- }
-
-
- //! converts the text file into the desired format.
- //! \param source: begin of the text (without byte order mark)
- //! \param pointerToStore: pointer to text data block which can be
- //! stored or deleted based on the nesessary conversion.
- //! \param sizeWithoutHeader: Text size in characters without header
- template<class src_char_type>
- void convertTextData(src_char_type* source, char* pointerToStore, int sizeWithoutHeader)
- {
- // convert little to big endian if necessary
- if (sizeof(src_char_type) > 1 &&
- isLittleEndian(TargetFormat) != isLittleEndian(SourceFormat))
- convertToLittleEndian(source);
-
- // check if conversion is necessary:
- if (sizeof(src_char_type) == sizeof(char_type))
- {
- // no need to convert
- TextBegin = (char_type*)source;
- TextData = (char_type*)pointerToStore;
- TextSize = sizeWithoutHeader;
- }
- else
- {
- // convert source into target data format.
- // TODO: implement a real conversion. This one just
- // copies bytes. This is a problem when there are
- // unicode symbols using more than one character.
-
- TextData = new char_type[sizeWithoutHeader];
-
- // MSVC debugger complains here about loss of data ...
-
-
- // FIXME - gcc complains about 'shift width larger than width of type'
- // for T == unsigned long. Avoid it by messing around volatile ..
- volatile unsigned int c = 3;
- const src_char_type cc = (src_char_type)((((uint64_t)1u << (sizeof( char_type)<<c)) - 1));
- for (int i=0; i<sizeWithoutHeader; ++i)
- TextData[i] = char_type( source[i] & cc);
-
- TextBegin = TextData;
- TextSize = sizeWithoutHeader;
-
- // delete original data because no longer needed
- delete [] pointerToStore;
- }
- }
-
- //! converts whole text buffer to little endian
- template<class src_char_type>
- void convertToLittleEndian(src_char_type* t)
- {
- if (sizeof(src_char_type) == 4)
- {
- // 32 bit
-
- while(*t)
- {
- *t = ((*t & 0xff000000) >> 24) |
- ((*t & 0x00ff0000) >> 8) |
- ((*t & 0x0000ff00) << 8) |
- ((*t & 0x000000ff) << 24);
- ++t;
- }
- }
- else
- {
- // 16 bit
-
- while(*t)
- {
- *t = (*t >> 8) | (*t << 8);
- ++t;
- }
- }
- }
-
- //! returns if a format is little endian
- inline bool isLittleEndian(ETEXT_FORMAT f)
- {
- return f == ETF_ASCII ||
- f == ETF_UTF8 ||
- f == ETF_UTF16_LE ||
- f == ETF_UTF32_LE;
- }
-
-
- //! returns true if a character is whitespace
- inline bool isWhiteSpace(char_type c)
- {
- return (c==' ' || c=='\t' || c=='\n' || c=='\r');
- }
-
-
- //! generates a list with xml special characters
- void createSpecialCharacterList()
- {
- // list of strings containing special symbols,
- // the first character is the special character,
- // the following is the symbol string without trailing &.
-
- SpecialCharacters.push_back("&amp;");
- SpecialCharacters.push_back("<lt;");
- SpecialCharacters.push_back(">gt;");
- SpecialCharacters.push_back("\"quot;");
- SpecialCharacters.push_back("'apos;");
-
- }
-
-
- //! compares the first n characters of the strings
- bool equalsn(const char_type* str1, const char_type* str2, int len)
- {
- int i;
- for(i=0; str1[i] && str2[i] && i < len; ++i)
- if (str1[i] != str2[i])
- return false;
-
- // if one (or both) of the strings was smaller then they
- // are only equal if they have the same lenght
- return (i == len) || (str1[i] == 0 && str2[i] == 0);
- }
-
-
- //! stores the target text format
- void storeTargetFormat()
- {
- // get target format. We could have done this using template specialization,
- // but VisualStudio 6 don't like it and we want to support it.
-
- switch(sizeof(char_type))
- {
- case 1:
- TargetFormat = ETF_UTF8;
- break;
- case 2:
- TargetFormat = ETF_UTF16_LE;
- break;
- case 4:
- TargetFormat = ETF_UTF32_LE;
- break;
- default:
- TargetFormat = ETF_ASCII; // should never happen.
- }
- }
-
-
- // instance variables:
-
- char_type* TextData; // data block of the text file
- char_type* P; // current point in text to parse
- char_type* TextBegin; // start of text to parse
- unsigned int TextSize; // size of text to parse in characters, not bytes
-
- EXML_NODE CurrentNodeType; // type of the currently parsed node
- ETEXT_FORMAT SourceFormat; // source format of the xml file
- ETEXT_FORMAT TargetFormat; // output format of this parser
-
- core::string<char_type> NodeName; // name of the node currently in
- core::string<char_type> EmptyString; // empty string to be returned by getSafe() methods
-
- bool IsEmptyElement; // is the currently parsed node empty?
-
- core::array< core::string<char_type> > SpecialCharacters; // see createSpecialCharacterList()
-
- core::array<SAttribute> Attributes; // attributes of current element
-
-}; // end CXMLReaderImpl
-
-
-} // end namespace
-} // end namespace
-
-#endif