/// <summary>
        /// Decodes an original stream and a delta stream, writing to a target stream.
        /// The original stream may be null, so long as the delta stream never
        /// refers to it. The original and delta streams must be readable, and the
        /// original stream (if any) and the target stream must be seekable.
        /// The target stream must be writable and readable. The original and target
        /// streams are rewound to their starts before any data is read; the relevant data
        /// must occur at the beginning of the original stream, and any data already present
        /// in the target stream may be overwritten. The delta data must begin
        /// wherever the delta stream is currently positioned. The delta stream must end
        /// after the last window. The streams are not disposed by this method.
        /// </summary>
        /// <param name="original">Stream containing delta. May be null.</param>
        /// <param name="delta">Stream containing delta data.</param>
        /// <param name="output">Stream to write resulting data to.</param>
        public static void Decode(Stream original, Stream delta, Stream output)
        {
            #region Simple argument checking
            if (original != null && (!original.CanRead || !original.CanSeek))
            {
                throw new ArgumentException("Must be able to read and seek in original stream", "original");
            }
            if (delta == null)
            {
                throw new ArgumentNullException("delta");
            }
            if (!delta.CanRead)
            {
                throw new ArgumentException("Unable to read from delta stream");
            }
            if (output == null)
            {
                throw new ArgumentNullException("output");
            }
            if (!output.CanWrite || !output.CanRead || !output.CanSeek)
            {
                throw new ArgumentException("Must be able to read, write and seek in output stream", "output");
            }
            #endregion

            // Now the arguments are checked, we construct an instance of the
            // class and ask it to do the decoding.
            VcdiffDecoder instance = new VcdiffDecoder(original, delta, output);
            instance.Decode();
        }
        /// <summary>
        /// Reads the custom code table, if there is one
        /// </summary>
        void ReadCodeTable()
        {
            // The length given includes the nearSize and sameSize bytes
            int compressedTableLength = IOHelper.ReadBigEndian7BitEncodedInt(delta) - 2;
            int nearSize = IOHelper.CheckedReadByte(delta);
            int sameSize = IOHelper.CheckedReadByte(delta);

            byte[] compressedTableData = IOHelper.CheckedReadBytes(delta, compressedTableLength);

            byte[] defaultTableData = CodeTable.Default.GetBytes();

            MemoryStream tableOriginal = new MemoryStream(defaultTableData, false);
            MemoryStream tableDelta    = new MemoryStream(compressedTableData, false);

            byte[]       decompressedTableData = new byte[1536];
            MemoryStream tableOutput           = new MemoryStream(decompressedTableData, true);

            VcdiffDecoder.Decode(tableOriginal, tableDelta, tableOutput);

            if (tableOutput.Position != 1536)
            {
                throw new VcdiffFormatException("Compressed code table was incorrect size");
            }

            codeTable = new CodeTable(decompressedTableData);
            cache     = new AddressCache(nearSize, sameSize);
        }
Esempio n. 3
0
		/// <summary>
		/// Decodes an original stream and a delta stream, writing to a target stream.
		/// The original stream may be null, so long as the delta stream never
		/// refers to it. The original and delta streams must be readable, and the
		/// original stream (if any) and the target stream must be seekable. 
		/// The target stream must be writable and readable. The original and target
		/// streams are rewound to their starts before any data is read; the relevant data
		/// must occur at the beginning of the original stream, and any data already present
		/// in the target stream may be overwritten. The delta data must begin
		/// wherever the delta stream is currently positioned. The delta stream must end
		/// after the last window. The streams are not disposed by this method.
		/// </summary>
		/// <param name="original">Stream containing delta. May be null.</param>
		/// <param name="delta">Stream containing delta data.</param>
		/// <param name="output">Stream to write resulting data to.</param>
		public static void Decode (Stream original, Stream delta, Stream output)
		{
			#region Simple argument checking
			if (original != null && (!original.CanRead || !original.CanSeek))
			{
				throw new ArgumentException ("Must be able to read and seek in original stream", "original");
			}
			if (delta==null)
			{
				throw new ArgumentNullException("delta");
			}
			if (!delta.CanRead)
			{
				throw new ArgumentException ("Unable to read from delta stream");
			}
			if (output==null)
			{
				throw new ArgumentNullException("output");
			}
			if (!output.CanWrite || !output.CanRead || !output.CanSeek)
			{
				throw new ArgumentException ("Must be able to read, write and seek in output stream", "output");
			}
			#endregion

			// Now the arguments are checked, we construct an instance of the
			// class and ask it to do the decoding.
			VcdiffDecoder instance = new VcdiffDecoder(original, delta, output);
			instance.Decode();
		}