//===========================================================================// // File: memstrm.cpp // // Project: MUNGA Brick: Resource Manager // // Contents: Implementation Details of resource management // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // //---------------------------------------------------------------------------// // Copyright (C) 1994-1995, Virtual World Entertainment, Inc. // // PROPRIETARY AND CONFIDENTIAL // //===========================================================================// #include #pragma hdrstop #if !defined(MEMSTRM_HPP) #include #endif //############################################################################# //########################## MemoryStream ############################### //############################################################################# //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MemoryStream::MemoryStream( void *stream_start, size_t stream_size, size_t initial_offset ) { Check_Pointer(this); 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 ) { Check(this); Check_Pointer(ptr); Verify(number_of_bytes > 0); Verify(GetBytesRemaining() >= number_of_bytes); Mem_Copy(ptr, GetPointer(), number_of_bytes, number_of_bytes); AdvancePointer(number_of_bytes); return *this; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MemoryStream& MemoryStream::WriteBytes( const void *ptr, size_t number_of_bytes ) { Check(this); Check_Pointer(ptr); Verify(number_of_bytes > 0) Mem_Copy(GetPointer(), ptr, number_of_bytes, GetBytesRemaining()); AdvancePointer(number_of_bytes); return *this; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MemoryStream& MemoryStream_Write( MemoryStream *stream, istream *input ) { Check(stream); Check_Pointer(input); Verify(!input->bad()); input->clear(); // //-------------------------------------------------------- // If we are reading a binary stream, read it in one chunk //-------------------------------------------------------- // #if defined(LBE4) if (input->flags() & ios::binary) { #endif input->seekg(0, ios::end); int len=input->tellg(); input->clear(); input->seekg(0); if (!stream->AllocateBytes(len)) { Fail("Not enough memory remaining in stream!"); } input->read((char*)stream->GetPointer(), len); stream->AdvancePointer(len); #if defined(LBE4) } // //---------------------------------------------------------------- // 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(byte)) { *stream << byte; } } #endif return *stream; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MemoryStream& MemoryStream_Write( MemoryStream *stream, const MemoryStream *input_stream ) { Check(stream); Check(input_stream); return stream->WriteBytes( input_stream->GetPointer(), input_stream->GetBytesRemaining() ); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical 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) { Check_Pointer(this); streamSize = Calculate_Buffer_Size(stream_size); streamStart = new char[streamSize]; Register_Pointer(streamStart); 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) { Check_Pointer(this); ownsStream = False; streamLength = stream_size; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // DynamicMemoryStream::~DynamicMemoryStream() { Check(this); if (ownsStream) { Unregister_Pointer(streamStart); delete[] streamStart; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Logical DynamicMemoryStream::AllocateBytes(size_t count) { Check(this); 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]; Register_Pointer(new_stream_start); Mem_Copy(new_stream_start, streamStart, streamSize, new_stream_size); Unregister_Pointer(streamStart); 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 ) { Check(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); streamLength = Max(streamLength, GetBytesUsed()); return *this; }