Example #1
0
        void EncodeInstruction(VCDiffInstructionType inst, int size, byte mode = 0)
        {
            if (lastOpcodeIndex >= 0)
            {
                int lastOp = instructionAndSizes[lastOpcodeIndex];

                if (inst == VCDiffInstructionType.ADD && (table.inst1[lastOp] == CodeTable.A))
                {
                    //warning adding two in a row
                    Console.WriteLine("Warning: performing two ADD instructions in a row.");
                }
                int compoundOp = CodeTable.kNoOpcode;
                if (size <= byte.MaxValue)
                {
                    compoundOp = instrMap.LookSecondOpcode((byte)lastOp, (byte)inst, (byte)size, mode);
                    if (compoundOp != CodeTable.kNoOpcode)
                    {
                        instructionAndSizes[lastOpcodeIndex] = (byte)compoundOp;
                        lastOpcodeIndex = -1;
                        return;
                    }
                }

                compoundOp = instrMap.LookSecondOpcode((byte)lastOp, (byte)inst, (byte)0, mode);
                if (compoundOp != CodeTable.kNoOpcode)
                {
                    instructionAndSizes[lastOpcodeIndex] = (byte)compoundOp;
                    //append size to instructionAndSizes
                    VarIntBE.AppendInt32(size, instructionAndSizes);
                    lastOpcodeIndex = -1;
                }
            }

            int opcode = CodeTable.kNoOpcode;

            if (size <= byte.MaxValue)
            {
                opcode = instrMap.LookFirstOpcode((byte)inst, (byte)size, mode);

                if (opcode != CodeTable.kNoOpcode)
                {
                    instructionAndSizes.Add((byte)opcode);
                    lastOpcodeIndex = instructionAndSizes.Count - 1;
                    return;
                }
            }
            opcode = instrMap.LookFirstOpcode((byte)inst, 0, mode);
            if (opcode == CodeTable.kNoOpcode)
            {
                return;
            }

            instructionAndSizes.Add((byte)opcode);
            lastOpcodeIndex = instructionAndSizes.Count - 1;
            VarIntBE.AppendInt32(size, instructionAndSizes);
        }
Example #2
0
        private void EncodeInstruction(VCDiffInstructionType inst, int size, byte mode = 0)
        {
            if (lastOpcodeIndex >= 0)
            {
                int lastOp = instructionAndSizes.GetBuffer()[lastOpcodeIndex];

                int compoundOp;
                if (size <= byte.MaxValue)
                {
                    compoundOp = instrMap.LookSecondOpcode((byte)lastOp, (byte)inst, (byte)size, mode);
                    if (compoundOp != CodeTable.kNoOpcode)
                    {
                        instructionAndSizes.GetBuffer()[lastOpcodeIndex] = (byte)compoundOp;
                        lastOpcodeIndex = -1;
                        return;
                    }
                }

                compoundOp = instrMap.LookSecondOpcode((byte)lastOp, (byte)inst, 0, mode);
                if (compoundOp != CodeTable.kNoOpcode)
                {
                    instructionAndSizes.GetBuffer()[lastOpcodeIndex] = (byte)compoundOp;
                    //append size to instructionAndSizes
                    VarIntBE.AppendInt32(size, instructionAndSizes);
                    lastOpcodeIndex = -1;
                }
            }

            int opcode;

            if (size <= byte.MaxValue)
            {
                opcode = instrMap.LookFirstOpcode((byte)inst, (byte)size, mode);

                if (opcode != CodeTable.kNoOpcode)
                {
                    instructionAndSizes.WriteByte((byte)opcode);
                    lastOpcodeIndex = (int)instructionAndSizes.Length - 1;
                    return;
                }
            }
            opcode = instrMap.LookFirstOpcode((byte)inst, 0, mode);
            if (opcode == CodeTable.kNoOpcode)
            {
                return;
            }

            instructionAndSizes.WriteByte((byte)opcode);
            lastOpcodeIndex = (int)instructionAndSizes.Length - 1;
            VarIntBE.AppendInt32(size, instructionAndSizes);
        }
