Alexandria.Compression.DclImplode.Decompress C# (CSharp) Метод

Decompress() публичный статический Метод

Decompress the source into the output, then return the number of decompressed bytes.
public static Decompress ( Stream source, byte output ) : int
source Stream The to decompress from.
output byte The byte array to store the decompressed data in.
Результат int
        public static int Decompress(Stream source, byte[] output)
        {
            int outputOffset = 0;

            int dictionaryTotalSize; // Size of the dictionary in bits.
            int dictionaryOffset = 0;
            int dictionarySize = 0; // Number of bytes currently used in the dictionary.
            byte[] dictionary;

            int bitBuffer = 0, bitCount = 0;

            // Read header.
            var format = (Format)source.ReadByte();
            var dictionaryCode = (Dictionary)source.ReadByte();

            // Check header data format.
            if (format != Format.Ascii && format != Format.Binary)
                throw new Exception();

            // Check header dictionary.
            switch (dictionaryCode) {
                case Dictionary._1k: dictionaryTotalSize = 1024; break;
                case Dictionary._2k: dictionaryTotalSize = 2048; break;
                case Dictionary._4k: dictionaryTotalSize = 4096; break;
                default: throw new Exception();
            }

            dictionary = new byte[dictionaryTotalSize];

            while (outputOffset < output.Length) {
                // Ensure there are 16 bits on the bit buffer.
                FillBitBuffer(ref bitBuffer, ref bitCount, 16, source);

                bool isDictionaryIndex = (bitBuffer & 1) != 0;
                RemoveBits(ref bitBuffer, ref bitCount, 1);

                // If first bit is set, copy from dictionary.
                if (isDictionaryIndex) {
                    int copyOffset, copyLength;

                    // Find the length code value.
                    int lengthCode;
                    for (lengthCode = 0; Truncate(bitBuffer, LengthBits[lengthCode]) != LengthCodes[lengthCode]; lengthCode++) ;
                    RemoveBits(ref bitBuffer, ref bitCount, LengthBits[lengthCode]);

                    // Get the copy length and remove the bits from the bit buffer.
                    copyLength = LengthBases[lengthCode] + Truncate(bitBuffer, LengthExtraBits[lengthCode]);
                    RemoveBits(ref bitBuffer, ref bitCount, LengthExtraBits[lengthCode]);

                    // This copy length indicates the end of the stream.
                    if (copyLength == 519)
                        break;

                    FillBitBuffer(ref bitBuffer, ref bitCount, 14, source);

                    // Determine the dictionary offset.
                    int offsetCode;
                    for (offsetCode = 0; Truncate(bitBuffer, OffsetBits[offsetCode]) != OffsetCodes[offsetCode]; offsetCode++) ;
                    RemoveBits(ref bitBuffer, ref bitCount, OffsetBits[offsetCode]);
                    int offsetBits = (copyLength == 2) ? 2 : (int)dictionaryCode;

                    copyOffset = dictionarySize - 1 - ((offsetCode << offsetBits) + Truncate(bitBuffer, offsetBits));
                    RemoveBits(ref bitBuffer, ref bitCount, offsetBits);

                    while (copyLength-- > 0) {
                        while (copyOffset < 0)
                            copyOffset += dictionarySize;
                        while (copyOffset >= dictionarySize)
                            copyOffset -= dictionarySize;

                        WriteToOutput(dictionary[copyOffset++], output, ref outputOffset, dictionary, dictionaryTotalSize, ref dictionaryOffset, ref dictionarySize);
                    }
                } else { // Literal byte
                    if (format == Format.Binary) {
                        WriteToOutput((byte)bitBuffer, output, ref outputOffset, dictionary, dictionaryTotalSize, ref dictionaryOffset, ref dictionarySize);
                        RemoveBits(ref bitBuffer, ref bitCount, 8);
                    } else {
                        int charCode;
                        for (charCode = 0; Truncate(bitBuffer, CharBits[charCode]) != CharCodes[charCode]; charCode++) ;
                        WriteToOutput((byte)charCode, output, ref outputOffset, dictionary, dictionaryTotalSize, ref dictionaryOffset, ref dictionarySize);
                        RemoveBits(ref bitBuffer, ref bitCount, CharBits[charCode]);
                    }
                }
            }

            return outputOffset;
        }