DecompressBlock() public static méthode

public static DecompressBlock ( byte inBuffer, int inLength, byte outBuffer, bool multi ) : int
inBuffer byte
inLength int
outBuffer byte
multi bool
Résultat int
Exemple #1
0
        private void ReadHighBlockTable(byte[] buffer, long tableLength, long tableOffset, long dataLength, byte[] compressedReadBuffer)
        {
            int  ushortCount    = checked ((int)tableLength);
            long realDataLength = checked (sizeof(ushort) * ushortCount);

            bool isCompressed = dataLength < realDataLength;
            // Stream.Read only takes an int length for now, and it is unlikely that the tables will ever exceed 2GB.
            // But anyway, if this ever happens in the future the overflow check should ensure us that the program will crash nicely.
            int dataLengthInt32 = checked ((int)dataLength);

            stream.Seek(archiveDataOffset + tableOffset, SeekOrigin.Begin);
            if (stream.Read(isCompressed ? compressedReadBuffer : buffer, 0, dataLengthInt32) != dataLengthInt32)
            {
                throw new EndOfStreamException();                 // Throw an exception if we are not able to read as many bytes as we were told we could read…
            }
            if (isCompressed)
            {
                if (CommonMethods.DecompressBlock(compressedReadBuffer, dataLengthInt32, buffer, true) != realDataLength)
                {
                    throw new InvalidDataException();                     // Only allow the exact amount of bytes as a result
                }
            }
            if (!BitConverter.IsLittleEndian)
            {
                CommonMethods.SwapBytes16(buffer);
            }
        }
Exemple #2
0
        /// <summary>Reads the encrypted <see cref="System.UInt32"/> table at the specified offset in the archive.</summary>
        /// <remarks>
        /// This method will place the bytes in their native order.
        /// Reading must be done by pinning the buffer and accessing it as an <see cref="System.UInt32"/> buffer.
        /// The only purpose of this method is to share code between the hash table and block table reading methods.
        /// Because of its specific behavior, it should not be used anywhere else…
        /// </remarks>
        /// <param name="buffer">The destination buffer.</param>
        /// <param name="tableLength">Length of the table in units of 16 bytes.</param>
        /// <param name="tableOffset">The offset in the archive.</param>
        /// <param name="dataLength">Length of the data to read.</param>
        /// <param name="hash">The hash to use for decrypting the data.</param>
        /// <param name="compressedReadBuffer">The compressed read buffer to use for holding temporary data.</param>
        private unsafe void ReadEncryptedUInt32Table(byte[] buffer, long tableLength, long tableOffset, long dataLength, uint hash, byte[] compressedReadBuffer)
        {
            int  uintCount      = checked ((int)(tableLength << 2));
            long realDataLength = checked (sizeof(uint) * uintCount);

            bool isCompressed = dataLength < realDataLength;
            // Stream.Read only takes an int length for now, and it is unlikely that the tables will ever exceed 2GB.
            // But anyway, if this ever happens in the future the overflow check should ensure us that the program will crash nicely.
            int dataLengthInt32 = checked ((int)dataLength);

            stream.Seek(archiveDataOffset + tableOffset, SeekOrigin.Begin);
            if (stream.Read(isCompressed ? compressedReadBuffer : buffer, 0, dataLengthInt32) != dataLengthInt32)
            {
                throw new EndOfStreamException();                 // Throw an exception if we are not able to read as many bytes as we were told we could read…

                fixed(byte *bufferPointer = buffer)
                {
                    uint *tablePointer = (uint *)bufferPointer;

                    // If the data is compressed, we will have to swap endianness three times on big endian platforms, but it can't be helped.
                    // (Endiannes swap is done by the Encryption.Decrypt method automatically when passing a byte buffer.)
                    // However, if we don't have to decompress, endiannes swap is only done once, before decrypting.

                    if (isCompressed)
                    {
                        if (hash != 0)
                        {
                            CommonMethods.Decrypt(compressedReadBuffer, hash, dataLengthInt32);                            // On big endian platforms : Read UInt32, Swap Bytes, Compute, Swap Bytes, Store UInt32
                        }
                        if (CommonMethods.DecompressBlock(compressedReadBuffer, dataLengthInt32, buffer, true) != realDataLength)
                        {
                            throw new InvalidDataException();                     // Only allow the exact amount of bytes as a result
                        }
                    }

                    if (!BitConverter.IsLittleEndian)
                    {
                        CommonMethods.SwapBytes(tablePointer, uintCount);
                    }

                    if (!isCompressed && hash != 0)
                    {
                        CommonMethods.Decrypt(tablePointer, hash, uintCount);
                    }
                }
        }