diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PxShared/src/fastxml | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'PxShared/src/fastxml')
| -rw-r--r-- | PxShared/src/fastxml/include/PsFastXml.h | 167 | ||||
| -rw-r--r-- | PxShared/src/fastxml/src/PsFastXml.cpp | 830 |
2 files changed, 997 insertions, 0 deletions
diff --git a/PxShared/src/fastxml/include/PsFastXml.h b/PxShared/src/fastxml/include/PsFastXml.h new file mode 100644 index 00000000..7fe91c09 --- /dev/null +++ b/PxShared/src/fastxml/include/PsFastXml.h @@ -0,0 +1,167 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PSFASTXML_PSFASTXML_H +#define PSFASTXML_PSFASTXML_H + +#include "foundation/PxSimpleTypes.h" // defines basic data types; modify for your platform as needed. +#include "foundation/PxIO.h" +#include "foundation/PxAssert.h" +#include "PsAllocator.h" + +namespace physx +{ +namespace shdfnd +{ + +class FastXml +{ + PX_NOCOPY(FastXml) + + public: + class AttributePairs + { + int argc; + const char** argv; + + public: + AttributePairs() : argc(0), argv(NULL) + { + } + AttributePairs(int c, const char** v) : argc(c), argv(v) + { + } + + PX_INLINE int getNbAttr() const + { + return argc / 2; + } + + const char* getKey(uint32_t index) const + { + PX_ASSERT((index * 2) < uint32_t(argc)); + return argv[index * 2]; + } + + const char* getValue(uint32_t index) const + { + PX_ASSERT((index * 2 + 1) < uint32_t(argc)); + return argv[index * 2 + 1]; + } + + const char* get(const char* attr) const + { + int32_t count = argc / 2; + for(int32_t i = 0; i < count; ++i) + { + const char* key = argv[i * 2], *value = argv[i * 2 + 1]; + if(strcmp(key, attr) == 0) + return value; + } + + return NULL; + } + }; + + /*** + * Callbacks to the user with the contents of the XML file properly digested. + */ + class Callback + { + public: + virtual ~Callback() + { + } + virtual bool processComment(const char* comment) = 0; // encountered a comment in the XML + + // 'element' is the name of the element that is being closed. + // depth is the recursion depth of this element. + // Return true to continue processing the XML file. + // Return false to stop processing the XML file; leaves the read pointer of the stream right after this close + // tag. + // The bool 'isError' indicates whether processing was stopped due to an error, or intentionally canceled early. + virtual bool processClose(const char* element, uint32_t depth, bool& isError) = 0; // process the 'close' + // indicator for a previously + // encountered element + + // return true to continue processing the XML document, false to skip. + virtual bool processElement(const char* elementName, // name of the element + const char* elementData, // element data, null if none + const AttributePairs& attr, // attributes + int32_t lineno) = 0; // line number in the source XML file + + // process the XML declaration header + virtual bool processXmlDeclaration(const AttributePairs&, // attributes + const char* /*elementData*/, int32_t /*lineno*/) + { + return true; + } + + virtual bool processDoctype(const char* /*rootElement*/, // Root element tag + const char* /*type*/, // SYSTEM or PUBLIC + const char* /*fpi*/, // Formal Public Identifier + const char* /*uri*/) // Path to schema file + { + return true; + } + + virtual void* allocate(uint32_t size) + { + return getAllocator().allocate(size, "FastXml", __FILE__, __LINE__); + } + + virtual void deallocate(void* ptr) + { + getAllocator().deallocate(ptr); + } + }; + + virtual bool processXml(PxInputData& buff, bool streamFromMemory = false) = 0; + + virtual const char* getError(int32_t& lineno) = 0; // report the reason for a parsing error, and the line number + // where it occurred. + + FastXml() + { + } + + virtual void release(void) = 0; + + protected: + virtual ~FastXml() + { + } +}; + +FastXml* createFastXml(FastXml::Callback* iface); + +} // shdfnd +} // physx + +#endif // PSFASTXML_PSFASTXML_H diff --git a/PxShared/src/fastxml/src/PsFastXml.cpp b/PxShared/src/fastxml/src/PsFastXml.cpp new file mode 100644 index 00000000..5969d2a9 --- /dev/null +++ b/PxShared/src/fastxml/src/PsFastXml.cpp @@ -0,0 +1,830 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#include "foundation/PxAssert.h" +#include "Ps.h" +#include "PsFastXml.h" +#include <stdio.h> +#include <string.h> +#include <new> +#include <ctype.h> + +namespace +{ +#define MIN_CLOSE_COUNT 2 +#define DEFAULT_READ_BUFFER_SIZE (16 * 1024) +#define NUM_ENTITY 5 + +struct Entity +{ + const char* str; + unsigned int strLength; + char chr; +}; + +static const Entity entity[NUM_ENTITY] = { + { "<", 4, '<' }, { "&", 5, '&' }, { ">", 4, '>' }, { """, 6, '\"' }, { "'", 6, '\'' } +}; + +class MyFastXml : public physx::shdfnd::FastXml +{ + public: + enum CharType + { + CT_DATA, + CT_EOF, + CT_SOFT, + CT_END_OF_ELEMENT, // either a forward slash or a greater than symbol + CT_END_OF_LINE + }; + + MyFastXml(Callback* c) + { + mStreamFromMemory = true; + mCallback = c; + memset(mTypes, CT_DATA, sizeof(mTypes)); + mTypes[0] = CT_EOF; + mTypes[uint8_t(' ')] = mTypes[uint8_t('\t')] = CT_SOFT; + mTypes[uint8_t('/')] = mTypes[uint8_t('>')] = mTypes[uint8_t('?')] = CT_END_OF_ELEMENT; + mTypes[uint8_t('\n')] = mTypes[uint8_t('\r')] = CT_END_OF_LINE; + mError = 0; + mStackIndex = 0; + mFileBuf = NULL; + mReadBufferEnd = NULL; + mReadBuffer = NULL; + mReadBufferSize = DEFAULT_READ_BUFFER_SIZE; + mOpenCount = 0; + mLastReadLoc = 0; + for(uint32_t i = 0; i < (MAX_STACK + 1); i++) + { + mStack[i] = NULL; + mStackAllocated[i] = false; + } + } + + char* processClose(char c, const char* element, char* scan, int32_t argc, const char** argv, + FastXml::Callback* iface, bool& isError) + { + AttributePairs attr(argc, argv); + isError = true; // by default, if we return null it's due to an error. + if(c == '/' || c == '?') + { + char* slash = const_cast<char*>(static_cast<const char*>(strchr(element, c))); + if(slash) + *slash = 0; + + if(c == '?' && strcmp(element, "xml") == 0) + { + if(!iface->processXmlDeclaration(attr, 0, mLineNo)) + return NULL; + } + else + { + if(!iface->processElement(element, 0, attr, mLineNo)) + { + mError = "User aborted the parsing process"; + return NULL; + } + + pushElement(element); + + const char* close = popElement(); + + if(!iface->processClose(close, mStackIndex, isError)) + { + return NULL; + } + } + + if(!slash) + ++scan; + } + else + { + scan = skipNextData(scan); + char* data = scan; // this is the data portion of the element, only copies memory if we encounter line feeds + char* dest_data = 0; + while(*scan && *scan != '<') + { + if(getCharType(scan) == CT_END_OF_LINE) + { + if(*scan == '\r') + mLineNo++; + dest_data = scan; + *dest_data++ = ' '; // replace the linefeed with a space... + scan = skipNextData(scan); + while(*scan && *scan != '<') + { + if(getCharType(scan) == CT_END_OF_LINE) + { + if(*scan == '\r') + mLineNo++; + *dest_data++ = ' '; // replace the linefeed with a space... + scan = skipNextData(scan); + } + else + { + *dest_data++ = *scan++; + } + } + break; + } + else if('&' == *scan) + { + dest_data = scan; + while(*scan && *scan != '<') + { + if('&' == *scan) + { + if(*(scan + 1) && *(scan + 1) == '#' && *(scan + 2)) + { + if(*(scan + 2) == 'x') + { + // Hexadecimal. + if(!*(scan + 3)) + break; + + char* q = scan + 3; + q = strchr(q, ';'); + + if(!q || !*q) + PX_ASSERT(0); + + --q; + char ch = char(*q > '9' ? (tolower(*q) - 'a' + 10) : *q - '0'); + if(*(--q) != tolower('x')) + ch |= char(*q > '9' ? (tolower(*q) - 'a' + 10) : *q - '0') << 4; + + *dest_data++ = ch; + } + else + { + // Decimal. + if(!*(scan + 2)) + break; + + const char* q = scan + 2; + q = strchr(q, ';'); + + if(!q || !*q) + PX_ASSERT(0); + + --q; + char ch = *q - '0'; + if(*(--q) != '#') + ch |= (*q - '0') * 10; + + *dest_data++ = ch; + } + + char* start = scan; + char* end = strchr(start, ';'); + if(end) + { + *end = 0; + scan = end + 1; + } + + continue; + } + + for(int i = 0; i < NUM_ENTITY; ++i) + { + if(strncmp(entity[i].str, scan, entity[i].strLength) == 0) + { + *dest_data++ = entity[i].chr; + scan += entity[i].strLength; + break; + } + } + } + else + { + *dest_data++ = *scan++; + } + } + break; + } + else + ++scan; + } + + if(*scan == '<') + { + if(scan[1] != '/') + { + PX_ASSERT(mOpenCount > 0); + mOpenCount--; + } + if(dest_data) + { + *dest_data = 0; + } + else + { + *scan = 0; + } + + scan++; // skip it.. + + if(*data == 0) + data = 0; + + if(!iface->processElement(element, data, attr, mLineNo)) + { + mError = "User aborted the parsing process"; + return 0; + } + + pushElement(element); + + // check for the comment use case... + if(scan[0] == '!' && scan[1] == '-' && scan[2] == '-') + { + scan += 3; + while(*scan && *scan == ' ') + ++scan; + + char* comment = scan; + char* comment_end = strstr(scan, "-->"); + if(comment_end) + { + *comment_end = 0; + scan = comment_end + 3; + if(!iface->processComment(comment)) + { + mError = "User aborted the parsing process"; + return 0; + } + } + } + else if(*scan == '/') + { + scan = processClose(scan, iface, isError); + if(scan == NULL) + { + return NULL; + } + } + } + else + { + mError = "Data portion of an element wasn't terminated properly"; + return NULL; + } + } + + if(mOpenCount < MIN_CLOSE_COUNT) + { + scan = readData(scan); + } + + return scan; + } + + char* processClose(char* scan, FastXml::Callback* iface, bool& isError) + { + const char* start = popElement(), *close = start; + if(scan[1] != '>') + { + scan++; + close = scan; + while(*scan && *scan != '>') + scan++; + *scan = 0; + } + + if(0 != strcmp(start, close)) + { + mError = "Open and closing tags do not match"; + return 0; + } + + if(!iface->processClose(close, mStackIndex, isError)) + { + // we need to set the read pointer! + uint32_t offset = uint32_t(mReadBufferEnd - scan) - 1; + uint32_t readLoc = mLastReadLoc - offset; + mFileBuf->seek(readLoc); + return NULL; + } + ++scan; + + return scan; + } + + virtual bool processXml(physx::PxInputData& fileBuf, bool streamFromMemory) + { + releaseMemory(); + mFileBuf = &fileBuf; + mStreamFromMemory = streamFromMemory; + return processXml(mCallback); + } + + // if we have finished processing the data we had pending.. + char* readData(char* scan) + { + for(uint32_t i = 0; i < (mStackIndex + 1); i++) + { + if(!mStackAllocated[i]) + { + const char* text = mStack[i]; + if(text) + { + uint32_t tlen = uint32_t(strlen(text)); + mStack[i] = static_cast<const char*>(mCallback->allocate(tlen + 1)); + memcpy(const_cast<void*>(static_cast<const void*>(mStack[i])), text, tlen + 1); + mStackAllocated[i] = true; + } + } + } + + if(!mStreamFromMemory) + { + if(scan == NULL) + { + uint32_t seekLoc = mFileBuf->tell(); + mReadBufferSize = (mFileBuf->getLength() - seekLoc); + } + else + { + return scan; + } + } + + if(mReadBuffer == NULL) + { + mReadBuffer = static_cast<char*>(mCallback->allocate(mReadBufferSize + 1)); + } + uint32_t offset = 0; + uint32_t readLen = mReadBufferSize; + + if(scan) + { + offset = uint32_t(scan - mReadBuffer); + uint32_t copyLen = mReadBufferSize - offset; + if(copyLen) + { + PX_ASSERT(scan >= mReadBuffer); + memmove(mReadBuffer, scan, copyLen); + mReadBuffer[copyLen] = 0; + readLen = mReadBufferSize - copyLen; + } + offset = copyLen; + } + + uint32_t readCount = mFileBuf->read(&mReadBuffer[offset], readLen); + + while(readCount > 0) + { + + mReadBuffer[readCount + offset] = 0; // end of string terminator... + mReadBufferEnd = &mReadBuffer[readCount + offset]; + + const char* scan_ = &mReadBuffer[offset]; + while(*scan_) + { + if(*scan_ == '<' && scan_[1] != '/') + { + mOpenCount++; + } + scan_++; + } + + if(mOpenCount < MIN_CLOSE_COUNT) + { + uint32_t oldSize = uint32_t(mReadBufferEnd - mReadBuffer); + mReadBufferSize = mReadBufferSize * 2; + char* oldReadBuffer = mReadBuffer; + mReadBuffer = static_cast<char*>(mCallback->allocate(mReadBufferSize + 1)); + memcpy(mReadBuffer, oldReadBuffer, oldSize); + mCallback->deallocate(oldReadBuffer); + offset = oldSize; + uint32_t readSize = mReadBufferSize - oldSize; + readCount = mFileBuf->read(&mReadBuffer[offset], readSize); + if(readCount == 0) + break; + } + else + { + break; + } + } + mLastReadLoc = mFileBuf->tell(); + + return mReadBuffer; + } + + bool processXml(FastXml::Callback* iface) + { + bool ret = true; + + const int MAX_ATTRIBUTE = 2048; // can't imagine having more than 2,048 attributes in a single element right? + + mLineNo = 1; + + char* element, *scan = readData(0); + + while(*scan) + { + + scan = skipNextData(scan); + + if(*scan == 0) + break; + + if(*scan == '<') + { + + if(scan[1] != '/') + { + PX_ASSERT(mOpenCount > 0); + mOpenCount--; + } + scan++; + + if(*scan == '?') // Allow xml declarations + { + scan++; + } + else if(scan[0] == '!' && scan[1] == '-' && scan[2] == '-') + { + scan += 3; + while(*scan && *scan == ' ') + scan++; + char* comment = scan, *comment_end = strstr(scan, "-->"); + if(comment_end) + { + *comment_end = 0; + scan = comment_end + 3; + if(!iface->processComment(comment)) + { + mError = "User aborted the parsing process"; + return false; + } + } + continue; + } + else if(scan[0] == '!') // Allow doctype + { + scan++; + + // DOCTYPE syntax differs from usual XML so we parse it here + + // Read DOCTYPE + const char* tag = "DOCTYPE"; + if(!strstr(scan, tag)) + { + mError = "Invalid DOCTYPE"; + return false; + } + + scan += strlen(tag); + + // Skip whites + while(CT_SOFT == getCharType(scan)) + ++scan; + + // Read rootElement + const char* rootElement = scan; + while(CT_DATA == getCharType(scan)) + ++scan; + + char* endRootElement = scan; + + // TODO: read remaining fields (fpi, uri, etc.) + while(CT_END_OF_ELEMENT != getCharType(scan++)) + ; + + *endRootElement = 0; + + if(!iface->processDoctype(rootElement, 0, 0, 0)) + { + mError = "User aborted the parsing process"; + return false; + } + + continue; // Restart loop + } + } + + if(*scan == '/') + { + bool isError; + scan = processClose(scan, iface, isError); + if(!scan) + { + if(isError) + { + mError = "User aborted the parsing process"; + } + return !isError; + } + } + else + { + if(*scan == '?') + scan++; + element = scan; + int32_t argc = 0; + const char* argv[MAX_ATTRIBUTE]; + bool close; + scan = nextSoftOrClose(scan, close); + if(close) + { + char c = *(scan - 1); + if(c != '?' && c != '/') + { + c = '>'; + } + *scan++ = 0; + bool isError; + scan = processClose(c, element, scan, argc, argv, iface, isError); + if(!scan) + { + if(isError) + { + mError = "User aborted the parsing process"; + } + return !isError; + } + } + else + { + if(*scan == 0) + { + return ret; + } + + *scan = 0; // place a zero byte to indicate the end of the element name... + scan++; + + while(*scan) + { + scan = skipNextData(scan); // advance past any soft seperators (tab or space) + + if(getCharType(scan) == CT_END_OF_ELEMENT) + { + char c = *scan++; + if('?' == c) + { + if('>' != *scan) //?> + { + PX_ASSERT(0); + return false; + } + + scan++; + } + bool isError; + scan = processClose(c, element, scan, argc, argv, iface, isError); + if(!scan) + { + if(isError) + { + mError = "User aborted the parsing process"; + } + return !isError; + } + break; + } + else + { + if(argc >= MAX_ATTRIBUTE) + { + mError = "encountered too many attributes"; + return false; + } + argv[argc] = scan; + scan = nextSep(scan); // scan up to a space, or an equal + if(*scan) + { + if(*scan != '=') + { + *scan = 0; + scan++; + while(*scan && *scan != '=') + scan++; + if(*scan == '=') + scan++; + } + else + { + *scan = 0; + scan++; + } + + if(*scan) // if not eof... + { + scan = skipNextData(scan); + if(*scan == '"') + { + scan++; + argc++; + argv[argc] = scan; + argc++; + while(*scan && *scan != 34) + scan++; + if(*scan == '"') + { + *scan = 0; + scan++; + } + else + { + mError = "Failed to find closing quote for attribute"; + return false; + } + } + else + { + // mError = "Expected quote to begin attribute"; + // return false; + // PH: let's try to have a more graceful fallback + argc--; + while(*scan != '/' && *scan != '>' && *scan != 0) + scan++; + } + } + } // if( *scan ) + } // if ( mTypes[*scan] + } // if( close ) + } // if( *scan == '/' + } // while( *scan ) + } + + if(mStackIndex) + { + mError = "Invalid file format"; + return false; + } + + return ret; + } + + const char* getError(int32_t& lineno) + { + const char* ret = mError; + lineno = mLineNo; + mError = 0; + return ret; + } + + virtual void release(void) + { + Callback* c = mCallback; // get the user allocator interface + MyFastXml* f = this; // cast the this pointer + f->~MyFastXml(); // explicitely invoke the destructor for this class + c->deallocate(f); // now free up the memory associated with it. + } + + private: + virtual ~MyFastXml(void) + { + releaseMemory(); + } + + PX_INLINE void releaseMemory(void) + { + mFileBuf = NULL; + mCallback->deallocate(mReadBuffer); + mReadBuffer = NULL; + mStackIndex = 0; + mReadBufferEnd = NULL; + mOpenCount = 0; + mLastReadLoc = 0; + mError = NULL; + for(uint32_t i = 0; i < (mStackIndex + 1); i++) + { + if(mStackAllocated[i]) + { + mCallback->deallocate(const_cast<void*>(static_cast<const void*>(mStack[i]))); + mStackAllocated[i] = false; + } + mStack[i] = NULL; + } + } + + PX_INLINE CharType getCharType(char* scan) const + { + return mTypes[uint8_t(*scan)]; + } + + PX_INLINE char* nextSoftOrClose(char* scan, bool& close) + { + while(*scan && getCharType(scan) != CT_SOFT && *scan != '>') + scan++; + close = *scan == '>'; + return scan; + } + + PX_INLINE char* nextSep(char* scan) + { + while(*scan && getCharType(scan) != CT_SOFT && *scan != '=') + scan++; + return scan; + } + + PX_INLINE char* skipNextData(char* scan) + { + // while we have data, and we encounter soft seperators or line feeds... + while(*scan && (getCharType(scan) == CT_SOFT || getCharType(scan) == CT_END_OF_LINE)) + { + if(*scan == '\n') + mLineNo++; + scan++; + } + return scan; + } + + void pushElement(const char* element) + { + PX_ASSERT(mStackIndex < uint32_t(MAX_STACK)); + if(mStackIndex < uint32_t(MAX_STACK)) + { + if(mStackAllocated[mStackIndex]) + { + mCallback->deallocate(const_cast<void*>(static_cast<const void*>(mStack[mStackIndex]))); + mStackAllocated[mStackIndex] = false; + } + mStack[mStackIndex++] = element; + } + } + + const char* popElement(void) + { + PX_ASSERT(mStackIndex > 0); + if(mStackAllocated[mStackIndex]) + { + mCallback->deallocate(const_cast<void*>(static_cast<const void*>(mStack[mStackIndex]))); + mStackAllocated[mStackIndex] = false; + } + mStack[mStackIndex] = NULL; + return mStackIndex ? mStack[--mStackIndex] : NULL; + } + + static const int MAX_STACK = 2048; + + CharType mTypes[256]; + + physx::PxInputData* mFileBuf; + + char* mReadBuffer; + char* mReadBufferEnd; + + uint32_t mOpenCount; + uint32_t mReadBufferSize; + uint32_t mLastReadLoc; + + int32_t mLineNo; + const char* mError; + uint32_t mStackIndex; + const char* mStack[MAX_STACK + 1]; + bool mStreamFromMemory; + bool mStackAllocated[MAX_STACK + 1]; + Callback* mCallback; +}; +} + +namespace physx +{ +namespace shdfnd +{ + +FastXml* createFastXml(FastXml::Callback* iface) +{ + MyFastXml* m = static_cast<MyFastXml*>(iface->allocate(sizeof(MyFastXml))); + if(m) + { + new (m) MyFastXml(iface); + } + return static_cast<FastXml*>(m); +} +} +} |