aboutsummaryrefslogtreecommitdiff
path: root/shared/filebuf/include
diff options
context:
space:
mode:
authorbgaldrikian <[email protected]>2020-11-10 20:53:31 -0800
committerbgaldrikian <[email protected]>2020-11-10 20:53:31 -0800
commitd61c455a4775f966b44cc47804b9e0f160d3d332 (patch)
tree7eff987598048409fe4ec9a1f733a87356f3aa21 /shared/filebuf/include
parent* Updated license file (diff)
downloadblast-1.1.7_rc1.tar.xz
blast-1.1.7_rc1.zip
Merge request #17 PhysX4 compatibilityv1.1.7_rc1
Other changes for linux and UE4CrossCompileLinux, and all packaging to work
Diffstat (limited to 'shared/filebuf/include')
-rw-r--r--shared/filebuf/include/PsAsciiConversion.h99
-rw-r--r--shared/filebuf/include/PsAsciiConversion.inl566
-rw-r--r--shared/filebuf/include/PsFileBuffer.h250
-rw-r--r--shared/filebuf/include/PsIOStream.h137
-rw-r--r--shared/filebuf/include/PsIOStream.inl415
-rw-r--r--shared/filebuf/include/PsMemoryBuffer.h449
6 files changed, 1916 insertions, 0 deletions
diff --git a/shared/filebuf/include/PsAsciiConversion.h b/shared/filebuf/include/PsAsciiConversion.h
new file mode 100644
index 0000000..9df5be9
--- /dev/null
+++ b/shared/filebuf/include/PsAsciiConversion.h
@@ -0,0 +1,99 @@
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of NVIDIA CORPORATION nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved.
+
+#ifndef PSFILEBUFFER_PSASCIICONVERSION_H
+#define PSFILEBUFFER_PSASCIICONVERSION_H
+
+/*!
+\file
+\brief PxAsciiConversion namespace contains string/value helper functions
+*/
+
+#include "PxMath.h"
+#include "PsString.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <float.h>
+
+namespace physx
+{
+namespace general_string_parsing2
+{
+namespace PxAsc
+{
+
+const uint32_t PxF32StrLen = 24;
+const uint32_t PxF64StrLen = 32;
+const uint32_t IntStrLen = 32;
+
+PX_INLINE bool isWhiteSpace(char c);
+PX_INLINE const char * skipNonWhiteSpace(const char *scan);
+PX_INLINE const char * skipWhiteSpace(const char *scan);
+
+//////////////////////////
+// str to value functions
+//////////////////////////
+PX_INLINE bool strToBool(const char *str, const char **endptr);
+PX_INLINE int8_t strToI8(const char *str, const char **endptr);
+PX_INLINE int16_t strToI16(const char *str, const char **endptr);
+PX_INLINE int32_t strToI32(const char *str, const char **endptr);
+PX_INLINE int64_t strToI64(const char *str, const char **endptr);
+PX_INLINE uint8_t strToU8(const char *str, const char **endptr);
+PX_INLINE uint16_t strToU16(const char *str, const char **endptr);
+PX_INLINE uint32_t strToU32(const char *str, const char **endptr);
+PX_INLINE uint64_t strToU64(const char *str, const char **endptr);
+PX_INLINE float strToF32(const char *str, const char **endptr);
+PX_INLINE double strToF64(const char *str, const char **endptr);
+PX_INLINE void strToF32s(float *v,uint32_t count,const char *str, const char**endptr);
+
+
+//////////////////////////
+// value to str functions
+//////////////////////////
+PX_INLINE const char * valueToStr( bool val, char *buf, uint32_t n );
+PX_INLINE const char * valueToStr( int8_t val, char *buf, uint32_t n );
+PX_INLINE const char * valueToStr( int16_t val, char *buf, uint32_t n );
+PX_INLINE const char * valueToStr( int32_t val, char *buf, uint32_t n );
+PX_INLINE const char * valueToStr( int64_t val, char *buf, uint32_t n );
+PX_INLINE const char * valueToStr( uint8_t val, char *buf, uint32_t n );
+PX_INLINE const char * valueToStr( uint16_t val, char *buf, uint32_t n );
+PX_INLINE const char * valueToStr( uint32_t val, char *buf, uint32_t n );
+PX_INLINE const char * valueToStr( uint64_t val, char *buf, uint32_t n );
+PX_INLINE const char * valueToStr( float val, char *buf, uint32_t n );
+PX_INLINE const char * valueToStr( double val, char *buf, uint32_t n );
+
+#include "PsAsciiConversion.inl"
+
+} // end of namespace
+} // end of namespace
+using namespace general_string_parsing2;
+} // end of namespace
+
+
+#endif // PSFILEBUFFER_PSASCIICONVERSION_H
diff --git a/shared/filebuf/include/PsAsciiConversion.inl b/shared/filebuf/include/PsAsciiConversion.inl
new file mode 100644
index 0000000..3b95813
--- /dev/null
+++ b/shared/filebuf/include/PsAsciiConversion.inl
@@ -0,0 +1,566 @@
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of NVIDIA CORPORATION nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved.
+
+/*!
+\file
+\brief NvAsciiConversion namespace contains string/value helper functions
+*/
+
+#include <ctype.h>
+
+PX_INLINE bool isWhiteSpace(char c)
+{
+ bool ret = false;
+ if ( c == 32 || c == 9 || c == 13 || c == 10 || c == ',' ) ret = true;
+ return ret;
+}
+
+PX_INLINE const char * skipNonWhiteSpace(const char *scan)
+{
+ while ( !isWhiteSpace(*scan) && *scan) scan++;
+ if ( *scan == 0 ) scan = NULL;
+ return scan;
+}
+PX_INLINE const char * skipWhiteSpace(const char *scan)
+{
+ while ( isWhiteSpace(*scan) && *scan ) scan++;
+ if ( *scan == 0 ) scan = NULL;
+ return scan;
+}
+
+static double strtod_fast(const char * pString)
+{
+ //---
+ // Find the start of the string
+ const char* pNumberStart = skipWhiteSpace(pString);
+
+ //---
+ // Find the end of the string
+ const char* pNumberEnd = pNumberStart;
+
+ // skip optional sign
+ if( *pNumberEnd == '-' || *pNumberEnd == '+' )
+ ++pNumberEnd;
+
+ // skip optional digits
+ while( isdigit(*pNumberEnd) )
+ ++pNumberEnd;
+
+ // skip optional decimal and digits
+ if( *pNumberEnd == '.' )
+ {
+ ++pNumberEnd;
+
+ while( isdigit(*pNumberEnd) )
+ ++pNumberEnd;
+ }
+
+ // skip optional exponent
+ if( *pNumberEnd == 'd'
+ || *pNumberEnd == 'D'
+ || *pNumberEnd == 'e'
+ || *pNumberEnd == 'E' )
+ {
+ ++pNumberEnd;
+
+ if( *pNumberEnd == '-' || *pNumberEnd == '+' )
+ ++pNumberEnd;
+
+ while( isdigit(*pNumberEnd) )
+ ++pNumberEnd;
+ }
+
+ //---
+ // Process the string
+ const uint32_t numberLen = (const uint32_t)(pNumberEnd-pNumberStart);
+ char buffer[32];
+ if( numberLen+1 < sizeof(buffer)/sizeof(buffer[0]) )
+ {
+ // copy into buffer and terminate with NUL before calling the
+ // standard function
+ memcpy( buffer, pNumberStart, numberLen*sizeof(buffer[0]) );
+ buffer[numberLen] = '\0';
+ const double result = strtod( buffer, NULL );
+
+ return result;
+ }
+ else
+ {
+ // buffer was too small so just call the standard function on the
+ // source input to get a proper result
+ return strtod( pString, NULL );
+ }
+}
+
+static float strtof_fast(const char* pString)
+{
+ return (float)strtod_fast(pString);
+}
+
+
+//////////////////////////
+// str to value functions
+//////////////////////////
+PX_INLINE bool strToBool(const char *str, const char **endptr)
+{
+ bool ret = false;
+ const char *begin = skipWhiteSpace(str);
+ const char *end = skipNonWhiteSpace(begin);
+
+ if( !end )
+ end = begin + strlen(str);
+
+ size_t len = (size_t)(end - begin);
+ if ( physx::shdfnd::strnicmp(begin,"true", len) == 0 || physx::shdfnd::strnicmp(begin,"1", len) == 0 )
+ ret = true;
+
+ if( endptr )
+ *endptr = skipNonWhiteSpace(begin);
+
+ return ret;
+}
+
+PX_INLINE int8_t strToI8(const char *str, const char **endptr)
+{
+ int8_t ret;
+ const char *begin = skipWhiteSpace(str);
+ const char *end = skipNonWhiteSpace(begin);
+
+ if( !end )
+ end = begin + strlen(str);
+
+ if( strncmp(begin, "INT8_MIN", (size_t)(end-begin)) == 0)
+ ret = INT8_MIN;
+ else if( strncmp(begin, "INT8_MAX", (size_t)(end-begin)) == 0)
+ ret = INT8_MAX;
+ else if( strncmp(begin, "PX_MIN_I8", (size_t)(end-begin)) == 0)
+ ret = INT8_MIN;
+ else if( strncmp(begin, "PX_MAX_I8", (size_t)(end-begin)) == 0)
+ ret = INT8_MAX;
+ else
+ ret = (int8_t)strtol(begin, 0, 0); //FIXME
+
+ if( endptr )
+ *endptr = skipNonWhiteSpace(begin);
+
+ return ret;
+}
+
+PX_INLINE int16_t strToI16(const char *str, const char **endptr)
+{
+ int16_t ret;
+ const char *begin = skipWhiteSpace(str);
+ const char *end = skipNonWhiteSpace(begin);
+
+ if( !end )
+ end = begin + strlen(str);
+
+ if( strncmp(begin, "INT16_MIN", (size_t)(end-begin)) == 0)
+ ret = INT16_MIN;
+ else if( strncmp(begin, "INT16_MAX", (size_t)(end-begin)) == 0)
+ ret = INT16_MAX;
+ else if( strncmp(begin, "PX_MIN_I16", (size_t)(end-begin)) == 0)
+ ret = INT16_MIN;
+ else if( strncmp(begin, "PX_MAX_I16", (size_t)(end-begin)) == 0)
+ ret = INT16_MAX;
+ else
+ ret = (int16_t)strtol(begin, 0, 0); //FIXME
+
+ if( endptr )
+ *endptr = skipNonWhiteSpace(begin);
+
+ return ret;
+}
+
+PX_INLINE int32_t strToI32(const char *str, const char **endptr)
+{
+ int32_t ret;
+ const char *begin = skipWhiteSpace(str);
+ const char *end = skipNonWhiteSpace(begin);
+
+ if( !end )
+ end = begin + strlen(str);
+
+ if( strncmp(begin, "INT32_MIN", (size_t)(end-begin)) == 0)
+ ret = INT32_MIN;
+ else if( strncmp(begin, "INT32_MAX", (size_t)(end-begin)) == 0)
+ ret = INT32_MAX;
+ else if( strncmp(begin, "PX_MIN_I32", (size_t)(end-begin)) == 0)
+ ret = INT32_MIN;
+ else if( strncmp(begin, "PX_MAX_I32", (size_t)(end-begin)) == 0)
+ ret = INT32_MAX;
+ else
+ ret = (int32_t)strtol(begin, 0, 0); //FIXME
+
+ if( endptr )
+ *endptr = skipNonWhiteSpace(begin);
+
+ return ret;
+}
+
+PX_INLINE int64_t strToI64(const char *str, const char **endptr)
+{
+ int64_t ret;
+ const char *begin = skipWhiteSpace(str);
+
+ //FIXME
+#ifdef _WIN32 //NV_WINDOWS, NV_XBOX
+ ret = (int64_t)_strtoi64(begin,0,10);
+#else
+ ret = (int64_t)strtoll(begin,0,10);
+#endif
+
+ if( endptr )
+ *endptr = skipNonWhiteSpace(begin);
+
+ return ret;
+}
+
+PX_INLINE uint8_t strToU8(const char *str, const char **endptr)
+{
+ uint8_t ret;
+ const char *begin = skipWhiteSpace(str);
+
+ ret = (uint8_t)strtoul(begin, 0, 0);
+
+ if( endptr )
+ *endptr = skipNonWhiteSpace(begin);
+
+ return ret;
+}
+
+PX_INLINE uint16_t strToU16(const char *str, const char **endptr)
+{
+ uint16_t ret;
+ const char *end;
+ const char *begin = skipWhiteSpace(str);
+
+ end = skipNonWhiteSpace(begin);
+ if( !end )
+ end = begin + strlen(str);
+
+ if( strncmp(begin, "UINT16_MAX", (size_t)(end-begin)) == 0)
+ ret = UINT16_MAX;
+ else if( strncmp(begin, "PX_MAX_U16", (size_t)(end-begin)) == 0)
+ ret = UINT16_MAX;
+ else
+ ret = (uint16_t)strtoul(begin,0,0);
+
+ if( endptr )
+ *endptr = skipNonWhiteSpace(begin);
+
+ return ret;
+}
+
+PX_INLINE uint32_t strToU32(const char *str, const char **endptr)
+{
+ uint32_t ret;
+ const char *begin = skipWhiteSpace(str);
+ const char *end = skipNonWhiteSpace(begin);
+
+ if( !end )
+ end = begin + strlen(str);
+
+ if( strncmp(begin, "UINT32_MAX", (size_t)(end-begin)) == 0)
+ ret = UINT32_MAX;
+ else if( strncmp(begin, "PX_U32_MAX", (size_t)(end-begin)) == 0)
+ ret = UINT32_MAX;
+ else
+ ret = (uint32_t)strtoul(begin,0,0);
+
+ if( endptr )
+ *endptr = skipNonWhiteSpace(begin);
+
+ return ret;
+}
+
+PX_INLINE uint64_t strToU64(const char *str, const char **endptr)
+{
+ uint64_t ret;
+ const char *begin;
+ begin = skipWhiteSpace(str);
+
+ //FIXME
+#ifdef _WIN32 //NV_WINDOWS, NV_XBOX
+ ret = (uint64_t)_strtoui64(begin,0,10);
+#else
+ ret = (uint64_t)strtoull(begin,0,10);
+#endif
+
+ if( endptr )
+ *endptr = skipNonWhiteSpace(begin);
+
+ return ret;
+}
+
+#ifndef DEBUGGING_MISMATCHES
+#define DEBUGGING_MISMATCHES 0
+#endif
+
+PX_INLINE float strToF32(const char *str, const char **endptr)
+{
+ float ret;
+ const char *begin = skipWhiteSpace(str);
+ const char *end = skipNonWhiteSpace(begin);
+
+ if( !end )
+ end = begin + strlen(str);
+
+ const uint32_t len = (uint32_t)(end - begin);
+
+ const char F32_MIN[] = "NV_MIN_F32";
+ const char F32_MAX[] = "NV_MAX_F32";
+ const char PX_F32_MIN[] = "PX_MIN_F32";
+ const char PX_F32_MAX[] = "PX_MAX_F32";
+
+ if( strncmp(begin, PX_F32_MIN, physx::PxMin(len, (uint32_t)(sizeof(PX_F32_MIN) - 1))) == 0)
+ ret = -PX_MAX_F32;
+ else if( strncmp(begin, PX_F32_MAX, physx::PxMin(len, (uint32_t)(sizeof(PX_F32_MAX) - 1))) == 0)
+ ret = PX_MAX_F32;
+ else if( strncmp(begin, F32_MIN, physx::PxMin(len, (uint32_t)(sizeof(F32_MIN) - 1))) == 0)
+ ret = -PX_MAX_F32;
+ else if( strncmp(begin, F32_MAX, physx::PxMin(len, (uint32_t)(sizeof(F32_MAX) - 1))) == 0)
+ ret = PX_MAX_F32;
+ else
+ {
+ ret = (float)strtof_fast(begin);
+ }
+
+#if DEBUGGING_MISMATCHES
+ float testRet = (float)atof(begin);
+ if( ret != testRet )
+ {
+ PX_ASSERT(0 && "Inaccurate float string");
+ }
+#endif
+
+ if( endptr )
+ *endptr = skipNonWhiteSpace(begin);
+
+ return ret;
+}
+
+
+PX_INLINE double strToF64(const char *str, const char **endptr)
+{
+ double ret;
+ const char *begin = skipWhiteSpace(str);
+ const char *end = skipNonWhiteSpace(begin);
+
+ end = skipNonWhiteSpace(begin);
+
+ if( !end )
+ end = begin + strlen(str);
+
+ const uint32_t len = (const uint32_t)(end - begin);
+
+ const char F64_MIN[] = "PX_MIN_F364";
+ const char F64_MAX[] = "PX_MAX_F64";
+ const char PX_F64_MIN[] = "PX_MIN_F64";
+ const char PX_F64_MAX[] = "PX_MAX_F64";
+
+ if( strncmp(begin, F64_MIN, physx::PxMin(len, (uint32_t)(sizeof(F64_MIN) - 1))) == 0)
+ ret = -PX_MAX_F64;
+ else if( strncmp(begin, F64_MAX, physx::PxMin(len, (uint32_t)(sizeof(F64_MAX) - 1))) == 0)
+ ret = PX_MAX_F64;
+ else if( strncmp(begin, PX_F64_MIN, physx::PxMin(len, (uint32_t)(sizeof(PX_F64_MIN) - 1))) == 0)
+ ret = -PX_MAX_F64;
+ else if( strncmp(begin, PX_F64_MAX, physx::PxMin(len, (uint32_t)(sizeof(PX_F64_MAX) - 1))) == 0)
+ ret = PX_MAX_F64;
+ else
+ ret = (double)strtod_fast(begin);
+
+ if( endptr )
+ *endptr = skipNonWhiteSpace(begin);
+
+ return ret;
+}
+
+PX_INLINE void strToF32s(float *v,uint32_t count,const char *str, const char**endptr)
+{
+ const char *begin = skipWhiteSpace(str);
+
+ if ( *begin == '(' ) begin++;
+ for (uint32_t i=0; i<count && *begin; i++)
+ {
+ v[i] = (float)strToF32(begin, &begin);
+ }
+
+ if( endptr )
+ *endptr = skipNonWhiteSpace(begin);
+}
+
+
+//////////////////////////
+// value to str functions
+//////////////////////////
+PX_INLINE const char * valueToStr( bool val, char *buf, uint32_t n )
+{
+ physx::shdfnd::snprintf(buf, n,"%s",val ? "true" : "false");
+ return buf;
+}
+
+PX_INLINE const char * valueToStr( int8_t val, char *buf, uint32_t n )
+{
+ if( val == INT8_MIN )
+ physx::shdfnd::snprintf(buf, n,"%s","INT8_MIN" );
+ else if( val == INT8_MAX )
+ physx::shdfnd::snprintf(buf, n,"%s","INT8_MAX" );
+ else
+ physx::shdfnd::snprintf(buf, n, "%d", val);
+ return buf;
+}
+
+PX_INLINE const char * valueToStr( int16_t val, char *buf, uint32_t n )
+{
+ if( val == INT16_MIN )
+ physx::shdfnd::snprintf(buf, n,"%s","INT16_MIN" );
+ else if( val == INT16_MAX )
+ physx::shdfnd::snprintf(buf, n,"%s","INT16_MAX" );
+ else
+ physx::shdfnd::snprintf(buf, n,"%d",val );
+ return buf;
+}
+
+PX_INLINE const char * valueToStr( int32_t val, char *buf, uint32_t n )
+{
+ if( val == INT32_MIN )
+ physx::shdfnd::snprintf(buf, n,"%s","INT32_MIN" );
+ else if( val == INT32_MAX )
+ physx::shdfnd::snprintf(buf, n,"%s","INT32_MAX" );
+ else
+ physx::shdfnd::snprintf(buf, n,"%d",val );
+ return buf;
+}
+
+PX_INLINE const char * valueToStr( int64_t val, char *buf, uint32_t n )
+{
+ physx::shdfnd::snprintf(buf, n,"%lld",val );
+ return buf;
+}
+
+PX_INLINE const char * valueToStr( uint8_t val, char *buf, uint32_t n )
+{
+ physx::shdfnd::snprintf(buf, n, "%u", val);
+ return buf;
+}
+
+PX_INLINE const char * valueToStr( uint16_t val, char *buf, uint32_t n )
+{
+ if( val == UINT16_MAX )
+ physx::shdfnd::snprintf(buf, n,"%s","UINT16_MAX" );
+ else
+ physx::shdfnd::snprintf(buf, n,"%u",val );
+ return buf;
+}
+
+PX_INLINE const char * valueToStr( uint32_t val, char *buf, uint32_t n )
+{
+ if( val == UINT32_MAX )
+ physx::shdfnd::snprintf(buf, n,"%s","UINT32_MAX" );
+ else
+ physx::shdfnd::snprintf(buf, n,"%u",val );
+ return buf;
+}
+
+PX_INLINE const char * valueToStr( uint64_t val, char *buf, uint32_t n )
+{
+ physx::shdfnd::snprintf(buf, n,"%llu",val );
+ return buf;
+}
+
+PX_INLINE const char * valueToStr( float val, char *buf, uint32_t n )
+{
+ if( !physx::PxIsFinite(val) )
+ {
+ PX_ASSERT( 0 && "invalid floating point" );
+ physx::shdfnd::snprintf(buf, n,"%s","0" );
+ }
+ else if( val == -PX_MAX_F32 )
+ physx::shdfnd::snprintf(buf, n,"%s","PX_MIN_F32" );
+ else if( val == PX_MAX_F32 )
+ physx::shdfnd::snprintf(buf, n,"%s","PX_MAX_F32" );
+ else if ( val == 1 )
+ physx::shdfnd::strlcpy(buf, n, "1");
+ else if ( val == 0 )
+ physx::shdfnd::strlcpy(buf, n, "0");
+ else if ( val == - 1 )
+ physx::shdfnd::strlcpy(buf, n, "-1");
+ else
+ {
+ physx::shdfnd::snprintf(buf,n,"%.9g", (double)val ); // %g expects double
+ const char *dot = strchr(buf,'.');
+ const char *e = strchr(buf,'e');
+ if ( dot && !e )
+ {
+ int32_t len = (int32_t)strlen(buf);
+ char *foo = &buf[len-1];
+ while ( *foo == '0' ) foo--;
+ if ( *foo == '.' )
+ *foo = 0;
+ else
+ foo[1] = 0;
+ }
+ }
+ return buf;
+}
+
+PX_INLINE const char * valueToStr( double val, char *buf, uint32_t n )
+{
+ if( !physx::PxIsFinite(val) )
+ {
+ PX_ASSERT( 0 && "invalid floating point" );
+ physx::shdfnd::snprintf(buf, n,"%s","0" );
+ }
+ else if( val == -PX_MAX_F64 )
+ physx::shdfnd::snprintf(buf, n,"%s","PX_MIN_F64" );
+ else if( val == PX_MAX_F64 )
+ physx::shdfnd::snprintf(buf, n,"%s","PX_MAX_F64" );
+ else if ( val == 1 )
+ physx::shdfnd::strlcpy(buf, n, "1");
+ else if ( val == 0 )
+ physx::shdfnd::strlcpy(buf, n, "0");
+ else if ( val == - 1 )
+ physx::shdfnd::strlcpy(buf, n, "-1");
+ else
+ {
+ physx::shdfnd::snprintf(buf,n,"%.18g", val );
+ const char *dot = strchr(buf,'.');
+ const char *e = strchr(buf,'e');
+ if ( dot && !e )
+ {
+ int32_t len = (int32_t)strlen(buf);
+ char *foo = &buf[len-1];
+ while ( *foo == '0' ) foo--;
+ if ( *foo == '.' )
+ *foo = 0;
+ else
+ foo[1] = 0;
+ }
+ }
+ return buf;
+}
diff --git a/shared/filebuf/include/PsFileBuffer.h b/shared/filebuf/include/PsFileBuffer.h
new file mode 100644
index 0000000..2a09257
--- /dev/null
+++ b/shared/filebuf/include/PsFileBuffer.h
@@ -0,0 +1,250 @@
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of NVIDIA CORPORATION nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved.
+
+#ifndef PSFILEBUFFER_PSFILEBUFFER_H
+#define PSFILEBUFFER_PSFILEBUFFER_H
+
+#include "filebuf/PxFileBuf.h"
+
+#include "Ps.h"
+#include "PsUserAllocated.h"
+#include <stdio.h>
+
+namespace physx
+{
+namespace general_PxIOStream2
+{
+ using namespace shdfnd;
+
+//Use this class if you want to use your own allocator
+class PxFileBufferBase : public PxFileBuf
+{
+public:
+ PxFileBufferBase(const char *fileName,OpenMode mode)
+ {
+ mOpenMode = mode;
+ mFph = NULL;
+ mFileLength = 0;
+ mSeekRead = 0;
+ mSeekWrite = 0;
+ mSeekCurrent = 0;
+ switch ( mode )
+ {
+ case OPEN_READ_ONLY:
+ mFph = fopen(fileName,"rb");
+ break;
+ case OPEN_WRITE_ONLY:
+ mFph = fopen(fileName,"wb");
+ break;
+ case OPEN_READ_WRITE_NEW:
+ mFph = fopen(fileName,"wb+");
+ break;
+ case OPEN_READ_WRITE_EXISTING:
+ mFph = fopen(fileName,"rb+");
+ break;
+ case OPEN_FILE_NOT_FOUND:
+ break;
+ }
+ if ( mFph )
+ {
+ fseek(mFph,0L,SEEK_END);
+ mFileLength = static_cast<uint32_t>(ftell(mFph));
+ fseek(mFph,0L,SEEK_SET);
+ }
+ else
+ {
+ mOpenMode = OPEN_FILE_NOT_FOUND;
+ }
+ }
+
+ virtual ~PxFileBufferBase()
+ {
+ close();
+ }
+
+ virtual void close()
+ {
+ if( mFph )
+ {
+ fclose(mFph);
+ mFph = 0;
+ }
+ }
+
+ virtual SeekType isSeekable(void) const
+ {
+ return mSeekType;
+ }
+
+ virtual uint32_t read(void* buffer, uint32_t size)
+ {
+ uint32_t ret = 0;
+ if ( mFph )
+ {
+ setSeekRead();
+ ret = static_cast<uint32_t>(::fread(buffer,1,size,mFph));
+ mSeekRead+=ret;
+ mSeekCurrent+=ret;
+ }
+ return ret;
+ }
+
+ virtual uint32_t peek(void* buffer, uint32_t size)
+ {
+ uint32_t ret = 0;
+ if ( mFph )
+ {
+ uint32_t loc = tellRead();
+ setSeekRead();
+ ret = static_cast<uint32_t>(::fread(buffer,1,size,mFph));
+ mSeekCurrent+=ret;
+ seekRead(loc);
+ }
+ return ret;
+ }
+
+ virtual uint32_t write(const void* buffer, uint32_t size)
+ {
+ uint32_t ret = 0;
+ if ( mFph )
+ {
+ setSeekWrite();
+ ret = static_cast<uint32_t>(::fwrite(buffer,1,size,mFph));
+ mSeekWrite+=ret;
+ mSeekCurrent+=ret;
+ if ( mSeekWrite > mFileLength )
+ {
+ mFileLength = mSeekWrite;
+ }
+ }
+ return ret;
+ }
+
+ virtual uint32_t tellRead(void) const
+ {
+ return mSeekRead;
+ }
+
+ virtual uint32_t tellWrite(void) const
+ {
+ return mSeekWrite;
+ }
+
+ virtual uint32_t seekRead(uint32_t loc)
+ {
+ mSeekRead = loc;
+ if ( mSeekRead > mFileLength )
+ {
+ mSeekRead = mFileLength;
+ }
+ return mSeekRead;
+ }
+
+ virtual uint32_t seekWrite(uint32_t loc)
+ {
+ mSeekWrite = loc;
+ if ( mSeekWrite > mFileLength )
+ {
+ mSeekWrite = mFileLength;
+ }
+ return mSeekWrite;
+ }
+
+ virtual void flush(void)
+ {
+ if ( mFph )
+ {
+ ::fflush(mFph);
+ }
+ }
+
+ virtual OpenMode getOpenMode(void) const
+ {
+ return mOpenMode;
+ }
+
+ virtual uint32_t getFileLength(void) const
+ {
+ return mFileLength;
+ }
+
+private:
+ // Moves the actual file pointer to the current read location
+ void setSeekRead(void)
+ {
+ if ( mSeekRead != mSeekCurrent && mFph )
+ {
+ if ( mSeekRead >= mFileLength )
+ {
+ fseek(mFph,0L,SEEK_END);
+ }
+ else
+ {
+ fseek(mFph,static_cast<long>(mSeekRead),SEEK_SET);
+ }
+ mSeekCurrent = mSeekRead = static_cast<uint32_t>(ftell(mFph));
+ }
+ }
+ // Moves the actual file pointer to the current write location
+ void setSeekWrite(void)
+ {
+ if ( mSeekWrite != mSeekCurrent && mFph )
+ {
+ if ( mSeekWrite >= mFileLength )
+ {
+ fseek(mFph,0L,SEEK_END);
+ }
+ else
+ {
+ fseek(mFph,static_cast<long>(mSeekWrite),SEEK_SET);
+ }
+ mSeekCurrent = mSeekWrite = static_cast<uint32_t>(ftell(mFph));
+ }
+ }
+
+
+ FILE *mFph;
+ uint32_t mSeekRead;
+ uint32_t mSeekWrite;
+ uint32_t mSeekCurrent;
+ uint32_t mFileLength;
+ SeekType mSeekType;
+ OpenMode mOpenMode;
+};
+
+//Use this class if you want to use PhysX memory allocator
+class PsFileBuffer: public PxFileBufferBase, public UserAllocated
+{
+public:
+ PsFileBuffer(const char *fileName,OpenMode mode): PxFileBufferBase(fileName, mode) {}
+};
+
+}
+using namespace general_PxIOStream2;
+}
+
+#endif // PSFILEBUFFER_PSFILEBUFFER_H
diff --git a/shared/filebuf/include/PsIOStream.h b/shared/filebuf/include/PsIOStream.h
new file mode 100644
index 0000000..54f9b89
--- /dev/null
+++ b/shared/filebuf/include/PsIOStream.h
@@ -0,0 +1,137 @@
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of NVIDIA CORPORATION nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved.
+
+#ifndef PSFILEBUFFER_PSIOSTREAM_H
+#define PSFILEBUFFER_PSIOSTREAM_H
+
+/*!
+\file
+\brief PsIOStream class
+*/
+#include "filebuf/PxFileBuf.h"
+
+#include "Ps.h"
+#include "PsString.h"
+#include <string.h>
+#include <stdlib.h>
+#include "PsAsciiConversion.h"
+
+#define safePrintf physx::shdfnd::snprintf
+
+PX_PUSH_PACK_DEFAULT
+
+namespace physx
+{
+ namespace general_PxIOStream2
+ {
+
+/**
+\brief A wrapper class for physx::PxFileBuf that provides both binary and ASCII streaming capabilities
+*/
+class PsIOStream
+{
+ static const uint32_t MAX_STREAM_STRING = 1024;
+public:
+ /**
+ \param [in] stream the physx::PxFileBuf through which all reads and writes will be performed
+ \param [in] streamLen the length of the input data stream when de-serializing
+ */
+ PsIOStream(physx::PxFileBuf &stream,uint32_t streamLen) : mBinary(true), mStreamLen(streamLen), mStream(stream) { }
+ ~PsIOStream(void) { }
+
+ /**
+ \brief Set the stream to binary or ASCII
+
+ \param [in] state if true, stream is binary, if false, stream is ASCII
+
+ If the stream is binary, stream access is passed straight through to the respecitve
+ physx::PxFileBuf methods. If the stream is ASCII, all stream reads and writes are converted to
+ human readable ASCII.
+ */
+ PX_INLINE void setBinary(bool state) { mBinary = state; }
+ PX_INLINE bool getBinary() { return mBinary; }
+
+ PX_INLINE PsIOStream& operator<<(bool v);
+ PX_INLINE PsIOStream& operator<<(char c);
+ PX_INLINE PsIOStream& operator<<(uint8_t v);
+ PX_INLINE PsIOStream& operator<<(int8_t v);
+
+ PX_INLINE PsIOStream& operator<<(const char *c);
+ PX_INLINE PsIOStream& operator<<(int64_t v);
+ PX_INLINE PsIOStream& operator<<(uint64_t v);
+ PX_INLINE PsIOStream& operator<<(double v);
+ PX_INLINE PsIOStream& operator<<(float v);
+ PX_INLINE PsIOStream& operator<<(uint32_t v);
+ PX_INLINE PsIOStream& operator<<(int32_t v);
+ PX_INLINE PsIOStream& operator<<(uint16_t v);
+ PX_INLINE PsIOStream& operator<<(int16_t v);
+ PX_INLINE PsIOStream& operator<<(const physx::PxVec3 &v);
+ PX_INLINE PsIOStream& operator<<(const physx::PxQuat &v);
+ PX_INLINE PsIOStream& operator<<(const physx::PxBounds3 &v);
+
+ PX_INLINE PsIOStream& operator>>(const char *&c);
+ PX_INLINE PsIOStream& operator>>(bool &v);
+ PX_INLINE PsIOStream& operator>>(char &c);
+ PX_INLINE PsIOStream& operator>>(uint8_t &v);
+ PX_INLINE PsIOStream& operator>>(int8_t &v);
+ PX_INLINE PsIOStream& operator>>(int64_t &v);
+ PX_INLINE PsIOStream& operator>>(uint64_t &v);
+ PX_INLINE PsIOStream& operator>>(double &v);
+ PX_INLINE PsIOStream& operator>>(float &v);
+ PX_INLINE PsIOStream& operator>>(uint32_t &v);
+ PX_INLINE PsIOStream& operator>>(int32_t &v);
+ PX_INLINE PsIOStream& operator>>(uint16_t &v);
+ PX_INLINE PsIOStream& operator>>(int16_t &v);
+ PX_INLINE PsIOStream& operator>>(physx::PxVec3 &v);
+ PX_INLINE PsIOStream& operator>>(physx::PxQuat &v);
+ PX_INLINE PsIOStream& operator>>(physx::PxBounds3 &v);
+
+ uint32_t getStreamLen(void) const { return mStreamLen; }
+
+ physx::PxFileBuf& getStream(void) { return mStream; }
+
+ PX_INLINE void storeString(const char *c,bool zeroTerminate=false);
+
+private:
+ PsIOStream& operator=( const PsIOStream& );
+
+
+ bool mBinary; // true if we are serializing binary data. Otherwise, everything is assumed converted to ASCII
+ uint32_t mStreamLen; // the length of the input data stream when de-serializing.
+ physx::PxFileBuf &mStream;
+ char mReadString[MAX_STREAM_STRING]; // a temp buffer for streaming strings on input.
+};
+
+#include "PsIOStream.inl" // inline methods...
+
+ } // end of namespace
+ using namespace general_PxIOStream2;
+} // end of physx namespace
+
+PX_POP_PACK
+
+#endif // PSFILEBUFFER_PSIOSTREAM_H
diff --git a/shared/filebuf/include/PsIOStream.inl b/shared/filebuf/include/PsIOStream.inl
new file mode 100644
index 0000000..f12ef68
--- /dev/null
+++ b/shared/filebuf/include/PsIOStream.inl
@@ -0,0 +1,415 @@
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of NVIDIA CORPORATION nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved.
+
+/*!
+\file
+\brief PsIOStream inline implementation
+*/
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(bool v)
+{
+ if ( mBinary )
+ {
+ mStream.storeByte((uint8_t)v);
+ }
+ else
+ {
+ char scratch[6];
+ storeString( physx::PxAsc::valueToStr(v, scratch, 6) );
+ }
+ return *this;
+}
+
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(char c)
+{
+ mStream.storeByte((uint8_t)c);
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(uint8_t c)
+{
+ if ( mBinary )
+ {
+ mStream.storeByte((uint8_t)c);
+ }
+ else
+ {
+ char scratch[physx::PxAsc::IntStrLen];
+ storeString( physx::PxAsc::valueToStr(c, scratch, physx::PxAsc::IntStrLen) );
+ }
+
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(int8_t c)
+{
+ if ( mBinary )
+ {
+ mStream.storeByte((uint8_t)c);
+ }
+ else
+ {
+ char scratch[physx::PxAsc::IntStrLen];
+ storeString( physx::PxAsc::valueToStr(c, scratch, physx::PxAsc::IntStrLen) );
+ }
+
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(const char *c)
+{
+ if ( mBinary )
+ {
+ c = c ? c : ""; // it it is a null pointer, assign it to an empty string.
+ uint32_t len = (uint32_t)strlen(c);
+ PX_ASSERT( len < (MAX_STREAM_STRING-1));
+ if ( len > (MAX_STREAM_STRING-1) )
+ {
+ len = MAX_STREAM_STRING-1;
+ }
+ mStream.storeDword(len);
+ if ( len )
+ mStream.write(c,len);
+ }
+ else
+ {
+ storeString(c);
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(uint64_t v)
+{
+ if ( mBinary )
+ {
+ mStream.storeDouble( (double) v );
+ }
+ else
+ {
+ char scratch[physx::PxAsc::IntStrLen];
+ storeString( physx::PxAsc::valueToStr(v, scratch, physx::PxAsc::IntStrLen) );
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(int64_t v)
+{
+ if ( mBinary )
+ {
+ mStream.storeDouble( (double) v );
+ }
+ else
+ {
+ char scratch[physx::PxAsc::IntStrLen];
+ storeString( physx::PxAsc::valueToStr(v, scratch, physx::PxAsc::IntStrLen) );
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(double v)
+{
+ if ( mBinary )
+ {
+ mStream.storeDouble( (double) v );
+ }
+ else
+ {
+ char scratch[physx::PxAsc::PxF64StrLen];
+ storeString( physx::PxAsc::valueToStr(v, scratch, physx::PxAsc::PxF64StrLen) );
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(float v)
+{
+ if ( mBinary )
+ {
+ mStream.storeFloat(v);
+ }
+ else
+ {
+ char scratch[physx::PxAsc::PxF32StrLen];
+ storeString( physx::PxAsc::valueToStr(v, scratch, physx::PxAsc::PxF32StrLen) );
+
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(uint32_t v)
+{
+ if ( mBinary )
+ {
+ mStream.storeDword(v);
+ }
+ else
+ {
+ char scratch[physx::PxAsc::IntStrLen];
+ storeString( physx::PxAsc::valueToStr(v, scratch, physx::PxAsc::IntStrLen) );
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(int32_t v)
+{
+ if ( mBinary )
+ {
+ mStream.storeDword( (uint32_t) v );
+ }
+ else
+ {
+ char scratch[physx::PxAsc::IntStrLen];
+ storeString( physx::PxAsc::valueToStr(v, scratch, physx::PxAsc::IntStrLen) );
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(uint16_t v)
+{
+ if ( mBinary )
+ {
+ mStream.storeWord(v);
+ }
+ else
+ {
+ char scratch[physx::PxAsc::IntStrLen];
+ storeString( physx::PxAsc::valueToStr(v, scratch, physx::PxAsc::IntStrLen) );
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(int16_t v)
+{
+ if ( mBinary )
+ {
+ mStream.storeWord( (uint16_t) v );
+ }
+ else
+ {
+ char scratch[physx::PxAsc::IntStrLen];
+ storeString( physx::PxAsc::valueToStr(v, scratch, physx::PxAsc::IntStrLen) );
+ }
+ return *this;
+}
+
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(uint32_t &v)
+{
+ if ( mBinary )
+ {
+ v = mStream.readDword();
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(char &v)
+{
+ if ( mBinary )
+ {
+ v = (char)mStream.readByte();
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(uint8_t &v)
+{
+ if ( mBinary )
+ {
+ v = mStream.readByte();
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(int8_t &v)
+{
+ if ( mBinary )
+ {
+ v = (int8_t)mStream.readByte();
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(int64_t &v)
+{
+ if ( mBinary )
+ {
+ v = mStream.readDword();
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(uint64_t &v)
+{
+ if ( mBinary )
+ {
+ v = (uint64_t)mStream.readDouble();
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(double &v)
+{
+ if ( mBinary )
+ {
+ v = mStream.readDouble();
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(float &v)
+{
+ if ( mBinary )
+ {
+ v = mStream.readFloat();
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(int32_t &v)
+{
+ if ( mBinary )
+ {
+ v = (int32_t)mStream.readDword();
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(uint16_t &v)
+{
+ if ( mBinary )
+ {
+ v = mStream.readWord();
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(int16_t &v)
+{
+ if ( mBinary )
+ {
+ v = (int16_t)mStream.readWord();
+ }
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(bool &v)
+{
+ int8_t iv;
+ iv = (int8_t)mStream.readByte();
+ v = iv ? true : false;
+ return *this;
+}
+
+#define NX_IOSTREAM_COMMA_SEPARATOR if(!mBinary) *this << ' ';
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(const physx::PxVec3 &v)
+{
+ *this << v.x;
+ NX_IOSTREAM_COMMA_SEPARATOR;
+ *this << v.y;
+ NX_IOSTREAM_COMMA_SEPARATOR;
+ *this << v.z;
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(const physx::PxQuat &v)
+{
+ *this << v.x;
+ NX_IOSTREAM_COMMA_SEPARATOR;
+ *this << v.y;
+ NX_IOSTREAM_COMMA_SEPARATOR;
+ *this << v.z;
+ NX_IOSTREAM_COMMA_SEPARATOR;
+ *this << v.w;
+ return *this;
+}
+
+
+PX_INLINE PsIOStream& PsIOStream::operator<<(const physx::PxBounds3 &v)
+{
+ *this << v.minimum;
+ NX_IOSTREAM_COMMA_SEPARATOR;
+ *this << v.maximum;
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(physx::PxVec3 &v)
+{
+ *this >> v.x;
+ *this >> v.y;
+ *this >> v.z;
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(physx::PxQuat &v)
+{
+ *this>>v.x;
+ *this>>v.y;
+ *this>>v.z;
+ *this>>v.w;
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(physx::PxBounds3 &v)
+{
+ *this >> v.minimum;
+ *this >> v.maximum;
+ return *this;
+}
+
+PX_INLINE PsIOStream& PsIOStream::operator>>(const char *&str)
+{
+ str = NULL; // by default no string streamed...
+ if ( mBinary )
+ {
+ uint32_t len=0;
+ *this >> len;
+
+ PX_ASSERT( len < (MAX_STREAM_STRING-1) );
+ if ( len < (MAX_STREAM_STRING-1) )
+ {
+ mStream.read(mReadString,len);
+ mReadString[len] = 0;
+ str = mReadString;
+ }
+ }
+ return *this;
+}
+
+
+PX_INLINE void PsIOStream::storeString(const char *c,bool zeroTerminate)
+{
+ while ( *c )
+ {
+ mStream.storeByte((uint8_t)*c);
+ c++;
+ }
+ if ( zeroTerminate )
+ {
+ mStream.storeByte(0);
+ }
+}
diff --git a/shared/filebuf/include/PsMemoryBuffer.h b/shared/filebuf/include/PsMemoryBuffer.h
new file mode 100644
index 0000000..f708819
--- /dev/null
+++ b/shared/filebuf/include/PsMemoryBuffer.h
@@ -0,0 +1,449 @@
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of NVIDIA CORPORATION nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved.
+
+#ifndef PSFILEBUFFER_PSMEMORYBUFFER_H
+#define PSFILEBUFFER_PSMEMORYBUFFER_H
+
+#include "Ps.h"
+#include "PsUserAllocated.h"
+#include "PsAlignedMalloc.h"
+#include "filebuf/PxFileBuf.h"
+#include "foundation/PxAssert.h"
+
+namespace physx
+{
+namespace general_PxIOStream2
+{
+ using namespace shdfnd;
+
+ const uint32_t BUFFER_SIZE_DEFAULT = 4096;
+
+//Use this class if you want to use your own allocator
+template<class Allocator>
+class PxMemoryBufferBase : public PxFileBuf, public Allocator
+{
+ PX_NOCOPY(PxMemoryBufferBase)
+ void init(const void *readMem, uint32_t readLen)
+ {
+ mAllocator = this;
+
+ mReadBuffer = mReadLoc = static_cast<const uint8_t *>(readMem);
+ mReadStop = &mReadLoc[readLen];
+
+ mWriteBuffer = mWriteLoc = mWriteStop = NULL;
+ mWriteBufferSize = 0;
+ mDefaultWriteBufferSize = BUFFER_SIZE_DEFAULT;
+
+ mOpenMode = OPEN_READ_ONLY;
+ mSeekType = SEEKABLE_READ;
+ }
+
+ void init(uint32_t defaultWriteBufferSize)
+ {
+ mAllocator = this;
+
+ mReadBuffer = mReadLoc = mReadStop = NULL;
+
+ mWriteBuffer = mWriteLoc = mWriteStop = NULL;
+ mWriteBufferSize = 0;
+ mDefaultWriteBufferSize = defaultWriteBufferSize;
+
+ mOpenMode = OPEN_READ_WRITE_NEW;
+ mSeekType = SEEKABLE_READWRITE;
+ }
+
+public:
+ PxMemoryBufferBase(const void *readMem,uint32_t readLen)
+ {
+ init(readMem, readLen);
+ }
+
+ PxMemoryBufferBase(const void *readMem,uint32_t readLen, const Allocator &alloc): Allocator(alloc)
+ {
+ init(readMem, readLen);
+ }
+
+ PxMemoryBufferBase(uint32_t defaultWriteBufferSize = BUFFER_SIZE_DEFAULT)
+ {
+ init(defaultWriteBufferSize);
+ }
+
+ PxMemoryBufferBase(uint32_t defaultWriteBufferSize, const Allocator &alloc): Allocator(alloc)
+ {
+ init(defaultWriteBufferSize);
+ }
+
+ virtual ~PxMemoryBufferBase(void)
+ {
+ reset();
+ }
+
+ void setAllocator(Allocator *allocator)
+ {
+ mAllocator = allocator;
+ }
+
+ void initWriteBuffer(uint32_t size)
+ {
+ if ( mWriteBuffer == NULL )
+ {
+ if ( size < mDefaultWriteBufferSize ) size = mDefaultWriteBufferSize;
+ mWriteBuffer = static_cast<uint8_t *>(mAllocator->allocate(size));
+ PX_ASSERT( mWriteBuffer );
+ mWriteLoc = mWriteBuffer;
+ mWriteStop = &mWriteBuffer[size];
+ mWriteBufferSize = size;
+ mReadBuffer = mWriteBuffer;
+ mReadStop = &mWriteBuffer[size];
+ mReadLoc = mWriteBuffer;
+ }
+ }
+
+ void reset(void)
+ {
+ mAllocator->deallocate(mWriteBuffer);
+ mWriteBuffer = NULL;
+ mWriteBufferSize = 0;
+ mWriteLoc = NULL;
+ mWriteStop = NULL;
+ mReadBuffer = NULL;
+ mReadStop = NULL;
+ mReadLoc = NULL;
+ }
+
+ virtual OpenMode getOpenMode(void) const
+ {
+ return mOpenMode;
+ }
+
+
+ SeekType isSeekable(void) const
+ {
+ return mSeekType;
+ }
+
+ virtual uint32_t read(void* buffer, uint32_t size)
+ {
+ if ( (mReadLoc+size) > mReadStop )
+ {
+ size = uint32_t(mReadStop - mReadLoc);
+ }
+ if ( size != 0 )
+ {
+ memmove(buffer,mReadLoc,size);
+ mReadLoc+=size;
+ }
+ return size;
+ }
+
+ virtual uint32_t peek(void* buffer, uint32_t size)
+ {
+ if ( (mReadLoc+size) > mReadStop )
+ {
+ size = uint32_t(mReadStop - mReadLoc);
+ }
+ if ( size != 0 )
+ {
+ memmove(buffer,mReadLoc,size);
+ }
+ return size;
+ }
+
+ virtual uint32_t write(const void* buffer, uint32_t size)
+ {
+ PX_ASSERT( mOpenMode == OPEN_READ_WRITE_NEW );
+ if ( mOpenMode == OPEN_READ_WRITE_NEW )
+ {
+ if ( (mWriteLoc+size) > mWriteStop )
+ growWriteBuffer(size);
+ memmove(mWriteLoc,buffer,size);
+ mWriteLoc+=size;
+ mReadStop = mWriteLoc;
+ }
+ else
+ {
+ size = 0;
+ }
+ return size;
+ }
+
+ PX_INLINE const uint8_t * getReadLoc(void) const { return mReadLoc; }
+ PX_INLINE void advanceReadLoc(uint32_t len)
+ {
+ PX_ASSERT(mReadBuffer);
+ if ( mReadBuffer )
+ {
+ mReadLoc+=len;
+ if ( mReadLoc >= mReadStop )
+ {
+ mReadLoc = mReadStop;
+ }
+ }
+ }
+
+ virtual uint32_t tellRead(void) const
+ {
+ uint32_t ret=0;
+
+ if ( mReadBuffer )
+ {
+ ret = uint32_t(mReadLoc-mReadBuffer);
+ }
+ return ret;
+ }
+
+ virtual uint32_t tellWrite(void) const
+ {
+ return uint32_t(mWriteLoc-mWriteBuffer);
+ }
+
+ virtual uint32_t seekRead(uint32_t loc)
+ {
+ uint32_t ret = 0;
+ PX_ASSERT(mReadBuffer);
+ if ( mReadBuffer )
+ {
+ mReadLoc = &mReadBuffer[loc];
+ if ( mReadLoc >= mReadStop )
+ {
+ mReadLoc = mReadStop;
+ }
+ ret = uint32_t(mReadLoc-mReadBuffer);
+ }
+ return ret;
+ }
+
+ virtual uint32_t seekWrite(uint32_t loc)
+ {
+ uint32_t ret = 0;
+ PX_ASSERT( mOpenMode == OPEN_READ_WRITE_NEW );
+ if ( mWriteBuffer )
+ {
+ if ( loc > mWriteBufferSize )
+ {
+ mWriteLoc = mWriteStop;
+ growWriteBuffer(loc - mWriteBufferSize);
+ }
+ mWriteLoc = &mWriteBuffer[loc];
+ ret = uint32_t(mWriteLoc-mWriteBuffer);
+ }
+ return ret;
+ }
+
+ virtual void flush(void)
+ {
+
+ }
+
+ virtual uint32_t getFileLength(void) const
+ {
+ uint32_t ret = 0;
+ if ( mReadBuffer )
+ {
+ ret = uint32_t(mReadStop-mReadBuffer);
+ }
+ else if ( mWriteBuffer )
+ {
+ ret = uint32_t(mWriteLoc-mWriteBuffer);
+ }
+ return ret;
+ }
+
+ uint32_t getWriteBufferSize(void) const
+ {
+ return uint32_t(mWriteLoc-mWriteBuffer);
+ }
+
+ void setWriteLoc(uint8_t *writeLoc)
+ {
+ PX_ASSERT(writeLoc >= mWriteBuffer && writeLoc < mWriteStop );
+ mWriteLoc = writeLoc;
+ mReadStop = mWriteLoc;
+ }
+
+ const uint8_t * getWriteBuffer(void) const
+ {
+ return mWriteBuffer;
+ }
+
+ /**
+ * Attention: if you use aligned allocator you cannot free memory with PX_FREE macros instead use deallocate method from base
+ */
+ uint8_t * getWriteBufferOwnership(uint32_t &dataLen) // return the write buffer, and zero it out, the caller is taking ownership of the memory
+ {
+ uint8_t *ret = mWriteBuffer;
+ dataLen = uint32_t(mWriteLoc-mWriteBuffer);
+ mWriteBuffer = NULL;
+ mWriteLoc = NULL;
+ mWriteStop = NULL;
+ mWriteBufferSize = 0;
+ return ret;
+ }
+
+
+ void alignRead(uint32_t a)
+ {
+ uint32_t loc = tellRead();
+ uint32_t aloc = ((loc+(a-1))/a)*a;
+ if ( aloc != loc )
+ {
+ seekRead(aloc);
+ }
+ }
+
+ void alignWrite(uint32_t a)
+ {
+ uint32_t loc = tellWrite();
+ uint32_t aloc = ((loc+(a-1))/a)*a;
+ if ( aloc != loc )
+ {
+ seekWrite(aloc);
+ }
+ }
+
+private:
+
+
+ // double the size of the write buffer or at least as large as the 'size' value passed in.
+ void growWriteBuffer(uint32_t size)
+ {
+ if ( mWriteBuffer == NULL )
+ {
+ if ( size < mDefaultWriteBufferSize ) size = mDefaultWriteBufferSize;
+ initWriteBuffer(size);
+ }
+ else
+ {
+ uint32_t oldWriteIndex = uint32_t(mWriteLoc - mWriteBuffer);
+ uint32_t newSize = mWriteBufferSize*2;
+ uint32_t avail = newSize-oldWriteIndex;
+ if ( size >= avail ) newSize = newSize+size;
+ uint8_t *writeBuffer = static_cast<uint8_t *>(mAllocator->allocate(newSize));
+ PX_ASSERT( writeBuffer );
+ memmove(writeBuffer,mWriteBuffer,mWriteBufferSize);
+ mAllocator->deallocate(mWriteBuffer);
+ mWriteBuffer = writeBuffer;
+ mWriteBufferSize = newSize;
+ mWriteLoc = &mWriteBuffer[oldWriteIndex];
+ mWriteStop = &mWriteBuffer[mWriteBufferSize];
+ uint32_t oldReadLoc = uint32_t(mReadLoc-mReadBuffer);
+ mReadBuffer = mWriteBuffer;
+ mReadStop = mWriteLoc;
+ mReadLoc = &mReadBuffer[oldReadLoc];
+ }
+ }
+
+ const uint8_t *mReadBuffer;
+ const uint8_t *mReadLoc;
+ const uint8_t *mReadStop;
+
+ uint8_t *mWriteBuffer;
+ uint8_t *mWriteLoc;
+ uint8_t *mWriteStop;
+
+ uint32_t mWriteBufferSize;
+ uint32_t mDefaultWriteBufferSize;
+ Allocator *mAllocator;
+ OpenMode mOpenMode;
+ SeekType mSeekType;
+
+};
+
+class PxMemoryBufferAllocator
+{
+public:
+ PxMemoryBufferAllocator(uint32_t a = 0) : alignment(a) {}
+
+ virtual void * allocate(uint32_t size)
+ {
+ switch(alignment)
+ {
+ case 0:
+ return PX_ALLOC(size, PX_DEBUG_EXP("PxMemoryBufferAllocator"));
+ case 16 :
+ return physx::AlignedAllocator<16>().allocate(size, __FILE__, __LINE__);
+ case 32 :
+ return physx::AlignedAllocator<32>().allocate(size, __FILE__, __LINE__);
+ case 64 :
+ return physx::AlignedAllocator<64>().allocate(size, __FILE__, __LINE__);
+ case 128 :
+ return physx::AlignedAllocator<128>().allocate(size, __FILE__, __LINE__);
+ default :
+ PX_ASSERT(0);
+ }
+ return NULL;
+ }
+ virtual void deallocate(void *mem)
+ {
+ switch(alignment)
+ {
+ case 0:
+ PX_FREE(mem);
+ break;
+ case 16 :
+ physx::AlignedAllocator<16>().deallocate(mem);
+ break;
+ case 32 :
+ physx::AlignedAllocator<32>().deallocate(mem);
+ break;
+ case 64 :
+ physx::AlignedAllocator<64>().deallocate(mem);
+ break;
+ case 128 :
+ physx::AlignedAllocator<128>().deallocate(mem);
+ break;
+ default :
+ PX_ASSERT(0);
+ }
+ }
+ virtual ~PxMemoryBufferAllocator(void) {}
+private:
+ PxMemoryBufferAllocator& operator=(const PxMemoryBufferAllocator&);
+
+ const uint32_t alignment;
+};
+
+//Use this class if you want to use PhysX memory allocator
+class PsMemoryBuffer: public PxMemoryBufferBase<PxMemoryBufferAllocator>, public UserAllocated
+{
+ PX_NOCOPY(PsMemoryBuffer)
+ typedef PxMemoryBufferBase<PxMemoryBufferAllocator> BaseClass;
+
+public:
+ PsMemoryBuffer(const void *readMem,uint32_t readLen): BaseClass(readMem, readLen) {}
+ PsMemoryBuffer(const void *readMem,uint32_t readLen, uint32_t alignment): BaseClass(readMem, readLen, PxMemoryBufferAllocator(alignment)) {}
+
+ PsMemoryBuffer(uint32_t defaultWriteBufferSize=BUFFER_SIZE_DEFAULT): BaseClass(defaultWriteBufferSize) {}
+ PsMemoryBuffer(uint32_t defaultWriteBufferSize,uint32_t alignment): BaseClass(defaultWriteBufferSize, PxMemoryBufferAllocator(alignment)) {}
+};
+
+}
+using namespace general_PxIOStream2;
+}
+
+#endif // PSFILEBUFFER_PSMEMORYBUFFER_H
+