Home | History | Annotate | Download | only in Common
      1 // OutBuffer.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "../../../C/Alloc.h"
      6 
      7 #include "OutBuffer.h"
      8 
      9 bool COutBuffer::Create(UInt32 bufferSize)
     10 {
     11   const UInt32 kMinBlockSize = 1;
     12   if (bufferSize < kMinBlockSize)
     13     bufferSize = kMinBlockSize;
     14   if (_buffer != 0 && _bufferSize == bufferSize)
     15     return true;
     16   Free();
     17   _bufferSize = bufferSize;
     18   _buffer = (Byte *)::MidAlloc(bufferSize);
     19   return (_buffer != 0);
     20 }
     21 
     22 void COutBuffer::Free()
     23 {
     24   ::MidFree(_buffer);
     25   _buffer = 0;
     26 }
     27 
     28 void COutBuffer::SetStream(ISequentialOutStream *stream)
     29 {
     30   _stream = stream;
     31 }
     32 
     33 void COutBuffer::Init()
     34 {
     35   _streamPos = 0;
     36   _limitPos = _bufferSize;
     37   _pos = 0;
     38   _processedSize = 0;
     39   _overDict = false;
     40   #ifdef _NO_EXCEPTIONS
     41   ErrorCode = S_OK;
     42   #endif
     43 }
     44 
     45 UInt64 COutBuffer::GetProcessedSize() const
     46 {
     47   UInt64 res = _processedSize + _pos - _streamPos;
     48   if (_streamPos > _pos)
     49     res += _bufferSize;
     50   return res;
     51 }
     52 
     53 
     54 HRESULT COutBuffer::FlushPart()
     55 {
     56   // _streamPos < _bufferSize
     57   UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);
     58   HRESULT result = S_OK;
     59   #ifdef _NO_EXCEPTIONS
     60   result = ErrorCode;
     61   #endif
     62   if (_buffer2 != 0)
     63   {
     64     memmove(_buffer2, _buffer + _streamPos, size);
     65     _buffer2 += size;
     66   }
     67 
     68   if (_stream != 0
     69       #ifdef _NO_EXCEPTIONS
     70       && (ErrorCode == S_OK)
     71       #endif
     72      )
     73   {
     74     UInt32 processedSize = 0;
     75     result = _stream->Write(_buffer + _streamPos, size, &processedSize);
     76     size = processedSize;
     77   }
     78   _streamPos += size;
     79   if (_streamPos == _bufferSize)
     80     _streamPos = 0;
     81   if (_pos == _bufferSize)
     82   {
     83     _overDict = true;
     84     _pos = 0;
     85   }
     86   _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;
     87   _processedSize += size;
     88   return result;
     89 }
     90 
     91 HRESULT COutBuffer::Flush()
     92 {
     93   #ifdef _NO_EXCEPTIONS
     94   if (ErrorCode != S_OK)
     95     return ErrorCode;
     96   #endif
     97 
     98   while(_streamPos != _pos)
     99   {
    100     HRESULT result = FlushPart();
    101     if (result != S_OK)
    102       return result;
    103   }
    104   return S_OK;
    105 }
    106 
    107 void COutBuffer::FlushWithCheck()
    108 {
    109   HRESULT result = Flush();
    110   #ifdef _NO_EXCEPTIONS
    111   ErrorCode = result;
    112   #else
    113   if (result != S_OK)
    114     throw COutBufferException(result);
    115   #endif
    116 }
    117