From 7115f60b91b5717d90f643fd692010905c7004db Mon Sep 17 00:00:00 2001 From: Bryan Galdrikian Date: Thu, 31 May 2018 11:36:08 -0700 Subject: Blast 1.1.3. See docs/release_notes.txt. --- .../NvParameterized/src/XmlSerializer.cpp | 2540 ++++++++++---------- 1 file changed, 1270 insertions(+), 1270 deletions(-) mode change 100644 => 100755 sdk/extensions/import/apexmodules/NvParameterized/src/XmlSerializer.cpp (limited to 'sdk/extensions/import/apexmodules/NvParameterized/src/XmlSerializer.cpp') diff --git a/sdk/extensions/import/apexmodules/NvParameterized/src/XmlSerializer.cpp b/sdk/extensions/import/apexmodules/NvParameterized/src/XmlSerializer.cpp old mode 100644 new mode 100755 index b3f3c22..120815e --- a/sdk/extensions/import/apexmodules/NvParameterized/src/XmlSerializer.cpp +++ b/sdk/extensions/import/apexmodules/NvParameterized/src/XmlSerializer.cpp @@ -1,1270 +1,1270 @@ -// 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-2013 NVIDIA Corporation. All rights reserved. - -#include "PxSimpleTypes.h" -#include "PxAssert.h" -#include "PsArray.h" -#include "PxVec3.h" -#include "PxQuat.h" -#include "PxBounds3.h" -#include "PsFastXml.h" -#include "PsIOStream.h" - -#include "nvparameterized/NvSerializer.h" -#include "XmlSerializer.h" -#include "nvparameterized/NvParameterized.h" -#include "nvparameterized/NvParameterizedTraits.h" -#include "NvParameters.h" - -#include "NvTraitsInternal.h" -#include "XmlDeserializer.h" - -#define PRINT_ELEMENT_HINTS 0 -#define PRINT_ELEMENTS_WITHIN_EMPTY_ARRAYS 0 - -#define UNOPTIMIZED_XML 0 - -namespace NvParameterized -{ - -static const char indentStr[] = " "; - -struct traversalState -{ - traversalState() - { - indent[0] = 0; - indentLen = 0; - level = 0; - } - - void incLevel() - { - physx::shdfnd::strlcat(indent, (uint32_t)strlen(indent) + (uint32_t)strlen(indentStr) + 1, indentStr); - level++; - } - - void decLevel() - { - level--; - indentLen = (sizeof(indentStr) - 1) * level; - if(indentLen < sizeof(indent)) - indent[indentLen] = 0; - } - - char indent[4096]; - uint32_t indentLen; - int32_t level; -}; - -Serializer::ErrorType XmlSerializer::peekNumObjects(char *data, uint32_t len, uint32_t &numObjects) -{ - //FIXME: this code is not robust - - data[len-1] = 0; - - const char *root = ::strstr(data, " => read className - mClassNames[mNumObjs] = mTraits->strdup( attr.get("className") ); - ++mNumObjs; - - return mNumObjs < mNumClassNames; - } - - void *allocate(uint32_t size) { return ::malloc(size); } - void deallocate(void *ptr) { ::free(ptr); }; - }; - - ClassNameReader myReader(classNames, numClassNames, mTraits); - physx::shdfnd::FastXml *xmlParser = physx::shdfnd::createFastXml(&myReader); - - InputDataFromPxFileBuf inputData(stream); - xmlParser->processXml(inputData); - numClassNames = myReader.numObjs(); - - return Serializer::ERROR_NONE; -} - -Serializer::ErrorType XmlSerializer::peekNumObjectsInplace(const void * data, uint32_t dataLen, uint32_t & numObjects) -{ - if ( !dataLen || ! data ) - return ERROR_STREAM_ERROR; - - char hdr[100]; - uint32_t len = physx::PxMin(dataLen, sizeof(hdr) - 1); - physx::shdfnd::strlcpy(hdr, len+1, (const char *)data); - - return peekNumObjects(hdr, len, numObjects); -} - -Serializer::ErrorType XmlSerializer::peekNumObjects(physx::PxFileBuf &stream, uint32_t &numObjects) -{ - //FIXME: this code is not robust - - char hdr[100]; - uint32_t len = stream.peek(hdr, sizeof(hdr)); - - return peekNumObjects(hdr, len, numObjects); -} - -#ifndef WITHOUT_APEX_SERIALIZATION - -static void storeVersionAndChecksum(physx::PsIOStream &stream, const Interface *obj) -{ - uint16_t major = obj->getMajorVersion(), - minor = obj->getMinorVersion(); - - stream << " version=\"" << major << '.' << minor << '"'; - - uint32_t bits; - const uint32_t *checksum = obj->checksum(bits); - - uint32_t u32s = bits / 32; - PX_ASSERT( 0 == bits % 32 ); - - stream << " checksum=\""; - for(uint32_t i = 0; i < u32s; ++i) - { - char hex[20]; - physx::shdfnd::snprintf(hex, sizeof(hex), "0x%x", checksum[i]); - stream << hex; - if( u32s - 1 != i ) - stream << ' '; - } - stream << '"'; -} - -static bool IsSimpleType(const Definition *d) -{ - //We do not consider strings simple because it causes errors with NULL and "" - if (d->type() == TYPE_ARRAY || d->type() == TYPE_STRUCT || - d->type() == TYPE_REF || d->type() == TYPE_STRING || - d->type() == TYPE_ENUM) - { - return false; - } - else - { - PX_ASSERT( d->numChildren() == 0 ); - return true; - } -} - -static bool IsSimpleStruct(const Definition *pd) -{ - bool ret = true; - - int32_t count = pd->numChildren(); - for (int32_t i=0; i < count; i++) - { - const Definition *d = pd->child(i); - if ( !IsSimpleType(d) ) - { - ret = false; - break; - } - } - - return ret; -} - -static bool DoesNeedQuote(const char *c) -{ - bool ret = false; - while ( *c ) - { - if ( *c == 32 || *c == ',' || *c == '<' || *c == '>' || *c == 9 ) - { - ret = true; - break; - } - c++; - } - - return ret; -} - -Serializer::ErrorType XmlSerializer::traverseParamDefTree( - const Interface &obj, - physx::PsIOStream &stream, - traversalState &state, - Handle &handle, - bool printValues) -{ - bool isRoot = !handle.numIndexes() && 0 == state.level; - - if( !handle.numIndexes() ) - { - NV_PARAM_ERR_CHECK_RETURN( obj.getParameterHandle("", handle), Serializer::ERROR_UNKNOWN ); - - if( isRoot ) - { - NV_ERR_CHECK_RETURN( emitElement(obj, stream, "value", handle, false, true, true) ); - stream << "\n"; - - state.incLevel(); - } - } - - const Definition *paramDef = handle.parameterDefinition(); - - if( !paramDef->hint("DONOTSERIALIZE") ) - { - -# if PRINT_ELEMENT_HINTS - bool includedRef = false; - - NV_ERR_CHECK_RETURN( emitElementNxHints(stream, handle, state, includedRef) ); -# else - bool includedRef = paramDef->isIncludedRef(); -# endif - - switch( paramDef->type() ) - { - case TYPE_STRUCT: - { - stream << state.indent; - NV_ERR_CHECK_RETURN( emitElement(obj, stream, "struct", handle, false, true) ); - stream << "\n"; - - state.incLevel(); - for(int32_t i = 0; i < paramDef->numChildren(); ++i) - { - handle.set(i); - NV_ERR_CHECK_RETURN( traverseParamDefTree(obj, stream, state, handle, printValues) ); - handle.popIndex(); - } - - state.decLevel(); - - stream << state.indent << "\n"; - - break; - } - - case TYPE_ARRAY: - { - stream << state.indent; - NV_ERR_CHECK_RETURN( emitElement(obj, stream, "array", handle, false, true) ); - - int32_t arraySize; - NV_PARAM_ERR_CHECK_RETURN( handle.getArraySize(arraySize), Serializer::ERROR_INVALID_ARRAY ); - - if( arraySize) - stream << "\n"; - - state.incLevel(); - - if ( arraySize > 0 ) - { -#if UNOPTIMIZED_XML - for(int32_t i = 0; i < arraySize; ++i) - { - handle.set(i); - NV_ERR_CHECK_RETURN( traverseParamDefTree(obj, stream, state, handle, printValues) ); - handle.popIndex(); - } -#else - handle.set(0); - const Definition *pd = handle.parameterDefinition(); - handle.popIndex(); - switch ( pd->type() ) - { - case TYPE_STRUCT: - { - if ( IsSimpleStruct(pd) ) - { - for(int32_t i = 0; i < arraySize; ++i) - { - - if ( (i&3) == 0 ) - { - if ( i ) - stream << "\n"; - stream << state.indent; - } - - handle.set(i); - - for( int32_t j=0; jnumChildren(); j++ ) - { - if (pd->child(j)->hint("DONOTSERIALIZE")) - continue; - - handle.set(j); - - char buf[512]; - const char *str = 0; - NV_PARAM_ERR_CHECK_RETURN( handle.valueToStr(buf, sizeof(buf), str), Serializer::ERROR_VAL2STRING_FAILED ); - - stream << str; - - if ( (j+1) < pd->numChildren() ) - { - stream << " "; - } - - handle.popIndex(); - } - - if ( (i+1) < arraySize ) - { - stream << ","; - } - - handle.popIndex(); - } //i - stream << "\n"; - } - else - { - for(int32_t i = 0; i < arraySize; ++i) - { - handle.set(i); - NV_ERR_CHECK_RETURN( traverseParamDefTree(obj, stream, state, handle, printValues) ); - handle.popIndex(); - } - } - } - break; - - case TYPE_REF: - for(int32_t i = 0; i < arraySize; ++i) - { - handle.set(i); - NV_ERR_CHECK_RETURN( traverseParamDefTree(obj, stream, state, handle, printValues) ); - handle.popIndex(); - } - break; - - case TYPE_BOOL: - { - bool v = false; - stream << state.indent; - for (int32_t i=0; i\n"; - - break; - } - - case TYPE_REF: - { - stream << state.indent; - NV_ERR_CHECK_RETURN( emitElement(obj, stream, "value", handle, includedRef, printValues) ); - - if( printValues && includedRef ) - { - stream << state.indent << "\n"; - - Interface *refObj = 0; - NV_PARAM_ERR_CHECK_RETURN( handle.getParamRef(refObj), Serializer::ERROR_UNKNOWN ); - - if( refObj ) - { - Handle refHandle(refObj); - state.incLevel(); - NV_ERR_CHECK_RETURN( traverseParamDefTree(*refObj, stream, state, refHandle) ); - state.decLevel(); - stream << state.indent; - } - } - - stream << "\n"; - - break; - } - - case TYPE_POINTER: - //Don't do anything with pointer - break; - -NV_PARAMETRIZED_LINAL_DATATYPE_LABELS -NV_PARAMETRIZED_ARITHMETIC_DATATYPE_LABELS -NV_PARAMETRIZED_STRING_DATATYPE_LABELS -NV_PARAMETRIZED_ENUM_DATATYPE_LABELS -NV_PARAMETRIZED_UNDEFINED_AND_LAST_DATATYPE_LABELS - default: - { - stream << state.indent; - NV_ERR_CHECK_RETURN( emitElement(obj, stream, "value", handle, includedRef, printValues) ); - - char buf[512]; - const char *str = 0; - if( printValues ) - NV_PARAM_ERR_CHECK_RETURN( handle.valueToStr(buf, sizeof(buf), str), Serializer::ERROR_VAL2STRING_FAILED ); - - if( str ) - stream << str; - - stream << "\n"; - - break; - } //default - } //switch - - } //DONOTSERIALIZE - - if( isRoot ) - { - state.decLevel(); - stream << "\n"; - } - - return Serializer::ERROR_NONE; -} - -Serializer::ErrorType XmlSerializer::emitElementNxHints( - physx::PsIOStream &stream, - Handle &handle, - traversalState &state, - bool &includedRef) -{ - const Definition *paramDef = handle.parameterDefinition(); - - for(int32_t j = 0; j < paramDef->numHints(); ++j) - { - if( 0 == j ) - stream << "\n"; - - const Hint *hint = paramDef->hint(j); - - stream << state.indent << "\n"; - } - - includedRef = paramDef->isIncludedRef(); - - return Serializer::ERROR_NONE; -} - -Serializer::ErrorType XmlSerializer::emitElement( - const Interface &obj, - physx::PsIOStream &stream, - const char *elementName, - Handle &handle, - bool includedRef, - bool printValues, - bool isRoot) -{ - const Definition *paramDef = handle.parameterDefinition(); - - DataType parentType = TYPE_UNDEFINED; - - if( paramDef->parent() ) - parentType = paramDef->parent()->type(); - - stream << '<' << elementName; - - if( isRoot ) - { - stream << " name=\"\"" - << " type=\"Ref\"" - << " className=\"" << obj.className() << "\""; - - const char *objectName = obj.name(); - if( objectName ) - stream << " objectName=\"" << objectName << "\""; - - if( isRoot ) //We only emit version info for root - storeVersionAndChecksum(stream, &obj); - } - else - { - if( parentType != TYPE_ARRAY ) - { - const char *name = paramDef->name(); - stream << " name=\"" << (name ? name : "") << "\""; - } - } - - switch( paramDef->type() ) - { - case TYPE_STRUCT: - break; - - case TYPE_ARRAY: - { - int32_t arraySize; - NV_PARAM_ERR_CHECK_RETURN( handle.getArraySize(arraySize), Serializer::ERROR_INVALID_ARRAY ); - stream << " size=\"" << arraySize << '"'; - handle.set(0); - const Definition *pd = handle.parameterDefinition(); - handle.popIndex(); - stream << " type=\"" << typeToStr(pd->type()) << '"'; - // ** handle use case for simple structs written out flat.. -#if !UNOPTIMIZED_XML - if ( pd->type() == TYPE_STRUCT && IsSimpleStruct(pd) ) - { - stream << " structElements=\""; - const int32_t count = pd->numChildren(); - - // find how many of them need serialization - int32_t serializeCount = 0; - for (int32_t i=0; ichild(i); - if (d->hint("DONOTSERIALIZE") == NULL) - { - serializeCount++; - } - } - - for (int32_t i=0; ichild(i); - if (d->hint("DONOTSERIALIZE")) - continue; - - stream << d->name(); - stream << "("; - stream << typeToStr(d->type()); - stream << ")"; - if ( (i+1) < serializeCount ) - { - stream<<","; - } - } - stream << "\""; - } -#endif - // - break; - } - - case TYPE_REF: - { - stream << " type=\"" << typeToStr(paramDef->type()) << '"'; - - Interface *paramPtr = 0; - if( printValues ) - NV_PARAM_ERR_CHECK_RETURN( handle.getParamRef(paramPtr), Serializer::ERROR_UNKNOWN ); - - stream << " included=\"" << ( includedRef ? "1" : "0" ) << "\""; - - if( !printValues || !paramPtr ) - { - stream << " classNames=\""; - for(int32_t i = 0; i < paramDef->numRefVariants(); ++i) - { - const char *ref = paramDef->refVariantVal(i); - if ( DoesNeedQuote(ref) ) - stream << "%20" << ref << "%20" << " "; - else - stream << ref << " "; - } - stream << '"'; - - break; - } - - stream << " className=\"" << paramPtr->className() << '"'; - - const char *objectName = paramPtr->name(); - if( objectName ) - stream << " objectName=\"" << objectName << "\""; - - if( includedRef ) - storeVersionAndChecksum(stream, paramPtr); - - break; - } - - case TYPE_STRING: - case TYPE_ENUM: - { - const char *val; - NV_PARAM_ERR_CHECK_RETURN( handle.getParamString(val), Serializer::ERROR_UNKNOWN ); - - //Make a note if value is NULL - if( !val ) - stream << " null=\"1\""; - } - - //Fall-through to default - -NV_PARAMETRIZED_LINAL_DATATYPE_LABELS -NV_PARAMETRIZED_ARITHMETIC_DATATYPE_LABELS -NV_PARAMETRIZED_SERVICE_DATATYPE_LABELS -NV_PARAMETRIZED_UNDEFINED_AND_LAST_DATATYPE_LABELS - default: - stream << " type=\"" << typeToStr(paramDef->type()) << "\""; - break; - } //switch - - stream << '>'; - - return Serializer::ERROR_NONE; -} - -Serializer::ErrorType XmlSerializer::internalSerialize(physx::PxFileBuf &fbuf, const Interface **objs, uint32_t n, bool doMetadata) -{ - PX_UNUSED(doMetadata); - - physx::PsIOStream stream(fbuf, fbuf.getFileLength()); - stream.setBinary(false); - - uint32_t minor = version() & 0xffffUL, - major = version() >> 16; - - stream << "\n" - << "\n"; - - for(uint32_t i = 0; i < n; ++i) - { - const Interface &obj = *objs[i]; - Handle handle(obj); - - traversalState state; - NV_ERR_CHECK_RETURN( traverseParamDefTree(obj, stream, state, handle) ); - } - - stream << "\n"; - - return Serializer::ERROR_NONE; -} - -#endif - -Serializer::ErrorType XmlSerializer::internalDeserialize( - physx::PxFileBuf &stream, - Serializer::DeserializedData &res, - bool & /*doesNeedUpdate*/) -{ - XmlDeserializer *d = XmlDeserializer::Create(mTraits, XmlSerializer::version()); - physx::shdfnd::FastXml *xmlParser = physx::shdfnd::createFastXml(d); - InputDataFromPxFileBuf inputData(stream); - if( xmlParser && !xmlParser->processXml(inputData) ) - { - Serializer::ErrorType err = d->getLastError(); - if( Serializer::ERROR_NONE == err ) //Proper error code not set? - { - DEBUG_ALWAYS_ASSERT(); //XmlDeserializer should set explicit error codes - err = Serializer::ERROR_UNKNOWN; - } - - xmlParser->release(); - - d->releaseAll(); - d->destroy(); - - return err; - } - - if ( xmlParser ) - xmlParser->release(); - - res.init(mTraits, d->getObjs(), d->getNobjs()); - - d->destroy(); - - return Serializer::ERROR_NONE; -} -bool isXmlFormat(physx::PxFileBuf &stream) -{ - // if it is at least 32 bytes long and the first 32 byte are all ASCII, then consider it potentially valid XML - - if( stream.getFileLength() < 32 ) - return false; - - char hdr[32]; - stream.peek(hdr, sizeof(hdr)); - - for(size_t i = 0; i < sizeof(hdr); ++i) - { - char c = hdr[i]; - if( !(c == '\r' || c == '\t' || c == '\n' || ( c >= 32 && c < 127)) ) - return false; - } - - const char *magic1 = ""; - const char *magic2 = ""; - return 0 == ::strncmp(hdr, magic1, strlen(magic1)) || - 0 == ::strncmp(hdr, magic2, strlen(magic2)); -} - -} // namespace NvParameterized - +// 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-2013 NVIDIA Corporation. All rights reserved. + +#include "PxSimpleTypes.h" +#include "PxAssert.h" +#include "PsArray.h" +#include "PxVec3.h" +#include "PxQuat.h" +#include "PxBounds3.h" +#include "PsFastXml.h" +#include "PsIOStream.h" + +#include "nvparameterized/NvSerializer.h" +#include "XmlSerializer.h" +#include "nvparameterized/NvParameterized.h" +#include "nvparameterized/NvParameterizedTraits.h" +#include "NvParameters.h" + +#include "NvTraitsInternal.h" +#include "XmlDeserializer.h" + +#define PRINT_ELEMENT_HINTS 0 +#define PRINT_ELEMENTS_WITHIN_EMPTY_ARRAYS 0 + +#define UNOPTIMIZED_XML 0 + +namespace NvParameterized +{ + +static const char indentStr[] = " "; + +struct traversalState +{ + traversalState() + { + indent[0] = 0; + indentLen = 0; + level = 0; + } + + void incLevel() + { + physx::shdfnd::strlcat(indent, (uint32_t)strlen(indent) + (uint32_t)strlen(indentStr) + 1, indentStr); + level++; + } + + void decLevel() + { + level--; + indentLen = (sizeof(indentStr) - 1) * level; + if(indentLen < sizeof(indent)) + indent[indentLen] = 0; + } + + char indent[4096]; + uint32_t indentLen; + int32_t level; +}; + +Serializer::ErrorType XmlSerializer::peekNumObjects(char *data, uint32_t len, uint32_t &numObjects) +{ + //FIXME: this code is not robust + + data[len-1] = 0; + + const char *root = ::strstr(data, " => read className + mClassNames[mNumObjs] = mTraits->strdup( attr.get("className") ); + ++mNumObjs; + + return mNumObjs < mNumClassNames; + } + + void *allocate(uint32_t size) { return ::malloc(size); } + void deallocate(void *ptr) { ::free(ptr); }; + }; + + ClassNameReader myReader(classNames, numClassNames, mTraits); + physx::shdfnd::FastXml *xmlParser = physx::shdfnd::createFastXml(&myReader); + + InputDataFromPxFileBuf inputData(stream); + xmlParser->processXml(inputData); + numClassNames = myReader.numObjs(); + + return Serializer::ERROR_NONE; +} + +Serializer::ErrorType XmlSerializer::peekNumObjectsInplace(const void * data, uint32_t dataLen, uint32_t & numObjects) +{ + if ( !dataLen || ! data ) + return ERROR_STREAM_ERROR; + + char hdr[100]; + uint32_t len = physx::PxMin(dataLen, sizeof(hdr) - 1); + physx::shdfnd::strlcpy(hdr, len+1, (const char *)data); + + return peekNumObjects(hdr, len, numObjects); +} + +Serializer::ErrorType XmlSerializer::peekNumObjects(physx::PxFileBuf &stream, uint32_t &numObjects) +{ + //FIXME: this code is not robust + + char hdr[100]; + uint32_t len = stream.peek(hdr, sizeof(hdr)); + + return peekNumObjects(hdr, len, numObjects); +} + +#ifndef WITHOUT_APEX_SERIALIZATION + +static void storeVersionAndChecksum(physx::PsIOStream &stream, const Interface *obj) +{ + uint16_t major = obj->getMajorVersion(), + minor = obj->getMinorVersion(); + + stream << " version=\"" << major << '.' << minor << '"'; + + uint32_t bits; + const uint32_t *checksum = obj->checksum(bits); + + uint32_t u32s = bits / 32; + PX_ASSERT( 0 == bits % 32 ); + + stream << " checksum=\""; + for(uint32_t i = 0; i < u32s; ++i) + { + char hex[20]; + physx::shdfnd::snprintf(hex, sizeof(hex), "0x%x", checksum[i]); + stream << hex; + if( u32s - 1 != i ) + stream << ' '; + } + stream << '"'; +} + +static bool IsSimpleType(const Definition *d) +{ + //We do not consider strings simple because it causes errors with NULL and "" + if (d->type() == TYPE_ARRAY || d->type() == TYPE_STRUCT || + d->type() == TYPE_REF || d->type() == TYPE_STRING || + d->type() == TYPE_ENUM) + { + return false; + } + else + { + PX_ASSERT( d->numChildren() == 0 ); + return true; + } +} + +static bool IsSimpleStruct(const Definition *pd) +{ + bool ret = true; + + int32_t count = pd->numChildren(); + for (int32_t i=0; i < count; i++) + { + const Definition *d = pd->child(i); + if ( !IsSimpleType(d) ) + { + ret = false; + break; + } + } + + return ret; +} + +static bool DoesNeedQuote(const char *c) +{ + bool ret = false; + while ( *c ) + { + if ( *c == 32 || *c == ',' || *c == '<' || *c == '>' || *c == 9 ) + { + ret = true; + break; + } + c++; + } + + return ret; +} + +Serializer::ErrorType XmlSerializer::traverseParamDefTree( + const Interface &obj, + physx::PsIOStream &stream, + traversalState &state, + Handle &handle, + bool printValues) +{ + bool isRoot = !handle.numIndexes() && 0 == state.level; + + if( !handle.numIndexes() ) + { + NV_PARAM_ERR_CHECK_RETURN( obj.getParameterHandle("", handle), Serializer::ERROR_UNKNOWN ); + + if( isRoot ) + { + NV_ERR_CHECK_RETURN( emitElement(obj, stream, "value", handle, false, true, true) ); + stream << "\n"; + + state.incLevel(); + } + } + + const Definition *paramDef = handle.parameterDefinition(); + + if( !paramDef->hint("DONOTSERIALIZE") ) + { + +# if PRINT_ELEMENT_HINTS + bool includedRef = false; + + NV_ERR_CHECK_RETURN( emitElementNxHints(stream, handle, state, includedRef) ); +# else + bool includedRef = paramDef->isIncludedRef(); +# endif + + switch( paramDef->type() ) + { + case TYPE_STRUCT: + { + stream << state.indent; + NV_ERR_CHECK_RETURN( emitElement(obj, stream, "struct", handle, false, true) ); + stream << "\n"; + + state.incLevel(); + for(int32_t i = 0; i < paramDef->numChildren(); ++i) + { + handle.set(i); + NV_ERR_CHECK_RETURN( traverseParamDefTree(obj, stream, state, handle, printValues) ); + handle.popIndex(); + } + + state.decLevel(); + + stream << state.indent << "\n"; + + break; + } + + case TYPE_ARRAY: + { + stream << state.indent; + NV_ERR_CHECK_RETURN( emitElement(obj, stream, "array", handle, false, true) ); + + int32_t arraySize; + NV_PARAM_ERR_CHECK_RETURN( handle.getArraySize(arraySize), Serializer::ERROR_INVALID_ARRAY ); + + if( arraySize) + stream << "\n"; + + state.incLevel(); + + if ( arraySize > 0 ) + { +#if UNOPTIMIZED_XML + for(int32_t i = 0; i < arraySize; ++i) + { + handle.set(i); + NV_ERR_CHECK_RETURN( traverseParamDefTree(obj, stream, state, handle, printValues) ); + handle.popIndex(); + } +#else + handle.set(0); + const Definition *pd = handle.parameterDefinition(); + handle.popIndex(); + switch ( pd->type() ) + { + case TYPE_STRUCT: + { + if ( IsSimpleStruct(pd) ) + { + for(int32_t i = 0; i < arraySize; ++i) + { + + if ( (i&3) == 0 ) + { + if ( i ) + stream << "\n"; + stream << state.indent; + } + + handle.set(i); + + for( int32_t j=0; jnumChildren(); j++ ) + { + if (pd->child(j)->hint("DONOTSERIALIZE")) + continue; + + handle.set(j); + + char buf[512]; + const char *str = 0; + NV_PARAM_ERR_CHECK_RETURN( handle.valueToStr(buf, sizeof(buf), str), Serializer::ERROR_VAL2STRING_FAILED ); + + stream << str; + + if ( (j+1) < pd->numChildren() ) + { + stream << " "; + } + + handle.popIndex(); + } + + if ( (i+1) < arraySize ) + { + stream << ","; + } + + handle.popIndex(); + } //i + stream << "\n"; + } + else + { + for(int32_t i = 0; i < arraySize; ++i) + { + handle.set(i); + NV_ERR_CHECK_RETURN( traverseParamDefTree(obj, stream, state, handle, printValues) ); + handle.popIndex(); + } + } + } + break; + + case TYPE_REF: + for(int32_t i = 0; i < arraySize; ++i) + { + handle.set(i); + NV_ERR_CHECK_RETURN( traverseParamDefTree(obj, stream, state, handle, printValues) ); + handle.popIndex(); + } + break; + + case TYPE_BOOL: + { + bool v = false; + stream << state.indent; + for (int32_t i=0; i\n"; + + break; + } + + case TYPE_REF: + { + stream << state.indent; + NV_ERR_CHECK_RETURN( emitElement(obj, stream, "value", handle, includedRef, printValues) ); + + if( printValues && includedRef ) + { + stream << state.indent << "\n"; + + Interface *refObj = 0; + NV_PARAM_ERR_CHECK_RETURN( handle.getParamRef(refObj), Serializer::ERROR_UNKNOWN ); + + if( refObj ) + { + Handle refHandle(refObj); + state.incLevel(); + NV_ERR_CHECK_RETURN( traverseParamDefTree(*refObj, stream, state, refHandle) ); + state.decLevel(); + stream << state.indent; + } + } + + stream << "\n"; + + break; + } + + case TYPE_POINTER: + //Don't do anything with pointer + break; + +NV_PARAMETRIZED_LINAL_DATATYPE_LABELS +NV_PARAMETRIZED_ARITHMETIC_DATATYPE_LABELS +NV_PARAMETRIZED_STRING_DATATYPE_LABELS +NV_PARAMETRIZED_ENUM_DATATYPE_LABELS +NV_PARAMETRIZED_UNDEFINED_AND_LAST_DATATYPE_LABELS + default: + { + stream << state.indent; + NV_ERR_CHECK_RETURN( emitElement(obj, stream, "value", handle, includedRef, printValues) ); + + char buf[512]; + const char *str = 0; + if( printValues ) + NV_PARAM_ERR_CHECK_RETURN( handle.valueToStr(buf, sizeof(buf), str), Serializer::ERROR_VAL2STRING_FAILED ); + + if( str ) + stream << str; + + stream << "\n"; + + break; + } //default + } //switch + + } //DONOTSERIALIZE + + if( isRoot ) + { + state.decLevel(); + stream << "\n"; + } + + return Serializer::ERROR_NONE; +} + +Serializer::ErrorType XmlSerializer::emitElementNxHints( + physx::PsIOStream &stream, + Handle &handle, + traversalState &state, + bool &includedRef) +{ + const Definition *paramDef = handle.parameterDefinition(); + + for(int32_t j = 0; j < paramDef->numHints(); ++j) + { + if( 0 == j ) + stream << "\n"; + + const Hint *hint = paramDef->hint(j); + + stream << state.indent << "\n"; + } + + includedRef = paramDef->isIncludedRef(); + + return Serializer::ERROR_NONE; +} + +Serializer::ErrorType XmlSerializer::emitElement( + const Interface &obj, + physx::PsIOStream &stream, + const char *elementName, + Handle &handle, + bool includedRef, + bool printValues, + bool isRoot) +{ + const Definition *paramDef = handle.parameterDefinition(); + + DataType parentType = TYPE_UNDEFINED; + + if( paramDef->parent() ) + parentType = paramDef->parent()->type(); + + stream << '<' << elementName; + + if( isRoot ) + { + stream << " name=\"\"" + << " type=\"Ref\"" + << " className=\"" << obj.className() << "\""; + + const char *objectName = obj.name(); + if( objectName ) + stream << " objectName=\"" << objectName << "\""; + + if( isRoot ) //We only emit version info for root + storeVersionAndChecksum(stream, &obj); + } + else + { + if( parentType != TYPE_ARRAY ) + { + const char *name = paramDef->name(); + stream << " name=\"" << (name ? name : "") << "\""; + } + } + + switch( paramDef->type() ) + { + case TYPE_STRUCT: + break; + + case TYPE_ARRAY: + { + int32_t arraySize; + NV_PARAM_ERR_CHECK_RETURN( handle.getArraySize(arraySize), Serializer::ERROR_INVALID_ARRAY ); + stream << " size=\"" << arraySize << '"'; + handle.set(0); + const Definition *pd = handle.parameterDefinition(); + handle.popIndex(); + stream << " type=\"" << typeToStr(pd->type()) << '"'; + // ** handle use case for simple structs written out flat.. +#if !UNOPTIMIZED_XML + if ( pd->type() == TYPE_STRUCT && IsSimpleStruct(pd) ) + { + stream << " structElements=\""; + const int32_t count = pd->numChildren(); + + // find how many of them need serialization + int32_t serializeCount = 0; + for (int32_t i=0; ichild(i); + if (d->hint("DONOTSERIALIZE") == NULL) + { + serializeCount++; + } + } + + for (int32_t i=0; ichild(i); + if (d->hint("DONOTSERIALIZE")) + continue; + + stream << d->name(); + stream << "("; + stream << typeToStr(d->type()); + stream << ")"; + if ( (i+1) < serializeCount ) + { + stream<<","; + } + } + stream << "\""; + } +#endif + // + break; + } + + case TYPE_REF: + { + stream << " type=\"" << typeToStr(paramDef->type()) << '"'; + + Interface *paramPtr = 0; + if( printValues ) + NV_PARAM_ERR_CHECK_RETURN( handle.getParamRef(paramPtr), Serializer::ERROR_UNKNOWN ); + + stream << " included=\"" << ( includedRef ? "1" : "0" ) << "\""; + + if( !printValues || !paramPtr ) + { + stream << " classNames=\""; + for(int32_t i = 0; i < paramDef->numRefVariants(); ++i) + { + const char *ref = paramDef->refVariantVal(i); + if ( DoesNeedQuote(ref) ) + stream << "%20" << ref << "%20" << " "; + else + stream << ref << " "; + } + stream << '"'; + + break; + } + + stream << " className=\"" << paramPtr->className() << '"'; + + const char *objectName = paramPtr->name(); + if( objectName ) + stream << " objectName=\"" << objectName << "\""; + + if( includedRef ) + storeVersionAndChecksum(stream, paramPtr); + + break; + } + + case TYPE_STRING: + case TYPE_ENUM: + { + const char *val; + NV_PARAM_ERR_CHECK_RETURN( handle.getParamString(val), Serializer::ERROR_UNKNOWN ); + + //Make a note if value is NULL + if( !val ) + stream << " null=\"1\""; + } + + //Fall-through to default + +NV_PARAMETRIZED_LINAL_DATATYPE_LABELS +NV_PARAMETRIZED_ARITHMETIC_DATATYPE_LABELS +NV_PARAMETRIZED_SERVICE_DATATYPE_LABELS +NV_PARAMETRIZED_UNDEFINED_AND_LAST_DATATYPE_LABELS + default: + stream << " type=\"" << typeToStr(paramDef->type()) << "\""; + break; + } //switch + + stream << '>'; + + return Serializer::ERROR_NONE; +} + +Serializer::ErrorType XmlSerializer::internalSerialize(physx::PxFileBuf &fbuf, const Interface **objs, uint32_t n, bool doMetadata) +{ + PX_UNUSED(doMetadata); + + physx::PsIOStream stream(fbuf, fbuf.getFileLength()); + stream.setBinary(false); + + uint32_t minor = version() & 0xffffUL, + major = version() >> 16; + + stream << "\n" + << "\n"; + + for(uint32_t i = 0; i < n; ++i) + { + const Interface &obj = *objs[i]; + Handle handle(obj); + + traversalState state; + NV_ERR_CHECK_RETURN( traverseParamDefTree(obj, stream, state, handle) ); + } + + stream << "\n"; + + return Serializer::ERROR_NONE; +} + +#endif + +Serializer::ErrorType XmlSerializer::internalDeserialize( + physx::PxFileBuf &stream, + Serializer::DeserializedData &res, + bool & /*doesNeedUpdate*/) +{ + XmlDeserializer *d = XmlDeserializer::Create(mTraits, XmlSerializer::version()); + physx::shdfnd::FastXml *xmlParser = physx::shdfnd::createFastXml(d); + InputDataFromPxFileBuf inputData(stream); + if( xmlParser && !xmlParser->processXml(inputData) ) + { + Serializer::ErrorType err = d->getLastError(); + if( Serializer::ERROR_NONE == err ) //Proper error code not set? + { + DEBUG_ALWAYS_ASSERT(); //XmlDeserializer should set explicit error codes + err = Serializer::ERROR_UNKNOWN; + } + + xmlParser->release(); + + d->releaseAll(); + d->destroy(); + + return err; + } + + if ( xmlParser ) + xmlParser->release(); + + res.init(mTraits, d->getObjs(), d->getNobjs()); + + d->destroy(); + + return Serializer::ERROR_NONE; +} +bool isXmlFormat(physx::PxFileBuf &stream) +{ + // if it is at least 32 bytes long and the first 32 byte are all ASCII, then consider it potentially valid XML + + if( stream.getFileLength() < 32 ) + return false; + + char hdr[32]; + stream.peek(hdr, sizeof(hdr)); + + for(size_t i = 0; i < sizeof(hdr); ++i) + { + char c = hdr[i]; + if( !(c == '\r' || c == '\t' || c == '\n' || ( c >= 32 && c < 127)) ) + return false; + } + + const char *magic1 = ""; + const char *magic2 = ""; + return 0 == ::strncmp(hdr, magic1, strlen(magic1)) || + 0 == ::strncmp(hdr, magic2, strlen(magic2)); +} + +} // namespace NvParameterized + -- cgit v1.2.3