This commit is contained in:
2025-11-28 23:13:44 +05:30
commit a3a8e79709
7360 changed files with 1156074 additions and 0 deletions

View File

@ -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-2021 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

View File

@ -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-2021 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;
}

View File

@ -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-2021 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

View File

@ -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-2021 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

View File

@ -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-2021 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);
}
}

View File

@ -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-2021 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