📄 memorystream.cpp
字号:
//SPEW(("jerryeds", "READ : %x", workingBitBuffer));
currentBit = 0;
}
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream&
MemoryStream::WriteBit(const bool &bit_value)
{
Check_Object(this);
int int_bit_value = (bit_value)?1:0;
if (currentBit == Empty_Bit_Buffer)
{
currentBit = 0;
workingBitBuffer = 0x0;
}
Verify(currentBit >= 0);
Verify(currentBit < 8);
workingBitBuffer |= (int_bit_value << currentBit);
currentBit++;
if (currentBit > 7)
{
WriteBytes(&workingBitBuffer, 1);
//SPEW(("jerryeds", "WRITE : %x", workingBitBuffer));
workingBitBuffer = 0x00;
currentBit = 0;
}
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream&
MemoryStream::ReadUnsafeBits(
void *ptr,
DWORD number_of_bits
)
{
Check_Object(this);
Check_Pointer(ptr);
if (currentBit == Empty_Bit_Buffer)
{
ReadBytes(&workingBitBuffer, 1);
//SPEW(("jerryeds", "READ : %x", workingBitBuffer));
currentBit = 0;
}
Verify(currentBit >= 0);
Verify(currentBit < 8);
int total_number_of_bytes = (int)(number_of_bits/8.0f);
int total_remainder_bits = number_of_bits - (total_number_of_bytes*8);
if ( total_remainder_bits != 0)
{
total_number_of_bytes += 1;
}
BYTE *dest_array = Cast_Pointer(BYTE *, ptr);
int dest_byte_counter = 0;
int bits_remaining = number_of_bits;
while (bits_remaining > 0)
{
BYTE *dest = &dest_array[dest_byte_counter];
// empy out destination
*dest = 0x00;
int total_bits_to_be_read = 8;
Max_Clamp(total_bits_to_be_read, bits_remaining);
int bits_in_first_source_byte = total_bits_to_be_read;
Max_Clamp(bits_in_first_source_byte, 8-currentBit);
// make a mask of bits to be used
int bit_mask = 0xff >> (8-bits_in_first_source_byte);
// shift past the used bits in the buffer
*dest = (BYTE)(workingBitBuffer >> currentBit);
// remove any bits from the next set that tagged along
*dest &= bit_mask;
currentBit += bits_in_first_source_byte;
if (currentBit == 8)
{
int bits_in_second_source_byte = total_bits_to_be_read - bits_in_first_source_byte;
if (GetBytesRemaining())
{
ReadBytes(&workingBitBuffer, 1);
//SPEW(("jerryeds", "READ : %x", workingBitBuffer));
}
++dest_byte_counter;
currentBit = 0;
if (bits_in_second_source_byte)
{
// make a bitmask of the used bits
bit_mask = 0xff >> (8-bits_in_second_source_byte);
// mask the used bits out of the buffer and then shift the buffer to the correct
// bit location. Then combine it with the destination
*dest |= ((workingBitBuffer & bit_mask) << bits_in_first_source_byte);
currentBit = bits_in_second_source_byte;
}
}
bits_remaining -= total_bits_to_be_read;
}
Verify(currentBit >= 0);
Verify(currentBit < 8);
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream&
MemoryStream::WriteBits(
const void *ptr,
DWORD number_of_bits
)
{
Check_Object(this);
Check_Pointer(ptr);
if (currentBit == Empty_Bit_Buffer)
{
workingBitBuffer = 0x00;
currentBit = 0;
}
Verify(currentBit >= 0);
Verify(currentBit < 8);
int total_number_of_bytes = (int)(number_of_bits/8.0f);
int total_remainder_bits = number_of_bits - (total_number_of_bytes*8);
if ( total_remainder_bits != 0)
{
total_number_of_bytes += 1;
}
const BYTE *source_array = Cast_Pointer(const BYTE *, ptr);
int source_byte_counter = 0;
int bits_remaining = number_of_bits;
while (bits_remaining > 0)
{
// if we are writing the full byte
const BYTE *source = &source_array[source_byte_counter];
int total_bits_to_be_written = 8;
Max_Clamp(total_bits_to_be_written, bits_remaining);
int bits_in_first_destination_byte = total_bits_to_be_written;
Max_Clamp(bits_in_first_destination_byte, 8-currentBit);
// make sure our destination is empty
workingBitBuffer &= (0xff >> (8-currentBit));
// move the source data to the correct bit location
BYTE new_source = (BYTE)(*source << currentBit);
// put the adjusted source into the destination
workingBitBuffer |= new_source;
currentBit += bits_in_first_destination_byte;
if (currentBit == 8)
{
int bits_in_second_destination_byte = total_bits_to_be_written - bits_in_first_destination_byte;
//SPEW(("jerryeds", "WRITE : %x", workingBitBuffer));
WriteBytes(&workingBitBuffer, 1);
++source_byte_counter;
workingBitBuffer = 0x00;
currentBit = 0;
if (bits_in_second_destination_byte)
{
// remove bits we have already used
workingBitBuffer = (BYTE)(*source >> bits_in_first_destination_byte);
currentBit = bits_in_second_destination_byte;
}
}
bits_remaining -= total_bits_to_be_written;
}
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream&
MemoryStream::ReadBitsToScaledInt(int &number, int min, int max, DWORD number_of_bits)
{
DWORD buffer = 0x0;
ReadUnsafeBits(&buffer, number_of_bits);
number = Scaled_Int_From_Bits(buffer, min, max, number_of_bits);
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream&
MemoryStream::WriteScaledIntToBits(const int &number, int min, int max, DWORD number_of_bits)
{
Check_Object(this);
DWORD buffer;
buffer = Scaled_Int_To_Bits(number, min, max, number_of_bits);
WriteBits(&buffer, number_of_bits);
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream&
MemoryStream::ReadBitsToScaledFloat(float &number, float min, float max, DWORD number_of_bits)
{
Check_Object(this);
DWORD buffer = 0x0;
ReadBits(&buffer, number_of_bits);
number = Scaled_Float_From_Bits(buffer, min, max, number_of_bits);
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream&
MemoryStream::WriteScaledFloatToBits(const float &number, float min, float max, DWORD number_of_bits)
{
Check_Object(this);
DWORD buffer;
buffer = Scaled_Float_To_Bits(number, min, max, number_of_bits);
WriteBits(&buffer, number_of_bits);
return *this;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MemoryStream::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
Verify(DWORD(currentPosition - streamStart) <= streamSize);
}
//#############################################################################
//###################### DynamicMemoryStream ############################
//#############################################################################
//
// calculate the allocation size for stream
//
static inline DWORD
Calculate_Buffer_Size(DWORD needed)
{
return (needed+0x80)&~0x7F;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DynamicMemoryStream::DynamicMemoryStream(DWORD stream_size):
MemoryStream(NULL, stream_size)
{
Check_Pointer(this);
bufferSize = Calculate_Buffer_Size(stream_size);
streamStart = new BYTE[bufferSize];
Check_Pointer(streamStart);
currentPosition = streamStart;
streamSize = stream_size;
ownsStream = true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DynamicMemoryStream::DynamicMemoryStream(const DynamicMemoryStream &otherStream):
MemoryStream(NULL, otherStream.GetSize())
{
Check_Pointer(this);
Check_Pointer(&otherStream);
bufferSize = otherStream.bufferSize;
streamStart = new BYTE[bufferSize];
Check_Pointer(streamStart);
streamSize = otherStream.GetSize();
Mem_Copy(streamStart, otherStream.streamStart, streamSize, bufferSize);
currentPosition = streamStart + otherStream.GetBytesUsed();
ownsStream = true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DynamicMemoryStream::DynamicMemoryStream(
void *stream_start,
DWORD stream_size,
DWORD initial_offset
):
MemoryStream(stream_start, stream_size, initial_offset)
{
Check_Pointer(this);
ownsStream = false;
bufferSize = stream_size;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DynamicMemoryStream::~DynamicMemoryStream()
{
Check_Object(this);
if (ownsStream)
{
Check_Pointer(streamStart);
delete[] streamStart;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
DynamicMemoryStream::AllocateBytes(DWORD count)
{
Check_Object(this);
DWORD current_offset = currentPosition - streamStart;
DWORD new_stream_size = current_offset + count;
if (ownsStream && bufferSize - current_offset < count)
{
bufferSize = Calculate_Buffer_Size(new_stream_size);
BYTE *new_stream_start = new BYTE[bufferSize];
Check_Pointer(new_stream_start);
Mem_Copy(new_stream_start, streamStart, streamSize, bufferSize);
Check_Pointer(streamStart);
delete[] streamStart;
streamStart = new_stream_start;
streamSize = new_stream_size;
currentPosition = streamStart + current_offset;
}
else if (new_stream_size > streamSize)
streamSize = new_stream_size;
return true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MemoryStream&
DynamicMemoryStream::WriteBytes(
const void *ptr,
DWORD number_of_bytes
)
{
Check_Object(this);
Check_Pointer(ptr);
Verify(number_of_bytes > 0);
//
//--------------------------------------------------------------------
// If we own the stream, and we don't have enough memory to accept the
// write, copy the buffer and make a new stream that is bigger
//--------------------------------------------------------------------
//
AllocateBytes(number_of_bytes);
Mem_Copy(
GetPointer(),
ptr,
number_of_bytes,
MemoryStream::GetBytesRemaining()
);
AdvancePointer(number_of_bytes);
bufferSize = Max(bufferSize, GetBytesUsed());
return *this;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -