mirror of https://github.com/goccy/go-json.git
when cap is enough, reuse slice data for compatibility with encoding/json
This commit is contained in:
parent
4d51b8b764
commit
2ad2f11326
|
@ -96,10 +96,11 @@ func (d *sliceDecoder) decodeStream(s *stream, depth int64, p unsafe.Pointer) er
|
||||||
s.cursor++
|
s.cursor++
|
||||||
s.skipWhiteSpace()
|
s.skipWhiteSpace()
|
||||||
if s.char() == ']' {
|
if s.char() == ']' {
|
||||||
*(*sliceHeader)(p) = sliceHeader{
|
dst := (*sliceHeader)(p)
|
||||||
data: newArray(d.elemType, 0),
|
if dst.data == nil {
|
||||||
len: 0,
|
dst.data = newArray(d.elemType, 0)
|
||||||
cap: 0,
|
} else {
|
||||||
|
dst.len = 0
|
||||||
}
|
}
|
||||||
s.cursor++
|
s.cursor++
|
||||||
return nil
|
return nil
|
||||||
|
@ -130,11 +131,12 @@ func (d *sliceDecoder) decodeStream(s *stream, depth int64, p unsafe.Pointer) er
|
||||||
slice.cap = capacity
|
slice.cap = capacity
|
||||||
slice.len = idx + 1
|
slice.len = idx + 1
|
||||||
slice.data = data
|
slice.data = data
|
||||||
|
dst := *(*sliceHeader)(p)
|
||||||
|
dst.len = idx + 1
|
||||||
dstCap := idx + 1
|
dstCap := idx + 1
|
||||||
dst := sliceHeader{
|
if dstCap > dst.cap {
|
||||||
data: newArray(d.elemType, dstCap),
|
dst.data = newArray(d.elemType, dstCap)
|
||||||
len: idx + 1,
|
dst.cap = dstCap
|
||||||
cap: dstCap,
|
|
||||||
}
|
}
|
||||||
copySlice(d.elemType, dst, sliceHeader{
|
copySlice(d.elemType, dst, sliceHeader{
|
||||||
data: slice.data,
|
data: slice.data,
|
||||||
|
@ -210,10 +212,11 @@ func (d *sliceDecoder) decode(buf []byte, cursor, depth int64, p unsafe.Pointer)
|
||||||
cursor++
|
cursor++
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
cursor = skipWhiteSpace(buf, cursor)
|
||||||
if buf[cursor] == ']' {
|
if buf[cursor] == ']' {
|
||||||
**(**sliceHeader)(unsafe.Pointer(&p)) = sliceHeader{
|
dst := (*sliceHeader)(p)
|
||||||
data: newArray(d.elemType, 0),
|
if dst.data == nil {
|
||||||
len: 0,
|
dst.data = newArray(d.elemType, 0)
|
||||||
cap: 0,
|
} else {
|
||||||
|
dst.len = 0
|
||||||
}
|
}
|
||||||
cursor++
|
cursor++
|
||||||
return cursor, nil
|
return cursor, nil
|
||||||
|
@ -245,11 +248,12 @@ func (d *sliceDecoder) decode(buf []byte, cursor, depth int64, p unsafe.Pointer)
|
||||||
slice.cap = capacity
|
slice.cap = capacity
|
||||||
slice.len = idx + 1
|
slice.len = idx + 1
|
||||||
slice.data = data
|
slice.data = data
|
||||||
|
dst := *(*sliceHeader)(p)
|
||||||
|
dst.len = idx + 1
|
||||||
dstCap := idx + 1
|
dstCap := idx + 1
|
||||||
dst := sliceHeader{
|
if dstCap > dst.cap {
|
||||||
data: newArray(d.elemType, dstCap),
|
dst.data = newArray(d.elemType, dstCap)
|
||||||
len: idx + 1,
|
dst.cap = dstCap
|
||||||
cap: dstCap,
|
|
||||||
}
|
}
|
||||||
copySlice(d.elemType, dst, sliceHeader{
|
copySlice(d.elemType, dst, sliceHeader{
|
||||||
data: slice.data,
|
data: slice.data,
|
||||||
|
|
|
@ -103,6 +103,12 @@ func Test_Decoder(t *testing.T) {
|
||||||
assertErr(t, json.Unmarshal([]byte(` [ 1 , 2 , 3 , 4 ] `), &v))
|
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, "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) {
|
t.Run("array", func(t *testing.T) {
|
||||||
var v [4]int
|
var v [4]int
|
||||||
assertErr(t, json.Unmarshal([]byte(` [ 1 , 2 , 3 , 4 ] `), &v))
|
assertErr(t, json.Unmarshal([]byte(` [ 1 , 2 , 3 , 4 ] `), &v))
|
||||||
|
|
Loading…
Reference in New Issue