/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
3735.26.1 by John Arbash Meinel
Write a pyrex extension for computing search keys.
1
# Copyright (C) 2009 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
18
cdef extern from *:
19
    void sprintf(char *, char *, ...)
20
21
cdef extern from "Python.h":
3735.26.2 by John Arbash Meinel
Finish handling incref/decref issues.
22
    struct _PyObject:
23
        pass
24
    ctypedef _PyObject PyObject
3735.26.1 by John Arbash Meinel
Write a pyrex extension for computing search keys.
25
    int PyTuple_CheckExact(object p)
26
    Py_ssize_t PyTuple_GET_SIZE(object t)
27
    char *PyString_AS_STRING(object s)
3735.26.2 by John Arbash Meinel
Finish handling incref/decref issues.
28
29
    PyObject * PyTuple_GET_ITEM_ptr "PyTuple_GET_ITEM" (object t,
30
                                                        Py_ssize_t offset)
31
    int PyString_CheckExact_ptr "PyString_CheckExact" (PyObject *p)
32
    Py_ssize_t PyString_GET_SIZE_ptr "PyTuple_GET_SIZE" (PyObject *s)
33
    char *PyString_AS_STRING_ptr "PyString_AS_STRING" (PyObject *s)
3735.26.1 by John Arbash Meinel
Write a pyrex extension for computing search keys.
34
    object PyString_FromStringAndSize(char*, Py_ssize_t)
35
36
cdef extern from "zlib.h":
37
    ctypedef unsigned long uLong
38
    ctypedef unsigned int uInt
39
    ctypedef unsigned char Bytef
40
41
    uLong crc32(uLong crc, Bytef *buf, uInt len)
42
43
44
def _search_key_16(key):
45
    """See chk_map._search_key_16."""
46
    cdef Py_ssize_t num_bits
47
    cdef Py_ssize_t i, j
48
    cdef Py_ssize_t num_out_bytes
49
    cdef Bytef *c_bit
50
    cdef uLong c_len
51
    cdef uInt crc_val
52
    cdef Py_ssize_t out_off
53
    cdef char *c_out
3735.26.2 by John Arbash Meinel
Finish handling incref/decref issues.
54
    cdef PyObject *bit
3735.26.1 by John Arbash Meinel
Write a pyrex extension for computing search keys.
55
56
    if not PyTuple_CheckExact(key):
57
        raise TypeError('key %r is not a tuple' % (key,))
58
    num_bits = PyTuple_GET_SIZE(key)
59
    # 4 bytes per crc32, and another 1 byte between bits
60
    num_out_bytes = (9 * num_bits) - 1
61
    out = PyString_FromStringAndSize(NULL, num_out_bytes)
62
    c_out = PyString_AS_STRING(out)
63
    for i from 0 <= i < num_bits:
64
        if i > 0:
65
            c_out[0] = c'\x00'
66
            c_out = c_out + 1
3735.26.2 by John Arbash Meinel
Finish handling incref/decref issues.
67
        # We use the _ptr variant, because GET_ITEM returns a borrowed
68
        # reference, and Pyrex assumes that returned 'object' are a new
69
        # reference
70
        bit = PyTuple_GET_ITEM_ptr(key, i)
71
        if not PyString_CheckExact_ptr(bit):
3735.26.1 by John Arbash Meinel
Write a pyrex extension for computing search keys.
72
            raise TypeError('Bit %d of %r is not a string' % (i, key))
3735.26.2 by John Arbash Meinel
Finish handling incref/decref issues.
73
        c_bit = <Bytef *>PyString_AS_STRING_ptr(bit)
74
        c_len = PyString_GET_SIZE_ptr(bit)
3735.26.1 by John Arbash Meinel
Write a pyrex extension for computing search keys.
75
        crc_val = crc32(0, c_bit, c_len)
76
        # Hex(val) order
77
        sprintf(c_out, '%08X', crc_val)
78
        c_out = c_out + 8
79
    return out
80
81
82
def _search_key_255(key):
83
    """See chk_map._search_key_255."""
84
    cdef Py_ssize_t num_bits
85
    cdef Py_ssize_t i, j
86
    cdef Py_ssize_t num_out_bytes
87
    cdef Bytef *c_bit
88
    cdef uLong c_len
89
    cdef uInt crc_val
90
    cdef Py_ssize_t out_off
91
    cdef char *c_out
3735.26.2 by John Arbash Meinel
Finish handling incref/decref issues.
92
    cdef PyObject *bit
3735.26.1 by John Arbash Meinel
Write a pyrex extension for computing search keys.
93
94
    if not PyTuple_CheckExact(key):
95
        raise TypeError('key %r is not a tuple' % (key,))
96
    num_bits = PyTuple_GET_SIZE(key)
97
    # 4 bytes per crc32, and another 1 byte between bits
98
    num_out_bytes = (5 * num_bits) - 1
99
    out = PyString_FromStringAndSize(NULL, num_out_bytes)
100
    c_out = PyString_AS_STRING(out)
101
    for i from 0 <= i < num_bits:
102
        if i > 0:
103
            c_out[0] = c'\x00'
104
            c_out = c_out + 1
3735.26.2 by John Arbash Meinel
Finish handling incref/decref issues.
105
        bit = PyTuple_GET_ITEM_ptr(key, i)
106
        if not PyString_CheckExact_ptr(bit):
107
            raise TypeError('Bit %d of %r is not a string: %r' % (i, key,
108
            <object>bit))
109
        c_bit = <Bytef *>PyString_AS_STRING_ptr(bit)
110
        c_len = PyString_GET_SIZE_ptr(bit)
3735.26.1 by John Arbash Meinel
Write a pyrex extension for computing search keys.
111
        crc_val = crc32(0, c_bit, c_len)
112
        # MSB order
113
        c_out[0] = (crc_val >> 24) & 0xFF
114
        c_out[1] = (crc_val >> 16) & 0xFF
115
        c_out[2] = (crc_val >> 8) & 0xFF
116
        c_out[3] = (crc_val >> 0) & 0xFF
117
        for j from 0 <= j < 4:
118
            if c_out[j] == c'\n':
119
                c_out[j] = c'_'
120
        c_out = c_out + 4
121
    return out