~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to contrib/NSch/NSch.ZLib/Inflate.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
 
3
 
 
4
Redistribution and use in source and binary forms, with or without
 
5
modification, are permitted provided that the following conditions are met:
 
6
 
 
7
  1. Redistributions of source code must retain the above copyright notice,
 
8
     this list of conditions and the following disclaimer.
 
9
 
 
10
  2. Redistributions in binary form must reproduce the above copyright 
 
11
     notice, this list of conditions and the following disclaimer in 
 
12
     the documentation and/or other materials provided with the distribution.
 
13
 
 
14
  3. The names of the authors may not be used to endorse or promote products
 
15
     derived from this software without specific prior written permission.
 
16
 
 
17
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 
18
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 
19
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 
20
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 
21
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
22
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 
23
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 
24
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 
25
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 
26
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 
 
28
This program is based on zlib-1.1.3, so all credit should go authors
 
29
Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
 
30
and contributors of zlib.
 
31
*/
 
32
 
 
33
using NSch.ZLib;
 
34
using Sharpen;
 
35
 
 
36
namespace NSch.ZLib
 
37
{
 
38
        internal sealed class Inflate
 
39
        {
 
40
                private const int MAX_WBITS = 15;
 
41
 
 
42
                private const int PRESET_DICT = unchecked((int)(0x20));
 
43
 
 
44
                internal const int Z_NO_FLUSH = 0;
 
45
 
 
46
                internal const int Z_PARTIAL_FLUSH = 1;
 
47
 
 
48
                internal const int Z_SYNC_FLUSH = 2;
 
49
 
 
50
                internal const int Z_FULL_FLUSH = 3;
 
51
 
 
52
                internal const int Z_FINISH = 4;
 
53
 
 
54
                private const int Z_DEFLATED = 8;
 
55
 
 
56
                private const int Z_OK = 0;
 
57
 
 
58
                private const int Z_STREAM_END = 1;
 
59
 
 
60
                private const int Z_NEED_DICT = 2;
 
61
 
 
62
                private const int Z_ERRNO = -1;
 
63
 
 
64
                private const int Z_STREAM_ERROR = -2;
 
65
 
 
66
                private const int Z_DATA_ERROR = -3;
 
67
 
 
68
                private const int Z_MEM_ERROR = -4;
 
69
 
 
70
                private const int Z_BUF_ERROR = -5;
 
71
 
 
72
                private const int Z_VERSION_ERROR = -6;
 
73
 
 
74
                private const int METHOD = 0;
 
75
 
 
76
                private const int FLAG = 1;
 
77
 
 
78
                private const int DICT4 = 2;
 
79
 
 
80
                private const int DICT3 = 3;
 
81
 
 
82
                private const int DICT2 = 4;
 
83
 
 
84
                private const int DICT1 = 5;
 
85
 
 
86
                private const int DICT0 = 6;
 
87
 
 
88
                private const int BLOCKS = 7;
 
89
 
 
90
                private const int CHECK4 = 8;
 
91
 
 
92
                private const int CHECK3 = 9;
 
93
 
 
94
                private const int CHECK2 = 10;
 
95
 
 
96
                private const int CHECK1 = 11;
 
97
 
 
98
                private const int DONE = 12;
 
99
 
 
100
                private const int BAD = 13;
 
101
 
 
102
                internal int mode;
 
103
 
 
104
                internal int method;
 
105
 
 
106
                internal long[] was = new long[1];
 
107
 
 
108
                internal long need;
 
109
 
 
110
                internal int marker;
 
111
 
 
112
                internal int nowrap;
 
113
 
 
114
                internal int wbits;
 
115
 
 
116
                internal InfBlocks blocks;
 
117
 
 
118
                // 32K LZ77 window
 
119
                // preset dictionary flag in zlib header
 
120
                // waiting for method byte
 
121
                // waiting for flag byte
 
122
                // four dictionary check bytes to go
 
123
                // three dictionary check bytes to go
 
124
                // two dictionary check bytes to go
 
125
                // one dictionary check byte to go
 
126
                // waiting for inflateSetDictionary
 
127
                // decompressing blocks
 
128
                // four check bytes to go
 
129
                // three check bytes to go
 
130
                // two check bytes to go
 
131
                // one check byte to go
 
132
                // finished check, done
 
133
                // got an error--stay here
 
134
                // current inflate mode
 
135
                // mode dependent information
 
136
                // if FLAGS, method byte
 
137
                // if CHECK, check values to compare
 
138
                // computed check value
 
139
                // stream check value
 
140
                // if BAD, inflateSync's marker bytes count
 
141
                // mode independent information
 
142
                // flag for no wrapper
 
143
                // log2(window size)  (8..15, defaults to 15)
 
144
                // current inflate_blocks state
 
145
                internal int InflateReset(ZStream z)
 
146
                {
 
147
                        if (z == null || z.istate == null)
 
148
                        {
 
149
                                return Z_STREAM_ERROR;
 
150
                        }
 
151
                        z.total_in = z.total_out = 0;
 
152
                        z.msg = null;
 
153
                        z.istate.mode = z.istate.nowrap != 0 ? BLOCKS : METHOD;
 
154
                        z.istate.blocks.Reset(z, null);
 
155
                        return Z_OK;
 
156
                }
 
157
 
 
158
                internal int InflateEnd(ZStream z)
 
159
                {
 
160
                        if (blocks != null)
 
161
                        {
 
162
                                blocks.Free(z);
 
163
                        }
 
164
                        blocks = null;
 
165
                        //    ZFREE(z, z->state);
 
166
                        return Z_OK;
 
167
                }
 
168
 
 
169
                internal int InflateInit(ZStream z, int w)
 
170
                {
 
171
                        z.msg = null;
 
172
                        blocks = null;
 
173
                        // handle undocumented nowrap option (no zlib header or check)
 
174
                        nowrap = 0;
 
175
                        if (w < 0)
 
176
                        {
 
177
                                w = -w;
 
178
                                nowrap = 1;
 
179
                        }
 
180
                        // set window size
 
181
                        if (w < 8 || w > 15)
 
182
                        {
 
183
                                InflateEnd(z);
 
184
                                return Z_STREAM_ERROR;
 
185
                        }
 
186
                        wbits = w;
 
187
                        z.istate.blocks = new InfBlocks(z, z.istate.nowrap != 0 ? null : this, 1 << w);
 
188
                        // reset state
 
189
                        InflateReset(z);
 
190
                        return Z_OK;
 
191
                }
 
192
 
 
193
                internal int DoInflate(ZStream z, int f)
 
194
                {
 
195
                        int r;
 
196
                        int b;
 
197
                        if (z == null || z.istate == null || z.next_in == null)
 
198
                        {
 
199
                                return Z_STREAM_ERROR;
 
200
                        }
 
201
                        f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
 
202
                        r = Z_BUF_ERROR;
 
203
                        while (true)
 
204
                        {
 
205
                                switch (z.istate.mode)
 
206
                                {
 
207
                                        case METHOD:
 
208
                                        {
 
209
                                                //System.out.println("mode: "+z.istate.mode);
 
210
                                                if (z.avail_in == 0)
 
211
                                                {
 
212
                                                        return r;
 
213
                                                }
 
214
                                                r = f;
 
215
                                                z.avail_in--;
 
216
                                                z.total_in++;
 
217
                                                if (((z.istate.method = z.next_in[z.next_in_index++]) & unchecked((int)(0xf))) !=
 
218
                                                         Z_DEFLATED)
 
219
                                                {
 
220
                                                        z.istate.mode = BAD;
 
221
                                                        z.msg = "unknown compression method";
 
222
                                                        z.istate.marker = 5;
 
223
                                                        // can't try inflateSync
 
224
                                                        break;
 
225
                                                }
 
226
                                                if ((z.istate.method >> 4) + 8 > z.istate.wbits)
 
227
                                                {
 
228
                                                        z.istate.mode = BAD;
 
229
                                                        z.msg = "invalid window size";
 
230
                                                        z.istate.marker = 5;
 
231
                                                        // can't try inflateSync
 
232
                                                        break;
 
233
                                                }
 
234
                                                z.istate.mode = FLAG;
 
235
                                                goto case FLAG;
 
236
                                        }
 
237
 
 
238
                                        case FLAG:
 
239
                                        {
 
240
                                                if (z.avail_in == 0)
 
241
                                                {
 
242
                                                        return r;
 
243
                                                }
 
244
                                                r = f;
 
245
                                                z.avail_in--;
 
246
                                                z.total_in++;
 
247
                                                b = (z.next_in[z.next_in_index++]) & unchecked((int)(0xff));
 
248
                                                if ((((z.istate.method << 8) + b) % 31) != 0)
 
249
                                                {
 
250
                                                        z.istate.mode = BAD;
 
251
                                                        z.msg = "incorrect header check";
 
252
                                                        z.istate.marker = 5;
 
253
                                                        // can't try inflateSync
 
254
                                                        break;
 
255
                                                }
 
256
                                                if ((b & PRESET_DICT) == 0)
 
257
                                                {
 
258
                                                        z.istate.mode = BLOCKS;
 
259
                                                        break;
 
260
                                                }
 
261
                                                z.istate.mode = DICT4;
 
262
                                                goto case DICT4;
 
263
                                        }
 
264
 
 
265
                                        case DICT4:
 
266
                                        {
 
267
                                                if (z.avail_in == 0)
 
268
                                                {
 
269
                                                        return r;
 
270
                                                }
 
271
                                                r = f;
 
272
                                                z.avail_in--;
 
273
                                                z.total_in++;
 
274
                                                z.istate.need = ((z.next_in[z.next_in_index++] & unchecked((int)(0xff))) << 24) &
 
275
                                                         unchecked((long)(0xff000000L));
 
276
                                                z.istate.mode = DICT3;
 
277
                                                goto case DICT3;
 
278
                                        }
 
279
 
 
280
                                        case DICT3:
 
281
                                        {
 
282
                                                if (z.avail_in == 0)
 
283
                                                {
 
284
                                                        return r;
 
285
                                                }
 
286
                                                r = f;
 
287
                                                z.avail_in--;
 
288
                                                z.total_in++;
 
289
                                                z.istate.need += ((z.next_in[z.next_in_index++] & unchecked((int)(0xff))) << 16) 
 
290
                                                        & unchecked((long)(0xff0000L));
 
291
                                                z.istate.mode = DICT2;
 
292
                                                goto case DICT2;
 
293
                                        }
 
294
 
 
295
                                        case DICT2:
 
296
                                        {
 
297
                                                if (z.avail_in == 0)
 
298
                                                {
 
299
                                                        return r;
 
300
                                                }
 
301
                                                r = f;
 
302
                                                z.avail_in--;
 
303
                                                z.total_in++;
 
304
                                                z.istate.need += ((z.next_in[z.next_in_index++] & unchecked((int)(0xff))) << 8) &
 
305
                                                         unchecked((long)(0xff00L));
 
306
                                                z.istate.mode = DICT1;
 
307
                                                goto case DICT1;
 
308
                                        }
 
309
 
 
310
                                        case DICT1:
 
311
                                        {
 
312
                                                if (z.avail_in == 0)
 
313
                                                {
 
314
                                                        return r;
 
315
                                                }
 
316
                                                r = f;
 
317
                                                z.avail_in--;
 
318
                                                z.total_in++;
 
319
                                                z.istate.need += (z.next_in[z.next_in_index++] & unchecked((long)(0xffL)));
 
320
                                                z.adler = z.istate.need;
 
321
                                                z.istate.mode = DICT0;
 
322
                                                return Z_NEED_DICT;
 
323
                                        }
 
324
 
 
325
                                        case DICT0:
 
326
                                        {
 
327
                                                z.istate.mode = BAD;
 
328
                                                z.msg = "need dictionary";
 
329
                                                z.istate.marker = 0;
 
330
                                                // can try inflateSync
 
331
                                                return Z_STREAM_ERROR;
 
332
                                        }
 
333
 
 
334
                                        case BLOCKS:
 
335
                                        {
 
336
                                                r = z.istate.blocks.Proc(z, r);
 
337
                                                if (r == Z_DATA_ERROR)
 
338
                                                {
 
339
                                                        z.istate.mode = BAD;
 
340
                                                        z.istate.marker = 0;
 
341
                                                        // can try inflateSync
 
342
                                                        break;
 
343
                                                }
 
344
                                                if (r == Z_OK)
 
345
                                                {
 
346
                                                        r = f;
 
347
                                                }
 
348
                                                if (r != Z_STREAM_END)
 
349
                                                {
 
350
                                                        return r;
 
351
                                                }
 
352
                                                r = f;
 
353
                                                z.istate.blocks.Reset(z, z.istate.was);
 
354
                                                if (z.istate.nowrap != 0)
 
355
                                                {
 
356
                                                        z.istate.mode = DONE;
 
357
                                                        break;
 
358
                                                }
 
359
                                                z.istate.mode = CHECK4;
 
360
                                                goto case CHECK4;
 
361
                                        }
 
362
 
 
363
                                        case CHECK4:
 
364
                                        {
 
365
                                                if (z.avail_in == 0)
 
366
                                                {
 
367
                                                        return r;
 
368
                                                }
 
369
                                                r = f;
 
370
                                                z.avail_in--;
 
371
                                                z.total_in++;
 
372
                                                z.istate.need = ((z.next_in[z.next_in_index++] & unchecked((int)(0xff))) << 24) &
 
373
                                                         unchecked((long)(0xff000000L));
 
374
                                                z.istate.mode = CHECK3;
 
375
                                                goto case CHECK3;
 
376
                                        }
 
377
 
 
378
                                        case CHECK3:
 
379
                                        {
 
380
                                                if (z.avail_in == 0)
 
381
                                                {
 
382
                                                        return r;
 
383
                                                }
 
384
                                                r = f;
 
385
                                                z.avail_in--;
 
386
                                                z.total_in++;
 
387
                                                z.istate.need += ((z.next_in[z.next_in_index++] & unchecked((int)(0xff))) << 16) 
 
388
                                                        & unchecked((long)(0xff0000L));
 
389
                                                z.istate.mode = CHECK2;
 
390
                                                goto case CHECK2;
 
391
                                        }
 
392
 
 
393
                                        case CHECK2:
 
394
                                        {
 
395
                                                if (z.avail_in == 0)
 
396
                                                {
 
397
                                                        return r;
 
398
                                                }
 
399
                                                r = f;
 
400
                                                z.avail_in--;
 
401
                                                z.total_in++;
 
402
                                                z.istate.need += ((z.next_in[z.next_in_index++] & unchecked((int)(0xff))) << 8) &
 
403
                                                         unchecked((long)(0xff00L));
 
404
                                                z.istate.mode = CHECK1;
 
405
                                                goto case CHECK1;
 
406
                                        }
 
407
 
 
408
                                        case CHECK1:
 
409
                                        {
 
410
                                                if (z.avail_in == 0)
 
411
                                                {
 
412
                                                        return r;
 
413
                                                }
 
414
                                                r = f;
 
415
                                                z.avail_in--;
 
416
                                                z.total_in++;
 
417
                                                z.istate.need += (z.next_in[z.next_in_index++] & unchecked((long)(0xffL)));
 
418
                                                if (((int)(z.istate.was[0])) != ((int)(z.istate.need)))
 
419
                                                {
 
420
                                                        z.istate.mode = BAD;
 
421
                                                        z.msg = "incorrect data check";
 
422
                                                        z.istate.marker = 5;
 
423
                                                        // can't try inflateSync
 
424
                                                        break;
 
425
                                                }
 
426
                                                z.istate.mode = DONE;
 
427
                                                goto case DONE;
 
428
                                        }
 
429
 
 
430
                                        case DONE:
 
431
                                        {
 
432
                                                return Z_STREAM_END;
 
433
                                        }
 
434
 
 
435
                                        case BAD:
 
436
                                        {
 
437
                                                return Z_DATA_ERROR;
 
438
                                        }
 
439
 
 
440
                                        default:
 
441
                                        {
 
442
                                                return Z_STREAM_ERROR;
 
443
                                                break;
 
444
                                        }
 
445
                                }
 
446
                        }
 
447
                }
 
448
 
 
449
                internal int InflateSetDictionary(ZStream z, byte[] dictionary, int dictLength)
 
450
                {
 
451
                        int index = 0;
 
452
                        int length = dictLength;
 
453
                        if (z == null || z.istate == null || z.istate.mode != DICT0)
 
454
                        {
 
455
                                return Z_STREAM_ERROR;
 
456
                        }
 
457
                        if (z._adler.Adler(1L, dictionary, 0, dictLength) != z.adler)
 
458
                        {
 
459
                                return Z_DATA_ERROR;
 
460
                        }
 
461
                        z.adler = z._adler.Adler(0, null, 0, 0);
 
462
                        if (length >= (1 << z.istate.wbits))
 
463
                        {
 
464
                                length = (1 << z.istate.wbits) - 1;
 
465
                                index = dictLength - length;
 
466
                        }
 
467
                        z.istate.blocks.Set_dictionary(dictionary, index, length);
 
468
                        z.istate.mode = BLOCKS;
 
469
                        return Z_OK;
 
470
                }
 
471
 
 
472
                private static byte[] mark = new byte[] { unchecked((byte)0), unchecked((byte)0), 
 
473
                        unchecked((byte)unchecked((int)(0xff))), unchecked((byte)unchecked((int)(0xff)))
 
474
                         };
 
475
 
 
476
                internal int InflateSync(ZStream z)
 
477
                {
 
478
                        int n;
 
479
                        // number of bytes to look at
 
480
                        int p;
 
481
                        // pointer to bytes
 
482
                        int m;
 
483
                        // number of marker bytes found in a row
 
484
                        long r;
 
485
                        long w;
 
486
                        // temporaries to save total_in and total_out
 
487
                        // set up
 
488
                        if (z == null || z.istate == null)
 
489
                        {
 
490
                                return Z_STREAM_ERROR;
 
491
                        }
 
492
                        if (z.istate.mode != BAD)
 
493
                        {
 
494
                                z.istate.mode = BAD;
 
495
                                z.istate.marker = 0;
 
496
                        }
 
497
                        if ((n = z.avail_in) == 0)
 
498
                        {
 
499
                                return Z_BUF_ERROR;
 
500
                        }
 
501
                        p = z.next_in_index;
 
502
                        m = z.istate.marker;
 
503
                        // search
 
504
                        while (n != 0 && m < 4)
 
505
                        {
 
506
                                if (z.next_in[p] == mark[m])
 
507
                                {
 
508
                                        m++;
 
509
                                }
 
510
                                else
 
511
                                {
 
512
                                        if (z.next_in[p] != 0)
 
513
                                        {
 
514
                                                m = 0;
 
515
                                        }
 
516
                                        else
 
517
                                        {
 
518
                                                m = 4 - m;
 
519
                                        }
 
520
                                }
 
521
                                p++;
 
522
                                n--;
 
523
                        }
 
524
                        // restore
 
525
                        z.total_in += p - z.next_in_index;
 
526
                        z.next_in_index = p;
 
527
                        z.avail_in = n;
 
528
                        z.istate.marker = m;
 
529
                        // return no joy or set up to restart on a new block
 
530
                        if (m != 4)
 
531
                        {
 
532
                                return Z_DATA_ERROR;
 
533
                        }
 
534
                        r = z.total_in;
 
535
                        w = z.total_out;
 
536
                        InflateReset(z);
 
537
                        z.total_in = r;
 
538
                        z.total_out = w;
 
539
                        z.istate.mode = BLOCKS;
 
540
                        return Z_OK;
 
541
                }
 
542
 
 
543
                // Returns true if inflate is currently at the end of a block generated
 
544
                // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
 
545
                // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
 
546
                // but removes the length bytes of the resulting empty stored block. When
 
547
                // decompressing, PPP checks that at the end of input packet, inflate is
 
548
                // waiting for these length bytes.
 
549
                internal int InflateSyncPoint(ZStream z)
 
550
                {
 
551
                        if (z == null || z.istate == null || z.istate.blocks == null)
 
552
                        {
 
553
                                return Z_STREAM_ERROR;
 
554
                        }
 
555
                        return z.istate.blocks.Sync_point();
 
556
                }
 
557
        }
 
558
}