@@ -56,6 +56,18 @@ 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+ return d .decodeFromTypeToDeserializer (typeNum , size , newOffset , dser , depth + 1 )
69+ }
70+
5971func (d * decoder ) decodeCtrlData (offset uint ) (dataType , uint , uint , error ) {
6072 newOffset := offset + 1
6173 if offset >= uint (len (d .buffer )) {
@@ -157,6 +169,68 @@ func (d *decoder) decodeFromType(
157169 }
158170}
159171
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 (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+
160234func (d * decoder ) unmarshalBool (size , offset uint , result reflect.Value ) (uint , error ) {
161235 if size > 1 {
162236 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 {
199273 if result .IsNil () {
200274 result .Set (reflect .New (result .Type ().Elem ()))
201275 }
276+
202277 result = result .Elem ()
203278 }
204279 return result
@@ -486,6 +561,35 @@ func (d *decoder) decodeMap(
486561 return offset , nil
487562}
488563
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+
489593func (d * decoder ) decodePointer (
490594 size uint ,
491595 offset uint ,
@@ -538,6 +642,29 @@ func (d *decoder) decodeSlice(
538642 return offset , nil
539643}
540644
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+
541668func (d * decoder ) decodeString (size , offset uint ) (string , uint ) {
542669 newOffset := offset + size
543670 return string (d .buffer [offset :newOffset ]), newOffset
0 commit comments