diff options
| author | bgaldrikian <[email protected]> | 2020-11-10 20:53:31 -0800 |
|---|---|---|
| committer | bgaldrikian <[email protected]> | 2020-11-10 20:53:31 -0800 |
| commit | d61c455a4775f966b44cc47804b9e0f160d3d332 (patch) | |
| tree | 7eff987598048409fe4ec9a1f733a87356f3aa21 /shared/filebuf | |
| parent | * Updated license file (diff) | |
| download | blast-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')
| -rw-r--r-- | shared/filebuf/include/PsAsciiConversion.h | 99 | ||||
| -rw-r--r-- | shared/filebuf/include/PsAsciiConversion.inl | 566 | ||||
| -rw-r--r-- | shared/filebuf/include/PsFileBuffer.h | 250 | ||||
| -rw-r--r-- | shared/filebuf/include/PsIOStream.h | 137 | ||||
| -rw-r--r-- | shared/filebuf/include/PsIOStream.inl | 415 | ||||
| -rw-r--r-- | shared/filebuf/include/PsMemoryBuffer.h | 449 |
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 + |