// Feed in an empty string - the shortest, simplest value -
// so that it knows we got to the end of the value.
if d.scan.redo {
- panic("redo")
+ // rewind.
+ d.scan.redo = false
+ d.scan.step = stateBeginValue
}
d.scan.step(&d.scan, '"')
d.scan.step(&d.scan, '"')
}
v = pv
- // Decoding into nil interface? Switch to non-reflect code.
- iv := v
- ok := iv.Kind() == reflect.Interface
- if ok {
- iv.Set(reflect.ValueOf(d.arrayInterface()))
- return
- }
-
// Check type of target.
- av := v
- if av.Kind() != reflect.Array && av.Kind() != reflect.Slice {
+ switch v.Kind() {
+ default:
d.saveError(&UnmarshalTypeError{"array", v.Type()})
d.off--
d.next()
return
+ case reflect.Interface:
+ // Decoding into nil interface? Switch to non-reflect code.
+ v.Set(reflect.ValueOf(d.arrayInterface()))
+ return
+ case reflect.Array:
+ case reflect.Slice:
+ break
}
- sv := v
-
i := 0
for {
// Look ahead for ] - can only happen on first iteration.
d.scan.undo(op)
// Get element of array, growing if necessary.
- if i >= av.Cap() && sv.IsValid() {
- newcap := sv.Cap() + sv.Cap()/2
- if newcap < 4 {
- newcap = 4
+ if v.Kind() == reflect.Slice {
+ // Grow slice if necessary
+ if i >= v.Cap() {
+ newcap := v.Cap() + v.Cap()/2
+ if newcap < 4 {
+ newcap = 4
+ }
+ newv := reflect.MakeSlice(v.Type(), v.Len(), newcap)
+ reflect.Copy(newv, v)
+ v.Set(newv)
+ }
+ if i >= v.Len() {
+ v.SetLen(i + 1)
}
- newv := reflect.MakeSlice(sv.Type(), sv.Len(), newcap)
- reflect.Copy(newv, sv)
- sv.Set(newv)
- }
- if i >= av.Len() && sv.IsValid() {
- // Must be slice; gave up on array during i >= av.Cap().
- sv.SetLen(i + 1)
}
- // Decode into element.
- if i < av.Len() {
- d.value(av.Index(i))
+ if i < v.Len() {
+ // Decode into element.
+ d.value(v.Index(i))
} else {
// Ran out of fixed array: skip.
d.value(reflect.Value{})
}
}
- if i < av.Len() {
- if !sv.IsValid() {
+ if i < v.Len() {
+ if v.Kind() == reflect.Array {
// Array. Zero the rest.
- z := reflect.Zero(av.Type().Elem())
- for ; i < av.Len(); i++ {
- av.Index(i).Set(z)
+ z := reflect.Zero(v.Type().Elem())
+ for ; i < v.Len(); i++ {
+ v.Index(i).Set(z)
}
} else {
- sv.SetLen(i)
+ v.SetLen(i)
}
}
- if i == 0 && av.Kind() == reflect.Slice && sv.IsNil() {
- sv.Set(reflect.MakeSlice(sv.Type(), 0, 0))
+ if i == 0 && v.Kind() == reflect.Slice {
+ v.Set(reflect.MakeSlice(v.Type(), 0, 0))
}
}
// syntax errors
{`{"X": "foo", "Y"}`, nil, nil, &SyntaxError{"invalid character '}' after object key", 17}},
+ {`[1, 2, 3+]`, nil, nil, &SyntaxError{"invalid character '+' after array element", 9}},
+
+ // array tests
+ {`[1, 2, 3]`, new([3]int), [3]int{1, 2, 3}, nil},
+ {`[1, 2, 3]`, new([1]int), [1]int{1}, nil},
+ {`[1, 2, 3]`, new([5]int), [5]int{1, 2, 3, 0, 0}, nil},
// composite tests
{allValueIndent, new(All), allValue, nil},