public static ObjectPatch GeneratePatch(byte[] org, byte[] mod, int chunk_size) { ObjectPatch op = new ObjectPatch(); List <MemPatch> lp = new List <MemPatch>(); int min_length = Math.Min(org.Length, mod.Length); for (int i = 0; i < min_length; i += chunk_size) { int remainder = min_length - i; int chunk = Math.Min(remainder, chunk_size); if (!CompareChunk(org, mod, i, chunk)) { MemPatch mp = new MemPatch(chunk, i); Buffer.BlockCopy(mod, i, mp.data, 0, chunk); lp.Add(mp); } } op.patchedLength = mod.Length; if (op.patchedLength > org.Length) { int diffLength = op.patchedLength - org.Length; MemPatch mp = new MemPatch(diffLength, org.Length); Buffer.BlockCopy(mod, org.Length, mp.data, 0, diffLength); lp.Add(mp); } Console.WriteLine("Found {0} deltas.", lp.Count); op.patches = lp.ToArray(); return(op); }
public static byte[] ApplyPatch(byte[] org, ObjectPatch patch) { byte[] mod = new byte[patch.patchedLength]; int min_length = Math.Min(patch.patchedLength, org.Length); Buffer.BlockCopy(org, 0, mod, 0, min_length); for (int i = 0; i < patch.patches.Length; ++i) { MemPatch mp = patch.patches[i]; Buffer.BlockCopy(mp.data, 0, mod, (int)mp.offset, (int)mp.length); } return(mod); }
static void Main(string[] args) { if (args.Length == 0) { PrintUsage(); return; } Mode mode = Mode.Invalid; switch (args[0]) { case "diff": mode = Mode.Diff; break; case "patch": mode = Mode.Patch; break; } if (mode == Mode.Diff) { if (args.Length != 5) { PrintUsage(); return; } int chunk_size = int.Parse(args[1]); string src1 = args[2]; string src2 = args[3]; string dst = args[4]; byte[] ms1 = ReadFile(src1); byte[] ms2 = ReadFile(src2); ObjectPatch patch = ObjectPatchRuntime.GeneratePatch(ms1, ms2, chunk_size); byte[] patch_data = patch.Serialize(); MemoryStream ms = new MemoryStream(); GZipStream compressedzipStream = new GZipStream(ms, CompressionMode.Compress, true); compressedzipStream.Write(patch_data, 0, patch_data.Length); compressedzipStream.Close(); FileStream fs = new FileStream(dst, FileMode.Create); byte[] data = ms.ToArray(); fs.Write(data, 0, data.Length); fs.Close(); } else if (mode == Mode.Patch) { if (args.Length != 4) { PrintUsage(); return; } string src1 = args[1]; string src2 = args[2]; string dst = args[3]; byte[] org = ReadFile(src1); byte[] zip_patch = ReadFile(src2); MemoryStream ms = new MemoryStream(zip_patch); MemoryStream ds = new MemoryStream(); GZipStream zipStream = new GZipStream(ms, CompressionMode.Decompress); zipStream.CopyTo(ds); ObjectPatch op = ObjectPatch.Deserialize(ds.ToArray()); byte[] mod = ObjectPatchRuntime.ApplyPatch(org, op); FileStream fs = new FileStream(dst, FileMode.Create); fs.Write(mod, 0, mod.Length); fs.Close(); } else { PrintUsage(); } }