root/branches/Abonament/BazaReklam.Updater/ICSharpCode.SharpZipLib/BZip2/BZip2InputStream.cs @ 754

Wersja 597, 24.8 KB (wprowadzona przez marek, 17 years temu)

re #165

Line 
1// BZip2InputStream.cs
2//
3// Copyright (C) 2001 Mike Krueger
4//
5// This program is free software; you can redistribute it and/or
6// modify it under the terms of the GNU General Public License
7// as published by the Free Software Foundation; either version 2
8// of the License, or (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18//
19// Linking this library statically or dynamically with other modules is
20// making a combined work based on this library.  Thus, the terms and
21// conditions of the GNU General Public License cover the whole
22// combination.
23//
24// As a special exception, the copyright holders of this library give you
25// permission to link this library with independent modules to produce an
26// executable, regardless of the license terms of these independent
27// modules, and to copy and distribute the resulting executable under
28// terms of your choice, provided that you also meet, for each linked
29// independent module, the terms and conditions of the license of that
30// module.  An independent module is a module which is not derived from
31// or based on this library.  If you modify this library, you may extend
32// this exception to your version of the library, but you are not
33// obligated to do so.  If you do not wish to do so, delete this
34// exception statement from your version.
35
36using System;
37using System.IO;
38
39using ICSharpCode.SharpZipLib.Checksums;
40
41namespace ICSharpCode.SharpZipLib.BZip2
42{
43       
44        /// <summary>
45        /// An input stream that decompresses files in the BZip2 format
46        /// </summary>
47        public class BZip2InputStream : Stream
48        {
49                #region Constants
50                const int START_BLOCK_STATE = 1;
51                const int RAND_PART_A_STATE = 2;
52                const int RAND_PART_B_STATE = 3;
53                const int RAND_PART_C_STATE = 4;
54                const int NO_RAND_PART_A_STATE = 5;
55                const int NO_RAND_PART_B_STATE = 6;
56                const int NO_RAND_PART_C_STATE = 7;
57                #endregion
58                #region Constructors
59                /// <summary>
60                /// Construct instance for reading from stream
61                /// </summary>
62                /// <param name="stream">Data source</param>
63                public BZip2InputStream(Stream stream)
64                {
65                        // init arrays
66                        for (int i = 0; i < BZip2Constants.GroupCount; ++i)
67                        {
68                                limit[i] = new int[BZip2Constants.MaximumAlphaSize];
69                                baseArray[i]  = new int[BZip2Constants.MaximumAlphaSize];
70                                perm[i]  = new int[BZip2Constants.MaximumAlphaSize];
71                        }
72                       
73                        BsSetStream(stream);
74                        Initialize();
75                        InitBlock();
76                        SetupBlock();
77                }
78               
79                #endregion
80
81                /// <summary>
82                /// Get/set flag indicating ownership of underlying stream.
83                /// When the flag is true <see cref="Close"></see> will close the underlying stream also.
84                /// </summary>
85                public bool IsStreamOwner
86                {
87                        get { return isStreamOwner; }
88                        set { isStreamOwner = value; }
89                }
90               
91
92                #region Stream Overrides
93                /// <summary>
94                /// Gets a value indicating if the stream supports reading
95                /// </summary>
96                public override bool CanRead
97                {
98                        get {
99                                return baseStream.CanRead;
100                        }
101                }
102               
103                /// <summary>
104                /// Gets a value indicating whether the current stream supports seeking.
105                /// </summary>
106                public override bool CanSeek {
107                        get {
108                                return baseStream.CanSeek;
109                        }
110                }
111               
112                /// <summary>
113                /// Gets a value indicating whether the current stream supports writing.
114                /// This property always returns false
115                /// </summary>
116                public override bool CanWrite {
117                        get {
118                                return false;
119                        }
120                }
121               
122                /// <summary>
123                /// Gets the length in bytes of the stream.
124                /// </summary>
125                public override long Length {
126                        get {
127                                return baseStream.Length;
128                        }
129                }
130               
131                /// <summary>
132                /// Gets or sets the streams position.
133                /// Setting the position is not supported and will throw a NotSupportException
134                /// </summary>
135                /// <exception cref="NotSupportedException">Any attempt to set the position</exception>
136                public override long Position {
137                        get {
138                                return baseStream.Position;
139                        }
140                        set {
141                                throw new NotSupportedException("BZip2InputStream position cannot be set");
142                        }
143                }
144               
145                /// <summary>
146                /// Flushes the stream.
147                /// </summary>
148                public override void Flush()
149                {
150                        if (baseStream != null) {
151                                baseStream.Flush();
152                        }
153                }
154               
155                /// <summary>
156                /// Set the streams position.  This operation is not supported and will throw a NotSupportedException
157                /// </summary>
158                /// <param name="offset">A byte offset relative to the <paramref name="origin"/> parameter.</param>
159                /// <param name="origin">A value of type <see cref="SeekOrigin"/> indicating the reference point used to obtain the new position.</param>
160                /// <returns>The new position of the stream.</returns>
161                /// <exception cref="NotSupportedException">Any access</exception>
162                public override long Seek(long offset, SeekOrigin origin)
163                {
164                        throw new NotSupportedException("BZip2InputStream Seek not supported");
165                }
166               
167                /// <summary>
168                /// Sets the length of this stream to the given value.
169                /// This operation is not supported and will throw a NotSupportedExceptionortedException
170                /// </summary>
171                /// <param name="value">The new length for the stream.</param>
172                /// <exception cref="NotSupportedException">Any access</exception>
173                public override void SetLength(long value)
174                {
175                        throw new NotSupportedException("BZip2InputStream SetLength not supported");
176                }
177               
178                /// <summary>
179                /// Writes a block of bytes to this stream using data from a buffer.
180                /// This operation is not supported and will throw a NotSupportedException
181                /// </summary>
182                /// <param name="buffer">The buffer to source data from.</param>
183                /// <param name="offset">The offset to start obtaining data from.</param>
184                /// <param name="count">The number of bytes of data to write.</param>
185                /// <exception cref="NotSupportedException">Any access</exception>
186                public override void Write(byte[] buffer, int offset, int count)
187                {
188                        throw new NotSupportedException("BZip2InputStream Write not supported");
189                }
190               
191                /// <summary>
192                /// Writes a byte to the current position in the file stream.
193                /// This operation is not supported and will throw a NotSupportedException
194                /// </summary>
195                /// <param name="value">The value to write.</param>
196                /// <exception cref="NotSupportedException">Any access</exception>
197                public override void WriteByte(byte value)
198                {
199                        throw new NotSupportedException("BZip2InputStream WriteByte not supported");
200                }
201               
202                /// <summary>
203                /// Read a sequence of bytes and advances the read position by one byte.
204                /// </summary>
205                /// <param name="buffer">Array of bytes to store values in</param>
206                /// <param name="offset">Offset in array to begin storing data</param>
207                /// <param name="count">The maximum number of bytes to read</param>
208                /// <returns>The total number of bytes read into the buffer. This might be less
209                /// than the number of bytes requested if that number of bytes are not
210                /// currently available or zero if the end of the stream is reached.
211                /// </returns>
212                public override int Read(byte[] buffer, int offset, int count)
213                {
214                        if ( buffer == null )
215                        {
216                                throw new ArgumentNullException("buffer");
217                        }
218
219                        for (int i = 0; i < count; ++i) {
220                                int rb = ReadByte();
221                                if (rb == -1) {
222                                        return i;
223                                }
224                                buffer[offset + i] = (byte)rb;
225                        }
226                        return count;
227                }
228               
229                /// <summary>
230                /// Closes the stream, releasing any associated resources.
231                /// </summary>
232                public override void Close()
233                {
234                        if ( IsStreamOwner && (baseStream != null) ) {
235                                baseStream.Close();
236                        }
237                }
238                /// <summary>
239                /// Read a byte from stream advancing position
240                /// </summary>
241                /// <returns>byte read or -1 on end of stream</returns>
242                public override int ReadByte()
243                {
244                        if (streamEnd)
245                        {
246                                return -1; // ok
247                        }
248                       
249                        int retChar = currentChar;
250                        switch (currentState)
251                        {
252                                case RAND_PART_B_STATE:
253                                        SetupRandPartB();
254                                        break;
255                                case RAND_PART_C_STATE:
256                                        SetupRandPartC();
257                                        break;
258                                case NO_RAND_PART_B_STATE:
259                                        SetupNoRandPartB();
260                                        break;
261                                case NO_RAND_PART_C_STATE:
262                                        SetupNoRandPartC();
263                                        break;
264                                case START_BLOCK_STATE:
265                                case NO_RAND_PART_A_STATE:
266                                case RAND_PART_A_STATE:
267                                        break;
268                                default:
269                                        break;
270                        }
271                        return retChar;
272                }
273               
274                #endregion
275
276                void MakeMaps()
277                {
278                        nInUse = 0;
279                        for (int i = 0; i < 256; ++i) {
280                                if (inUse[i]) {
281                                        seqToUnseq[nInUse] = (byte)i;
282                                        unseqToSeq[i] = (byte)nInUse;
283                                        nInUse++;
284                                }
285                        }
286                }
287                               
288                void Initialize()
289                {
290                        char magic1 = BsGetUChar();
291                        char magic2 = BsGetUChar();
292                       
293                        char magic3 = BsGetUChar();
294                        char magic4 = BsGetUChar();
295                       
296                        if (magic1 != 'B' || magic2 != 'Z' || magic3 != 'h' || magic4 < '1' || magic4 > '9') {
297                                streamEnd = true;
298                                return;
299                        }
300                       
301                        SetDecompressStructureSizes(magic4 - '0');
302                        computedCombinedCRC = 0;
303                }
304               
305                void InitBlock()
306                {
307                        char magic1 = BsGetUChar();
308                        char magic2 = BsGetUChar();
309                        char magic3 = BsGetUChar();
310                        char magic4 = BsGetUChar();
311                        char magic5 = BsGetUChar();
312                        char magic6 = BsGetUChar();
313                       
314                        if (magic1 == 0x17 && magic2 == 0x72 && magic3 == 0x45 && magic4 == 0x38 && magic5 == 0x50 && magic6 == 0x90) {
315                                Complete();
316                                return;
317                        }
318                       
319                        if (magic1 != 0x31 || magic2 != 0x41 || magic3 != 0x59 || magic4 != 0x26 || magic5 != 0x53 || magic6 != 0x59) {
320                                BadBlockHeader();
321                                streamEnd = true;
322                                return;
323                        }
324                       
325                        storedBlockCRC  = BsGetInt32();
326                       
327                        blockRandomised = (BsR(1) == 1);
328                       
329                        GetAndMoveToFrontDecode();
330                       
331                        mCrc.Reset();
332                        currentState = START_BLOCK_STATE;
333                }
334               
335                void EndBlock()
336                {
337                        computedBlockCRC = (int)mCrc.Value;
338                       
339                        // -- A bad CRC is considered a fatal error. --
340                        if (storedBlockCRC != computedBlockCRC) {
341                                CrcError();
342                        }
343                       
344                        // 1528150659
345                        computedCombinedCRC = ((computedCombinedCRC << 1) & 0xFFFFFFFF) | (computedCombinedCRC >> 31);
346                        computedCombinedCRC = computedCombinedCRC ^ (uint)computedBlockCRC;
347                }
348               
349                void Complete()
350                {
351                        storedCombinedCRC = BsGetInt32();
352                        if (storedCombinedCRC != (int)computedCombinedCRC) {
353                                CrcError();
354                        }
355                       
356                        streamEnd = true;
357                }
358               
359                void BsSetStream(Stream stream)
360                {
361                        baseStream = stream;
362                        bsLive = 0;
363                        bsBuff = 0;
364                }
365               
366                void FillBuffer()
367                {
368                        int thech = 0;
369                       
370                        try {
371                                thech = baseStream.ReadByte();
372                        } catch (Exception) {
373                                CompressedStreamEOF();
374                        }
375                       
376                        if (thech == -1) {
377                                CompressedStreamEOF();
378                        }
379                       
380                        bsBuff = (bsBuff << 8) | (thech & 0xFF);
381                        bsLive += 8;
382                }
383               
384                int BsR(int n)
385                {
386                        while (bsLive < n) {
387                                FillBuffer();
388                        }
389                       
390                        int v = (bsBuff >> (bsLive - n)) & ((1 << n) - 1);
391                        bsLive -= n;
392                        return v;
393                }
394               
395                char BsGetUChar()
396                {
397                        return (char)BsR(8);
398                }
399               
400                int BsGetIntVS(int numBits)
401                {
402                        return BsR(numBits);
403                }
404               
405                int BsGetInt32()
406                {
407                        int result = BsR(8);
408                        result = (result << 8) | BsR(8);
409                        result = (result << 8) | BsR(8);
410                        result = (result << 8) | BsR(8);
411                        return result;
412                }
413               
414                void RecvDecodingTables()
415                {
416                        char[][] len = new char[BZip2Constants.GroupCount][];
417                        for (int i = 0; i < BZip2Constants.GroupCount; ++i) {
418                                len[i] = new char[BZip2Constants.MaximumAlphaSize];
419                        }
420                       
421                        bool[] inUse16 = new bool[16];
422                       
423                        //--- Receive the mapping table ---
424                        for (int i = 0; i < 16; i++) {
425                                inUse16[i] = (BsR(1) == 1);
426                        }
427                       
428                        for (int i = 0; i < 16; i++) {
429                                if (inUse16[i]) {
430                                        for (int j = 0; j < 16; j++) {
431                                                inUse[i * 16 + j] = (BsR(1) == 1);
432                                        }
433                                } else {
434                                        for (int j = 0; j < 16; j++) {
435                                                inUse[i * 16 + j] = false;
436                                        }
437                                }
438                        }
439                       
440                        MakeMaps();
441                        int alphaSize = nInUse + 2;
442                       
443                        //--- Now the selectors ---
444                        int nGroups    = BsR(3);
445                        int nSelectors = BsR(15);
446                       
447                        for (int i = 0; i < nSelectors; i++) {
448                                int j = 0;
449                                while (BsR(1) == 1) {
450                                        j++;
451                                }
452                                selectorMtf[i] = (byte)j;
453                        }
454                       
455                        //--- Undo the MTF values for the selectors. ---
456                        byte[] pos = new byte[BZip2Constants.GroupCount];
457                        for (int v = 0; v < nGroups; v++) {
458                                pos[v] = (byte)v;
459                        }
460                       
461                        for (int i = 0; i < nSelectors; i++) {
462                                int  v   = selectorMtf[i];
463                                byte tmp = pos[v];
464                                while (v > 0) {
465                                        pos[v] = pos[v - 1];
466                                        v--;
467                                }
468                                pos[0]      = tmp;
469                                selector[i] = tmp;
470                        }
471                       
472                        //--- Now the coding tables ---
473                        for (int t = 0; t < nGroups; t++) {
474                                int curr = BsR(5);
475                                for (int i = 0; i < alphaSize; i++) {
476                                        while (BsR(1) == 1) {
477                                                if (BsR(1) == 0) {
478                                                        curr++;
479                                                } else {
480                                                        curr--;
481                                                }
482                                        }
483                                        len[t][i] = (char)curr;
484                                }
485                        }
486                       
487                        //--- Create the Huffman decoding tables ---
488                        for (int t = 0; t < nGroups; t++) {
489                                int minLen = 32;
490                                int maxLen = 0;
491                                for (int i = 0; i < alphaSize; i++) {
492                                        maxLen = Math.Max(maxLen, len[t][i]);
493                                        minLen = Math.Min(minLen, len[t][i]);
494                                }
495                                HbCreateDecodeTables(limit[t], baseArray[t], perm[t], len[t], minLen, maxLen, alphaSize);
496                                minLens[t] = minLen;
497                        }
498                }
499               
500                void GetAndMoveToFrontDecode()
501                {
502                        byte[] yy = new byte[256];
503                        int nextSym;
504                       
505                        int limitLast = BZip2Constants.BaseBlockSize * blockSize100k;
506                        origPtr = BsGetIntVS(24);
507                       
508                        RecvDecodingTables();
509                        int EOB = nInUse+1;
510                        int groupNo = -1;
511                        int groupPos = 0;
512                       
513                        /*--
514                        Setting up the unzftab entries here is not strictly
515                        necessary, but it does save having to do it later
516                        in a separate pass, and so saves a block's worth of
517                        cache misses.
518                        --*/
519                        for (int i = 0; i <= 255; i++) {
520                                unzftab[i] = 0;
521                        }
522                       
523                        for (int i = 0; i <= 255; i++) {
524                                yy[i] = (byte)i;
525                        }
526                       
527                        last = -1;
528                       
529                        if (groupPos == 0) {
530                                groupNo++;
531                                groupPos = BZip2Constants.GroupSize;
532                        }
533                       
534                        groupPos--;
535                        int zt = selector[groupNo];
536                        int zn = minLens[zt];
537                        int zvec = BsR(zn);
538                        int zj;
539                       
540                        while (zvec > limit[zt][zn]) {
541                                if (zn > 20) { // the longest code
542                                        throw new BZip2Exception("Bzip data error");
543                                }
544                                zn++;
545                                while (bsLive < 1) {
546                                        FillBuffer();
547                                }
548                                zj = (bsBuff >> (bsLive-1)) & 1;
549                                bsLive--;
550                                zvec = (zvec << 1) | zj;
551                        }
552                        if (zvec - baseArray[zt][zn] < 0 || zvec - baseArray[zt][zn] >= BZip2Constants.MaximumAlphaSize) {
553                                throw new BZip2Exception("Bzip data error");
554                        }
555                        nextSym = perm[zt][zvec - baseArray[zt][zn]];
556                       
557                        while (true) {
558                                if (nextSym == EOB) {
559                                        break;
560                                }
561                               
562                                if (nextSym == BZip2Constants.RunA || nextSym == BZip2Constants.RunB) {
563                                        int s = -1;
564                                        int n = 1;
565                                        do {
566                                                if (nextSym == BZip2Constants.RunA) {
567                                                        s += (0 + 1) * n;
568                                                } else if (nextSym == BZip2Constants.RunB) {
569                                                        s += (1 + 1) * n;
570                                                }
571
572                                                n <<= 1;
573                                               
574                                                if (groupPos == 0) {
575                                                        groupNo++;
576                                                        groupPos = BZip2Constants.GroupSize;
577                                                }
578                                               
579                                                groupPos--;
580                                               
581                                                zt = selector[groupNo];
582                                                zn = minLens[zt];
583                                                zvec = BsR(zn);
584                                               
585                                                while (zvec > limit[zt][zn]) {
586                                                        zn++;
587                                                        while (bsLive < 1) {
588                                                                FillBuffer();
589                                                        }
590                                                        zj = (bsBuff >> (bsLive - 1)) & 1;
591                                                        bsLive--;
592                                                        zvec = (zvec << 1) | zj;
593                                                }
594                                                nextSym = perm[zt][zvec - baseArray[zt][zn]];
595                                        } while (nextSym == BZip2Constants.RunA || nextSym == BZip2Constants.RunB);
596                                       
597                                        s++;
598                                        byte ch = seqToUnseq[yy[0]];
599                                        unzftab[ch] += s;
600                                       
601                                        while (s > 0) {
602                                                last++;
603                                                ll8[last] = ch;
604                                                s--;
605                                        }
606                                       
607                                        if (last >= limitLast) {
608                                                BlockOverrun();
609                                        }
610                                        continue;
611                                } else {
612                                        last++;
613                                        if (last >= limitLast) {
614                                                BlockOverrun();
615                                        }
616                                       
617                                        byte tmp = yy[nextSym - 1];
618                                        unzftab[seqToUnseq[tmp]]++;
619                                        ll8[last] = seqToUnseq[tmp];
620                                       
621                                        for (int j = nextSym-1; j > 0; --j) {
622                                                yy[j] = yy[j - 1];
623                                        }
624                                        yy[0] = tmp;
625                                       
626                                        if (groupPos == 0) {
627                                                groupNo++;
628                                                groupPos = BZip2Constants.GroupSize;
629                                        }
630                                       
631                                        groupPos--;
632                                        zt = selector[groupNo];
633                                        zn = minLens[zt];
634                                        zvec = BsR(zn);
635                                        while (zvec > limit[zt][zn]) {
636                                                zn++;
637                                                while (bsLive < 1) {
638                                                        FillBuffer();
639                                                }
640                                                zj = (bsBuff >> (bsLive-1)) & 1;
641                                                bsLive--;
642                                                zvec = (zvec << 1) | zj;
643                                        }
644                                        nextSym = perm[zt][zvec - baseArray[zt][zn]];
645                                        continue;
646                                }
647                        }
648                }
649               
650                void SetupBlock()
651                {
652                        int[] cftab = new int[257];
653                       
654                        cftab[0] = 0;
655                        Array.Copy(unzftab, 0, cftab, 1, 256);
656                       
657                        for (int i = 1; i <= 256; i++) {
658                                cftab[i] += cftab[i - 1];
659                        }
660                       
661                        for (int i = 0; i <= last; i++) {
662                                byte ch = ll8[i];
663                                tt[cftab[ch]] = i;
664                                cftab[ch]++;
665                        }
666                       
667                        cftab = null;
668                       
669                        tPos = tt[origPtr];
670                       
671                        count = 0;
672                        i2    = 0;
673                        ch2   = 256;   /*-- not a char and not EOF --*/
674                       
675                        if (blockRandomised) {
676                                rNToGo = 0;
677                                rTPos = 0;
678                                SetupRandPartA();
679                        } else {
680                                SetupNoRandPartA();
681                        }
682                }
683               
684                void SetupRandPartA()
685                {
686                        if (i2 <= last) {
687                                chPrev = ch2;
688                                ch2  = ll8[tPos];
689                                tPos = tt[tPos];
690                                if (rNToGo == 0) {
691                                        rNToGo = BZip2Constants.RandomNumbers[rTPos];
692                                        rTPos++;
693                                        if (rTPos == 512) {
694                                                rTPos = 0;
695                                        }
696                                }
697                                rNToGo--;
698                                ch2 ^= (int)((rNToGo == 1) ? 1 : 0);
699                                i2++;
700                               
701                                currentChar  = ch2;
702                                currentState = RAND_PART_B_STATE;
703                                mCrc.Update(ch2);
704                        } else {
705                                EndBlock();
706                                InitBlock();
707                                SetupBlock();
708                        }
709                }
710               
711                void SetupNoRandPartA()
712                {
713                        if (i2 <= last) {
714                                chPrev = ch2;
715                                ch2  = ll8[tPos];
716                                tPos = tt[tPos];
717                                i2++;
718                               
719                                currentChar = ch2;
720                                currentState = NO_RAND_PART_B_STATE;
721                                mCrc.Update(ch2);
722                        } else {
723                                EndBlock();
724                                InitBlock();
725                                SetupBlock();
726                        }
727                }
728               
729                void SetupRandPartB()
730                {
731                        if (ch2 != chPrev) {
732                                currentState = RAND_PART_A_STATE;
733                                count = 1;
734                                SetupRandPartA();
735                        } else {
736                                count++;
737                                if (count >= 4) {
738                                        z = ll8[tPos];
739                                        tPos = tt[tPos];
740                                        if (rNToGo == 0) {
741                                                rNToGo = BZip2Constants.RandomNumbers[rTPos];
742                                                rTPos++;
743                                                if (rTPos == 512) {
744                                                        rTPos = 0;
745                                                }
746                                        }
747                                        rNToGo--;
748                                        z ^= (byte)((rNToGo == 1) ? 1 : 0);
749                                        j2 = 0;
750                                        currentState = RAND_PART_C_STATE;
751                                        SetupRandPartC();
752                                } else {
753                                        currentState = RAND_PART_A_STATE;
754                                        SetupRandPartA();
755                                }
756                        }
757                }
758               
759                void SetupRandPartC()
760                {
761                        if (j2 < (int)z) {
762                                currentChar = ch2;
763                                mCrc.Update(ch2);
764                                j2++;
765                        } else {
766                                currentState = RAND_PART_A_STATE;
767                                i2++;
768                                count = 0;
769                                SetupRandPartA();
770                        }
771                }
772               
773                void SetupNoRandPartB()
774                {
775                        if (ch2 != chPrev) {
776                                currentState = NO_RAND_PART_A_STATE;
777                                count = 1;
778                                SetupNoRandPartA();
779                        } else {
780                                count++;
781                                if (count >= 4) {
782                                        z = ll8[tPos];
783                                        tPos = tt[tPos];
784                                        currentState = NO_RAND_PART_C_STATE;
785                                        j2 = 0;
786                                        SetupNoRandPartC();
787                                } else {
788                                        currentState = NO_RAND_PART_A_STATE;
789                                        SetupNoRandPartA();
790                                }
791                        }
792                }
793               
794                void SetupNoRandPartC()
795                {
796                        if (j2 < (int)z) {
797                                currentChar = ch2;
798                                mCrc.Update(ch2);
799                                j2++;
800                        } else {
801                                currentState = NO_RAND_PART_A_STATE;
802                                i2++;
803                                count = 0;
804                                SetupNoRandPartA();
805                        }
806                }
807               
808                void SetDecompressStructureSizes(int newSize100k)
809                {
810                        if (!(0 <= newSize100k && newSize100k <= 9 && 0 <= blockSize100k && blockSize100k <= 9)) {
811                                throw new BZip2Exception("Invalid block size");
812                        }
813                       
814                        blockSize100k = newSize100k;
815                       
816                        if (newSize100k == 0) {
817                                return;
818                        }
819                       
820                        int n = BZip2Constants.BaseBlockSize * newSize100k;
821                        ll8 = new byte[n];
822                        tt  = new int[n];
823                }
824
825                static void CompressedStreamEOF()
826                {
827                        throw new EndOfStreamException("BZip2 input stream end of compressed stream");
828                }
829               
830                static void BlockOverrun()
831                {
832                        throw new BZip2Exception("BZip2 input stream block overrun");
833                }
834               
835                static void BadBlockHeader()
836                {
837                        throw new BZip2Exception("BZip2 input stream bad block header");
838                }
839               
840                static void CrcError()
841                {
842                        throw new BZip2Exception("BZip2 input stream crc error");
843                }
844               
845                static void HbCreateDecodeTables(int[] limit, int[] baseArray, int[] perm, char[] length, int minLen, int maxLen, int alphaSize)
846                {
847                        int pp = 0;
848                       
849                        for (int i = minLen; i <= maxLen; ++i)
850                        {
851                                for (int j = 0; j < alphaSize; ++j)
852                                {
853                                        if (length[j] == i)
854                                        {
855                                                perm[pp] = j;
856                                                ++pp;
857                                        }
858                                }
859                        }
860                       
861                        for (int i = 0; i < BZip2Constants.MaximumCodeLength; i++)
862                        {
863                                baseArray[i] = 0;
864                        }
865                       
866                        for (int i = 0; i < alphaSize; i++)
867                        {
868                                ++baseArray[length[i] + 1];
869                        }
870                       
871                        for (int i = 1; i < BZip2Constants.MaximumCodeLength; i++)
872                        {
873                                baseArray[i] += baseArray[i - 1];
874                        }
875                       
876                        for (int i = 0; i < BZip2Constants.MaximumCodeLength; i++)
877                        {
878                                limit[i] = 0;
879                        }
880                       
881                        int vec = 0;
882                       
883                        for (int i = minLen; i <= maxLen; i++)
884                        {
885                                vec += (baseArray[i + 1] - baseArray[i]);
886                                limit[i] = vec - 1;
887                                vec <<= 1;
888                        }
889                       
890                        for (int i = minLen + 1; i <= maxLen; i++)
891                        {
892                                baseArray[i] = ((limit[i - 1] + 1) << 1) - baseArray[i];
893                        }
894                }
895               
896                #region Instance Fields
897                /*--
898                index of the last char in the block, so
899                the block size == last + 1.
900                --*/
901                int last;
902               
903                /*--
904                index in zptr[] of original string after sorting.
905                --*/
906                int origPtr;
907               
908                /*--
909                always: in the range 0 .. 9.
910                The current block size is 100000 * this number.
911                --*/
912                int blockSize100k;
913               
914                bool blockRandomised;
915               
916                int bsBuff;
917                int bsLive;
918                IChecksum mCrc = new StrangeCRC();
919               
920                bool[] inUse = new bool[256];
921                int    nInUse;
922               
923                byte[] seqToUnseq = new byte[256];
924                byte[] unseqToSeq = new byte[256];
925               
926                byte[] selector    = new byte[BZip2Constants.MaximumSelectors];
927                byte[] selectorMtf = new byte[BZip2Constants.MaximumSelectors];
928               
929                int[] tt;
930                byte[] ll8;
931               
932                /*--
933                freq table collected to save a pass over the data
934                during decompression.
935                --*/
936                int[] unzftab = new int[256];
937               
938                int[][] limit     = new int[BZip2Constants.GroupCount][];
939                int[][] baseArray = new int[BZip2Constants.GroupCount][];
940                int[][] perm      = new int[BZip2Constants.GroupCount][];
941                int[] minLens     = new int[BZip2Constants.GroupCount];
942               
943                Stream baseStream;
944                bool   streamEnd;
945               
946                int currentChar = -1;
947       
948                int currentState = START_BLOCK_STATE;
949               
950                int storedBlockCRC, storedCombinedCRC;
951                int computedBlockCRC;
952                uint computedCombinedCRC;
953               
954                int count, chPrev, ch2;
955                int tPos;
956                int rNToGo;
957                int rTPos;
958                int i2, j2;
959                byte z;
960                bool isStreamOwner = true;
961                #endregion
962        }
963}
964/* This file was derived from a file containing this license:
965 *
966 * This file is a part of bzip2 and/or libbzip2, a program and
967 * library for lossless, block-sorting data compression.
968 *
969 * Copyright (C) 1996-1998 Julian R Seward.  All rights reserved.
970 *
971 * Redistribution and use in source and binary forms, with or without
972 * modification, are permitted provided that the following conditions
973 * are met:
974 *
975 * 1. Redistributions of source code must retain the above copyright
976 * notice, this list of conditions and the following disclaimer.
977 *
978 * 2. The origin of this software must not be misrepresented; you must
979 * not claim that you wrote the original software.  If you use this
980 * software in a product, an acknowledgment in the product
981 * documentation would be appreciated but is not required.
982 *
983 * 3. Altered source versions must be plainly marked as such, and must
984 * not be misrepresented as being the original software.
985 *
986 * 4. The name of the author may not be used to endorse or promote
987 * products derived from this software without specific prior written
988 * permission.
989 *
990 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
991 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
992 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
993 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
994 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
995 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
996 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
997 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
998 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
999 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1000 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1001 *
1002 * Java version ported by Keiron Liddle, Aftex Software <keiron@aftexsw.com> 1999-2001
1003 */
Notatka: Zobacz TracBrowser aby uzyskać więcej informacji.