/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2220.3.1 by Martin Pool
add bencode utility
1
# bencode structured encoding
2
#
3
# Written by Petru Paler
4
#
5
# Permission is hereby granted, free of charge, to any person
6
# obtaining a copy of this software and associated documentation files
7
# (the "Software"), to deal in the Software without restriction,
8
# including without limitation the rights to use, copy, modify, merge,
9
# publish, distribute, sublicense, and/or sell copies of the Software,
10
# and to permit persons to whom the Software is furnished to do so,
11
# subject to the following conditions:
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
12
#
2220.3.1 by Martin Pool
add bencode utility
13
# The above copyright notice and this permission notice shall be
14
# included in all copies or substantial portions of the Software.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
15
#
3923.4.2 by Andrew Bennetts
Tweaks prompted by John's review.
16
# Modifications copyright (C) 2008 Canonical Ltd
2220.3.1 by Martin Pool
add bencode utility
17
6621.18.1 by Martin
Remove or fix use of long type and nearby type issues
18
import sys
19
20
3923.4.1 by Andrew Bennetts
Fix encoding of bools, provide a bdecode_tuple function.
21
class BDecoder(object):
22
23
    def __init__(self, yield_tuples=False):
24
        """Constructor.
25
26
        :param yield_tuples: if true, decode "l" elements as tuples rather than
27
            lists.
28
        """
29
        self.yield_tuples = yield_tuples
30
        decode_func = {}
6681.1.1 by Martin
Switch bencode to bytes types for Python 3
31
        decode_func[b'l'] = self.decode_list
32
        decode_func[b'd'] = self.decode_dict
33
        decode_func[b'i'] = self.decode_int
34
        decode_func[b'0'] = self.decode_string
35
        decode_func[b'1'] = self.decode_string
36
        decode_func[b'2'] = self.decode_string
37
        decode_func[b'3'] = self.decode_string
38
        decode_func[b'4'] = self.decode_string
39
        decode_func[b'5'] = self.decode_string
40
        decode_func[b'6'] = self.decode_string
41
        decode_func[b'7'] = self.decode_string
42
        decode_func[b'8'] = self.decode_string
43
        decode_func[b'9'] = self.decode_string
3923.4.1 by Andrew Bennetts
Fix encoding of bools, provide a bdecode_tuple function.
44
        self.decode_func = decode_func
45
46
    def decode_int(self, x, f):
47
        f += 1
6681.1.1 by Martin
Switch bencode to bytes types for Python 3
48
        newf = x.index(b'e', f)
6621.18.1 by Martin
Remove or fix use of long type and nearby type issues
49
        n = int(x[f:newf])
7143.15.2 by Jelmer Vernooij
Run autopep8.
50
        if x[f:f + 2] == b'-0':
51
            raise ValueError
52
        elif x[f:f + 1] == b'0' and newf != f + 1:
53
            raise ValueError
54
        return (n, newf + 1)
3923.4.1 by Andrew Bennetts
Fix encoding of bools, provide a bdecode_tuple function.
55
56
    def decode_string(self, x, f):
6681.1.1 by Martin
Switch bencode to bytes types for Python 3
57
        colon = x.index(b':', f)
6621.18.1 by Martin
Remove or fix use of long type and nearby type issues
58
        n = int(x[f:colon])
7143.15.2 by Jelmer Vernooij
Run autopep8.
59
        if x[f:f + 1] == b'0' and colon != f + 1:
3923.4.1 by Andrew Bennetts
Fix encoding of bools, provide a bdecode_tuple function.
60
            raise ValueError
61
        colon += 1
7143.15.2 by Jelmer Vernooij
Run autopep8.
62
        return (x[colon:colon + n], colon + n)
3923.4.1 by Andrew Bennetts
Fix encoding of bools, provide a bdecode_tuple function.
63
64
    def decode_list(self, x, f):
7143.15.2 by Jelmer Vernooij
Run autopep8.
65
        r, f = [], f + 1
66
        while x[f:f + 1] != b'e':
67
            v, f = self.decode_func[x[f:f + 1]](x, f)
3923.4.1 by Andrew Bennetts
Fix encoding of bools, provide a bdecode_tuple function.
68
            r.append(v)
69
        if self.yield_tuples:
70
            r = tuple(r)
71
        return (r, f + 1)
72
73
    def decode_dict(self, x, f):
7143.15.2 by Jelmer Vernooij
Run autopep8.
74
        r, f = {}, f + 1
3923.4.1 by Andrew Bennetts
Fix encoding of bools, provide a bdecode_tuple function.
75
        lastkey = None
7143.15.2 by Jelmer Vernooij
Run autopep8.
76
        while x[f:f + 1] != b'e':
3923.4.1 by Andrew Bennetts
Fix encoding of bools, provide a bdecode_tuple function.
77
            k, f = self.decode_string(x, f)
6701.1.1 by Martin
Really fix all bencode behaviour on Python 3
78
            if lastkey is not None and lastkey >= k:
3923.4.1 by Andrew Bennetts
Fix encoding of bools, provide a bdecode_tuple function.
79
                raise ValueError
80
            lastkey = k
7143.15.2 by Jelmer Vernooij
Run autopep8.
81
            r[k], f = self.decode_func[x[f:f + 1]](x, f)
3923.4.1 by Andrew Bennetts
Fix encoding of bools, provide a bdecode_tuple function.
82
        return (r, f + 1)
83
84
    def bdecode(self, x):
