diff options
Diffstat (limited to 'SrcShared/EmStream.cpp')
-rw-r--r-- | SrcShared/EmStream.cpp | 591 |
1 files changed, 591 insertions, 0 deletions
diff --git a/SrcShared/EmStream.cpp b/SrcShared/EmStream.cpp new file mode 100644 index 0000000..d513de0 --- /dev/null +++ b/SrcShared/EmStream.cpp @@ -0,0 +1,591 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +// =========================================================================== +// EmStream.cpp ©1993-1998 Metrowerks Inc. All rights reserved. +// =========================================================================== +// +// Abstract class for reading/writing an ordered sequence of bytes + +#include "EmCommon.h" +#include "EmStream.h" + +#include "Byteswapping.h" // Canonical + + +#pragma mark --- Construction & Destruction --- + +// --------------------------------------------------------------------------- +// ¥ EmStream +// --------------------------------------------------------------------------- +// Default Constructor + +EmStream::EmStream (void) : + mMarker (0), + mLength (0) +{ +} + + +// --------------------------------------------------------------------------- +// ¥ ~EmStream +// --------------------------------------------------------------------------- +// Destructor + +EmStream::~EmStream (void) +{ +} + + +#pragma mark --- Accessors --- + +// --------------------------------------------------------------------------- +// ¥ SetMarker +// --------------------------------------------------------------------------- +// Place the Read/Write Marker at an offset from a specified position +// +// inFromWhere can be streamFrom_Start, streamFrom_End, or streamFrom_Marker + +void +EmStream::SetMarker ( + int32 inOffset, + StreamFromType inFromWhere) +{ + int32 newMarker = mMarker; + + switch (inFromWhere) + { + case kStreamFromStart: + newMarker = inOffset; + break; + + case kStreamFromEnd: + newMarker = this->GetLength () - inOffset; + break; + + case kStreamFromMarker: + newMarker += inOffset; + break; + } + + if (newMarker < 0) // marker must be between 0 and Length, inclusive + { + newMarker = 0; + } + else if (newMarker > GetLength ()) + { + newMarker = this->GetLength (); + } + + mMarker = newMarker; +} + + +// --------------------------------------------------------------------------- +// ¥ GetMarker +// --------------------------------------------------------------------------- +// Return the Read/Write Marker position +// +// Position is a byte offset from the start of the Stream + +int32 +EmStream::GetMarker (void) const +{ + return mMarker; +} + + +// --------------------------------------------------------------------------- +// ¥ SetLength +// --------------------------------------------------------------------------- +// Set the length, in bytes, of the Stream + +void +EmStream::SetLength( + int32 inLength) +{ + int32 oldLength = this->GetLength (); + mLength = inLength; + // If making Stream shorter, call + // SetMarker to make sure that + if (oldLength > inLength) // marker is not past the end + { + this->SetMarker (this->GetMarker (), kStreamFromStart); + } +} + + +// --------------------------------------------------------------------------- +// ¥ GetLength +// --------------------------------------------------------------------------- +// Return the length, in bytes, of the Stream + +int32 +EmStream::GetLength (void) const +{ + return mLength; +} + +#pragma mark --- Low-Level I/O --- + +// --------------------------------------------------------------------------- +// ¥ PutBytes +// --------------------------------------------------------------------------- +// Write bytes from a buffer to a Stream +// +// Returns an error code and passes back the number of bytes actually +// written, which may be less than the number requested if an error occurred. +// +// Subclasses must override this function to support writing. +// +// NOTE: You should not throw an Exception out of this function. + +ErrCode +EmStream::PutBytes ( + const void* inBuffer, + int32 ioByteCount) +{ + UNUSED_PARAM(inBuffer) + UNUSED_PARAM(ioByteCount) + + return 1; +} + + +EmStream& +EmStream::operator << (const char* inString) +{ + WriteCString (inString); + return (*this); +} + +EmStream& +EmStream::operator << (const string& inString) +{ + WriteString (inString); + return (*this); +} + +EmStream& +EmStream::operator << (int8 inNum) +{ + Canonical (inNum); + PutBytes (&inNum, sizeof (inNum)); + return (*this); +} + +EmStream& +EmStream::operator << (uint8 inNum) +{ + Canonical (inNum); + PutBytes (&inNum, sizeof (inNum)); + return (*this); +} + +EmStream& +EmStream::operator << (char inChar) +{ + Canonical (inChar); + PutBytes (&inChar, sizeof (inChar)); + return (*this); +} + +EmStream& +EmStream::operator << (int16 inNum) +{ + Canonical (inNum); + PutBytes (&inNum, sizeof (inNum)); + return (*this); +} + +EmStream& +EmStream::operator << (uint16 inNum) +{ + Canonical (inNum); + PutBytes (&inNum, sizeof (inNum)); + return (*this); +} + +EmStream& +EmStream::operator << (int32 inNum) +{ + Canonical (inNum); + PutBytes (&inNum, sizeof (inNum)); + return (*this); +} + +EmStream& +EmStream::operator << (uint32 inNum) +{ + Canonical (inNum); + PutBytes (&inNum, sizeof (inNum)); + return (*this); +} + +EmStream& +EmStream::operator << (int64 inNum) +{ + Canonical (inNum); + PutBytes (&inNum, sizeof (inNum)); + return (*this); +} + +EmStream& +EmStream::operator << (uint64 inNum) +{ + Canonical (inNum); + PutBytes (&inNum, sizeof (inNum)); + return (*this); +} + +EmStream& +EmStream::operator << (bool inBool) +{ + Canonical (inBool); + PutBytes (&inBool, sizeof (inBool)); + return (*this); +} + + +// --------------------------------------------------------------------------- +// ¥ GetBytes +// --------------------------------------------------------------------------- +// Read bytes from a Stream to a buffer +// +// Returns an error code and passes back the number of bytes actually +// read, which may be less than the number requested if an error occurred. +// +// Subclasses must override this function to support reading. +// +// NOTE: You should not throw an Exception out of this function. + +ErrCode +EmStream::GetBytes ( + void* outBuffer, + int32 ioByteCount) +{ + UNUSED_PARAM(outBuffer) + UNUSED_PARAM(ioByteCount) + + return 1; +} + + +// --------------------------------------------------------------------------- +// ¥ PeekData +// --------------------------------------------------------------------------- +// Read data from a Stream to a buffer, without moving the Marker +// +// Return the number of bytes actually read, which may be less than the +// number requested if an error occurred + +int32 +EmStream::PeekData ( + void* outBuffer, + int32 inByteCount) +{ + int32 currentMarker = this->GetMarker (); + + int32 bytesToPeek = inByteCount; + this->GetBytes (outBuffer, bytesToPeek); + + this->SetMarker (currentMarker, kStreamFromStart); + + return bytesToPeek; +} + +EmStream& +EmStream::operator >> (char* outString) +{ + ReadCString (outString); + return (*this); +} + +EmStream& +EmStream::operator >> (string& outString) +{ + ReadString (outString); + return (*this); +} + +EmStream& +EmStream::operator >> (int8 &outNum) +{ + GetBytes (&outNum, sizeof (outNum)); + Canonical (outNum); + return (*this); +} + +EmStream& +EmStream::operator >> (uint8 &outNum) +{ + GetBytes (&outNum, sizeof (outNum)); + Canonical (outNum); + return (*this); +} + +EmStream& +EmStream::operator >> (char &outChar) +{ + GetBytes (&outChar, sizeof (outChar)); + Canonical (outChar); + return (*this); +} + +EmStream& +EmStream::operator >> (int16 &outNum) +{ + GetBytes (&outNum, sizeof (outNum)); + Canonical (outNum); + return (*this); +} + +EmStream& +EmStream::operator >> (uint16 &outNum) +{ + GetBytes (&outNum, sizeof (outNum)); + Canonical (outNum); + return (*this); +} + +EmStream& +EmStream::operator >> (int32 &outNum) +{ + GetBytes (&outNum, sizeof (outNum)); + Canonical (outNum); + return (*this); +} + +EmStream& +EmStream::operator >> (uint32 &outNum) +{ + GetBytes (&outNum, sizeof (outNum)); + Canonical (outNum); + return (*this); +} + +EmStream& +EmStream::operator >> (int64 &outNum) +{ + GetBytes (&outNum, sizeof (outNum)); + Canonical (outNum); + return (*this); +} + +EmStream& +EmStream::operator >> (uint64 &outNum) +{ + GetBytes (&outNum, sizeof (outNum)); + Canonical (outNum); + return (*this); +} + +EmStream& +EmStream::operator >> (bool &outBool) +{ + GetBytes (&outBool, sizeof (outBool)); + Canonical (outBool); + return (*this); +} + + +#pragma mark --- High-Level I/O --- + +// --------------------------------------------------------------------------- +// ¥ WriteCString +// --------------------------------------------------------------------------- +// Write a C string to a Stream +// +// Returns the number of bytes written. + +int32 +EmStream::WriteCString ( + const char* inString) +{ + EmAssert (inString); + + int32 strLen = strlen (inString); + + // Write C string as a 4-byte count followed by the characters. + // Do not write the null terminator. + + *this << strLen; + this->PutBytes (inString, strLen); + + return (strLen + (int32) sizeof (strLen)); +} + + +// --------------------------------------------------------------------------- +// ¥ ReadCString +// --------------------------------------------------------------------------- +// Read a C string from a Stream +// +// Returns the number of bytes read + +int32 +EmStream::ReadCString ( + char* outString) +{ + EmAssert (outString); + + // C string is stored as a 4-byte count followed by the + // characters. The null terminator is not stored and must + // be added afterwards. + + int32 strLen; + *this >> strLen; + + this->GetBytes (outString, strLen); + outString[strLen] = '\0'; // Null terminator + + return (strLen + (int32) sizeof (int32)); +} + +// --------------------------------------------------------------------------- +// ¥ WriteString +// --------------------------------------------------------------------------- +// Write a C string to a Stream +// +// Returns the number of bytes written. + +int32 +EmStream::WriteString ( + const string& inString) +{ + return this->WriteCString (inString.c_str ()); +} + + +// --------------------------------------------------------------------------- +// ¥ ReadString +// --------------------------------------------------------------------------- +// Read a C string from a Stream +// +// Returns the number of bytes read + +int32 +EmStream::ReadString( + string& outString) +{ + // C string is stored as a 4-byte count followed by the + // characters. The null terminator is not stored and must + // be added afterwards. + + int32 strLen; + *this >> strLen; + + outString.resize (strLen); + if (strLen > 0) + { + GetBytes(&outString[0], strLen); + } + + return (strLen + (int32) sizeof (int32)); +} + + +// =========================================================================== +// EmStreamBlock.cpp ©1993-1998 Metrowerks Inc. All rights reserved. +// =========================================================================== +// +// A Stream whose bytes are in a Chunk + + +// --------------------------------------------------------------------------- +// ¥ EmStreamBlock(Handle) Parameterized Constructor [public] +// --------------------------------------------------------------------------- +// Construct from an existing Chunk + +EmStreamBlock::EmStreamBlock(void* data, int32 length) : + EmStream (), + fData (data) +{ + EmStream::SetLength (length); +} + + +// --------------------------------------------------------------------------- +// ¥ ~EmStreamBlock Destructor [public] +// --------------------------------------------------------------------------- + +EmStreamBlock::~EmStreamBlock() +{ +} + + +// --------------------------------------------------------------------------- +// ¥ SetLength [public] +// --------------------------------------------------------------------------- +// Set the length, in bytes, of the EmStreamBlock + +void +EmStreamBlock::SetLength( + int32 /*inLength*/) +{ + // Do nothing...can't change the length. +} + + +// --------------------------------------------------------------------------- +// ¥ PutBytes +// --------------------------------------------------------------------------- +// Write bytes from a buffer to a EmStreamBlock +// +// Returns an error code and passes back the number of bytes actually +// written, which may be less than the number requested if an error occurred. +// +// Grows data Chunk if necessary. + +ErrCode +EmStreamBlock::PutBytes( + const void* inBuffer, + int32 ioByteCount) +{ + ErrCode err = errNone; + int32 endOfWrite = this->GetMarker () + ioByteCount; + + if (endOfWrite > this->GetLength ()) // Need to grow Chunk + { + this->SetLength (endOfWrite); + } + // Copy bytes into Chunk + if (ioByteCount > 0) + { + memmove ((char*) fData + this->GetMarker (), inBuffer, ioByteCount); + this->SetMarker (ioByteCount, kStreamFromMarker); + } + + return err; +} + + +// --------------------------------------------------------------------------- +// ¥ GetBytes +// --------------------------------------------------------------------------- +// Read bytes from a EmStreamBlock to a buffer +// +// Returns an error code and passes back the number of bytes actually +// read, which may be less than the number requested if an error occurred. +// +// Errors: +// readErr Attempt to read past the end of the EmStreamBlock + +ErrCode +EmStreamBlock::GetBytes( + void* outBuffer, + int32 ioByteCount) +{ + ErrCode err = errNone; + // Upper bound is number of bytes from + // marker to end + if ((this->GetMarker () + ioByteCount) > this->GetLength ()) + { + ioByteCount = this->GetLength () - this->GetMarker (); + err = 1; + } + // Copy bytes from Handle into buffer + + memmove (outBuffer, (char*) fData + this->GetMarker (), ioByteCount); + this->SetMarker (ioByteCount, kStreamFromMarker); + + return err; +} |