ruby-lzma 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/.gitignore +6 -0
  2. data/README.markdown +15 -0
  3. data/Rakefile +53 -0
  4. data/VERSION +1 -0
  5. data/ext/Alloc.cpp +118 -0
  6. data/ext/Alloc.h +29 -0
  7. data/ext/BinTree.h +55 -0
  8. data/ext/BinTree2.h +12 -0
  9. data/ext/BinTree3.h +16 -0
  10. data/ext/BinTree3Z.h +16 -0
  11. data/ext/BinTree4.h +18 -0
  12. data/ext/BinTree4b.h +20 -0
  13. data/ext/BinTreeMain.h +444 -0
  14. data/ext/BranchX86.c +101 -0
  15. data/ext/BranchX86.h +19 -0
  16. data/ext/CRC.cpp +61 -0
  17. data/ext/CRC.h +36 -0
  18. data/ext/C_FileIO.h +45 -0
  19. data/ext/CommandLineParser.h +82 -0
  20. data/ext/Defs.h +20 -0
  21. data/ext/FileStreams.h +98 -0
  22. data/ext/HC.h +55 -0
  23. data/ext/HC2.h +13 -0
  24. data/ext/HC3.h +17 -0
  25. data/ext/HC4.h +19 -0
  26. data/ext/HC4b.h +21 -0
  27. data/ext/HCMain.h +350 -0
  28. data/ext/ICoder.h +156 -0
  29. data/ext/IMatchFinder.h +63 -0
  30. data/ext/IStream.h +62 -0
  31. data/ext/InBuffer.cpp +80 -0
  32. data/ext/InBuffer.h +76 -0
  33. data/ext/LZInWindow.cpp +102 -0
  34. data/ext/LZInWindow.h +84 -0
  35. data/ext/LZMA.h +82 -0
  36. data/ext/LZMADecoder.h +248 -0
  37. data/ext/LZMAEncoder.cpp +1504 -0
  38. data/ext/LZMAEncoder.h +416 -0
  39. data/ext/LZOutWindow.cpp +17 -0
  40. data/ext/LZOutWindow.h +66 -0
  41. data/ext/LzmaBench.h +11 -0
  42. data/ext/LzmaDecode.c +588 -0
  43. data/ext/LzmaDecode.h +131 -0
  44. data/ext/LzmaRam.cpp +228 -0
  45. data/ext/LzmaRam.h +46 -0
  46. data/ext/LzmaRamDecode.c +79 -0
  47. data/ext/LzmaRamDecode.h +55 -0
  48. data/ext/MyCom.h +203 -0
  49. data/ext/MyGuidDef.h +54 -0
  50. data/ext/MyInitGuid.h +13 -0
  51. data/ext/MyString.h +631 -0
  52. data/ext/MyUnknown.h +24 -0
  53. data/ext/MyWindows.h +183 -0
  54. data/ext/OutBuffer.cpp +117 -0
  55. data/ext/OutBuffer.h +64 -0
  56. data/ext/Pat.h +318 -0
  57. data/ext/Pat2.h +22 -0
  58. data/ext/Pat2H.h +24 -0
  59. data/ext/Pat2R.h +20 -0
  60. data/ext/Pat3H.h +24 -0
  61. data/ext/Pat4H.h +24 -0
  62. data/ext/PatMain.h +989 -0
  63. data/ext/RangeCoder.h +205 -0
  64. data/ext/RangeCoderBit.cpp +80 -0
  65. data/ext/RangeCoderBit.h +120 -0
  66. data/ext/RangeCoderBitTree.h +161 -0
  67. data/ext/RangeCoderOpt.h +31 -0
  68. data/ext/StdAfx.h +8 -0
  69. data/ext/StreamUtils.cpp +44 -0
  70. data/ext/StreamUtils.h +11 -0
  71. data/ext/StringConvert.h +71 -0
  72. data/ext/StringToInt.h +17 -0
  73. data/ext/Types.h +19 -0
  74. data/ext/Vector.h +211 -0
  75. data/ext/extconf.rb +7 -0
  76. data/ext/lzma_ruby.cpp +51 -0
  77. data/ext/lzmalib.h +64 -0
  78. data/ext/mylib.cpp +81 -0
  79. data/java/SevenZip/CRC.java +52 -0
  80. data/java/SevenZip/Compression/LZ/BinTree.java +382 -0
  81. data/java/SevenZip/Compression/LZ/InWindow.java +131 -0
  82. data/java/SevenZip/Compression/LZ/OutWindow.java +85 -0
  83. data/java/SevenZip/Compression/LZMA/Base.java +88 -0
  84. data/java/SevenZip/Compression/LZMA/Decoder.java +329 -0
  85. data/java/SevenZip/Compression/LZMA/Encoder.java +1415 -0
  86. data/java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java +55 -0
  87. data/java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java +99 -0
  88. data/java/SevenZip/Compression/RangeCoder/Decoder.java +88 -0
  89. data/java/SevenZip/Compression/RangeCoder/Encoder.java +151 -0
  90. data/java/SevenZip/ICodeProgress.java +6 -0
  91. data/java/SevenZip/LzmaAlone.java +253 -0
  92. data/java/SevenZip/LzmaBench.java +391 -0
  93. data/java/com/ephemeronindustries/lzma/LZMA.java +104 -0
  94. data/lib/lzma.rb +32 -0
  95. data/ruby-lzma.gemspec +136 -0
  96. data/test/test_lzma.rb +42 -0
  97. metadata +157 -0
