1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
// 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" run %u\n", winst.position, winst.size);
break;
case XD3_ADD:
DP(RINT "%"Q" add %u\n", winst.position, winst.size);
break;
default:
DP(RINT "%"Q" copy %u @ %"Q" (mode %u)\n",
winst.position, winst.size, winst.addr, winst.mode);
break;
}
}
}
private:
xd3_stream stream_;
};
|