/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/util/bencode.py

  • Committer: Robert Collins
  • Date: 2007-07-15 15:40:37 UTC
  • mto: (2592.3.33 repository)
  • mto: This revision was merged to the branch mainline in revision 2624.
  • Revision ID: robertc@robertcollins.net-20070715154037-3ar8g89decddc9su
Make GraphIndex accept nodes as key, value, references, so that the method
signature is closer to what a simple key->value index delivers. Also
change the behaviour when the reference list count is zero to accept
key, value as nodes, and emit key, value to make it identical in that case
to a simple key->value index. This may not be a good idea, but for now it
seems ok.

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
# publish, distribute, sublicense, and/or sell copies of the Software,
10
10
# and to permit persons to whom the Software is furnished to do so,
11
11
# subject to the following conditions:
12
 
#
 
12
13
13
# The above copyright notice and this permission notice shall be
14
14
# included in all copies or substantial portions of the Software.
15
 
#
16
 
# Modifications copyright (C) 2008 Canonical Ltd
17
 
 
18
 
class BDecoder(object):
19
 
 
20
 
    def __init__(self, yield_tuples=False):
21
 
        """Constructor.
22
 
 
23
 
        :param yield_tuples: if true, decode "l" elements as tuples rather than
24
 
            lists.
25
 
        """
26
 
        self.yield_tuples = yield_tuples
27
 
        decode_func = {}
28
 
        decode_func['l'] = self.decode_list
29
 
        decode_func['d'] = self.decode_dict
30
 
        decode_func['i'] = self.decode_int
31
 
        decode_func['0'] = self.decode_string
32
 
        decode_func['1'] = self.decode_string
33
 
        decode_func['2'] = self.decode_string
34
 
        decode_func['3'] = self.decode_string
35
 
        decode_func['4'] = self.decode_string
36
 
        decode_func['5'] = self.decode_string
37
 
        decode_func['6'] = self.decode_string
38
 
        decode_func['7'] = self.decode_string
39
 
        decode_func['8'] = self.decode_string
40
 
        decode_func['9'] = self.decode_string
41
 
        self.decode_func = decode_func
42
 
 
43
 
    def decode_int(self, x, f):
44
 
        f += 1
45
 
        newf = x.index('e', f)
46
 
        try:
47
 
            n = int(x[f:newf])
48
 
        except (OverflowError, ValueError):
49
 
            n = long(x[f:newf])
50
 
        if x[f] == '-':
51
 
            if x[f + 1] == '0':
52
 
                raise ValueError
53
 
        elif x[f] == '0' and newf != f+1:
54
 
            raise ValueError
55
 
        return (n, newf+1)
56
 
 
57
 
    def decode_string(self, x, f):
58
 
        colon = x.index(':', f)
59
 
        try:
60
 
            n = int(x[f:colon])
61
 
        except (OverflowError, ValueError):
62
 
            n = long(x[f:colon])
63
 
        if x[f] == '0' and colon != f+1:
64
 
            raise ValueError
65
 
        colon += 1
66
 
        return (x[colon:colon+n], colon+n)
67
 
 
68
 
    def decode_list(self, x, f):
69
 
        r, f = [], f+1
70
 
        while x[f] != 'e':
71
 
            v, f = self.decode_func[x[f]](x, f)
72
 
            r.append(v)
73
 
        if self.yield_tuples:
74
 
            r = tuple(r)
75
 
        return (r, f + 1)
76
 
 
77
 
    def decode_dict(self, x, f):
78
 
        r, f = {}, f+1
79
 
        lastkey = None
80
 
        while x[f] != 'e':
81
 
            k, f = self.decode_string(x, f)
82
 
            if lastkey >= k:
83
 
                raise ValueError
84
 
            lastkey = k
85
 
            r[k], f = self.decode_func[x[f]](x, f)
86
 
        return (r, f + 1)
87
 
 
88
 
    def bdecode(self, x):
89
 
        if type(x) != str:
90
 
            raise TypeError
91
 
        try:
92
 
            r, l = self.decode_func[x[0]](x, 0)
93
 
        except (IndexError, KeyError):
94
 
            raise ValueError
95
 
        if l != len(x):
96
 
            raise ValueError
97
 
        return r
98
 
 
99
 
 
100
 
_decoder = BDecoder()
101
 
bdecode = _decoder.bdecode
102
 
 
103
 
_tuple_decoder = BDecoder(True)
104
 
bdecode_as_tuple = _tuple_decoder.bdecode
105
 
 
 
15
 
16
# The Software is provided "AS IS", without warranty of any kind,
 
17
# express or implied, including but not limited to the warranties of
 
18
# merchantability,  fitness for a particular purpose and
 
19
# noninfringement. In no event shall the  authors or copyright holders
 
20
# be liable for any claim, damages or other liability, whether in an
 
21
# action of contract, tort or otherwise, arising from, out of or in
 
22
# connection with the Software or the use or other dealings in the
 
23
# Software.
 
24
 
 
25
def decode_int(x, f):
 
26
    f += 1
 
27
    newf = x.index('e', f)
 
28
    try:
 
29
        n = int(x[f:newf])
 
30
    except (OverflowError, ValueError):
 
31
        n = long(x[f:newf])
 
32
    if x[f] == '-':
 
33
        if x[f + 1] == '0':
 
34
            raise ValueError
 
35
    elif x[f] == '0' and newf != f+1:
 
36
        raise ValueError
 
37
    return (n, newf+1)
 
38
 
 
39
def decode_string(x, f):
 
40
    colon = x.index(':', f)
 
41
    try:
 
42
        n = int(x[f:colon])
 
43
    except (OverflowError, ValueError):
 
44
        n = long(x[f:colon])
 
45
    if x[f] == '0' and colon != f+1:
 
46
        raise ValueError
 
47
    colon += 1
 
48
    return (x[colon:colon+n], colon+n)
 
49
 
 
50
def decode_list(x, f):
 
51
    r, f = [], f+1
 
52
    while x[f] != 'e':
 
53
        v, f = decode_func[x[f]](x, f)
 
54
        r.append(v)
 
55
    return (r, f + 1)
 
56
 
 
57
def decode_dict(x, f):
 
58
    r, f = {}, f+1
 
59
    lastkey = None
 
60
    while x[f] != 'e':
 
61
        k, f = decode_string(x, f)
 
62
        if lastkey >= k:
 
63
            raise ValueError
 
64
        lastkey = k
 
65
        r[k], f = decode_func[x[f]](x, f)
 
66
    return (r, f + 1)
 
67
 
 
68
decode_func = {}
 
69
decode_func['l'] = decode_list
 
70
decode_func['d'] = decode_dict
 
71
decode_func['i'] = decode_int
 
72
decode_func['0'] = decode_string
 
73
decode_func['1'] = decode_string
 
74
decode_func['2'] = decode_string
 
75
decode_func['3'] = decode_string
 
76
decode_func['4'] = decode_string
 
77
decode_func['5'] = decode_string
 
78
decode_func['6'] = decode_string
 
79
decode_func['7'] = decode_string
 
80
decode_func['8'] = decode_string
 
81
decode_func['9'] = decode_string
 
82
 
 
83
def bdecode(x):
 
84
    try:
 
85
        r, l = decode_func[x[0]](x, 0)
 
86
    except (IndexError, KeyError):
 
87
        raise ValueError
 
88
    if l != len(x):
 
89
        raise ValueError
 
90
    return r
 
91
 
 
92
def test_bdecode():
 
93
    try:
 
94
        bdecode('0:0:')
 
95
        assert 0
 
96
    except ValueError:
 
97
        pass
 
98
    try:
 
99
        bdecode('ie')
 
100
        assert 0
 
101
    except ValueError:
 
102
        pass
 
103
    try:
 
104
        bdecode('i341foo382e')
 
105
        assert 0
 
106
    except ValueError:
 
107
        pass
 
108
    assert bdecode('i4e') == 4L
 
109
    assert bdecode('i0e') == 0L
 
110
    assert bdecode('i123456789e') == 123456789L
 
111
    assert bdecode('i-10e') == -10L
 
112
    try:
 
113
        bdecode('i-0e')
 
114
        assert 0
 
115
    except ValueError:
 
116
        pass
 
117
    try:
 
118
        bdecode('i123')
 
119
        assert 0
 
120
    except ValueError:
 
121
        pass
 
122
    try:
 
123
        bdecode('')
 
124
        assert 0
 
125
    except ValueError:
 
126
        pass
 
127
    try:
 
128
        bdecode('i6easd')
 
129
        assert 0
 
130
    except ValueError:
 
131
        pass
 
132
    try:
 
133
        bdecode('35208734823ljdahflajhdf')
 
134
        assert 0
 
135
    except ValueError:
 
136
        pass
 
137
    try:
 
138
        bdecode('2:abfdjslhfld')
 
139
        assert 0
 
140
    except ValueError:
 
141
        pass
 
142
    assert bdecode('0:') == ''
 
143
    assert bdecode('3:abc') == 'abc'
 
144
    assert bdecode('10:1234567890') == '1234567890'
 
145
    try:
 
146
        bdecode('02:xy')
 
147
        assert 0
 
148
    except ValueError:
 
149
        pass
 
150
    try:
 
151
        bdecode('l')
 
152
        assert 0
 
153
    except ValueError:
 
154
        pass
 
155
    assert bdecode('le') == []
 
156
    try:
 
157
        bdecode('leanfdldjfh')
 
158
        assert 0
 
159
    except ValueError:
 
160
        pass
 
161
    assert bdecode('l0:0:0:e') == ['', '', '']
 
162
    try:
 
163
        bdecode('relwjhrlewjh')
 
164
        assert 0
 
165
    except ValueError:
 
166
        pass
 
167
    assert bdecode('li1ei2ei3ee') == [1, 2, 3]
 
