forked from mirror/go-json
Merge branch 'master' of github.com:goccy/go-json into feature/support-stream-decoding
This commit is contained in:
commit
daec57244d
|
@ -70,7 +70,7 @@ WIP
|
||||||
- [ ] `InvalidUTF8Error`
|
- [ ] `InvalidUTF8Error`
|
||||||
- [x] `InvalidUnmarshalError`
|
- [x] `InvalidUnmarshalError`
|
||||||
- [x] `MarshalerError`
|
- [x] `MarshalerError`
|
||||||
- [ ] `SyntaxError`
|
- [x] `SyntaxError`
|
||||||
- [ ] `UnmarshalFieldError`
|
- [ ] `UnmarshalFieldError`
|
||||||
- [ ] `UnmarshalTypeError`
|
- [ ] `UnmarshalTypeError`
|
||||||
- [x] `UnsupportedTypeError`
|
- [x] `UnsupportedTypeError`
|
||||||
|
|
|
@ -6,7 +6,6 @@ require (
|
||||||
github.com/francoispqt/gojay v1.2.13
|
github.com/francoispqt/gojay v1.2.13
|
||||||
github.com/goccy/go-json v0.0.0-00010101000000-000000000000
|
github.com/goccy/go-json v0.0.0-00010101000000-000000000000
|
||||||
github.com/json-iterator/go v1.1.9
|
github.com/json-iterator/go v1.1.9
|
||||||
github.com/mailru/easyjson v0.7.1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/goccy/go-json => ../
|
replace github.com/goccy/go-json => ../
|
||||||
|
|
|
@ -56,8 +56,6 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8=
|
|
||||||
github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
@ -149,8 +147,6 @@ golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGm
|
||||||
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
|
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
|
||||||
|
|
|
@ -13,6 +13,15 @@ type sliceDecoder struct {
|
||||||
arrayPool sync.Pool
|
arrayPool sync.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If use reflect.SliceHeader, data type is uintptr.
|
||||||
|
// In this case, Go compiler cannot trace reference created by newArray().
|
||||||
|
// So, define using unsafe.Pointer as data type
|
||||||
|
type sliceHeader struct {
|
||||||
|
data unsafe.Pointer
|
||||||
|
len int
|
||||||
|
cap int
|
||||||
|
}
|
||||||
|
|
||||||
func newSliceDecoder(dec decoder, elemType *rtype, size uintptr) *sliceDecoder {
|
func newSliceDecoder(dec decoder, elemType *rtype, size uintptr) *sliceDecoder {
|
||||||
return &sliceDecoder{
|
return &sliceDecoder{
|
||||||
valueDecoder: dec,
|
valueDecoder: dec,
|
||||||
|
@ -21,23 +30,23 @@ func newSliceDecoder(dec decoder, elemType *rtype, size uintptr) *sliceDecoder {
|
||||||
arrayPool: sync.Pool{
|
arrayPool: sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() interface{} {
|
||||||
cap := 2
|
cap := 2
|
||||||
return &reflect.SliceHeader{
|
return &sliceHeader{
|
||||||
Data: uintptr(newArray(elemType, cap)),
|
data: newArray(elemType, cap),
|
||||||
Len: 0,
|
len: 0,
|
||||||
Cap: cap,
|
cap: cap,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *sliceDecoder) newSlice() *reflect.SliceHeader {
|
func (d *sliceDecoder) newSlice() *sliceHeader {
|
||||||
slice := d.arrayPool.Get().(*reflect.SliceHeader)
|
slice := d.arrayPool.Get().(*sliceHeader)
|
||||||
slice.Len = 0
|
slice.len = 0
|
||||||
return slice
|
return slice
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *sliceDecoder) releaseSlice(p *reflect.SliceHeader) {
|
func (d *sliceDecoder) releaseSlice(p *sliceHeader) {
|
||||||
d.arrayPool.Put(p)
|
d.arrayPool.Put(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,18 +135,18 @@ func (d *sliceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error
|
||||||
case '[':
|
case '[':
|
||||||
idx := 0
|
idx := 0
|
||||||
slice := d.newSlice()
|
slice := d.newSlice()
|
||||||
cap := slice.Cap
|
cap := slice.cap
|
||||||
data := slice.Data
|
data := slice.data
|
||||||
for {
|
for {
|
||||||
cursor++
|
cursor++
|
||||||
if cap <= idx {
|
if cap <= idx {
|
||||||
src := reflect.SliceHeader{Data: data, Len: idx, Cap: cap}
|
src := reflect.SliceHeader{Data: uintptr(data), Len: idx, Cap: cap}
|
||||||
cap *= 2
|
cap *= 2
|
||||||
data = uintptr(newArray(d.elemType, cap))
|
data = newArray(d.elemType, cap)
|
||||||
dst := reflect.SliceHeader{Data: data, Len: idx, Cap: cap}
|
dst := reflect.SliceHeader{Data: uintptr(data), Len: idx, Cap: cap}
|
||||||
copySlice(d.elemType, dst, src)
|
copySlice(d.elemType, dst, src)
|
||||||
}
|
}
|
||||||
c, err := d.valueDecoder.decode(buf, cursor, data+uintptr(idx)*d.size)
|
c, err := d.valueDecoder.decode(buf, cursor, uintptr(data)+uintptr(idx)*d.size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -145,16 +154,20 @@ func (d *sliceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error
|
||||||
cursor = skipWhiteSpace(buf, cursor)
|
cursor = skipWhiteSpace(buf, cursor)
|
||||||
switch buf[cursor] {
|
switch buf[cursor] {
|
||||||
case ']':
|
case ']':
|
||||||
slice.Cap = cap
|
slice.cap = cap
|
||||||
slice.Len = idx + 1
|
slice.len = idx + 1
|
||||||
slice.Data = data
|
slice.data = data
|
||||||
dstCap := idx + 1
|
dstCap := idx + 1
|
||||||
dst := reflect.SliceHeader{
|
dst := reflect.SliceHeader{
|
||||||
Data: uintptr(newArray(d.elemType, dstCap)),
|
Data: uintptr(newArray(d.elemType, dstCap)),
|
||||||
Len: idx + 1,
|
Len: idx + 1,
|
||||||
Cap: dstCap,
|
Cap: dstCap,
|
||||||
}
|
}
|
||||||
copySlice(d.elemType, dst, *slice)
|
copySlice(d.elemType, dst, reflect.SliceHeader{
|
||||||
|
Data: uintptr(slice.data),
|
||||||
|
Len: slice.len,
|
||||||
|
Cap: slice.cap,
|
||||||
|
})
|
||||||
*(*reflect.SliceHeader)(unsafe.Pointer(p)) = dst
|
*(*reflect.SliceHeader)(unsafe.Pointer(p)) = dst
|
||||||
d.releaseSlice(slice)
|
d.releaseSlice(slice)
|
||||||
cursor++
|
cursor++
|
||||||
|
@ -163,8 +176,8 @@ func (d *sliceDecoder) decode(buf []byte, cursor int64, p uintptr) (int64, error
|
||||||
idx++
|
idx++
|
||||||
continue
|
continue
|
||||||
default:
|
default:
|
||||||
slice.Cap = cap
|
slice.cap = cap
|
||||||
slice.Data = data
|
slice.data = data
|
||||||
d.releaseSlice(slice)
|
d.releaseSlice(slice)
|
||||||
return 0, errInvalidCharacter(buf[cursor], "slice", cursor)
|
return 0, errInvalidCharacter(buf[cursor], "slice", cursor)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue