CBufferSegment.cpp [plain text]
#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, (uintptr_t)z & 0xffff, TraceEvents, true )
#else
#define XTRACE(x, y, z) ((void) 0)
#endif
#define super CBuffer
OSDefineMetaClassAndStructors(CBufferSegment, CBuffer);
CBufferSegment * CBufferSegment::New(Size len)
{
#pragma unused(len)
CBufferSegment *obj = new CBufferSegment;
XTRACE(kLogNew, 0, obj);
if (obj && !obj->Init(nil, kDefaultCBufferSize)) { obj->release();
obj = nil;
}
return obj;
}
CBufferSegment * CBufferSegment::New(UByte *buffer, Size len)
{
CBufferSegment *obj = new CBufferSegment;
XTRACE(kLogNewWith, 0, obj);
XTRACE(kLogNewWith, 0, buffer);
if (obj && !obj->Init(buffer, len)) {
obj->release();
obj = nil;
}
return obj;
}
void
CBufferSegment::free(void)
{
XTRACE(kLogFree1, 0, this);
XTRACE(kLogFree2, (uintptr_t)fBufBase>>16, fBufBase);
if (fFreeMe && fBufBase) {
check(fSize);
XTRACE(kLogIOFreeBuf, 0, fBufBase);
XTRACE(kLogIOFreeSize, fSize >> 16, fSize);
IOFree(fBufBase, fSize);
fBufBase = nil;
fSize = 0;
}
super::free();
}
Boolean CBufferSegment::Init(UByte *buffer, Size len)
{
XTRACE(kLogCBInit1, 0, len);
fBufBase = nil;
if (!super::init()) return false;
if (buffer == nil) { fBufBase = (UByte*)IOMalloc(len);
XTRACE(kLogIOAllocBuf, 0, fBufBase);
XTRACE(kLogIOAllocSize, len >> 16, len);
require(fBufBase, Fail);
fFreeMe = true;
} else {
fBufBase = buffer;
fFreeMe = false;
}
XTRACE(kLogCBInit2, (uintptr_t)fBufBase>>16, fBufBase);
fSize = len;
fBufEnd = fBufBase + fSize;
fBase = fMark = fBufBase;
fEnd = fBufEnd;
return true;
Fail:
return false;
}
int CBufferSegment::Peek()
{
return (fMark >= fEnd) ? EOF : *fMark;
}
int CBufferSegment::Next()
{
return (fMark >= fEnd) ? EOF : *(++fMark);
}
uintptr_t CBufferSegment::Skip()
{
return (fMark >= fEnd) ? EOF : (uintptr_t)fMark++;
}
int CBufferSegment::Get()
{
return (fMark >= fEnd) ? EOF : *fMark++;
}
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;
}
int CBufferSegment::CopyOut(UByte* p, Size& n)
{
int result = 0;
if (n > 0)
{
n -= Getn(p, n);
if (fMark == fEnd)
result = EOF;
}
return result;
}
int CBufferSegment::Put(int b)
{
return (fMark >= fEnd) ? EOF : (*fMark++ = b);
}
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;
}
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;
}
void CBufferSegment::Reset()
{
fBase = fMark = fBufBase;
fEnd = fBufEnd;
}
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;
}
Size CBufferSegment::Seek(Long off, int dir)
{
UByte* newPos;
if (off == 0)
{
if (dir == kPosBeg)
fMark = fBase;
else if (dir == kPosEnd)
fMark = fEnd;
else if (dir == kPosCur)
;
}
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((uintptr_t) fBase, (uintptr_t) newPos, (uintptr_t) fEnd);
}
return (Size) (fMark - fBase);
}
Size CBufferSegment::Position() const
{
return (Size) (fMark ? (fMark - fBase) : 0);
}
Size CBufferSegment::GetSize() const
{
return (Size) (fEnd - fBase);
}
Boolean CBufferSegment::AtEOF() const
{
return (fMark == fEnd);
}