| // LZInWindow.h |
| |
| #ifndef __LZ_IN_WINDOW_H |
| #define __LZ_IN_WINDOW_H |
| |
| #include "../../IStream.h" |
| |
| class CLZInWindow |
| { |
| Byte *_bufferBase; // pointer to buffer with data |
| ISequentialInStream *_stream; |
| UInt32 _posLimit; // offset (from _buffer) when new block reading must be done |
| bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream |
| const Byte *_pointerToLastSafePosition; |
| protected: |
| Byte *_buffer; // Pointer to virtual Buffer begin |
| UInt32 _blockSize; // Size of Allocated memory block |
| UInt32 _pos; // offset (from _buffer) of curent byte |
| UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos |
| UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos |
| UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream |
| |
| void MoveBlock(); |
| HRESULT ReadBlock(); |
| void Free(); |
| public: |
| CLZInWindow(): _bufferBase(0) {} |
| virtual ~CLZInWindow() { Free(); } |
| |
| // keepSizeBefore + keepSizeAfter + keepSizeReserv < 4G) |
| bool Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv = (1<<17)); |
| |
| void SetStream(ISequentialInStream *stream); |
| HRESULT Init(); |
| // void ReleaseStream(); |
| |
| Byte *GetBuffer() const { return _buffer; } |
| |
| const Byte *GetPointerToCurrentPos() const { return _buffer + _pos; } |
| |
| HRESULT MovePos() |
| { |
| _pos++; |
| if (_pos > _posLimit) |
| { |
| const Byte *pointerToPostion = _buffer + _pos; |
| if(pointerToPostion > _pointerToLastSafePosition) |
| MoveBlock(); |
| return ReadBlock(); |
| } |
| else |
| return S_OK; |
| } |
| Byte GetIndexByte(Int32 index) const { return _buffer[(size_t)_pos + index]; } |
| |
| // index + limit have not to exceed _keepSizeAfter; |
| // -2G <= index < 2G |
| UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) const |
| { |
| if(_streamEndWasReached) |
| if ((_pos + index) + limit > _streamPos) |
| limit = _streamPos - (_pos + index); |
| distance++; |
| const Byte *pby = _buffer + (size_t)_pos + index; |
| UInt32 i; |
| for(i = 0; i < limit && pby[i] == pby[(size_t)i - distance]; i++); |
| return i; |
| } |
| |
| UInt32 GetNumAvailableBytes() const { return _streamPos - _pos; } |
| |
| void ReduceOffsets(Int32 subValue) |
| { |
| _buffer += subValue; |
| _posLimit -= subValue; |
| _pos -= subValue; |
| _streamPos -= subValue; |
| } |
| |
| bool NeedMove(UInt32 numCheckBytes) |
| { |
| UInt32 reserv = _pointerToLastSafePosition - (_buffer + _pos); |
| return (reserv <= numCheckBytes); |
| } |
| }; |
| |
| #endif |