data/ext/LZMAEncoder.h ADDED
@@ -0,0 +1,416 @@
1
+ // LZMA/Encoder.h
2
+
3
+ #ifndef __LZMA_ENCODER_H
4
+ #define __LZMA_ENCODER_H
5
+
6
+ #include "MyCom.h"
7
+ #include "Alloc.h"
8
+ #include "ICoder.h"
9
+ #include "IMatchFinder.h"
10
+ #include "RangeCoderBitTree.h"
11
+
12
+ #include "LZMA.h"
13
+
14
+ namespace NCompress {
15
+ namespace NLZMA {
16
+
17
+ typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;
18
+
19
+ class CBaseState
20
+ {
21
+ protected:
22
+ CState _state;
23
+ Byte _previousByte;
24
+ UInt32 _repDistances[kNumRepDistances];
25
+ void Init()
26
+ {
27
+ _state.Init();
28
+ _previousByte = 0;
29
+ for(UInt32 i = 0 ; i < kNumRepDistances; i++)
30
+ _repDistances[i] = 0;
31
+ }
32
+ };
33
+
34
+ struct COptimal
35
+ {
36
+ CState State;
37
+
38
+ bool Prev1IsChar;
39
+ bool Prev2;
40
+
41
+ UInt32 PosPrev2;
42
+ UInt32 BackPrev2;
43
+
44
+ UInt32 Price;
45
+ UInt32 PosPrev; // posNext;
46
+ UInt32 BackPrev;
47
+ UInt32 Backs[kNumRepDistances];
48
+ void MakeAsChar() { BackPrev = UInt32(-1); Prev1IsChar = false; }
49
+ void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
50
+ bool IsShortRep() { return (BackPrev == 0); }
51
+ };
52
+
53
+
54
+ extern Byte g_FastPos[1024];
55
+ inline UInt32 GetPosSlot(UInt32 pos)
56
+ {
57
+ if (pos < (1 << 10))
58
+ return g_FastPos[pos];
59
+ if (pos < (1 << 19))
60
+ return g_FastPos[pos >> 9] + 18;
61
+ return g_FastPos[pos >> 18] + 36;
62
+ }
63
+
64
+ inline UInt32 GetPosSlot2(UInt32 pos)
65
+ {
66
+ if (pos < (1 << 16))
67
+ return g_FastPos[pos >> 6] + 12;
68
+ if (pos < (1 << 25))
69
+ return g_FastPos[pos >> 15] + 30;
70
+ return g_FastPos[pos >> 24] + 48;
71
+ }
72
+
73
+ const UInt32 kIfinityPrice = 0xFFFFFFF;
74
+
75
+ const UInt32 kNumOpts = 1 << 12;
76
+
77
+
78
+ class CLiteralEncoder2
79
+ {
80
+ CMyBitEncoder _encoders[0x300];
81
+ public:
82
+ void Init()
83
+ {
84
+ for (int i = 0; i < 0x300; i++)
85
+ _encoders[i].Init();
86
+ }
87
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol);
88
+ void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, Byte matchByte, Byte symbol);
89
+ UInt32 GetPrice(bool matchMode, Byte matchByte, Byte symbol) const;
90
+ };
91
+
92
+ class CLiteralEncoder
93
+ {
94
+ CLiteralEncoder2 *_coders;
95
+ int _numPrevBits;
96
+ int _numPosBits;
97
+ UInt32 _posMask;
98
+ public:
99
+ CLiteralEncoder(): _coders(0) {}
100
+ ~CLiteralEncoder() { Free(); }
101
+ void Free()
102
+ {
103
+ MyFree(_coders);
104
+ _coders = 0;
105
+ }
106
+ bool Create(int numPosBits, int numPrevBits)
107
+ {
108
+ if (_coders == 0 || (numPosBits + numPrevBits) !=
109
+ (_numPrevBits + _numPosBits) )
110
+ {
111
+ Free();
112
+ UInt32 numStates = 1 << (numPosBits + numPrevBits);
113
+ _coders = (CLiteralEncoder2 *)MyAlloc(numStates * sizeof(CLiteralEncoder2));
114
+ }
115
+ _numPosBits = numPosBits;
116
+ _posMask = (1 << numPosBits) - 1;
117
+ _numPrevBits = numPrevBits;
118
+ return (_coders != 0);
119
+ }
120
+ void Init()
121
+ {
122
+ UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
123
+ for (UInt32 i = 0; i < numStates; i++)
124
+ _coders[i].Init();
125
+ }
126
+ UInt32 GetState(UInt32 pos, Byte prevByte) const
127
+ { return ((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits)); }
128
+ CLiteralEncoder2 *GetSubCoder(UInt32 pos, Byte prevByte)
129
+ { return &_coders[GetState(pos, prevByte)]; }
130
+ /*
131
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 pos, Byte prevByte,
132
+ Byte symbol)
133
+ { _coders[GetState(pos, prevByte)].Encode(rangeEncoder, symbol); }
134
+ void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, UInt32 pos, Byte prevByte,
135
+ Byte matchByte, Byte symbol)
136
+ { _coders[GetState(pos, prevByte)].Encode(rangeEncoder,
137
+ matchByte, symbol); }
138
+ */
139
+ UInt32 GetPrice(UInt32 pos, Byte prevByte, bool matchMode, Byte matchByte, Byte symbol) const
140
+ { return _coders[GetState(pos, prevByte)].GetPrice(matchMode, matchByte, symbol); }
141
+ };
142
+
143
+ namespace NLength {
144
+
145
+ class CEncoder
146
+ {
147
+ CMyBitEncoder _choice;
148
+ CMyBitEncoder _choice2;
149
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesEncodingMax];
150
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesEncodingMax];
151
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumHighBits> _highCoder;
152
+ public:
153
+ void Init(UInt32 numPosStates);
154
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState);
155
+ UInt32 GetPrice(UInt32 symbol, UInt32 posState) const;
156
+ };
157
+
158
+ const UInt32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols;
159
+
160
+ class CPriceTableEncoder: public CEncoder
161
+ {
162
+ UInt32 _prices[kNumSymbolsTotal][kNumPosStatesEncodingMax];
163
+ UInt32 _tableSize;
164
+ UInt32 _counters[kNumPosStatesEncodingMax];
165
+ public:
166
+ void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; }
167
+ UInt32 GetPrice(UInt32 symbol, UInt32 posState) const
168
+ { return _prices[symbol][posState]; }
169
+ void UpdateTable(UInt32 posState)
170
+ {
171
+ for (UInt32 len = 0; len < _tableSize; len++)
172
+ _prices[len][posState] = CEncoder::GetPrice(len, posState);
173
+ _counters[posState] = _tableSize;
174
+ }
175
+ void UpdateTables(UInt32 numPosStates)
176
+ {
177
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
178
+ UpdateTable(posState);
179
+ }
180
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState)
181
+ {
182
+ CEncoder::Encode(rangeEncoder, symbol, posState);
183
+ if (--_counters[posState] == 0)
184
+ UpdateTable(posState);
185
+ }
186
+ };
187
+
188
+ }
189
+
190
+ class CEncoder :
191
+ public ICompressCoder,
192
+ public ICompressSetOutStream,
193
+ public ICompressSetCoderProperties,
194
+ public ICompressWriteCoderProperties,
195
+ public CBaseState,
196
+ public CMyUnknownImp
197
+ {
198
+ COptimal _optimum[kNumOpts];
199
+ CMyComPtr<IMatchFinder> _matchFinder; // test it
200
+ NRangeCoder::CEncoder _rangeEncoder;
201
+
202
+ CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax];
203
+ CMyBitEncoder _isRep[kNumStates];
204
+ CMyBitEncoder _isRepG0[kNumStates];
205
+ CMyBitEncoder _isRepG1[kNumStates];
206
+ CMyBitEncoder _isRepG2[kNumStates];
207
+ CMyBitEncoder _isRep0Long[kNumStates][NLength::kNumPosStatesEncodingMax];
208
+
209
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates];
210
+
211
+ CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex];
212
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumAlignBits> _posAlignEncoder;
213
+
214
+ NLength::CPriceTableEncoder _lenEncoder;
215
+ NLength::CPriceTableEncoder _repMatchLenEncoder;
216
+
217
+ CLiteralEncoder _literalEncoder;
218
+
219
+ UInt32 _matchDistances[kMatchMaxLen + 1];
220
+
221
+ bool _fastMode;
222
+ bool _maxMode;
223
+ UInt32 _numFastBytes;
224
+ UInt32 _longestMatchLength;
225
+
226
+ UInt32 _additionalOffset;
227
+
228
+ UInt32 _optimumEndIndex;
229
+ UInt32 _optimumCurrentIndex;
230
+
231
+ bool _longestMatchWasFound;
232
+
233
+ UInt32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
234
+
235
+ UInt32 _distancesPrices[kNumLenToPosStates][kNumFullDistances];
236
+
237
+ UInt32 _alignPrices[kAlignTableSize];
238
+ UInt32 _alignPriceCount;
239
+
240
+ UInt32 _distTableSize;
241
+
242
+ UInt32 _posStateBits;
243
+ UInt32 _posStateMask;
244
+ UInt32 _numLiteralPosStateBits;
245
+ UInt32 _numLiteralContextBits;
246
+
247
+ UInt32 _dictionarySize;
248
+
249
+ UInt32 _dictionarySizePrev;
250
+ UInt32 _numFastBytesPrev;
251
+
252
+ UInt64 lastPosSlotFillingPos;
253
+ UInt64 nowPos64;
254
+ bool _finished;
255
+ ISequentialInStream *_inStream;
256
+
257
+ int _matchFinderIndex;
258
+ #ifdef COMPRESS_MF_MT
259
+ bool _multiThread;
260
+ #endif
261
+
262
+ bool _writeEndMark;
263
+
264
+ bool _needReleaseMFStream;
265
+
266
+ HRESULT ReadMatchDistances(UInt32 &len);
267
+
268
+ HRESULT MovePos(UInt32 num);
269
+ UInt32 GetRepLen1Price(CState state, UInt32 posState) const
270
+ {
271
+ return _isRepG0[state.Index].GetPrice0() +
272
+ _isRep0Long[state.Index][posState].GetPrice0();
273
+ }
274
+ UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const
275
+ {
276
+ UInt32 price = _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState);
277
+ if(repIndex == 0)
278
+ {
279
+ price += _isRepG0[state.Index].GetPrice0();
280
+ price += _isRep0Long[state.Index][posState].GetPrice1();
281
+ }
282
+ else
283
+ {
284
+ price += _isRepG0[state.Index].GetPrice1();
285
+ if (repIndex == 1)
286
+ price += _isRepG1[state.Index].GetPrice0();
287
+ else
288
+ {
289
+ price += _isRepG1[state.Index].GetPrice1();
290
+ price += _isRepG2[state.Index].GetPrice(repIndex - 2);
291
+ }
292
+ }
293
+ return price;
294
+ }
295
+ /*
296
+ UInt32 GetPosLen2Price(UInt32 pos, UInt32 posState) const
297
+ {
298
+ if (pos >= kNumFullDistances)
299
+ return kIfinityPrice;
300
+ return _distancesPrices[0][pos] + _lenEncoder.GetPrice(0, posState);
301
+ }
302
+ UInt32 GetPosLen3Price(UInt32 pos, UInt32 len, UInt32 posState) const
303
+ {
304
+ UInt32 price;
305
+ UInt32 lenToPosState = GetLenToPosState(len);
306
+ if (pos < kNumFullDistances)
307
+ price = _distancesPrices[lenToPosState][pos];
308
+ else
309
+ price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
310
+ _alignPrices[pos & kAlignMask];
311
+ return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
312
+ }
313
+ */
314
+ UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) const
315
+ {
316
+ if (len == 2 && pos >= 0x80)
317
+ return kIfinityPrice;
318
+ UInt32 price;
319
+ UInt32 lenToPosState = GetLenToPosState(len);
320
+ if (pos < kNumFullDistances)
321
+ price = _distancesPrices[lenToPosState][pos];
322
+ else
323
+ price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
324
+ _alignPrices[pos & kAlignMask];
325
+ return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
326
+ }
327
+
328
+ UInt32 Backward(UInt32 &backRes, UInt32 cur);
329
+ HRESULT GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
330
+ HRESULT GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
331
+
332
+ void FillPosSlotPrices();
333
+ void FillDistancesPrices();
334
+ void FillAlignPrices();
335
+
336
+ void ReleaseMFStream()
337
+ {
338
+ if (_matchFinder && _needReleaseMFStream)
339
+ {
340
+ _matchFinder->ReleaseStream();
341
+ _needReleaseMFStream = false;
342
+ }
343
+ }
344
+
345
+ void ReleaseStreams()
346
+ {
347
+ ReleaseMFStream();
348
+ ReleaseOutStream();
349
+ }
350
+
351
+ HRESULT Flush(UInt32 nowPos);
352
+ class CCoderReleaser
353
+ {
354
+ CEncoder *_coder;
355
+ public:
356
+ CCoderReleaser(CEncoder *coder): _coder(coder) {}
357
+ ~CCoderReleaser()
358
+ {
359
+ _coder->ReleaseStreams();
360
+ }
361
+ };
362
+ friend class CCoderReleaser;
363
+
364
+ void WriteEndMarker(UInt32 posState);
365
+
366
+ public:
367
+ CEncoder();
368
+ void SetWriteEndMarkerMode(bool writeEndMarker)
369
+ { _writeEndMark= writeEndMarker; }
370
+
371
+ HRESULT Create();
372
+
373
+ MY_UNKNOWN_IMP3(
374
+ ICompressSetOutStream,
375
+ ICompressSetCoderProperties,
376
+ ICompressWriteCoderProperties
377
+ )
378
+
379
+ HRESULT Init();
380
+
381
+ // ICompressCoder interface
382
+ HRESULT SetStreams(ISequentialInStream *inStream,
383
+ ISequentialOutStream *outStream,
384
+ const UInt64 *inSize, const UInt64 *outSize);
385
+ HRESULT CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished);
386
+
387
+ HRESULT CodeReal(ISequentialInStream *inStream,
388
+ ISequentialOutStream *outStream,
389
+ const UInt64 *inSize, const UInt64 *outSize,
390
+ ICompressProgressInfo *progress);
391
+
392
+ // ICompressCoder interface
393
+ STDMETHOD(Code)(ISequentialInStream *inStream,
394
+ ISequentialOutStream *outStream,
395
+ const UInt64 *inSize, const UInt64 *outSize,
396
+ ICompressProgressInfo *progress);
397
+
398
+ // IInitMatchFinder interface
399
+ STDMETHOD(InitMatchFinder)(IMatchFinder *matchFinder);
400
+
401
+ // ICompressSetCoderProperties2
402
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
403
+ const PROPVARIANT *properties, UInt32 numProperties);
404
+
405
+ // ICompressWriteCoderProperties
406
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
407
+
408
+ STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
409
+ STDMETHOD(ReleaseOutStream)();
410
+
411
+ virtual ~CEncoder() {}
412
+ };
413
+
414
+ }}
415
+
416
+ #endif
@@ -0,0 +1,17 @@
1
+ // LZOutWindow.cpp
2
+
3
+ #include "StdAfx.h"
4
+
5
+ #include "Alloc.h"
6
+ #include "LZOutWindow.h"
7
+
8
+ void CLZOutWindow::Init(bool solid)
9
+ {
10
+ if(!solid)
11
+ COutBuffer::Init();
12
+ #ifdef _NO_EXCEPTIONS
13
+ ErrorCode = S_OK;
14
+ #endif
15
+ }
16
+
17
+
data/ext/LZOutWindow.h ADDED
@@ -0,0 +1,66 @@
1
+ // LZOutWindow.h
2
+
3
+ #ifndef __LZ_OUT_WINDOW_H
4
+ #define __LZ_OUT_WINDOW_H
5
+
6
+ #include "IStream.h"
7
+ #include "OutBuffer.h"
8
+
9
+ /*
10
+ #ifndef _NO_EXCEPTIONS
11
+ class CLZOutWindowException
12
+ {
13
+ public:
14
+ HRESULT ErrorCode;
15
+ CLZOutWindowException(HRESULT errorCode): ErrorCode(errorCode) {}
16
+ };
17
+ #endif
18
+ */
19
+ #ifndef _NO_EXCEPTIONS
20
+ typedef COutBufferException CLZOutWindowException;
21
+ #endif
22
+
23
+ class CLZOutWindow: public COutBuffer
24
+ {
25
+ public:
26
+ void Init(bool solid = false);
27
+
28
+ // distance >= 0, len > 0,
29
+ bool CopyBlock(UInt32 distance, UInt32 len)
30
+ {
31
+ UInt32 pos = _pos - distance - 1;
32
+ if (pos >= _bufferSize)
33
+ {
34
+ if (!_overDict)
35
+ return false;
36
+ pos += _bufferSize;
37
+ }
38
+ do
39
+ {
40
+ if (pos == _bufferSize)
41
+ pos = 0;
42
+ _buffer[_pos++] = _buffer[pos++];
43
+ if (_pos == _limitPos)
44
+ FlushWithCheck();
45
+ }
46
+ while(--len != 0);
47
+ return true;
48
+ }
49
+
50
+ void PutByte(Byte b)
51
+ {
52
+ _buffer[_pos++] = b;
53
+ if (_pos == _limitPos)
54
+ FlushWithCheck();
55
+ }
56
+
57
+ Byte GetByte(UInt32 distance) const
58
+ {
59
+ UInt32 pos = _pos - distance - 1;
60
+ if (pos >= _bufferSize)
61
+ pos += _bufferSize;
62
+ return _buffer[pos];
63
+ }
64
+ };
65
+
66
+ #endif