Example #3
0
        private VCDiffResult DecodeInterleaveCore()
        {
            VCDiffResult result = VCDiffResult.SUCCESS;
            //since interleave expected then the last point that was most likely decoded was the lengths section
            //so following is all data for the add run copy etc
            long interleaveLength = window.InstructionAndSizesLength;

            using var previous = new MemoryStream();
            int lastDecodedSize = 0;
            VCDiffInstructionType lastDecodedInstruction = VCDiffInstructionType.NOOP;

            while (interleaveLength > 0)
            {
                if (!delta.CanRead)
                {
                    continue;
                }
                //read in
                var didBreakBeforeComplete = false;

                //try to read in all interleaved bytes
                //if not then it will buffer for next time
                previous.Write(delta.ReadBytes((int)interleaveLength).Span);
                using ByteBuffer incoming = new ByteBuffer(previous.ToArray());
                previous.SetLength(0);
                long initialLength = incoming.Length;

                InstructionDecoder instrDecoder = new InstructionDecoder(incoming, customTable);

                while (incoming.CanRead && TotalBytesDecoded < window.TargetWindowLength)
                {
                    int  decodedSize = 0;
                    byte mode        = 0;
                    VCDiffInstructionType instruction = VCDiffInstructionType.NOOP;

                    if (lastDecodedSize > 0 && lastDecodedInstruction != VCDiffInstructionType.NOOP)
                    {
                        decodedSize = lastDecodedSize;
                        instruction = lastDecodedInstruction;
                    }
                    else
                    {
                        instruction = instrDecoder.Next(out decodedSize, out mode);

                        switch (instruction)
                        {
                        case VCDiffInstructionType.EOD:
                            didBreakBeforeComplete = true;
                            break;

                        case VCDiffInstructionType.ERROR:
                            targetData.SetLength(0);
                            return(VCDiffResult.ERROR);
                        }
                    }

                    //if instruction is EOD then decodedSize will be 0 as well
                    //the last part of the buffer containing the instruction will be
                    //buffered for the next loop
                    lastDecodedInstruction = instruction;
                    lastDecodedSize        = decodedSize;

                    if (didBreakBeforeComplete)
                    {
                        //we don't have all the data so store this pointer into a temporary list to resolve next loop
                        didBreakBeforeComplete = true;
                        interleaveLength      -= incoming.Position;

                        if (initialLength - incoming.Position > 0)
                        {
                            previous.Write(incoming.ReadBytes((int)(initialLength - incoming.Position)).Span);
                        }

                        break;
                    }

                    switch (instruction)
                    {
                    case VCDiffInstructionType.ADD:
                        result = DecodeAdd(decodedSize, incoming);
                        break;

                    case VCDiffInstructionType.RUN:
                        result = DecodeRun(decodedSize, incoming);
                        break;

                    case VCDiffInstructionType.COPY:
                        result = DecodeCopy(decodedSize, mode, incoming);
                        break;

                    default:
                        targetData.SetLength(0);
                        return(VCDiffResult.ERROR);
                    }

                    if (result == VCDiffResult.EOD)
                    {
                        //we don't have all the data so store this pointer into a temporary list to resolve next loop
                        didBreakBeforeComplete = true;
                        interleaveLength      -= incoming.Position;

                        if (initialLength - incoming.Position > 0)
                        {
                            previous.Write(incoming.ReadBytes((int)(initialLength - incoming.Position)).Span);
                        }

                        break;
                    }

                    //reset these as we have successfully used them
                    lastDecodedInstruction = VCDiffInstructionType.NOOP;
                    lastDecodedSize        = 0;
                }

                if (!didBreakBeforeComplete)
                {
                    interleaveLength -= initialLength;
                }
            }

            if (window.ChecksumFormat == ChecksumFormat.SDCH)
            {
                uint adler = Checksum.ComputeGoogleAdler32(targetData.GetBuffer().AsMemory(0, (int)targetData.Length));

                if (adler != window.Checksum)
                {
                    result = VCDiffResult.ERROR;
                }
            }

            return(result);
        }
