This file is indexed.

/usr/share/doc/libghc-zlib-doc/html/src/Codec-Compression-Zlib-Internal.html is in libghc-zlib-doc 0.5.4.1-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<!-- Generated by HsColour, http://code.haskell.org/~malcolm/hscolour/ -->
<title>Codec/Compression/Zlib/Internal.hs</title>
<link type='text/css' rel='stylesheet' href='hscolour.css' />
</head>
<body>
<pre><a name="line-1"></a><span class='hs-comment'>{-# LANGUAGE CPP #-}</span>
<a name="line-2"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span>
<a name="line-3"></a><span class='hs-comment'>-- |</span>
<a name="line-4"></a><span class='hs-comment'>-- Copyright   :  (c) 2006-2008 Duncan Coutts</span>
<a name="line-5"></a><span class='hs-comment'>-- License     :  BSD-style</span>
<a name="line-6"></a><span class='hs-comment'>--</span>
<a name="line-7"></a><span class='hs-comment'>-- Maintainer  :  duncan@haskell.org</span>
<a name="line-8"></a><span class='hs-comment'>-- Stability   :  provisional</span>
<a name="line-9"></a><span class='hs-comment'>-- Portability :  portable (H98 + FFI)</span>
<a name="line-10"></a><span class='hs-comment'>--</span>
<a name="line-11"></a><span class='hs-comment'>-- Pure stream based interface to lower level zlib wrapper</span>
<a name="line-12"></a><span class='hs-comment'>--</span>
<a name="line-13"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span>
<a name="line-14"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>Codec</span><span class='hs-varop'>.</span><span class='hs-conid'>Compression</span><span class='hs-varop'>.</span><span class='hs-conid'>Zlib</span><span class='hs-varop'>.</span><span class='hs-conid'>Internal</span> <span class='hs-layout'>(</span>
<a name="line-15"></a>
<a name="line-16"></a>  <span class='hs-comment'>-- * Compression</span>
<a name="line-17"></a>  <span class='hs-varid'>compress</span><span class='hs-layout'>,</span>
<a name="line-18"></a>  <span class='hs-conid'>CompressParams</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-19"></a>  <span class='hs-varid'>defaultCompressParams</span><span class='hs-layout'>,</span>
<a name="line-20"></a>
<a name="line-21"></a>  <span class='hs-comment'>-- * Decompression</span>
<a name="line-22"></a>  <span class='hs-varid'>decompress</span><span class='hs-layout'>,</span>
<a name="line-23"></a>  <span class='hs-conid'>DecompressParams</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-24"></a>  <span class='hs-varid'>defaultDecompressParams</span><span class='hs-layout'>,</span>
<a name="line-25"></a>
<a name="line-26"></a>  <span class='hs-comment'>-- * The compression parameter types</span>
<a name="line-27"></a>  <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Format</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-28"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>gzipFormat</span><span class='hs-layout'>,</span>
<a name="line-29"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>zlibFormat</span><span class='hs-layout'>,</span>
<a name="line-30"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>rawFormat</span><span class='hs-layout'>,</span>
<a name="line-31"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>gzipOrZlibFormat</span><span class='hs-layout'>,</span>
<a name="line-32"></a>  <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>CompressionLevel</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-33"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>defaultCompression</span><span class='hs-layout'>,</span>
<a name="line-34"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>noCompression</span><span class='hs-layout'>,</span>
<a name="line-35"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>bestSpeed</span><span class='hs-layout'>,</span>
<a name="line-36"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>bestCompression</span><span class='hs-layout'>,</span>
<a name="line-37"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>compressionLevel</span><span class='hs-layout'>,</span>
<a name="line-38"></a>  <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Method</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-39"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>deflateMethod</span><span class='hs-layout'>,</span>
<a name="line-40"></a>  <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>WindowBits</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-41"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>defaultWindowBits</span><span class='hs-layout'>,</span>
<a name="line-42"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>windowBits</span><span class='hs-layout'>,</span>
<a name="line-43"></a>  <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>MemoryLevel</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-44"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>defaultMemoryLevel</span><span class='hs-layout'>,</span>
<a name="line-45"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>minMemoryLevel</span><span class='hs-layout'>,</span>
<a name="line-46"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>maxMemoryLevel</span><span class='hs-layout'>,</span>
<a name="line-47"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>memoryLevel</span><span class='hs-layout'>,</span>
<a name="line-48"></a>  <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>CompressionStrategy</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-49"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>defaultStrategy</span><span class='hs-layout'>,</span>
<a name="line-50"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>filteredStrategy</span><span class='hs-layout'>,</span>
<a name="line-51"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>huffmanOnlyStrategy</span><span class='hs-layout'>,</span>
<a name="line-52"></a>
<a name="line-53"></a>  <span class='hs-comment'>-- * Low-level API to get explicit error reports</span>
<a name="line-54"></a>  <span class='hs-varid'>decompressWithErrors</span><span class='hs-layout'>,</span>
<a name="line-55"></a>  <span class='hs-conid'>DecompressStream</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-56"></a>  <span class='hs-conid'>DecompressError</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-57"></a>  <span class='hs-varid'>foldDecompressStream</span><span class='hs-layout'>,</span>
<a name="line-58"></a>  <span class='hs-varid'>fromDecompressStream</span><span class='hs-layout'>,</span>
<a name="line-59"></a>  <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<a name="line-60"></a>
<a name="line-61"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Prelude</span> <span class='hs-varid'>hiding</span> <span class='hs-layout'>(</span><span class='hs-varid'>length</span><span class='hs-layout'>)</span>
<a name="line-62"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Monad</span> <span class='hs-layout'>(</span><span class='hs-varid'>when</span><span class='hs-layout'>)</span>
<a name="line-63"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Control</span><span class='hs-varop'>.</span><span class='hs-conid'>Exception</span> <span class='hs-layout'>(</span><span class='hs-varid'>assert</span><span class='hs-layout'>)</span>
<a name="line-64"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Lazy</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>L</span>
<a name="line-65"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Lazy</span><span class='hs-varop'>.</span><span class='hs-conid'>Internal</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>L</span>
<a name="line-66"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-varop'>.</span><span class='hs-conid'>Internal</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>S</span>
<a name="line-67"></a>
<a name="line-68"></a><span class='hs-keyword'>import</span> <span class='hs-keyword'>qualified</span> <span class='hs-conid'>Codec</span><span class='hs-varop'>.</span><span class='hs-conid'>Compression</span><span class='hs-varop'>.</span><span class='hs-conid'>Zlib</span><span class='hs-varop'>.</span><span class='hs-conid'>Stream</span> <span class='hs-keyword'>as</span> <span class='hs-conid'>Stream</span>
<a name="line-69"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Codec</span><span class='hs-varop'>.</span><span class='hs-conid'>Compression</span><span class='hs-varop'>.</span><span class='hs-conid'>Zlib</span><span class='hs-varop'>.</span><span class='hs-conid'>Stream</span> <span class='hs-layout'>(</span><span class='hs-conid'>Stream</span><span class='hs-layout'>)</span>
<a name="line-70"></a>
<a name="line-71"></a><a name="CompressParams"></a><span class='hs-comment'>-- | The full set of parameters for compression. The defaults are</span>
<a name="line-72"></a><a name="CompressParams"></a><span class='hs-comment'>-- 'defaultCompressParams'.</span>
<a name="line-73"></a><a name="CompressParams"></a><span class='hs-comment'>--</span>
<a name="line-74"></a><a name="CompressParams"></a><span class='hs-comment'>-- The 'compressBufferSize' is the size of the first output buffer containing</span>
<a name="line-75"></a><a name="CompressParams"></a><span class='hs-comment'>-- the compressed data. If you know an approximate upper bound on the size of</span>
<a name="line-76"></a><a name="CompressParams"></a><span class='hs-comment'>-- the compressed data then setting this parameter can save memory. The default</span>
<a name="line-77"></a><a name="CompressParams"></a><span class='hs-comment'>-- compression output buffer size is @16k@. If your extimate is wrong it does</span>
<a name="line-78"></a><a name="CompressParams"></a><span class='hs-comment'>-- not matter too much, the default buffer size will be used for the remaining</span>
<a name="line-79"></a><a name="CompressParams"></a><span class='hs-comment'>-- chunks.</span>
<a name="line-80"></a><a name="CompressParams"></a><span class='hs-comment'>--</span>
<a name="line-81"></a><a name="CompressParams"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>CompressParams</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>CompressParams</span> <span class='hs-layout'>{</span>
<a name="line-82"></a>  <span class='hs-varid'>compressLevel</span>       <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>CompressionLevel</span><span class='hs-layout'>,</span>
<a name="line-83"></a>  <span class='hs-varid'>compressMethod</span>      <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Method</span><span class='hs-layout'>,</span>
<a name="line-84"></a>  <span class='hs-varid'>compressWindowBits</span>  <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>WindowBits</span><span class='hs-layout'>,</span>
<a name="line-85"></a>  <span class='hs-varid'>compressMemoryLevel</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>MemoryLevel</span><span class='hs-layout'>,</span>
<a name="line-86"></a>  <span class='hs-varid'>compressStrategy</span>    <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>CompressionStrategy</span><span class='hs-layout'>,</span>
<a name="line-87"></a>  <span class='hs-varid'>compressBufferSize</span>  <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span>
<a name="line-88"></a>  <span class='hs-varid'>compressDictionary</span>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Maybe</span> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-89"></a><span class='hs-layout'>}</span>
<a name="line-90"></a>
<a name="line-91"></a><a name="DecompressParams"></a><span class='hs-comment'>-- | The full set of parameters for decompression. The defaults are</span>
<a name="line-92"></a><a name="DecompressParams"></a><span class='hs-comment'>-- 'defaultDecompressParams'.</span>
<a name="line-93"></a><a name="DecompressParams"></a><span class='hs-comment'>--</span>
<a name="line-94"></a><a name="DecompressParams"></a><span class='hs-comment'>-- The 'decompressBufferSize' is the size of the first output buffer,</span>
<a name="line-95"></a><a name="DecompressParams"></a><span class='hs-comment'>-- containing the uncompressed data. If you know an exact or approximate upper</span>
<a name="line-96"></a><a name="DecompressParams"></a><span class='hs-comment'>-- bound on the size of the decompressed data then setting this parameter can</span>
<a name="line-97"></a><a name="DecompressParams"></a><span class='hs-comment'>-- save memory. The default decompression output buffer size is @32k@. If your</span>
<a name="line-98"></a><a name="DecompressParams"></a><span class='hs-comment'>-- extimate is wrong it does not matter too much, the default buffer size will</span>
<a name="line-99"></a><a name="DecompressParams"></a><span class='hs-comment'>-- be used for the remaining chunks.</span>
<a name="line-100"></a><a name="DecompressParams"></a><span class='hs-comment'>--</span>
<a name="line-101"></a><a name="DecompressParams"></a><span class='hs-comment'>-- One particular use case for setting the 'decompressBufferSize' is if you</span>
<a name="line-102"></a><a name="DecompressParams"></a><span class='hs-comment'>-- know the exact size of the decompressed data and want to produce a strict</span>
<a name="line-103"></a><a name="DecompressParams"></a><span class='hs-comment'>-- 'Data.ByteString.ByteString'. The compression and deccompression functions</span>
<a name="line-104"></a><a name="DecompressParams"></a><span class='hs-comment'>-- use lazy 'Data.ByteString.Lazy.ByteString's but if you set the</span>
<a name="line-105"></a><a name="DecompressParams"></a><span class='hs-comment'>-- 'decompressBufferSize' correctly then you can generate a lazy</span>
<a name="line-106"></a><a name="DecompressParams"></a><span class='hs-comment'>-- 'Data.ByteString.Lazy.ByteString' with exactly one chunk, which can be</span>
<a name="line-107"></a><a name="DecompressParams"></a><span class='hs-comment'>-- converted to a strict 'Data.ByteString.ByteString' in @O(1)@ time using</span>
<a name="line-108"></a><a name="DecompressParams"></a><span class='hs-comment'>-- @'Data.ByteString.concat' . 'Data.ByteString.Lazy.toChunks'@.</span>
<a name="line-109"></a><a name="DecompressParams"></a><span class='hs-comment'>--</span>
<a name="line-110"></a><a name="DecompressParams"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>DecompressParams</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>DecompressParams</span> <span class='hs-layout'>{</span>
<a name="line-111"></a>  <span class='hs-varid'>decompressWindowBits</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>WindowBits</span><span class='hs-layout'>,</span>
<a name="line-112"></a>  <span class='hs-varid'>decompressBufferSize</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span>
<a name="line-113"></a>  <span class='hs-varid'>decompressDictionary</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Maybe</span> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-114"></a><span class='hs-layout'>}</span>
<a name="line-115"></a>
<a name="line-116"></a><a name="defaultCompressParams"></a><span class='hs-comment'>-- | The default set of parameters for compression. This is typically used with</span>
<a name="line-117"></a><span class='hs-comment'>-- the @compressWith@ function with specific parameters overridden.</span>
<a name="line-118"></a><span class='hs-comment'>--</span>
<a name="line-119"></a><span class='hs-definition'>defaultCompressParams</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CompressParams</span>
<a name="line-120"></a><span class='hs-definition'>defaultCompressParams</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>CompressParams</span> <span class='hs-layout'>{</span>
<a name="line-121"></a>  <span class='hs-varid'>compressLevel</span>       <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>defaultCompression</span><span class='hs-layout'>,</span>
<a name="line-122"></a>  <span class='hs-varid'>compressMethod</span>      <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>deflateMethod</span><span class='hs-layout'>,</span>
<a name="line-123"></a>  <span class='hs-varid'>compressWindowBits</span>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>defaultWindowBits</span><span class='hs-layout'>,</span>
<a name="line-124"></a>  <span class='hs-varid'>compressMemoryLevel</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>defaultMemoryLevel</span><span class='hs-layout'>,</span>
<a name="line-125"></a>  <span class='hs-varid'>compressStrategy</span>    <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>defaultStrategy</span><span class='hs-layout'>,</span>
<a name="line-126"></a>  <span class='hs-varid'>compressBufferSize</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>defaultCompressBufferSize</span><span class='hs-layout'>,</span>
<a name="line-127"></a>  <span class='hs-varid'>compressDictionary</span>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
<a name="line-128"></a><span class='hs-layout'>}</span>
<a name="line-129"></a>
<a name="line-130"></a><a name="defaultDecompressParams"></a><span class='hs-comment'>-- | The default set of parameters for decompression. This is typically used with</span>
<a name="line-131"></a><span class='hs-comment'>-- the @compressWith@ function with specific parameters overridden.</span>
<a name="line-132"></a><span class='hs-comment'>--</span>
<a name="line-133"></a><span class='hs-definition'>defaultDecompressParams</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>DecompressParams</span>
<a name="line-134"></a><span class='hs-definition'>defaultDecompressParams</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>DecompressParams</span> <span class='hs-layout'>{</span>
<a name="line-135"></a>  <span class='hs-varid'>decompressWindowBits</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>defaultWindowBits</span><span class='hs-layout'>,</span>
<a name="line-136"></a>  <span class='hs-varid'>decompressBufferSize</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>defaultDecompressBufferSize</span><span class='hs-layout'>,</span>
<a name="line-137"></a>  <span class='hs-varid'>decompressDictionary</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
<a name="line-138"></a><span class='hs-layout'>}</span>
<a name="line-139"></a>
<a name="line-140"></a><a name="defaultCompressBufferSize"></a><span class='hs-comment'>-- | The default chunk sizes for the output of compression and decompression</span>
<a name="line-141"></a><span class='hs-comment'>-- are 16k and 32k respectively (less a small accounting overhead).</span>
<a name="line-142"></a><span class='hs-comment'>--</span>
<a name="line-143"></a><span class='hs-definition'>defaultCompressBufferSize</span><span class='hs-layout'>,</span> <span class='hs-varid'>defaultDecompressBufferSize</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span>
<a name="line-144"></a><span class='hs-definition'>defaultCompressBufferSize</span>   <span class='hs-keyglyph'>=</span> <span class='hs-num'>16</span> <span class='hs-varop'>*</span> <span class='hs-num'>1024</span> <span class='hs-comment'>-</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>chunkOverhead</span>
<a name="line-145"></a><a name="defaultDecompressBufferSize"></a><span class='hs-definition'>defaultDecompressBufferSize</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>32</span> <span class='hs-varop'>*</span> <span class='hs-num'>1024</span> <span class='hs-comment'>-</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>chunkOverhead</span>
<a name="line-146"></a>
<a name="line-147"></a><a name="DecompressStream"></a><span class='hs-comment'>-- | A sequence of chunks of data produced from decompression.</span>
<a name="line-148"></a><a name="DecompressStream"></a><span class='hs-comment'>--</span>
<a name="line-149"></a><a name="DecompressStream"></a><span class='hs-comment'>-- The difference from a simple list is that it contains a representation of</span>
<a name="line-150"></a><a name="DecompressStream"></a><span class='hs-comment'>-- errors as data rather than as exceptions. This allows you to handle error</span>
<a name="line-151"></a><a name="DecompressStream"></a><span class='hs-comment'>-- conditions explicitly.</span>
<a name="line-152"></a><a name="DecompressStream"></a><span class='hs-comment'>--</span>
<a name="line-153"></a><a name="DecompressStream"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>DecompressStream</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>StreamEnd</span>
<a name="line-154"></a>                      <span class='hs-keyglyph'>|</span> <span class='hs-conid'>StreamChunk</span> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span> <span class='hs-conid'>DecompressStream</span>
<a name="line-155"></a>
<a name="line-156"></a>                        <span class='hs-comment'>-- | An error code and a human readable error message.</span>
<a name="line-157"></a>                      <span class='hs-keyglyph'>|</span> <span class='hs-conid'>StreamError</span> <span class='hs-conid'>DecompressError</span> <span class='hs-conid'>String</span>
<a name="line-158"></a>
<a name="line-159"></a><a name="DecompressError"></a><span class='hs-comment'>-- | The possible error cases when decompressing a stream.</span>
<a name="line-160"></a><a name="DecompressError"></a><span class='hs-comment'>--</span>
<a name="line-161"></a><a name="DecompressError"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>DecompressError</span> <span class='hs-keyglyph'>=</span>
<a name="line-162"></a>     <span class='hs-comment'>-- | The compressed data stream ended prematurely. This may happen if the</span>
<a name="line-163"></a>     <span class='hs-comment'>-- input data stream was truncated.</span>
<a name="line-164"></a>     <span class='hs-conid'>TruncatedInput</span>
<a name="line-165"></a>
<a name="line-166"></a>     <span class='hs-comment'>-- | It is possible to do zlib compression with a custom dictionary. This</span>
<a name="line-167"></a>     <span class='hs-comment'>-- allows slightly higher compression ratios for short files. However such</span>
<a name="line-168"></a>     <span class='hs-comment'>-- compressed streams require the same dictionary when decompressing. This</span>
<a name="line-169"></a>     <span class='hs-comment'>-- error is for when we encounter a compressed stream that needs a</span>
<a name="line-170"></a>     <span class='hs-comment'>-- dictionary, and it's not provided.</span>
<a name="line-171"></a>   <span class='hs-keyglyph'>|</span> <span class='hs-conid'>DictionaryRequired</span>
<a name="line-172"></a>
<a name="line-173"></a>     <span class='hs-comment'>-- | If the compressed data stream is corrupted in any way then you will</span>
<a name="line-174"></a>     <span class='hs-comment'>-- get this error, for example if the input data just isn't a compressed</span>
<a name="line-175"></a>     <span class='hs-comment'>-- zlib data stream. In particular if the data checksum turns out to be</span>
<a name="line-176"></a>     <span class='hs-comment'>-- wrong then you will get all the decompressed data but this error at the</span>
<a name="line-177"></a>     <span class='hs-comment'>-- end, instead of the normal sucessful 'StreamEnd'.</span>
<a name="line-178"></a>   <span class='hs-keyglyph'>|</span> <span class='hs-conid'>DataError</span>
<a name="line-179"></a>
<a name="line-180"></a><a name="foldDecompressStream"></a><span class='hs-comment'>-- | Fold an 'DecompressionStream'. Just like 'foldr' but with an extra error</span>
<a name="line-181"></a><span class='hs-comment'>-- case. For example to convert to a list and translate the errors into</span>
<a name="line-182"></a><span class='hs-comment'>-- exceptions:</span>
<a name="line-183"></a><span class='hs-comment'>--</span>
<a name="line-184"></a><span class='hs-comment'>-- &gt; foldDecompressStream (:) [] (\code msg -&gt; error msg)</span>
<a name="line-185"></a><span class='hs-comment'>--</span>
<a name="line-186"></a><span class='hs-definition'>foldDecompressStream</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span>
<a name="line-187"></a>                 <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>DecompressError</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span>
<a name="line-188"></a>                 <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>DecompressStream</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>a</span>
<a name="line-189"></a><span class='hs-definition'>foldDecompressStream</span> <span class='hs-varid'>chunk</span> <span class='hs-varid'>end</span> <span class='hs-varid'>err</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fold</span>
<a name="line-190"></a>  <span class='hs-keyword'>where</span>
<a name="line-191"></a>    <span class='hs-varid'>fold</span> <span class='hs-conid'>StreamEnd</span>               <span class='hs-keyglyph'>=</span> <span class='hs-varid'>end</span>
<a name="line-192"></a>    <span class='hs-varid'>fold</span> <span class='hs-layout'>(</span><span class='hs-conid'>StreamChunk</span> <span class='hs-varid'>bs</span> <span class='hs-varid'>stream</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>chunk</span> <span class='hs-varid'>bs</span> <span class='hs-layout'>(</span><span class='hs-varid'>fold</span> <span class='hs-varid'>stream</span><span class='hs-layout'>)</span>
<a name="line-193"></a>    <span class='hs-varid'>fold</span> <span class='hs-layout'>(</span><span class='hs-conid'>StreamError</span> <span class='hs-varid'>code</span> <span class='hs-varid'>msg</span><span class='hs-layout'>)</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>err</span> <span class='hs-varid'>code</span> <span class='hs-varid'>msg</span>
<a name="line-194"></a>
<a name="line-195"></a><a name="fromDecompressStream"></a><span class='hs-comment'>-- | Convert a 'DecompressStream' to a lazy 'ByteString'. If any decompression</span>
<a name="line-196"></a><span class='hs-comment'>-- errors are encountered then they are thrown as exceptions.</span>
<a name="line-197"></a><span class='hs-comment'>--</span>
<a name="line-198"></a><span class='hs-comment'>-- This is a special case of 'foldDecompressStream'.</span>
<a name="line-199"></a><span class='hs-comment'>--</span>
<a name="line-200"></a><span class='hs-definition'>fromDecompressStream</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>DecompressStream</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-201"></a><span class='hs-definition'>fromDecompressStream</span> <span class='hs-keyglyph'>=</span>
<a name="line-202"></a>  <span class='hs-varid'>foldDecompressStream</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-conid'>Chunk</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-conid'>Empty</span>
<a name="line-203"></a>    <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-sel'>_code</span> <span class='hs-varid'>msg</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>error</span> <span class='hs-layout'>(</span><span class='hs-str'>"Codec.Compression.Zlib: "</span> <span class='hs-varop'>++</span> <span class='hs-varid'>msg</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-204"></a>
<a name="line-205"></a><span class='hs-comment'>--TODO: throw DecompressError as an Exception class type and document that it</span>
<a name="line-206"></a><span class='hs-comment'>-- does this.</span>
<a name="line-207"></a>
<a name="line-208"></a><a name="compress"></a><span class='hs-comment'>-- | Compress a data stream.</span>
<a name="line-209"></a><span class='hs-comment'>--</span>
<a name="line-210"></a><span class='hs-comment'>-- There are no expected error conditions. All input data streams are valid. It</span>
<a name="line-211"></a><span class='hs-comment'>-- is possible for unexpected errors to occur, such as running out of memory,</span>
<a name="line-212"></a><span class='hs-comment'>-- or finding the wrong version of the zlib C library, these are thrown as</span>
<a name="line-213"></a><span class='hs-comment'>-- exceptions.</span>
<a name="line-214"></a><span class='hs-comment'>--</span>
<a name="line-215"></a><span class='hs-definition'>compress</span>
<a name="line-216"></a>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Format</span>
<a name="line-217"></a>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CompressParams</span>
<a name="line-218"></a>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-219"></a>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-220"></a><span class='hs-definition'>compress</span> <span class='hs-varid'>format</span>
<a name="line-221"></a>  <span class='hs-layout'>(</span><span class='hs-conid'>CompressParams</span> <span class='hs-varid'>compLevel</span> <span class='hs-varid'>method</span> <span class='hs-varid'>bits</span> <span class='hs-varid'>memLevel</span> <span class='hs-varid'>strategy</span> <span class='hs-varid'>initChunkSize</span> <span class='hs-varid'>mdict</span><span class='hs-layout'>)</span>
<a name="line-222"></a>  <span class='hs-varid'>input</span> <span class='hs-keyglyph'>=</span>
<a name="line-223"></a>  <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>fromChunks</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>run</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>do</span>
<a name="line-224"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>deflateInit</span> <span class='hs-varid'>format</span> <span class='hs-varid'>compLevel</span> <span class='hs-varid'>method</span> <span class='hs-varid'>bits</span> <span class='hs-varid'>memLevel</span> <span class='hs-varid'>strategy</span>
<a name="line-225"></a>    <span class='hs-varid'>setDictionary</span> <span class='hs-varid'>mdict</span>
<a name="line-226"></a>    <span class='hs-keyword'>case</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>toChunks</span> <span class='hs-varid'>input</span> <span class='hs-keyword'>of</span>
<a name="line-227"></a>      <span class='hs-conid'>[]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>fillBuffers</span> <span class='hs-num'>20</span> <span class='hs-conid'>[]</span> <span class='hs-comment'>--gzip header is 20 bytes, others even smaller</span>
<a name="line-228"></a>      <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>PS</span> <span class='hs-varid'>inFPtr</span> <span class='hs-varid'>offset</span> <span class='hs-varid'>length</span> <span class='hs-conop'>:</span> <span class='hs-varid'>chunks</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span>
<a name="line-229"></a>        <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>pushInputBuffer</span> <span class='hs-varid'>inFPtr</span> <span class='hs-varid'>offset</span> <span class='hs-varid'>length</span>
<a name="line-230"></a>        <span class='hs-varid'>r</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>fillBuffers</span> <span class='hs-varid'>initChunkSize</span> <span class='hs-varid'>chunks</span>
<a name="line-231"></a>        <span class='hs-varid'>return</span> <span class='hs-varid'>r</span>
<a name="line-232"></a>
<a name="line-233"></a>  <span class='hs-keyword'>where</span>
<a name="line-234"></a>    <span class='hs-comment'>-- we flick between two states:</span>
<a name="line-235"></a>    <span class='hs-comment'>--   * where one or other buffer is empty</span>
<a name="line-236"></a>    <span class='hs-comment'>--       - in which case we refill one or both</span>
<a name="line-237"></a>    <span class='hs-comment'>--   * where both buffers are non-empty</span>
<a name="line-238"></a>    <span class='hs-comment'>--       - in which case we compress until a buffer is empty</span>
<a name="line-239"></a>
<a name="line-240"></a>  <span class='hs-varid'>fillBuffers</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span>
<a name="line-241"></a>              <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-keyglyph'>]</span>
<a name="line-242"></a>              <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Stream</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-keyglyph'>]</span>
<a name="line-243"></a>  <span class='hs-varid'>fillBuffers</span> <span class='hs-varid'>outChunkSize</span> <span class='hs-varid'>inChunks</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-244"></a><span class='hs-cpp'>#ifdef DEBUG</span>
<a name="line-245"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>consistencyCheck</span>
<a name="line-246"></a><span class='hs-cpp'>#endif</span>
<a name="line-247"></a>
<a name="line-248"></a>    <span class='hs-comment'>-- in this state there are two possabilities:</span>
<a name="line-249"></a>    <span class='hs-comment'>--   * no outbut buffer space is available</span>
<a name="line-250"></a>    <span class='hs-comment'>--       - in which case we must make more available</span>
<a name="line-251"></a>    <span class='hs-comment'>--   * no input buffer is available</span>
<a name="line-252"></a>    <span class='hs-comment'>--       - in which case we must supply more</span>
<a name="line-253"></a>    <span class='hs-varid'>inputBufferEmpty</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>inputBufferEmpty</span>
<a name="line-254"></a>    <span class='hs-varid'>outputBufferFull</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>outputBufferFull</span>
<a name="line-255"></a>
<a name="line-256"></a>    <span class='hs-varid'>assert</span> <span class='hs-layout'>(</span><span class='hs-varid'>inputBufferEmpty</span> <span class='hs-varop'>||</span> <span class='hs-varid'>outputBufferFull</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span>
<a name="line-257"></a>
<a name="line-258"></a>    <span class='hs-varid'>when</span> <span class='hs-varid'>outputBufferFull</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>do</span>
<a name="line-259"></a>      <span class='hs-varid'>outFPtr</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>unsafeLiftIO</span> <span class='hs-layout'>(</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-varid'>mallocByteString</span> <span class='hs-varid'>outChunkSize</span><span class='hs-layout'>)</span>
<a name="line-260"></a>      <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>pushOutputBuffer</span> <span class='hs-varid'>outFPtr</span> <span class='hs-num'>0</span> <span class='hs-varid'>outChunkSize</span>
<a name="line-261"></a>
<a name="line-262"></a>    <span class='hs-keyword'>if</span> <span class='hs-varid'>inputBufferEmpty</span>
<a name="line-263"></a>      <span class='hs-keyword'>then</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>inChunks</span> <span class='hs-keyword'>of</span>
<a name="line-264"></a>             <span class='hs-conid'>[]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>drainBuffers</span> <span class='hs-conid'>[]</span>
<a name="line-265"></a>             <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>PS</span> <span class='hs-varid'>inFPtr</span> <span class='hs-varid'>offset</span> <span class='hs-varid'>length</span> <span class='hs-conop'>:</span> <span class='hs-varid'>inChunks'</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span>
<a name="line-266"></a>                <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>pushInputBuffer</span> <span class='hs-varid'>inFPtr</span> <span class='hs-varid'>offset</span> <span class='hs-varid'>length</span>
<a name="line-267"></a>                <span class='hs-varid'>drainBuffers</span> <span class='hs-varid'>inChunks'</span>
<a name="line-268"></a>      <span class='hs-keyword'>else</span> <span class='hs-varid'>drainBuffers</span> <span class='hs-varid'>inChunks</span>
<a name="line-269"></a>
<a name="line-270"></a>
<a name="line-271"></a>  <span class='hs-varid'>drainBuffers</span> <span class='hs-keyglyph'>::</span>
<a name="line-272"></a>      <span class='hs-keyglyph'>[</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-keyglyph'>]</span>
<a name="line-273"></a>   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Stream</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-keyglyph'>]</span>
<a name="line-274"></a>  <span class='hs-varid'>drainBuffers</span> <span class='hs-varid'>inChunks</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-275"></a>
<a name="line-276"></a>    <span class='hs-varid'>inputBufferEmpty'</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>inputBufferEmpty</span>
<a name="line-277"></a>    <span class='hs-varid'>outputBufferFull'</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>outputBufferFull</span>
<a name="line-278"></a>    <span class='hs-varid'>assert</span><span class='hs-layout'>(</span><span class='hs-varid'>not</span> <span class='hs-varid'>outputBufferFull'</span>
<a name="line-279"></a>       <span class='hs-varop'>&amp;&amp;</span> <span class='hs-layout'>(</span><span class='hs-varid'>null</span> <span class='hs-varid'>inChunks</span> <span class='hs-varop'>||</span> <span class='hs-varid'>not</span> <span class='hs-varid'>inputBufferEmpty'</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span>
<a name="line-280"></a>    <span class='hs-comment'>-- this invariant guarantees we can always make forward progress</span>
<a name="line-281"></a>    <span class='hs-comment'>-- and that therefore a BufferError is impossible</span>
<a name="line-282"></a>
<a name="line-283"></a>    <span class='hs-keyword'>let</span> <span class='hs-varid'>flush</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>null</span> <span class='hs-varid'>inChunks</span> <span class='hs-keyword'>then</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Finish</span> <span class='hs-keyword'>else</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>NoFlush</span>
<a name="line-284"></a>    <span class='hs-varid'>status</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>deflate</span> <span class='hs-varid'>flush</span>
<a name="line-285"></a>
<a name="line-286"></a>    <span class='hs-keyword'>case</span> <span class='hs-varid'>status</span> <span class='hs-keyword'>of</span>
<a name="line-287"></a>      <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Ok</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span>
<a name="line-288"></a>        <span class='hs-varid'>outputBufferFull</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>outputBufferFull</span>
<a name="line-289"></a>        <span class='hs-keyword'>if</span> <span class='hs-varid'>outputBufferFull</span>
<a name="line-290"></a>          <span class='hs-keyword'>then</span> <span class='hs-keyword'>do</span> <span class='hs-layout'>(</span><span class='hs-varid'>outFPtr</span><span class='hs-layout'>,</span> <span class='hs-varid'>offset</span><span class='hs-layout'>,</span> <span class='hs-varid'>length</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>popOutputBuffer</span>
<a name="line-291"></a>                  <span class='hs-varid'>outChunks</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>unsafeInterleave</span>
<a name="line-292"></a>                    <span class='hs-layout'>(</span><span class='hs-varid'>fillBuffers</span> <span class='hs-varid'>defaultCompressBufferSize</span> <span class='hs-varid'>inChunks</span><span class='hs-layout'>)</span>
<a name="line-293"></a>                  <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>PS</span> <span class='hs-varid'>outFPtr</span> <span class='hs-varid'>offset</span> <span class='hs-varid'>length</span> <span class='hs-conop'>:</span> <span class='hs-varid'>outChunks</span><span class='hs-layout'>)</span>
<a name="line-294"></a>          <span class='hs-keyword'>else</span> <span class='hs-keyword'>do</span> <span class='hs-varid'>fillBuffers</span> <span class='hs-varid'>defaultCompressBufferSize</span> <span class='hs-varid'>inChunks</span>
<a name="line-295"></a>
<a name="line-296"></a>      <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>StreamEnd</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span>
<a name="line-297"></a>        <span class='hs-varid'>inputBufferEmpty</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>inputBufferEmpty</span>
<a name="line-298"></a>        <span class='hs-varid'>assert</span> <span class='hs-varid'>inputBufferEmpty</span> <span class='hs-varop'>$</span> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span>
<a name="line-299"></a>        <span class='hs-varid'>outputBufferBytesAvailable</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>outputBufferBytesAvailable</span>
<a name="line-300"></a>        <span class='hs-keyword'>if</span> <span class='hs-varid'>outputBufferBytesAvailable</span> <span class='hs-varop'>&gt;</span> <span class='hs-num'>0</span>
<a name="line-301"></a>          <span class='hs-keyword'>then</span> <span class='hs-keyword'>do</span> <span class='hs-layout'>(</span><span class='hs-varid'>outFPtr</span><span class='hs-layout'>,</span> <span class='hs-varid'>offset</span><span class='hs-layout'>,</span> <span class='hs-varid'>length</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>popOutputBuffer</span>
<a name="line-302"></a>                  <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>finalise</span>
<a name="line-303"></a>                  <span class='hs-varid'>return</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>PS</span> <span class='hs-varid'>outFPtr</span> <span class='hs-varid'>offset</span> <span class='hs-varid'>length</span><span class='hs-keyglyph'>]</span>
<a name="line-304"></a>          <span class='hs-keyword'>else</span> <span class='hs-keyword'>do</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>finalise</span>
<a name="line-305"></a>                  <span class='hs-varid'>return</span> <span class='hs-conid'>[]</span>
<a name="line-306"></a>
<a name="line-307"></a>      <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Error</span> <span class='hs-varid'>code</span> <span class='hs-varid'>msg</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>code</span> <span class='hs-keyword'>of</span>
<a name="line-308"></a>        <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>BufferError</span>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>fail</span> <span class='hs-str'>"BufferError should be impossible!"</span>
<a name="line-309"></a>        <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>NeedDict</span> <span class='hs-keyword'>_</span>   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>fail</span> <span class='hs-str'>"NeedDict is impossible!"</span>
<a name="line-310"></a>        <span class='hs-keyword'>_</span>                   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>fail</span> <span class='hs-varid'>msg</span>
<a name="line-311"></a>
<a name="line-312"></a>  <span class='hs-comment'>-- Set the custom dictionary, if we were provided with one</span>
<a name="line-313"></a>  <span class='hs-comment'>-- and if the format supports it (zlib and raw, not gzip).</span>
<a name="line-314"></a>  <span class='hs-varid'>setDictionary</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Maybe</span> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Stream</span> <span class='hs-conid'>()</span>
<a name="line-315"></a>  <span class='hs-varid'>setDictionary</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>dict</span><span class='hs-layout'>)</span>
<a name="line-316"></a>    <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>formatSupportsDictionary</span> <span class='hs-varid'>format</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-317"></a>        <span class='hs-varid'>status</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>deflateSetDictionary</span> <span class='hs-varid'>dict</span>
<a name="line-318"></a>        <span class='hs-keyword'>case</span> <span class='hs-varid'>status</span> <span class='hs-keyword'>of</span>
<a name="line-319"></a>          <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Ok</span>          <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span>
<a name="line-320"></a>          <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Error</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>msg</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>fail</span> <span class='hs-varid'>msg</span>
<a name="line-321"></a>          <span class='hs-keyword'>_</span>                  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>fail</span> <span class='hs-str'>"error when setting deflate dictionary"</span>
<a name="line-322"></a>  <span class='hs-varid'>setDictionary</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span>
<a name="line-323"></a>
<a name="line-324"></a>
<a name="line-325"></a><a name="decompress"></a><span class='hs-comment'>-- | Decompress a data stream.</span>
<a name="line-326"></a><span class='hs-comment'>--</span>
<a name="line-327"></a><span class='hs-comment'>-- It will throw an exception if any error is encountered in the input data. If</span>
<a name="line-328"></a><span class='hs-comment'>-- you need more control over error handling then use 'decompressWithErrors'.</span>
<a name="line-329"></a><span class='hs-comment'>--</span>
<a name="line-330"></a><span class='hs-definition'>decompress</span>
<a name="line-331"></a>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Format</span>
<a name="line-332"></a>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>DecompressParams</span>
<a name="line-333"></a>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-334"></a>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-335"></a><span class='hs-definition'>decompress</span> <span class='hs-varid'>format</span> <span class='hs-varid'>params</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fromDecompressStream</span>
<a name="line-336"></a>                         <span class='hs-varop'>.</span> <span class='hs-varid'>decompressWithErrors</span> <span class='hs-varid'>format</span> <span class='hs-varid'>params</span>
<a name="line-337"></a>
<a name="line-338"></a><a name="decompressWithErrors"></a><span class='hs-comment'>-- | Like 'decompress' but returns a 'DecompressStream' data structure that</span>
<a name="line-339"></a><span class='hs-comment'>-- contains an explicit representation of the error conditions that one may</span>
<a name="line-340"></a><span class='hs-comment'>-- encounter when decompressing.</span>
<a name="line-341"></a><span class='hs-comment'>--</span>
<a name="line-342"></a><span class='hs-comment'>-- Note that in addition to errors in the input data, it is possible for other</span>
<a name="line-343"></a><span class='hs-comment'>-- unexpected errors to occur, such as out of memory, or finding the wrong</span>
<a name="line-344"></a><span class='hs-comment'>-- version of the zlib C library, these are still thrown as exceptions (because</span>
<a name="line-345"></a><span class='hs-comment'>-- representing them as data would make this function impure).</span>
<a name="line-346"></a><span class='hs-comment'>--</span>
<a name="line-347"></a><span class='hs-definition'>decompressWithErrors</span>
<a name="line-348"></a>  <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Format</span>
<a name="line-349"></a>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>DecompressParams</span>
<a name="line-350"></a>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-351"></a>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>DecompressStream</span>
<a name="line-352"></a><span class='hs-definition'>decompressWithErrors</span> <span class='hs-varid'>format</span> <span class='hs-layout'>(</span><span class='hs-conid'>DecompressParams</span> <span class='hs-varid'>bits</span> <span class='hs-varid'>initChunkSize</span> <span class='hs-varid'>mdict</span><span class='hs-layout'>)</span> <span class='hs-varid'>input</span> <span class='hs-keyglyph'>=</span>
<a name="line-353"></a>  <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>run</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>do</span>
<a name="line-354"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>inflateInit</span> <span class='hs-varid'>format</span> <span class='hs-varid'>bits</span>
<a name="line-355"></a>    <span class='hs-keyword'>case</span> <span class='hs-conid'>L</span><span class='hs-varop'>.</span><span class='hs-varid'>toChunks</span> <span class='hs-varid'>input</span> <span class='hs-keyword'>of</span>
<a name="line-356"></a>      <span class='hs-conid'>[]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>fillBuffers</span> <span class='hs-num'>4</span> <span class='hs-conid'>[]</span> <span class='hs-comment'>--always an error anyway</span>
<a name="line-357"></a>      <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>PS</span> <span class='hs-varid'>inFPtr</span> <span class='hs-varid'>offset</span> <span class='hs-varid'>length</span> <span class='hs-conop'>:</span> <span class='hs-varid'>chunks</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span>
<a name="line-358"></a>        <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>pushInputBuffer</span> <span class='hs-varid'>inFPtr</span> <span class='hs-varid'>offset</span> <span class='hs-varid'>length</span>
<a name="line-359"></a>        <span class='hs-varid'>fillBuffers</span> <span class='hs-varid'>initChunkSize</span> <span class='hs-varid'>chunks</span>
<a name="line-360"></a>
<a name="line-361"></a>  <span class='hs-keyword'>where</span>
<a name="line-362"></a>    <span class='hs-comment'>-- we flick between two states:</span>
<a name="line-363"></a>    <span class='hs-comment'>--   * where one or other buffer is empty</span>
<a name="line-364"></a>    <span class='hs-comment'>--       - in which case we refill one or both</span>
<a name="line-365"></a>    <span class='hs-comment'>--   * where both buffers are non-empty</span>
<a name="line-366"></a>    <span class='hs-comment'>--       - in which case we compress until a buffer is empty</span>
<a name="line-367"></a>
<a name="line-368"></a>  <span class='hs-varid'>fillBuffers</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span>
<a name="line-369"></a>              <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-keyglyph'>]</span>
<a name="line-370"></a>              <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Stream</span> <span class='hs-conid'>DecompressStream</span>
<a name="line-371"></a>  <span class='hs-varid'>fillBuffers</span> <span class='hs-varid'>outChunkSize</span> <span class='hs-varid'>inChunks</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-372"></a><span class='hs-cpp'>#ifdef DEBUG</span>
<a name="line-373"></a>    <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>consistencyCheck</span>
<a name="line-374"></a><span class='hs-cpp'>#endif</span>
<a name="line-375"></a>
<a name="line-376"></a>    <span class='hs-comment'>-- in this state there are two possabilities:</span>
<a name="line-377"></a>    <span class='hs-comment'>--   * no outbut buffer space is available</span>
<a name="line-378"></a>    <span class='hs-comment'>--       - in which case we must make more available</span>
<a name="line-379"></a>    <span class='hs-comment'>--   * no input buffer is available</span>
<a name="line-380"></a>    <span class='hs-comment'>--       - in which case we must supply more</span>
<a name="line-381"></a>    <span class='hs-varid'>inputBufferEmpty</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>inputBufferEmpty</span>
<a name="line-382"></a>    <span class='hs-varid'>outputBufferFull</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>outputBufferFull</span>
<a name="line-383"></a>
<a name="line-384"></a>    <span class='hs-varid'>assert</span> <span class='hs-layout'>(</span><span class='hs-varid'>inputBufferEmpty</span> <span class='hs-varop'>||</span> <span class='hs-varid'>outputBufferFull</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span>
<a name="line-385"></a>
<a name="line-386"></a>    <span class='hs-varid'>when</span> <span class='hs-varid'>outputBufferFull</span> <span class='hs-varop'>$</span> <span class='hs-keyword'>do</span>
<a name="line-387"></a>      <span class='hs-varid'>outFPtr</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>unsafeLiftIO</span> <span class='hs-layout'>(</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-varid'>mallocByteString</span> <span class='hs-varid'>outChunkSize</span><span class='hs-layout'>)</span>
<a name="line-388"></a>      <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>pushOutputBuffer</span> <span class='hs-varid'>outFPtr</span> <span class='hs-num'>0</span> <span class='hs-varid'>outChunkSize</span>
<a name="line-389"></a>
<a name="line-390"></a>    <span class='hs-keyword'>if</span> <span class='hs-varid'>inputBufferEmpty</span>
<a name="line-391"></a>      <span class='hs-keyword'>then</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>inChunks</span> <span class='hs-keyword'>of</span>
<a name="line-392"></a>             <span class='hs-conid'>[]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>drainBuffers</span> <span class='hs-conid'>[]</span>
<a name="line-393"></a>             <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>PS</span> <span class='hs-varid'>inFPtr</span> <span class='hs-varid'>offset</span> <span class='hs-varid'>length</span> <span class='hs-conop'>:</span> <span class='hs-varid'>inChunks'</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span>
<a name="line-394"></a>                <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>pushInputBuffer</span> <span class='hs-varid'>inFPtr</span> <span class='hs-varid'>offset</span> <span class='hs-varid'>length</span>
<a name="line-395"></a>                <span class='hs-varid'>drainBuffers</span> <span class='hs-varid'>inChunks'</span>
<a name="line-396"></a>      <span class='hs-keyword'>else</span> <span class='hs-varid'>drainBuffers</span> <span class='hs-varid'>inChunks</span>
<a name="line-397"></a>
<a name="line-398"></a>
<a name="line-399"></a>  <span class='hs-varid'>drainBuffers</span> <span class='hs-keyglyph'>::</span>
<a name="line-400"></a>      <span class='hs-keyglyph'>[</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span><span class='hs-keyglyph'>]</span>
<a name="line-401"></a>   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Stream</span> <span class='hs-conid'>DecompressStream</span>
<a name="line-402"></a>  <span class='hs-varid'>drainBuffers</span> <span class='hs-varid'>inChunks</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-403"></a>
<a name="line-404"></a>    <span class='hs-varid'>inputBufferEmpty'</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>inputBufferEmpty</span>
<a name="line-405"></a>    <span class='hs-varid'>outputBufferFull'</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>outputBufferFull</span>
<a name="line-406"></a>    <span class='hs-varid'>assert</span><span class='hs-layout'>(</span><span class='hs-varid'>not</span> <span class='hs-varid'>outputBufferFull'</span>
<a name="line-407"></a>       <span class='hs-varop'>&amp;&amp;</span> <span class='hs-layout'>(</span><span class='hs-varid'>null</span> <span class='hs-varid'>inChunks</span> <span class='hs-varop'>||</span> <span class='hs-varid'>not</span> <span class='hs-varid'>inputBufferEmpty'</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span> <span class='hs-varid'>return</span> <span class='hs-conid'>()</span>
<a name="line-408"></a>    <span class='hs-comment'>-- this invariant guarantees we can always make forward progress or at</span>
<a name="line-409"></a>    <span class='hs-comment'>-- least if a BufferError does occur that it must be due to a premature EOF</span>
<a name="line-410"></a>
<a name="line-411"></a>    <span class='hs-varid'>status</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>inflate</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>NoFlush</span>
<a name="line-412"></a>
<a name="line-413"></a>    <span class='hs-keyword'>case</span> <span class='hs-varid'>status</span> <span class='hs-keyword'>of</span>
<a name="line-414"></a>      <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Ok</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span>
<a name="line-415"></a>        <span class='hs-varid'>outputBufferFull</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>outputBufferFull</span>
<a name="line-416"></a>        <span class='hs-keyword'>if</span> <span class='hs-varid'>outputBufferFull</span>
<a name="line-417"></a>          <span class='hs-keyword'>then</span> <span class='hs-keyword'>do</span> <span class='hs-layout'>(</span><span class='hs-varid'>outFPtr</span><span class='hs-layout'>,</span> <span class='hs-varid'>offset</span><span class='hs-layout'>,</span> <span class='hs-varid'>length</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>popOutputBuffer</span>
<a name="line-418"></a>                  <span class='hs-varid'>outChunks</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>unsafeInterleave</span>
<a name="line-419"></a>                    <span class='hs-layout'>(</span><span class='hs-varid'>fillBuffers</span> <span class='hs-varid'>defaultDecompressBufferSize</span> <span class='hs-varid'>inChunks</span><span class='hs-layout'>)</span>
<a name="line-420"></a>                  <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-conid'>StreamChunk</span> <span class='hs-layout'>(</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>PS</span> <span class='hs-varid'>outFPtr</span> <span class='hs-varid'>offset</span> <span class='hs-varid'>length</span><span class='hs-layout'>)</span> <span class='hs-varid'>outChunks</span>
<a name="line-421"></a>          <span class='hs-keyword'>else</span> <span class='hs-keyword'>do</span> <span class='hs-varid'>fillBuffers</span> <span class='hs-varid'>defaultDecompressBufferSize</span> <span class='hs-varid'>inChunks</span>
<a name="line-422"></a>
<a name="line-423"></a>      <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>StreamEnd</span>      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>inChunks</span> <span class='hs-varop'>`seq`</span> <span class='hs-varid'>finish</span> <span class='hs-conid'>StreamEnd</span>
<a name="line-424"></a>        <span class='hs-comment'>-- The decompressor tells us we're done, but that doesn't mean we have</span>
<a name="line-425"></a>        <span class='hs-comment'>-- consumed all the input (there could be trailing data). But more</span>
<a name="line-426"></a>        <span class='hs-comment'>-- subtle than that, the decompressor will actually never demand the</span>
<a name="line-427"></a>        <span class='hs-comment'>-- tail of the input (in the usual case where it's empty) because</span>
<a name="line-428"></a>        <span class='hs-comment'>-- the zlib and gzip formats know their own length. So we force the</span>
<a name="line-429"></a>        <span class='hs-comment'>-- tail of the input here because this can be important for closing</span>
<a name="line-430"></a>        <span class='hs-comment'>-- file handles etc.</span>
<a name="line-431"></a>
<a name="line-432"></a>      <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Error</span> <span class='hs-varid'>code</span> <span class='hs-varid'>msg</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>code</span> <span class='hs-keyword'>of</span>
<a name="line-433"></a>        <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>BufferError</span>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>finish</span> <span class='hs-layout'>(</span><span class='hs-conid'>StreamError</span> <span class='hs-conid'>TruncatedInput</span> <span class='hs-varid'>msg'</span><span class='hs-layout'>)</span>
<a name="line-434"></a>          <span class='hs-keyword'>where</span> <span class='hs-varid'>msg'</span> <span class='hs-keyglyph'>=</span> <span class='hs-str'>"premature end of compressed stream"</span>
<a name="line-435"></a>        <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>NeedDict</span> <span class='hs-varid'>adler</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span>
<a name="line-436"></a>          <span class='hs-varid'>err</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>setDictionary</span> <span class='hs-varid'>adler</span> <span class='hs-varid'>mdict</span>
<a name="line-437"></a>          <span class='hs-keyword'>case</span> <span class='hs-varid'>err</span> <span class='hs-keyword'>of</span>
<a name="line-438"></a>            <span class='hs-conid'>Just</span> <span class='hs-varid'>streamErr</span>  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>finish</span> <span class='hs-varid'>streamErr</span>
<a name="line-439"></a>            <span class='hs-conid'>Nothing</span>         <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>drainBuffers</span> <span class='hs-varid'>inChunks</span>
<a name="line-440"></a>        <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>DataError</span>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>finish</span> <span class='hs-layout'>(</span><span class='hs-conid'>StreamError</span> <span class='hs-conid'>DataError</span> <span class='hs-varid'>msg</span><span class='hs-layout'>)</span>
<a name="line-441"></a>        <span class='hs-keyword'>_</span>                   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>fail</span> <span class='hs-varid'>msg</span>
<a name="line-442"></a>
<a name="line-443"></a>  <span class='hs-comment'>-- Note even if we end with an error we still try to flush the last chunk if</span>
<a name="line-444"></a>  <span class='hs-comment'>-- there is one. The user just has to decide what they want to trust.</span>
<a name="line-445"></a>  <span class='hs-varid'>finish</span> <span class='hs-varid'>end</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-446"></a>    <span class='hs-comment'>-- Note that there may be input bytes still available if the stream</span>
<a name="line-447"></a>    <span class='hs-comment'>-- is embeded in some other data stream. Here we just silently discard</span>
<a name="line-448"></a>    <span class='hs-comment'>-- any trailing data.</span>
<a name="line-449"></a>    <span class='hs-varid'>outputBufferBytesAvailable</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>outputBufferBytesAvailable</span>
<a name="line-450"></a>    <span class='hs-keyword'>if</span> <span class='hs-varid'>outputBufferBytesAvailable</span> <span class='hs-varop'>&gt;</span> <span class='hs-num'>0</span>
<a name="line-451"></a>      <span class='hs-keyword'>then</span> <span class='hs-keyword'>do</span> <span class='hs-layout'>(</span><span class='hs-varid'>outFPtr</span><span class='hs-layout'>,</span> <span class='hs-varid'>offset</span><span class='hs-layout'>,</span> <span class='hs-varid'>length</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>popOutputBuffer</span>
<a name="line-452"></a>              <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>finalise</span>
<a name="line-453"></a>              <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-conid'>StreamChunk</span> <span class='hs-layout'>(</span><span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>PS</span> <span class='hs-varid'>outFPtr</span> <span class='hs-varid'>offset</span> <span class='hs-varid'>length</span><span class='hs-layout'>)</span> <span class='hs-varid'>end</span><span class='hs-layout'>)</span>
<a name="line-454"></a>      <span class='hs-keyword'>else</span> <span class='hs-keyword'>do</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>finalise</span>
<a name="line-455"></a>              <span class='hs-varid'>return</span> <span class='hs-varid'>end</span>
<a name="line-456"></a>
<a name="line-457"></a>  <span class='hs-varid'>setDictionary</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>DictionaryHash</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-conid'>S</span><span class='hs-varop'>.</span><span class='hs-conid'>ByteString</span>
<a name="line-458"></a>                <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Stream</span> <span class='hs-layout'>(</span><span class='hs-conid'>Maybe</span> <span class='hs-conid'>DecompressStream</span><span class='hs-layout'>)</span>
<a name="line-459"></a>  <span class='hs-varid'>setDictionary</span> <span class='hs-sel'>_adler</span> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>=</span>
<a name="line-460"></a>    <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>StreamError</span> <span class='hs-conid'>DictionaryRequired</span> <span class='hs-str'>"custom dictionary needed"</span><span class='hs-layout'>)</span>
<a name="line-461"></a>  <span class='hs-varid'>setDictionary</span> <span class='hs-sel'>_adler</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-varid'>dict</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-462"></a>    <span class='hs-varid'>status</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-varid'>inflateSetDictionary</span> <span class='hs-varid'>dict</span>
<a name="line-463"></a>    <span class='hs-keyword'>case</span> <span class='hs-varid'>status</span> <span class='hs-keyword'>of</span>
<a name="line-464"></a>      <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Ok</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>return</span> <span class='hs-conid'>Nothing</span>
<a name="line-465"></a>      <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Error</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>StreamError</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-466"></a>        <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>StreamError</span> <span class='hs-conid'>DictionaryRequired</span> <span class='hs-str'>"provided dictionary not valid"</span><span class='hs-layout'>)</span>
<a name="line-467"></a>      <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>Error</span> <span class='hs-conid'>Stream</span><span class='hs-varop'>.</span><span class='hs-conid'>DataError</span> <span class='hs-keyword'>_</span>   <span class='hs-keyglyph'>-&gt;</span>
<a name="line-468"></a>        <span class='hs-varid'>return</span> <span class='hs-varop'>$</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>StreamError</span> <span class='hs-conid'>DictionaryRequired</span> <span class='hs-str'>"given dictionary does not match the expected one"</span><span class='hs-layout'>)</span>
<a name="line-469"></a>      <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>fail</span> <span class='hs-str'>"error when setting inflate dictionary"</span>
</pre></body>
</html>