// Mode: -*- C++ -*- class Delta { public: Delta(const Block &block) { int ret; xd3_config config; memset(&stream_, 0, sizeof (stream_)); memset(&config, 0, sizeof (config)); xd3_init_config(&config, XD3_SKIP_EMIT | XD3_ADLER32_NOVER); CHECK_EQ(0, xd3_config_stream (&stream_, &config)); xd3_avail_input (&stream_, block.Data(), block.Size()); bool done = false; while (!done) { ret = xd3_decode_input(&stream_); switch (ret) { case XD3_INPUT: done = true; break; case XD3_OUTPUT: CHECK_EQ(0, xd3_whole_append_window (&stream_)); break; case XD3_GOTHEADER: case XD3_WINSTART: case XD3_WINFINISH: break; default: DP(RINT "error code %s\n", xd3_strerror (ret)); abort(); } } } ~Delta() { xd3_free_stream(&stream_); } xoff_t AddedBytes() const { return stream_.whole_target.addslen; } xoff_t Windows() const { return stream_.whole_target.wininfolen; } void Print() const { for (size_t i = 0; i < stream_.whole_target.instlen; i++) { xd3_winst &winst = stream_.whole_target.inst[i]; switch (winst.type) { case XD3_RUN: DP(RINT "%"Q"u run %u\n", winst.position, winst.size); break; case XD3_ADD: DP(RINT "%"Q"u add %u\n", winst.position, winst.size); break; default: DP(RINT "%"Q"u copy %u @ %"Q"u (mode %u)\n", winst.position, winst.size, winst.addr, winst.mode); break; } } } private: xd3_stream stream_; };