1 // LzOutWindow.h 2 3 #ifndef ZIP7_INC_LZ_OUT_WINDOW_H 4 #define ZIP7_INC_LZ_OUT_WINDOW_H 5 6 #include "../Common/OutBuffer.h" 7 8 #ifndef Z7_NO_EXCEPTIONS 9 typedef COutBufferException CLzOutWindowException; 10 #endif 11 12 class CLzOutWindow: public COutBuffer 13 { 14 public: 15 void Init(bool solid = false) throw(); 16 17 // distance >= 0, len > 0, CopyBlock(UInt32 distance,UInt32 len)18 bool CopyBlock(UInt32 distance, UInt32 len) 19 { 20 UInt32 pos = _pos - distance - 1; 21 if (distance >= _pos) 22 { 23 if (!_overDict || distance >= _bufSize) 24 return false; 25 pos += _bufSize; 26 } 27 if (_limitPos - _pos > len && _bufSize - pos > len) 28 { 29 const Byte *src = _buf + pos; 30 Byte *dest = _buf + _pos; 31 _pos += len; 32 do 33 *dest++ = *src++; 34 while (--len != 0); 35 } 36 else do 37 { 38 UInt32 pos2; 39 if (pos == _bufSize) 40 pos = 0; 41 pos2 = _pos; 42 _buf[pos2++] = _buf[pos++]; 43 _pos = pos2; 44 if (pos2 == _limitPos) 45 FlushWithCheck(); 46 } 47 while (--len != 0); 48 return true; 49 } 50 PutByte(Byte b)51 void PutByte(Byte b) 52 { 53 UInt32 pos = _pos; 54 _buf[pos++] = b; 55 _pos = pos; 56 if (pos == _limitPos) 57 FlushWithCheck(); 58 } 59 PutBytes(const Byte * data,UInt32 size)60 void PutBytes(const Byte *data, UInt32 size) 61 { 62 if (size == 0) 63 return; 64 UInt32 pos = _pos; 65 Byte *buf = _buf; 66 buf[pos++] = *data++; 67 size--; 68 for (;;) 69 { 70 UInt32 limitPos = _limitPos; 71 UInt32 rem = limitPos - pos; 72 if (rem == 0) 73 { 74 _pos = pos; 75 FlushWithCheck(); 76 pos = _pos; 77 continue; 78 } 79 80 if (size == 0) 81 break; 82 83 if (rem > size) 84 rem = size; 85 size -= rem; 86 do 87 buf[pos++] = *data++; 88 while (--rem); 89 } 90 _pos = pos; 91 } 92 GetByte(UInt32 distance)93 Byte GetByte(UInt32 distance) const 94 { 95 UInt32 pos = _pos - distance - 1; 96 if (distance >= _pos) 97 pos += _bufSize; 98 return _buf[pos]; 99 } 100 }; 101 102 #endif 103