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

  • Committer: Vincent Ladeuil
  • Date: 2012-01-18 14:09:19 UTC
  • mto: This revision was merged to the branch mainline in revision 6468.
  • Revision ID: v.ladeuil+lp@free.fr-20120118140919-rlvdrhpc0nq1lbwi
Change set/remove to require a lock for the branch config files.

This means that tests (or any plugin for that matter) do not requires an
explicit lock on the branch anymore to change a single option. This also
means the optimisation becomes "opt-in" and as such won't be as
spectacular as it may be and/or harder to get right (nothing fails
anymore).

This reduces the diff by ~300 lines.

Code/tests that were updating more than one config option is still taking
a lock to at least avoid some IOs and demonstrate the benefits through
the decreased number of hpss calls.

The duplication between BranchStack and BranchOnlyStack will be removed
once the same sharing is in place for local config files, at which point
the Stack class itself may be able to host the changes.

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
from __future__ import absolute_import
 
19
 
 
20
class BDecoder(object):
 
21
 
 
22
    def __init__(self, yield_tuples=False):
 
23
        """Constructor.
 
24
 
 
25
        :param yield_tuples: if true, decode "l" elements as tuples rather than
 
26
            lists.
 
27
        """
 
28
        self.yield_tuples = yield_tuples
 
29
        decode_func = {}
 
30
        decode_func['l'] = self.decode_list
 
31
        decode_func['d'] = self.decode_dict
 
32
        decode_func['i'] = self.decode_int
 
33
        decode_func['0'] = self.decode_string
 
34
        decode_func['1'] = self.decode_string
 
35
        decode_func['2'] = self.decode_string
 
36
        decode_func['3'] = self.decode_string
 
37
        decode_func['4'] = self.decode_string
 
38
        decode_func['5'] = self.decode_string
 
39
        decode_func['6'] = self.decode_string
 
40
        decode_func['7'] = self.decode_string
 
41
        decode_func['8'] = self.decode_string
 
42
        decode_func['9'] = self.decode_string
 
43
        self.decode_func = decode_func
 
44
 
 
45
    def decode_int(self, x, f):
 
46
        f += 1
 
47
        newf = x.index('e', f)
 
48
        try:
 
49
            n = int(x[f:newf])
 
50
        except (OverflowError, ValueError):
 
51
            n = long(x[f:newf])
 
52
        if x[f] == '-':
 
53
            if x[f + 1] == '0':
 
54
                raise ValueError
 
55
        elif x[f] == '0' and newf != f+1:
 
56
            raise ValueError
 
57
        return (n, newf+1)
 
58
 
 
59
    def decode_string(self, x, f):
 
60
        colon = x.index(':', f)
 
61
        try:
 
62
            n = int(x[f:colon])
 
63
        except (OverflowError, ValueError):
 
64
            n = long(x[f:colon])
 
65
        if x[f] == '0' and colon != f+1:
 
66
            raise ValueError
 
67
        colon += 1
 
68
        return (x[colon:colon+n], colon+n)
 
69
 
 
70
    def decode_list(self, x, f):
 
71
        r, f = [], f+1
 
72
        while x[f] != 'e':
 
73
            v, f = self.decode_func[x[f]](x, f)
 
74
            r.append(v)
 
75
        if self.yield_tuples:
 
76
            r = tuple(r)
 
77
        return (r, f + 1)
 
78
 
 
79
    def decode_dict(self, x, f):
 
80
        r, f = {}, f+1
 
81
        lastkey = None
 
82
        while x[f] != 'e':
 
83
            k, f = self.decode_string(x, f)
 
84
            if lastkey >= k:
 
85
                raise ValueError
 
86
            lastkey = k
 
87
            r[k], f = self.decode_func[x[f]](x, f)
 
88
        return (r, f + 1)
 
89
 
 
90
    def bdecode(self, x):
 
91
        if type(x) != str:
 
92
            raise TypeError
 
93
        try:
 
94
            r, l = self.decode_func[x[0]](x, 0)
 
95
        except (IndexError, KeyError, OverflowError), e:
 
96
            import sys
 
97
            raise ValueError, ValueError(str(e)), sys.exc_info()[2]
 
98
        if l != len(x):
 
99
            raise ValueError
 
100
        return r
 
101
 
 
102
 
 
103
_decoder = BDecoder()
 
104
bdecode = _decoder.bdecode
 
105
 
 
106
_tuple_decoder = BDecoder(True)
 
107
bdecode_as_tuple = _tuple_decoder.bdecode
 
108
 
 
109
 
 
110
from types import StringType, IntType, LongType, DictType, ListType, TupleType
 
111
 
 
112
class Bencached(object):
 
113
    __slots__ = ['bencoded']
 
114
 
 
115
    def __init__(self, s):
 
116
        self.bencoded = s
 
117
 
 
118
def encode_bencached(x,r):
 
119
    r.append(x.bencoded)
 
120
 
 
121
def encode_int(x, r):
 
122
    r.extend(('i', str(x), 'e'))
 
123
 
 
124
def encode_string(x, r):
 
125
    r.extend((str(len(x)), ':', x))
 
126
 
 
127
def encode_list(x, r):
 
128
    r.append('l')
 
129
    for i in x:
 
130
        encode_func[type(i)](i, r)
 
131
    r.append('e')
 
132
 
 
133
def encode_dict(x,r):
 
134
    r.append('d')
 
135
    ilist = x.items()
 
136
    ilist.sort()
 
137
    for k, v in ilist:
 
138
        r.extend((str(len(k)), ':', k))
 
139
        encode_func[type(v)](v, r)
 
140
    r.append('e')
 
141
 
 
142
encode_func = {}
 
143
encode_func[type(Bencached(0))] = encode_bencached
 
144
encode_func[IntType] = encode_int
 
145
encode_func[LongType] = encode_int
 
146
encode_func[StringType] = encode_string
 
147
encode_func[ListType] = encode_list
 
148
encode_func[TupleType] = encode_list
 
149
encode_func[DictType] = encode_dict
 
150
 
 
151
try:
 
152
    from types import BooleanType
 
153
except ImportError:
 
154
    pass
 
155
else:
 
156
    def encode_bool(x,r):
 
157
        encode_int(int(x), r)
 
158
    encode_func[BooleanType] = encode_bool
 
159
 
 
160
from bzrlib._static_tuple_py import StaticTuple
 
161
encode_func[StaticTuple] = encode_list
 
162
try:
 
163
    from bzrlib._static_tuple_c import StaticTuple
 
164
except ImportError:
 
165
    pass
 
166
else:
 
167
    encode_func[StaticTuple] = encode_list
 
168
 
 
169
 
 
170
def bencode(x):
 
171
    r = []
 
172
    encode_func[type(x)](x, r)
 
173
    return ''.join(r)
 
174