1// InBuffer.h
2
3#ifndef __INBUFFER_H
4#define __INBUFFER_H
5
6#include "../IStream.h"
7#include "../../Common/MyCom.h"
8#include "../../Common/MyException.h"
9
10#ifndef _NO_EXCEPTIONS
11struct CInBufferException: public CSystemException
12{
13  CInBufferException(HRESULT errorCode): CSystemException(errorCode) {}
14};
15#endif
16
17class CInBuffer
18{
19  Byte *_buffer;
20  Byte *_bufferLimit;
21  Byte *_bufferBase;
22  CMyComPtr<ISequentialInStream> _stream;
23  UInt64 _processedSize;
24  UInt32 _bufferSize;
25  bool _wasFinished;
26
27  bool ReadBlock();
28  Byte ReadBlock2();
29
30public:
31  #ifdef _NO_EXCEPTIONS
32  HRESULT ErrorCode;
33  #endif
34
35  CInBuffer();
36  ~CInBuffer() { Free(); }
37
38  bool Create(UInt32 bufferSize);
39  void Free();
40
41  void SetStream(ISequentialInStream *stream);
42  void Init();
43  void ReleaseStream() { _stream.Release(); }
44
45  bool ReadByte(Byte &b)
46  {
47    if (_buffer >= _bufferLimit)
48      if (!ReadBlock())
49        return false;
50    b = *_buffer++;
51    return true;
52  }
53  Byte ReadByte()
54  {
55    if (_buffer >= _bufferLimit)
56      return ReadBlock2();
57    return *_buffer++;
58  }
59  UInt32 ReadBytes(Byte *buf, UInt32 size)
60  {
61    if ((UInt32)(_bufferLimit - _buffer) >= size)
62    {
63      for (UInt32 i = 0; i < size; i++)
64        buf[i] = _buffer[i];
65      _buffer += size;
66      return size;
67    }
68    for (UInt32 i = 0; i < size; i++)
69    {
70      if (_buffer >= _bufferLimit)
71        if (!ReadBlock())
72          return i;
73      buf[i] = *_buffer++;
74    }
75    return size;
76  }
77  UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
78  bool WasFinished() const { return _wasFinished; }
79};
80
81#endif
82