From d04a510fa310c6d5fa8b6a3dec07e88f0b998dd6 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Fri, 13 Nov 2009 13:00:45 -0800 Subject: json: allow one to unmarshal a top-level JSON array. Fixies issue 114. R=rsc CC=golang-dev http://codereview.appspot.com/154121 --- src/pkg/json/struct.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src/pkg/json/struct.go') 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 -- cgit v1.2.3