/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-04-08 16:33:19 UTC
  • mfrom: (3735.2.187 brisbane-core)
  • mto: This revision was merged to the branch mainline in revision 4280.
  • Revision ID: john@arbash-meinel.com-20090408163319-jzin98xnzklj8vun
Merge the a couple rev older brisbane-core into bzr.dev, most things are resolve in favor of bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2008, 2009, 2010 Canonical Ltd
 
1
# Copyright (C) 2009 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
18
18
 
19
19
#python2.4 support
20
20
cdef extern from "python-compat.h":
21
 
    pass
 
21
    ctypedef int Py_ssize_t # Required for older pyrex versions
22
22
 
23
23
 
24
24
cdef extern from "Python.h":
25
 
    ctypedef int Py_ssize_t # Required for older pyrex versions
26
25
    int PyString_CheckExact(object)
27
26
    char * PyString_AS_STRING(object)
28
27
    Py_ssize_t PyString_GET_SIZE(object)
31
30
 
32
31
cdef extern from *:
33
32
    ctypedef unsigned long size_t
34
 
    void * malloc(size_t) nogil
35
 
    void * realloc(void *, size_t) nogil
36
 
    void free(void *) nogil
37
 
    void memcpy(void *, void *, size_t) nogil
 
33
    void * malloc(size_t)
 
34
    void * realloc(void *, size_t)
 
35
    void free(void *)
 
36
    void memcpy(void *, void *, size_t)
38
37
 
39
38
 
40
39
cdef extern from "delta.h":
44
43
        unsigned long agg_offset
45
44
    struct delta_index:
46
45
        pass
47
 
    delta_index * create_delta_index(source_info *src, delta_index *old) nogil
 
46
    delta_index * create_delta_index(source_info *src, delta_index *old)
48
47
    delta_index * create_delta_index_from_delta(source_info *delta,
49
 
                                                delta_index *old) nogil
50
 
    void free_delta_index(delta_index *index) nogil
 
48
                                                delta_index *old)
 
49
    void free_delta_index(delta_index *index)
51
50
    void *create_delta(delta_index *indexes,
52
51
             void *buf, unsigned long bufsize,
53
 
             unsigned long *delta_size, unsigned long max_delta_size) nogil
 
52
             unsigned long *delta_size, unsigned long max_delta_size)
54
53
    unsigned long get_delta_hdr_size(unsigned char **datap,
55
 
                                     unsigned char *top) nogil
 
54
                                     unsigned char *top)
56
55
    Py_ssize_t DELTA_SIZE_MIN
 
56
    void *patch_delta(void *src_buf, unsigned long src_size,
 
57
                      void *delta_buf, unsigned long delta_size,
 
58
                      unsigned long *dst_size)
57
59
 
58
60
 
59
61
cdef void *safe_malloc(size_t count) except NULL:
115
117
            self._index = NULL
116
118
        safe_free(<void **>&self._source_infos)
117
119
 
118
 
    def _has_index(self):
119
 
        return (self._index != NULL)
120
 
 
121
120
    def add_delta_source(self, delta, unadded_bytes):
122
121
        """Add a new delta to the source texts.
123
122
 
145
144
        src.buf = c_delta
146
145
        src.size = c_delta_size
147
146
        src.agg_offset = self._source_offset + unadded_bytes
148
 
        with nogil:
149
 
            index = create_delta_index_from_delta(src, self._index)
 
147
        index = create_delta_index_from_delta(src, self._index)
150
148
        self._source_offset = src.agg_offset + src.size
151
149
        if index != NULL:
152
150
            free_delta_index(self._index)
172
170
        source_location = len(self._sources)
173
171
        if source_location >= self._max_num_sources:
174
172
            self._expand_sources()
175
 
        if source_location != 0 and self._index == NULL:
176
 
            # We were lazy about populating the index, create it now
177
 
            self._populate_first_index()
178
173
        self._sources.append(source)
179
174
        c_source = PyString_AS_STRING(source)
180
175
        c_source_size = PyString_GET_SIZE(source)
183
178
        src.size = c_source_size
184
179
 
185
180
        src.agg_offset = self._source_offset + unadded_bytes
 
181
        index = create_delta_index(src, self._index)
186
182
        self._source_offset = src.agg_offset + src.size
187
 
        # We delay creating the index on the first insert
188
 
        if source_location != 0:
189
 
            with nogil:
190
 
                index = create_delta_index(src, self._index)
191
 
            if index != NULL:
192
 
                free_delta_index(self._index)
193
 
                self._index = index
194
 
 
195
 
    cdef _populate_first_index(self):
196
 
        cdef delta_index *index
197
 
        if len(self._sources) != 1 or self._index != NULL:
198
 
            raise AssertionError('_populate_first_index should only be'
199
 
                ' called when we have a single source and no index yet')
200
 
 
201
 
        # We know that self._index is already NULL, so whatever
202
 
        # create_delta_index returns is fine
203
 
        with nogil:
204
 
            self._index = create_delta_index(&self._source_infos[0], NULL)
205
 
        assert self._index != NULL
 
183
        if index != NULL:
 
184
            free_delta_index(self._index)
 
185
            self._index = index
206
186
 
207
187
    cdef _expand_sources(self):
208
188
        raise RuntimeError('if we move self._source_infos, then we need to'
218
198
        cdef Py_ssize_t target_size
219
199
        cdef void * delta
220
200
        cdef unsigned long delta_size
221
 
        cdef unsigned long c_max_delta_size
222
201
 
223
202
        if self._index == NULL:
224
 
            if len(self._sources) == 0:
225
 
                return None
226
 
            # We were just lazy about generating the index
227
 
            self._populate_first_index()
 
203
            return None
228
204
 
229
205
        if not PyString_CheckExact(target_bytes):
230
206
            raise TypeError('target is not a str')
235
211
        # TODO: inline some of create_delta so we at least don't have to double
236
212
        #       malloc, and can instead use PyString_FromStringAndSize, to
237
213
        #       allocate the bytes into the final string
238
 
        c_max_delta_size = max_delta_size
239
 
        with nogil:
240
 
            delta = create_delta(self._index,
241
 
                                 target, target_size,
242
 
                                 &delta_size, c_max_delta_size)
 
214
        delta = create_delta(self._index,
 
215
                             target, target_size,
 
216
                             &delta_size, max_delta_size)
243
217
        result = None
244
218
        if delta:
245
219
            result = PyString_FromStringAndSize(<char *>delta, delta_size)
279
253
 
280
254
 
281
255
cdef unsigned char *_decode_copy_instruction(unsigned char *bytes,
282
 
    unsigned char cmd, unsigned int *offset,
283
 
    unsigned int *length) nogil: # cannot_raise
 
256
    unsigned char cmd, unsigned int *offset, unsigned int *length):
284
257
    """Decode a copy instruction from the next few bytes.
