1 from mobi.mtld.da.carrier.bucket_type import BucketType
2 from mobi.mtld.da.carrier.byte_reader import ByteReader
3 from mobi.mtld.da.carrier.carrier_data_type import CarrierDataType
4 from mobi.mtld.da.exception.data_file_exception import DataFileException
5 from mobi.mtld.da.data_type import DataType
6 from mobi.mtld.da.property import Property
7 from mobi.mtld.da.property_name import PropertyName
8
9 from binascii import crc32
10
12 _NO_VALUE = -1
13 _NO_CONTAINER = 0
14 _ORDER_SET_CONTAINER = 1
15 CRC32_DOES_NOT_MATCH = 'CRC-32 does not match for bucket "%s".'
16 _property_names = None
17 _propertyStringNames = None
18 _propertyValues = None
19 _properties = None
20 _treeLefts = None
21 _treeRights = None
22 _treeProperties = None
23
32
42
44 """
45 Returns the Radix Trie "left" pointers
46 """
47 return self._treeLefts
48
50 """
51 Returns the Radix Trie "right" pointers
52 """
53 return self._treeRights
54
56 """
57 Returns the properties used in the Radix Trie nodes
58 """
59 return self._treeProperties
60
62 """
63 Returns the property names array
64 """
65 return self._property_names
66
72
89
110
112 """
113 The following is the structure of this bucket:
114 2b Number of indexed items
115 <repeating>
116 1b container type ID: no container, ordered set etc
117 <if container="no container">
118 1B property type - int, boolean, string etc
119 1B/2B/4B length of value bytes --OPTIONAL-- (only applies to some string types)
120 ?B the converted value, some data types have a fixed length such as (boolean len=1, byte len=1, short len=2, int len=4, float len=4)
121 </if>
122
123 <elseif container="ordered set">
124 1B property type - int, boolean, string etc
125 2B number of items in the set
126 <repeat>
127 <if type=string>
128 1B property type - the type of string -
129 1B/2B/4B length of value bytes --OPTIONAL-- (only applies to some string types)
130 </if>
131 ?B the converted value, some data types have a fixed length such as (boolean len=1, byte len=1, short len=2, int len=4, float len=4)
132 </repeat>
133 </if>
134 </repeating>
135 """
136 reader = ByteReader(data)
137 numItems = reader.getShort()
138 self._propertyValues = []
139
140 for i in range(0, numItems):
141 prop = None
142 containerType = reader.getByte()
143 if containerType == self._NO_CONTAINER:
144 prop = self._getSingleValueProperty(reader)
145 elif containerType == self._ORDER_SET_CONTAINER:
146 prop = self._getMultipleValueProperty(reader)
147
148 self._propertyValues.insert(i, prop)
149
159
161 """
162 Read a multi-value property. If the type is a string then the string type
163 is read from the data file for each value in order to know how many bytes
164 to read.
165 """
166 dataType = reader.getByte()
167 numItems = reader.getShort()
168
169 values = []
170 for i in range(0, numItems):
171 tempdataType = dataType
172 if dataType == DataType.STRING:
173 tempdataType = reader.getByte()
174
175 value = self._getPropertyValue(tempdataType, reader)
176 values.insert(i, value)
177
178 dataType = CarrierDataType.getBaseDataType(dataType)
179 return Property(values, dataType)
180
182 """
183 Properties - nameid:valueid
184 The following is the structure of this bucket
185
186
187 The following is the structure of this bucket:
188
189 2B Num of indexed items
190 <repeating>
191 2B num items in collection
192 <repeating>
193 4B property name ID
194 4B property value ID
195 </repeating>
196 </repeating>
197
198
199 The order of the properties is taken as the index for each item. As each
200 """
201 reader = ByteReader(data)
202 numItems = reader.getShort()
203 self._properties = []
204
205 for i in range(0, numItems):
206 props = {}
207 numPropVals = reader.getShort()
208
209 for s in range(0, numPropVals):
210 propId = reader.getInt()
211 valId = reader.getInt()
212
213 if self._property_names[propId] != None:
214 propName = self._property_names[propId]
215 propValue = None
216
217 if self._propertyValues[valId] != None:
218 propValue = self._propertyValues[valId]
219 props[propName.name] = propValue
220
221 self._properties.insert(i, props)
222
224 """
225 Load the data for the IPv4 Tree bucket. This bucket has
226 the following structure:
227
228 These 3 ints repeat for the entire bucket:
229 <repeating>
230 4B properties ID value
231 4B Left value
232 4B Right value
233 </repeating>
234 """
235 reader = ByteReader(data)
236 size = int(len(data) / 12)
237 self._treeRights = []
238 self._treeLefts = []
239 self._treeProperties = []
240
241 for i in range(0, size):
242 propsId = reader.getInt()
243 self._treeLefts.insert(i, reader.getInt())
244 self._treeRights.insert(i, reader.getInt())
245 prop = None
246
247 if(propsId != self._NO_VALUE):
248 prop = self._properties[propsId]
249
250 self._treeProperties.insert(i, prop)
251
297