|
|
@@ -1732,7 +1732,9 @@ type rtid2rv struct {
|
|
|
type decReaderSwitch struct {
|
|
|
rb bytesDecReader
|
|
|
// ---- cpu cache line boundary?
|
|
|
- ri *ioDecReader
|
|
|
+ ri *ioDecReader
|
|
|
+ bi *bufioDecReader
|
|
|
+
|
|
|
mtr, str bool // whether maptype or slicetype are known types
|
|
|
|
|
|
be bool // is binary encoding
|
|
|
@@ -1740,73 +1742,92 @@ type decReaderSwitch struct {
|
|
|
js bool // is json handle
|
|
|
jsms bool // is json handle, and MapKeyAsString
|
|
|
esep bool // has elem separators
|
|
|
+ bufio bool // is this a bufioDecReader?
|
|
|
}
|
|
|
|
|
|
-// TODO: Uncomment after mid-stack inlining enabled in go 1.11
|
|
|
-//
|
|
|
-// func (z *decReaderSwitch) unreadn1() {
|
|
|
-// if z.bytes {
|
|
|
-// z.rb.unreadn1()
|
|
|
-// } else {
|
|
|
-// z.ri.unreadn1()
|
|
|
-// }
|
|
|
-// }
|
|
|
-// func (z *decReaderSwitch) readx(n int) []byte {
|
|
|
-// if z.bytes {
|
|
|
-// return z.rb.readx(n)
|
|
|
-// }
|
|
|
-// return z.ri.readx(n)
|
|
|
-// }
|
|
|
-// func (z *decReaderSwitch) readb(s []byte) {
|
|
|
-// if z.bytes {
|
|
|
-// z.rb.readb(s)
|
|
|
-// } else {
|
|
|
-// z.ri.readb(s)
|
|
|
-// }
|
|
|
-// }
|
|
|
-// func (z *decReaderSwitch) readn1() uint8 {
|
|
|
-// if z.bytes {
|
|
|
-// return z.rb.readn1()
|
|
|
-// }
|
|
|
-// return z.ri.readn1()
|
|
|
-// }
|
|
|
-// func (z *decReaderSwitch) numread() int {
|
|
|
-// if z.bytes {
|
|
|
-// return z.rb.numread()
|
|
|
-// }
|
|
|
-// return z.ri.numread()
|
|
|
-// }
|
|
|
-// func (z *decReaderSwitch) track() {
|
|
|
-// if z.bytes {
|
|
|
-// z.rb.track()
|
|
|
-// } else {
|
|
|
-// z.ri.track()
|
|
|
-// }
|
|
|
-// }
|
|
|
-// func (z *decReaderSwitch) stopTrack() []byte {
|
|
|
-// if z.bytes {
|
|
|
-// return z.rb.stopTrack()
|
|
|
-// }
|
|
|
-// return z.ri.stopTrack()
|
|
|
-// }
|
|
|
-// func (z *decReaderSwitch) skip(accept *bitset256) (token byte) {
|
|
|
-// if z.bytes {
|
|
|
-// return z.rb.skip(accept)
|
|
|
-// }
|
|
|
-// return z.ri.skip(accept)
|
|
|
-// }
|
|
|
-// func (z *decReaderSwitch) readTo(in []byte, accept *bitset256) (out []byte) {
|
|
|
-// if z.bytes {
|
|
|
-// return z.rb.readTo(in, accept)
|
|
|
-// }
|
|
|
-// return z.ri.readTo(in, accept)
|
|
|
-// }
|
|
|
-// func (z *decReaderSwitch) readUntil(in []byte, stop byte) (out []byte) {
|
|
|
-// if z.bytes {
|
|
|
-// return z.rb.readUntil(in, stop)
|
|
|
-// }
|
|
|
-// return z.ri.readUntil(in, stop)
|
|
|
-// }
|
|
|
+func (z *decReaderSwitch) unreadn1() {
|
|
|
+ if z.bytes {
|
|
|
+ z.rb.unreadn1()
|
|
|
+ } else if z.bufio {
|
|
|
+ z.bi.unreadn1()
|
|
|
+ } else {
|
|
|
+ z.ri.unreadn1()
|
|
|
+ }
|
|
|
+}
|
|
|
+func (z *decReaderSwitch) readx(n int) []byte {
|
|
|
+ if z.bytes {
|
|
|
+ return z.rb.readx(n)
|
|
|
+ } else if z.bufio {
|
|
|
+ return z.bi.readx(n)
|
|
|
+ }
|
|
|
+ return z.ri.readx(n)
|
|
|
+}
|
|
|
+func (z *decReaderSwitch) readb(s []byte) {
|
|
|
+ if z.bytes {
|
|
|
+ z.rb.readb(s)
|
|
|
+ } else if z.bufio {
|
|
|
+ z.bi.readb(s)
|
|
|
+ } else {
|
|
|
+ z.ri.readb(s)
|
|
|
+ }
|
|
|
+}
|
|
|
+func (z *decReaderSwitch) readn1() uint8 {
|
|
|
+ if z.bytes {
|
|
|
+ return z.rb.readn1()
|
|
|
+ } else if z.bufio {
|
|
|
+ return z.bi.readn1()
|
|
|
+ }
|
|
|
+ return z.ri.readn1()
|
|
|
+}
|
|
|
+func (z *decReaderSwitch) numread() int {
|
|
|
+ if z.bytes {
|
|
|
+ return z.rb.numread()
|
|
|
+ } else if z.bufio {
|
|
|
+ return z.bi.numread()
|
|
|
+ }
|
|
|
+ return z.ri.numread()
|
|
|
+}
|
|
|
+func (z *decReaderSwitch) track() {
|
|
|
+ if z.bytes {
|
|
|
+ z.rb.track()
|
|
|
+ } else if z.bufio {
|
|
|
+ z.bi.track()
|
|
|
+ } else {
|
|
|
+ z.ri.track()
|
|
|
+ }
|
|
|
+}
|
|
|
+func (z *decReaderSwitch) stopTrack() []byte {
|
|
|
+ if z.bytes {
|
|
|
+ return z.rb.stopTrack()
|
|
|
+ } else if z.bufio {
|
|
|
+ return z.bi.stopTrack()
|
|
|
+ }
|
|
|
+ return z.ri.stopTrack()
|
|
|
+}
|
|
|
+func (z *decReaderSwitch) skip(accept *bitset256) (token byte) {
|
|
|
+ if z.bytes {
|
|
|
+ return z.rb.skip(accept)
|
|
|
+ } else if z.bufio {
|
|
|
+ return z.bi.skip(accept)
|
|
|
+ }
|
|
|
+ return z.ri.skip(accept)
|
|
|
+}
|
|
|
+func (z *decReaderSwitch) readTo(in []byte, accept *bitset256) (out []byte) {
|
|
|
+ if z.bytes {
|
|
|
+ return z.rb.readTo(in, accept)
|
|
|
+ } else if z.bufio {
|
|
|
+ return z.bi.readTo(in, accept)
|
|
|
+ }
|
|
|
+ return z.ri.readTo(in, accept)
|
|
|
+}
|
|
|
+func (z *decReaderSwitch) readUntil(in []byte, stop byte) (out []byte) {
|
|
|
+ if z.bytes {
|
|
|
+ return z.rb.readUntil(in, stop)
|
|
|
+ } else if z.bufio {
|
|
|
+ return z.bi.readUntil(in, stop)
|
|
|
+ }
|
|
|
+ return z.ri.readUntil(in, stop)
|
|
|
+}
|
|
|
|
|
|
// A Decoder reads and decodes an object from an input stream in the codec format.
|
|
|
type Decoder struct {
|
|
|
@@ -1817,23 +1838,26 @@ type Decoder struct {
|
|
|
d decDriver
|
|
|
// NOTE: Decoder shouldn't call it's read methods,
|
|
|
// as the handler MAY need to do some coordination.
|
|
|
- r decReader
|
|
|
- h *BasicHandle
|
|
|
- bi *bufioDecReader
|
|
|
+ r *decReaderSwitch // formerly decReader
|
|
|
+ h *BasicHandle
|
|
|
+ // bi *bufioDecReader
|
|
|
// cache the mapTypeId and sliceTypeId for faster comparisons
|
|
|
mtid uintptr
|
|
|
stid uintptr
|
|
|
|
|
|
+ n *decNaked
|
|
|
+ nsp *sync.Pool
|
|
|
+
|
|
|
// ---- cpu cache line boundary?
|
|
|
decReaderSwitch
|
|
|
|
|
|
// ---- cpu cache line boundary?
|
|
|
codecFnPooler
|
|
|
// cr containerStateRecv
|
|
|
- n *decNaked
|
|
|
- nsp *sync.Pool
|
|
|
err error
|
|
|
|
|
|
+ _ [1]uint64 // padding
|
|
|
+
|
|
|
// ---- cpu cache line boundary?
|
|
|
b [decScratchByteArrayLen]byte // scratch buffer, used by Decoder and xxxEncDrivers
|
|
|
is map[string]string // used for interning strings
|
|
|
@@ -1882,6 +1906,7 @@ func newDecoder(h Handle) *Decoder {
|
|
|
}
|
|
|
|
|
|
func (d *Decoder) resetCommon() {
|
|
|
+ d.r = &d.decReaderSwitch
|
|
|
d.n.reset()
|
|
|
d.d.reset()
|
|
|
d.err = nil
|
|
|
@@ -1904,14 +1929,18 @@ func (d *Decoder) Reset(r io.Reader) {
|
|
|
if r == nil {
|
|
|
return
|
|
|
}
|
|
|
- if d.bi == nil {
|
|
|
- d.bi = new(bufioDecReader)
|
|
|
- }
|
|
|
d.bytes = false
|
|
|
if d.h.ReaderBufferSize > 0 {
|
|
|
- d.bi.buf = make([]byte, 0, d.h.ReaderBufferSize)
|
|
|
+ if d.bi == nil {
|
|
|
+ d.bi = new(bufioDecReader)
|
|
|
+ }
|
|
|
+ if cap(d.bi.buf) < d.h.ReaderBufferSize {
|
|
|
+ d.bi.buf = make([]byte, 0, d.h.ReaderBufferSize)
|
|
|
+ } else {
|
|
|
+ d.bi.buf = d.bi.buf[:0]
|
|
|
+ }
|
|
|
d.bi.reset(r)
|
|
|
- d.r = d.bi
|
|
|
+ d.bufio = true
|
|
|
} else {
|
|
|
// d.ri.x = &d.b
|
|
|
// d.s = d.sa[:0]
|
|
|
@@ -1919,7 +1948,8 @@ func (d *Decoder) Reset(r io.Reader) {
|
|
|
d.ri = new(ioDecReader)
|
|
|
}
|
|
|
d.ri.reset(r)
|
|
|
- d.r = d.ri
|
|
|
+ // d.r = d.ri
|
|
|
+ d.bufio = false
|
|
|
}
|
|
|
d.resetCommon()
|
|
|
}
|
|
|
@@ -1932,7 +1962,7 @@ func (d *Decoder) ResetBytes(in []byte) {
|
|
|
}
|
|
|
d.bytes = true
|
|
|
d.rb.reset(in)
|
|
|
- d.r = &d.rb
|
|
|
+ // d.r = &d.rb
|
|
|
d.resetCommon()
|
|
|
}
|
|
|
|
|
|
@@ -2382,6 +2412,7 @@ func (d *Decoder) wrapErrstr(v interface{}, err *error) {
|
|
|
*err = fmt.Errorf("%s decode error [pos %d]: %v", d.hh.Name(), d.r.numread(), v)
|
|
|
}
|
|
|
|
|
|
+// NumBytesRead returns the number of bytes read
|
|
|
func (d *Decoder) NumBytesRead() int {
|
|
|
return d.r.numread()
|
|
|
}
|
|
|
@@ -2431,7 +2462,7 @@ func (x decSliceHelper) ElemContainerState(index int) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func decByteSlice(r decReader, clen, maxInitLen int, bs []byte) (bsOut []byte) {
|
|
|
+func decByteSlice(r *decReaderSwitch, clen, maxInitLen int, bs []byte) (bsOut []byte) {
|
|
|
if clen == 0 {
|
|
|
return zeroByteSlice
|
|
|
}
|