tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

InBuffer.cpp (3029B)


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