Source code

Revision control

Copy as Markdown

Other Tools

// InBuffer.cpp↩
#include "StdAfx.h"
#include "../../../C/Alloc.h"
#include "InBuffer.h"
CInBufferBase::CInBufferBase() throw():↩
_buf(0),↩
_bufLim(0),↩
_bufBase(0),↩
_stream(0),↩
_processedSize(0),↩
_bufSize(0),↩
_wasFinished(false),↩
NumExtraBytes(0)↩
{}↩
bool CInBuffer::Create(size_t bufSize) throw()↩
{↩
const unsigned kMinBlockSize = 1;↩
if (bufSize < kMinBlockSize)↩
bufSize = kMinBlockSize;↩
if (_bufBase != 0 && _bufSize == bufSize)↩
return true;↩
Free();↩
_bufSize = bufSize;↩
_bufBase = (Byte *)::MidAlloc(bufSize);↩
return (_bufBase != 0);↩
}↩
void CInBuffer::Free() throw()↩
{↩
::MidFree(_bufBase);↩
_bufBase = 0;↩
}↩
void CInBufferBase::Init() throw()↩
{↩
_processedSize = 0;↩
_buf = _bufBase;↩
_bufLim = _buf;↩
_wasFinished = false;↩
#ifdef _NO_EXCEPTIONS↩
ErrorCode = S_OK;↩
#endif
NumExtraBytes = 0;↩
}↩
bool CInBufferBase::ReadBlock()↩
{↩
#ifdef _NO_EXCEPTIONS↩
if (ErrorCode != S_OK)↩
return false;↩
#endif
if (_wasFinished)↩
return false;↩
_processedSize += (_buf - _bufBase);↩
_buf = _bufBase;↩
_bufLim = _bufBase;↩
UInt32 processed;↩
// FIX_ME: we can improve it to support (_bufSize >= (1 << 32))↩
HRESULT result = _stream->Read(_bufBase, (UInt32)_bufSize, &processed);↩
#ifdef _NO_EXCEPTIONS↩
ErrorCode = result;↩
#else
if (result != S_OK)↩
throw CInBufferException(result);↩
#endif
_bufLim = _buf + processed;↩
_wasFinished = (processed == 0);↩
return !_wasFinished;↩
}↩
bool CInBufferBase::ReadByte_FromNewBlock(Byte &b)↩
{↩
if (!ReadBlock())↩
{↩
NumExtraBytes++;↩
b = 0xFF;↩
return false;↩
}↩
b = *_buf++;↩
return true;↩
}↩
Byte CInBufferBase::ReadByte_FromNewBlock()↩
{↩
if (!ReadBlock())↩
{↩
NumExtraBytes++;↩
return 0xFF;↩
}↩
return *_buf++;↩
}↩
size_t CInBufferBase::ReadBytes(Byte *buf, size_t size)↩
{↩
size_t num = 0;↩
for (;;)↩
{↩
const size_t rem = _bufLim - _buf;↩
if (size <= rem)↩
{↩
if (size != 0)↩
{↩
memcpy(buf, _buf, size);↩
_buf += size;↩
num += size;↩
}↩
return num;↩
}↩
if (rem != 0)↩
{↩
memcpy(buf, _buf, rem);↩
_buf += rem;↩
buf += rem;↩
num += rem;↩
size -= rem;↩
}↩
if (!ReadBlock())↩
return num;↩
}↩
/*↩
if ((size_t)(_bufLim - _buf) >= size)↩
{↩
const Byte *src = _buf;↩
for (size_t i = 0; i < size; i++)↩
buf[i] = src[i];↩
_buf += size;↩
return size;↩
}↩
for (size_t i = 0; i < size; i++)↩
{↩
if (_buf >= _bufLim)↩
if (!ReadBlock())↩
return i;↩
buf[i] = *_buf++;↩
}↩
return size;↩
*/
}↩
size_t CInBufferBase::Skip(size_t size)↩
{↩
size_t processed = 0;↩
for (;;)↩
{↩
size_t rem = (_bufLim - _buf);↩
if (rem >= size)↩
{↩
_buf += size;↩
return processed + size;↩
}↩
_buf += rem;↩
processed += rem;↩
size -= rem;↩
if (!ReadBlock())↩
return processed;↩
}↩
}↩