/* File: CBufferSegment.c Contains: Implementation of the CBufferSegment class */ #include "CBufferSegment.h" #include "IrDALog.h" #if (hasTracing > 0 && hasCBufferSegTracing > 0) enum { kLogNew = 1, kLogNewWith, kLogDelete, kLogFree1, kLogFree2, kLogCBInit1, kLogCBInit2, kLogIOAllocBuf, kLogIOAllocSize, kLogIOFreeBuf, kLogIOFreeSize }; static EventTraceCauseDesc TraceEvents[] = { {kLogNew, "CBufferSegment: New, obj="}, {kLogNewWith, "CBufferSegment: New hdr, obj=, buffer="}, {kLogDelete, "CBufferSegment: Delete"}, {kLogFree1, "CBufferSegment: Free, obj="}, {kLogFree2, "CBufferSegment: Free, buffer="}, {kLogCBInit1, "CBufferSegment: Init, length="}, {kLogCBInit2, "CBufferSegment: Init, buffer="}, {kLogIOAllocBuf, "CBufferSegment: ioalloc, buffer="}, {kLogIOAllocSize, "CBufferSegment: ioalloc, size="}, {kLogIOFreeBuf, "CBufferSegment: iofree, buffer="}, {kLogIOFreeSize, "CBufferSegment: iofree, size="} }; #define XTRACE(x, y, z) IrDALogAdd( x, y, z, TraceEvents, true ) #else #define XTRACE(x, y, z) ((void) 0) #endif #define super CBuffer OSDefineMetaClassAndStructors(CBufferSegment, CBuffer); //-------------------------------------------------------------------------------- // CBufferSegment::New // This is the preferred method (and easiest) of getting a statically // allocated CbufferSegment and its associated buffer. Initializes // the object also. // //-------------------------------------------------------------------------------- CBufferSegment * CBufferSegment::New(Size len) { #pragma unused(len) int Fix_Unused_Length; CBufferSegment *obj = new CBufferSegment; XTRACE(kLogNew, (int)obj >> 16, (short)obj); if (obj && !obj->Init(nil, kDefaultCBufferSize)) { // alloc a big buffer obj->release(); obj = nil; } return obj; } CBufferSegment * CBufferSegment::New(UByte *buffer, Size len) { CBufferSegment *obj = new CBufferSegment; XTRACE(kLogNewWith, (int)obj >> 16, (short)obj); XTRACE(kLogNewWith, (int)buffer >> 16, (short)buffer); if (obj && !obj->Init(buffer, len)) { obj->release(); obj = nil; } return obj; } //-------------------------------------------------------------------------------- // CBufferSegment::Delete // Old naming style, just calls release //-------------------------------------------------------------------------------- /*void CBufferSegment::Delete() { XTRACE( kLogDelete, (int)this >> 16, (int)this); this->release(); }*/ //-------------------------------------------------------------------------------- // CBufferSegment::free //-------------------------------------------------------------------------------- void CBufferSegment::free(void) { XTRACE(kLogFree1, (int)this >> 16, (short)this); XTRACE(kLogFree2, (int)fBufBase>>16, (short)fBufBase); if (fFreeMe && fBufBase) { check(fSize); XTRACE(kLogIOFreeBuf, (int)fBufBase >> 16, (short)fBufBase); XTRACE(kLogIOFreeSize, fSize >> 16, (short)fSize); IOFree(fBufBase, fSize); fBufBase = nil; fSize = 0; } super::free(); } //-------------------------------------------------------------------------------- // CBufferSegment::init //-------------------------------------------------------------------------------- Boolean CBufferSegment::Init(UByte *buffer, Size len) { XTRACE(kLogCBInit1, 0, len); fBufBase = nil; if (!super::init()) return false; if (buffer == nil) { // callers wants us to alloc and free fBufBase = (UByte*)IOMalloc(len); XTRACE(kLogIOAllocBuf, (int)fBufBase >> 16, (short)fBufBase); XTRACE(kLogIOAllocSize, len >> 16, (short)len); require(fBufBase, Fail); fFreeMe = true; } else { fBufBase = buffer; fFreeMe = false; } XTRACE(kLogCBInit2, (int)fBufBase>>16, (short)fBufBase); fSize = len; fBufEnd = fBufBase + fSize; // the whole buffer is available fBase = fMark = fBufBase; fEnd = fBufEnd; return true; Fail: return false; } // CBufferSegment::init //-------------------------------------------------------------------------------- // CBufferSegment::Peek //-------------------------------------------------------------------------------- int CBufferSegment::Peek() { return (fMark >= fEnd) ? EOF : *fMark; } // CBufferSegment::Peek //-------------------------------------------------------------------------------- // CBufferSegment::Next //-------------------------------------------------------------------------------- int CBufferSegment::Next() { return (fMark >= fEnd) ? EOF : *(++fMark); } // CBufferSegment::Next //-------------------------------------------------------------------------------- // CBufferSegment::Skip //-------------------------------------------------------------------------------- int CBufferSegment::Skip() { return (fMark >= fEnd) ? EOF : (int) fMark++; } // CBufferSegment::Skip //-------------------------------------------------------------------------------- // CBufferSegment::Get //-------------------------------------------------------------------------------- int CBufferSegment::Get() { return (fMark >= fEnd) ? EOF : *fMark++; } // CBufferSegment::Get //-------------------------------------------------------------------------------- // CBufferSegment::Getn //-------------------------------------------------------------------------------- Size CBufferSegment::Getn(UByte* p, Size n) { if (n > 0) { n = Min(n, fEnd - fMark); if (n > 0) { BlockMove(fMark, p, n); fMark += n; } } return n; } // CBufferSegment::Getn //-------------------------------------------------------------------------------- // CBufferSegment::CopyOut //-------------------------------------------------------------------------------- int CBufferSegment::CopyOut(UByte* p, Size& n) { int result = 0; if (n > 0) { n -= Getn(p, n); if (fMark == fEnd) result = EOF; } return result; } // CBufferSegment::CopyOut //-------------------------------------------------------------------------------- // CBufferSegment::Put //-------------------------------------------------------------------------------- int CBufferSegment::Put(int b) { return (fMark >= fEnd) ? EOF : (*fMark++ = b); } // CBufferSegment::Put //-------------------------------------------------------------------------------- // CBufferSegment::Putn //-------------------------------------------------------------------------------- Size CBufferSegment::Putn(const UByte* p, Size n) { if (n > 0) { n = Min(n, fEnd - fMark); if (n > 0) { BlockMove(p, fMark, n); fMark += n; } } return n; } // CBufferSegment::Putn //-------------------------------------------------------------------------------- // CBufferSegment::CopyIn //-------------------------------------------------------------------------------- int CBufferSegment::CopyIn(const UByte* p, Size& n) { int result = 0; if (n > 0) { n -= Putn(p, n); if (fMark == fEnd) return EOF; } return result; } // CBufferSegment::CopyIn //-------------------------------------------------------------------------------- // CBufferSegment::Reset //-------------------------------------------------------------------------------- void CBufferSegment::Reset() { fBase = fMark = fBufBase; fEnd = fBufEnd; } // CBufferSegment::Reset //-------------------------------------------------------------------------------- // CBufferSegment::Hide //-------------------------------------------------------------------------------- Size CBufferSegment::Hide(Long count, int dir) { if (count == 0) return 0; switch (dir) { case kPosBeg: fBase += count; if (fBase < fBufBase) { count += (Long) (fBufBase - fBase); fBase = fBufBase; } else if (fBase > fBufEnd) { count -= (Long) (fBase - fBufEnd); fBase = fBufEnd; } fMark = fBase; break; case kPosEnd: fEnd -= count; if (fEnd < fBufBase) { count -= (Long) (fBufBase - fEnd); fEnd = fBufBase; } else if (fEnd > fBufEnd) { count += (Long) (fEnd - fBufEnd); fEnd = fBufEnd; } fMark = fEnd; break; default: count = 0; break; } return count; } // CBufferSegment::Hide //-------------------------------------------------------------------------------- // CBufferSegment::Seek //-------------------------------------------------------------------------------- Size CBufferSegment::Seek(Long off, int dir) { UByte* newPos; // quick check for simple cases if (off == 0) { if (dir == kPosBeg) fMark = fBase; else if (dir == kPosEnd) fMark = fEnd; else if (dir == kPosCur) /* no change */; } else { switch (dir) { case kPosBeg: newPos = fBase + off; break; case kPosCur: newPos = fMark + off; break; case kPosEnd: newPos = fEnd - off; break; default: newPos = fMark; break; } fMark = (UByte*) UMinMax((ULong) fBase, (ULong) newPos, (ULong) fEnd); } return (Size) (fMark - fBase); } // CBufferSegment::Seek //-------------------------------------------------------------------------------- // CBufferSegment::Position //-------------------------------------------------------------------------------- Size CBufferSegment::Position() const { return (Size) (fMark ? (fMark - fBase) : 0); } // CBufferSegment::Position //-------------------------------------------------------------------------------- // CBufferSegment::GetSize //-------------------------------------------------------------------------------- Size CBufferSegment::GetSize() const { return (Size) (fEnd - fBase); } // CBufferSegment::GetSize //-------------------------------------------------------------------------------- // CBufferSegment::AtEOF //-------------------------------------------------------------------------------- Boolean CBufferSegment::AtEOF() const { return (fMark == fEnd); } // CBufferSegment::AtEOF