285
258
 
286
259
    A copy instruction is a variable number of bytes, so we will parse the
330
303
    cdef unsigned char *dst_buf, *out, cmd
331
304
    cdef Py_ssize_t size
332
305
    cdef unsigned int cp_off, cp_size
333
 
    cdef int failed
334
306
 
335
307
    data = <unsigned char *>delta
336
308
    top = data + delta_size
340
312
    result = PyString_FromStringAndSize(NULL, size)
341
313
    dst_buf = <unsigned char*>PyString_AS_STRING(result)
342
314
 
343
 
    failed = 0
344
 
    with nogil:
345
 
        out = dst_buf
346
 
        while (data < top):
347
 
            cmd = data[0]
348
 
            data = data + 1
349
 
            if (cmd & 0x80):
350
 
                # Copy instruction
351
 
                data = _decode_copy_instruction(data, cmd, &cp_off, &cp_size)
352
 
                if (cp_off + cp_size < cp_size or
353
 
                    cp_off + cp_size > source_size or
354
 
                    cp_size > size):
355
 
                    failed = 1
356
 
                    break
357
 
                memcpy(out, source + cp_off, cp_size)
358
 
                out = out + cp_size
359
 
                size = size - cp_size
360
 
            else:
361
 
                # Insert instruction
362
 
                if cmd == 0:
363
 
                    # cmd == 0 is reserved for future encoding
364
 
                    # extensions. In the mean time we must fail when
365
 
                    # encountering them (might be data corruption).
366
 
                    failed = 2
367
 
                    break
368
 
                if cmd > size:
369
 
                    failed = 3
370
 
                    break
371
 
                memcpy(out, data, cmd)
372
 
                out = out + cmd
373
 
                data = data + cmd
374
 
                size = size - cmd
375
 
    if failed:
376
 
        if failed == 1:
377
 
            raise ValueError('Something wrong with:'
378
 
                ' cp_off = %s, cp_size = %s'
379
 
                ' source_size = %s, size = %s'
380
 
                % (cp_off, cp_size, source_size, size))
381
 
        elif failed == 2:
382
 
            raise ValueError('Got delta opcode: 0, not supported')
383
 
        elif failed == 3:
384
 
            raise ValueError('Insert instruction longer than remaining'
385
 
                ' bytes: %d > %d' % (cmd, size))
 
315
    out = dst_buf
 
316
    while (data < top):
 
317
        cmd = data[0]
 
318
        data = data + 1
 
319
        if (cmd & 0x80):
 
320
            # Copy instruction
 
321
            data = _decode_copy_instruction(data, cmd, &cp_off, &cp_size)
 
322
            if (cp_off + cp_size < cp_size or
 
323
                cp_off + cp_size > source_size or
 
324
                cp_size > size):
 
325
                raise RuntimeError('Something wrong with:'
 
326
                    ' cp_off = %s, cp_size = %s'
 
327
                    ' source_size = %s, size = %s'
 
328
                    % (cp_off, cp_size, source_size, size))
 
329
            memcpy(out, source + cp_off, cp_size)
 
330
            out = out + cp_size
 
331
            size = size - cp_size
 
332
        else:
 
333
            # Insert instruction
 
334
            if cmd == 0:
 
335
                # cmd == 0 is reserved for future encoding
 
336
                # extensions. In the mean time we must fail when
 
337
                # encountering them (might be data corruption).
 
338
                raise RuntimeError('Got delta opcode: 0, not supported')
 
339
            if (cmd > size):
 
340
                raise RuntimeError('Insert instruction longer than remaining'
 
341
                    ' bytes: %d > %d' % (cmd, size))
 
342
            memcpy(out, data, cmd)
 
343
            out = out + cmd
 
344
            data = data + cmd
 
345
            size = size - cmd
386
346
 
387
347
    # sanity check
388
348
    if (data != top or size != 0):