diff --git a/deluge/rencode.py b/deluge/rencode.py index 7c0f7d8b1..40d93634f 100644 --- a/deluge/rencode.py +++ b/deluge/rencode.py @@ -73,19 +73,19 @@ MAX_INT_LENGTH = 64 # The bencode 'typecodes' such as i, d, etc have been extended and # relocated on the base-256 character set. -CHR_LIST = chr(59) -CHR_DICT = chr(60) -CHR_INT = chr(61) -CHR_INT1 = chr(62) -CHR_INT2 = chr(63) -CHR_INT4 = chr(64) -CHR_INT8 = chr(65) +CHR_LIST = chr(59) +CHR_DICT = chr(60) +CHR_INT = chr(61) +CHR_INT1 = chr(62) +CHR_INT2 = chr(63) +CHR_INT4 = chr(64) +CHR_INT8 = chr(65) CHR_FLOAT32 = chr(66) CHR_FLOAT64 = chr(44) -CHR_TRUE = chr(67) -CHR_FALSE = chr(68) -CHR_NONE = chr(69) -CHR_TERM = chr(127) +CHR_TRUE = chr(67) +CHR_FALSE = chr(68) +CHR_NONE = chr(69) +CHR_TERM = chr(127) # Positive integers with value embedded in typecode. INT_POS_FIXED_START = 0 @@ -110,6 +110,7 @@ LIST_FIXED_COUNT = 64 # Whether strings should be decoded when loading _decode_utf8 = False + def decode_int(x, f): f += 1 newf = x.index(CHR_TERM, f) @@ -126,32 +127,39 @@ def decode_int(x, f): raise ValueError return (n, newf+1) + def decode_intb(x, f): f += 1 return (struct.unpack('!b', x[f:f+1])[0], f+1) + def decode_inth(x, f): f += 1 return (struct.unpack('!h', x[f:f+2])[0], f+2) + def decode_intl(x, f): f += 1 return (struct.unpack('!l', x[f:f+4])[0], f+4) + def decode_intq(x, f): f += 1 return (struct.unpack('!q', x[f:f+8])[0], f+8) + def decode_float32(x, f): f += 1 n = struct.unpack('!f', x[f:f+4])[0] return (n, f+4) + def decode_float64(x, f): f += 1 n = struct.unpack('!d', x[f:f+8])[0] return (n, f+8) + def decode_string(x, f): colon = x.index(':', f) try: @@ -166,6 +174,7 @@ def decode_string(x, f): s = s.decode('utf8') return (s, colon+n) + def decode_list(x, f): r, f = [], f+1 while x[f] != CHR_TERM: @@ -173,6 +182,7 @@ def decode_list(x, f): r.append(v) return (tuple(r), f + 1) + def decode_dict(x, f): r, f = {}, f+1 while x[f] != CHR_TERM: @@ -180,14 +190,17 @@ def decode_dict(x, f): r[k], f = decode_func[x[f]](x, f) return (r, f + 1) + def decode_true(x, f): - return (True, f+1) + return (True, f+1) + def decode_false(x, f): - return (False, f+1) + return (False, f+1) + def decode_none(x, f): - return (None, f+1) + return (None, f+1) decode_func = {} decode_func['0'] = decode_string @@ -200,18 +213,19 @@ decode_func['6'] = decode_string decode_func['7'] = decode_string decode_func['8'] = decode_string decode_func['9'] = decode_string -decode_func[CHR_LIST ] = decode_list -decode_func[CHR_DICT ] = decode_dict -decode_func[CHR_INT ] = decode_int -decode_func[CHR_INT1 ] = decode_intb -decode_func[CHR_INT2 ] = decode_inth -decode_func[CHR_INT4 ] = decode_intl -decode_func[CHR_INT8 ] = decode_intq +decode_func[CHR_LIST] = decode_list +decode_func[CHR_DICT] = decode_dict +decode_func[CHR_INT] = decode_int +decode_func[CHR_INT1] = decode_intb +decode_func[CHR_INT2] = decode_inth +decode_func[CHR_INT4] = decode_intl +decode_func[CHR_INT8] = decode_intq decode_func[CHR_FLOAT32] = decode_float32 decode_func[CHR_FLOAT64] = decode_float64 -decode_func[CHR_TRUE ] = decode_true -decode_func[CHR_FALSE ] = decode_false -decode_func[CHR_NONE ] = decode_none +decode_func[CHR_TRUE] = decode_true +decode_func[CHR_FALSE] = decode_false +decode_func[CHR_NONE] = decode_none + def make_fixed_length_string_decoders(): def make_decoder(slen): @@ -226,6 +240,7 @@ def make_fixed_length_string_decoders(): make_fixed_length_string_decoders() + def make_fixed_length_list_decoders(): def make_decoder(slen): def f(x, f): @@ -240,6 +255,7 @@ def make_fixed_length_list_decoders(): make_fixed_length_list_decoders() + def make_fixed_length_int_decoders(): def make_decoder(j): def f(x, f): @@ -252,6 +268,7 @@ def make_fixed_length_int_decoders(): make_fixed_length_int_decoders() + def make_fixed_length_dict_decoders(): def make_decoder(slen): def f(x, f): @@ -266,13 +283,6 @@ def make_fixed_length_dict_decoders(): make_fixed_length_dict_decoders() -def encode_dict(x,r): - r.append(CHR_DICT) - for k, v in x.items(): - encode_func[type(k)](k, r) - encode_func[type(v)](v, r) - r.append(CHR_TERM) - def loads(x, decode_utf8=False): global _decode_utf8 @@ -287,6 +297,7 @@ def loads(x, decode_utf8=False): from types import StringType, IntType, LongType, DictType, ListType, TupleType, FloatType, NoneType, UnicodeType + def encode_int(x, r): if 0 <= x < INT_POS_FIXED_COUNT: r.append(chr(INT_POS_FIXED_START+x)) @@ -306,27 +317,34 @@ def encode_int(x, r): raise ValueError('overflow') r.extend((CHR_INT, s, CHR_TERM)) + def encode_float32(x, r): r.extend((CHR_FLOAT32, struct.pack('!f', x))) + def encode_float64(x, r): r.extend((CHR_FLOAT64, struct.pack('!d', x))) + def encode_bool(x, r): r.extend({False: CHR_FALSE, True: CHR_TRUE}[bool(x)]) + def encode_none(x, r): r.extend(CHR_NONE) + def encode_string(x, r): if len(x) < STR_FIXED_COUNT: r.extend((chr(STR_FIXED_START + len(x)), x)) else: r.extend((str(len(x)), ':', x)) + def encode_unicode(x, r): encode_string(x.encode("utf8"), r) + def encode_list(x, r): if len(x) < LIST_FIXED_COUNT: r.append(chr(LIST_FIXED_START + len(x))) @@ -338,7 +356,8 @@ def encode_list(x, r): encode_func[type(i)](i, r) r.append(CHR_TERM) -def encode_dict(x,r): + +def encode_dict(x, r): if len(x) < DICT_FIXED_COUNT: r.append(chr(DICT_FIXED_START + len(x))) for k, v in x.items(): @@ -369,6 +388,7 @@ try: except ImportError: pass + def dumps(x, float_bits=DEFAULT_FLOAT_BITS): """ Dump data structure to str. @@ -389,33 +409,36 @@ def dumps(x, float_bits=DEFAULT_FLOAT_BITS): lock.release() return ''.join(r) + def test(): f1 = struct.unpack('!f', struct.pack('!f', 25.5))[0] f2 = struct.unpack('!f', struct.pack('!f', 29.3))[0] f3 = struct.unpack('!f', struct.pack('!f', -0.6))[0] - L = (({'a':15, 'bb':f1, 'ccc':f2, '':(f3,(),False,True,'')},('a',10**20),tuple(range(-100000,100000)),'b'*31,'b'*62,'b'*64,2**30,2**33,2**62,2**64,2**30,2**33,2**62,2**64,False,False, True, -1, 2, 0),) - assert loads(dumps(L)) == L - d = dict(zip(range(-100000,100000),range(-100000,100000))) - d.update({'a':20, 20:40, 40:41, f1:f2, f2:f3, f3:False, False:True, True:False}) - L = (d, {}, {5:6}, {7:7,True:8}, {9:10, 22:39, 49:50, 44: ''}) - assert loads(dumps(L)) == L - L = ('', 'a'*10, 'a'*100, 'a'*1000, 'a'*10000, 'a'*100000, 'a'*1000000, 'a'*10000000) - assert loads(dumps(L)) == L - L = tuple([dict(zip(range(n),range(n))) for n in range(100)]) + ('b',) - assert loads(dumps(L)) == L - L = tuple([dict(zip(range(n),range(-n,0))) for n in range(100)]) + ('b',) - assert loads(dumps(L)) == L - L = tuple([tuple(range(n)) for n in range(100)]) + ('b',) - assert loads(dumps(L)) == L - L = tuple(['a'*n for n in range(1000)]) + ('b',) - assert loads(dumps(L)) == L - L = tuple(['a'*n for n in range(1000)]) + (None,True,None) - assert loads(dumps(L)) == L - assert loads(dumps(None)) == None - assert loads(dumps({None:None})) == {None:None} - assert 1e-10