1 // InBuffer.h
2 
3 #ifndef ZIP7_INC_IN_BUFFER_H
4 #define ZIP7_INC_IN_BUFFER_H
5 
6 #include "../../Common/MyException.h"
7 #include "../IStream.h"
8 
9 #ifndef Z7_NO_EXCEPTIONS
10 struct CInBufferException: public CSystemException
11 {
CInBufferExceptionCInBufferException12   CInBufferException(HRESULT errorCode): CSystemException(errorCode) {}
13 };
14 #endif
15 
16 class CInBufferBase
17 {
18 protected:
19   Byte *_buf;
20   Byte *_bufLim;
21   Byte *_bufBase;
22 
23   ISequentialInStream *_stream;
24   UInt64 _processedSize;
25   size_t _bufSize; // actually it's number of Bytes for next read. The buf can be larger
26                    // only up to 32-bits values now are supported!
27   bool _wasFinished;
28 
29   bool ReadBlock();
30   bool ReadByte_FromNewBlock(Byte &b);
31   Byte ReadByte_FromNewBlock();
32 
33 public:
34   #ifdef Z7_NO_EXCEPTIONS
35   HRESULT ErrorCode;
36   #endif
37   UInt32 NumExtraBytes;
38 
39   CInBufferBase() throw();
40 
41   // the size of portion of data in real stream that was already read from this object
42   // it doesn't include unused data in buffer
43   // it doesn't include virtual Extra bytes after the end of real stream data
GetStreamSize() const44   UInt64 GetStreamSize() const { return _processedSize + (size_t)(_buf - _bufBase); }
45 
46   // the size of virtual data that was read from this object
47   // it doesn't include unused data in buffers
48   // it includes any virtual Extra bytes after the end of real data
GetProcessedSize() const49   UInt64 GetProcessedSize() const { return _processedSize + NumExtraBytes + (size_t)(_buf - _bufBase); }
50 
WasFinished() const51   bool WasFinished() const { return _wasFinished; }
52 
SetStream(ISequentialInStream *stream)53   void SetStream(ISequentialInStream *stream) { _stream = stream; }
54 
SetBuf(Byte *buf, size_t bufSize, size_t end, size_t pos)55   void SetBuf(Byte *buf, size_t bufSize, size_t end, size_t pos)
56   {
57     _bufBase = buf;
58     _bufSize = bufSize;
59     _processedSize = 0;
60     _buf = buf + pos;
61     _bufLim = buf + end;
62     _wasFinished = false;
63     #ifdef Z7_NO_EXCEPTIONS
64     ErrorCode = S_OK;
65     #endif
66     NumExtraBytes = 0;
67   }
68 
69   void Init() throw();
70 
71   Z7_FORCE_INLINE
ReadByte(Byte &b)72   bool ReadByte(Byte &b)
73   {
74     if (_buf >= _bufLim)
75       return ReadByte_FromNewBlock(b);
76     b = *_buf++;
77     return true;
78   }
79 
80   Z7_FORCE_INLINE
ReadByte_FromBuf(Byte &b)81   bool ReadByte_FromBuf(Byte &b)
82   {
83     if (_buf >= _bufLim)
84       return false;
85     b = *_buf++;
86     return true;
87   }
88 
89   Z7_FORCE_INLINE
ReadByte()90   Byte ReadByte()
91   {
92     if (_buf >= _bufLim)
93       return ReadByte_FromNewBlock();
94     return *_buf++;
95   }
96 
97   size_t ReadBytes(Byte *buf, size_t size);
98   size_t Skip(size_t size);
99 };
100 
101 class CInBuffer: public CInBufferBase
102 {
103 public:
~CInBuffer()104   ~CInBuffer() { Free(); }
105   bool Create(size_t bufSize) throw(); // only up to 32-bits values now are supported!
106   void Free() throw();
107 };
108 
109 #endif
110