1370b324cSopenharmony_ci// InBuffer.h
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#ifndef ZIP7_INC_IN_BUFFER_H
4370b324cSopenharmony_ci#define ZIP7_INC_IN_BUFFER_H
5370b324cSopenharmony_ci
6370b324cSopenharmony_ci#include "../../Common/MyException.h"
7370b324cSopenharmony_ci#include "../IStream.h"
8370b324cSopenharmony_ci
9370b324cSopenharmony_ci#ifndef Z7_NO_EXCEPTIONS
10370b324cSopenharmony_cistruct CInBufferException: public CSystemException
11370b324cSopenharmony_ci{
12370b324cSopenharmony_ci  CInBufferException(HRESULT errorCode): CSystemException(errorCode) {}
13370b324cSopenharmony_ci};
14370b324cSopenharmony_ci#endif
15370b324cSopenharmony_ci
16370b324cSopenharmony_ciclass CInBufferBase
17370b324cSopenharmony_ci{
18370b324cSopenharmony_ciprotected:
19370b324cSopenharmony_ci  Byte *_buf;
20370b324cSopenharmony_ci  Byte *_bufLim;
21370b324cSopenharmony_ci  Byte *_bufBase;
22370b324cSopenharmony_ci
23370b324cSopenharmony_ci  ISequentialInStream *_stream;
24370b324cSopenharmony_ci  UInt64 _processedSize;
25370b324cSopenharmony_ci  size_t _bufSize; // actually it's number of Bytes for next read. The buf can be larger
26370b324cSopenharmony_ci                   // only up to 32-bits values now are supported!
27370b324cSopenharmony_ci  bool _wasFinished;
28370b324cSopenharmony_ci
29370b324cSopenharmony_ci  bool ReadBlock();
30370b324cSopenharmony_ci  bool ReadByte_FromNewBlock(Byte &b);
31370b324cSopenharmony_ci  Byte ReadByte_FromNewBlock();
32370b324cSopenharmony_ci
33370b324cSopenharmony_cipublic:
34370b324cSopenharmony_ci  #ifdef Z7_NO_EXCEPTIONS
35370b324cSopenharmony_ci  HRESULT ErrorCode;
36370b324cSopenharmony_ci  #endif
37370b324cSopenharmony_ci  UInt32 NumExtraBytes;
38370b324cSopenharmony_ci
39370b324cSopenharmony_ci  CInBufferBase() throw();
40370b324cSopenharmony_ci
41370b324cSopenharmony_ci  // the size of portion of data in real stream that was already read from this object
42370b324cSopenharmony_ci  // it doesn't include unused data in buffer
43370b324cSopenharmony_ci  // it doesn't include virtual Extra bytes after the end of real stream data
44370b324cSopenharmony_ci  UInt64 GetStreamSize() const { return _processedSize + (size_t)(_buf - _bufBase); }
45370b324cSopenharmony_ci
46370b324cSopenharmony_ci  // the size of virtual data that was read from this object
47370b324cSopenharmony_ci  // it doesn't include unused data in buffers
48370b324cSopenharmony_ci  // it includes any virtual Extra bytes after the end of real data
49370b324cSopenharmony_ci  UInt64 GetProcessedSize() const { return _processedSize + NumExtraBytes + (size_t)(_buf - _bufBase); }
50370b324cSopenharmony_ci
51370b324cSopenharmony_ci  bool WasFinished() const { return _wasFinished; }
52370b324cSopenharmony_ci
53370b324cSopenharmony_ci  void SetStream(ISequentialInStream *stream) { _stream = stream; }
54370b324cSopenharmony_ci
55370b324cSopenharmony_ci  void SetBuf(Byte *buf, size_t bufSize, size_t end, size_t pos)
56370b324cSopenharmony_ci  {
57370b324cSopenharmony_ci    _bufBase = buf;
58370b324cSopenharmony_ci    _bufSize = bufSize;
59370b324cSopenharmony_ci    _processedSize = 0;
60370b324cSopenharmony_ci    _buf = buf + pos;
61370b324cSopenharmony_ci    _bufLim = buf + end;
62370b324cSopenharmony_ci    _wasFinished = false;
63370b324cSopenharmony_ci    #ifdef Z7_NO_EXCEPTIONS
64370b324cSopenharmony_ci    ErrorCode = S_OK;
65370b324cSopenharmony_ci    #endif
66370b324cSopenharmony_ci    NumExtraBytes = 0;
67370b324cSopenharmony_ci  }
68370b324cSopenharmony_ci
69370b324cSopenharmony_ci  void Init() throw();
70370b324cSopenharmony_ci
71370b324cSopenharmony_ci  Z7_FORCE_INLINE
72370b324cSopenharmony_ci  bool ReadByte(Byte &b)
73370b324cSopenharmony_ci  {
74370b324cSopenharmony_ci    if (_buf >= _bufLim)
75370b324cSopenharmony_ci      return ReadByte_FromNewBlock(b);
76370b324cSopenharmony_ci    b = *_buf++;
77370b324cSopenharmony_ci    return true;
78370b324cSopenharmony_ci  }
79370b324cSopenharmony_ci
80370b324cSopenharmony_ci  Z7_FORCE_INLINE
81370b324cSopenharmony_ci  bool ReadByte_FromBuf(Byte &b)
82370b324cSopenharmony_ci  {
83370b324cSopenharmony_ci    if (_buf >= _bufLim)
84370b324cSopenharmony_ci      return false;
85370b324cSopenharmony_ci    b = *_buf++;
86370b324cSopenharmony_ci    return true;
87370b324cSopenharmony_ci  }
88370b324cSopenharmony_ci
89370b324cSopenharmony_ci  Z7_FORCE_INLINE
90370b324cSopenharmony_ci  Byte ReadByte()
91370b324cSopenharmony_ci  {
92370b324cSopenharmony_ci    if (_buf >= _bufLim)
93370b324cSopenharmony_ci      return ReadByte_FromNewBlock();
94370b324cSopenharmony_ci    return *_buf++;
95370b324cSopenharmony_ci  }
96370b324cSopenharmony_ci
97370b324cSopenharmony_ci  size_t ReadBytes(Byte *buf, size_t size);
98370b324cSopenharmony_ci  size_t Skip(size_t size);
99370b324cSopenharmony_ci};
100370b324cSopenharmony_ci
101370b324cSopenharmony_ciclass CInBuffer: public CInBufferBase
102370b324cSopenharmony_ci{
103370b324cSopenharmony_cipublic:
104370b324cSopenharmony_ci  ~CInBuffer() { Free(); }
105370b324cSopenharmony_ci  bool Create(size_t bufSize) throw(); // only up to 32-bits values now are supported!
106370b324cSopenharmony_ci  void Free() throw();
107370b324cSopenharmony_ci};
108370b324cSopenharmony_ci
109370b324cSopenharmony_ci#endif
110