Browse Source

codec: bufioDecReader.ReadByte: special case for common path where there is buffered data

Ugorji Nwoke 7 years ago
parent
commit
ef9792b2e7
1 changed files with 461 additions and 446 deletions
  1. 461 446
      codec/decode.go

+ 461 - 446
codec/decode.go

@@ -259,587 +259,602 @@ type DecodeOptions struct {
 	DeleteOnNilMapValue bool
 }
 
-// ------------------------------------
+// ------------------------------------------------
 
-type bufioDecReader struct {
-	ioDecReaderCommon
+type ioDecReaderCommon struct {
+	r io.Reader // the reader passed in
 
-	c   int // cursor
-	buf []byte
-	err error
+	n int // num read
 
-	_ [3]uint64 // padding
+	l   byte // last byte
+	ls  byte // last byte status. 0: init-canDoNothing, 1: canRead, 2: canUnread
+	trb bool // tracking bytes turned on
+	_   bool
+	b   [4]byte // tiny buffer for reading single bytes
+
+	tr []byte // tracking bytes read
 }
 
-func (z *bufioDecReader) reset(r io.Reader) {
-	z.ioDecReaderCommon.reset(r)
-	z.c, z.err = 0, nil
+func (z *ioDecReaderCommon) reset(r io.Reader) {
+	z.r = r
+	z.l, z.ls, z.n, z.trb = 0, 0, 0, false
+	if z.tr != nil {
+		z.tr = z.tr[:0]
+	}
 }
 
-func (z *bufioDecReader) Read(p []byte) (n int, err error) {
-	if z.err != nil {
-		return 0, z.err
+func (z *ioDecReaderCommon) numread() int {
+	return z.n
+}
+
+func (z *ioDecReaderCommon) track() {
+	if z.tr != nil {
+		z.tr = z.tr[:0]
 	}
-	p0 := p
-	n = copy(p, z.buf[z.c:])
-	z.c += n
-	if z.c == len(z.buf) {
-		z.c = 0
+	z.trb = true
+}
+
+func (z *ioDecReaderCommon) stopTrack() (bs []byte) {
+	z.trb = false
+	return z.tr
+}
+
+// ------------------------------------------
+
+// ioDecReader is a decReader that reads off an io.Reader.
+//
+// It also has a fallback implementation of ByteScanner if needed.
+type ioDecReader struct {
+	ioDecReaderCommon
+
+	rr io.Reader
+	br io.ByteScanner
+
+	x [scratchByteArrayLen]byte // for: get struct field name, swallow valueTypeBytes, etc
+	_ [1]uint64                 // padding
+}
+
+func (z *ioDecReader) reset(r io.Reader) {
+	z.ioDecReaderCommon.reset(r)
+
+	var ok bool
+	z.rr = r
+	z.br, ok = r.(io.ByteScanner)
+	if !ok {
+		z.br = z
+		z.rr = z
 	}
-	z.n += n
-	if len(p) == n {
-		if z.c == 0 {
-			z.buf = z.buf[:1]
-			z.buf[0] = p[len(p)-1]
-			z.c = 1
-		}
-		if z.trb {
-			z.tr = append(z.tr, p0[:n]...)
-		}
+}
+
+func (z *ioDecReader) Read(p []byte) (n int, err error) {
+	if len(p) == 0 {
 		return
 	}
-	p = p[n:]
-	var n2 int
-	// if we are here, then z.buf is all read
-	if len(p) > len(z.buf) {
-		n2, err = decReadFull(z.r, p)
-		n += n2
-		z.n += n2
-		z.err = err
-		// don't return EOF if some bytes were read. keep for next time.
-		if n > 0 && err == io.EOF {
-			err = nil
-		}
-		// always keep last byte in z.buf
-		z.buf = z.buf[:1]
-		z.buf[0] = p[len(p)-1]
-		z.c = 1
-		if z.trb {
-			z.tr = append(z.tr, p0[:n]...)
+	var firstByte bool
+	if z.ls == 1 {
+		z.ls = 2
+		p[0] = z.l
+		if len(p) == 1 {
+			n = 1
+			return
 		}
-		return
+		firstByte = true
+		p = p[1:]
 	}
-	// z.c is now 0, and len(p) <= len(z.buf)
-	for len(p) > 0 && z.err == nil {
-		// println("len(p) loop starting ... ")
-		z.c = 0
-		z.buf = z.buf[0:cap(z.buf)]
-		n2, err = z.r.Read(z.buf)
-		if n2 > 0 {
-			if err == io.EOF {
-				err = nil
-			}
-			z.buf = z.buf[:n2]
-			n2 = copy(p, z.buf)
-			z.c = n2
-			n += n2
-			z.n += n2
-			p = p[n2:]
+	n, err = z.r.Read(p)
+	if n > 0 {
+		if err == io.EOF && n == len(p) {
+			err = nil // read was successful, so postpone EOF (till next time)
 		}
-		z.err = err
-		// println("... len(p) loop done")
-	}
-	if z.c == 0 {
-		z.buf = z.buf[:1]
-		z.buf[0] = p[len(p)-1]
-		z.c = 1
+		z.l = p[n-1]
+		z.ls = 2
 	}
-	if z.trb {
-		z.tr = append(z.tr, p0[:n]...)
+	if firstByte {
+		n++
 	}
 	return
 }
 
-func (z *bufioDecReader) ReadByte() (b byte, err error) {
-	// z.b[0] = 0 // unnecessary, as err is returned if problem
-	_, err = z.Read(z.b[:1])
-	b = z.b[0]
+func (z *ioDecReader) ReadByte() (c byte, err error) {
+	n, err := z.Read(z.b[:1])
+	if n == 1 {
+		c = z.b[0]
+		if err == io.EOF {
+			err = nil // read was successful, so postpone EOF (till next time)
+		}
+	}
 	return
 }
 
-func (z *bufioDecReader) UnreadByte() (err error) {
-	if z.err != nil {
-		return z.err
-	}
-	if z.c > 0 {
-		z.c--
-		z.n--
-		if z.trb {
-			z.tr = z.tr[:len(z.tr)-1]
-		}
-		return
+func (z *ioDecReader) UnreadByte() (err error) {
+	switch z.ls {
+	case 2:
+		z.ls = 1
+	case 0:
+		err = errDecUnreadByteNothingToRead
+	case 1:
+		err = errDecUnreadByteLastByteNotRead
+	default:
+		err = errDecUnreadByteUnknown
 	}
-	return errDecUnreadByteNothingToRead
+	return
 }
 
-func (z *bufioDecReader) readx(n int) (bs []byte) {
+// //go:noinline
+func (z *ioDecReader) readx(n int) (bs []byte) {
 	if n <= 0 {
 		return
 	}
-	if z.err != nil {
-		panic(z.err)
-	}
-	if z.c+n <= len(z.buf) {
-		bs = z.buf[z.c : z.c+n]
-		z.n += n
-		z.c += n
-		if z.trb {
-			z.tr = append(z.tr, bs...)
-		}
-		return
+	if n < len(z.x) {
+		bs = z.x[:n]
+	} else {
+		bs = make([]byte, n)
 	}
-	bs = make([]byte, n)
-	_, err := z.Read(bs)
-	if err != nil {
+	if _, err := decReadFull(z.rr, bs); err != nil {
 		panic(err)
 	}
+	z.n += len(bs)
+	if z.trb {
+		z.tr = append(z.tr, bs...)
+	}
 	return
 }
 
-func (z *bufioDecReader) readb(bs []byte) {
-	_, err := z.Read(bs)
-	if err != nil {
+// //go:noinline
+func (z *ioDecReader) readb(bs []byte) {
+	if len(bs) == 0 {
+		return
+	}
+	if _, err := decReadFull(z.rr, bs); err != nil {
 		panic(err)
 	}
+	z.n += len(bs)
+	if z.trb {
+		z.tr = append(z.tr, bs...)
+	}
 }
 
-func (z *bufioDecReader) readn1() (b uint8) {
-	b, err := z.ReadByte()
-	if err != nil {
+// //go:noinline
+func (z *ioDecReader) readn1eof() (b uint8, eof bool) {
+	b, err := z.br.ReadByte()
+	if err == nil {
+		z.n++
+		if z.trb {
+			z.tr = append(z.tr, b)
+		}
+	} else if err == io.EOF {
+		eof = true
+	} else {
 		panic(err)
 	}
 	return
 }
 
-// func (z *bufioDecReader) readn1eof() (b uint8, eof bool) {
-// 	b, err := z.ReadByte()
-// 	if err != nil {
-// 		if err == io.EOF {
-// 			eof = true
-// 		} else {
-// 			panic(err)
-// 		}
-// 	}
-// 	return
-// }
-
-func (z *bufioDecReader) skipLoopFn(i int) {
-	z.n += (i - z.c) - 1
-	i++
-	if z.trb {
-		z.tr = append(z.tr, z.buf[z.c:i]...)
-	}
-	z.c = i
-}
-
-func (z *bufioDecReader) skip(accept *bitset256) (token byte) {
-	// token, _ = z.search(nil, accept, 0, 1); return
-	for i := z.c; i < len(z.buf); i++ {
-		if token = z.buf[i]; !accept.isset(token) {
-			z.skipLoopFn(i)
-			return
-		}
-	}
-	z.n += len(z.buf) - z.c
-	if z.trb {
-		z.tr = append(z.tr, z.buf[z.c:]...)
-	}
-	var n2 int
-	for {
-		if z.err != nil {
-			panic(z.err)
-		}
-		z.c = 0
-		z.buf = z.buf[0:cap(z.buf)]
-		n2, z.err = z.r.Read(z.buf)
-		z.buf = z.buf[:n2]
-		for i := 0; i < n2; i++ {
-			if token = z.buf[i]; !accept.isset(token) {
-				z.skipLoopFn(i)
-				return
-			}
-		}
-		z.n += n2
+// //go:noinline
+func (z *ioDecReader) readn1() (b uint8) {
+	b, err := z.br.ReadByte()
+	if err == nil {
+		z.n++
 		if z.trb {
-			z.tr = append(z.tr, z.buf[:n2]...)
+			z.tr = append(z.tr, b)
 		}
+		return
 	}
+	panic(err)
 }
 
-func (z *bufioDecReader) readToLoopFn(i int, out0 []byte) (out []byte) {
-	z.n += (i - z.c) - 1
-	if out0 == nil {
-		out = z.buf[z.c:i]
-	} else {
-		out = append(out0, z.buf[z.c:i]...)
+// //go:noinline
+func (z *ioDecReader) skip(accept *bitset256) (token byte) {
+	var eof bool
+	// for {
+	// 	token, eof = z.readn1eof()
+	// 	if eof {
+	// 		return
+	// 	}
+	// 	if accept.isset(token) {
+	// 		continue
+	// 	}
+	// 	return
+	// }
+LOOP:
+	token, eof = z.readn1eof()
+	if eof {
+		return
 	}
-	if z.trb {
-		z.tr = append(z.tr, z.buf[z.c:i]...)
+	if accept.isset(token) {
+		goto LOOP
 	}
-	z.c = i
 	return
 }
 
-func (z *bufioDecReader) readTo(in []byte, accept *bitset256) (out []byte) {
-	// _, out = z.search(in, accept, 0, 2); return
-	for i := z.c; i < len(z.buf); i++ {
-		if !accept.isset(z.buf[i]) {
-			return z.readToLoopFn(i, nil)
-		}
-	}
-	z.n += len(z.buf) - z.c
-	out = append(in, z.buf[z.c:]...)
-	if z.trb {
-		z.tr = append(z.tr, z.buf[z.c:]...)
-	}
-	var n2 int
-	for {
-		if z.err != nil {
-			if z.err == io.EOF {
-				return // readTo should read until it matches or end is reached
-			}
-			panic(z.err)
-		}
-		z.c = 0
-		z.buf = z.buf[0:cap(z.buf)]
-		n2, z.err = z.r.Read(z.buf)
-		z.buf = z.buf[:n2]
-		for i := 0; i < n2; i++ {
-			if !accept.isset(z.buf[i]) {
-				return z.readToLoopFn(i, out)
-			}
-		}
-		out = append(out, z.buf[:n2]...)
-		z.n += n2
-		if z.trb {
-			z.tr = append(z.tr, z.buf[:n2]...)
-		}
+func (z *ioDecReader) readTo(in []byte, accept *bitset256) (out []byte) {
+	out = in
+	// for {
+	// 	token, eof := z.readn1eof()
+	// 	if eof {
+	// 		return
+	// 	}
+	// 	if accept.isset(token) {
+	// 		out = append(out, token)
+	// 	} else {
+	// 		z.unreadn1()
+	// 		return
+	// 	}
+	// }
+LOOP:
+	token, eof := z.readn1eof()
+	if eof {
+		return
 	}
-}
-
-func (z *bufioDecReader) readUntilLoopFn(i int, out0 []byte) (out []byte) {
-	z.n += (i - z.c) - 1
-	i++
-	if out0 == nil {
-		out = z.buf[z.c:i]
+	if accept.isset(token) {
+		out = append(out, token)
 	} else {
-		out = append(out0, z.buf[z.c:i]...)
-	}
-	if z.trb {
-		z.tr = append(z.tr, z.buf[z.c:i]...)
+		z.unreadn1()
+		return
 	}
-	z.c = i
-	return
+	goto LOOP
 }
 
-func (z *bufioDecReader) readUntil(in []byte, stop byte) (out []byte) {
-	// _, out = z.search(in, nil, stop, 4); return
-	for i := z.c; i < len(z.buf); i++ {
-		if z.buf[i] == stop {
-			return z.readUntilLoopFn(i, nil)
-		}
-	}
-	z.n += len(z.buf) - z.c
-	out = append(in, z.buf[z.c:]...)
-	if z.trb {
-		z.tr = append(z.tr, z.buf[z.c:]...)
+func (z *ioDecReader) readUntil(in []byte, stop byte) (out []byte) {
+	out = in
+	// for {
+	// 	token, eof := z.readn1eof()
+	// 	if eof {
+	// 		panic(io.EOF)
+	// 	}
+	// 	out = append(out, token)
+	// 	if token == stop {
+	// 		return
+	// 	}
+	// }
+LOOP:
+	token, eof := z.readn1eof()
+	if eof {
+		panic(io.EOF)
 	}
-	var n2 int
-	for {
-		if z.err != nil {
-			panic(z.err)
-		}
-		z.c = 0
-		z.buf = z.buf[0:cap(z.buf)]
-		n2, z.err = z.r.Read(z.buf)
-		z.buf = z.buf[:n2]
-		for i := 0; i < n2; i++ {
-			if z.buf[i] == stop {
-				return z.readUntilLoopFn(i, out)
-			}
-		}
-		out = append(out, z.buf[:n2]...)
-		z.n += n2
-		if z.trb {
-			z.tr = append(z.tr, z.buf[:n2]...)
-		}
+	out = append(out, token)
+	if token == stop {
+		return
 	}
+	goto LOOP
 }
 
-func (z *bufioDecReader) unreadn1() {
-	err := z.UnreadByte()
+func (z *ioDecReader) unreadn1() {
+	err := z.br.UnreadByte()
 	if err != nil {
 		panic(err)
 	}
-}
-
-type ioDecReaderCommon struct {
-	r io.Reader // the reader passed in
-
-	n int // num read
-
-	l   byte // last byte
-	ls  byte // last byte status. 0: init-canDoNothing, 1: canRead, 2: canUnread
-	trb bool // tracking bytes turned on
-	_   bool
-	b   [4]byte // tiny buffer for reading single bytes
-
-	tr []byte // tracking bytes read
-}
-
-func (z *ioDecReaderCommon) reset(r io.Reader) {
-	z.r = r
-	z.l, z.ls, z.n, z.trb = 0, 0, 0, false
-	if z.tr != nil {
-		z.tr = z.tr[:0]
-	}
-}
-
-func (z *ioDecReaderCommon) numread() int {
-	return z.n
-}
-
-func (z *ioDecReaderCommon) track() {
-	if z.tr != nil {
-		z.tr = z.tr[:0]
+	z.n--
+	if z.trb {
+		if l := len(z.tr) - 1; l >= 0 {
+			z.tr = z.tr[:l]
+		}
 	}
-	z.trb = true
 }
 
-func (z *ioDecReaderCommon) stopTrack() (bs []byte) {
-	z.trb = false
-	return z.tr
-}
+// ------------------------------------
 
-// ioDecReader is a decReader that reads off an io.Reader.
-//
-// It also has a fallback implementation of ByteScanner if needed.
-type ioDecReader struct {
+type bufioDecReader struct {
 	ioDecReaderCommon
 
-	rr io.Reader
-	br io.ByteScanner
+	c   int // cursor
+	buf []byte
+	err error
 
-	x [scratchByteArrayLen]byte // for: get struct field name, swallow valueTypeBytes, etc
-	_ [1]uint64                 // padding
+	_ [3]uint64 // padding
 }
 
-func (z *ioDecReader) reset(r io.Reader) {
+func (z *bufioDecReader) reset(r io.Reader) {
 	z.ioDecReaderCommon.reset(r)
-
-	var ok bool
-	z.rr = r
-	z.br, ok = r.(io.ByteScanner)
-	if !ok {
-		z.br = z
-		z.rr = z
-	}
+	z.c, z.err = 0, nil
 }
 
-func (z *ioDecReader) Read(p []byte) (n int, err error) {
-	if len(p) == 0 {
+func (z *bufioDecReader) Read(p []byte) (n int, err error) {
+	if z.err != nil {
+		return 0, z.err
+	}
+	p0 := p
+	n = copy(p, z.buf[z.c:])
+	z.c += n
+	if z.c == len(z.buf) {
+		z.c = 0
+	}
+	z.n += n
+	if len(p) == n {
+		if z.c == 0 {
+			z.buf = z.buf[:1]
+			z.buf[0] = p[len(p)-1]
+			z.c = 1
+		}
+		if z.trb {
+			z.tr = append(z.tr, p0[:n]...)
+		}
 		return
 	}
-	var firstByte bool
-	if z.ls == 1 {
-		z.ls = 2
-		p[0] = z.l
-		if len(p) == 1 {
-			n = 1
-			return
+	p = p[n:]
+	var n2 int
+	// if we are here, then z.buf is all read
+	if len(p) > len(z.buf) {
+		n2, err = decReadFull(z.r, p)
+		n += n2
+		z.n += n2
+		z.err = err
+		// don't return EOF if some bytes were read. keep for next time.
+		if n > 0 && err == io.EOF {
+			err = nil
 		}
-		firstByte = true
-		p = p[1:]
+		// always keep last byte in z.buf
+		z.buf = z.buf[:1]
+		z.buf[0] = p[len(p)-1]
+		z.c = 1
+		if z.trb {
+			z.tr = append(z.tr, p0[:n]...)
+		}
+		return
 	}
-	n, err = z.r.Read(p)
-	if n > 0 {
-		if err == io.EOF && n == len(p) {
-			err = nil // read was successful, so postpone EOF (till next time)
+	// z.c is now 0, and len(p) <= len(z.buf)
+	for len(p) > 0 && z.err == nil {
+		// println("len(p) loop starting ... ")
+		z.c = 0
+		z.buf = z.buf[0:cap(z.buf)]
+		n2, err = z.r.Read(z.buf)
+		if n2 > 0 {
+			if err == io.EOF {
+				err = nil
+			}
+			z.buf = z.buf[:n2]
+			n2 = copy(p, z.buf)
+			z.c = n2
+			n += n2
+			z.n += n2
+			p = p[n2:]
 		}
-		z.l = p[n-1]
-		z.ls = 2
+		z.err = err
+		// println("... len(p) loop done")
 	}
-	if firstByte {
-		n++
+	if z.c == 0 {
+		z.buf = z.buf[:1]
+		z.buf[0] = p[len(p)-1]
+		z.c = 1
+	}
+	if z.trb {
+		z.tr = append(z.tr, p0[:n]...)
 	}
 	return
 }
 
-func (z *ioDecReader) ReadByte() (c byte, err error) {
-	n, err := z.Read(z.b[:1])
-	if n == 1 {
-		c = z.b[0]
-		if err == io.EOF {
-			err = nil // read was successful, so postpone EOF (till next time)
+func (z *bufioDecReader) ReadByte() (b byte, err error) {
+	// fast-path, so we elide calling into Read() most of the time
+	// if z.err == nil && z.c < (len(z.buf)-1) {
+	if z.c < (len(z.buf) - 1) { // means z.err == nil, and we don't read to end of buf
+		b = z.buf[z.c]
+		z.c++
+		z.n++
+		if z.trb {
+			z.tr = append(z.tr, b)
 		}
+		return
 	}
+	// z.b[0] = 0 // unnecessary, as err is returned if problem
+	_, err = z.Read(z.b[:1])
+	b = z.b[0]
 	return
 }
 
-func (z *ioDecReader) UnreadByte() (err error) {
-	switch z.ls {
-	case 2:
-		z.ls = 1
-	case 0:
-		err = errDecUnreadByteNothingToRead
-	case 1:
-		err = errDecUnreadByteLastByteNotRead
-	default:
-		err = errDecUnreadByteUnknown
+func (z *bufioDecReader) UnreadByte() (err error) {
+	if z.err != nil {
+		return z.err
 	}
-	return
+	if z.c > 0 {
+		z.c--
+		z.n--
+		if z.trb {
+			z.tr = z.tr[:len(z.tr)-1]
+		}
+		return
+	}
+	return errDecUnreadByteNothingToRead
 }
 
-// //go:noinline
-func (z *ioDecReader) readx(n int) (bs []byte) {
+func (z *bufioDecReader) readx(n int) (bs []byte) {
 	if n <= 0 {
 		return
 	}
-	if n < len(z.x) {
-		bs = z.x[:n]
-	} else {
-		bs = make([]byte, n)
-	}
-	if _, err := decReadFull(z.rr, bs); err != nil {
+	if z.err != nil {
+		panic(z.err)
+	}
+	if z.c+n <= len(z.buf) {
+		bs = z.buf[z.c : z.c+n]
+		z.n += n
+		z.c += n
+		if z.trb {
+			z.tr = append(z.tr, bs...)
+		}
+		return
+	}
+	bs = make([]byte, n)
+	_, err := z.Read(bs)
+	if err != nil {
 		panic(err)
 	}
-	z.n += len(bs)
-	if z.trb {
-		z.tr = append(z.tr, bs...)
-	}
 	return
 }
 
-// //go:noinline
-func (z *ioDecReader) readb(bs []byte) {
-	if len(bs) == 0 {
-		return
+func (z *bufioDecReader) readb(bs []byte) {
+	_, err := z.Read(bs)
+	if err != nil {
+		panic(err)
 	}
-	if _, err := decReadFull(z.rr, bs); err != nil {
+}
+
+func (z *bufioDecReader) readn1() (b uint8) {
+	b, err := z.ReadByte()
+	if err != nil {
 		panic(err)
 	}
-	z.n += len(bs)
+	return
+}
+
+// func (z *bufioDecReader) readn1eof() (b uint8, eof bool) {
+// 	b, err := z.ReadByte()
+// 	if err != nil {
+// 		if err == io.EOF {
+// 			eof = true
+// 		} else {
+// 			panic(err)
+// 		}
+// 	}
+// 	return
+// }
+
+func (z *bufioDecReader) skipLoopFn(i int) {
+	z.n += (i - z.c) - 1
+	i++
 	if z.trb {
-		z.tr = append(z.tr, bs...)
+		z.tr = append(z.tr, z.buf[z.c:i]...)
 	}
+	z.c = i
 }
 
-// //go:noinline
-func (z *ioDecReader) readn1eof() (b uint8, eof bool) {
-	b, err := z.br.ReadByte()
-	if err == nil {
-		z.n++
+func (z *bufioDecReader) skip(accept *bitset256) (token byte) {
+	// token, _ = z.search(nil, accept, 0, 1); return
+	for i := z.c; i < len(z.buf); i++ {
+		if token = z.buf[i]; !accept.isset(token) {
+			z.skipLoopFn(i)
+			return
+		}
+	}
+	z.n += len(z.buf) - z.c
+	if z.trb {
+		z.tr = append(z.tr, z.buf[z.c:]...)
+	}
+	var n2 int
+	for {
+		if z.err != nil {
+			panic(z.err)
+		}
+		z.c = 0
+		z.buf = z.buf[0:cap(z.buf)]
+		n2, z.err = z.r.Read(z.buf)
+		z.buf = z.buf[:n2]
+		for i := 0; i < n2; i++ {
+			if token = z.buf[i]; !accept.isset(token) {
+				z.skipLoopFn(i)
+				return
+			}
+		}
+		z.n += n2
 		if z.trb {
-			z.tr = append(z.tr, b)
+			z.tr = append(z.tr, z.buf[:n2]...)
 		}
-	} else if err == io.EOF {
-		eof = true
+	}
+}
+
+func (z *bufioDecReader) readToLoopFn(i int, out0 []byte) (out []byte) {
+	z.n += (i - z.c) - 1
+	if out0 == nil {
+		out = z.buf[z.c:i]
 	} else {
-		panic(err)
+		out = append(out0, z.buf[z.c:i]...)
+	}
+	if z.trb {
+		z.tr = append(z.tr, z.buf[z.c:i]...)
 	}
+	z.c = i
 	return
 }
 
-// //go:noinline
-func (z *ioDecReader) readn1() (b uint8) {
-	b, err := z.br.ReadByte()
-	if err == nil {
-		z.n++
+func (z *bufioDecReader) readTo(in []byte, accept *bitset256) (out []byte) {
+	// _, out = z.search(in, accept, 0, 2); return
+	for i := z.c; i < len(z.buf); i++ {
+		if !accept.isset(z.buf[i]) {
+			return z.readToLoopFn(i, nil)
+		}
+	}
+	z.n += len(z.buf) - z.c
+	out = append(in, z.buf[z.c:]...)
+	if z.trb {
+		z.tr = append(z.tr, z.buf[z.c:]...)
+	}
+	var n2 int
+	for {
+		if z.err != nil {
+			if z.err == io.EOF {
+				return // readTo should read until it matches or end is reached
+			}
+			panic(z.err)
+		}
+		z.c = 0
+		z.buf = z.buf[0:cap(z.buf)]
+		n2, z.err = z.r.Read(z.buf)
+		z.buf = z.buf[:n2]
+		for i := 0; i < n2; i++ {
+			if !accept.isset(z.buf[i]) {
+				return z.readToLoopFn(i, out)
+			}
+		}
+		out = append(out, z.buf[:n2]...)
+		z.n += n2
 		if z.trb {
-			z.tr = append(z.tr, b)
+			z.tr = append(z.tr, z.buf[:n2]...)
 		}
-		return
 	}
-	panic(err)
 }
 
-// //go:noinline
-func (z *ioDecReader) skip(accept *bitset256) (token byte) {
-	var eof bool
-	// for {
-	// 	token, eof = z.readn1eof()
-	// 	if eof {
-	// 		return
-	// 	}
-	// 	if accept.isset(token) {
-	// 		continue
-	// 	}
-	// 	return
-	// }
-LOOP:
-	token, eof = z.readn1eof()
-	if eof {
-		return
+func (z *bufioDecReader) readUntilLoopFn(i int, out0 []byte) (out []byte) {
+	z.n += (i - z.c) - 1
+	i++
+	if out0 == nil {
+		out = z.buf[z.c:i]
+	} else {
+		out = append(out0, z.buf[z.c:i]...)
 	}
-	if accept.isset(token) {
-		goto LOOP
+	if z.trb {
+		z.tr = append(z.tr, z.buf[z.c:i]...)
 	}
+	z.c = i
 	return
 }
 
-func (z *ioDecReader) readTo(in []byte, accept *bitset256) (out []byte) {
-	out = in
-	// for {
-	// 	token, eof := z.readn1eof()
-	// 	if eof {
-	// 		return
-	// 	}
-	// 	if accept.isset(token) {
-	// 		out = append(out, token)
-	// 	} else {
-	// 		z.unreadn1()
-	// 		return
-	// 	}
-	// }
-LOOP:
-	token, eof := z.readn1eof()
-	if eof {
-		return
-	}
-	if accept.isset(token) {
-		out = append(out, token)
-	} else {
-		z.unreadn1()
-		return
+func (z *bufioDecReader) readUntil(in []byte, stop byte) (out []byte) {
+	// _, out = z.search(in, nil, stop, 4); return
+	for i := z.c; i < len(z.buf); i++ {
+		if z.buf[i] == stop {
+			return z.readUntilLoopFn(i, nil)
+		}
 	}
-	goto LOOP
-}
-
-func (z *ioDecReader) readUntil(in []byte, stop byte) (out []byte) {
-	out = in
-	// for {
-	// 	token, eof := z.readn1eof()
-	// 	if eof {
-	// 		panic(io.EOF)
-	// 	}
-	// 	out = append(out, token)
-	// 	if token == stop {
-	// 		return
-	// 	}
-	// }
-LOOP:
-	token, eof := z.readn1eof()
-	if eof {
-		panic(io.EOF)
+	z.n += len(z.buf) - z.c
+	out = append(in, z.buf[z.c:]...)
+	if z.trb {
+		z.tr = append(z.tr, z.buf[z.c:]...)
 	}
-	out = append(out, token)
-	if token == stop {
-		return
+	var n2 int
+	for {
+		if z.err != nil {
+			panic(z.err)
+		}
+		z.c = 0
+		z.buf = z.buf[0:cap(z.buf)]
+		n2, z.err = z.r.Read(z.buf)
+		z.buf = z.buf[:n2]
+		for i := 0; i < n2; i++ {
+			if z.buf[i] == stop {
+				return z.readUntilLoopFn(i, out)
+			}
+		}
+		out = append(out, z.buf[:n2]...)
+		z.n += n2
+		if z.trb {
+			z.tr = append(z.tr, z.buf[:n2]...)
+		}
 	}
-	goto LOOP
 }
 
-func (z *ioDecReader) unreadn1() {
-	err := z.br.UnreadByte()
+func (z *bufioDecReader) unreadn1() {
+	err := z.UnreadByte()
 	if err != nil {
 		panic(err)
 	}
-	z.n--
-	if z.trb {
-		if l := len(z.tr) - 1; l >= 0 {
-			z.tr = z.tr[:l]
-		}
-	}
 }
 
 // ------------------------------------