xref: /aosp_15_r20/external/lzma/CPP/7zip/Compress/LzOutWindow.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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