Browse Source

codec: decode: if unset, default MapType for json decoding to map[string]interface{}

This does the "right" thing for default decoding of json.

Update #217
Ugorji Nwoke 8 years ago
parent
commit
b051152d28
1 changed files with 14 additions and 4 deletions
  1. 14 4
      codec/decode.go

+ 14 - 4
codec/decode.go

@@ -127,11 +127,12 @@ func (x decDriverNoopContainerReader) CheckBreak() (v bool)    { return }
 // DecodeOptions captures configuration options during decode.
 // DecodeOptions captures configuration options during decode.
 type DecodeOptions struct {
 type DecodeOptions struct {
 	// MapType specifies type to use during schema-less decoding of a map in the stream.
 	// MapType specifies type to use during schema-less decoding of a map in the stream.
-	// If nil, we use map[interface{}]interface{}
+	// If nil (unset), we default to map[string]interface{} for json and
+	// map[interface{}]interface{} for all other formats.
 	MapType reflect.Type
 	MapType reflect.Type
 
 
 	// SliceType specifies type to use during schema-less decoding of an array in the stream.
 	// SliceType specifies type to use during schema-less decoding of an array in the stream.
-	// If nil, we use []interface{}
+	// If nil (unset), we default to []interface{} for all formats.
 	SliceType reflect.Type
 	SliceType reflect.Type
 
 
 	// MaxInitLen defines the maxinum initial length that we "make" a collection (string, slice, map, chan).
 	// MaxInitLen defines the maxinum initial length that we "make" a collection (string, slice, map, chan).
@@ -950,7 +951,16 @@ func (d *Decoder) kInterfaceNaked(f *codecFnInfo) (rvn reflect.Value) {
 	// var useRvn bool
 	// var useRvn bool
 	switch n.v {
 	switch n.v {
 	case valueTypeMap:
 	case valueTypeMap:
-		if d.mtid == 0 || d.mtid == mapIntfIntfTypId {
+		// if json, default to a map type with string keys
+		mtid := d.mtid
+		if mtid == 0 {
+			if d.js {
+				mtid = mapStrIntfTypId
+			} else {
+				mtid = mapIntfIntfTypId
+			}
+		}
+		if mtid == mapIntfIntfTypId {
 			if n.lm < arrayCacheLen {
 			if n.lm < arrayCacheLen {
 				n.ma[n.lm] = nil
 				n.ma[n.lm] = nil
 				rvn = n.rr[decNakedMapIntfIntfIdx*arrayCacheLen+n.lm]
 				rvn = n.rr[decNakedMapIntfIntfIdx*arrayCacheLen+n.lm]
@@ -962,7 +972,7 @@ func (d *Decoder) kInterfaceNaked(f *codecFnInfo) (rvn reflect.Value) {
 				d.decode(&v2)
 				d.decode(&v2)
 				rvn = reflect.ValueOf(&v2).Elem()
 				rvn = reflect.ValueOf(&v2).Elem()
 			}
 			}
-		} else if d.mtid == mapStrIntfTypId { // for json performance
+		} else if mtid == mapStrIntfTypId { // for json performance
 			if n.ln < arrayCacheLen {
 			if n.ln < arrayCacheLen {
 				n.na[n.ln] = nil
 				n.na[n.ln] = nil
 				rvn = n.rr[decNakedMapStrIntfIdx*arrayCacheLen+n.ln]
 				rvn = n.rr[decNakedMapStrIntfIdx*arrayCacheLen+n.ln]