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