public static byte[] Apply(byte[] origin, byte[] delta) { uint limit, total = 0; uint lenSrc = (uint)origin.Length; uint lenDelta = (uint)delta.Length; Reader zDelta = new Reader(delta); limit = zDelta.GetInt(); if (zDelta.GetChar() != '\n') { throw new Exception("size integer not terminated by \'\\n\'"); } Writer zOut = new Writer(); while (zDelta.HaveBytes()) { uint cnt, ofst; cnt = zDelta.GetInt(); switch (zDelta.GetChar()) { case '@': ofst = zDelta.GetInt(); if (zDelta.HaveBytes() && zDelta.GetChar() != ',') { throw new Exception("copy command not terminated by \',\'"); } total += cnt; if (total > limit) { throw new Exception("copy exceeds output file size"); } if (ofst + cnt > lenSrc) { throw new Exception("copy extends past end of input"); } zOut.PutArray(origin, (int)ofst, (int)(ofst + cnt)); break; case ':': total += cnt; if (total > limit) { throw new Exception("insert command gives an output larger than predicted"); } if (cnt > lenDelta) { throw new Exception("insert count exceeds size of delta"); } zOut.PutArray(zDelta.a, (int)zDelta.pos, (int)(zDelta.pos + cnt)); zDelta.pos += cnt; break; case ';': byte[] output = zOut.ToArray(); // // Checksum is optional (2017-10-05) // http://fossil-scm.org/xfer/info/d3a46b2a45b92bbc // //if (cnt != Checksum (output)) // throw new Exception("bad checksum"); if (total != limit) { throw new Exception("generated size does not match predicted size"); } return(output); default: throw new Exception("unknown delta operator"); } } throw new Exception("unterminated delta"); }