[raknet] Add BitStream ctor/dtor

This commit is contained in:
RD42 2023-12-07 23:17:19 +08:00
parent 3019bf70c1
commit c15853af35
2 changed files with 190 additions and 0 deletions

121
raknet/BitStream.cpp Normal file
View File

@ -0,0 +1,121 @@
// TODO: Implement BitStream.cpp
#include "BitStream.h"
#include <stdlib.h>
#include <string.h>
using namespace RakNet;
BitStream::BitStream()
{
numberOfBitsUsed = 0;
//numberOfBitsAllocated = 32 * 8;
numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE * 8;
readOffset = 0;
//data = ( unsigned char* ) malloc( 32 );
data = ( unsigned char* ) stackData;
#ifdef _DEBUG
// assert( data );
#endif
//memset(data, 0, 32);
copyData = true;
}
BitStream::BitStream( int initialBytesToAllocate )
{
numberOfBitsUsed = 0;
readOffset = 0;
if (initialBytesToAllocate <= BITSTREAM_STACK_ALLOCATION_SIZE)
{
data = ( unsigned char* ) stackData;
numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE * 8;
}
else
{
data = ( unsigned char* ) malloc( initialBytesToAllocate );
numberOfBitsAllocated = initialBytesToAllocate << 3;
}
#ifdef _DEBUG
assert( data );
#endif
// memset(data, 0, initialBytesToAllocate);
copyData = true;
}
BitStream::BitStream( unsigned char* _data, unsigned int lengthInBytes, bool _copyData )
{
numberOfBitsUsed = lengthInBytes << 3;
readOffset = 0;
copyData = _copyData;
numberOfBitsAllocated = lengthInBytes << 3;
if ( copyData )
{
if ( lengthInBytes > 0 )
{
if (lengthInBytes < BITSTREAM_STACK_ALLOCATION_SIZE)
{
data = ( unsigned char* ) stackData;
numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE << 3;
}
else
{
data = ( unsigned char* ) malloc( lengthInBytes );
}
#ifdef _DEBUG
assert( data );
#endif
memcpy( data, _data, lengthInBytes );
}
else
data = 0;
}
else
data = ( unsigned char* ) _data;
}
// SAMPSRV (adding this just as a tag for next RakNet upgrade)
BitStream::BitStream( char* _dataC, unsigned int lengthInBytes, bool _copyData )
{
unsigned char* _data = reinterpret_cast<unsigned char*>(_dataC);
numberOfBitsUsed = lengthInBytes << 3;
readOffset = 0;
copyData = _copyData;
numberOfBitsAllocated = lengthInBytes << 3;
if ( copyData )
{
if ( lengthInBytes > 0 )
{
if (lengthInBytes < BITSTREAM_STACK_ALLOCATION_SIZE)
{
data = ( unsigned char* ) stackData;
numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE << 3;
}
else
{
data = ( unsigned char* ) malloc( lengthInBytes );
}
#ifdef _DEBUG
assert( data );
#endif
memcpy( data, _data, lengthInBytes );
}
else
data = 0;
}
else
data = ( unsigned char* ) _data;
}
BitStream::~BitStream()
{
if ( copyData && numberOfBitsAllocated > BITSTREAM_STACK_ALLOCATION_SIZE << 3)
free( data ); // Use realloc and free so we are more efficient than delete and new for resizing
}

69
raknet/BitStream.h Normal file
View File

@ -0,0 +1,69 @@
// TODO: Implement BitStream.h
#ifndef __BITSTREAM_H
#define __BITSTREAM_H
#include "Export.h"
#include "NetworkTypes.h"
/// Arbitrary size, just picking something likely to be larger than most packets
#define BITSTREAM_STACK_ALLOCATION_SIZE 256
/// The namespace RakNet is not consistently used. It's only purpose is to avoid compiler errors for classes whose names are very common.
/// For the most part I've tried to avoid this simply by using names very likely to be unique for my classes.
namespace RakNet
{
/// This class allows you to write and read native types as a string of bits. BitStream is used extensively throughout RakNet and is designed to be used by users as well.
/// \sa BitStreamSample.txt
class RAK_DLL_EXPORT BitStream
{
public:
/// Default Constructor
BitStream();
/// Create the bitstream, with some number of bytes to immediately allocate.
/// There is no benefit to calling this, unless you know exactly how many bytes you need and it is greater than BITSTREAM_STACK_ALLOCATION_SIZE.
/// In that case all it does is save you one or more realloc calls.
/// \param[in] initialBytesToAllocate the number of bytes to pre-allocate.
BitStream( int initialBytesToAllocate );
/// Initialize the BitStream, immediately setting the data it contains to a predefined pointer.
/// Set \a _copyData to true if you want to make an internal copy of the data you are passing. Set it to false to just save a pointer to the data.
/// You shouldn't call Write functions with \a _copyData as false, as this will write to unallocated memory
/// 99% of the time you will use this function to cast Packet::data to a bitstream for reading, in which case you should write something as follows:
/// \code
/// RakNet::BitStream bs(packet->data, packet->length, false);
/// \endcode
/// \param[in] _data An array of bytes.
/// \param[in] lengthInBytes Size of the \a _data.
/// \param[in] _copyData true or false to make a copy of \a _data or not.
BitStream( unsigned char* _data, unsigned int lengthInBytes, bool _copyData );
// SAMPSRV (adding this just as a tag for next RakNet upgrade)
BitStream( char* _dataC, unsigned int lengthInBytes, bool _copyData );
// SAMPSRV end
/// Destructor
~BitStream();
private:
int numberOfBitsUsed;
int numberOfBitsAllocated;
int readOffset;
unsigned char *data;
/// true if the internal buffer is copy of the data passed to the constructor
bool copyData;
/// BitStreams that use less than BITSTREAM_STACK_ALLOCATION_SIZE use the stack, rather than the heap to store data. It switches over if BITSTREAM_STACK_ALLOCATION_SIZE is exceeded
unsigned char stackData[BITSTREAM_STACK_ALLOCATION_SIZE];
};
}
#endif