CrystalMpq.MpqFileStream.ApplyBsd0Patch C# (CSharp) Method

ApplyBsd0Patch() private method

private ApplyBsd0Patch ( PatchInfoHeader &patchInfoHeader, PatchHeader &patchHeader, uint patchLength, byte originalData ) : byte[]
patchInfoHeader PatchInfoHeader
patchHeader PatchHeader
patchLength uint
originalData byte
return byte[]
        private unsafe byte[] ApplyBsd0Patch(ref PatchInfoHeader patchInfoHeader, ref PatchHeader patchHeader, uint patchLength, byte[] originalData)
        {
            byte[] patchData;

            if (patchLength < patchHeader.PatchLength) patchData = UnpackRle(patchLength);
            else
            {
                patchData = new byte[patchLength];
                if (Read(patchData, 0, checked((int)patchLength)) != patchLength) throw new EndOfStreamException();
            }

            fixed (byte* patchDataPointer = patchData)
            {
                var bsdiffHeader = (PatchBsdiff40Header*)patchDataPointer;

                if (!BitConverter.IsLittleEndian) CommonMethods.SwapBytes((ulong*)patchDataPointer, sizeof(PatchBsdiff40Header)/sizeof(ulong));

                if (bsdiffHeader->Signature != 0x3034464649445342 /* 'BSDIFF40' */) throw new InvalidDataException(ErrorMessages.GetString("Bsd0PatchHeaderInvalidSignature"));

                var controlBlock = (uint*)(patchDataPointer + sizeof(PatchBsdiff40Header));
                var differenceBlock = (byte*)controlBlock + bsdiffHeader->ControlBlockLength;
                var extraBlock = differenceBlock + bsdiffHeader->DifferenceBlockLength;

                if (!BitConverter.IsLittleEndian) CommonMethods.SwapBytes(controlBlock, bsdiffHeader->ControlBlockLength/sizeof(uint));

                var patchedBuffer = new byte[bsdiffHeader->PatchedFileSize];

                uint o = 0;
                uint n = 0;
                try
                {
                    while (n < patchedBuffer.Length)
                    {
                        uint differenceLength = *controlBlock++;
                        uint extraLength = *controlBlock++;
                        uint sourceOffset = *controlBlock++;

                        // Apply the difference patch (Patched Data = Original data + Difference data)
                        for (uint i = 0; i < differenceLength; i++, n++, o++)
                        {
                            patchedBuffer[n] = differenceBlock[i];
                            if (o < originalData.Length)
                                patchedBuffer[n] += originalData[o];
                        }
                        differenceBlock += differenceLength;

                        // Apply the extra data patch (New data)
                        for (int e = 0; e < extraLength; e++)
                            patchedBuffer[n++] = extraBlock[e];
                        extraBlock += extraLength;

                        unchecked
                        {
                            o += (sourceOffset & 0x80000000) != 0 ? (0x80000000 - sourceOffset) : sourceOffset;
                        }
                    }
                }
                catch (IndexOutOfRangeException ex)
                {
                    throw new InvalidDataException(ErrorMessages.GetString("Bsd0PatchInvalidData"), ex);
                }

                return patchedBuffer;
            }
        }