@@ -123,6 +123,12 @@ func (r *peekLengthReader) Read(b []byte) (int, error) {
123
123
return int (bytesToRead ), nil
124
124
}
125
125
126
+ func convertToPtr (val reflect.Value ) reflect.Value {
127
+ valPtr := reflect .New (val .Type ())
128
+ valPtr .Elem ().Set (val )
129
+ return valPtr
130
+ }
131
+
126
132
// NewDecoder constructs a new default Decoder implementation from the given io.Reader.
127
133
//
128
134
// In this implementation, the value can be any one of the following types:
@@ -305,6 +311,8 @@ func (d *decoder) createEmptyValue(r Reader, t reflect.Type) (reflect.Value, err
305
311
func (d * decoder ) getReflectValue (v * Value , containerType reflect.Type , outer reflect.Type ) (reflect.Value , error ) {
306
312
var val reflect.Value
307
313
314
+ isPtr := (containerType .Kind () == reflect .Ptr )
315
+
308
316
for containerType .Kind () == reflect .Ptr {
309
317
containerType = containerType .Elem ()
310
318
}
@@ -381,6 +389,13 @@ func (d *decoder) getReflectValue(v *Value, containerType reflect.Type, outer re
381
389
switch containerType {
382
390
case tString , tEmpty :
383
391
val = reflect .ValueOf (str )
392
+ case tJSONNumber :
393
+ _ , err := strconv .ParseFloat (str , 64 )
394
+ if err != nil {
395
+ return val , err
396
+ }
397
+ val = reflect .ValueOf (str ).Convert (tJSONNumber )
398
+
384
399
case tURL :
385
400
u , err := url .Parse (str )
386
401
if err != nil {
@@ -398,7 +413,12 @@ func (d *decoder) getReflectValue(v *Value, containerType reflect.Type, outer re
398
413
return val , err
399
414
}
400
415
401
- val = newVal
416
+ if isPtr {
417
+ val = convertToPtr (newVal )
418
+ isPtr = false
419
+ } else {
420
+ val = newVal
421
+ }
402
422
403
423
break
404
424
}
@@ -410,7 +430,12 @@ func (d *decoder) getReflectValue(v *Value, containerType reflect.Type, outer re
410
430
return val , err
411
431
}
412
432
413
- val = newVal
433
+ if isPtr {
434
+ val = convertToPtr (newVal )
435
+ isPtr = false
436
+ } else {
437
+ val = newVal
438
+ }
414
439
415
440
break
416
441
}
@@ -422,7 +447,12 @@ func (d *decoder) getReflectValue(v *Value, containerType reflect.Type, outer re
422
447
return val , err
423
448
}
424
449
425
- val = newVal
450
+ if isPtr {
451
+ val = convertToPtr (newVal )
452
+ isPtr = false
453
+ } else {
454
+ val = newVal
455
+ }
426
456
427
457
break
428
458
}
@@ -450,6 +480,10 @@ func (d *decoder) getReflectValue(v *Value, containerType reflect.Type, outer re
450
480
451
481
if reflect .PtrTo (typeToCreate ) == empty .Type () {
452
482
empty = empty .Elem ()
483
+ if isPtr {
484
+ empty = convertToPtr (empty )
485
+ isPtr = false
486
+ }
453
487
}
454
488
455
489
val = empty
@@ -492,6 +526,7 @@ func (d *decoder) getReflectValue(v *Value, containerType reflect.Type, outer re
492
526
} else {
493
527
val = reflect .ValueOf (v .DateTime ())
494
528
}
529
+
495
530
case 0xA :
496
531
if containerType != tEmpty {
497
532
return val , nil
@@ -573,7 +608,6 @@ func (d *decoder) getReflectValue(v *Value, containerType reflect.Type, outer re
573
608
}
574
609
575
610
val = reflect .ValueOf (uint (i ))
576
-
577
611
case tEmpty , tInt32 , tInt64 , tInt , tFloat32 , tFloat64 :
578
612
val = reflect .ValueOf (i ).Convert (containerType )
579
613
case tJSONNumber :
@@ -666,6 +700,9 @@ func (d *decoder) getReflectValue(v *Value, containerType reflect.Type, outer re
666
700
return val , fmt .Errorf ("invalid BSON type: %s" , v .Type ())
667
701
}
668
702
703
+ if isPtr && val .IsValid () && ! val .CanAddr () {
704
+ val = convertToPtr (val )
705
+ }
669
706
return val , nil
670
707
}
671
708
@@ -736,7 +773,11 @@ func (d *decoder) decodeBSONArrayToSlice(sliceType reflect.Type) (reflect.Value,
736
773
}
737
774
738
775
if sliceType .Elem ().Kind () == reflect .Ptr {
739
- elem = elem .Addr ()
776
+ if elem .CanAddr () {
777
+ elem = elem .Addr ()
778
+ } else {
779
+ elem = elem .Elem ().Addr ()
780
+ }
740
781
}
741
782
out .Index (i ).Set (elem )
742
783
}
@@ -872,7 +913,11 @@ func (d *decoder) decodeIntoStruct(structVal reflect.Value) error {
872
913
873
914
if v != zeroVal {
874
915
if field .Type ().Kind () == reflect .Ptr {
875
- v = v .Addr ()
916
+ if v .CanAddr () {
917
+ v = v .Addr ()
918
+ } else {
919
+ v = v .Elem ().Addr ()
920
+ }
876
921
}
877
922
878
923
field .Set (v )
0 commit comments