Imported Upstream version 2008.1+svn1656
[opeanno-debian-packaging.git] / game / util / encoder.py
blobaa58ebd9de3ed7a1256fda8c3fb9bfadbed7793e
1 # ###################################################
2 # Copyright (C) 2008 The OpenAnno Team
3 # team@openanno.org
4 # This file is part of OpenAnno.
6 # OpenAnno is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the
18 # Free Software Foundation, Inc.,
19 # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 # ###################################################
22 classes=[]
24 def register_classes(*classes_):
25 global classes
26 for c in classes_:
27 classes.append(c)
29 def encode(obj):
30 if obj is None:
31 return 'n'
32 if type(obj) == bool:
33 return 'b' + ('t' if obj else 'f')
34 if type(obj) == int:
35 return 'i' + str(obj)
36 if type(obj) == long:
37 return 'I' + str(obj)
38 if type(obj) == float:
39 return 'f' + str(obj)
40 if type(obj) == str:
41 return 's' + str(len(obj)) + ':' + obj
42 if type(obj) == list:
43 return 'l' + str(len(obj)) + ''.join(encode(i) for i in obj)
44 if type(obj) == tuple:
45 return 't' + str(len(obj)) + ''.join(encode(i) for i in obj)
46 if type(obj) == set:
47 return 'z' + str(len(obj)) + ''.join(encode(i) for i in obj)
48 if type(obj) == frozenset:
49 return 'Z' + str(len(obj)) + ''.join(encode(i) for i in obj)
50 if type(obj) == dict:
51 return 'd' + str(len(obj)) + ''.join(encode(i) + encode(j) for i, j in obj.items())
52 if obj.__class__ in classes:
53 attrs = [i for i in dir(obj) if type(i) != str or i[0] != '_']
54 return 'o' + encode(obj.__class__.__name__) + str(len(attrs)) + ''.join(encode(i) + encode(getattr(obj,i)) for i in attrs)
55 raise NotImplementedError("Cant handle object " + repr(obj.__class__))
57 def decode(text):
58 return __decode(text, 0)[1]
60 def __read_number(text, pos):
61 for p in xrange(pos, len(text)):
62 if text[p] not in ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.') and (p != pos or text[p] not in ('+', '-')):
63 return text[pos:p]
64 return text[pos:]
66 def __decode(text, pos):
67 if text[pos] == 'n':
68 return (1, None)
69 if text[pos] == 'b':
70 return (2, text[1 + pos] == 't')
71 if text[pos] == 'i':
72 i = __read_number(text, 1 + pos)
73 return (1 + len(i), int(i))
74 if text[pos] == 'I':
75 i = __read_number(text, 1 + pos)
76 return (1 + len(i), long(i))
77 if text[pos] == 'f':
78 i = __read_number(text, 1 + pos)
79 return (1 + len(i), float(i))
80 if text[pos] == 's':
81 i = __read_number(text, 1 + pos)
82 return (2 + len(i) + int(i), text[2 + len(i) + pos:2 + len(i) + int(i) + pos])
83 if text[pos] in ('l', 't'):
84 i = __read_number(text, 1 + pos)
85 length = 1 + len(i)
86 r = []
87 for x in xrange(0, int(i)):
88 l, o = __decode(text, pos + length)
89 length += l
90 r.append(o)
91 return (length, tuple(r) if text[pos] == 't' else r)
92 if text[pos] in ('z', 'Z'):
93 i = __read_number(text, 1 + pos)
94 length = 1 + len(i)
95 r = set()
96 for x in xrange(0, int(i)):
97 l, o = __decode(text, pos + length)
98 length += l
99 r.add(o)
100 return (length, frozenset(r) if text[pos] == 'f' else r)
101 if text[pos] == 'd':
102 i = __read_number(text, 1 + pos)
103 length = 1 + len(i)
104 r = {}
105 for x in xrange(0, int(i)):
106 l, k = __decode(text, pos + length)
107 length += l
108 l, v = __decode(text, pos + length)
109 length += l
110 r[k] = v
111 return (length, r)
112 if text[pos] == 'o':
113 length, class_name = __decode(text, pos + 1)
114 i = __read_number(text, 1 + length + pos)
115 length += 1 + len(i)
116 for c in classes:
117 if c.__name__ == class_name:
118 r = c.__new__(c)
119 for x in xrange(0, int(i)):
120 l, k = __decode(text, pos + length)
121 length += l
122 l, v = __decode(text, pos + length)
123 length += l
124 setattr(r, k, v)
125 return (length, r)
126 raise NotImplementedError("Cant handle object " + repr(class_name))
127 return (0, None)