// LzOutWindow.h #ifndef ZIP7_INC_LZ_OUT_WINDOW_H #define ZIP7_INC_LZ_OUT_WINDOW_H #include "../Common/OutBuffer.h" #ifndef Z7_NO_EXCEPTIONS typedef COutBufferException CLzOutWindowException; #endif class CLzOutWindow: public COutBuffer { public: void Init(bool solid = false) throw(); // distance >= 0, len > 0, bool CopyBlock(UInt32 distance, UInt32 len) { UInt32 pos = _pos - distance - 1; if (distance >= _pos) { if (!_overDict || distance >= _bufSize) return false; pos += _bufSize; } if (_limitPos - _pos > len && _bufSize - pos > len) { const Byte *src = _buf + pos; Byte *dest = _buf + _pos; _pos += len; do *dest++ = *src++; while (--len != 0); } else do { UInt32 pos2; if (pos == _bufSize) pos = 0; pos2 = _pos; _buf[pos2++] = _buf[pos++]; _pos = pos2; if (pos2 == _limitPos) FlushWithCheck(); } while (--len != 0); return true; } void PutByte(Byte b) { UInt32 pos = _pos; _buf[pos++] = b; _pos = pos; if (pos == _limitPos) FlushWithCheck(); } void PutBytes(const Byte *data, UInt32 size) { if (size == 0) return; UInt32 pos = _pos; Byte *buf = _buf; buf[pos++] = *data++; size--; for (;;) { UInt32 limitPos = _limitPos; UInt32 rem = limitPos - pos; if (rem == 0) { _pos = pos; FlushWithCheck(); pos = _pos; continue; } if (size == 0) break; if (rem > size) rem = size; size -= rem; do buf[pos++] = *data++; while (--rem); } _pos = pos; } Byte GetByte(UInt32 distance) const { UInt32 pos = _pos - distance - 1; if (distance >= _pos) pos += _bufSize; return _buf[pos]; } }; #endif