include/filebuf/PxFileBuf.h
File members: include/filebuf/PxFileBuf.h
// 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-2024 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 PSFILEBUFFER_PXFILEBUF_H
#define PSFILEBUFFER_PXFILEBUF_H
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxAllocator.h"
#if !PX_DOXYGEN
namespace physx
{
namespace general_PxIOStream2
{
#endif
PX_PUSH_PACK_DEFAULT
class PxFileBuf
{
public:
enum EndianMode
{
ENDIAN_NONE = 0, // do no conversion for endian mode
ENDIAN_BIG = 1, // always read/write data as natively big endian (Power PC, etc.)
ENDIAN_LITTLE = 2 // always read/write data as natively little endian (Intel, etc.) Default Behavior!
};
PxFileBuf(EndianMode mode=ENDIAN_LITTLE)
{
setEndianMode(mode);
}
virtual ~PxFileBuf(void)
{
}
static const uint32_t STREAM_SEEK_END=0xFFFFFFFF;
enum OpenMode
{
OPEN_FILE_NOT_FOUND,
OPEN_READ_ONLY, // open file buffer stream for read only access
OPEN_WRITE_ONLY, // open file buffer stream for write only access
OPEN_READ_WRITE_NEW, // open a new file for both read/write access
OPEN_READ_WRITE_EXISTING // open an existing file for both read/write access
};
virtual OpenMode getOpenMode(void) const = 0;
bool isOpen(void) const
{
return getOpenMode()!=OPEN_FILE_NOT_FOUND;
}
enum SeekType
{
SEEKABLE_NO = 0,
SEEKABLE_READ = 0x1,
SEEKABLE_WRITE = 0x2,
SEEKABLE_READWRITE = 0x3
};
virtual SeekType isSeekable(void) const = 0;
void setEndianMode(EndianMode e)
{
mEndianMode = e;
if ( (e==ENDIAN_BIG && !isBigEndian() ) ||
(e==ENDIAN_LITTLE && isBigEndian() ) )
{
mEndianSwap = true;
}
else
{
mEndianSwap = false;
}
}
EndianMode getEndianMode(void) const
{
return mEndianMode;
}
virtual uint32_t getFileLength(void) const = 0;
virtual uint32_t seekRead(uint32_t loc) = 0;
virtual uint32_t seekWrite(uint32_t loc) = 0;
virtual uint32_t read(void *mem,uint32_t len) = 0;
virtual uint32_t peek(void *mem,uint32_t len) = 0;
virtual uint32_t write(const void *mem,uint32_t len) = 0;
virtual uint32_t tellRead(void) const = 0;
virtual uint32_t tellWrite(void) const = 0;
virtual void flush(void) = 0;
virtual void close(void) {}
void release(void)
{
PX_DELETE_THIS;
}
static PX_INLINE bool isBigEndian()
{
int32_t i = 1;
return *(reinterpret_cast<char*>(&i))==0;
}
PX_INLINE void swap2Bytes(void* _data) const
{
char *data = static_cast<char *>(_data);
char one_byte;
one_byte = data[0]; data[0] = data[1]; data[1] = one_byte;
}
PX_INLINE void swap4Bytes(void* _data) const
{
char *data = static_cast<char *>(_data);
char one_byte;
one_byte = data[0]; data[0] = data[3]; data[3] = one_byte;
one_byte = data[1]; data[1] = data[2]; data[2] = one_byte;
}
PX_INLINE void swap8Bytes(void *_data) const
{
char *data = static_cast<char *>(_data);
char one_byte;
one_byte = data[0]; data[0] = data[7]; data[7] = one_byte;
one_byte = data[1]; data[1] = data[6]; data[6] = one_byte;
one_byte = data[2]; data[2] = data[5]; data[5] = one_byte;
one_byte = data[3]; data[3] = data[4]; data[4] = one_byte;
}
PX_INLINE void storeDword(uint32_t v)
{
if ( mEndianSwap )
swap4Bytes(&v);
write(&v,sizeof(v));
}
PX_INLINE void storeFloat(float v)
{
if ( mEndianSwap )
swap4Bytes(&v);
write(&v,sizeof(v));
}
PX_INLINE void storeDouble(double v)
{
if ( mEndianSwap )
swap8Bytes(&v);
write(&v,sizeof(v));
}
PX_INLINE void storeByte(uint8_t b)
{
write(&b,sizeof(b));
}
PX_INLINE void storeWord(uint16_t w)
{
if ( mEndianSwap )
swap2Bytes(&w);
write(&w,sizeof(w));
}
uint8_t readByte(void)
{
uint8_t v=0;
read(&v,sizeof(v));
return v;
}
uint16_t readWord(void)
{
uint16_t v=0;
read(&v,sizeof(v));
if ( mEndianSwap )
swap2Bytes(&v);
return v;
}
uint32_t readDword(void)
{
uint32_t v=0;
read(&v,sizeof(v));
if ( mEndianSwap )
swap4Bytes(&v);
return v;
}
float readFloat(void)
{
float v=0;
read(&v,sizeof(v));
if ( mEndianSwap )
swap4Bytes(&v);
return v;
}
double readDouble(void)
{
double v=0;
read(&v,sizeof(v));
if ( mEndianSwap )
swap8Bytes(&v);
return v;
}
private:
bool mEndianSwap; // whether or not the endian should be swapped on the current platform
EndianMode mEndianMode; // the current endian mode behavior for the stream
};
PX_POP_PACK
#if !PX_DOXYGEN
} // end of namespace
using namespace general_PxIOStream2;
namespace general_PxIOStream = general_PxIOStream2;
} // end of namespace
#endif
#endif // PSFILEBUFFER_PXFILEBUF_H