コード例 #1
0
ファイル: HuffmanTree.cs プロジェクト: dimcc/hprose-dotnet
        private uint[] CalculateHuffmanCode()
        {
            uint[] numArray        = new uint[0x11];
            byte[] codeLengthArray = this.codeLengthArray;
            for (int i = 0; i < codeLengthArray.Length; i++)
            {
                int index = codeLengthArray[i];
                numArray[index]++;
            }
            numArray[0] = 0;
            uint[] numArray2 = new uint[0x11];
            uint   num2      = 0;

            for (int j = 1; j <= 0x10; j++)
            {
                numArray2[j] = (num2 + numArray[j - 1]) << 1;
            }
            uint[] numArray3 = new uint[0x120];
            for (int k = 0; k < this.codeLengthArray.Length; k++)
            {
                int length = this.codeLengthArray[k];
                if (length > 0)
                {
                    numArray3[k] = DecodeHelper.BitReverse(numArray2[length], length);
                    numArray2[length]++;
                }
            }
            return(numArray3);
        }
コード例 #2
0
        // Calculate the huffman code for each character based on the code length for each character.
        // This algorithm is described in standard RFC 1951
        uint[] CalculateHuffmanCode()
        {
            uint[] bitLengthCount = new uint[17];
            foreach (int codeLength in codeLengthArray)
            {
                bitLengthCount[codeLength]++;
            }
            bitLengthCount[0] = 0;  // clear count for length 0

            uint[] nextCode = new uint[17];
            uint   tempCode = 0;

            for (int bits = 1; bits <= 16; bits++)
            {
                tempCode       = (tempCode + bitLengthCount[bits - 1]) << 1;
                nextCode[bits] = tempCode;
            }

            uint[] code = new uint[MaxLiteralTreeElements];
            for (int i = 0; i < codeLengthArray.Length; i++)
            {
                int len = codeLengthArray[i];

                if (len > 0)
                {
                    code[i] = DecodeHelper.BitReverse(nextCode[len], len);
                    nextCode[len]++;
                }
            }
            return(code);
        }
コード例 #3
0
        public int Inflate(byte[] bytes, int offset, int length)
        {
            // copy bytes from output to outputbytes if we have aviable bytes
            // if buffer is not filled up. keep decoding until no input are available
            // if decodeBlock returns false. Throw an exception.
            int count = 0;

            do
            {
                int copied = output.CopyTo(bytes, offset, length);
                if (copied > 0)
                {
                    if (using_gzip)
                    {
                        crc32 = DecodeHelper.UpdateCrc32(crc32, bytes, offset, copied);
                        uint n = streamSize + (uint)copied;
                        if (n < streamSize)    // overflow, the gzip stream is probably malicious.
                        {
                            throw new InvalidDataException(SR.GetString(SR.StreamSizeOverflow));
                        }
                        streamSize = n;
                    }

                    offset += copied;
                    count  += copied;
                    length -= copied;
                }

                if (length == 0)     // filled in the bytes array
                {
                    break;
                }
                // Decode will return false when more input is needed
            } while (!Finished() && Decode());

            if (state == InflaterState.VerifyingGZIPFooter)    // finished reading CRC
            // In this case finished is true and output window has all the data.
            // But some data in output window might not be copied out.
            {
                if (output.AvailableBytes == 0)
                {
                    if (crc32 != gZipDecoder.Crc32)
                    {
                        throw new InvalidDataException(SR.GetString(SR.InvalidCRC));
                    }

                    if (streamSize != gZipDecoder.StreamSize)
                    {
                        throw new InvalidDataException(SR.GetString(SR.InvalidStreamSize));
                    }
                }
            }

            return(count);
        }
コード例 #4
0
 public int GetCompressedOutput(byte[] outputBuffer)
 {
     this.output.UpdateBuffer(outputBuffer);
     if (this.usingGzip && !this.hasGzipHeader)
     {
         this.output.WriteGzipHeader(3);
         this.hasGzipHeader = true;
     }
     if (!this.hasBlockHeader)
     {
         this.hasBlockHeader = true;
         this.output.WritePreamble();
     }
     do
     {
         int count = (this.inputBuffer.Count < this.inputWindow.FreeWindowSpace) ? this.inputBuffer.Count : this.inputWindow.FreeWindowSpace;
         if (count > 0)
         {
             this.inputWindow.CopyBytes(this.inputBuffer.Buffer, this.inputBuffer.StartIndex, count);
             if (this.usingGzip)
             {
                 this.gzipCrc32 = DecodeHelper.UpdateCrc32(this.gzipCrc32, this.inputBuffer.Buffer, this.inputBuffer.StartIndex, count);
                 uint num2 = this.inputStreamSize + ((uint)count);
                 if (num2 < this.inputStreamSize)
                 {
                     throw new InvalidDataException("The gzip stream can't contain more than 4GB data.");
                 }
                 this.inputStreamSize = num2;
             }
             this.inputBuffer.ConsumeBytes(count);
         }
         while ((this.inputWindow.BytesAvailable > 0) && this.output.SafeToWriteTo())
         {
             this.inputWindow.GetNextSymbolOrMatch(this.currentMatch);
             if (this.currentMatch.State == MatchState.HasSymbol)
             {
                 this.output.WriteChar(this.currentMatch.Symbol);
             }
             else
             {
                 if (this.currentMatch.State == MatchState.HasMatch)
                 {
                     this.output.WriteMatch(this.currentMatch.Length, this.currentMatch.Position);
                     continue;
                 }
                 this.output.WriteChar(this.currentMatch.Symbol);
                 this.output.WriteMatch(this.currentMatch.Length, this.currentMatch.Position);
             }
         }
     }while (this.output.SafeToWriteTo() && !this.NeedsInput());
     this.needsEOB = true;
     return(this.output.BytesWritten);
 }
