diff options
| author | Adam Langley <agl@golang.org> | 2009-11-13 13:00:45 -0800 | 
|---|---|---|
| committer | Adam Langley <agl@golang.org> | 2009-11-13 13:00:45 -0800 | 
| commit | d04a510fa310c6d5fa8b6a3dec07e88f0b998dd6 (patch) | |
| tree | 98bf497be1f78e90b0e0547d7e1f5f994d8546ec /src/pkg/json/struct.go | |
| parent | 23abe19ca16ba0939ec537d950f2315a6122ad43 (diff) | |
| download | golang-d04a510fa310c6d5fa8b6a3dec07e88f0b998dd6.tar.gz | |
json: allow one to unmarshal a top-level JSON array.
Fixies issue 114.
R=rsc
CC=golang-dev
http://codereview.appspot.com/154121
Diffstat (limited to 'src/pkg/json/struct.go')
| -rw-r--r-- | src/pkg/json/struct.go | 20 | 
1 files changed, 18 insertions, 2 deletions
| diff --git a/src/pkg/json/struct.go b/src/pkg/json/struct.go index d94988b64..ab07d9339 100644 --- a/src/pkg/json/struct.go +++ b/src/pkg/json/struct.go @@ -224,7 +224,7 @@ func (b *structBuilder) Key(k string) Builder {  }  // Unmarshal parses the JSON syntax string s and fills in -// an arbitrary struct or array pointed at by val. +// an arbitrary struct or slice pointed at by val.  // It uses the reflect package to assign to fields  // and arrays embedded in val.  Well-formed data that does not fit  // into the struct is discarded. @@ -279,11 +279,27 @@ func (b *structBuilder) Key(k string) Builder {  // assign to upper case fields.  Unmarshal uses a case-insensitive  // comparison to match JSON field names to struct field names.  // +// To unmarshal a top-level JSON array, pass in a pointer to an empty +// slice of the correct type. +//  // On success, Unmarshal returns with ok set to true.  // On a syntax error, it returns with ok set to false and errtok  // set to the offending token.  func Unmarshal(s string, val interface{}) (ok bool, errtok string) { -	b := &structBuilder{val: reflect.NewValue(val)}; +	v := reflect.NewValue(val); +	var b *structBuilder; + +	// If val is a pointer to a slice, we mutate the pointee. +	if ptr, ok := v.(*reflect.PtrValue); ok { +		if slice, ok := ptr.Elem().(*reflect.SliceValue); ok { +			b = &structBuilder{val: slice} +		} +	} + +	if b == nil { +		b = &structBuilder{val: v} +	} +  	ok, _, errtok = Parse(s, b);  	if !ok {  		return false, errtok | 
