1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// InBuffer.cpp 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h" 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../C/Alloc.h" 6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "InBuffer.h" 8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 9cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyCInBufferBase::CInBufferBase() throw(): 10cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _buf(0), 11cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _bufLim(0), 12cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _bufBase(0), 13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _stream(0), 14cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _processedSize(0), 15cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _bufSize(0), 16cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _wasFinished(false), 17cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky NumExtraBytes(0) 18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{} 19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 20cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckybool CInBuffer::Create(size_t bufSize) throw() 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 22cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const unsigned kMinBlockSize = 1; 23cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (bufSize < kMinBlockSize) 24cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky bufSize = kMinBlockSize; 25cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (_bufBase != 0 && _bufSize == bufSize) 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return true; 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Free(); 28cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _bufSize = bufSize; 29cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _bufBase = (Byte *)::MidAlloc(bufSize); 30cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return (_bufBase != 0); 31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 33cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInBuffer::Free() throw() 34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 35cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ::MidFree(_bufBase); 36cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _bufBase = 0; 37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 39cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInBufferBase::Init() throw() 40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _processedSize = 0; 42cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _buf = _bufBase; 43cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _bufLim = _buf; 44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _wasFinished = false; 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _NO_EXCEPTIONS 46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ErrorCode = S_OK; 47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 48cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky NumExtraBytes = 0; 49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 51cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckybool CInBufferBase::ReadBlock() 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _NO_EXCEPTIONS 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (ErrorCode != S_OK) 55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_wasFinished) 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 59cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _processedSize += (_buf - _bufBase); 60cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _buf = _bufBase; 61cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _bufLim = _bufBase; 62cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 processed; 63cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // FIX_ME: we can improve it to support (_bufSize >= (1 << 32)) 64cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky HRESULT result = _stream->Read(_bufBase, (UInt32)_bufSize, &processed); 65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef _NO_EXCEPTIONS 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ErrorCode = result; 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #else 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (result != S_OK) 69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync throw CInBufferException(result); 70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 71cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _bufLim = _buf + processed; 72cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _wasFinished = (processed == 0); 73cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return !_wasFinished; 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 76cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckybool CInBufferBase::ReadByte_FromNewBlock(Byte &b) 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (!ReadBlock()) 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 80cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky NumExtraBytes++; 81cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky b = 0xFF; 82cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return false; 83cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 84cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky b = *_buf++; 85cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return true; 86cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 87cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 88cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyByte CInBufferBase::ReadByte_FromNewBlock() 89cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 90cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (!ReadBlock()) 91cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 92cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky NumExtraBytes++; 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return 0xFF; 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 95cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return *_buf++; 96cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 97cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 98cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckysize_t CInBufferBase::ReadBytes(Byte *buf, size_t size) 99cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 100cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if ((size_t)(_bufLim - _buf) >= size) 101cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 102cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const Byte *src = _buf; 103cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (size_t i = 0; i < size; i++) 104cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky buf[i] = src[i]; 105cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _buf += size; 106cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return size; 107cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 108cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (size_t i = 0; i < size; i++) 109cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 110cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (_buf >= _bufLim) 111cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (!ReadBlock()) 112cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return i; 113cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky buf[i] = *_buf++; 114cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 115cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return size; 116cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 117cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 118cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckysize_t CInBufferBase::Skip(size_t size) 119cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 120cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t processed = 0; 121cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (;;) 122cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 123cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t rem = (_bufLim - _buf); 124cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (rem >= size) 125cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 126cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _buf += size; 127cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return processed + size; 128cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 129cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _buf += rem; 130cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky processed += rem; 131cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size -= rem; 132cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (!ReadBlock()) 133cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return processed; 134cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 136