コード例 #5
0
ファイル: Inflater.cs プロジェクト: jmptrader/hprose-dotnet
        public int Inflate(byte[] bytes, int offset, int length)
        {
            int num = 0;

            do
            {
                int num2 = this.output.CopyTo(bytes, offset, length);
                if (num2 > 0)
                {
                    if (this.using_gzip)
                    {
                        this.crc32 = DecodeHelper.UpdateCrc32(this.crc32, bytes, offset, num2);
                        uint num3 = this.streamSize + ((uint)num2);
                        if (num3 < this.streamSize)
                        {
                            throw new InvalidDataException("The gzip stream can't contain more than 4GB data.");
                        }
                        this.streamSize = num3;
                    }
                    offset += num2;
                    num    += num2;
                    length -= num2;
                }
            }while (((length != 0) && !this.Finished()) && this.Decode());
            if ((this.state == InflaterState.VerifyingGZIPFooter) && (this.output.AvailableBytes == 0))
            {
                if (this.crc32 != this.gZipDecoder.Crc32)
                {
                    throw new InvalidDataException("The CRC in GZip footer does not match the CRC calculated from the decompressed data.");
                }
                if (this.streamSize != this.gZipDecoder.StreamSize)
                {
                    throw new InvalidDataException("The stream size in GZip footer does not match the real stream size.");
                }
            }
            return(num);
        }
コード例 #6
0
        //
        // Copy the compressed byte to outputBuffer
        // Returns the bytes we have copied. The caller needs to provide the buffer
        // to avoid extra coping.
        //
        public int GetCompressedOutput(byte[] outputBuffer)
        {
            Debug.Assert(!NeedsInput(), "call SetInput before trying to compress!");

            output.UpdateBuffer(outputBuffer);
            if (usingGzip && !hasGzipHeader)
            {
                // Write the GZIP header only once
                output.WriteGzipHeader(3);
                hasGzipHeader = true;
            }

            if (!hasBlockHeader)
            {
                // Output dynamic block header only once
                hasBlockHeader = true;
                output.WritePreamble();
            }

            do
            {
                // read more input data into the window if there is space available
                int bytesToCopy = (inputBuffer.Count < inputWindow.FreeWindowSpace) ?
                                  inputBuffer.Count : inputWindow.FreeWindowSpace;
                if (bytesToCopy > 0)
                {
                    // copy data into history window
                    inputWindow.CopyBytes(inputBuffer.Buffer, inputBuffer.StartIndex, bytesToCopy);

                    if (usingGzip)
                    {
                        // update CRC for gzip stream
                        gzipCrc32 = DecodeHelper.UpdateCrc32(gzipCrc32, inputBuffer.Buffer, inputBuffer.StartIndex, bytesToCopy);

                        uint n = inputStreamSize + (uint)bytesToCopy;
                        if (n < inputStreamSize)    // overflow, gzip doesn't support compressing more than Int32.Maxvalue bytes.
                        {
                            throw new InvalidDataException(SR.GetString(SR.StreamSizeOverflow));
                        }
                        inputStreamSize = n;
                    }

                    inputBuffer.ConsumeBytes(bytesToCopy);
                }

                // compress the bytes in input history window
                while (inputWindow.BytesAvailable > 0 && output.SafeToWriteTo())
                {
                    // Find next match. A match can be a symbol,
                    // a distance/length pair, a symbol followed by a distance/Length pair

                    inputWindow.GetNextSymbolOrMatch(currentMatch);

                    if (currentMatch.State == MatchState.HasSymbol)
                    {
                        output.WriteChar(currentMatch.Symbol);
                    }
                    else if (currentMatch.State == MatchState.HasMatch)
                    {
                        output.WriteMatch(currentMatch.Length, currentMatch.Position);
                    }
                    else
                    {
                        output.WriteChar(currentMatch.Symbol);
                        output.WriteMatch(currentMatch.Length, currentMatch.Position);
                    }
                }
            } while (output.SafeToWriteTo() && !NeedsInput());

            // update book keeping needed to write end of block data
            needsEOB = true;

            return(output.BytesWritten); // number of bytes we have written
        }