168
    assert bdecode('l3:asd2:xye') == ['asd', 'xy']
 
169
    assert bdecode('ll5:Alice3:Bobeli2ei3eee') == [['Alice', 'Bob'], [2, 3]]
 
170
    try:
 
171
        bdecode('d')
 
172
        assert 0
 
173
    except ValueError:
 
174
        pass
 
175
    try:
 
176
        bdecode('defoobar')
 
177
        assert 0
 
178
    except ValueError:
 
179
        pass
 
180
    assert bdecode('de') == {}
 
181
    assert bdecode('d3:agei25e4:eyes4:bluee') == {'age': 25, 'eyes': 'blue'}
 
182
    assert bdecode('d8:spam.mp3d6:author5:Alice6:lengthi100000eee') == {'spam.mp3': {'author': 'Alice', 'length': 100000}}
 
183
    try:
 
184
        bdecode('d3:fooe')
 
185
        assert 0
 
186
    except ValueError:
 
187
        pass
 
188
    try:
 
189
        bdecode('di1e0:e')
 
190
        assert 0
 
191
    except ValueError:
 
192
        pass
 
193
    try:
 
194
        bdecode('d1:b0:1:a0:e')
 
195
        assert 0
 
196
    except ValueError:
 
197
        pass
 
198
    try:
 
199
        bdecode('d1:a0:1:a0:e')
 
200
        assert 0
 
201
    except ValueError:
 
202
        pass
 
203
    try:
 
204
        bdecode('i03e')
 
205
        assert 0
 
206
    except ValueError:
 
207
        pass
 
208
    try:
 
209
        bdecode('l01:ae')
 
210
        assert 0
 
211
    except ValueError:
 
212
        pass
 
213
    try:
 
214
        bdecode('9999:x')
 
215
        assert 0
 
216
    except ValueError:
 
217
        pass
 
218
    try:
 
219
        bdecode('l0:')
 
220
        assert 0
 
221
    except ValueError:
 
222
        pass
 
223
    try:
 
224
        bdecode('d0:0:')
 
225
        assert 0
 
226
    except ValueError:
 
227
        pass
 
228
    try:
 
229
        bdecode('d0:')
 
230
        assert 0
 
231
    except ValueError:
 
232
        pass
 
233
    try:
 
234
        bdecode('00:')
 
235
        assert 0
 
236
    except ValueError:
 
237
        pass
 
238
    try:
 
239
        bdecode('l-3:e')
 
240
        assert 0
 
241
    except ValueError:
 
242
        pass
 
243
    try:
 
244
        bdecode('i-03e')
 
245
        assert 0
 
246
    except ValueError:
 
247
        pass
 
248
    bdecode('d0:i3ee')
106
249
 
107
250
from types import StringType, IntType, LongType, DictType, ListType, TupleType
108
251
 
147
290
 
148
291
try:
149
292
    from types import BooleanType
150
 
except ImportError:
151
 
    pass
152
 
else:
153
 
    def encode_bool(x,r):
154
 
        encode_int(int(x), r)
155
 
    encode_func[BooleanType] = encode_bool
156
 
 
157
 
from bzrlib._static_tuple_py import StaticTuple
158
 
encode_func[StaticTuple] = encode_list
159
 
try:
160
 
    from bzrlib._static_tuple_c import StaticTuple
161
 
except ImportError:
162
 
    pass
163
 
else:
164
 
    encode_func[StaticTuple] = encode_list
165
 
 
 
293
    encode_func[BooleanType] = encode_int
 
294
except ImportError:
 
295
    pass
166
296
 
167
297
def bencode(x):
168
298
    r = []
169
299
    encode_func[type(x)](x, r)
170
300
    return ''.join(r)
171
301
 
 
302
def test_bencode():
 
303
    assert bencode(4) == 'i4e'
 
304
    assert bencode(0) == 'i0e'
 
305
    assert bencode(-10) == 'i-10e'
 
306
    assert bencode(12345678901234567890L) == 'i12345678901234567890e'
 
307
    assert bencode('') == '0:'
 
308
    assert bencode('abc') == '3:abc'
 
309
    assert bencode('1234567890') == '10:1234567890'
 
310
    assert bencode([]) == 'le'
 
311
    assert bencode([1, 2, 3]) == 'li1ei2ei3ee'
 
312
    assert bencode([['Alice', 'Bob'], [2, 3]]) == 'll5:Alice3:Bobeli2ei3eee'
 
313
    assert bencode({}) == 'de'
 
314
    assert bencode({'age': 25, 'eyes': 'blue'}) == 'd3:agei25e4:eyes4:bluee'
 
315
    assert bencode({'spam.mp3': {'author': 'Alice', 'length': 100000}}) == 'd8:spam.mp3d6:author5:Alice6:lengthi100000eee'
 
316
    assert bencode(Bencached(bencode(3))) == 'i3e'
 
317
    try:
 
318
        bencode({1: 'foo'})
 
319
    except TypeError:
 
320
        return
 
321
    assert 0
 
322