示例#1
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.ERRROR);
            }

            VCDiffResult result = VCDiffResult.SUCCESS;

            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);
        }
示例#2
0
        /// <summary>
        /// Calculate and write a diff for the file.
        /// </summary>
        /// <param name="interleaved">Whether to output in SDCH interleaved diff format.</param>
        /// <param name="checksumFormat">
        /// Whether to include Adler32 checksums for encoded data windows. If interleaved is true, <see cref="ChecksumFormat.Xdelta3"/>
        /// is not supported.
        /// </param>
        /// <returns>
        /// <see cref="VCDiffResult.SUCCESS"/> if successful, <see cref="VCDiffResult.ERROR"/> if the sourceStream or target are zero-length.</returns>
        /// <exception cref="ArgumentException">If interleaved is true, and <see cref="ChecksumFormat.Xdelta3"/> is chosen.</exception>
        public VCDiffResult Encode(bool interleaved = false,
                                   ChecksumFormat checksumFormat = ChecksumFormat.None)
        {
            if (oldData == null)
            {
                this.oldData = new ByteBuffer(sourceStream);
            }

            if (interleaved && checksumFormat == ChecksumFormat.Xdelta3)
            {
                throw new ArgumentException("Interleaved diffs can not have an xdelta3 checksum!");
            }

            if (targetData.Length == 0 || oldData.Length == 0)
            {
                return(VCDiffResult.ERROR);
            }

            VCDiffResult result = VCDiffResult.SUCCESS;

            oldData.Position    = 0;
            targetData.Position = 0;

            // file header
            // write magic bytes
            if (!interleaved && checksumFormat != ChecksumFormat.SDCH)
            {
                outputStream.Write(MagicBytes);
            }
            else
            {
                outputStream.Write(MagicBytesExtended);
            }

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

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

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

            while (targetData.CanRead)
            {
                using ByteBuffer ntarget = new ByteBuffer(targetData.ReadBytesAsBuf(bufferSize));
                chunker.EncodeChunk(ntarget, outputStream);
            }

            return(result);
        }