#include #include "memstrm.h" //############################################################################# //########################## MemoryStream ############################### //############################################################################# //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MemoryStream::MemoryStream(void *stream_start, size_t stream_size, size_t initial_offset) { streamStart = (char*)stream_start; streamSize = stream_size; Verify(initial_offset <= stream_size); currentPosition = streamStart + initial_offset; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MemoryStream& MemoryStream::ReadBytes(void *ptr, size_t number_of_bytes) { Verify(GetBytesRemaining() >= number_of_bytes); memcpy(ptr, GetPointer(), number_of_bytes); AdvancePointer(number_of_bytes); return *this; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MemoryStream& MemoryStream::WriteBytes(const void *ptr, size_t number_of_bytes) { Verify(number_of_bytes > 0); Verify(number_of_bytes <= GetBytesRemaining()); memcpy(GetPointer(), ptr, number_of_bytes); AdvancePointer(number_of_bytes); return *this; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MemoryStream& MemoryStream_Write(MemoryStream *stream, std::istream *input) { Verify(!input->bad()); input->clear(); // //-------------------------------------------------------- // If we are reading a binary stream, read it in one chunk //-------------------------------------------------------- // if (input->flags() & std::ios::binary) { input->seekg(0, std::ios::end); int len = input->tellg(); input->clear(); input->seekg(0); if (!stream->AllocateBytes(len)) return *stream; input->read((char*)stream->GetPointer(), len); stream->AdvancePointer(len); } // //---------------------------------------------------------------- // Read a text file character by character if we are a DOS machine //---------------------------------------------------------------- // else { input->clear(); input->seekg(0); unsigned char byte; while (input->get((char*)&byte, 1)) *stream << byte; } return *stream; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MemoryStream& MemoryStream_Write(MemoryStream *stream, const MemoryStream *input_stream) { return stream->WriteBytes(input_stream->GetPointer(), input_stream->GetBytesRemaining()); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool MemoryStream::TestInstance() const { return size_t(currentPosition - streamStart) <= streamSize; } //############################################################################# //###################### DynamicMemoryStream ############################ //############################################################################# // // calculate the allocation size for stream // inline size_t Calculate_Buffer_Size(size_t needed) { return (needed + 0x80) & ~0x7F; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // DynamicMemoryStream::DynamicMemoryStream(size_t stream_size) : MemoryStream(NULL, stream_size) { streamSize = Calculate_Buffer_Size(stream_size); streamStart = new char[streamSize]; currentPosition = streamStart; streamLength = 0L; ownsStream = true; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // DynamicMemoryStream::DynamicMemoryStream(void *stream_start, size_t stream_size, size_t initial_offset) : MemoryStream(stream_start, stream_size, initial_offset) { ownsStream = false; streamLength = stream_size; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // DynamicMemoryStream::~DynamicMemoryStream() { if (ownsStream) delete[] streamStart; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool DynamicMemoryStream::AllocateBytes(size_t count) { if (ownsStream && MemoryStream::GetBytesRemaining() < count) { size_t current_offset = currentPosition - streamStart; size_t new_stream_size = streamSize + count - MemoryStream::GetBytesRemaining() + 1; new_stream_size = Calculate_Buffer_Size(new_stream_size); char *new_stream_start = new char[new_stream_size]; memcpy(new_stream_start, streamStart, streamSize); delete[] streamStart; streamStart = new_stream_start; streamSize = new_stream_size; currentPosition = streamStart + current_offset; } return true; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MemoryStream& DynamicMemoryStream::WriteBytes(const void *ptr, size_t number_of_bytes) { 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); memcpy(GetPointer(), ptr, number_of_bytes); AdvancePointer(number_of_bytes); streamLength = __max(streamLength, GetBytesUsed()); return *this; }