diff options
Diffstat (limited to 'src/pkg/json/decode.go')
| -rw-r--r-- | src/pkg/json/decode.go | 41 | 
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  	} | 
