public static async Task <long> CreatePatchCached(Stream srcStream, Hash srcHash, Stream destStream, Hash destHash, Stream?patchOutStream = null) { var key = PatchKey(srcHash, destHash); var patch = _patchCache !.Get(key); if (patch != null) { if (patchOutStream == null) { return(patch.Length); } await patchOutStream.WriteAsync(patch); return(patch.Length); } Utils.Status("Creating Patch"); await using var sigStream = new MemoryStream(); await using var patchStream = new MemoryStream(); OctoDiff.Create(srcStream, destStream, sigStream, patchStream); _patchCache.Put(key, patchStream.ToArray()); if (patchOutStream == null) { return(patchStream.Position); } patchStream.Position = 0; await patchStream.CopyToAsync(patchOutStream); return(patchStream.Position); }
public static async Task CreatePatchCached(byte[] a, byte[] b, Stream output) { await using var cmd = new SQLiteCommand(_conn); cmd.CommandText = @"INSERT INTO PatchCache (FromHash, ToHash, PatchSize, Patch) VALUES (@fromHash, @toHash, @patchSize, @patch)"; var dataA = a.xxHash(); var dataB = b.xxHash(); cmd.Parameters.AddWithValue("@fromHash", (long)dataA); cmd.Parameters.AddWithValue("@toHash", (long)dataB); await using var patch = new MemoryStream(); Utils.Status("Creating Patch"); OctoDiff.Create(a, b, patch); patch.Position = 0; cmd.Parameters.AddWithValue("@patchSize", patch.Length); cmd.Parameters.AddWithValue("@patch", patch.ToArray()); try { await cmd.ExecuteNonQueryAsync(); } catch (SQLiteException ex) { if (!ex.Message.StartsWith("constraint failed")) { throw; } } await patch.CopyToAsync(output); }
public static void ApplyPatch(Stream input, Func <Stream> openPatchStream, Stream output) { using var ps = openPatchStream(); using var br = new BinaryReader(ps); var bytes = br.ReadBytes(8); var str = Encoding.ASCII.GetString(bytes); switch (str) { case "BSDIFF40": BSDiff.Apply(input, openPatchStream, output); return; case "OCTODELT": OctoDiff.Apply(input, openPatchStream, output); return; default: throw new Exception($"No diff dispatch for: {str}"); } }
public static async Task CreatePatchCached(byte[] a, byte[] b, Stream output) { var dataA = a.xxHash(); var dataB = b.xxHash(); var key = PatchKey(dataA, dataB); var found = _patchCache !.Get(key); if (found != null) { await output.WriteAsync(found); return; } await using var patch = new MemoryStream(); Utils.Status("Creating Patch"); OctoDiff.Create(a, b, patch); _patchCache.Put(key, patch.ToArray()); patch.Position = 0; await patch.CopyToAsync(output); }
public static async Task <long> CreatePatchCached(Stream srcStream, Hash srcHash, Stream destStream, Hash destHash, Stream?patchOutStream = null) { if (patchOutStream == null) { await using var rcmd = new SQLiteCommand(_conn); rcmd.CommandText = "SELECT PatchSize FROM PatchCache WHERE FromHash = @fromHash AND ToHash = @toHash"; rcmd.Parameters.AddWithValue("@fromHash", (long)srcHash); rcmd.Parameters.AddWithValue("@toHash", (long)destHash); await using var rdr = await rcmd.ExecuteReaderAsync(); while (await rdr.ReadAsync()) { return(rdr.GetInt64(0)); } } else { if (TryGetPatch(srcHash, destHash, out var entry)) { await patchOutStream !.WriteAsync(await entry.GetData()); return(entry.PatchSize); } } await using var cmd = new SQLiteCommand(_conn); cmd.CommandText = @"INSERT INTO PatchCache (FromHash, ToHash, PatchSize, Patch) VALUES (@fromHash, @toHash, @patchSize, @patch)"; cmd.Parameters.AddWithValue("@fromHash", (long)srcHash); cmd.Parameters.AddWithValue("@toHash", (long)destHash); Utils.Status("Creating Patch"); await using var sigStream = new MemoryStream(); await using var patchStream = new MemoryStream(); OctoDiff.Create(srcStream, destStream, sigStream, patchStream); cmd.Parameters.AddWithValue("@patchSize", patchStream.Length); cmd.Parameters.AddWithValue("@patch", patchStream.ToArray()); try { await cmd.ExecuteNonQueryAsync(); } catch (SQLiteException ex) { if (!ex.Message.StartsWith("constraint failed")) { throw; } } if (patchOutStream == null) { return(patchStream.Position); } patchStream.Position = 0; await patchStream.CopyToAsync(patchOutStream); return(patchStream.Position); }