Statistics
| Branch: | Tag: | Revision:

root / commissioning / utils / betteron.py @ d6936cd8

History | View | Annotate | Download (4.7 kB)

1
from collections import OrderedDict
2
from itertools import chain
3
from cStringIO import StringIO
4

    
5
class arguments(object):
6
    __slots__ = ('args', 'kw')
7

    
8
    def __init__(self, *args, **kwargs):
9
        self.args = list(args)
10
        kw = OrderedDict()
11
        kwitems = kw.pop('kwitems', None)
12
        if kwitems is not None:
13
            kw.update(kwitems)
14
        kw.update(kwargs)
15
        self.kw = kw
16

    
17
    def __str__(self):
18
        return str(self.args) + '+' + str(self.kw)
19

    
20
    def __repr__(self):
21
        return repr(self.args) + '+' + repr(self.kw)
22

    
23
    def __getitem__(self, key):
24
        if (isinstance(key, int)
25
            or isinstance(key, long)
26
            or isinstance(key, slice)):
27
                return self.args[key]
28
        else:
29
            return self.kw[key]
30

    
31
    def __setitem__(self, key, value):
32
        if (isinstance(key, int)
33
            or isinstance(key, long)
34
            or isinstance(key, slice)):
35
                self.args[key] = value
36
        else:
37
            self.kw[key] = value
38

    
39
    def __delitem__(self, key):
40
        if (isinstance(key, int)
41
            or isinstance(key, long)
42
            or isinstance(key, slice)):
43
                del self.args[key]
44
        else:
45
                del self.kw[key]
46

    
47
    def iteritems(self):
48
        for item in self.args:
49
            yield None, item
50
        for k, v in self.kw:
51
            yield k, v
52

    
53
    def items(self):
54
        return list(self.iteritems())
55

    
56
    def iterkeys(self):
57
        return self.kw.iterkeys()
58

    
59
    def keys(self):
60
        return self.kw.keys()
61

    
62
    def itervalues(self):
63
        return chain(self.args, self.kw.itervalues())
64

    
65
    def values(self):
66
        return list(self.itervalues)
67

    
68
    def append(self, value):
69
        self.args.append(value)
70

    
71

    
72
def betteron_encode(obj, output):
73
    if obj is None:
74
        output('[=null]')
75
        return
76

    
77
    if isinstance(obj, basestring):
78
        if not obj:
79
            output('""')
80
        if isinstance(obj, unicode):
81
            obj = obj.encode('utf-8')
82
        output('"')
83
        start = 0
84
        while 1:
85
            end = obj.find(start) + 1
86
            if end < 0:
87
                break
88
            output(obj[start:end] + '"')
89
            start = end
90
        output(obj[start:])
91
        output('"')
92
        return
93

    
94
    if isinstance(obj, int) or isinstance(obj, long):
95
        output(str(obj))
96
        return
97

    
98
    if hasattr(obj, 'iteritems'):
99
        output('[')
100
        once = 1
101
        for k, v in obj.iteritems():
102
            if once:
103
                once = 0
104
            else:
105
                output(' ')
106
            if k is not None:
107
                betteron_encode(k)
108
                output('=')
109
            betteron_encode(v)
110
        output(']')
111
        
112
    if hasattr(obj, '__iter__'):
113
        output('[')
114
        once = 1
115
        for item in obj:
116
            if once:
117
                once = 0
118
            else:
119
                output(' ')
120
            betteron_encode(item)
121
        output(']')
122

    
123
    m = "Unsupported type '%s'" % (type(obj))
124

    
125

    
126
def betteron_decode(inputf, s=None):
127
    if isinstance(inputf, str):
128
        inputf = StringIO(inputf).read
129

    
130
    if s is None:
131
        s = inputf(1)
132

    
133
    while 1:
134
        if not s.isspace():
135
            break
136
        s = inputf(1)
137

    
138
    item = ''
139
    if s == '"':
140
        s = inputf(1)
141
        while 1:
142
            if s == '"':
143
                s = inputf(1)
144
                if s != '"':
145
                    return item, s
146
            item += s
147
            s = inputf(1)
148
    elif s == '[':
149
        item, s = betteron_decode_args(inputf)
150
        return item, s
151
    else:
152
        while 1:
153
            item += s
154
            s = inputf(1)
155
            if s in ' =]':
156
                return item, s
157

    
158

    
159
def betteron_decode_atom(inputf):
160
    s = inputf(4)
161
    if s != 'null':
162
        m = "Invalid atom '%s'" % (s,)
163
        raise ValueError(m)
164
    return None, None
165

    
166

    
167
def betteron_decode_args(inputf):
168
    args = []
169
    append = args.append
170
    s = inputf(1)
171
    key = None
172

    
173
    while 1:
174
        if s is None:
175
            s = inputf(1)
176

    
177
        if s == ']':
178
            if key is not None:
179
                append((None, key))
180
            return args, None
181

    
182
        if s == '=':
183
            if key is None:
184
                atom, s = betteron_decode_atom(inputf)
185
                append((None, atom))
186
            else:
187
                value, s = betteron_decode(inputf)
188
                append((key, value))
189
                key = None
190
            continue
191
        elif s == ' ':
192
            if key is not None:
193
                append((None, key))
194
                key = None
195
            s = inputf(1)
196
        elif s == '':
197
            m = "EOF while scanning for ']'"
198
            raise ValueError(m)
199
        else:
200
            if key is not None:
201
                append((None, key))
202
            key, s = betteron_decode(inputf, s=s)
203