1 // LZInWindow.h
2 
3 #ifndef __LZ_IN_WINDOW_H
4 #define __LZ_IN_WINDOW_H
5 
6 #include "../../IStream.h"
7 
8 class CLZInWindow
9 {
10   Byte *_bufferBase; // pointer to buffer with data
11   ISequentialInStream *_stream;
12   UInt32 _posLimit;  // offset (from _buffer) of first byte when new block reading must be done
13   bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
14   const Byte *_pointerToLastSafePosition;
15 protected:
16   Byte  *_buffer;   // Pointer to virtual Buffer begin
17   UInt32 _blockSize;  // Size of Allocated memory block
18   UInt32 _pos;             // offset (from _buffer) of curent byte
19   UInt32 _keepSizeBefore;  // how many BYTEs must be kept in buffer before _pos
20   UInt32 _keepSizeAfter;   // how many BYTEs must be kept buffer after _pos
21   UInt32 _keepSizeReserv;  // how many BYTEs must be kept as reserv
22   UInt32 _streamPos;   // offset (from _buffer) of first not read byte from Stream
23 
BeforeMoveBlock()24   virtual void BeforeMoveBlock() {};
AfterMoveBlock()25   virtual void AfterMoveBlock() {};
26   void MoveBlock();
27   virtual HRESULT ReadBlock();
28   void Free();
29 public:
CLZInWindow()30   CLZInWindow(): _bufferBase(0) {}
~CLZInWindow()31   virtual ~CLZInWindow() { Free(); }
32 
33   bool Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter,
34       UInt32 keepSizeReserv = (1<<17));
35 
36   HRESULT Init(ISequentialInStream *stream);
37   // void ReleaseStream();
38 
GetBuffer()39   Byte *GetBuffer() const { return _buffer; }
40 
GetPointerToCurrentPos()41   const Byte *GetPointerToCurrentPos() const { return _buffer + _pos; }
42 
MovePos()43   HRESULT MovePos()
44   {
45     _pos++;
46     if (_pos > _posLimit)
47     {
48       const Byte *pointerToPostion = _buffer + _pos;
49       if(pointerToPostion > _pointerToLastSafePosition)
50         MoveBlock();
51       return ReadBlock();
52     }
53     else
54       return S_OK;
55   }
GetIndexByte(Int32 index)56   Byte GetIndexByte(Int32 index)const
57     {  return _buffer[(size_t)_pos + index]; }
58 
59   // index + limit have not to exceed _keepSizeAfter;
GetMatchLen(Int32 index,UInt32 distance,UInt32 limit)60   UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) const
61   {
62     if(_streamEndWasReached)
63       if ((_pos + index) + limit > _streamPos)
64         limit = _streamPos - (_pos + index);
65     distance++;
66     Byte *pby = _buffer + (size_t)_pos + index;
67     UInt32 i;
68     for(i = 0; i < limit && pby[i] == pby[(size_t)i - distance]; i++);
69     return i;
70   }
71 
GetNumAvailableBytes()72   UInt32 GetNumAvailableBytes() const { return _streamPos - _pos; }
73 
ReduceOffsets(Int32 subValue)74   void ReduceOffsets(Int32 subValue)
75   {
76     _buffer += subValue;
77     _posLimit -= subValue;
78     _pos -= subValue;
79     _streamPos -= subValue;
80   }
81 
82 };
83 
84 #endif
85