@@ -56,6 +56,18 @@ func (d *decoder) decode(offset uint, result reflect.Value, depth int) (uint, er
56
56
return d .decodeFromType (typeNum , size , newOffset , result , depth + 1 )
57
57
}
58
58
59
+ func (d * decoder ) decodeToDeserializer (offset uint , dser Deserializer , depth int ) (uint , error ) {
60
+ if depth > maximumDataStructureDepth {
61
+ return 0 , newInvalidDatabaseError ("exceeded maximum data structure depth; database is likely corrupt" )
62
+ }
63
+ typeNum , size , newOffset , err := d .decodeCtrlData (offset )
64
+ if err != nil {
65
+ return 0 , err
66
+ }
67
+
68
+ return d .decodeFromTypeToDeserializer (typeNum , size , newOffset , dser , depth + 1 )
69
+ }
70
+
59
71
func (d * decoder ) decodeCtrlData (offset uint ) (dataType , uint , uint , error ) {
60
72
newOffset := offset + 1
61
73
if offset >= uint (len (d .buffer )) {
@@ -157,6 +169,68 @@ func (d *decoder) decodeFromType(
157
169
}
158
170
}
159
171
172
+ func (d * decoder ) decodeFromTypeToDeserializer (
173
+ dtype dataType ,
174
+ size uint ,
175
+ offset uint ,
176
+ dser Deserializer ,
177
+ depth int ,
178
+ ) (uint , error ) {
179
+ // For these types, size has a special meaning
180
+ switch dtype {
181
+ case _Bool :
182
+ v , offset := d .decodeBool (size , offset )
183
+ return offset , dser .Bool (v )
184
+ case _Map :
185
+ return d .decodeMapToDeserializer (size , offset , dser , depth )
186
+ case _Pointer :
187
+ pointer , newOffset , err := d .decodePointer (size , offset )
188
+ if err != nil {
189
+ return 0 , err
190
+ }
191
+ _ , err = d .decodeToDeserializer (pointer , dser , depth )
192
+ return newOffset , err
193
+ case _Slice :
194
+ return d .decodeSliceToDeserializer (size , offset , dser , depth )
195
+ }
196
+
197
+ // For the remaining types, size is the byte size
198
+ if offset + size > uint (len (d .buffer )) {
199
+ return 0 , newOffsetError ()
200
+ }
201
+ switch dtype {
202
+ case _Bytes :
203
+ v , offset := d .decodeBytes (size , offset )
204
+ return offset , dser .Bytes (v )
205
+ case _Float32 :
206
+ v , offset := d .decodeFloat32 (size , offset )
207
+ return offset , dser .Float32 (v )
208
+ case _Float64 :
209
+ v , offset := d .decodeFloat64 (size , offset )
210
+ return offset , dser .Float64 (v )
211
+ case _Int32 :
212
+ v , offset := d .decodeInt (size , offset )
213
+ return offset , dser .Int32 (int32 (v ))
214
+ case _String :
215
+ v , offset := d .decodeString (size , offset )
216
+ return offset , dser .String (v )
217
+ case _Uint16 :
218
+ v , offset := d .decodeUint (size , offset )
219
+ return offset , dser .Uint16 (uint16 (v ))
220
+ case _Uint32 :
221
+ v , offset := d .decodeUint (size , offset )
222
+ return offset , dser .Uint32 (uint32 (v ))
223
+ case _Uint64 :
224
+ v , offset := d .decodeUint (size , offset )
225
+ return offset , dser .Uint64 (uint64 (v ))
226
+ case _Uint128 :
227
+ v , offset := d .decodeUint128 (size , offset )
228
+ return offset , dser .Uint128 (v )
229
+ default :
230
+ return 0 , newInvalidDatabaseError ("unknown type: %d" , dtype )
231
+ }
232
+ }
233
+
160
234
func (d * decoder ) unmarshalBool (size , offset uint , result reflect.Value ) (uint , error ) {
161
235
if size > 1 {
162
236
return 0 , newInvalidDatabaseError ("the MaxMind DB file's data section contains bad data (bool size of %v)" , size )
@@ -199,6 +273,7 @@ func (d *decoder) indirect(result reflect.Value) reflect.Value {
199
273
if result .IsNil () {
200
274
result .Set (reflect .New (result .Type ().Elem ()))
201
275
}
276
+
202
277
result = result .Elem ()
203
278
}
204
279
return result
@@ -486,6 +561,35 @@ func (d *decoder) decodeMap(
486
561
return offset , nil
487
562
}
488
563
564
+ func (d * decoder ) decodeMapToDeserializer (
565
+ size uint ,
566
+ offset uint ,
567
+ dser Deserializer ,
568
+ depth int ,
569
+ ) (uint , error ) {
570
+ err := dser .StartMap (size )
571
+ if err != nil {
572
+ return 0 , err
573
+ }
574
+ for i := uint (0 ); i < size ; i ++ {
575
+ // TODO - implement key/value skipping?
576
+ offset , err = d .decodeToDeserializer (offset , dser , depth )
577
+ if err != nil {
578
+ return 0 , err
579
+ }
580
+
581
+ offset , err = d .decodeToDeserializer (offset , dser , depth )
582
+ if err != nil {
583
+ return 0 , err
584
+ }
585
+ }
586
+ err = dser .End ()
587
+ if err != nil {
588
+ return 0 , err
589
+ }
590
+ return offset , nil
591
+ }
592
+
489
593
func (d * decoder ) decodePointer (
490
594
size uint ,
491
595
offset uint ,
@@ -538,6 +642,29 @@ func (d *decoder) decodeSlice(
538
642
return offset , nil
539
643
}
540
644
645
+ func (d * decoder ) decodeSliceToDeserializer (
646
+ size uint ,
647
+ offset uint ,
648
+ dser Deserializer ,
649
+ depth int ,
650
+ ) (uint , error ) {
651
+ err := dser .StartSlice (size )
652
+ if err != nil {
653
+ return 0 , err
654
+ }
655
+ for i := uint (0 ); i < size ; i ++ {
656
+ offset , err = d .decodeToDeserializer (offset , dser , depth )
657
+ if err != nil {
658
+ return 0 , err
659
+ }
660
+ }
661
+ err = dser .End ()
662
+ if err != nil {
663
+ return 0 , err
664
+ }
665
+ return offset , nil
666
+ }
667
+
541
668
func (d * decoder ) decodeString (size , offset uint ) (string , uint ) {
542
669
newOffset := offset + size
543
670
return string (d .buffer [offset :newOffset ]), newOffset
0 commit comments