Example #4
0
        private VCDiffResult DecodeCore()
        {
            using ByteBuffer instructionBuffer = new ByteBuffer(window.InstructionsAndSizesData);
            using ByteBuffer addressBuffer     = new ByteBuffer(window.AddressesForCopyData);
            using ByteBuffer addRunBuffer      = new ByteBuffer(window.AddRunData);

            InstructionDecoder instrDecoder = new InstructionDecoder(instructionBuffer, customTable);

            VCDiffResult result = VCDiffResult.SUCCESS;

            while (this.TotalBytesDecoded < window.TargetWindowLength)
            {
                VCDiffInstructionType instruction = instrDecoder.Next(out int decodedSize, out byte mode);

                switch (instruction)
                {
                case VCDiffInstructionType.EOD:
                    targetData.SetLength(0);
                    return(VCDiffResult.EOD);

                case VCDiffInstructionType.ERROR:
                    targetData.SetLength(0);
                    return(VCDiffResult.ERROR);
                }

                switch (instruction)
                {
                case VCDiffInstructionType.ADD:
                    result = DecodeAdd(decodedSize, addRunBuffer);
                    break;

                case VCDiffInstructionType.RUN:
                    result = DecodeRun(decodedSize, addRunBuffer);
                    break;

                case VCDiffInstructionType.COPY:
                    result = DecodeCopy(decodedSize, mode, addressBuffer);
                    break;

                default:
                    targetData.SetLength(0);
                    return(VCDiffResult.ERROR);
                }
            }

            if (window.ChecksumFormat == ChecksumFormat.SDCH)
            {
                uint adler = Checksum.ComputeGoogleAdler32(targetData.GetBuffer().AsMemory(0, (int)targetData.Length));

                if (adler != window.Checksum)
                {
                    result = VCDiffResult.ERROR;
                }
            }
            else if (window.ChecksumFormat == ChecksumFormat.Xdelta3)
            {
                uint adler = Checksum.ComputeXdelta3Adler32(targetData.GetBuffer().AsMemory(0, (int)targetData.Length));

                if (adler != window.Checksum)
                {
                    result = VCDiffResult.ERROR;
                }
            }

            return(result);
        }
