1+ """
2+ maxminddb.decoder
3+ ~~~~~~~~~~~~~~~~~
4+
5+ This package contains code for decoding the MaxMind DB data section.
6+
7+ """
18from __future__ import unicode_literals
29
3- from struct import pack , unpack
10+ import struct
411
5- from .compat import byte_from_int , int_from_bytes
6- from .errors import InvalidDatabaseError
12+ from maxminddb .compat import byte_from_int , int_from_bytes
13+ from maxminddb .errors import InvalidDatabaseError
714
815
9- class Decoder (object ):
16+ class Decoder (object ): # pylint: disable=too-few-public-methods
1017
11- """Decodes the data section of the MaxMind DB"""
18+ """Decoder for the data section of the MaxMind DB"""
1219
1320 def __init__ (self , database_buffer , pointer_base = 0 , pointer_test = False ):
21+ """Created a Decoder for a MaxMind DB
22+
23+ Arguments:
24+ database_buffer -- an mmap'd MaxMind DB file.
25+ pointer_base -- the base number to use when decoding a pointer
26+ pointer_test -- used for internal unit testing of pointer code
27+ """
1428 self ._pointer_test = pointer_test
1529 self ._buffer = database_buffer
1630 self ._pointer_base = pointer_base
@@ -29,15 +43,19 @@ def _decode_bytes(self, size, offset):
2943 new_offset = offset + size
3044 return self ._buffer [offset :new_offset ], new_offset
3145
46+ # pylint: disable=no-self-argument
47+ # |-> I am open to better ways of doing this as long as it doesn't involve
48+ # lots of code duplication.
3249 def _decode_packed_type (type_code , type_size , pad = False ):
50+ # pylint: disable=protected-access, missing-docstring
3351 def unpack_type (self , size , offset ):
3452 if not pad :
3553 self ._verify_size (size , type_size )
3654 new_offset = offset + type_size
3755 packed_bytes = self ._buffer [offset :new_offset ]
3856 if pad :
3957 packed_bytes = packed_bytes .rjust (type_size , b'\x00 ' )
40- (value ,) = unpack (type_code , packed_bytes )
58+ (value ,) = struct . unpack (type_code , packed_bytes )
4159 return value , new_offset
4260 return unpack_type
4361
@@ -59,9 +77,9 @@ def _decode_map(self, size, offset):
5977 def _decode_pointer (self , size , offset ):
6078 pointer_size = ((size >> 3 ) & 0x3 ) + 1
6179 new_offset = offset + pointer_size
62- b = self ._buffer [offset :new_offset ]
63- packed = b if pointer_size == 4 else pack (
64- b'!c' , byte_from_int (size & 0x7 )) + b
80+ pointer_bytes = self ._buffer [offset :new_offset ]
81+ packed = pointer_bytes if pointer_size == 4 else struct . pack (
82+ b'!c' , byte_from_int (size & 0x7 )) + pointer_bytes
6583 unpacked = int_from_bytes (packed )
6684 pointer = unpacked + self ._pointer_base + \
6785 self ._pointer_value_offset [pointer_size ]
@@ -72,8 +90,8 @@ def _decode_pointer(self, size, offset):
7290
7391 def _decode_uint (self , size , offset ):
7492 new_offset = offset + size
75- b = self ._buffer [offset :new_offset ]
76- return int_from_bytes (b ), new_offset
93+ uint_bytes = self ._buffer [offset :new_offset ]
94+ return int_from_bytes (uint_bytes ), new_offset
7795
7896 def _decode_utf8_string (self , size , offset ):
7997 new_offset = offset + size
@@ -96,8 +114,13 @@ def _decode_utf8_string(self, size, offset):
96114 }
97115
98116 def decode (self , offset ):
117+ """Decode a section of the data section starting at offset
118+
119+ Arguments:
120+ offset -- the location of the data structure to decode
121+ """
99122 new_offset = offset + 1
100- (ctrl_byte ,) = unpack (b'!B' , self ._buffer [offset :new_offset ])
123+ (ctrl_byte ,) = struct . unpack (b'!B' , self ._buffer [offset :new_offset ])
101124 type_num = ctrl_byte >> 5
102125 # Extended type
103126 if not type_num :
@@ -108,7 +131,7 @@ def decode(self, offset):
108131 return self ._type_dispatch [type_num ](self , size , new_offset )
109132
110133 def _read_extended (self , offset ):
111- (next_byte ,) = unpack (b'!B' , self ._buffer [offset :offset + 1 ])
134+ (next_byte ,) = struct . unpack (b'!B' , self ._buffer [offset :offset + 1 ])
112135 type_num = next_byte + 7
113136 if type_num < 7 :
114137 raise InvalidDatabaseError (
@@ -134,10 +157,11 @@ def _size_from_ctrl_byte(self, ctrl_byte, offset, type_num):
134157 # Using unpack rather than int_from_bytes as it is about 200 lookups
135158 # per second faster here.
136159 if size == 29 :
137- size = 29 + unpack (b'!B' , size_bytes )[0 ]
160+ size = 29 + struct . unpack (b'!B' , size_bytes )[0 ]
138161 elif size == 30 :
139- size = 285 + unpack (b'!H' , size_bytes )[0 ]
162+ size = 285 + struct . unpack (b'!H' , size_bytes )[0 ]
140163 elif size > 30 :
141- size = unpack (b'!I' , size_bytes .rjust (4 , b'\x00 ' ))[0 ] + 65821
164+ size = struct .unpack (
165+ b'!I' , size_bytes .rjust (4 , b'\x00 ' ))[0 ] + 65821
142166
143167 return size , offset + bytes_to_read
0 commit comments