summaryrefslogtreecommitdiff
path: root/src/pkg/json/decode.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/json/decode.go')
-rw-r--r--src/pkg/json/decode.go41
1 files changed, 24 insertions, 17 deletions
diff --git a/src/pkg/json/decode.go b/src/pkg/json/decode.go
index a5fd33912..e78b60ccb 100644
--- a/src/pkg/json/decode.go
+++ b/src/pkg/json/decode.go
@@ -122,11 +122,10 @@ func (d *decodeState) unmarshal(v interface{}) (err os.Error) {
}
}()
- rv := reflect.NewValue(v)
+ rv := reflect.ValueOf(v)
pv := rv
- if pv.Kind() != reflect.Ptr ||
- pv.IsNil() {
- return &InvalidUnmarshalError{reflect.Typeof(v)}
+ if pv.Kind() != reflect.Ptr || pv.IsNil() {
+ return &InvalidUnmarshalError{reflect.TypeOf(v)}
}
d.scan.reset()
@@ -267,17 +266,17 @@ func (d *decodeState) indirect(v reflect.Value, wantptr bool) (Unmarshaler, refl
v = iv.Elem()
continue
}
+
pv := v
if pv.Kind() != reflect.Ptr {
break
}
- if pv.Elem().Kind() != reflect.Ptr &&
- wantptr && !isUnmarshaler {
+ if pv.Elem().Kind() != reflect.Ptr && wantptr && pv.CanSet() && !isUnmarshaler {
return nil, pv
}
if pv.IsNil() {
- pv.Set(reflect.Zero(pv.Type().Elem()).Addr())
+ pv.Set(reflect.New(pv.Type().Elem()))
}
if isUnmarshaler {
// Using v.Interface().(Unmarshaler)
@@ -314,7 +313,7 @@ func (d *decodeState) array(v reflect.Value) {
iv := v
ok := iv.Kind() == reflect.Interface
if ok {
- iv.Set(reflect.NewValue(d.arrayInterface()))
+ iv.Set(reflect.ValueOf(d.arrayInterface()))
return
}
@@ -410,7 +409,7 @@ func (d *decodeState) object(v reflect.Value) {
// Decoding into nil interface? Switch to non-reflect code.
iv := v
if iv.Kind() == reflect.Interface {
- iv.Set(reflect.NewValue(d.objectInterface()))
+ iv.Set(reflect.ValueOf(d.objectInterface()))
return
}
@@ -423,7 +422,7 @@ func (d *decodeState) object(v reflect.Value) {
case reflect.Map:
// map must have string type
t := v.Type()
- if t.Key() != reflect.Typeof("") {
+ if t.Key() != reflect.TypeOf("") {
d.saveError(&UnmarshalTypeError{"object", v.Type()})
break
}
@@ -443,6 +442,8 @@ func (d *decodeState) object(v reflect.Value) {
return
}
+ var mapElem reflect.Value
+
for {
// Read opening " of string key or closing }.
op := d.scanWhile(scanSkipSpace)
@@ -466,7 +467,13 @@ func (d *decodeState) object(v reflect.Value) {
// Figure out field corresponding to key.
var subv reflect.Value
if mv.IsValid() {
- subv = reflect.Zero(mv.Type().Elem())
+ elemType := mv.Type().Elem()
+ if !mapElem.IsValid() {
+ mapElem = reflect.New(elemType).Elem()
+ } else {
+ mapElem.Set(reflect.Zero(elemType))
+ }
+ subv = mapElem
} else {
var f reflect.StructField
var ok bool
@@ -514,7 +521,7 @@ func (d *decodeState) object(v reflect.Value) {
// Write value back to map;
// if using struct, subv points into struct already.
if mv.IsValid() {
- mv.SetMapIndex(reflect.NewValue(key), subv)
+ mv.SetMapIndex(reflect.ValueOf(key), subv)
}
// Next token must be , or }.
@@ -570,7 +577,7 @@ func (d *decodeState) literal(v reflect.Value) {
case reflect.Bool:
v.SetBool(value)
case reflect.Interface:
- v.Set(reflect.NewValue(value))
+ v.Set(reflect.ValueOf(value))
}
case '"': // string
@@ -592,11 +599,11 @@ func (d *decodeState) literal(v reflect.Value) {
d.saveError(err)
break
}
- v.Set(reflect.NewValue(b[0:n]))
+ v.Set(reflect.ValueOf(b[0:n]))
case reflect.String:
v.SetString(string(s))
case reflect.Interface:
- v.Set(reflect.NewValue(string(s)))
+ v.Set(reflect.ValueOf(string(s)))
}
default: // number
@@ -613,7 +620,7 @@ func (d *decodeState) literal(v reflect.Value) {
d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
break
}
- v.Set(reflect.NewValue(n))
+ v.Set(reflect.ValueOf(n))
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
n, err := strconv.Atoi64(s)
@@ -767,7 +774,7 @@ func (d *decodeState) literalInterface() interface{} {
}
n, err := strconv.Atof64(string(item))
if err != nil {
- d.saveError(&UnmarshalTypeError{"number " + string(item), reflect.Typeof(0.0)})
+ d.saveError(&UnmarshalTypeError{"number " + string(item), reflect.TypeOf(0.0)})
}
return n
}