Beispiel #1
0
        VCDiffResult DecodeCopy(int size, byte mode, ByteBuffer addresses)
        {
            long here    = window.SourceLength + decodedOnly;
            long decoded = addressCache.DecodeAddress(here, mode, addresses);

            switch ((VCDiffResult)decoded)
            {
            case VCDiffResult.ERRROR:
                return(VCDiffResult.ERRROR);

            case VCDiffResult.EOD:
                return(VCDiffResult.EOD);

            default:
                if (decoded < 0 || decoded > here)
                {
                    return(VCDiffResult.ERRROR);
                }
                break;
            }

            if (decoded + size <= window.SourceLength)
            {
                dict.Position = decoded;
                byte[] rbytes = dict.ReadBytes(size);
                sout.writeBytes(rbytes);
                targetData.AddRange(rbytes);
                decodedOnly += size;
                return(VCDiffResult.SUCCESS);
            }

            ///will come back to this once
            ///target data reading is implemented

            /*if(decoded < window.SourceLength)
             * {
             *   long partial = window.SourceLength - decoded;
             *   dict.Position = decoded;
             *   sout.writeBytes(dict.ReadBytes((int)partial));
             *   bytesWritten += partial;
             *   size -= (int)partial;
             * }
             *
             * decoded -= window.SourceLength;
             *
             * while(size > (bytesDecoded - decoded))
             * {
             *   long partial = bytesDecoded - decoded;
             *   target.Position = decoded;
             *   sout.writeBytes(target.ReadBytes((int)partial));
             *   decoded += partial;
             *   size -= (int)partial;
             *   bytesWritten += partial;
             * }
             *
             * target.Position = decoded;
             * sout.writeBytes(target.ReadBytes(size));*/

            return(VCDiffResult.ERRROR);
        }
Beispiel #2
0
        /// <summary>
        /// Encodes the file
        /// </summary>
        /// <param name="interleaved">Set this to true to enable SDHC interleaved vcdiff google format</param>
        /// <param name="checksum">Set this to true to add checksum for encoded data windows</param>
        /// <returns></returns>
        public VCDiffResult Encode(bool interleaved = false, bool checksum = false)
        {
            if (newData.Length == 0 || oldData.Length == 0)
            {
                return(VCDiffResult.Error);
            }

            VCDiffResult result = VCDiffResult.Succes;

            oldData.Position = 0;
            newData.Position = 0;

            //file header
            //write magic bytes
            if (!interleaved && !checksum)
            {
                sout.writeBytes(MagicBytes);
            }
            else
            {
                sout.writeBytes(MagicBytesExtended);
            }

            //buffer the whole olddata (dictionary)
            //otherwise it will be a slow process
            //even Google's version reads in the entire dictionary file to memory
            //it is just faster that way because of having to move the memory pointer around
            //to find all the hash comparisons and stuff.
            //It is much slower trying to random access read from file with FileStream class
            //however the newData is read in chunks and processed for memory efficiency and speed
            oldData.BufferAll();

            //read in all the dictionary it is the only thing that needs to be
            BlockHash dictionary = new BlockHash(oldData, 0, hasher);

            dictionary.AddAllBlocks();
            oldData.Position = 0;

            ChunkEncoder chunker = new ChunkEncoder(dictionary, oldData, hasher, interleaved, checksum);

            while (newData.CanRead)
            {
                using (ByteBuffer ntarget = new ByteBuffer(newData.ReadBytes(bufferSize)))
                {
                    chunker.EncodeChunk(ntarget, sout);
                }

                //just in case
                // System.GC.Collect();
            }

            return(result);
        }
Beispiel #3
0
        public void Output(ByteStreamWriter sout)
        {
            int lengthOfDelta = CalculateLengthOfTheDeltaEncoding();
            int windowSize    = lengthOfDelta +
                                1 +
                                VarIntBE.CalcInt32Length((int)dictionarySize) +
                                VarIntBE.CalcInt32Length(0);

            VarIntBE.CalcInt32Length(lengthOfDelta);

            //Google's Checksum Implementation Support
            if (hasChecksum)
            {
                sout.writeByte((byte)VCDiffWindowFlags.VCDSOURCE | (byte)VCDiffWindowFlags.VCDCHECKSUM); //win indicator
            }
            else
            {
                sout.writeByte((byte)VCDiffWindowFlags.VCDSOURCE); //win indicator
            }
            VarIntBE.AppendInt32((int)dictionarySize, sout);       //dictionary size
            VarIntBE.AppendInt32(0, sout);                         //dictionary start position 0 is default aka encompass the whole dictionary

            VarIntBE.AppendInt32(lengthOfDelta, sout);             //length of delta

            //begin of delta encoding
            Int64 sizeBeforeDelta = sout.Position;

            VarIntBE.AppendInt32((int)targetLength, sout); //final target length after decoding
            sout.writeByte(0x00);                          //uncompressed

            // [Here is where a secondary compressor would be used
            //  if the encoder and decoder supported that feature.]

            //non interleaved then it is separata areas for each type
            if (!interleaved)
            {
                VarIntBE.AppendInt32(dataForAddAndRun.Count, sout);    //length of add/run
                VarIntBE.AppendInt32(instructionAndSizes.Count, sout); //length of instructions and sizes
                VarIntBE.AppendInt32(addressForCopy.Count, sout);      //length of addresses for copys

                //Google Checksum Support
                if (hasChecksum)
                {
                    VarIntBE.AppendInt64(checksum, sout);
                }

                sout.writeBytes(dataForAddAndRun.ToArray());    //data section for adds and runs
                sout.writeBytes(instructionAndSizes.ToArray()); //data for instructions and sizes
                sout.writeBytes(addressForCopy.ToArray());      //data for addresses section copys
            }
            else
            {
                //interleaved everything is woven in and out in one block
                VarIntBE.AppendInt32(0, sout);                         //length of add/run
                VarIntBE.AppendInt32(instructionAndSizes.Count, sout); //length of instructions and sizes + other data for interleaved
                VarIntBE.AppendInt32(0, sout);                         //length of addresses for copys

                //Google Checksum Support
                if (hasChecksum)
                {
                    VarIntBE.AppendInt64(checksum, sout);
                }

                sout.writeBytes(instructionAndSizes.ToArray()); //data for instructions and sizes, in interleaved it is everything
            }
            //end of delta encoding

            Int64 sizeAfterDelta = sout.Position;

            if (lengthOfDelta != sizeAfterDelta - sizeBeforeDelta)
            {
                Console.WriteLine("Delta output length does not match");
            }
            dataForAddAndRun.Clear();
            instructionAndSizes.Clear();
            addressForCopy.Clear();
            if (targetLength == 0)
            {
                Console.WriteLine("Empty target window");
            }
            addrCache = new AddressCache();
        }