6621.18.1 by Martin
Remove or fix use of long type and nearby type issues
85
        if not isinstance(x, bytes):
2694.5.9 by Jelmer Vernooij
Fix tests.
86
            raise TypeError
3923.4.1 by Andrew Bennetts
Fix encoding of bools, provide a bdecode_tuple function.
87
        try:
6681.1.1 by Martin
Switch bencode to bytes types for Python 3
88
            r, l = self.decode_func[x[:1]](x, 0)
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
89
        except (IndexError, KeyError, OverflowError) as e:
6621.14.1 by Martin
Remove remaining uses of multi-argument raise
90
            raise ValueError(str(e))
3923.4.1 by Andrew Bennetts
Fix encoding of bools, provide a bdecode_tuple function.
91
        if l != len(x):
92
            raise ValueError
93
        return r
94
95
96
_decoder = BDecoder()
97
bdecode = _decoder.bdecode
98
99
_tuple_decoder = BDecoder(True)
3923.4.2 by Andrew Bennetts
Tweaks prompted by John's review.
100
bdecode_as_tuple = _tuple_decoder.bdecode
2220.3.1 by Martin Pool
add bencode utility
101
102
103
class Bencached(object):
104
    __slots__ = ['bencoded']
105
106
    def __init__(self, s):
107
        self.bencoded = s
108
6701.1.2 by Martin
Tidy up some transitional changes in bencode
109
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
110
def encode_bencached(x, r):
2220.3.1 by Martin Pool
add bencode utility
111
    r.append(x.bencoded)
112
7143.15.2 by Jelmer Vernooij
Run autopep8.
113
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
114
def encode_bool(x, r):
6621.18.1 by Martin
Remove or fix use of long type and nearby type issues
115
    encode_int(int(x), r)
116
7143.15.2 by Jelmer Vernooij
Run autopep8.
117
2220.3.1 by Martin Pool
add bencode utility
118
def encode_int(x, r):
6681.1.1 by Martin
Switch bencode to bytes types for Python 3
119
    r.extend((b'i', int_to_bytes(x), b'e'))
2220.3.1 by Martin Pool
add bencode utility
120
7143.15.2 by Jelmer Vernooij
Run autopep8.
121
2220.3.1 by Martin Pool
add bencode utility
122
def encode_string(x, r):
6681.1.1 by Martin
Switch bencode to bytes types for Python 3
123
    r.extend((int_to_bytes(len(x)), b':', x))
124
7143.15.2 by Jelmer Vernooij
Run autopep8.
125
2220.3.1 by Martin Pool
add bencode utility
126
def encode_list(x, r):
6681.1.1 by Martin
Switch bencode to bytes types for Python 3
127
    r.append(b'l')
2220.3.1 by Martin Pool
add bencode utility
128
    for i in x:
129
        encode_func[type(i)](i, r)
6681.1.1 by Martin
Switch bencode to bytes types for Python 3
130
    r.append(b'e')
2220.3.1 by Martin Pool
add bencode utility
131
7143.15.2 by Jelmer Vernooij
Run autopep8.
132
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
133
def encode_dict(x, r):
6681.1.1 by Martin
Switch bencode to bytes types for Python 3
134
    r.append(b'd')
6619.3.18 by Jelmer Vernooij
Run 2to3 idioms fixer.
135
    ilist = sorted(x.items())
2220.3.1 by Martin Pool
add bencode utility
136
    for k, v in ilist:
6681.1.1 by Martin
Switch bencode to bytes types for Python 3
137
        r.extend((int_to_bytes(len(k)), b':', k))
2220.3.1 by Martin Pool
add bencode utility
138
        encode_func[type(v)](v, r)
6681.1.1 by Martin
Switch bencode to bytes types for Python 3
139
    r.append(b'e')
2220.3.1 by Martin Pool
add bencode utility
140
7143.15.2 by Jelmer Vernooij
Run autopep8.
141
2220.3.1 by Martin Pool
add bencode utility
142
encode_func = {}
143
encode_func[type(Bencached(0))] = encode_bencached
6621.18.1 by Martin
Remove or fix use of long type and nearby type issues
144
encode_func[int] = encode_int
7479.2.1 by Jelmer Vernooij
Drop python2 support.
145
def int_to_bytes(n):
146
    return b'%d' % n
6621.18.1 by Martin
Remove or fix use of long type and nearby type issues
147
encode_func[bytes] = encode_string
148
encode_func[list] = encode_list
149
encode_func[tuple] = encode_list
150
encode_func[dict] = encode_dict
151
encode_func[bool] = encode_bool
3923.4.1 by Andrew Bennetts
Fix encoding of bools, provide a bdecode_tuple function.
152
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
153
from breezy._static_tuple_py import StaticTuple
4848.1.2 by John Arbash Meinel
we need to support the non-extension StaticTuple type.
154
encode_func[StaticTuple] = encode_list
4679.8.10 by John Arbash Meinel
quick patch to allow bencode to handle StaticTuple objects.
155
try:
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
156
    from breezy._static_tuple_c import StaticTuple
4679.8.10 by John Arbash Meinel
quick patch to allow bencode to handle StaticTuple objects.
157
except ImportError:
158
    pass
159
else:
160
    encode_func[StaticTuple] = encode_list
161
2220.3.1 by Martin Pool
add bencode utility
162
163
def bencode(x):
164
    r = []
165
    encode_func[type(x)](x, r)
6681.1.1 by Martin
Switch bencode to bytes types for Python 3
166
    return b''.join(r)