~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/util/_bencode_py.py

  • Committer: Martin Pool
  • Date: 2005-08-24 08:59:32 UTC
  • Revision ID: mbp@sourcefrog.net-20050824085932-c61f1f1f1c930e13
- Add a simple UIFactory 

  The idea of this is to let a client of bzrlib set some 
  policy about how output is displayed.

  In this revision all that's done is that progress bars
  are constructed by a policy established by the application
  rather than being randomly constructed in the library 
  or passed down the calls.  This avoids progress bars
  popping up while running the test suite and cleans up
  some code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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:
12
 
#
13
 
# The above copyright notice and this permission notice shall be
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
 
 
106
 
 
107
 
from types import StringType, IntType, LongType, DictType, ListType, TupleType
108
 
 
109
 
class Bencached(object):
110
 
    __slots__ = ['bencoded']
111
 
 
112
 
    def __init__(self, s):
113
 
        self.bencoded = s
114
 
 
115
 
def encode_bencached(x,r):
116
 
    r.append(x.bencoded)
117
 
 
118
 
def encode_int(x, r):
119
 
    r.extend(('i', str(x), 'e'))
120
 
 
121
 
def encode_string(x, r):
122
 
    r.extend((str(len(x)), ':', x))
123
 
 
124
 
def encode_list(x, r):
125
 
    r.append('l')
126
 
    for i in x:
127
 
        encode_func[type(i)](i, r)
128
 
    r.append('e')
129
 
 
130
 
def encode_dict(x,r):
131
 
    r.append('d')
132
 
    ilist = x.items()
133
 
    ilist.sort()
134
 
    for k, v in ilist:
135
 
        r.extend((str(len(k)), ':', k))
136
 
        encode_func[type(v)](v, r)
137
 
    r.append('e')
138
 
 
139
 
encode_func = {}
140
 
encode_func[type(Bencached(0))] = encode_bencached
141
 
encode_func[IntType] = encode_int
142
 
encode_func[LongType] = encode_int
143
 
encode_func[StringType] = encode_string
144
 
encode_func[ListType] = encode_list
145
 
encode_func[TupleType] = encode_list
146
 
encode_func[DictType] = encode_dict
147
 
 
148
 
try:
149
 
    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
 
 
166
 
 
167
 
def bencode(x):
168
 
    r = []
169
 
    encode_func[type(x)](x, r)
170
 
    return ''.join(r)
171