/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/_groupcompress_pyx.pyx

  • Committer: John Arbash Meinel
  • Date: 2009-03-27 22:44:25 UTC
  • mto: (3735.39.2 clean)
  • mto: This revision was merged to the branch mainline in revision 4280.
  • Revision ID: john@arbash-meinel.com-20090327224425-la9qwxkvtiipof1p
cleanup the apply_delta code a bit.
Pull out a _decode_copy_instruction, to make it clear what that
code is actually doing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
245
245
    return _apply_delta(source, source_size, delta, delta_size)
246
246
 
247
247
 
 
248
cdef unsigned char *_decode_copy_instruction(unsigned char *bytes,
 
249
    unsigned char cmd, unsigned int *offset, unsigned int *length):
 
250
    """Decode a copy instruction from the next few bytes.
 
251
 
 
252
    A copy instruction is a variable number of bytes, so we will parse the
 
253
    bytes we care about, and return the new position, as well as the offset and
 
254
    length referred to in the bytes.
 
255
 
 
256
    :param bytes: Pointer to the start of bytes after cmd
 
257
    :param cmd: The command code
 
258
    :return: Pointer to the bytes just after the last decode byte
 
259
    """
 
260
    cdef unsigned int off, size, count
 
261
    off = 0
 
262
    size = 0
 
263
    count = 0
 
264
    if (cmd & 0x01):
 
265
        off = bytes[count]
 
266
        count = count + 1
 
267
    if (cmd & 0x02):
 
268
        off = off | (bytes[count] << 8)
 
269
        count = count + 1
 
270
    if (cmd & 0x04):
 
271
        off = off | (bytes[count] << 16)
 
272
        count = count + 1
 
273
    if (cmd & 0x08):
 
274
        off = off | (bytes[count] << 24)
 
275
        count = count + 1
 
276
    if (cmd & 0x10):
 
277
        size = bytes[count]
 
278
        count = count + 1
 
279
    if (cmd & 0x20):
 
280
        size = size | (bytes[count] << 8)
 
281
        count = count + 1
 
282
    if (cmd & 0x40):
 
283
        size = size | (bytes[count] << 16)
 
284
        count = count + 1
 
285
    if (size == 0):
 
286
        size = 0x10000
 
287
    offset[0] = off
 
288
    length[0] = size
 
289
    return bytes + count
 
290
 
 
291
 
248
292
cdef object _apply_delta(char *source, Py_ssize_t source_size,
249
293
                         char *delta, Py_ssize_t delta_size):
250
294
    """common functionality between apply_delta and apply_delta_to_source."""
251
295
    cdef unsigned char *data, *top
252
296
    cdef unsigned char *dst_buf, *out, cmd
253
297
    cdef Py_ssize_t size
254
 
    cdef unsigned long cp_off, cp_size
 
298
    cdef unsigned int cp_off, cp_size
255
299
 
256
300
    data = <unsigned char *>delta
257
301
    top = data + delta_size
260
304
    size = get_delta_hdr_size(&data, top)
261
305
    result = PyString_FromStringAndSize(NULL, size)
262
306
    dst_buf = <unsigned char*>PyString_AS_STRING(result)
263
 
    # XXX: The original code added a trailing null here, but this shouldn't be
264
 
    #      necessary when using PyString_FromStringAndSize
265
 
    # dst_buf[size] = 0
266
307
 
267
308
    out = dst_buf
268
309
    while (data < top):
269
310
        cmd = data[0]
270
311
        data = data + 1
271
312
        if (cmd & 0x80):
272
 
            cp_off = cp_size = 0
273
 
            if (cmd & 0x01):
274
 
                cp_off = data[0]
275
 
                data = data + 1
276
 
            if (cmd & 0x02):
277
 
                cp_off = cp_off | (data[0] << 8)
278
 
                data = data + 1
279
 
            if (cmd & 0x04):
280
 
                cp_off = cp_off | (data[0] << 16)
281
 
                data = data + 1
282
 
            if (cmd & 0x08):
283
 
                cp_off = cp_off | (data[0] << 24)
284
 
                data = data + 1
285
 
            if (cmd & 0x10):
286
 
                cp_size = data[0]
287
 
                data = data + 1
288
 
            if (cmd & 0x20):
289
 
                cp_size = cp_size | (data[0] << 8)
290
 
                data = data + 1
291
 
            if (cmd & 0x40):
292
 
                cp_size = cp_size | (data[0] << 16)
293
 
                data = data + 1
294
 
            if (cp_size == 0):
295
 
                cp_size = 0x10000
 
313
            # Copy instruction
 
314
            data = _decode_copy_instruction(data, cmd, &cp_off, &cp_size)
296
315
            if (cp_off + cp_size < cp_size or
297
316
                cp_off + cp_size > source_size or
298
317
                cp_size > size):
303
322
            memcpy(out, source + cp_off, cp_size)
304
323
            out = out + cp_size
305
324
            size = size - cp_size
306
 
        elif (cmd):
 
325
        else:
 
326
            # Insert instruction
 
327
            if cmd == 0:
 
328
                # cmd == 0 is reserved for future encoding
 
329
                # extensions. In the mean time we must fail when
 
330
                # encountering them (might be data corruption).
 
331
                raise RuntimeError('Got delta opcode: 0, not supported')
307
332
            if (cmd > size):
308
333
                raise RuntimeError('Insert instruction longer than remaining'
309
334
                    ' bytes: %d > %d' % (cmd, size))
311
336
            out = out + cmd
312
337
            data = data + cmd
313
338
            size = size - cmd
314
 
        else:
315
 
            # /*
316
 
            #  * cmd == 0 is reserved for future encoding
317
 
            #  * extensions. In the mean time we must fail when
318
 
            #  * encountering them (might be data corruption).
319
 
            #  */
320
 
            ## /* XXX: error("unexpected delta opcode 0"); */
321
 
            raise RuntimeError('Got delta opcode: 0, not supported')
322
339
 
323
 
    # /* sanity check */
 
340
    # sanity check
324
341
    if (data != top or size != 0):
325
 
        ## /* XXX: error("delta replay has gone wild"); */
326
342
        raise RuntimeError('Did not extract the number of bytes we expected'
327
343
            ' we were left with %d bytes in "size", and top - data = %d'
328
344
            % (size, <int>(top - data)))
329
345
        return None
330
346
 
331
347
    # *dst_size = out - dst_buf;
332
 
    assert (out - dst_buf) == PyString_GET_SIZE(result)
 
348
    if (out - dst_buf) != PyString_GET_SIZE(result):
 
349
        raise RuntimeError('Number of bytes extracted did not match the'
 
350
            ' size encoded in the delta header.')
333
351
    return result
334
352
 
335
353