/// <summary> /// The main decoder loop for the data /// </summary> /// <param name="w">the window decoder</param> /// <param name="dictionary">the dictionary data</param> /// <param name="target">the target data</param> /// <param name="sout">the out stream</param> /// <param name="customTable">custom table if any. Default is null.</param> public BodyDecoder(WindowDecoder w, IByteBuffer dictionary, IByteBuffer target, ByteStreamWriter sout, CustomCodeTableDecoder customTable = null) { if (customTable != null) { this.customTable = customTable; addressCache = new AddressCache((byte)customTable.NearSize, (byte)customTable.SameSize); } else { addressCache = new AddressCache(); } window = w; this.sout = sout; dict = dictionary; this.target = target; targetData = new List <byte>(); }
/// <summary> /// Use this after calling Start /// Each time the decode is called it is expected /// that at least 1 Window header is available in the stream /// </summary> /// <param name="bytesWritten">bytes decoded for all available windows</param> /// <returns></returns> public VCDiffResult Decode(out long bytesWritten) { if (!IsStarted) { bytesWritten = 0; return(VCDiffResult.Error); } VCDiffResult result = VCDiffResult.Succes; bytesWritten = 0; if (!delta.CanRead) { return(VCDiffResult.EOD); } while (delta.CanRead) { //delta is streamed in order aka not random access WindowDecoder w = new WindowDecoder(dict.Length, delta); if (w.Decode(IsSDHCFormat)) { using (BodyDecoder body = new BodyDecoder(w, dict, delta, sout)) { if (IsSDHCFormat && w.AddRunLength == 0 && w.AddressesForCopyLength == 0 && w.InstructionAndSizesLength > 0) { //interleaved //decodedinterleave actually has an internal loop for waiting and streaming the incoming rest of the interleaved window result = body.DecodeInterleave(); if (result != VCDiffResult.Succes && result != VCDiffResult.EOD) { return(result); } bytesWritten += body.Decoded; } //technically add could be 0 if it is all copy instructions //so do an or check on those two else if (IsSDHCFormat && (w.AddRunLength > 0 || w.AddressesForCopyLength > 0) && w.InstructionAndSizesLength > 0) { //not interleaved //expects the full window to be available //in the stream result = body.Decode(); if (result != VCDiffResult.Succes) { return(result); } bytesWritten += body.Decoded; } else if (!IsSDHCFormat) { //not interleaved //expects the full window to be available //in the stream result = body.Decode(); if (result != VCDiffResult.Succes) { return(result); } bytesWritten += body.Decoded; } else { //invalid file return(VCDiffResult.Error); } } } else { return((VCDiffResult)w.Result); } } return(result); }