import string from itertools import takewhile islice from types import

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import string
from itertools import takewhile,islice
from types import *
import errors
from utils import AdvancedIterator
class InvalidData(errors.Standart):
pass
def _ext_str(itr):
dec_len=''.join(takewhile(lambda char:char!=':',itr))
try:
dec_len=int(dec_len)
except ValueError:
raise InvalidData(dec_len,"invalid string's length declaration")
ext_str=''.join(islice(itr,dec_len))
str_len=len(ext_str)
if dec_len!=str_len:
raise InvalidData(ext_str,"length of string (%(str_len)i) differs from "
"declared (%(dec_len)i)" %locals())
return ext_str
def _ext_int(itr):
# skipping 'i'
itr.shift()
ext_int=''.join(takewhile(lambda char:char!='e',itr))
try:
ext_int=int(ext_int)
except ValueError:
raise InvalidData,(ext_int,"is not an integer")
return ext_int
def _ext_list(itr):
# skipping 'l'
itr.shift()
ext_list=[]
for ichar in itr:
if ichar=='e':
break
else:
itr.shift(-1)
ext_list.append(_get_extractor(ichar)(itr))
return ext_list
def _ext_dict(itr):
# skipping 'd'
itr.shift()
ext_dict={}
for key_ichar in itr:
if key_ichar=='e':
break
else:
itr.shift(-1)
key=_get_extractor(key_ichar)(itr)
value=_get_extractor(itr._next())(itr)
ext_dict[key]=value
return ext_dict
def _enc_str(dec_str):
return '%i:%s' %(len(dec_str),dec_str)
def _enc_int(dec_int):
return 'i%ie' %dec_int
def _enc_list(dec_list):
return 'l%se' %''.join(_get_encoder(type(item))(item) for item in dec_list)
def _enc_dict(dec_dict):
content=''
for key in sorted(dec_dict.keys()):
if isinstance(key,(StringType,StringTypes)):
content+=(encode(key)+encode(dec_dict[key]))
else:
raise InvalidData(key,"dictionary keys must be strings")
return 'd%se' %content
def _enc_bool(dec_bool):
if dec_bool:
return _enc_int(1)
return _enc_int(0)
def _get_extractor(ichar):
if ichar in string.digits:
return _ext_str
elif ichar=='i':
return _ext_int
elif ichar=='l':
return _ext_list
elif ichar=='d':
return _ext_dict
else:
raise InvalidData(ichar,"invalid initial character")
def _get_encoder(type):
if type in (StringType,StringTypes):
return _enc_str
elif type in (IntType,LongType):
return _enc_int
elif type in (ListType,TupleType):
return _enc_list
elif type is DictType:
return _enc_dict
elif type is BooleanType:
return _enc_bool
else:
raise ValueError,"unsupported value type"
def decode(be_data):
return _get_extractor(be_data[0])(AdvancedIterator(be_data))
def encode(value):
return _get_encoder(type(value))(value)