@@ -150,25 +150,71 @@ def read_byte(self):
150150 if self .bit_shift == 0 :
151151 return ord (self .read_basic (1 ))
152152 else :
153- return self .read (1 )[0 ]
153+ extra_bits = self .bit_shift
154+ hi_bits = self .last_byte >> extra_bits
155+ last_byte = ord (self .read_basic (1 ))
156+ lo_bits = last_byte & self .lo_masks [extra_bits ]
157+ self .last_byte = last_byte
158+ return hi_bits << extra_bits | lo_bits
159+
154160
155161 def read_int (self , endian = LITTLE_ENDIAN ):
156- """ int32 read """
157- chars = self .read_basic (4 ) if self .bit_shift == 0 else self .read_chars (4 )
158- return struct .unpack (endian + 'I' , chars )[0 ]
162+ if self .bit_shift == 0 :
163+ return struct .unpack (endian + 'I' , self .read_basic (4 ))[0 ]
164+
165+ else :
166+ old_bit_shift = self .bit_shift
167+
168+ # Get all the bytes at once
169+ hi_bits = self .shift (8 - old_bit_shift )
170+ block = struct .unpack ('>I' , self .read_basic (4 ))[0 ]
171+
172+ # Reformat them according to the rules
173+ number = (block >> 8 ) << old_bit_shift | (block & self .lo_masks [old_bit_shift ])
174+ number += hi_bits << (24 + old_bit_shift )
175+
176+ # If the number is little endian, repack it
177+ if endian == LITTLE_ENDIAN :
178+ number = (number & 0xFF000000 ) >> 24 | (number & 0xFF0000 ) >> 8 | (number & 0xFF00 ) << 8 | (number & 0xFF ) << 24
179+
180+ # Reset the shift
181+ self .last_byte = block & 0xFF
182+ self .bit_shift = old_bit_shift
183+
184+ return number
159185
160186 def read_short (self , endian = LITTLE_ENDIAN ):
161187 """ short16 read """
162- chars = self .read_basic (2 ) if self .bit_shift == 0 else self .read_chars (2 )
163- return struct .unpack (endian + 'H' , chars )[0 ]
188+ if self .bit_shift == 0 :
189+ return struct .unpack (endian + 'H' , self .read_basic (2 ))[0 ]
190+
191+ else :
192+ old_bit_shift = self .bit_shift
193+
194+ # Get all the bytes at once
195+ hi_bits = self .shift (8 - old_bit_shift )
196+ block = struct .unpack ('>H' , self .read_basic (2 ))[0 ]
197+
198+ # Reformat them according to the rules
199+ number = (block >> 8 ) << old_bit_shift | (block & self .lo_masks [old_bit_shift ])
200+ number += hi_bits << (8 + old_bit_shift )
201+
202+ # If the number is little endian, repack it
203+ if endian == LITTLE_ENDIAN :
204+ number = (number & 0xFF00 ) >> 8 | (number & 0xFF ) << 8
205+
206+ # Reset the shift
207+ self .last_byte = block & 0xFF
208+ self .bit_shift = old_bit_shift
209+
210+ return number
164211
165212 def read_chars (self , length = 0 ):
166213 if self .bit_shift == 0 :
167214 return self .read_basic (length )
168215 else :
169216 self .char_buffer .truncate (0 )
170- for byte in self .read (length ):
171- self .char_buffer .write (chr (byte ))
217+ self .char_buffer .writelines (map (chr ,self .read (length )))
172218 return self .char_buffer .getvalue ()
173219
174220 def read_hex (self , length = 0 ):
0 commit comments