11# vim: set ts=4 sw=4 tw=79 fileencoding=utf-8:
22# Copyright (c) 2011, Timo Schmid <[email protected] > 33# All rights reserved.
4- #
4+ #
55# Redistribution and use in source and binary forms, with or without
66# modification, are permitted provided that the following conditions
77# are met:
88#
9- # * Redistributions of source code must retain the above copyright
9+ # * Redistributions of source code must retain the above copyright
1010# notice, this list of conditions and the following disclaimer.
1111# * Redistributions in binary form must reproduce the above copyright
1212# notice, this list of conditions and the following disclaimer in the
2626# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2727# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2828# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+ from __future__ import unicode_literals
30+
31+ from builtins import str , bytes
2932
3033import struct
3134import logging
3235import sys
3336
3437log = logging .getLogger (__name__ )
3538
39+
3640class MultiByteInt31 (object ):
3741
3842 def __init__ (self , * args ):
3943 self .value = args [0 ] if len (args ) else None
40-
44+
4145 def to_bytes (self ):
4246 """
4347 >>> MultiByteInt31(268435456).to_bytes()
44- '\\ x80\\ x80\\ x80\\ x80\\ x01'
48+ b '\\ x80\\ x80\\ x80\\ x80\\ x01'
4549 >>> MultiByteInt31(0x7f).to_bytes()
46- '\\ x7f'
50+ b '\\ x7f'
4751 >>> MultiByteInt31(0x3fff).to_bytes()
48- '\\ xff\\ x7f'
52+ b '\\ xff\\ x7f'
4953 >>> MultiByteInt31(0x1fffff).to_bytes()
50- '\\ xff\\ xff\\ x7f'
54+ b '\\ xff\\ xff\\ x7f'
5155 >>> MultiByteInt31(0xfffffff).to_bytes()
52- '\\ xff\\ xff\\ xff\\ x7f'
56+ b '\\ xff\\ xff\\ xff\\ x7f'
5357 >>> MultiByteInt31(0x3fffffff).to_bytes()
54- '\\ xff\\ xff\\ xff\\ xff\\ x03'
58+ b '\\ xff\\ xff\\ xff\\ xff\\ x03'
5559 """
5660 value_a = self .value & 0x7F
57- value_b = (self .value >> 7 ) & 0x7F
61+ value_b = (self .value >> 7 ) & 0x7F
5862 value_c = (self .value >> 14 ) & 0x7F
5963 value_d = (self .value >> 21 ) & 0x7F
6064 value_e = (self .value >> 28 ) & 0x03
6165 if value_e != 0 :
62- return struct .pack ('<BBBBB' ,
63- value_a | 0x80 ,
64- value_b | 0x80 ,
65- value_c | 0x80 ,
66- value_d | 0x80 ,
67- value_e )
66+ ret = struct .pack (b '<BBBBB' ,
67+ value_a | 0x80 ,
68+ value_b | 0x80 ,
69+ value_c | 0x80 ,
70+ value_d | 0x80 ,
71+ value_e )
6872 elif value_d != 0 :
69- return struct .pack ('<BBBB' ,
70- value_a | 0x80 ,
71- value_b | 0x80 ,
72- value_c | 0x80 ,
73- value_d )
73+ ret = struct .pack (b '<BBBB' ,
74+ value_a | 0x80 ,
75+ value_b | 0x80 ,
76+ value_c | 0x80 ,
77+ value_d )
7478 elif value_c != 0 :
75- return struct .pack ('<BBB' ,
76- value_a | 0x80 ,
77- value_b | 0x80 ,
78- value_c )
79+ ret = struct .pack (b '<BBB' ,
80+ value_a | 0x80 ,
81+ value_b | 0x80 ,
82+ value_c )
7983 elif value_b != 0 :
80- return struct .pack ('<BB' ,
81- value_a | 0x80 ,
82- value_b )
84+ ret = struct .pack (b '<BB' ,
85+ value_a | 0x80 ,
86+ value_b )
8387 else :
84- return struct .pack ('<B' ,
85- value_a )
88+ ret = struct .pack (b'<B' ,
89+ value_a )
90+ return bytes (ret )
8691
8792 def __str__ (self ):
8893 return str (self .value )
8994
9095 @classmethod
9196 def parse (cls , fp ):
9297 v = 0
93- #tmp = ''
98+ # tmp = ''
9499 for pos in range (4 ):
95100 b = fp .read (1 )
96- #tmp += b
97- value = struct .unpack ('<B' , b )[0 ]
101+ # tmp += b
102+ value = struct .unpack (b '<B' , b )[0 ]
98103 v |= (value & 0x7F ) << 7 * pos
99104 if not value & 0x80 :
100105 break
101- #print ('%s => 0x%X' % (repr(tmp), v))
102-
106+ # print ('%s => 0x%X' % (repr(tmp), v))
107+
103108 return cls (v )
104109
110+
105111class Utf8String (object ):
106112
107113 def __init__ (self , * args ):
108114 self .value = args [0 ] if len (args ) else None
109- if sys .version_info >= (3 ,0 , 0 ):
115+ if sys .version_info >= (3 , 0 , 0 ):
110116 if not isinstance (self .value , str ):
111117 self .value = self .value .decode ('utf-8' )
112118 else :
@@ -115,62 +121,60 @@ def __init__(self, *args):
115121
116122 def to_bytes (self ):
117123 """
118- >>> Utf8String(u "abc").to_bytes()
119- '\\ x03\x61 \x62 \x63 '
120- >>> Utf8String(u "\xfc ber").to_bytes()
121- '\\ x05\\ xc3\\ xbcber'
122- >>> Utf8String("\\ xc3\\ xbcber".decode('utf-8')).to_bytes()
123- '\\ x05\\ xc3\\ xbcber'
124+ >>> Utf8String("abc").to_bytes()
125+ b '\\ x03\x61 \x62 \x63 '
126+ >>> Utf8String("\xfc ber").to_bytes()
127+ b '\\ x05\\ xc3\\ xbcber'
128+ >>> Utf8String(b "\\ xc3\\ xbcber".decode('utf-8')).to_bytes()
129+ b '\\ x05\\ xc3\\ xbcber'
124130 """
125- data = self .value .encode ('utf-8' )
131+ data = self .value .encode ('utf-8' )
126132 strlen = len (data )
127133
128- return MultiByteInt31 (strlen ).to_bytes () + data
134+ return bytes ( MultiByteInt31 (strlen ).to_bytes () + data )
129135
130136 def __str__ (self ):
131- return self .value .encode ('utf-8' )
132-
133- def __unicode__ (self ):
134- return self .value
137+ return str (self .value )
135138
136139 @classmethod
137140 def parse (cls , fp ):
138141 """
139- >>> from StringIO import StringIO as io
140- >>> fp = io( "\\ x05\\ xc3\\ xbcber")
142+ >>> from io import BytesIO
143+ >>> fp = BytesIO(b "\\ x05\\ xc3\\ xbcber")
141144 >>> s = Utf8String.parse(fp)
142145 >>> s.to_bytes()
143- '\\ x05\\ xc3\\ xbcber'
144- >>> print str(s)
146+ b '\\ x05\\ xc3\\ xbcber'
147+ >>> print( str(s) )
145148 über
146149 """
147- lngth = struct .unpack ('<B' , fp .read (1 ))[0 ]
148-
150+ lngth = struct .unpack (b '<B' , fp .read (1 ))[0 ]
151+
149152 return cls (fp .read (lngth ).decode ('utf-8' ))
150153
154+
151155class Decimal (object ):
152156 def __init__ (self , sign , high , low , scale ):
153157
154158 if not 0 <= scale <= 28 :
155159 raise ValueError ('scale %d isn\' t between 0 and 28' % scale )
156160 self .sign = sign
157161 self .high = high
158- self .low = low
162+ self .low = low
159163 self .scale = scale
160164
161165 def to_bytes (self ):
162166 """
163167 >>> Decimal(False, 0, 5123456, 6).to_bytes()
164- '\\ x00\\ x00\\ x06\\ x00\\ x00\\ x00\\ x00\\ x00\\ x80-N\\ x00\\ x00\\ x00\\ x00\\ x00'
168+ b '\\ x00\\ x00\\ x06\\ x00\\ x00\\ x00\\ x00\\ x00\\ x80-N\\ x00\\ x00\\ x00\\ x00\\ x00'
165169 """
166170 log .warn ('Possible false interpretation' )
167- bytes = struct .pack ('<H' , 0 )
168- bytes += struct .pack ('<B' , self .scale )
169- bytes += struct .pack ('<B' , 0x80 if self .sign else 0x00 )
170- bytes += struct .pack ('<I' , self .high )
171- bytes += struct .pack ('<Q' , self .low )
171+ bt = struct .pack (b '<H' , 0 )
172+ bt += struct .pack (b '<B' , self .scale )
173+ bt += struct .pack (b '<B' , 0x80 if self .sign else 0x00 )
174+ bt += struct .pack (b '<I' , self .high )
175+ bt += struct .pack (b '<Q' , self .low )
172176
173- return bytes
177+ return bytes ( bt )
174178
175179 def __str__ (self ):
176180 """
@@ -187,25 +191,25 @@ def __str__(self):
187191 value = str (self .high * 2 ** 64 + self .low )
188192 if self .scale > 0 :
189193 value = value [:- self .scale ] + '.' + value [- self .scale :]
190-
194+
191195 if self .sign :
192196 value = '-%s' % value
193197 return value
194198
195199 @classmethod
196200 def parse (cls , fp ):
197201 """
198- >>> from StringIO import StringIO as io
199- >>> buf = io( '\\ x00\\ x00\\ x06\\ x00\\ x00\\ x00\\ x00\\ x00\\ x80-N\\ x00\\ x00\\ x00\\ x00\\ x00')
202+ >>> from io import BytesIO
203+ >>> buf = BytesIO(b '\\ x00\\ x00\\ x06\\ x00\\ x00\\ x00\\ x00\\ x00\\ x80-N\\ x00\\ x00\\ x00\\ x00\\ x00')
200204 >>> str(Decimal.parse(buf))
201205 '5.123456'
202206 """
203207 log .warn ('Possible false interpretation' )
204208 fp .read (2 )
205- scale = struct .unpack ('<B' , fp .read (1 ))[0 ]
206- sign = struct .unpack ('<B' , fp .read (1 ))[0 ] & 0x80
207- high = struct .unpack ('<I' , fp .read (4 ))[0 ]
208- low = struct .unpack ('<Q' , fp .read (8 ))[0 ]
209+ scale = struct .unpack (b '<B' , fp .read (1 ))[0 ]
210+ sign = struct .unpack (b '<B' , fp .read (1 ))[0 ] & 0x80
211+ high = struct .unpack (b '<I' , fp .read (4 ))[0 ]
212+ low = struct .unpack (b '<Q' , fp .read (8 ))[0 ]
209213
210214 return cls (sign , high , low , scale )
211215
0 commit comments