LZScene

Форк
0
/
GLSZLibEx.pas 
2146 строк · 65.6 Кб
1
//
2
// This unit is part of the GLScene Engine https://github.com/glscene
3
//
4
{
5
  History :  
6
       07/05/10 - Yar - Fixed for Linux x64
7
       06/05/10 - Yar - Added to GLScene (contributed by oleg matrozov)
8
   
9

10
{*****************************************************************************
11
*                                                                            *
12
*  copyright (c) 2000-2010 base2 technologies                                *
13
*  copyright (c) 1995-2002 Borland Software Corporation                      *
14
*                                                                            *
15
*  revision history                                                          *
16
*    2010.05.02  added ZDelfateEx and ZInflateEx                             *
17
*    2010.04.20  added TZ*Buffer classes                                     *
18
*    2010.04.15  moved core zlib routines to separate unit (ZLibExApi.pas)   *
19
*                added ZDeflate* and ZInflate*                               *
20
*    2010.04.14  fixed ZInternalCompress loops                               *
21
*                fixed ZInternalDecompress loops                             *
22
*                updated ZInternalCompressStream loops                       *
23
*                updated ZInternalDecompressStream loops                     *
24
*    2010.01.27  updated for delphi 2010                                     *
25
*    2009.04.14  added overloaded string routines for AnsiString and         *
26
*                  UnicodeString                                             *
27
*    2009.01.28  updated for delphi 2009 String (UnicodeString)              *
28
*    2008.05.15  added TStreamPos type for Stream.Position variants          *
29
*                added TCustomZStream.Stream* methods                        *
30
*    2007.08.17  modified TZCompressionStream.Write to use Write instead of  *
31
*                  WriteBuffer                                               *
32
*    2007.03.15  moved gzip routines to separate unit (ZLibExGZ.pas)         *
33
*    2006.10.07  fixed EZLibError constructor for c++ builder compatibility  *
34
*    2006.03.28  moved Z_DEFLATED to interface section                       *
35
*                added custom compression levels zcLevel1 thru zcLevel9      *
36
*    2006.03.27  added ZCompressStreamWeb                                    *
37
*    2006.03.24  added ZAdler32 and ZCrc32                                   *
38
*    2005.11.29  changed FStreamPos to Int64 for delphi 6+                   *
39
*    2005.03.04  modified ZInternalCompressStream loops                      *
40
*                modified ZInternalDecompressStream loops                    *
41
*    2005.02.07  fixed ZInternalCompressStream loop conditions               *
42
*                fixed ZInternalDecompressStream loop conditions             *
43
*    2005.01.11  added ZCompressStrWeb                                       *
44
*    2003.04.14  added ZCompress2 and ZDecompress2                           *
45
*                added ZCompressStr2 and ZDecompressStr2                     *
46
*                added ZCompressStream2 and ZDecompressStream2               *
47
*                added overloaded T*Stream constructors to support           *
48
*                  InflateInit2 and DeflateInit2                             *
49
*                fixed ZDecompressStream to use ZDecompressCheck instead of  *
50
*                  ZCompressCheck                                            *
51
*    2001.11.27  enhanced TZDecompressionStream.Read to adjust source        *
52
*                  stream position upon end of compression data              *
53
*                fixed endless loop in TZDecompressionStream.Read when       *
54
*                  destination count was greater than uncompressed data      *
55
*    2001.10.26  renamed unit to integrate "nicely" with delphi 6            *
56
*    2000.11.24  added soFromEnd condition to TZDecompressionStream.Seek     *
57
*                added ZCompressStream and ZDecompressStream                 *
58
*    2000.06.13  optimized, fixed, rewrote, and enhanced the zlib.pas unit   *
59
*                  included on the delphi cd (zlib version 1.1.3)            *
60
*                                                                            *
61
*  acknowledgments                                                           *
62
*    erik turner                                                             *
63
*      2001.10.26  Z*Stream routines                                         *
64
*                                                                            *
65
*    david bennion                                                           *
66
*      2001.11.27  finding the nasty little endless loop quirk with the      *
67
*                    TZDecompressionStream.Read method                       *
68
*                                                                            *
69
*    luigi sandon                                                            *
70
*      2005.02.07  pointing out the missing loop condition (Z_STREAM_END)    *
71
*                    in ZInternalCompressStream and                          *
72
*                    ZInternalDecompressStream                               *
73
*                                                                            *
74
*    ferry van genderen                                                      *
75
*      2005.03.04  assisting me fine tune and beta test                      *
76
*                    ZInternalCompressStream and ZInternalDecompressStream   *
77
*                                                                            *
78
*    j. rathlev                                                              *
79
*      2005.11.28  pointing out the FStreamPos and TStream.Position type     *
80
*                    inconsistency                                           *
81
*                                                                            *
82
*    anders johansen                                                         *
83
*      2006.10.07  pointing out the ELibError constructor incompatibility    *
84
*                    with c++ builder                                        *
85
*                                                                            *
86
*    marcin szafranski                                                       *
87
*      2009.01.28  beta testing the delphi 2009 changes                      *
88
*                                                                            *
89
*    iztok kacin                                                             *
90
*      2009.04.14  assisting me design and further improve support for       *
91
*                    delphi 2009                                             *
92
*                                                                            *
93
*    oleg matrozov                                                           *
94
*      2010.04.14  pointing out the missing loop condition (avail_in > 0)    *
95
*                    in ZInternalCompress and ZInternalDecompress            *
96
*      2010.04.20  prototyping and assisting with the TZ*Buffer classes      *
97
*****************************************************************************}
98

99
unit GLSZLibEx;
100

101
interface
102

103
{$I ZLibEx.inc}
104
{$I GLScene.inc}
105

106
uses
107
  SysUtils, Classes, GLCrossPlatform, GLSZLibExApi;
108

109
type
110

111
{$ifndef UNICODE}
112

113
  RawByteString = AnsiString;
114

115
  UnicodeString = WideString;
116
  UnicodeChar = WideChar;
117

118
{$else ifdef Version2010Plus}
119

120
  UnicodeChar = WideChar;
121

122
{$endif}
123

124
  TStreamPos = {$ifdef Version6Plus} Int64 {$else} Longint {$endif};
125

126
  TZCompressionLevel = (
127
    zcNone,
128
    zcFastest,
129
    zcDefault,
130
    zcMax,
131
    zcLevel1,
132
    zcLevel2,
133
    zcLevel3,
134
    zcLevel4,
135
    zcLevel5,
136
    zcLevel6,
137
    zcLevel7,
138
    zcLevel8,
139
    zcLevel9
140
  );
141

142
  TZStrategy = (
143
    zsDefault,
144
    zsFiltered,
145
    zsHuffman,
146
    zsRLE,
147
    zsFixed
148
  );
149

150
  TZError = (
151
    zeError,
152
    zeStreamError,
153
    zeDataError,
154
    zeMemoryError,
155
    zeBufferError,
156
    zeVersionError
157
  );
158

159
  TZFlush = (
160
    zfNoFlush,
161
    zfPartialFlush,
162
    zfSyncFlush,
163
    zfFullFlush,
164
    zfFinish,
165
    zfBlock,
166
    zfTrees
167
  );
168

169
const
170
  ZLevels: Array [TZCompressionLevel] of Integer = (
171
    Z_NO_COMPRESSION,       // zcNone
172
    Z_BEST_SPEED,           // zcFastest
173
    Z_DEFAULT_COMPRESSION,  // zcDefault
174
    Z_BEST_COMPRESSION,     // zcMax
175
    1,                      // zcLevel1
176
    2,                      // zcLevel2
177
    3,                      // zcLevel3
178
    4,                      // zcLevel4
179
    5,                      // zcLevel5
180
    6,                      // zcLevel6
181
    7,                      // zcLevel7
182
    8,                      // zcLevel8
183
    9                       // zcLevel9
184
  );
185

186
  ZStrategies: Array [TZStrategy] of Integer = (
187
    Z_DEFAULT_STRATEGY,     // zsDefault
188
    Z_FILTERED,             // zsFiltered
189
    Z_HUFFMAN_ONLY,         // zsHuffman
190
    Z_RLE,                  // zsRLE
191
    Z_FIXED                 // zsFixed
192
  );
193

194
  ZErrors: Array [TZError] of Integer = (
195
    Z_ERRNO,                // zeError
196
    Z_STREAM_ERROR,         // zeStreamError
197
    Z_DATA_ERROR,           // zeDataError
198
    Z_MEM_ERROR,            // zeMemoryError
199
    Z_BUF_ERROR,            // zeBufferError
200
    Z_VERSION_ERROR         // zeVersionError
201
  );
202

203
  ZFlushes: Array [TZFlush] of Integer = (
204
    Z_NO_FLUSH,             // zfNoFlush
205
    Z_PARTIAL_FLUSH,        // zfPartialFlush
206
    Z_SYNC_FLUSH,           // zfSyncFlush
207
    Z_FULL_FLUSH,           // zfFullFlush
208
    Z_FINISH,               // zfFinish
209
    Z_BLOCK,                // zfBlock
210
    Z_TREES                 // zfTrees
211
  );
212

213
type
214
  {** TZ*Function ***********************************************************}
215

216
  TZReadFunction = function (param: Pointer; var buffer;
217
    size: Integer): Integer;
218

219
  TZWriteFunction = function (param: Pointer; const buffer;
220
    size: Integer): Integer;
221

222
  {** TZInformation *********************************************************}
223

224
  TZInformation = packed record
225
    CompressedFlags  : Longint;
226
    CompressedSize   : TStreamPos;
227
    CompressedCrc    : Longint;
228
    CompressedAdler  : Longint;
229

230
    UncompressedFlags: Longint;
231
    UncompressedSize : TStreamPos;
232
    UncompressedCrc  : Longint;
233
    UncompressedAdler: Longint;
234
  end;
235

236
  {** TCustomZStream ********************************************************}
237

238
  TCustomZStream = class(TStream)
239
  private
240
    FStream    : TStream;
241
    FStreamPos : TStreamPos;
242
    FOnProgress: TNotifyEvent;
243

244
    FZStream   : TZStreamRec;
245
    FBuffer    : Array [Word] of Byte;
246

247
    function  GetStreamPosition: TStreamPos;
248
    procedure SetStreamPosition(value: TStreamPos);
249
  protected
250
    function  StreamRead(var buffer; count: Longint): Longint;
251
    function  StreamWrite(const buffer; count: Longint): Longint;
252
    function  StreamSeek(offset: Longint; origin: Word): Longint;
253

254
    procedure StreamReadBuffer(var buffer; count: Longint);
255
    procedure StreamWriteBuffer(const buffer; count: Longint);
256

257
    procedure DoProgress; dynamic;
258

259
    property StreamPosition: TStreamPos read GetStreamPosition write SetStreamPosition;
260

261
    property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
262
  public
263
    constructor Create(stream: TStream);
264
  end;
265

266
  {** TZCompressionStream ***************************************************}
267

268
  TZCompressionStream = class(TCustomZStream)
269
  private
270
    function GetCompressionRate: Single;
271
  public
272
    constructor Create(dest: TStream;
273
      compressionLevel: TZCompressionLevel = zcDefault); overload;
274

275
    constructor Create(dest: TStream; compressionLevel: TZCompressionLevel;
276
      windowBits, memLevel: Integer; strategy: TZStrategy); overload;
277

278
    destructor  Destroy; override;
279

280
    function  Read(var buffer; count: Longint): Longint; override;
281
    function  Write(const buffer; count: Longint): Longint; override;
282
    function  Seek(offset: Longint; origin: Word): Longint; override;
283

284
    property CompressionRate: Single read GetCompressionRate;
285
    property OnProgress;
286
  end;
287

288
  {** TZDecompressionStream *************************************************}
289

290
  TZDecompressionStream = class(TCustomZStream)
291
  public
292
    constructor Create(source: TStream); overload;
293
    constructor Create(source: TStream; windowBits: Integer); overload;
294

295
    destructor  Destroy; override;
296

297
    function  Read(var buffer; count: Longint): Longint; override;
298
    function  Write(const buffer; count: Longint): Longint; override;
299
    function  Seek(offset: Longint; origin: Word): Longint; override;
300

301
    property OnProgress;
302
  end;
303

304
  {** TZCustomBuffer ********************************************************}
305

306
  TZCustomBuffer = class(TObject)
307
  private
308
    FBuffer        : Pointer;
309
    FBufferCapacity: Integer;
310
    FBufferSize    : Integer;
311
  protected
312
    FZStream: TZStreamRec;
313

314
    procedure BufferWrite(const buffer: Pointer; size: Integer);
315
    procedure BufferRead(var buffer: Pointer; size: Integer);
316

317
    procedure BufferCapacity(capacity: Integer);
318

319
    property BufferSize: Integer read FBufferSize;
320
  public
321
    constructor Create;
322
    destructor  Destroy; override;
323

324
    procedure Clear; virtual;
325

326
    procedure Flush(flush: TZFlush); virtual;
327

328
    function  Write(const buffer: Pointer; size: Integer): Integer; overload;
329
      virtual; abstract;
330

331
    function  Write(const s: AnsiString): Integer; overload;
332

333
    function  Read(var buffer: Pointer; size: Integer): Integer; overload;
334
    function  Read(var s: AnsiString): Integer; overload;
335
  end;
336

337
  {** TZCompressionBuffer ***************************************************}
338

339
  TZCompressionBuffer = class(TZCustomBuffer)
340
  public
341
    constructor Create(level: TZCompressionLevel = zcDefault); overload;
342
    constructor Create(level: TZCompressionLevel;
343
      windowBits, memLevel: Integer; strategy: TZStrategy); overload;
344

345
    destructor  Destroy; override;
346

347
    procedure Clear; override;
348

349
    procedure Flush(flush: TZFlush); override;
350

351
    function  Write(const buffer: Pointer; size: Integer): Integer;
352
      override;
353
  end;
354

355
  {** TZDecompressionBuffer *************************************************}
356

357
  TZDecompressionBuffer = class(TZCustomBuffer)
358
  public
359
    constructor Create; overload;
360
    constructor Create(windowBits: Integer); overload;
361

362
    destructor  Destroy; override;
363

364
    procedure Clear; override;
365

366
    function  Write(const buffer: Pointer; size: Integer): Integer; override;
367
  end;
368

369
{** zlib deflate routines ***************************************************}
370

371
function  ZDeflateInit(var stream: TZStreamRec;
372
  level: TZCompressionLevel): Integer;
373
  {$ifdef GLS_INLINE} inline; {$endif}
374

375
function  ZDeflateInit2(var stream: TZStreamRec;
376
  level: TZCompressionLevel; windowBits, memLevel: Integer;
377
  strategy: TZStrategy): Integer;
378
  {$ifdef GLS_INLINE} inline; {$endif}
379

380
function  ZDeflate(var stream: TZStreamRec; flush: TZFlush): Integer;
381
  {$ifdef GLS_INLINE} inline; {$endif}
382

383
function  ZDeflateEnd(var stream: TZStreamRec): Integer;
384
  {$ifdef GLS_INLINE} inline; {$endif}
385

386
function  ZDeflateReset(var stream: TZStreamRec): Integer;
387
  {$ifdef GLS_INLINE} inline; {$endif}
388

389
{** zlib inflate routines ***************************************************}
390

391
function  ZInflateInit(var stream: TZStreamRec): Integer;
392
  {$ifdef GLS_INLINE} inline; {$endif}
393

394
function  ZInflateInit2(var stream: TZStreamRec;
395
  windowBits: Integer): Integer;
396
  {$ifdef GLS_INLINE} inline; {$endif}
397

398
function  ZInflate(var stream: TZStreamRec; flush: TZFlush): Integer;
399
  {$ifdef GLS_INLINE} inline; {$endif}
400

401
function  ZInflateEnd(var stream: TZStreamRec): Integer;
402
  {$ifdef GLS_INLINE} inline; {$endif}
403

404
function  ZInflateReset(var stream: TZStreamRec): Integer;
405
  {$ifdef GLS_INLINE} inline; {$endif}
406

407
{** zlib checksum routines **************************************************}
408

409
function  ZAdler32(adler: Longint; const buffer; size: Integer): Longint;
410
  {$ifdef GLS_INLINE} inline; {$endif}
411

412
function  ZCrc32(crc: Longint; const buffer; size: Integer): Longint;
413
  {$ifdef GLS_INLINE} inline; {$endif}
414

415
{** zlib custom routines ****************************************************}
416

417
procedure ZDeflateEx(var stream: TZStreamRec; param: Pointer;
418
  read: TZReadFunction; write: TZWriteFunction; flush: TZFlush);
419

420
procedure ZInflateEx(var stream: TZStreamRec; param: Pointer;
421
  read: TZReadFunction; write: TZWriteFunction; flush: TZFlush);
422

423
{*****************************************************************************
424
*  ZCompress                                                                 *
425
*                                                                            *
426
*  pre-conditions                                                            *
427
*    inBuffer  = pointer to uncompressed data                                *
428
*    inSize    = size of inBuffer (bytes)                                    *
429
*    outBuffer = pointer (unallocated)                                       *
430
*    level     = compression level                                           *
431
*                                                                            *
432
*  post-conditions                                                           *
433
*    outBuffer = pointer to compressed data (allocated)                      *
434
*    outSize   = size of outBuffer (bytes)                                   *
435
*****************************************************************************}
436

437
procedure ZCompress(const inBuffer: Pointer; inSize: Integer;
438
  out outBuffer: Pointer; out outSize: Integer;
439
  level: TZCompressionLevel = zcDefault);
440

441
{*****************************************************************************
442
*  ZCompress2                                                                *
443
*                                                                            *
444
*  pre-conditions                                                            *
445
*    inBuffer   = pointer to uncompressed data                               *
446
*    inSize     = size of inBuffer (bytes)                                   *
447
*    outBuffer  = pointer (unallocated)                                      *
448
*    level      = compression level                                          *
449
*    method     = compression method                                         *
450
*    windowBits = window bits                                                *
451
*    memLevel   = memory level                                               *
452
*    strategy   = compression strategy                                       *
453
*                                                                            *
454
*  post-conditions                                                           *
455
*    outBuffer = pointer to compressed data (allocated)                      *
456
*    outSize   = size of outBuffer (bytes)                                   *
457
*****************************************************************************}
458

459
procedure ZCompress2(const inBuffer: Pointer; inSize: Integer;
460
  out outBuffer: Pointer; out outSize: Integer; level: TZCompressionLevel;
461
  windowBits, memLevel: Integer; strategy: TZStrategy);
462

463
{*****************************************************************************
464
*  ZDecompress                                                               *
465
*                                                                            *
466
*  pre-conditions                                                            *
467
*    inBuffer    = pointer to compressed data                                *
468
*    inSize      = size of inBuffer (bytes)                                  *
469
*    outBuffer   = pointer (unallocated)                                     *
470
*    outEstimate = estimated size of uncompressed data (bytes)               *
471
*                                                                            *
472
*  post-conditions                                                           *
473
*    outBuffer = pointer to decompressed data (allocated)                    *
474
*    outSize   = size of outBuffer (bytes)                                   *
475
*****************************************************************************}
476

477
procedure ZDecompress(const inBuffer: Pointer; inSize: Integer;
478
 out outBuffer: Pointer; out outSize: Integer; outEstimate: Integer = 0);
479

480
{*****************************************************************************
481
*  ZDecompress2                                                              *
482
*                                                                            *
483
*  pre-conditions                                                            *
484
*    inBuffer    = pointer to compressed data                                *
485
*    inSize      = size of inBuffer (bytes)                                  *
486
*    outBuffer   = pointer (unallocated)                                     *
487
*    windowBits  = window bits                                               *
488
*    outEstimate = estimated size of uncompressed data (bytes)               *
489
*                                                                            *
490
*  post-conditions                                                           *
491
*    outBuffer = pointer to decompressed data (allocated)                    *
492
*    outSize   = size of outBuffer (bytes)                                   *
493
*****************************************************************************}
494

495
procedure ZDecompress2(const inBuffer: Pointer; inSize: Integer;
496
 out outBuffer: Pointer; out outSize: Integer; windowBits: Integer;
497
 outEstimate: Integer = 0);
498

499
{** string routines *********************************************************}
500

501
{*****************************************************************************
502
*  ZCompressStr                                                              *
503
*                                                                            *
504
*  pre-conditions                                                            *
505
*    s     = uncompressed data string                                        *
506
*    level = compression level                                               *
507
*                                                                            *
508
*  return                                                                    *
509
*    compressed data string                                                  *
510
*****************************************************************************}
511

512
function  ZCompressStr(const s: AnsiString;
513
  level: TZCompressionLevel = zcDefault): RawByteString;
514

515
procedure ZCompressString(var result: RawByteString; const s: AnsiString;
516
  level: TZCompressionLevel = zcDefault); overload;
517

518
procedure ZCompressString(var result: RawByteString; const s: UnicodeString;
519
  level: TZCompressionLevel = zcDefault); overload;
520

521
{*****************************************************************************
522
*  ZCompressStrEx                                                            *
523
*                                                                            *
524
*  pre-conditions                                                            *
525
*    s     = uncompressed data string                                        *
526
*    level = compression level                                               *
527
*                                                                            *
528
*  return                                                                    *
529
*    compressed data string with 4 byte (integer) header indicating          *
530
*    original uncompressed data length                                       *
531
*****************************************************************************}
532

533
function  ZCompressStrEx(const s: AnsiString;
534
  level: TZCompressionLevel = zcDefault): RawByteString;
535

536
procedure ZCompressStringEx(var result: RawByteString; const s: AnsiString;
537
  level: TZCompressionLevel = zcDefault); overload;
538

539
procedure ZCompressStringEx(var result: RawByteString; const s: UnicodeString;
540
  level: TZCompressionLevel = zcDefault); overload;
541

542
{*****************************************************************************
543
*  ZCompressStr2                                                             *
544
*                                                                            *
545
*  pre-conditions                                                            *
546
*    s          = uncompressed data string                                   *
547
*    level      = compression level                                          *
548
*    windowBits = window bits                                                *
549
*    memLevel   = memory level                                               *
550
*    strategy   = compression strategy                                       *
551
*                                                                            *
552
*  return                                                                    *
553
*    compressed data string                                                  *
554
*****************************************************************************}
555

556
function  ZCompressStr2(const s: AnsiString; level: TZCompressionLevel;
557
  windowBits, memLevel: Integer; strategy: TZStrategy): RawByteString;
558

559
procedure ZCompressString2(var result: RawByteString; const s: AnsiString;
560
  level: TZCompressionLevel; windowBits, memLevel: Integer;
561
  strategy: TZStrategy); overload;
562

563
procedure ZCompressString2(var result: RawByteString; const s: UnicodeString;
564
  level: TZCompressionLevel; windowBits, memLevel: Integer;
565
  strategy: TZStrategy); overload;
566

567
{*****************************************************************************
568
*  ZCompressStrWeb                                                           *
569
*                                                                            *
570
*  pre-conditions                                                            *
571
*    s = uncompressed data string                                            *
572
*                                                                            *
573
*  return                                                                    *
574
*    compressed data string                                                  *
575
*****************************************************************************}
576

577
function  ZCompressStrWeb(const s: AnsiString): RawByteString;
578

579
procedure ZCompressStringWeb(var result: RawByteString; const s: AnsiString);
580
  overload;
581

582
procedure  ZCompressStringWeb(var result: RawByteString;
583
  const s: UnicodeString); overload;
584

585
{*****************************************************************************
586
*  ZDecompressStr                                                            *
587
*                                                                            *
588
*  pre-conditions                                                            *
589
*    s = compressed data string                                              *
590
*                                                                            *
591
*  return                                                                    *
592
*    uncompressed data string                                                *
593
*****************************************************************************}
594

595
function  ZDecompressStr(const s: RawByteString): AnsiString;
596

597
procedure ZDecompressString(var result: AnsiString; const s: RawByteString);
598
  overload;
599

600
procedure ZDecompressString(var result: UnicodeString;
601
  const s: RawByteString); overload;
602

603
{*****************************************************************************
604
*  ZDecompressStrEx                                                          *
605
*                                                                            *
606
*  pre-conditions                                                            *
607
*    s = compressed data string with 4 byte (integer) header indicating      *
608
*        original uncompressed data length                                   *
609
*                                                                            *
610
*  return                                                                    *
611
*    uncompressed data string                                                *
612
*****************************************************************************}
613

614
function  ZDecompressStrEx(const s: RawByteString): AnsiString;
615

616
procedure ZDecompressStringEx(var result: AnsiString; const s: RawByteString);
617
  overload;
618

619
procedure ZDecompressStringEx(var result: UnicodeString;
620
  const s: RawByteString); overload;
621

622
{*****************************************************************************
623
*  ZDecompressStr2                                                           *
624
*                                                                            *
625
*  pre-conditions                                                            *
626
*    s          = compressed data string                                     *
627
*    windowBits = window bits                                                *
628
*                                                                            *
629
*  return                                                                    *
630
*    uncompressed data string                                                *
631
*****************************************************************************}
632

633
function  ZDecompressStr2(const s: RawByteString;
634
  windowBits: Integer): AnsiString;
635

636
procedure ZDecompressString2(var result: AnsiString; const s: RawByteString;
637
  windowBits: Integer); overload;
638

639
procedure ZDecompressString2(var result: UnicodeString;
640
  const s: RawByteString; windowBits: Integer); overload;
641

642
{** stream routines *********************************************************}
643

644
procedure ZCompressStream(inStream, outStream: TStream;
645
  level: TZCompressionLevel = zcDefault);
646

647
procedure ZCompressStream2(inStream, outStream: TStream;
648
  level: TZCompressionLevel; windowBits, memLevel: Integer;
649
  strategy: TZStrategy);
650

651
procedure ZCompressStreamWeb(inStream, outStream: TStream);
652

653
procedure ZDecompressStream(inStream, outStream: TStream);
654

655
procedure ZDecompressStream2(inStream, outStream: TStream;
656
  windowBits: Integer);
657

658
{****************************************************************************}
659

660
type
661
  EZLibErrorClass = class of EZlibError;
662

663
  EZLibError = class(Exception)
664
  private
665
    FErrorCode: Integer;
666
  public
667
    constructor Create(code: Integer; const dummy: String = ''); overload;
668
    constructor Create(error: TZError; const dummy: String = ''); overload;
669

670
    property ErrorCode: Integer read FErrorCode write FErrorCode;
671
  end;
672

673
  EZCompressionError = class(EZLibError);
674
  EZDecompressionError = class(EZLibError);
675

676
implementation
677

678
const
679
  SZInvalid = 'Invalid ZStream operation!';
680

681
{****************************************************************************}
682

683
function ZCompressCheck(code: Integer): Integer;
684
begin
685
  result := code;
686

687
  if code < 0 then
688
  begin
689
    raise EZCompressionError.Create(code);
690
  end;
691
end;
692

693
function ZDecompressCheck(code: Integer; raiseBufferError: Boolean = True): Integer;
694
begin
695
  Result := code;
696

697
  if code < 0 then
698
  begin
699
    if (code <> Z_BUF_ERROR) or raiseBufferError then
700
    begin
701
      raise EZDecompressionError.Create(code);
702
    end;
703
  end;
704
end;
705

706
{** zlib deflate routines ***************************************************}
707

708
function ZDeflateInit(var stream: TZStreamRec;
709
  level: TZCompressionLevel): Integer;
710
begin
711
  result := deflateInit_(stream, ZLevels[level], ZLIB_VERSION,
712
    SizeOf(TZStreamRec));
713
end;
714

715
function ZDeflateInit2(var stream: TZStreamRec;
716
  level: TZCompressionLevel; windowBits, memLevel: Integer;
717
  strategy: TZStrategy): Integer;
718
begin
719
  result := deflateInit2_(stream, ZLevels[level], Z_DEFLATED, windowBits,
720
    memLevel, ZStrategies[strategy], ZLIB_VERSION, SizeOf(TZStreamRec));
721
end;
722

723
function ZDeflate(var stream: TZStreamRec; flush: TZFlush): Integer;
724
begin
725
  result := deflate(stream, ZFlushes[flush]);
726
end;
727

728
function ZDeflateEnd(var stream: TZStreamRec): Integer;
729
begin
730
  result := deflateEnd(stream);
731
end;
732

733
function ZDeflateReset(var stream: TZStreamRec): Integer;
734
begin
735
  result := deflateReset(stream);
736
end;
737

738
{** zlib inflate routines ***************************************************}
739

740
function ZInflateInit(var stream: TZStreamRec): Integer;
741
begin
742
  result := inflateInit_(stream, ZLIB_VERSION, SizeOf(TZStreamRec));
743
end;
744

745
function ZInflateInit2(var stream: TZStreamRec;
746
  windowBits: Integer): Integer;
747
begin
748
  result := inflateInit2_(stream, windowBits, ZLIB_VERSION,
749
    SizeOf(TZStreamRec));
750
end;
751

752
function ZInflate(var stream: TZStreamRec; flush: TZFlush): Integer;
753
begin
754
  result := inflate(stream, ZFlushes[flush]);
755
end;
756

757
function ZInflateEnd(var stream: TZStreamRec): Integer;
758
begin
759
  result := inflateEnd(stream);
760
end;
761

762
function ZInflateReset(var stream: TZStreamRec): Integer;
763
begin
764
  result := inflateReset(stream);
765
end;
766

767
{** zlib checksum routines **************************************************}
768
{$WARNINGS OFF}
769
function ZAdler32(adler: Longint; const buffer; size: Integer): Longint;
770
begin
771
  result := adler32(adler,buffer,size);
772
end;
773

774
function ZCrc32(crc: Longint; const buffer; size: Integer): Longint;
775
begin
776
  result := crc32(crc,buffer,size);
777
end;
778
{$WARNINGS ON}
779
{** zlib extended routines **************************************************}
780

781
procedure ZDeflateEx(var stream: TZStreamRec; param: Pointer;
782
  read: TZReadFunction; write: TZWriteFunction; flush: TZFlush);
783
const
784
  bufferSize = 8192;
785
var
786
  zresult    : Integer;
787
  readBuffer : Array [0..bufferSize - 1] of Byte;
788
  writeBuffer: Array [0..bufferSize - 1] of Byte;
789
  writeSize  : Integer;
790
  flushEx    : TZFlush;
791
begin
792
  if Assigned(read) then
793
  begin
794
    stream.avail_in := read(param, readBuffer, bufferSize);
795
  end
796
  else stream.avail_in := 0;
797

798
  repeat
799
    stream.next_in := @readBuffer;
800

801
    repeat
802
      stream.avail_out := bufferSize;
803
      stream.next_out := @writeBuffer;
804

805
      flushEx := flush;
806

807
      if (flushEx = zfFinish) and (stream.avail_in = bufferSize) then
808
      begin
809
        flushEx := zfNoFlush;
810
      end;
811

812
      zresult := ZCompressCheck(ZDeflate(stream, flushEx));
813

814
      writeSize := bufferSize - stream.avail_out;
815

816
      write(param, writeBuffer, writeSize);
817
    until stream.avail_out > 0;
818

819
    //assert: stream.avail_in = 0
820

821
    if (zresult <> Z_STREAM_END) and Assigned(read) then
822
    begin
823
      stream.avail_in := read(param, readBuffer, bufferSize);
824
    end;
825
  until (stream.avail_in = 0) and (flush = flushEx);
826
end;
827

828
procedure ZInflateEx(var stream: TZStreamRec; param: Pointer;
829
  read: TZReadFunction; write: TZWriteFunction; flush: TZFlush);
830
const
831
  bufferSize = 8192;
832
var
833
  zresult    : Integer;
834
  readBuffer : Array [0..bufferSize - 1] of Byte;
835
  writeBuffer: Array [0..bufferSize - 1] of Byte;
836
  writeSize  : Integer;
837
begin
838
  if Assigned(read) then
839
  begin
840
    stream.avail_in := read(param, readBuffer, bufferSize);
841
  end
842
  else stream.avail_in := 0;
843

844
  zresult := Z_OK;
845

846
  while (zresult <> Z_STREAM_END) and (stream.avail_in > 0) do
847
  begin
848
    stream.next_in := @readBuffer;
849

850
    repeat
851
      stream.avail_out := bufferSize;
852
      stream.next_out := @writeBuffer;
853

854
      zresult := ZDecompressCheck(ZInflate(stream, flush), False);
855

856
      writeSize := bufferSize - stream.avail_out;
857

858
      write(param, writeBuffer, writeSize);
859
    until stream.avail_out > 0;
860

861
    if (zresult <> Z_STREAM_END) and Assigned(read) then
862
    begin
863
      stream.avail_in := read(param, readBuffer, bufferSize);
864
    end;
865
  end;
866
end;
867

868
{** private buffer routines *************************************************}
869

870
type
871
  PZBufferParam = ^TZBufferParam;
872
  TZBufferParam = packed record
873
    InBuffer   : Pointer;
874
    InPosition : Integer;
875
    InSize     : Integer;
876
    OutBuffer  : Pointer;
877
    OutPosition: Integer;
878
    OutSize    : Integer;
879
  end;
880

881
function ZBufferRead(p: Pointer; var buffer; size: Integer): Integer;
882
var
883
  param: PZBufferParam;
884
begin
885
  param := PZBufferParam(p);
886

887
  result := param^.InSize - param^.InPosition;
888
  if result > size then result := size;
889

890
  Move(Pointer(PtrUInt(param^.InBuffer) + PtrUInt(param^.InPosition))^, buffer, result);
891

892
  Inc(param^.InPosition, result);
893
end;
894

895
function ZBufferWrite(p: Pointer; const buffer; size: Integer): Integer;
896
var
897
  param: PZBufferParam;
898
begin
899
  param := PZBufferParam(p);
900

901
  if param^.OutPosition + size > param^.OutSize then
902
  begin
903
    param^.OutSize := param^.OutPosition + size;
904

905
    ReallocMem(Pointer(param^.OutBuffer), param^.OutSize);
906
  end;
907

908
  Move(buffer, Pointer(PtrUInt(param^.OutBuffer) + PtrUInt(param^.OutPosition))^, size);
909

910
  Inc(param^.OutPosition, size);
911

912
  result := size;
913
end;
914

915
procedure ZInternalCompressEx(var zstream: TZStreamRec; const inBuffer: Pointer;
916
  inSize: Integer; out outBuffer: Pointer; out outSize: Integer);
917
var
918
  param: TZBufferParam;
919
begin
920
  FillChar(param, SizeOf(TZBufferParam), 0);
921

922
  outBuffer := Nil;
923
  outSize := 0;
924

925
  param.InBuffer := inBuffer;
926
  param.InSize := inSize;
927

928
  try
929
    ZDeflateEx(zstream, @param, @ZBufferRead, @ZBufferWrite, zfFinish);
930

931
    ZCompressCheck(ZDeflateEnd(zstream));
932

933
    outBuffer := param.OutBuffer;
934
    outSize := param.OutSize;
935
  except
936
    FreeMem(param.OutBuffer);
937

938
    raise;
939
  end;
940
end;
941

942
procedure ZInternalDecompressEx(zstream: TZStreamRec; const inBuffer: Pointer;
943
  inSize: Integer; out outBuffer: Pointer; out outSize: Integer;
944
  outEstimate: Integer);
945
var
946
  param: TZBufferParam;
947
begin
948
  FillChar(param, SizeOf(TZBufferParam), 0);
949

950
  outBuffer := Nil;
951
  outSize := 0;
952

953
  param.InBuffer := inBuffer;
954
  param.InSize := inSize;
955

956
  if outEstimate > 0 then
957
  begin
958
    GetMem(param.OutBuffer, outEstimate);
959

960
    param.OutSize := outEstimate;
961
  end;
962

963
  try
964
    ZInflateEx(zstream, @param, @ZBufferRead, @ZBufferWrite, zfNoFlush);
965

966
    ZDecompressCheck(ZInflateEnd(zstream));
967

968
    outBuffer := param.OutBuffer;
969
    outSize := param.OutSize;
970
  except
971
    FreeMem(param.OutBuffer);
972

973
    raise;
974
  end;
975
end;
976

977
procedure ZInternalCompress(var zstream: TZStreamRec; const inBuffer: Pointer;
978
  inSize: Integer; out outBuffer: Pointer; out outSize: Integer);
979
const
980
  delta = 256;
981
var
982
  zresult: Integer;
983
begin
984
  outSize := ((inSize + (inSize div 10) + 12) + 255) and not 255;
985

986
  outBuffer := Nil;
987

988
  try
989
    try
990
      zstream.next_in := inBuffer;
991
      zstream.avail_in := inSize;
992

993
      repeat
994
        ReallocMem(outBuffer, outSize);
995

996
        zstream.next_out := Pointer(PtrUInt(outBuffer) + PtrUInt(zstream.total_out));
997
        zstream.avail_out := outSize - zstream.total_out;
998

999
        zresult := ZCompressCheck(ZDeflate(zstream, zfNoFlush));
1000

1001
        Inc(outSize, delta);
1002
      until (zresult = Z_STREAM_END) or (zstream.avail_in = 0);
1003

1004
      while zresult <> Z_STREAM_END do
1005
      begin
1006
        ReallocMem(outBuffer, outSize);
1007

1008
        zstream.next_out := Pointer(PtrUInt(outBuffer) + PtrUInt(zstream.total_out));
1009
        zstream.avail_out := outSize - zstream.total_out;
1010

1011
        zresult := ZCompressCheck(ZDeflate(zstream, zfFinish));
1012

1013
        Inc(outSize, delta);
1014
      end;
1015
    finally
1016
      ZCompressCheck(ZDeflateEnd(zstream));
1017
    end;
1018

1019
    ReallocMem(outBuffer, zstream.total_out);
1020

1021
    outSize := zstream.total_out;
1022
  except
1023
    FreeMem(outBuffer);
1024
    raise;
1025
  end;
1026
end;
1027

1028
procedure ZInternalDecompress(zstream: TZStreamRec; const inBuffer: Pointer;
1029
  inSize: Integer; out outBuffer: Pointer; out outSize: Integer;
1030
  outEstimate: Integer);
1031
var
1032
  zresult: Integer;
1033
  delta  : Integer;
1034
begin
1035
  delta := (inSize + 255) and not 255;
1036

1037
  if outEstimate = 0 then outSize := delta
1038
  else outSize := outEstimate;
1039

1040
  outBuffer := Nil;
1041

1042
  try
1043
    try
1044
      zresult := Z_OK;
1045

1046
      zstream.avail_in := inSize;
1047
      zstream.next_in := inBuffer;
1048

1049
      while (zresult <> Z_STREAM_END) and (zstream.avail_in > 0) do
1050
      begin
1051
        repeat
1052
          ReallocMem(outBuffer, outSize);
1053

1054
          zstream.next_out := Pointer(PtrUInt(outBuffer) + PtrUInt(zstream.total_out));
1055
          zstream.avail_out := outSize - zstream.total_out;
1056

1057
          zresult := ZDecompressCheck(ZInflate(zstream, zfNoFlush), False);
1058

1059
          Inc(outSize, delta);
1060
        until (zresult = Z_STREAM_END) or (zstream.avail_out > 0);
1061
      end;
1062
    finally
1063
      ZDecompressCheck(ZInflateEnd(zstream));
1064
    end;
1065

1066
    ReallocMem(outBuffer, zstream.total_out);
1067

1068
    outSize := zstream.total_out;
1069
  except
1070
    if Assigned(outBuffer) then FreeMem(outBuffer);
1071

1072
    raise;
1073
  end;
1074
end;
1075

1076
{** buffer routines *********************************************************}
1077

1078
procedure ZCompress(const inBuffer: Pointer; inSize: Integer;
1079
  out outBuffer: Pointer; out outSize: Integer;
1080
  level: TZCompressionLevel);
1081
var
1082
  zstream: TZStreamRec;
1083
begin
1084
  FillChar(zstream, SizeOf(TZStreamRec), 0);
1085

1086
  ZCompressCheck(ZDeflateInit(zstream, level));
1087

1088
  ZInternalCompress(zstream, inBuffer, inSize, outBuffer, outSize);
1089
end;
1090

1091
procedure ZCompress2(const inBuffer: Pointer; inSize: Integer;
1092
  out outBuffer: Pointer; out outSize: Integer; level: TZCompressionLevel;
1093
  windowBits, memLevel: Integer; strategy: TZStrategy);
1094
var
1095
  zstream: TZStreamRec;
1096
begin
1097
  FillChar(zstream, SizeOf(TZStreamRec), 0);
1098

1099
  ZCompressCheck(ZDeflateInit2(zstream, level, windowBits, memLevel,
1100
    strategy));
1101

1102
  ZInternalCompress(zstream, inBuffer, inSize, outBuffer, outSize);
1103
end;
1104

1105
procedure ZDecompress(const inBuffer: Pointer; inSize: Integer;
1106
  out outBuffer: Pointer; out outSize: Integer; outEstimate: Integer);
1107
var
1108
  zstream: TZStreamRec;
1109
begin
1110
  FillChar(zstream, SizeOf(TZStreamRec), 0);
1111

1112
  ZDecompressCheck(ZInflateInit(zstream));
1113

1114
  ZInternalDecompress(zstream, inBuffer, inSize, outBuffer, outSize,
1115
    outEstimate);
1116
end;
1117

1118
procedure ZDecompress2(const inBuffer: Pointer; inSize: Integer;
1119
  out outBuffer: Pointer; out outSize: Integer; windowBits: Integer;
1120
  outEstimate: Integer);
1121
var
1122
  zstream: TZStreamRec;
1123
begin
1124
  FillChar(zstream, SizeOf(TZStreamRec), 0);
1125

1126
  ZDecompressCheck(ZInflateInit2(zstream, windowBits));
1127

1128
  ZInternalDecompress(zstream, inBuffer, inSize, outBuffer, outSize,
1129
    outEstimate);
1130
end;
1131

1132
{** string routines *********************************************************}
1133

1134
function ZCompressStr(const s: AnsiString;
1135
  level: TZCompressionLevel): RawByteString;
1136
begin
1137
  ZCompressString(result, s, level);
1138
end;
1139

1140
procedure ZCompressString(var result: RawByteString; const s: AnsiString;
1141
  level: TZCompressionLevel);
1142
var
1143
  buffer: Pointer;
1144
  size  : Integer;
1145
begin
1146
  ZCompress(Pointer(s), Length(s), buffer, size, level);
1147

1148
  SetLength(result, size);
1149

1150
  Move(buffer^, result[1], size);
1151

1152
  FreeMem(buffer);
1153
end;
1154

1155
procedure ZCompressString(var result: RawByteString; const s: UnicodeString;
1156
  level: TZCompressionLevel);
1157
var
1158
  buffer: Pointer;
1159
  size  : Integer;
1160
begin
1161
  ZCompress(Pointer(s), Length(s) * SizeOf(UnicodeChar), buffer, size, level);
1162

1163
  SetLength(result, size);
1164

1165
  Move(buffer^, result[1], size);
1166

1167
  FreeMem(buffer);
1168
end;
1169

1170
function ZCompressStrEx(const s: AnsiString;
1171
  level: TZCompressionLevel): RawByteString;
1172
begin
1173
  ZCompressStringEx(result, s, level);
1174
end;
1175

1176
procedure ZCompressStringEx(var result: RawByteString; const s: AnsiString;
1177
  level: TZCompressionLevel);
1178
var
1179
  buffer: Pointer;
1180
  size  : Integer;
1181
begin
1182
  ZCompress(Pointer(s), Length(s), buffer, size, level);
1183

1184
  SetLength(result, size + SizeOf(Integer));
1185

1186
  Move(buffer^, result[5], size);
1187

1188
  size := Length(s);
1189

1190
  Move(size, result[1], SizeOf(Integer));
1191

1192
  FreeMem(buffer);
1193
end;
1194

1195
procedure ZCompressStringEx(var result: RawByteString; const s: UnicodeString;
1196
  level: TZCompressionLevel);
1197
var
1198
  buffer: Pointer;
1199
  size  : Integer;
1200
begin
1201
  ZCompress(Pointer(s), Length(s) * SizeOf(UnicodeChar), buffer, size, level);
1202

1203
  SetLength(result, size + SizeOf(Integer));
1204

1205
  Move(buffer^, result[5], size);
1206

1207
  size := Length(s) * SizeOf(UnicodeChar);
1208

1209
  Move(size, result[1], SizeOf(Integer));
1210

1211
  FreeMem(buffer);
1212
end;
1213

1214
function ZCompressStr2(const s: AnsiString; level: TZCompressionLevel;
1215
  windowBits, memLevel: Integer; strategy: TZStrategy): RawByteString;
1216
begin
1217
  ZCompressString2(result, s, level, windowBits, memLevel, strategy);
1218
end;
1219

1220
procedure ZCompressString2(var result: RawByteString; const s: AnsiString;
1221
  level: TZCompressionLevel; windowBits, memLevel: Integer;
1222
  strategy: TZStrategy);
1223
var
1224
  buffer: Pointer;
1225
  size  : Integer;
1226
begin
1227
  ZCompress2(Pointer(s), Length(s), buffer, size, level, windowBits,
1228
    memLevel, strategy);
1229

1230
  SetLength(result, size);
1231

1232
  Move(buffer^, result[1], size);
1233

1234
  FreeMem(buffer);
1235
end;
1236

1237
procedure ZCompressString2(var result: RawByteString; const s: UnicodeString;
1238
  level: TZCompressionLevel; windowBits, memLevel: Integer;
1239
  strategy: TZStrategy);
1240
var
1241
  buffer: Pointer;
1242
  size  : Integer;
1243
begin
1244
  ZCompress2(Pointer(s), Length(s) * SizeOf(UnicodeChar), buffer, size,
1245
    level, windowBits, memLevel, strategy);
1246

1247
  SetLength(result, size);
1248

1249
  Move(buffer^, result[1], size);
1250

1251
  FreeMem(buffer);
1252
end;
1253

1254
function ZCompressStrWeb(const s: AnsiString): RawByteString;
1255
begin
1256
  ZCompressStringWeb(result, s);
1257
end;
1258

1259
procedure ZCompressStringWeb(var result: RawByteString; const s: AnsiString);
1260
begin
1261
  ZCompressString2(result, s, zcFastest, -15, 9, zsDefault);
1262
end;
1263

1264
procedure ZCompressStringWeb(var result: RawBytestring;
1265
  const s: UnicodeString);
1266
begin
1267
  ZCompressString2(result, s, zcFastest, -15, 9, zsDefault);
1268
end;
1269

1270
function ZDecompressStr(const s: RawByteString): AnsiString;
1271
begin
1272
  ZDecompressString(result, s);
1273
end;
1274

1275
procedure ZDecompressString(var result: AnsiString;
1276
  const s: RawByteString);
1277
var
1278
  buffer: Pointer;
1279
  size  : Integer;
1280
begin
1281
  ZDecompress(Pointer(s), Length(s), buffer, size);
1282

1283
  SetLength(result, size);
1284

1285
  Move(buffer^, result[1], size);
1286

1287
  FreeMem(buffer);
1288
end;
1289

1290
procedure ZDecompressString(var result: UnicodeString;
1291
  const s: RawByteString);
1292
var
1293
  buffer: Pointer;
1294
  size  : Integer;
1295
begin
1296
  ZDecompress(Pointer(s), Length(s), buffer, size);
1297

1298
  SetLength(result, size div SizeOf(UnicodeChar));
1299

1300
  Move(buffer^, result[1], size);
1301

1302
  FreeMem(buffer);
1303
end;
1304

1305
function ZDecompressStrEx(const s: RawByteString): AnsiString;
1306
begin
1307
  ZDecompressStringEx(result, s);
1308
end;
1309

1310
procedure ZDecompressStringEx(var result: AnsiString; const s: RawByteString);
1311
var
1312
  buffer  : Pointer;
1313
  size    : Integer;
1314
  data    : AnsiString;
1315
  dataSize: Integer;
1316
begin
1317
  Move(s[1], size, SizeOf(Integer));
1318

1319
  dataSize := Length(s) - SizeOf(Integer);
1320

1321
  SetLength(data, dataSize);
1322

1323
  Move(s[5], data[1], dataSize);
1324

1325
  ZDecompress(Pointer(data), dataSize, buffer, size, size);
1326

1327
  SetLength(result, size);
1328

1329
  Move(buffer^, result[1], size);
1330

1331
  FreeMem(buffer);
1332
end;
1333

1334
procedure ZDecompressStringEx(var result: UnicodeString;
1335
  const s: RawByteString);
1336
var
1337
  buffer  : Pointer;
1338
  size    : Integer;
1339
  data    : AnsiString;
1340
  dataSize: Integer;
1341
begin
1342
  Move(s[1], size, SizeOf(Integer));
1343

1344
  dataSize := Length(s) - SizeOf(Integer);
1345

1346
  SetLength(data, dataSize);
1347

1348
  Move(s[5], data[1], dataSize);
1349

1350
  ZDecompress(Pointer(data), dataSize, buffer, size, size);
1351

1352
  SetLength(result, size div SizeOf(UnicodeChar));
1353

1354
  Move(buffer^, result[1], size);
1355

1356
  FreeMem(buffer);
1357
end;
1358

1359
function ZDecompressStr2(const s: RawByteString;
1360
  windowBits: Integer): AnsiString;
1361
begin
1362
  ZDecompressString2(result, s, windowBits);
1363
end;
1364

1365
procedure ZDecompressString2(var result: AnsiString; const s: RawByteString;
1366
  windowBits: Integer);
1367
var
1368
  buffer: Pointer;
1369
  size  : Integer;
1370
begin
1371
  ZDecompress2(Pointer(s), Length(s), buffer, size, windowBits);
1372

1373
  SetLength(result, size);
1374

1375
  Move(buffer^, result[1], size);
1376

1377
  FreeMem(buffer);
1378
end;
1379

1380
procedure ZDecompressString2(var result: UnicodeString;
1381
  const s: RawByteString; windowBits: Integer);
1382
var
1383
  buffer: Pointer;
1384
  size  : Integer;
1385
begin
1386
  ZDecompress2(Pointer(s), Length(s), buffer, size, windowBits);
1387

1388
  SetLength(result, size div SizeOf(UnicodeChar));
1389

1390
  Move(buffer^, result[1], size);
1391

1392
  FreeMem(buffer);
1393
end;
1394

1395
{** private stream routines *************************************************}
1396

1397
type
1398
  PZStreamParam = ^TZStreamParam;
1399
  TZStreamParam = packed record
1400
    InStream   : TStream;
1401
    OutStream  : TStream;
1402
  end;
1403

1404
function ZStreamRead(p: Pointer; var buffer; size: Integer): Integer;
1405
var
1406
  param: PZStreamParam;
1407
begin
1408
  param := PZStreamParam(p);
1409

1410
  result := param^.InStream.Read(buffer, size);
1411
end;
1412

1413
function ZStreamWrite(p: Pointer; const buffer; size: Integer): Integer;
1414
var
1415
  param: PZStreamParam;
1416
begin
1417
  param := PZStreamParam(p);
1418

1419
  result := param^.OutStream.Write(buffer, size);
1420
end;
1421

1422
procedure ZInternalCompressStreamEx(zstream: TZStreamRec; inStream,
1423
  outStream: TStream);
1424
var
1425
  param: TZStreamParam;
1426
begin
1427
  FillChar(param, SizeOf(TZStreamParam), 0);
1428

1429
  param.InStream := inStream;
1430
  param.OutStream := outStream;
1431

1432
  ZDeflateEx(zstream, @param, @ZBufferRead, @ZBufferWrite, zfFinish);
1433

1434
  ZCompressCheck(ZDeflateEnd(zstream));
1435
end;
1436

1437
procedure ZInternalDecompressStreamEx(zstream: TZStreamRec; inStream,
1438
  outStream: TStream);
1439
var
1440
  param: TZStreamParam;
1441
begin
1442
  FillChar(param, SizeOf(TZStreamParam), 0);
1443

1444
  param.InStream := inStream;
1445
  param.OutStream := outStream;
1446

1447
  ZInflateEx(zstream, @param, @ZBufferRead, @ZBufferWrite, zfNoFlush);
1448

1449
  ZDecompressCheck(ZInflateEnd(zstream));
1450
end;
1451

1452
procedure ZInternalCompressStream(zstream: TZStreamRec; inStream,
1453
  outStream: TStream);
1454
const
1455
  bufferSize = 32768;
1456
var
1457
  zresult  : Integer;
1458
  inBuffer : Array [0..bufferSize-1] of Byte;
1459
  outBuffer: Array [0..bufferSize-1] of Byte;
1460
  outSize  : Integer;
1461
begin
1462
  zresult := Z_STREAM_END;
1463

1464
  zstream.avail_in := inStream.Read(inBuffer, bufferSize);
1465

1466
  while zstream.avail_in > 0 do
1467
  begin
1468
    zstream.next_in := @inBuffer;
1469

1470
    repeat
1471
      zstream.next_out := @outBuffer;
1472
      zstream.avail_out := bufferSize;
1473

1474
      zresult := ZCompressCheck(ZDeflate(zstream, zfNoFlush));
1475

1476
      outSize := bufferSize - zstream.avail_out;
1477

1478
      outStream.Write(outBuffer, outSize);
1479
    until (zresult = Z_STREAM_END) or (zstream.avail_in = 0);
1480

1481
    zstream.avail_in := inStream.Read(inBuffer, bufferSize);
1482
  end;
1483

1484
  while zresult <> Z_STREAM_END do
1485
  begin
1486
    zstream.next_out := @outBuffer;
1487
    zstream.avail_out := bufferSize;
1488

1489
    zresult := ZCompressCheck(ZDeflate(zstream, zfFinish));
1490

1491
    outSize := bufferSize - zstream.avail_out;
1492

1493
    outStream.Write(outBuffer, outSize);
1494
  end;
1495

1496
  ZCompressCheck(ZDeflateEnd(zstream));
1497
end;
1498

1499
procedure ZInternalDecompressStream(zstream: TZStreamRec; inStream,
1500
  outStream: TStream);
1501
const
1502
  bufferSize = 32768;
1503
var
1504
  zresult  : Integer;
1505
  inBuffer : Array [0..bufferSize-1] of Byte;
1506
  outBuffer: Array [0..bufferSize-1] of Byte;
1507
  outSize  : Integer;
1508
begin
1509
  try
1510
    zresult := Z_OK;
1511

1512
    zstream.avail_in := inStream.Read(inBuffer, bufferSize);
1513

1514
    while (zresult <> Z_STREAM_END) and (zstream.avail_in > 0) do
1515
    begin
1516
      zstream.next_in := @inBuffer;
1517

1518
      repeat
1519
        zstream.next_out := @outBuffer;
1520
        zstream.avail_out := bufferSize;
1521

1522
        zresult := ZDecompressCheck(ZInflate(zstream, zfNoFlush), False);
1523

1524
        outSize := bufferSize - zstream.avail_out;
1525

1526
        outStream.Write(outBuffer, outSize);
1527
      until (zresult = Z_STREAM_END) or (zstream.avail_out > 0);
1528

1529
      if zstream.avail_in > 0 then
1530
      begin
1531
        inStream.Position := inStream.Position - zstream.avail_in;
1532
      end;
1533

1534
      if zresult <> Z_STREAM_END then
1535
      begin
1536
        zstream.avail_in := inStream.Read(inBuffer, bufferSize);
1537
      end;
1538
    end;
1539
  finally
1540
    ZDecompressCheck(ZInflateEnd(zstream));
1541
  end;
1542
end;
1543

1544
{** stream routines *********************************************************}
1545

1546
procedure ZCompressStream(inStream, outStream: TStream;
1547
  level: TZCompressionLevel);
1548
var
1549
  zstream: TZStreamRec;
1550
begin
1551
  FillChar(zstream, SizeOf(TZStreamRec), 0);
1552

1553
  ZCompressCheck(ZDeflateInit(zstream, level));
1554

1555
  ZInternalCompressStream(zstream, inStream, outStream);
1556
end;
1557

1558
procedure ZCompressStream2(inStream, outStream: TStream;
1559
  level: TZCompressionLevel; windowBits, memLevel: Integer;
1560
  strategy: TZStrategy);
1561
var
1562
  zstream: TZStreamRec;
1563
begin
1564
  FillChar(zstream, SizeOf(TZStreamRec), 0);
1565

1566
  ZCompressCheck(ZDeflateInit2(zstream, level, windowBits, memLevel,
1567
    strategy));
1568

1569
  ZInternalCompressStream(zstream,inStream,outStream);
1570
end;
1571

1572
procedure ZCompressStreamWeb(inStream, outStream: TStream);
1573
begin
1574
  ZCompressStream2(inStream, outStream, zcFastest, -15, 9, zsDefault);
1575
end;
1576

1577
procedure ZDecompressStream(inStream, outStream: TStream);
1578
var
1579
  zstream: TZStreamRec;
1580
begin
1581
  FillChar(zstream, SizeOf(TZStreamRec), 0);
1582

1583
  ZDecompressCheck(ZInflateInit(zstream));
1584

1585
  ZInternalDecompressStream(zstream, inStream, outStream);
1586
end;
1587

1588
procedure ZDecompressStream2(inStream, outStream: TStream;
1589
  windowBits: Integer);
1590
var
1591
  zstream: TZStreamRec;
1592
begin
1593
  FillChar(zstream, SizeOf(TZStreamRec), 0);
1594

1595
  ZDecompressCheck(ZInflateInit2(zstream, windowBits));
1596

1597
  ZInternalDecompressStream(zstream, inStream, outStream);
1598
end;
1599

1600
{** TCustomZStream **********************************************************}
1601

1602
constructor TCustomZStream.Create(stream: TStream);
1603
begin
1604
  inherited Create;
1605

1606
  FStream := stream;
1607
  FStreamPos := stream.Position;
1608
end;
1609

1610
function TCustomZStream.StreamRead(var buffer; count: Longint): Longint;
1611
begin
1612
  if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
1613

1614
  result := FStream.Read(buffer,count);
1615

1616
  FStreamPos := FStreamPos + result;
1617
end;
1618

1619
function TCustomZStream.StreamWrite(const buffer; count: Longint): Longint;
1620
begin
1621
  if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
1622

1623
  result := FStream.Write(buffer,count);
1624

1625
  FStreamPos := FStreamPos + result;
1626
end;
1627

1628
function TCustomZStream.StreamSeek(offset: Longint; origin: Word): Longint;
1629
begin
1630
  if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
1631

1632
  result := FStream.Seek(offset,origin);
1633

1634
  FStreamPos := FStream.Position;
1635
end;
1636

1637
procedure TCustomZStream.StreamReadBuffer(var buffer; count: Longint);
1638
begin
1639
  if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
1640

1641
  FStream.ReadBuffer(buffer,count);
1642

1643
  FStreamPos := FStreamPos + count;
1644
end;
1645

1646
procedure TCustomZStream.StreamWriteBuffer(const buffer; count: Longint);
1647
begin
1648
  if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;
1649

1650
  FStream.WriteBuffer(buffer,count);
1651

1652
  FStreamPos := FStreamPos + count;
1653
end;
1654

1655
procedure TCustomZStream.DoProgress;
1656
begin
1657
  if Assigned(FOnProgress) then FOnProgress(Self);
1658
end;
1659

1660
function TCustomZStream.GetStreamPosition: TStreamPos;
1661
begin
1662
  result := FStream.Position;
1663
end;
1664

1665
procedure TCustomZStream.SetStreamPosition(value: TStreamPos);
1666
begin
1667
  FStream.Position := value;
1668
  FStreamPos := FStream.Position;
1669
end;
1670

1671
{** TZCompressionStream *****************************************************}
1672

1673
constructor TZCompressionStream.Create(dest: TStream;
1674
  compressionLevel: TZCompressionLevel);
1675
begin
1676
  inherited Create(dest);
1677

1678
  FZStream.next_out := @FBuffer;
1679
  FZStream.avail_out := SizeOf(FBuffer);
1680

1681
  ZCompressCheck(ZDeflateInit(FZStream, compressionLevel));
1682
end;
1683

1684
constructor TZCompressionStream.Create(dest: TStream;
1685
  compressionLevel: TZCompressionLevel; windowBits, memLevel: Integer;
1686
  strategy: TZStrategy);
1687
begin
1688
  inherited Create(dest);
1689

1690
  FZStream.next_out := @FBuffer;
1691
  FZStream.avail_out := SizeOf(FBuffer);
1692

1693
  ZCompressCheck(ZDeflateInit2(FZStream, compressionLevel, windowBits,
1694
    memLevel, strategy));
1695
end;
1696

1697
destructor TZCompressionStream.Destroy;
1698
begin
1699
  FZStream.next_in := Nil;
1700
  FZStream.avail_in := 0;
1701

1702
  try
1703
    while ZCompressCheck(ZDeflate(FZStream, zfFinish)) <> Z_STREAM_END do
1704
    begin
1705
      StreamWriteBuffer(FBuffer, SizeOf(FBuffer) - FZStream.avail_out);
1706

1707
      FZStream.next_out := @FBuffer;
1708
      FZStream.avail_out := SizeOf(FBuffer);
1709
    end;
1710

1711
    if FZStream.avail_out < SizeOf(FBuffer) then
1712
    begin
1713
      StreamWriteBuffer(FBuffer, SizeOf(FBuffer) - FZStream.avail_out);
1714
    end;
1715
  finally
1716
    ZDeflateEnd(FZStream);
1717
  end;
1718

1719
  inherited Destroy;
1720
end;
1721

1722
function TZCompressionStream.Read(var buffer; count: Longint): Longint;
1723
begin
1724
//  Result:=0;
1725
  raise EZCompressionError.Create(SZInvalid);
1726
end;
1727

1728
function TZCompressionStream.Write(const buffer; count: Longint): Longint;
1729
var
1730
  writeCount: Longint;
1731
begin
1732
  result := count;
1733

1734
  FZStream.next_in := @buffer;
1735
  FZStream.avail_in := count;
1736

1737
  while FZStream.avail_in > 0 do
1738
  begin
1739
    ZCompressCheck(ZDeflate(FZStream, zfNoFlush));
1740

1741
    if FZStream.avail_out = 0 then
1742
    begin
1743
      writeCount := StreamWrite(FBuffer,SizeOf(FBuffer));
1744

1745
      if writeCount = SizeOf(FBuffer) then
1746
      begin
1747
        FZStream.next_out := @FBuffer;
1748
        FZStream.avail_out := SizeOf(FBuffer);
1749

1750
        DoProgress;
1751
      end
1752
      else
1753
      begin
1754
        StreamPosition := StreamPosition - writeCount;
1755

1756
        result := count - FZStream.avail_in;
1757

1758
        FZStream.avail_in := 0;
1759
      end;
1760
    end;
1761
  end;
1762
end;
1763

1764
function TZCompressionStream.Seek(offset: Longint; origin: Word): Longint;
1765
begin
1766
  if (offset = 0) and (origin = soFromCurrent) then
1767
  begin
1768
    result := FZStream.total_in;
1769
  end
1770
  else raise EZCompressionError.Create(SZInvalid);
1771
end;
1772

1773
function TZCompressionStream.GetCompressionRate: Single;
1774
begin
1775
  if FZStream.total_in = 0 then result := 0
1776
  else result := (1.0 - (FZStream.total_out / FZStream.total_in)) * 100.0;
1777
end;
1778

1779
{** TZDecompressionStream ***************************************************}
1780

1781
constructor TZDecompressionStream.Create(source: TStream);
1782
begin
1783
  inherited Create(source);
1784

1785
  FZStream.next_in := @FBuffer;
1786
  FZStream.avail_in := 0;
1787

1788
  ZDecompressCheck(ZInflateInit(FZStream));
1789
end;
1790

1791
constructor TZDecompressionStream.Create(source: TStream;
1792
  windowBits: Integer);
1793
begin
1794
  inherited Create(source);
1795

1796
  FZStream.next_in := @FBuffer;
1797
  FZStream.avail_in := 0;
1798

1799
  ZDecompressCheck(ZInflateInit2(FZStream, windowBits));
1800
end;
1801

1802
destructor TZDecompressionStream.Destroy;
1803
begin
1804
  ZInflateEnd(FZStream);
1805

1806
  inherited Destroy;
1807
end;
1808

1809
function TZDecompressionStream.Read(var buffer; count: Longint): Longint;
1810
var
1811
  zresult: Integer;
1812
begin
1813
  FZStream.next_out := @buffer;
1814
  FZStream.avail_out := count;
1815

1816
  zresult := Z_OK;
1817

1818
  while (FZStream.avail_out > 0) and (zresult <> Z_STREAM_END) do
1819
  begin
1820
    if FZStream.avail_in = 0 then
1821
    begin
1822
      FZStream.avail_in := StreamRead(FBuffer,SizeOf(FBuffer));
1823

1824
      if FZStream.avail_in = 0 then
1825
      begin
1826
        result := count - FZStream.avail_out;
1827

1828
        Exit;
1829
      end;
1830

1831
      FZStream.next_in := @FBuffer;
1832

1833
      DoProgress;
1834
    end;
1835

1836
    zresult := ZDecompressCheck(ZInflate(FZStream, zfNoFlush));
1837
  end;
1838

1839
  if (zresult = Z_STREAM_END) and (FZStream.avail_in > 0) then
1840
  begin
1841
    StreamPosition := StreamPosition - FZStream.avail_in;
1842

1843
    FZStream.avail_in := 0;
1844
  end;
1845

1846
  result := count - FZStream.avail_out;
1847
end;
1848

1849
function TZDecompressionStream.Write(const Buffer; Count: Longint): Longint;
1850
begin
1851
//  Result := 0;
1852
  raise EZDecompressionError.Create(SZInvalid);
1853
end;
1854

1855
function TZDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
1856
var
1857
  buf: Array [0..8191] of Byte;
1858
  i  : Integer;
1859
begin
1860
  if (offset = 0) and (origin = soFromBeginning) then
1861
  begin
1862
    ZDecompressCheck(ZInflateReset(FZStream));
1863

1864
    FZStream.next_in := @FBuffer;
1865
    FZStream.avail_in := 0;
1866

1867
    StreamPosition := 0;
1868
  end
1869
  else if ((offset >= 0) and (origin = soFromCurrent)) or
1870
          (((offset - FZStream.total_out) > 0) and (origin = soFromBeginning)) then
1871
  begin
1872
    if origin = soFromBeginning then Dec(offset, FZStream.total_out);
1873

1874
    if offset > 0 then
1875
    begin
1876
      for i := 1 to offset div SizeOf(buf) do ReadBuffer(buf, SizeOf(buf));
1877
      ReadBuffer(buf, offset mod SizeOf(buf));
1878
    end;
1879
  end
1880
  else if (offset = 0) and (origin = soFromEnd) then
1881
  begin
1882
    while Read(buf, SizeOf(buf)) > 0 do ;
1883
  end
1884
  else raise EZDecompressionError.Create(SZInvalid);
1885

1886
  result := FZStream.total_out;
1887
end;
1888

1889
{** TZCustomBuffer **********************************************************}
1890

1891
constructor TZCustomBuffer.Create;
1892
begin
1893
  inherited Create;
1894

1895
  FillChar(FZStream, SizeOf(TZStreamRec), 0);
1896

1897
  FBuffer := Nil;
1898
  FBufferCapacity := 0;
1899

1900
  FBufferSize := 0;
1901
end;
1902

1903
destructor TZCustomBuffer.Destroy;
1904
begin
1905
  BufferCapacity(0);
1906

1907
  inherited Destroy;
1908
end;
1909

1910
procedure TZCustomBuffer.Clear;
1911
begin
1912
  BufferCapacity(0);
1913

1914
  FBufferSize := 0;
1915
end;
1916

1917
procedure TZCustomBuffer.Flush(flush: TZFlush);
1918
begin
1919
  // to be implemented by descendents as needed
1920
end;
1921

1922
function TZCustomBuffer.Write(const s: AnsiString): Integer;
1923
begin
1924
  result := Write(Pointer(s), Length(s));
1925
end;
1926

1927
function TZCustomBuffer.Read(var buffer: Pointer; size: Integer): Integer;
1928
begin
1929
  result := BufferSize;
1930
  if size < result then result := size;
1931

1932
  BufferRead(buffer, result);
1933
end;
1934

1935
function TZCustomBuffer.Read(var s: AnsiString): Integer;
1936
begin
1937
  SetLength(s, BufferSize);
1938

1939
  result := Read(Pointer(s), Length(s));
1940
end;
1941

1942
procedure TZCustomBuffer.BufferWrite(const buffer: Pointer; size: Integer);
1943
begin
1944
  if size > 0 then
1945
  begin
1946
    BufferCapacity(FBufferSize + size);
1947

1948
    Move(buffer^, Pointer(PtrUInt(FBuffer) + PtrUInt(FBufferSize))^, size);
1949

1950
    Inc(FBufferSize, size);
1951
  end;
1952
end;
1953

1954
procedure TZCustomBuffer.BufferRead(var buffer: Pointer; size: Integer);
1955
begin
1956
  if size > 0 then
1957
  begin
1958
    Move(FBuffer^, buffer^, size);
1959

1960
    Move(Pointer(PtrUInt(FBuffer) + PtrUInt(size))^, FBuffer^, FBufferSize - size);
1961

1962
    Dec(FBufferSize, size);
1963
  end;
1964
end;
1965

1966
procedure TZCustomBuffer.BufferCapacity(capacity: Integer);
1967
const
1968
  delta = 8192; // must be a power of 2
1969
begin
1970
  if capacity > 0 then
1971
  begin
1972
    capacity := (capacity + (delta - 1)) and not (delta - 1);
1973
  end;
1974

1975
  if FBufferCapacity <> capacity then
1976
  begin
1977
    if capacity = 0 then FreeMem(FBuffer)
1978
    else if FBufferCapacity = 0 then GetMem(FBuffer, capacity)
1979
    else ReallocMem(FBuffer, capacity);
1980

1981
    FBufferCapacity := capacity;
1982
  end;
1983
end;
1984

1985
{** TZCompressionBuffer *****************************************************}
1986

1987
constructor TZCompressionBuffer.Create(level: TZCompressionLevel);
1988
begin
1989
  inherited Create;
1990

1991
  ZCompressCheck(ZDeflateInit(FZStream, level));
1992
end;
1993

1994
constructor TZCompressionBuffer.Create(level: TZCompressionLevel;
1995
  windowBits, memLevel: Integer; strategy: TZStrategy);
1996
begin
1997
  inherited Create;
1998

1999
  ZCompressCheck(ZDeflateInit2(FZStream, level, windowBits, memLevel,
2000
    strategy));
2001
end;
2002

2003
destructor TZCompressionBuffer.Destroy;
2004
begin
2005
  ZCompressCheck(ZDeflateEnd(FZStream));
2006

2007
  inherited Destroy;
2008
end;
2009

2010
procedure TZCompressionBuffer.Clear;
2011
begin
2012
  inherited Clear;
2013

2014
  ZCompressCheck(ZDeflateReset(FZStream));
2015
end;
2016

2017
procedure TZCompressionBuffer.Flush(flush: TZFlush);
2018
const
2019
  outSize = 32768;
2020
var
2021
  zresult  : Integer;
2022
  outBuffer: Array [0..outSize - 1] of Byte;
2023
  outCount : Integer;
2024
begin
2025
  FZStream.next_in := Nil;
2026
  FZStream.avail_in := 0;
2027

2028
  repeat
2029
    FZStream.next_out := @outBuffer;
2030
    FZStream.avail_out := outSize;
2031

2032
    zresult := ZCompressCheck(ZDeflate(FZStream, flush));
2033

2034
    outCount := outSize - FZStream.avail_out;
2035

2036
    BufferWrite(@outBuffer, outCount);
2037
  until (zresult = Z_STREAM_END) or (FZStream.avail_out > 0);
2038
end;
2039

2040
function TZCompressionBuffer.Write(const buffer: Pointer;
2041
  size: Integer): Integer;
2042
const
2043
  outSize = 32768;
2044
var
2045
  zresult  : Integer;
2046
  outBuffer: Array [0..outSize - 1] of Byte;
2047
  outCount : Integer;
2048
begin
2049
  zresult := Z_OK;
2050

2051
  FZStream.next_in := buffer;
2052
  FZStream.avail_in := size;
2053

2054
  while (zresult <> Z_STREAM_END) and (FZStream.avail_in > 0) do
2055
  begin
2056
    repeat
2057
      FZStream.next_out := @outBuffer;
2058
      FZStream.avail_out := outSize;
2059

2060
      zresult := ZCompressCheck(ZDeflate(FZStream, zfNoFlush));
2061

2062
      outCount := outSize - FZStream.avail_out;
2063

2064
      BufferWrite(@outBuffer, outCount);
2065
    until (zresult = Z_STREAM_END) or (FZStream.avail_out > 0);
2066
  end;
2067

2068
  result := size - FZStream.avail_in;
2069
end;
2070

2071
{** TZDecompressionBuffer ***************************************************}
2072

2073
constructor TZDecompressionBuffer.Create;
2074
begin
2075
  inherited Create;
2076

2077
  ZDecompressCheck(ZInflateInit(FZStream));
2078
end;
2079

2080
constructor TZDecompressionBuffer.Create(windowBits: Integer);
2081
begin
2082
  inherited Create;
2083

2084
  ZDecompressCheck(ZInflateInit2(FZStream, windowBits));
2085
end;
2086

2087
destructor TZDecompressionBuffer.Destroy;
2088
begin
2089
  ZDecompressCheck(ZInflateEnd(FZStream));
2090

2091
  inherited Destroy;
2092
end;
2093

2094
procedure TZDecompressionBuffer.Clear;
2095
begin
2096
  inherited Clear;
2097

2098
  ZDecompressCheck(ZInflateReset(FZStream));
2099
end;
2100

2101
function TZDecompressionBuffer.Write(const buffer: Pointer;
2102
  size: Integer): Integer;
2103
const
2104
  outSize = 32768;
2105
var
2106
  zresult  : Integer;
2107
  outBuffer: Array [0..outSize - 1] of Byte;
2108
  outCount : Integer;
2109
begin
2110
  zresult := Z_OK;
2111

2112
  FZStream.next_in := buffer;
2113
  FZStream.avail_in := size;
2114

2115
  while (zresult <> Z_STREAM_END) and (FZStream.avail_in > 0) do
2116
  begin
2117
    repeat
2118
      FZStream.next_out := @outBuffer;
2119
      FZStream.avail_out := outSize;
2120

2121
      zresult := ZDecompressCheck(ZInflate(FZStream, zfNoFlush), False);
2122

2123
      outCount := outSize - FZStream.avail_out;
2124

2125
      BufferWrite(@outBuffer, outCount);
2126
    until (zresult = Z_STREAM_END) or (FZStream.avail_out > 0);
2127
  end;
2128

2129
  result := size - FZStream.avail_in;
2130
end;
2131

2132
{** EZLibError **************************************************************}
2133

2134
constructor EZLibError.Create(code: Integer; const dummy: String);
2135
begin
2136
  inherited Create(_z_errmsg[2 - code]);
2137

2138
  FErrorCode := code;
2139
end;
2140

2141
constructor EZLibError.Create(error: TZError; const dummy: String);
2142
begin
2143
  Create(ZErrors[error], dummy);
2144
end;
2145

2146
end.
2147

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.