GRK/dependencies/physx-4.1/source/pvd/src/PxProfileDataParsing.h
secret_dude a7bd7ecb75 master
2022-01-12 16:07:16 +01:00

219 lines
8.4 KiB
C++

//
// 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.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#ifndef PXPVDSDK_PXPROFILEDATAPARSING_H
#define PXPVDSDK_PXPROFILEDATAPARSING_H
#include "foundation/Px.h"
namespace physx { namespace profile {
//Converts datatypes without using type punning.
struct BlockParserDataConverter
{
union
{
uint8_t mU8[8];
uint16_t mU16[4];
uint32_t mU32[2];
uint64_t mU64[1];
int8_t mI8[8];
int16_t mI16[4];
int32_t mI32[2];
int64_t mI64[1];
float mF32[2];
double mF64[1];
};
template<typename TDataType> inline TDataType convert() { PX_ASSERT( false ); return TDataType(); }
template<typename TDataType>
inline void convert( const TDataType& ) {}
};
template<> inline uint8_t BlockParserDataConverter::convert<uint8_t>() { return mU8[0]; }
template<> inline uint16_t BlockParserDataConverter::convert<uint16_t>() { return mU16[0]; }
template<> inline uint32_t BlockParserDataConverter::convert<uint32_t>() { return mU32[0]; }
template<> inline uint64_t BlockParserDataConverter::convert<uint64_t>() { return mU64[0]; }
template<> inline int8_t BlockParserDataConverter::convert<int8_t>() { return mI8[0]; }
template<> inline int16_t BlockParserDataConverter::convert<int16_t>() { return mI16[0]; }
template<> inline int32_t BlockParserDataConverter::convert<int32_t>() { return mI32[0]; }
template<> inline int64_t BlockParserDataConverter::convert<int64_t>() { return mI64[0]; }
template<> inline float BlockParserDataConverter::convert<float>() { return mF32[0]; }
template<> inline double BlockParserDataConverter::convert<double>() { return mF64[0]; }
template<> inline void BlockParserDataConverter::convert<uint8_t>( const uint8_t& inData ) { mU8[0] = inData; }
template<> inline void BlockParserDataConverter::convert<uint16_t>( const uint16_t& inData ) { mU16[0] = inData; }
template<> inline void BlockParserDataConverter::convert<uint32_t>( const uint32_t& inData ) { mU32[0] = inData; }
template<> inline void BlockParserDataConverter::convert<uint64_t>( const uint64_t& inData ) { mU64[0] = inData; }
template<> inline void BlockParserDataConverter::convert<int8_t>( const int8_t& inData ) { mI8[0] = inData; }
template<> inline void BlockParserDataConverter::convert<int16_t>( const int16_t& inData ) { mI16[0] = inData; }
template<> inline void BlockParserDataConverter::convert<int32_t>( const int32_t& inData ) { mI32[0] = inData; }
template<> inline void BlockParserDataConverter::convert<int64_t>( const int64_t& inData ) { mI64[0] = inData; }
template<> inline void BlockParserDataConverter::convert<float>( const float& inData ) { mF32[0] = inData; }
template<> inline void BlockParserDataConverter::convert<double>( const double& inData ) { mF64[0] = inData; }
//Handles various details around parsing blocks of uint8_t data.
struct BlockParseFunctions
{
template<uint8_t ByteCount>
static inline void swapBytes( uint8_t* inData )
{
for ( uint32_t idx = 0; idx < ByteCount/2; ++idx )
{
uint32_t endIdx = ByteCount-idx-1;
uint8_t theTemp = inData[idx];
inData[idx] = inData[endIdx];
inData[endIdx] = theTemp;
}
}
static inline bool checkLength( const uint8_t* inStart, const uint8_t* inStop, uint32_t inLength )
{
return static_cast<uint32_t>(inStop - inStart) >= inLength;
}
//warning work-around
template<typename T>
static inline T val(T v) {return v;}
template<bool DoSwapBytes, typename TDataType>
static inline bool parse( const uint8_t*& inStart, const uint8_t* inStop, TDataType& outData )
{
if ( checkLength( inStart, inStop, sizeof( TDataType ) ) )
{
BlockParserDataConverter theConverter;
for ( uint32_t idx =0; idx < sizeof( TDataType ); ++idx )
theConverter.mU8[idx] = inStart[idx];
if ( val(DoSwapBytes))
swapBytes<sizeof(TDataType)>( theConverter.mU8 );
outData = theConverter.convert<TDataType>();
inStart += sizeof( TDataType );
return true;
}
return false;
}
template<bool DoSwapBytes, typename TDataType>
static inline bool parseBlock( const uint8_t*& inStart, const uint8_t* inStop, TDataType* outData, uint32_t inNumItems )
{
uint32_t desired = sizeof(TDataType)*inNumItems;
if ( checkLength( inStart, inStop, desired ) )
{
if ( val(DoSwapBytes) )
{
for ( uint32_t item = 0; item < inNumItems; ++item )
{
BlockParserDataConverter theConverter;
for ( uint32_t idx =0; idx < sizeof( TDataType ); ++idx )
theConverter.mU8[idx] = inStart[idx];
swapBytes<sizeof(TDataType)>( theConverter.mU8 );
outData[item] = theConverter.convert<TDataType>();
inStart += sizeof(TDataType);
}
}
else
{
uint8_t* target = reinterpret_cast<uint8_t*>(outData);
memmove( target, inStart, desired );
inStart += desired;
}
return true;
}
return false;
}
//In-place byte swapping block
template<bool DoSwapBytes, typename TDataType>
static inline bool parseBlock( uint8_t*& inStart, const uint8_t* inStop, uint32_t inNumItems )
{
uint32_t desired = sizeof(TDataType)*inNumItems;
if ( checkLength( inStart, inStop, desired ) )
{
if ( val(DoSwapBytes) )
{
for ( uint32_t item = 0; item < inNumItems; ++item, inStart += sizeof( TDataType ) )
swapBytes<sizeof(TDataType)>( inStart ); //In-place swap.
}
else
inStart += sizeof( TDataType ) * inNumItems;
return true;
}
return false;
}
};
//Wraps the begin/end keeping track of them.
template<bool DoSwapBytes>
struct BlockParser
{
const uint8_t* mBegin;
const uint8_t* mEnd;
BlockParser( const uint8_t* inBegin=NULL, const uint8_t* inEnd=NULL )
: mBegin( inBegin )
, mEnd( inEnd )
{
}
inline bool hasMoreData() const { return mBegin != mEnd; }
inline bool checkLength( uint32_t inLength ) { return BlockParseFunctions::checkLength( mBegin, mEnd, inLength ); }
template<typename TDataType>
inline bool read( TDataType& outDatatype ) { return BlockParseFunctions::parse<DoSwapBytes>( mBegin, mEnd, outDatatype ); }
template<typename TDataType>
inline bool readBlock( TDataType* outDataPtr, uint32_t inNumItems ) { return BlockParseFunctions::parseBlock<DoSwapBytes>( mBegin, mEnd, outDataPtr, inNumItems ); }
template<typename TDataType>
inline bool readBlock( uint32_t inNumItems )
{
uint8_t* theTempPtr = const_cast<uint8_t*>(mBegin);
bool retval = BlockParseFunctions::parseBlock<DoSwapBytes, TDataType>( theTempPtr, mEnd, inNumItems );
mBegin = theTempPtr;
return retval;
}
uint32_t amountLeft() const { return static_cast<uint32_t>( mEnd - mBegin ); }
};
//Reads the data without checking for error conditions
template<typename TDataType, typename TBlockParserType>
inline TDataType blockParserRead( TBlockParserType& inType )
{
TDataType retval;
inType.read( retval );
return retval;
}
}}
#endif // PXPVDSDK_PXPROFILEDATAPARSING_H