xref: /netbsd-src/common/dist/zlib/contrib/pascal/example.pas (revision aaf4ece63a859a04e37cf3a7229b5fab0157cc06)
1*aaf4ece6Schristos (* example.c -- usage example of the zlib compression library
2*aaf4ece6Schristos  * Copyright (C) 1995-2003 Jean-loup Gailly.
3*aaf4ece6Schristos  * For conditions of distribution and use, see copyright notice in zlib.h
4*aaf4ece6Schristos  *
5*aaf4ece6Schristos  * Pascal translation
6*aaf4ece6Schristos  * Copyright (C) 1998 by Jacques Nomssi Nzali.
7*aaf4ece6Schristos  * For conditions of distribution and use, see copyright notice in readme.txt
8*aaf4ece6Schristos  *
9*aaf4ece6Schristos  * Adaptation to the zlibpas interface
10*aaf4ece6Schristos  * Copyright (C) 2003 by Cosmin Truta.
11*aaf4ece6Schristos  * For conditions of distribution and use, see copyright notice in readme.txt
12*aaf4ece6Schristos  *)
13*aaf4ece6Schristos 
14*aaf4ece6Schristos program example;
15*aaf4ece6Schristos 
16*aaf4ece6Schristos {$DEFINE TEST_COMPRESS}
17*aaf4ece6Schristos {DO NOT $DEFINE TEST_GZIO}
18*aaf4ece6Schristos {$DEFINE TEST_DEFLATE}
19*aaf4ece6Schristos {$DEFINE TEST_INFLATE}
20*aaf4ece6Schristos {$DEFINE TEST_FLUSH}
21*aaf4ece6Schristos {$DEFINE TEST_SYNC}
22*aaf4ece6Schristos {$DEFINE TEST_DICT}
23*aaf4ece6Schristos 
24*aaf4ece6Schristos uses SysUtils, zlibpas;
25*aaf4ece6Schristos 
26*aaf4ece6Schristos const TESTFILE = 'foo.gz';
27*aaf4ece6Schristos 
28*aaf4ece6Schristos (* "hello world" would be more standard, but the repeated "hello"
29*aaf4ece6Schristos  * stresses the compression code better, sorry...
30*aaf4ece6Schristos  *)
31*aaf4ece6Schristos const hello: PChar = 'hello, hello!';
32*aaf4ece6Schristos 
33*aaf4ece6Schristos const dictionary: PChar = 'hello';
34*aaf4ece6Schristos 
35*aaf4ece6Schristos var dictId: LongInt; (* Adler32 value of the dictionary *)
36*aaf4ece6Schristos 
37*aaf4ece6Schristos procedure CHECK_ERR(err: Integer; msg: String);
38*aaf4ece6Schristos begin
39*aaf4ece6Schristos   if err <> Z_OK then
40*aaf4ece6Schristos   begin
41*aaf4ece6Schristos     WriteLn(msg, ' error: ', err);
42*aaf4ece6Schristos     Halt(1);
43*aaf4ece6Schristos   end;
44*aaf4ece6Schristos end;
45*aaf4ece6Schristos 
46*aaf4ece6Schristos procedure EXIT_ERR(const msg: String);
47*aaf4ece6Schristos begin
48*aaf4ece6Schristos   WriteLn('Error: ', msg);
49*aaf4ece6Schristos   Halt(1);
50*aaf4ece6Schristos end;
51*aaf4ece6Schristos 
52*aaf4ece6Schristos (* ===========================================================================
53*aaf4ece6Schristos  * Test compress and uncompress
54*aaf4ece6Schristos  *)
55*aaf4ece6Schristos {$IFDEF TEST_COMPRESS}
56*aaf4ece6Schristos procedure test_compress(compr: Pointer; comprLen: LongInt;
57*aaf4ece6Schristos                         uncompr: Pointer; uncomprLen: LongInt);
58*aaf4ece6Schristos var err: Integer;
59*aaf4ece6Schristos     len: LongInt;
60*aaf4ece6Schristos begin
61*aaf4ece6Schristos   len := StrLen(hello)+1;
62*aaf4ece6Schristos 
63*aaf4ece6Schristos   err := compress(compr, comprLen, hello, len);
64*aaf4ece6Schristos   CHECK_ERR(err, 'compress');
65*aaf4ece6Schristos 
66*aaf4ece6Schristos   StrCopy(PChar(uncompr), 'garbage');
67*aaf4ece6Schristos 
68*aaf4ece6Schristos   err := uncompress(uncompr, uncomprLen, compr, comprLen);
69*aaf4ece6Schristos   CHECK_ERR(err, 'uncompress');
70*aaf4ece6Schristos 
71*aaf4ece6Schristos   if StrComp(PChar(uncompr), hello) <> 0 then
72*aaf4ece6Schristos     EXIT_ERR('bad uncompress')
73*aaf4ece6Schristos   else
74*aaf4ece6Schristos     WriteLn('uncompress(): ', PChar(uncompr));
75*aaf4ece6Schristos end;
76*aaf4ece6Schristos {$ENDIF}
77*aaf4ece6Schristos 
78*aaf4ece6Schristos (* ===========================================================================
79*aaf4ece6Schristos  * Test read/write of .gz files
80*aaf4ece6Schristos  *)
81*aaf4ece6Schristos {$IFDEF TEST_GZIO}
82*aaf4ece6Schristos procedure test_gzio(const fname: PChar; (* compressed file name *)
83*aaf4ece6Schristos                     uncompr: Pointer;
84*aaf4ece6Schristos                     uncomprLen: LongInt);
85*aaf4ece6Schristos var err: Integer;
86*aaf4ece6Schristos     len: Integer;
87*aaf4ece6Schristos     zfile: gzFile;
88*aaf4ece6Schristos     pos: LongInt;
89*aaf4ece6Schristos begin
90*aaf4ece6Schristos   len := StrLen(hello)+1;
91*aaf4ece6Schristos 
92*aaf4ece6Schristos   zfile := gzopen(fname, 'wb');
93*aaf4ece6Schristos   if zfile = NIL then
94*aaf4ece6Schristos   begin
95*aaf4ece6Schristos     WriteLn('gzopen error');
96*aaf4ece6Schristos     Halt(1);
97*aaf4ece6Schristos   end;
98*aaf4ece6Schristos   gzputc(zfile, 'h');
99*aaf4ece6Schristos   if gzputs(zfile, 'ello') <> 4 then
100*aaf4ece6Schristos   begin
101*aaf4ece6Schristos     WriteLn('gzputs err: ', gzerror(zfile, err));
102*aaf4ece6Schristos     Halt(1);
103*aaf4ece6Schristos   end;
104*aaf4ece6Schristos   {$IFDEF GZ_FORMAT_STRING}
105*aaf4ece6Schristos   if gzprintf(zfile, ', %s!', 'hello') <> 8 then
106*aaf4ece6Schristos   begin
107*aaf4ece6Schristos     WriteLn('gzprintf err: ', gzerror(zfile, err));
108*aaf4ece6Schristos     Halt(1);
109*aaf4ece6Schristos   end;
110*aaf4ece6Schristos   {$ELSE}
111*aaf4ece6Schristos   if gzputs(zfile, ', hello!') <> 8 then
112*aaf4ece6Schristos   begin
113*aaf4ece6Schristos     WriteLn('gzputs err: ', gzerror(zfile, err));
114*aaf4ece6Schristos     Halt(1);
115*aaf4ece6Schristos   end;
116*aaf4ece6Schristos   {$ENDIF}
117*aaf4ece6Schristos   gzseek(zfile, 1, SEEK_CUR); (* add one zero byte *)
118*aaf4ece6Schristos   gzclose(zfile);
119*aaf4ece6Schristos 
120*aaf4ece6Schristos   zfile := gzopen(fname, 'rb');
121*aaf4ece6Schristos   if zfile = NIL then
122*aaf4ece6Schristos   begin
123*aaf4ece6Schristos     WriteLn('gzopen error');
124*aaf4ece6Schristos     Halt(1);
125*aaf4ece6Schristos   end;
126*aaf4ece6Schristos 
127*aaf4ece6Schristos   StrCopy(PChar(uncompr), 'garbage');
128*aaf4ece6Schristos 
129*aaf4ece6Schristos   if gzread(zfile, uncompr, uncomprLen) <> len then
130*aaf4ece6Schristos   begin
131*aaf4ece6Schristos     WriteLn('gzread err: ', gzerror(zfile, err));
132*aaf4ece6Schristos     Halt(1);
133*aaf4ece6Schristos   end;
134*aaf4ece6Schristos   if StrComp(PChar(uncompr), hello) <> 0 then
135*aaf4ece6Schristos   begin
136*aaf4ece6Schristos     WriteLn('bad gzread: ', PChar(uncompr));
137*aaf4ece6Schristos     Halt(1);
138*aaf4ece6Schristos   end
139*aaf4ece6Schristos   else
140*aaf4ece6Schristos     WriteLn('gzread(): ', PChar(uncompr));
141*aaf4ece6Schristos 
142*aaf4ece6Schristos   pos := gzseek(zfile, -8, SEEK_CUR);
143*aaf4ece6Schristos   if (pos <> 6) or (gztell(zfile) <> pos) then
144*aaf4ece6Schristos   begin
145*aaf4ece6Schristos     WriteLn('gzseek error, pos=', pos, ', gztell=', gztell(zfile));
146*aaf4ece6Schristos     Halt(1);
147*aaf4ece6Schristos   end;
148*aaf4ece6Schristos 
149*aaf4ece6Schristos   if gzgetc(zfile) <> ' ' then
150*aaf4ece6Schristos   begin
151*aaf4ece6Schristos     WriteLn('gzgetc error');
152*aaf4ece6Schristos     Halt(1);
153*aaf4ece6Schristos   end;
154*aaf4ece6Schristos 
155*aaf4ece6Schristos   if gzungetc(' ', zfile) <> ' ' then
156*aaf4ece6Schristos   begin
157*aaf4ece6Schristos     WriteLn('gzungetc error');
158*aaf4ece6Schristos     Halt(1);
159*aaf4ece6Schristos   end;
160*aaf4ece6Schristos 
161*aaf4ece6Schristos   gzgets(zfile, PChar(uncompr), uncomprLen);
162*aaf4ece6Schristos   uncomprLen := StrLen(PChar(uncompr));
163*aaf4ece6Schristos   if uncomprLen <> 7 then (* " hello!" *)
164*aaf4ece6Schristos   begin
165*aaf4ece6Schristos     WriteLn('gzgets err after gzseek: ', gzerror(zfile, err));
166*aaf4ece6Schristos     Halt(1);
167*aaf4ece6Schristos   end;
168*aaf4ece6Schristos   if StrComp(PChar(uncompr), hello + 6) <> 0 then
169*aaf4ece6Schristos   begin
170*aaf4ece6Schristos     WriteLn('bad gzgets after gzseek');
171*aaf4ece6Schristos     Halt(1);
172*aaf4ece6Schristos   end
173*aaf4ece6Schristos   else
174*aaf4ece6Schristos     WriteLn('gzgets() after gzseek: ', PChar(uncompr));
175*aaf4ece6Schristos 
176*aaf4ece6Schristos   gzclose(zfile);
177*aaf4ece6Schristos end;
178*aaf4ece6Schristos {$ENDIF}
179*aaf4ece6Schristos 
180*aaf4ece6Schristos (* ===========================================================================
181*aaf4ece6Schristos  * Test deflate with small buffers
182*aaf4ece6Schristos  *)
183*aaf4ece6Schristos {$IFDEF TEST_DEFLATE}
184*aaf4ece6Schristos procedure test_deflate(compr: Pointer; comprLen: LongInt);
185*aaf4ece6Schristos var c_stream: z_stream; (* compression stream *)
186*aaf4ece6Schristos     err: Integer;
187*aaf4ece6Schristos     len: LongInt;
188*aaf4ece6Schristos begin
189*aaf4ece6Schristos   len := StrLen(hello)+1;
190*aaf4ece6Schristos 
191*aaf4ece6Schristos   c_stream.zalloc := NIL;
192*aaf4ece6Schristos   c_stream.zfree := NIL;
193*aaf4ece6Schristos   c_stream.opaque := NIL;
194*aaf4ece6Schristos 
195*aaf4ece6Schristos   err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);
196*aaf4ece6Schristos   CHECK_ERR(err, 'deflateInit');
197*aaf4ece6Schristos 
198*aaf4ece6Schristos   c_stream.next_in := hello;
199*aaf4ece6Schristos   c_stream.next_out := compr;
200*aaf4ece6Schristos 
201*aaf4ece6Schristos   while (c_stream.total_in <> len) and
202*aaf4ece6Schristos         (c_stream.total_out < comprLen) do
203*aaf4ece6Schristos   begin
204*aaf4ece6Schristos     c_stream.avail_out := 1; { force small buffers }
205*aaf4ece6Schristos     c_stream.avail_in := 1;
206*aaf4ece6Schristos     err := deflate(c_stream, Z_NO_FLUSH);
207*aaf4ece6Schristos     CHECK_ERR(err, 'deflate');
208*aaf4ece6Schristos   end;
209*aaf4ece6Schristos 
210*aaf4ece6Schristos   (* Finish the stream, still forcing small buffers: *)
211*aaf4ece6Schristos   while TRUE do
212*aaf4ece6Schristos   begin
213*aaf4ece6Schristos     c_stream.avail_out := 1;
214*aaf4ece6Schristos     err := deflate(c_stream, Z_FINISH);
215*aaf4ece6Schristos     if err = Z_STREAM_END then
216*aaf4ece6Schristos       break;
217*aaf4ece6Schristos     CHECK_ERR(err, 'deflate');
218*aaf4ece6Schristos   end;
219*aaf4ece6Schristos 
220*aaf4ece6Schristos   err := deflateEnd(c_stream);
221*aaf4ece6Schristos   CHECK_ERR(err, 'deflateEnd');
222*aaf4ece6Schristos end;
223*aaf4ece6Schristos {$ENDIF}
224*aaf4ece6Schristos 
225*aaf4ece6Schristos (* ===========================================================================
226*aaf4ece6Schristos  * Test inflate with small buffers
227*aaf4ece6Schristos  *)
228*aaf4ece6Schristos {$IFDEF TEST_INFLATE}
229*aaf4ece6Schristos procedure test_inflate(compr: Pointer; comprLen : LongInt;
230*aaf4ece6Schristos                        uncompr: Pointer; uncomprLen : LongInt);
231*aaf4ece6Schristos var err: Integer;
232*aaf4ece6Schristos     d_stream: z_stream; (* decompression stream *)
233*aaf4ece6Schristos begin
234*aaf4ece6Schristos   StrCopy(PChar(uncompr), 'garbage');
235*aaf4ece6Schristos 
236*aaf4ece6Schristos   d_stream.zalloc := NIL;
237*aaf4ece6Schristos   d_stream.zfree := NIL;
238*aaf4ece6Schristos   d_stream.opaque := NIL;
239*aaf4ece6Schristos 
240*aaf4ece6Schristos   d_stream.next_in := compr;
241*aaf4ece6Schristos   d_stream.avail_in := 0;
242*aaf4ece6Schristos   d_stream.next_out := uncompr;
243*aaf4ece6Schristos 
244*aaf4ece6Schristos   err := inflateInit(d_stream);
245*aaf4ece6Schristos   CHECK_ERR(err, 'inflateInit');
246*aaf4ece6Schristos 
247*aaf4ece6Schristos   while (d_stream.total_out < uncomprLen) and
248*aaf4ece6Schristos         (d_stream.total_in < comprLen) do
249*aaf4ece6Schristos   begin
250*aaf4ece6Schristos     d_stream.avail_out := 1; (* force small buffers *)
251*aaf4ece6Schristos     d_stream.avail_in := 1;
252*aaf4ece6Schristos     err := inflate(d_stream, Z_NO_FLUSH);
253*aaf4ece6Schristos     if err = Z_STREAM_END then
254*aaf4ece6Schristos       break;
255*aaf4ece6Schristos     CHECK_ERR(err, 'inflate');
256*aaf4ece6Schristos   end;
257*aaf4ece6Schristos 
258*aaf4ece6Schristos   err := inflateEnd(d_stream);
259*aaf4ece6Schristos   CHECK_ERR(err, 'inflateEnd');
260*aaf4ece6Schristos 
261*aaf4ece6Schristos   if StrComp(PChar(uncompr), hello) <> 0 then
262*aaf4ece6Schristos     EXIT_ERR('bad inflate')
263*aaf4ece6Schristos   else
264*aaf4ece6Schristos     WriteLn('inflate(): ', PChar(uncompr));
265*aaf4ece6Schristos end;
266*aaf4ece6Schristos {$ENDIF}
267*aaf4ece6Schristos 
268*aaf4ece6Schristos (* ===========================================================================
269*aaf4ece6Schristos  * Test deflate with large buffers and dynamic change of compression level
270*aaf4ece6Schristos  *)
271*aaf4ece6Schristos {$IFDEF TEST_DEFLATE}
272*aaf4ece6Schristos procedure test_large_deflate(compr: Pointer; comprLen: LongInt;
273*aaf4ece6Schristos                              uncompr: Pointer; uncomprLen: LongInt);
274*aaf4ece6Schristos var c_stream: z_stream; (* compression stream *)
275*aaf4ece6Schristos     err: Integer;
276*aaf4ece6Schristos begin
277*aaf4ece6Schristos   c_stream.zalloc := NIL;
278*aaf4ece6Schristos   c_stream.zfree := NIL;
279*aaf4ece6Schristos   c_stream.opaque := NIL;
280*aaf4ece6Schristos 
281*aaf4ece6Schristos   err := deflateInit(c_stream, Z_BEST_SPEED);
282*aaf4ece6Schristos   CHECK_ERR(err, 'deflateInit');
283*aaf4ece6Schristos 
284*aaf4ece6Schristos   c_stream.next_out := compr;
285*aaf4ece6Schristos   c_stream.avail_out := Integer(comprLen);
286*aaf4ece6Schristos 
287*aaf4ece6Schristos   (* At this point, uncompr is still mostly zeroes, so it should compress
288*aaf4ece6Schristos    * very well:
289*aaf4ece6Schristos    *)
290*aaf4ece6Schristos   c_stream.next_in := uncompr;
291*aaf4ece6Schristos   c_stream.avail_in := Integer(uncomprLen);
292*aaf4ece6Schristos   err := deflate(c_stream, Z_NO_FLUSH);
293*aaf4ece6Schristos   CHECK_ERR(err, 'deflate');
294*aaf4ece6Schristos   if c_stream.avail_in <> 0 then
295*aaf4ece6Schristos     EXIT_ERR('deflate not greedy');
296*aaf4ece6Schristos 
297*aaf4ece6Schristos   (* Feed in already compressed data and switch to no compression: *)
298*aaf4ece6Schristos   deflateParams(c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
299*aaf4ece6Schristos   c_stream.next_in := compr;
300*aaf4ece6Schristos   c_stream.avail_in := Integer(comprLen div 2);
301*aaf4ece6Schristos   err := deflate(c_stream, Z_NO_FLUSH);
302*aaf4ece6Schristos   CHECK_ERR(err, 'deflate');
303*aaf4ece6Schristos 
304*aaf4ece6Schristos   (* Switch back to compressing mode: *)
305*aaf4ece6Schristos   deflateParams(c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
306*aaf4ece6Schristos   c_stream.next_in := uncompr;
307*aaf4ece6Schristos   c_stream.avail_in := Integer(uncomprLen);
308*aaf4ece6Schristos   err := deflate(c_stream, Z_NO_FLUSH);
309*aaf4ece6Schristos   CHECK_ERR(err, 'deflate');
310*aaf4ece6Schristos 
311*aaf4ece6Schristos   err := deflate(c_stream, Z_FINISH);
312*aaf4ece6Schristos   if err <> Z_STREAM_END then
313*aaf4ece6Schristos     EXIT_ERR('deflate should report Z_STREAM_END');
314*aaf4ece6Schristos 
315*aaf4ece6Schristos   err := deflateEnd(c_stream);
316*aaf4ece6Schristos   CHECK_ERR(err, 'deflateEnd');
317*aaf4ece6Schristos end;
318*aaf4ece6Schristos {$ENDIF}
319*aaf4ece6Schristos 
320*aaf4ece6Schristos (* ===========================================================================
321*aaf4ece6Schristos  * Test inflate with large buffers
322*aaf4ece6Schristos  *)
323*aaf4ece6Schristos {$IFDEF TEST_INFLATE}
324*aaf4ece6Schristos procedure test_large_inflate(compr: Pointer; comprLen: LongInt;
325*aaf4ece6Schristos                              uncompr: Pointer; uncomprLen: LongInt);
326*aaf4ece6Schristos var err: Integer;
327*aaf4ece6Schristos     d_stream: z_stream; (* decompression stream *)
328*aaf4ece6Schristos begin
329*aaf4ece6Schristos   StrCopy(PChar(uncompr), 'garbage');
330*aaf4ece6Schristos 
331*aaf4ece6Schristos   d_stream.zalloc := NIL;
332*aaf4ece6Schristos   d_stream.zfree := NIL;
333*aaf4ece6Schristos   d_stream.opaque := NIL;
334*aaf4ece6Schristos 
335*aaf4ece6Schristos   d_stream.next_in := compr;
336*aaf4ece6Schristos   d_stream.avail_in := Integer(comprLen);
337*aaf4ece6Schristos 
338*aaf4ece6Schristos   err := inflateInit(d_stream);
339*aaf4ece6Schristos   CHECK_ERR(err, 'inflateInit');
340*aaf4ece6Schristos 
341*aaf4ece6Schristos   while TRUE do
342*aaf4ece6Schristos   begin
343*aaf4ece6Schristos     d_stream.next_out := uncompr;            (* discard the output *)
344*aaf4ece6Schristos     d_stream.avail_out := Integer(uncomprLen);
345*aaf4ece6Schristos     err := inflate(d_stream, Z_NO_FLUSH);
346*aaf4ece6Schristos     if err = Z_STREAM_END then
347*aaf4ece6Schristos       break;
348*aaf4ece6Schristos     CHECK_ERR(err, 'large inflate');
349*aaf4ece6Schristos   end;
350*aaf4ece6Schristos 
351*aaf4ece6Schristos   err := inflateEnd(d_stream);
352*aaf4ece6Schristos   CHECK_ERR(err, 'inflateEnd');
353*aaf4ece6Schristos 
354*aaf4ece6Schristos   if d_stream.total_out <> 2 * uncomprLen + comprLen div 2 then
355*aaf4ece6Schristos   begin
356*aaf4ece6Schristos     WriteLn('bad large inflate: ', d_stream.total_out);
357*aaf4ece6Schristos     Halt(1);
358*aaf4ece6Schristos   end
359*aaf4ece6Schristos   else
360*aaf4ece6Schristos     WriteLn('large_inflate(): OK');
361*aaf4ece6Schristos end;
362*aaf4ece6Schristos {$ENDIF}
363*aaf4ece6Schristos 
364*aaf4ece6Schristos (* ===========================================================================
365*aaf4ece6Schristos  * Test deflate with full flush
366*aaf4ece6Schristos  *)
367*aaf4ece6Schristos {$IFDEF TEST_FLUSH}
368*aaf4ece6Schristos procedure test_flush(compr: Pointer; var comprLen : LongInt);
369*aaf4ece6Schristos var c_stream: z_stream; (* compression stream *)
370*aaf4ece6Schristos     err: Integer;
371*aaf4ece6Schristos     len: Integer;
372*aaf4ece6Schristos begin
373*aaf4ece6Schristos   len := StrLen(hello)+1;
374*aaf4ece6Schristos 
375*aaf4ece6Schristos   c_stream.zalloc := NIL;
376*aaf4ece6Schristos   c_stream.zfree := NIL;
377*aaf4ece6Schristos   c_stream.opaque := NIL;
378*aaf4ece6Schristos 
379*aaf4ece6Schristos   err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);
380*aaf4ece6Schristos   CHECK_ERR(err, 'deflateInit');
381*aaf4ece6Schristos 
382*aaf4ece6Schristos   c_stream.next_in := hello;
383*aaf4ece6Schristos   c_stream.next_out := compr;
384*aaf4ece6Schristos   c_stream.avail_in := 3;
385*aaf4ece6Schristos   c_stream.avail_out := Integer(comprLen);
386*aaf4ece6Schristos   err := deflate(c_stream, Z_FULL_FLUSH);
387*aaf4ece6Schristos   CHECK_ERR(err, 'deflate');
388*aaf4ece6Schristos 
389*aaf4ece6Schristos   Inc(PByteArray(compr)^[3]); (* force an error in first compressed block *)
390*aaf4ece6Schristos   c_stream.avail_in := len - 3;
391*aaf4ece6Schristos 
392*aaf4ece6Schristos   err := deflate(c_stream, Z_FINISH);
393*aaf4ece6Schristos   if err <> Z_STREAM_END then
394*aaf4ece6Schristos     CHECK_ERR(err, 'deflate');
395*aaf4ece6Schristos 
396*aaf4ece6Schristos   err := deflateEnd(c_stream);
397*aaf4ece6Schristos   CHECK_ERR(err, 'deflateEnd');
398*aaf4ece6Schristos 
399*aaf4ece6Schristos   comprLen := c_stream.total_out;
400*aaf4ece6Schristos end;
401*aaf4ece6Schristos {$ENDIF}
402*aaf4ece6Schristos 
403*aaf4ece6Schristos (* ===========================================================================
404*aaf4ece6Schristos  * Test inflateSync()
405*aaf4ece6Schristos  *)
406*aaf4ece6Schristos {$IFDEF TEST_SYNC}
407*aaf4ece6Schristos procedure test_sync(compr: Pointer; comprLen: LongInt;
408*aaf4ece6Schristos                     uncompr: Pointer; uncomprLen : LongInt);
409*aaf4ece6Schristos var err: Integer;
410*aaf4ece6Schristos     d_stream: z_stream; (* decompression stream *)
411*aaf4ece6Schristos begin
412*aaf4ece6Schristos   StrCopy(PChar(uncompr), 'garbage');
413*aaf4ece6Schristos 
414*aaf4ece6Schristos   d_stream.zalloc := NIL;
415*aaf4ece6Schristos   d_stream.zfree := NIL;
416*aaf4ece6Schristos   d_stream.opaque := NIL;
417*aaf4ece6Schristos 
418*aaf4ece6Schristos   d_stream.next_in := compr;
419*aaf4ece6Schristos   d_stream.avail_in := 2; (* just read the zlib header *)
420*aaf4ece6Schristos 
421*aaf4ece6Schristos   err := inflateInit(d_stream);
422*aaf4ece6Schristos   CHECK_ERR(err, 'inflateInit');
423*aaf4ece6Schristos 
424*aaf4ece6Schristos   d_stream.next_out := uncompr;
425*aaf4ece6Schristos   d_stream.avail_out := Integer(uncomprLen);
426*aaf4ece6Schristos 
427*aaf4ece6Schristos   inflate(d_stream, Z_NO_FLUSH);
428*aaf4ece6Schristos   CHECK_ERR(err, 'inflate');
429*aaf4ece6Schristos 
430*aaf4ece6Schristos   d_stream.avail_in := Integer(comprLen-2);   (* read all compressed data *)
431*aaf4ece6Schristos   err := inflateSync(d_stream);               (* but skip the damaged part *)
432*aaf4ece6Schristos   CHECK_ERR(err, 'inflateSync');
433*aaf4ece6Schristos 
434*aaf4ece6Schristos   err := inflate(d_stream, Z_FINISH);
435*aaf4ece6Schristos   if err <> Z_DATA_ERROR then
436*aaf4ece6Schristos     EXIT_ERR('inflate should report DATA_ERROR');
437*aaf4ece6Schristos     (* Because of incorrect adler32 *)
438*aaf4ece6Schristos 
439*aaf4ece6Schristos   err := inflateEnd(d_stream);
440*aaf4ece6Schristos   CHECK_ERR(err, 'inflateEnd');
441*aaf4ece6Schristos 
442*aaf4ece6Schristos   WriteLn('after inflateSync(): hel', PChar(uncompr));
443*aaf4ece6Schristos end;
444*aaf4ece6Schristos {$ENDIF}
445*aaf4ece6Schristos 
446*aaf4ece6Schristos (* ===========================================================================
447*aaf4ece6Schristos  * Test deflate with preset dictionary
448*aaf4ece6Schristos  *)
449*aaf4ece6Schristos {$IFDEF TEST_DICT}
450*aaf4ece6Schristos procedure test_dict_deflate(compr: Pointer; comprLen: LongInt);
451*aaf4ece6Schristos var c_stream: z_stream; (* compression stream *)
452*aaf4ece6Schristos     err: Integer;
453*aaf4ece6Schristos begin
454*aaf4ece6Schristos   c_stream.zalloc := NIL;
455*aaf4ece6Schristos   c_stream.zfree := NIL;
456*aaf4ece6Schristos   c_stream.opaque := NIL;
457*aaf4ece6Schristos 
458*aaf4ece6Schristos   err := deflateInit(c_stream, Z_BEST_COMPRESSION);
459*aaf4ece6Schristos   CHECK_ERR(err, 'deflateInit');
460*aaf4ece6Schristos 
461*aaf4ece6Schristos   err := deflateSetDictionary(c_stream, dictionary, StrLen(dictionary));
462*aaf4ece6Schristos   CHECK_ERR(err, 'deflateSetDictionary');
463*aaf4ece6Schristos 
464*aaf4ece6Schristos   dictId := c_stream.adler;
465*aaf4ece6Schristos   c_stream.next_out := compr;
466*aaf4ece6Schristos   c_stream.avail_out := Integer(comprLen);
467*aaf4ece6Schristos 
468*aaf4ece6Schristos   c_stream.next_in := hello;
469*aaf4ece6Schristos   c_stream.avail_in := StrLen(hello)+1;
470*aaf4ece6Schristos 
471*aaf4ece6Schristos   err := deflate(c_stream, Z_FINISH);
472*aaf4ece6Schristos   if err <> Z_STREAM_END then
473*aaf4ece6Schristos     EXIT_ERR('deflate should report Z_STREAM_END');
474*aaf4ece6Schristos 
475*aaf4ece6Schristos   err := deflateEnd(c_stream);
476*aaf4ece6Schristos   CHECK_ERR(err, 'deflateEnd');
477*aaf4ece6Schristos end;
478*aaf4ece6Schristos {$ENDIF}
479*aaf4ece6Schristos 
480*aaf4ece6Schristos (* ===========================================================================
481*aaf4ece6Schristos  * Test inflate with a preset dictionary
482*aaf4ece6Schristos  *)
483*aaf4ece6Schristos {$IFDEF TEST_DICT}
484*aaf4ece6Schristos procedure test_dict_inflate(compr: Pointer; comprLen: LongInt;
485*aaf4ece6Schristos                             uncompr: Pointer; uncomprLen: LongInt);
486*aaf4ece6Schristos var err: Integer;
487*aaf4ece6Schristos     d_stream: z_stream; (* decompression stream *)
488*aaf4ece6Schristos begin
489*aaf4ece6Schristos   StrCopy(PChar(uncompr), 'garbage');
490*aaf4ece6Schristos 
491*aaf4ece6Schristos   d_stream.zalloc := NIL;
492*aaf4ece6Schristos   d_stream.zfree := NIL;
493*aaf4ece6Schristos   d_stream.opaque := NIL;
494*aaf4ece6Schristos 
495*aaf4ece6Schristos   d_stream.next_in := compr;
496*aaf4ece6Schristos   d_stream.avail_in := Integer(comprLen);
497*aaf4ece6Schristos 
498*aaf4ece6Schristos   err := inflateInit(d_stream);
499*aaf4ece6Schristos   CHECK_ERR(err, 'inflateInit');
500*aaf4ece6Schristos 
501*aaf4ece6Schristos   d_stream.next_out := uncompr;
502*aaf4ece6Schristos   d_stream.avail_out := Integer(uncomprLen);
503*aaf4ece6Schristos 
504*aaf4ece6Schristos   while TRUE do
505*aaf4ece6Schristos   begin
506*aaf4ece6Schristos     err := inflate(d_stream, Z_NO_FLUSH);
507*aaf4ece6Schristos     if err = Z_STREAM_END then
508*aaf4ece6Schristos       break;
509*aaf4ece6Schristos     if err = Z_NEED_DICT then
510*aaf4ece6Schristos     begin
511*aaf4ece6Schristos       if d_stream.adler <> dictId then
512*aaf4ece6Schristos         EXIT_ERR('unexpected dictionary');
513*aaf4ece6Schristos       err := inflateSetDictionary(d_stream, dictionary, StrLen(dictionary));
514*aaf4ece6Schristos     end;
515*aaf4ece6Schristos     CHECK_ERR(err, 'inflate with dict');
516*aaf4ece6Schristos   end;
517*aaf4ece6Schristos 
518*aaf4ece6Schristos   err := inflateEnd(d_stream);
519*aaf4ece6Schristos   CHECK_ERR(err, 'inflateEnd');
520*aaf4ece6Schristos 
521*aaf4ece6Schristos   if StrComp(PChar(uncompr), hello) <> 0 then
522*aaf4ece6Schristos     EXIT_ERR('bad inflate with dict')
523*aaf4ece6Schristos   else
524*aaf4ece6Schristos     WriteLn('inflate with dictionary: ', PChar(uncompr));
525*aaf4ece6Schristos end;
526*aaf4ece6Schristos {$ENDIF}
527*aaf4ece6Schristos 
528*aaf4ece6Schristos var compr, uncompr: Pointer;
529*aaf4ece6Schristos     comprLen, uncomprLen: LongInt;
530*aaf4ece6Schristos 
531*aaf4ece6Schristos begin
532*aaf4ece6Schristos   if zlibVersion^ <> ZLIB_VERSION[1] then
533*aaf4ece6Schristos     EXIT_ERR('Incompatible zlib version');
534*aaf4ece6Schristos 
535*aaf4ece6Schristos   WriteLn('zlib version: ', zlibVersion);
536*aaf4ece6Schristos   WriteLn('zlib compile flags: ', Format('0x%x', [zlibCompileFlags]));
537*aaf4ece6Schristos 
538*aaf4ece6Schristos   comprLen := 10000 * SizeOf(Integer); (* don't overflow on MSDOS *)
539*aaf4ece6Schristos   uncomprLen := comprLen;
540*aaf4ece6Schristos   GetMem(compr, comprLen);
541*aaf4ece6Schristos   GetMem(uncompr, uncomprLen);
542*aaf4ece6Schristos   if (compr = NIL) or (uncompr = NIL) then
543*aaf4ece6Schristos     EXIT_ERR('Out of memory');
544*aaf4ece6Schristos   (* compr and uncompr are cleared to avoid reading uninitialized
545*aaf4ece6Schristos    * data and to ensure that uncompr compresses well.
546*aaf4ece6Schristos    *)
547*aaf4ece6Schristos   FillChar(compr^, comprLen, 0);
548*aaf4ece6Schristos   FillChar(uncompr^, uncomprLen, 0);
549*aaf4ece6Schristos 
550*aaf4ece6Schristos   {$IFDEF TEST_COMPRESS}
551*aaf4ece6Schristos   WriteLn('** Testing compress');
552*aaf4ece6Schristos   test_compress(compr, comprLen, uncompr, uncomprLen);
553*aaf4ece6Schristos   {$ENDIF}
554*aaf4ece6Schristos 
555*aaf4ece6Schristos   {$IFDEF TEST_GZIO}
556*aaf4ece6Schristos   WriteLn('** Testing gzio');
557*aaf4ece6Schristos   if ParamCount >= 1 then
558*aaf4ece6Schristos     test_gzio(ParamStr(1), uncompr, uncomprLen)
559*aaf4ece6Schristos   else
560*aaf4ece6Schristos     test_gzio(TESTFILE, uncompr, uncomprLen);
561*aaf4ece6Schristos   {$ENDIF}
562*aaf4ece6Schristos 
563*aaf4ece6Schristos   {$IFDEF TEST_DEFLATE}
564*aaf4ece6Schristos   WriteLn('** Testing deflate with small buffers');
565*aaf4ece6Schristos   test_deflate(compr, comprLen);
566*aaf4ece6Schristos   {$ENDIF}
567*aaf4ece6Schristos   {$IFDEF TEST_INFLATE}
568*aaf4ece6Schristos   WriteLn('** Testing inflate with small buffers');
569*aaf4ece6Schristos   test_inflate(compr, comprLen, uncompr, uncomprLen);
570*aaf4ece6Schristos   {$ENDIF}
571*aaf4ece6Schristos 
572*aaf4ece6Schristos   {$IFDEF TEST_DEFLATE}
573*aaf4ece6Schristos   WriteLn('** Testing deflate with large buffers');
574*aaf4ece6Schristos   test_large_deflate(compr, comprLen, uncompr, uncomprLen);
575*aaf4ece6Schristos   {$ENDIF}
576*aaf4ece6Schristos   {$IFDEF TEST_INFLATE}
577*aaf4ece6Schristos   WriteLn('** Testing inflate with large buffers');
578*aaf4ece6Schristos   test_large_inflate(compr, comprLen, uncompr, uncomprLen);
579*aaf4ece6Schristos   {$ENDIF}
580*aaf4ece6Schristos 
581*aaf4ece6Schristos   {$IFDEF TEST_FLUSH}
582*aaf4ece6Schristos   WriteLn('** Testing deflate with full flush');
583*aaf4ece6Schristos   test_flush(compr, comprLen);
584*aaf4ece6Schristos   {$ENDIF}
585*aaf4ece6Schristos   {$IFDEF TEST_SYNC}
586*aaf4ece6Schristos   WriteLn('** Testing inflateSync');
587*aaf4ece6Schristos   test_sync(compr, comprLen, uncompr, uncomprLen);
588*aaf4ece6Schristos   {$ENDIF}
589*aaf4ece6Schristos   comprLen := uncomprLen;
590*aaf4ece6Schristos 
591*aaf4ece6Schristos   {$IFDEF TEST_DICT}
592*aaf4ece6Schristos   WriteLn('** Testing deflate and inflate with preset dictionary');
593*aaf4ece6Schristos   test_dict_deflate(compr, comprLen);
594*aaf4ece6Schristos   test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
595*aaf4ece6Schristos   {$ENDIF}
596*aaf4ece6Schristos 
597*aaf4ece6Schristos   FreeMem(compr, comprLen);
598*aaf4ece6Schristos   FreeMem(uncompr, uncomprLen);
599*aaf4ece6Schristos end.
600