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 /APEX_1.4/NvParameterized/src/XmlSerializer.cpp | |
| 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 'APEX_1.4/NvParameterized/src/XmlSerializer.cpp')
| -rw-r--r-- | APEX_1.4/NvParameterized/src/XmlSerializer.cpp | 1270 |
1 files changed, 1270 insertions, 0 deletions
diff --git a/APEX_1.4/NvParameterized/src/XmlSerializer.cpp b/APEX_1.4/NvParameterized/src/XmlSerializer.cpp new file mode 100644 index 00000000..b3f3c22e --- /dev/null +++ b/APEX_1.4/NvParameterized/src/XmlSerializer.cpp @@ -0,0 +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, "<NvParameters"); + if( !root ) + { + root = ::strstr(data, "<NvParameters"); + if (!root) + { + return Serializer::ERROR_MISSING_ROOT_ELEMENT; + } + } + + const char *numObjectsString = ::strstr(root, "numObjects"); + if( !numObjectsString ) + return Serializer::ERROR_INVALID_ATTR; + + numObjectsString = ::strstr(numObjectsString, "\""); + if( !numObjectsString ) + return Serializer::ERROR_INVALID_ATTR; + + numObjects = strtoul(numObjectsString + 1, 0, 0); //Skip leading quote + return Serializer::ERROR_NONE; +} + +class InputDataFromPxFileBuf: public physx::PxInputData +{ +public: + InputDataFromPxFileBuf(physx::PxFileBuf& fileBuf): mFileBuf(fileBuf) {} + + // physx::PxInputData interface + virtual uint32_t getLength() const + { + return mFileBuf.getFileLength(); + } + + virtual void seek(uint32_t offset) + { + mFileBuf.seekRead(offset); + } + + virtual uint32_t tell() const + { + return mFileBuf.tellRead(); + } + + // physx::PxInputStream interface + virtual uint32_t read(void* dest, uint32_t count) + { + return mFileBuf.read(dest, count); + } + + PX_NOCOPY(InputDataFromPxFileBuf) +private: + physx::PxFileBuf& mFileBuf; +}; + +Serializer::ErrorType XmlSerializer::peekClassNames(physx::PxFileBuf &stream, char **classNames, uint32_t &numClassNames) +{ + class ClassNameReader: public physx::shdfnd::FastXml::Callback + { + uint32_t mDepth; + uint32_t mNumObjs; + + char **mClassNames; + uint32_t mNumClassNames; + + Traits *mTraits; + + public: + ClassNameReader(char **classNames, uint32_t &numClassNames, Traits *traits) + : mDepth(0), mNumObjs(0), mClassNames(classNames), mNumClassNames(numClassNames), mTraits(traits) {} + + uint32_t numObjs() const { return mNumObjs; } + + bool processComment(const char * /*comment*/) { return true; } + + bool processClose(const char * /*element*/,uint32_t /*depth*/,bool & /*isError*/) + { + --mDepth; + return true; + } + + bool processElement( + const char *elementName, + const char * /*elementData*/, + const physx::shdfnd::FastXml::AttributePairs& attr, + int32_t /*lineno*/) + { + //Ignore top-level element + if( 0 == strcmp(elementName, "NvParameters") || 0 == strcmp(elementName, "NxParameters")) + return true; + + ++mDepth; + + if( 1 != mDepth || 0 != strcmp(elementName, "value") ) + return true; + + //Top-level <value> => 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<uint32_t>(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 << "</struct>\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; j<pd->numChildren(); 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<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamBoolArray(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << (uint32_t)v; + if ( (i+1) < arraySize ) + { + stream << " "; + } + if ( ((i+1)&63) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_I8: + { + int8_t v = 0; + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamI8Array(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << v; + if ( (i+1) < arraySize ) + { + stream << " "; + } + if ( ((i+1)&63) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_I16: + { + int16_t v = 0; + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamI16Array(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << v; + if ( (i+1) < arraySize ) + { + stream << " "; + } + if ( ((i+1)&31) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_I32: + { + int32_t v = 0; + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamI32Array(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << v; + if ( (i+1) < arraySize ) + { + stream << " "; + } + if ( ((i+1)&31) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_I64: + { + int64_t v = 0; + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamI64Array(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << v; + if ( (i+1) < arraySize ) + { + stream << " "; + } + if ( ((i+1)&31) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_U8: + { + uint8_t v = 0; + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamU8Array(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << v; + if ( (i+1) < arraySize ) + { + stream << " "; + } + if ( ((i+1)&63) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_U16: + { + uint16_t v = 0; + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamU16Array(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << v; + if ( (i+1) < arraySize ) + { + stream << " "; + } + if ( ((i+1)&63) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_U32: + { + uint32_t v = 0; + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamU32Array(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << v; + if ( (i+1) < arraySize ) + { + stream << " "; + } + if ( ((i+1)&31) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_U64: + { + uint64_t v = 0; + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamU64Array(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << v; + if ( (i+1) < arraySize ) + { + stream << " "; + } + if ( ((i+1)&31) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_F32: + { + float v = 0; + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamF32Array(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << v; + if ( (i+1) < arraySize ) + { + stream << " "; + } + if ( ((i+1)&31) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_F64: + { + double v = 0; + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamF64Array(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << v; + if ( (i+1) < arraySize ) + { + stream << " "; + } + if ( ((i+1)&31) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_VEC2: + { + physx::PxVec2 v(0,0); + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamVec2Array(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << v.x << " " << v.y; + if ( (i+1) < arraySize ) + { + stream << ", "; + } + if ( ((i+1)&15) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_VEC3: + { + physx::PxVec3 v(0,0,0); + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamVec3Array(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << v.x << " " << v.y << " " << v.z; + if ( (i+1) < arraySize ) + { + stream << ", "; + } + if ( ((i+1)&15) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_VEC4: + { + physx::PxVec4 v(0,0,0,0); + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamVec4Array(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << v.x << " " << v.y << " " << v.z << " " << v.w; + if ( (i+1) < arraySize ) + { + stream << ", "; + } + if ( ((i+1)&15) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_QUAT: + { + physx::PxQuat v(0,0,0,1); + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamQuatArray(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << v.x << " " << v.y << " " << v.z << " " << v.w; + if ( (i+1) < arraySize ) + { + stream << ", "; + } + if ( ((i+1)&15) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_MAT33: + { + physx::PxMat33 m = physx::PxMat33(physx::PxIdentity); + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamMat33Array(&m,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + const float *f = (const float *)m.front(); + stream << f[0] << " " << f[1] << " " << f[2] << " " ; + stream << f[3] << " " << f[4] << " " << f[5] << " "; + stream << f[6] << " " << f[7] << " " << f[8]; + if ( (i+1) < arraySize ) + { + stream << ", "; + } + if ( ((i+1)&15) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_BOUNDS3: + { + physx::PxBounds3 v; + v.minimum = physx::PxVec3(0.0f); + v.maximum = physx::PxVec3(0.0f); + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamBounds3Array(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + stream << v.minimum.x << " " << v.minimum.y << " " << v.minimum.z << " " << v.maximum.x << " " << v.maximum.y << " " << v.maximum.z; + if ( (i+1) < arraySize ) + { + stream << ", "; + } + if ( ((i+1)&15) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_MAT44: + { + physx::PxMat44 v = physx::PxMat44(physx::PxIdentity); + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamMat44Array(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + const float *f = (const float *)v.front(); + stream << f[0] << " " << f[1] << " " << f[2] << " " << f[3] << " "; + stream << f[4] << " " << f[5] << " " << f[6] << " " << f[7] << " "; + stream << f[8] << " " << f[9] << " " << f[10] << " " << f[11] << " "; + stream << f[12] << " " << f[13] << " " << f[14] << " " << f[15]; + if ( (i+1) < arraySize ) + { + stream << ", "; + } + if ( ((i+1)&15) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + case TYPE_TRANSFORM: + { + physx::PxTransform v = physx::PxTransform(physx::PxIdentity); + stream << state.indent; + for (int32_t i=0; i<arraySize; i++) + { + NV_PARAM_ERR_CHECK_RETURN( handle.getParamTransformArray(&v,1,i), Serializer::ERROR_ARRAY_INDEX_OUT_OF_RANGE ); + const float *f = (const float *)&v; + stream << f[0] << " " << f[1] << " " << f[2] << " " << f[3] << " "; + stream << f[4] << " " << f[5] << " " << f[6] << " "; + if ( (i+1) < arraySize ) + { + stream << ", "; + } + if ( ((i+1)&15) == 0 ) + { + stream << "\n"; + stream << state.indent; + } + } + stream << "\n"; + } + break; + + NV_PARAMETRIZED_STRING_DATATYPE_LABELS + NV_PARAMETRIZED_ENUM_DATATYPE_LABELS + NV_PARAMETRIZED_SERVICE_DATATYPE_LABELS + NV_PARAMETRIZED_UNDEFINED_AND_LAST_DATATYPE_LABELS + NV_PARAMETRIZED_LEGACY_DATATYPE_LABELS + case NvParameterized::TYPE_ARRAY: + default: + for(int32_t i = 0; i < arraySize; ++i) + { + handle.set(i); + NV_ERR_CHECK_RETURN( traverseParamDefTree(obj, stream, state, handle, printValues) ); + handle.popIndex(); + } + break; + } +#endif + } + +# if PRINT_ELEMENTS_WITHIN_EMPTY_ARRAYS + if( arraySize == 0 ) + { + handle.set(0); + NV_ERR_CHECK_RETURN( traverseParamDefTree(obj, stream, state, handle, false) ); + handle.popIndex(); + } +# endif + + state.decLevel(); + if( arraySize) + stream << state.indent; + + stream << "</array>\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 << "</value>\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 << "</value>\n"; + + break; + } //default + } //switch + + } //DONOTSERIALIZE + + if( isRoot ) + { + state.decLevel(); + stream << "</value>\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 << "<!-- " << hint->name() << ": "; + + if( hint->type() == TYPE_STRING ) + stream << hint->asString() ; + else if( hint->type() == TYPE_U64 ) + stream << hint->asUInt() ; + else if( hint->type() == TYPE_F64 ) + stream << hint->asFloat() ; + + stream << " -->\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 <struct> + 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; i<count; i++) + { + const Definition *d = pd->child(i); + if (d->hint("DONOTSERIALIZE") == NULL) + { + serializeCount++; + } + } + + for (int32_t i=0; i<count; i++) + { + const Definition *d = pd->child(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 << "<!DOCTYPE NvParameters>\n" + << "<NvParameters " + << "numObjects=\"" << n << "\" " + << "version=\"" << major << '.' << minor << "\" " + << ">\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 << "</NvParameters>\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 = "<!DOCTYPE NvParameters>"; + const char *magic2 = "<!DOCTYPE NxParameters>"; + return 0 == ::strncmp(hdr, magic1, strlen(magic1)) || + 0 == ::strncmp(hdr, magic2, strlen(magic2)); +} + +} // namespace NvParameterized + |