forked from mirror/go-json
Merge pull request #200 from IncSW/slice-decoding-compatibility
when cap is enough, reuse slice data for compatibility with encoding/json
This commit is contained in:
commit
51905367ec
|
@ -101,10 +101,11 @@ func (d *sliceDecoder) decodeStream(s *stream, depth int64, p unsafe.Pointer) er
|
|||
s.cursor++
|
||||
s.skipWhiteSpace()
|
||||
if s.char() == ']' {
|
||||
*(*sliceHeader)(p) = sliceHeader{
|
||||
data: newArray(d.elemType, 0),
|
||||
len: 0,
|
||||
cap: 0,
|
||||
dst := (*sliceHeader)(p)
|
||||
if dst.data == nil {
|
||||
dst.data = newArray(d.elemType, 0)
|
||||
} else {
|
||||
dst.len = 0
|
||||
}
|
||||
s.cursor++
|
||||
return nil
|
||||
|
@ -138,18 +139,13 @@ func (d *sliceDecoder) decodeStream(s *stream, depth int64, p unsafe.Pointer) er
|
|||
slice.cap = capacity
|
||||
slice.len = idx + 1
|
||||
slice.data = data
|
||||
dstCap := idx + 1
|
||||
dst := sliceHeader{
|
||||
data: newArray(d.elemType, dstCap),
|
||||
len: idx + 1,
|
||||
cap: dstCap,
|
||||
dst := (*sliceHeader)(p)
|
||||
dst.len = idx + 1
|
||||
if dst.len > dst.cap {
|
||||
dst.data = newArray(d.elemType, dst.len)
|
||||
dst.cap = dst.len
|
||||
}
|
||||
copySlice(d.elemType, dst, sliceHeader{
|
||||
data: slice.data,
|
||||
len: slice.len,
|
||||
cap: slice.cap,
|
||||
})
|
||||
*(*sliceHeader)(p) = dst
|
||||
copySlice(d.elemType, *dst, *slice)
|
||||
d.releaseSlice(slice)
|
||||
s.cursor++
|
||||
return nil
|
||||
|
@ -218,10 +214,11 @@ func (d *sliceDecoder) decode(buf []byte, cursor, depth int64, p unsafe.Pointer)
|
|||
cursor++
|
||||
cursor = skipWhiteSpace(buf, cursor)
|
||||
if buf[cursor] == ']' {
|
||||
**(**sliceHeader)(unsafe.Pointer(&p)) = sliceHeader{
|
||||
data: newArray(d.elemType, 0),
|
||||
len: 0,
|
||||
cap: 0,
|
||||
dst := (*sliceHeader)(p)
|
||||
if dst.data == nil {
|
||||
dst.data = newArray(d.elemType, 0)
|
||||
} else {
|
||||
dst.len = 0
|
||||
}
|
||||
cursor++
|
||||
return cursor, nil
|
||||
|
@ -256,18 +253,13 @@ func (d *sliceDecoder) decode(buf []byte, cursor, depth int64, p unsafe.Pointer)
|
|||
slice.cap = capacity
|
||||
slice.len = idx + 1
|
||||
slice.data = data
|
||||
dstCap := idx + 1
|
||||
dst := sliceHeader{
|
||||
data: newArray(d.elemType, dstCap),
|
||||
len: idx + 1,
|
||||
cap: dstCap,
|
||||
dst := (*sliceHeader)(p)
|
||||
dst.len = idx + 1
|
||||
if dst.len > dst.cap {
|
||||
dst.data = newArray(d.elemType, dst.len)
|
||||
dst.cap = dst.len
|
||||
}
|
||||
copySlice(d.elemType, dst, sliceHeader{
|
||||
data: slice.data,
|
||||
len: slice.len,
|
||||
cap: slice.cap,
|
||||
})
|
||||
**(**sliceHeader)(unsafe.Pointer(&p)) = dst
|
||||
copySlice(d.elemType, *dst, *slice)
|
||||
d.releaseSlice(slice)
|
||||
cursor++
|
||||
return cursor, nil
|
||||
|
|
|
@ -103,6 +103,12 @@ func Test_Decoder(t *testing.T) {
|
|||
assertErr(t, json.Unmarshal([]byte(` [ 1 , 2 , 3 , 4 ] `), &v))
|
||||
assertEq(t, "slice", fmt.Sprint([]int{1, 2, 3, 4}), fmt.Sprint(v))
|
||||
})
|
||||
t.Run("slice_reuse_data", func(t *testing.T) {
|
||||
v := make([]int, 0, 10)
|
||||
assertErr(t, json.Unmarshal([]byte(` [ 1 , 2 , 3 , 4 ] `), &v))
|
||||
assertEq(t, "slice", fmt.Sprint([]int{1, 2, 3, 4}), fmt.Sprint(v))
|
||||
assertEq(t, "cap", 10, cap(v))
|
||||
})
|
||||
t.Run("array", func(t *testing.T) {
|
||||
var v [4]int
|
||||
assertErr(t, json.Unmarshal([]byte(` [ 1 , 2 , 3 , 4 ] `), &v))
|
||||
|
@ -121,10 +127,10 @@ func Test_Decoder(t *testing.T) {
|
|||
{
|
||||
"a": {
|
||||
"nestedA": "value of nested a"
|
||||
},
|
||||
},
|
||||
"b": {
|
||||
"nestedB": "value of nested b"
|
||||
},
|
||||
},
|
||||
"c": {
|
||||
"nestedC": "value of nested c"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue