@@ -56,6 +56,26 @@ func (d *decoder) decode(offset uint, result reflect.Value, depth int) (uint, er
5656 return d .decodeFromType (typeNum , size , newOffset , result , depth + 1 )
5757}
5858
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+ skip , err := dser .ShouldSkip (uintptr (offset ))
69+ if err != nil {
70+ return 0 , err
71+ }
72+ if skip {
73+ return d .nextValueOffset (offset , 1 )
74+ }
75+
76+ return d .decodeFromTypeToDeserializer (typeNum , size , newOffset , dser , depth + 1 )
77+ }
78+
5979func (d * decoder ) decodeCtrlData (offset uint ) (dataType , uint , uint , error ) {
6080 newOffset := offset + 1
6181 if offset >= uint (len (d .buffer )) {
@@ -157,6 +177,68 @@ func (d *decoder) decodeFromType(
157177 }
158178}
159179
180+ func (d * decoder ) decodeFromTypeToDeserializer (
181+ dtype dataType ,
182+ size uint ,
183+ offset uint ,
184+ dser deserializer ,
185+ depth int ,
186+ ) (uint , error ) {
187+ // For these types, size has a special meaning
188+ switch dtype {
189+ case _Bool :
190+ v , offset := d .decodeBool (size , offset )
191+ return offset , dser .Bool (v )
192+ case _Map :
193+ return d .decodeMapToDeserializer (size , offset , dser , depth )
194+ case _Pointer :
195+ pointer , newOffset , err := d .decodePointer (size , offset )
196+ if err != nil {
197+ return 0 , err
198+ }
199+ _ , err = d .decodeToDeserializer (pointer , dser , depth )
200+ return newOffset , err
201+ case _Slice :
202+ return d .decodeSliceToDeserializer (size , offset , dser , depth )
203+ }
204+
205+ // For the remaining types, size is the byte size
206+ if offset + size > uint (len (d .buffer )) {
207+ return 0 , newOffsetError ()
208+ }
209+ switch dtype {
210+ case _Bytes :
211+ v , offset := d .decodeBytes (size , offset )
212+ return offset , dser .Bytes (v )
213+ case _Float32 :
214+ v , offset := d .decodeFloat32 (size , offset )
215+ return offset , dser .Float32 (v )
216+ case _Float64 :
217+ v , offset := d .decodeFloat64 (size , offset )
218+ return offset , dser .Float64 (v )
219+ case _Int32 :
220+ v , offset := d .decodeInt (size , offset )
221+ return offset , dser .Int32 (int32 (v ))
222+ case _String :
223+ v , offset := d .decodeString (size , offset )
224+ return offset , dser .String (v )
225+ case _Uint16 :
226+ v , offset := d .decodeUint (size , offset )
227+ return offset , dser .Uint16 (uint16 (v ))
228+ case _Uint32 :
229+ v , offset := d .decodeUint (size , offset )
230+ return offset , dser .Uint32 (uint32 (v ))
231+ case _Uint64 :
232+ v , offset := d .decodeUint (size , offset )
233+ return offset , dser .Uint64 (v )
234+ case _Uint128 :
235+ v , offset := d .decodeUint128 (size , offset )
236+ return offset , dser .Uint128 (v )
237+ default :
238+ return 0 , newInvalidDatabaseError ("unknown type: %d" , dtype )
239+ }
240+ }
241+
160242func (d * decoder ) unmarshalBool (size , offset uint , result reflect.Value ) (uint , error ) {
161243 if size > 1 {
162244 return 0 , newInvalidDatabaseError ("the MaxMind DB file's data section contains bad data (bool size of %v)" , size )
@@ -199,6 +281,7 @@ func (d *decoder) indirect(result reflect.Value) reflect.Value {
199281 if result .IsNil () {
200282 result .Set (reflect .New (result .Type ().Elem ()))
201283 }
284+
202285 result = result .Elem ()
203286 }
204287 return result
@@ -486,6 +569,35 @@ func (d *decoder) decodeMap(
486569 return offset , nil
487570}
488571
572+ func (d * decoder ) decodeMapToDeserializer (
573+ size uint ,
574+ offset uint ,
575+ dser deserializer ,
576+ depth int ,
577+ ) (uint , error ) {
578+ err := dser .StartMap (size )
579+ if err != nil {
580+ return 0 , err
581+ }
582+ for i := uint (0 ); i < size ; i ++ {
583+ // TODO - implement key/value skipping?
584+ offset , err = d .decodeToDeserializer (offset , dser , depth )
585+ if err != nil {
586+ return 0 , err
587+ }
588+
589+ offset , err = d .decodeToDeserializer (offset , dser , depth )
590+ if err != nil {
591+ return 0 , err
592+ }
593+ }
594+ err = dser .End ()
595+ if err != nil {
596+ return 0 , err
597+ }
598+ return offset , nil
599+ }
600+
489601func (d * decoder ) decodePointer (
490602 size uint ,
491603 offset uint ,
@@ -538,6 +650,29 @@ func (d *decoder) decodeSlice(
538650 return offset , nil
539651}
540652
653+ func (d * decoder ) decodeSliceToDeserializer (
654+ size uint ,
655+ offset uint ,
656+ dser deserializer ,
657+ depth int ,
658+ ) (uint , error ) {
659+ err := dser .StartSlice (size )
660+ if err != nil {
661+ return 0 , err
662+ }
663+ for i := uint (0 ); i < size ; i ++ {
664+ offset , err = d .decodeToDeserializer (offset , dser , depth )
665+ if err != nil {
666+ return 0 , err
667+ }
668+ }
669+ err = dser .End ()
670+ if err != nil {
671+ return 0 , err
672+ }
673+ return offset , nil
674+ }
675+
541676func (d * decoder ) decodeString (size , offset uint ) (string , uint ) {
542677 newOffset := offset + size
543678 return string (d .buffer [offset :newOffset ]), newOffset
0 commit comments