/// <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(nameof(delta)); } if (!delta.CanRead) { throw new ArgumentException("Unable to read from delta stream"); } if (output == null) { throw new ArgumentNullException(nameof(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); }