Example #5
0
        /// <summary>
        /// Decode if as expecting interleave
        /// </summary>
        /// <returns></returns>
        public VCDiffResult DecodeInterleave()
        {
            VCDiffResult result = VCDiffResult.SUCCESS;
            //since interleave expected then the last point that was most likely decoded was the lengths section
            //so following is all data for the add run copy etc
            long                  interleaveLength       = window.InstructionAndSizesLength;
            List <byte>           previous               = new List <byte>();
            bool                  didBreakBeforeComplete = false;
            int                   lastDecodedSize        = 0;
            VCDiffInstructionType lastDecodedInstruction = VCDiffInstructionType.NOOP;

            while (interleaveLength > 0)
            {
                if (target.CanRead)
                {
                    //read in
                    didBreakBeforeComplete = false;

                    //try to read in all interleaved bytes
                    //if not then it will buffer for next time
                    previous.AddRange(target.ReadBytes((int)interleaveLength));
                    ByteBuffer incoming = new ByteBuffer(previous.ToArray());
                    previous.Clear();
                    long initialLength = incoming.Length;

                    InstructionDecoder instrDecoder = new InstructionDecoder(incoming, this.customTable);

                    while (incoming.CanRead && decodedOnly < window.DecodedDeltaLength)
                    {
                        int  decodedSize = 0;
                        byte mode        = 0;
                        VCDiffInstructionType instruction = VCDiffInstructionType.NOOP;

                        if (lastDecodedSize > 0 && lastDecodedInstruction != VCDiffInstructionType.NOOP)
                        {
                            decodedSize = lastDecodedSize;
                            instruction = lastDecodedInstruction;
                        }
                        else
                        {
                            instruction = instrDecoder.Next(out decodedSize, out mode);

                            switch (instruction)
                            {
                            case VCDiffInstructionType.EOD:
                                didBreakBeforeComplete = true;
                                break;

                            case VCDiffInstructionType.ERROR:
                                targetData.Clear();
                                return(VCDiffResult.ERRROR);

                            default:
                                break;
                            }
                        }

                        //if instruction is EOD then decodedSize will be 0 as well
                        //the last part of the buffer containing the instruction will be
                        //buffered for the next loop
                        lastDecodedInstruction = instruction;
                        lastDecodedSize        = decodedSize;

                        if (didBreakBeforeComplete)
                        {
                            //we don't have all the data so store this pointer into a temporary list to resolve next loop
                            didBreakBeforeComplete = true;
                            interleaveLength      -= incoming.Position;

                            if (initialLength - incoming.Position > 0)
                            {
                                previous.AddRange(incoming.ReadBytes((int)(initialLength - incoming.Position)));
                            }

                            break;
                        }

                        switch (instruction)
                        {
                        case VCDiffInstructionType.ADD:
                            result = DecodeAdd(decodedSize, incoming);
                            break;

                        case VCDiffInstructionType.RUN:
                            result = DecodeRun(decodedSize, incoming);
                            break;

                        case VCDiffInstructionType.COPY:
                            result = DecodeCopy(decodedSize, mode, incoming);
                            break;

                        default:
                            targetData.Clear();
                            return(VCDiffResult.ERRROR);
                        }

                        if (result == VCDiffResult.EOD)
                        {
                            //we don't have all the data so store this pointer into a temporary list to resolve next loop
                            didBreakBeforeComplete = true;
                            interleaveLength      -= incoming.Position;

                            if (initialLength - incoming.Position > 0)
                            {
                                previous.AddRange(incoming.ReadBytes((int)(initialLength - incoming.Position)));
                            }

                            break;
                        }

                        //reset these as we have successfully used them
                        lastDecodedInstruction = VCDiffInstructionType.NOOP;
                        lastDecodedSize        = 0;
                    }

                    if (!didBreakBeforeComplete)
                    {
                        interleaveLength -= initialLength;
                    }
                }
            }

            if (window.HasChecksum)
            {
                uint adler = Checksum.ComputeAdler32(targetData.ToArray());

                if (adler != window.Checksum)
                {
                    result = VCDiffResult.ERRROR;
                }
            }

            targetData.Clear();
            return(result);
        }
Example #6
0
        /// <summary>
        /// Decode normally
        /// </summary>
        /// <returns></returns>
        public VCDiffResult Decode()
        {
            ByteBuffer instructionBuffer = new ByteBuffer(window.InstructionsAndSizesData);
            ByteBuffer addressBuffer     = new ByteBuffer(window.AddressesForCopyData);
            ByteBuffer addRunBuffer      = new ByteBuffer(window.AddRunData);

            InstructionDecoder instrDecoder = new InstructionDecoder(instructionBuffer, this.customTable);

            VCDiffResult result = VCDiffResult.SUCCESS;

            while (decodedOnly < window.DecodedDeltaLength && instructionBuffer.CanRead)
            {
                int  decodedSize = 0;
                byte mode        = 0;

                VCDiffInstructionType instruction = instrDecoder.Next(out decodedSize, out mode);

                switch (instruction)
                {
                case VCDiffInstructionType.EOD:
                    targetData.Clear();
                    return(VCDiffResult.EOD);

                case VCDiffInstructionType.ERROR:
                    targetData.Clear();
                    return(VCDiffResult.ERRROR);

                default:
                    break;
                }

                switch (instruction)
                {
                case VCDiffInstructionType.ADD:
                    result = DecodeAdd(decodedSize, addRunBuffer);
                    break;

                case VCDiffInstructionType.RUN:
                    result = DecodeRun(decodedSize, addRunBuffer);
                    break;

                case VCDiffInstructionType.COPY:
                    result = DecodeCopy(decodedSize, mode, addressBuffer);
                    break;

                default:
                    targetData.Clear();
                    return(VCDiffResult.ERRROR);
                }
            }

            if (window.HasChecksum)
            {
                uint adler = Checksum.ComputeAdler32(targetData.ToArray());

                if (adler != window.Checksum)
                {
                    result = VCDiffResult.ERRROR;
                }
            }

            targetData.Clear();
            return(result);
        }