24
* view_selector ::= copyfrom_source
25
* | copyfrom_target
26
* ;
27
+ * copyfrom_source ::= # binary 00 000000;
28
* copyfrom_target ::= # binary 01 000000;
29
* copyfrom_data ::= # binary 10 000000;
30
* packed_view_selector ::= # view_selector OR-ed with 6 bit value;
35
*/
36
37
#define INSN_MASK 0xc0
38
+#define INSN_COPYFROM_SOURCE 0x00
39
#define INSN_COPYFROM_TARGET 0x40
40
#define INSN_COPYFROM_DATA 0x80
41
#define OPERAND_MASK 0x3f
45
#define VLI_BITS_PER_DIGIT 7
46
47
struct window {
48
+ struct sliding_view *in;
49
struct strbuf out;
50
struct strbuf instructions;
51
struct strbuf data;
52
};
53
51
-#define WINDOW_INIT { STRBUF_INIT, STRBUF_INIT, STRBUF_INIT }
54
+#define WINDOW_INIT(w) { (w), STRBUF_INIT, STRBUF_INIT, STRBUF_INIT }
55
56
static void window_release(struct window *ctx)
57
{
164
return 0;
165
}
166
167
+static int copyfrom_source(struct window *ctx, const char **instructions,
168
+ size_t nbytes, const char *insns_end)
169
+{
170
+ size_t offset;
171
+ if (parse_int(instructions, &offset, insns_end))
172
+ return -1;
173
+ if (unsigned_add_overflows(offset, nbytes) ||
174
+ offset + nbytes > ctx->in->width)
175
+ return error("invalid delta: copies source data outside view");
176
+ strbuf_add(&ctx->out, ctx->in->buf.buf + offset, nbytes);
177
+ return 0;
178
+}
179
+
180
static int copyfrom_target(struct window *ctx, const char **instructions,
181
size_t nbytes, const char *instructions_end)
182
{
225
if (parse_first_operand(instructions, &nbytes, insns_end))
226
return -1;
227
switch (instruction & INSN_MASK) {
228
+ case INSN_COPYFROM_SOURCE:
229
+ return copyfrom_source(ctx, instructions, nbytes, insns_end);
230
case INSN_COPYFROM_TARGET:
231
return copyfrom_target(ctx, instructions, nbytes, insns_end);
232
case INSN_COPYFROM_DATA:
233
return copyfrom_data(ctx, data_pos, nbytes);
234
default:
217
- return error("Unknown instruction %x", instruction);
235
+ return error("invalid delta: unrecognized instruction");
236
}
237
}
238
256
}
257
258
static int apply_one_window(struct line_buffer *delta, off_t *delta_len,
241
- FILE *out)
259
+ struct sliding_view *preimage, FILE *out)
260
{
243
- struct window ctx = WINDOW_INIT;
261
+ struct window ctx = WINDOW_INIT(preimage);
262
size_t out_len;
263
size_t instructions_len;
264
size_t data_len;
301
if (read_offset(delta, &pre_off, &delta_len) ||
302
read_length(delta, &pre_len, &delta_len) ||
303
move_window(preimage, pre_off, pre_len) ||
286
- apply_one_window(delta, &delta_len, postimage))
304
+ apply_one_window(delta, &delta_len, preimage, postimage))
305
return -1;
306
}
307
return 0;