Bläddra i källkod

codec: add readn and writen methods for reading/writing up to 6 bytes at once

Ugorji Nwoke 6 år sedan
förälder
incheckning
a2c9bf1666
3 ändrade filer med 65 tillägg och 65 borttagningar
  1. 13 9
      codec/json.go
  2. 28 56
      codec/reader.go
  3. 24 0
      codec/writer.go

+ 13 - 9
codec/json.go

@@ -166,9 +166,11 @@ func (e *jsonEncDriverTypical) WriteMapEnd() {
 
 func (e *jsonEncDriverTypical) EncodeBool(b bool) {
 	if b {
-		e.e.encWr.writeb(jsonLiteralTrue)
+		// e.e.encWr.writeb(jsonLiteralTrue)
+		e.e.encWr.writen([6]byte{'t', 'r', 'u', 'e'}, 4)
 	} else {
-		e.e.encWr.writeb(jsonLiteralFalse)
+		// e.e.encWr.writeb(jsonLiteralFalse)
+		e.e.encWr.writen([6]byte{'f', 'a', 'l', 's', 'e'}, 5)
 	}
 }
 
@@ -423,7 +425,9 @@ func (e *jsonEncDriver) EncodeNil() {
 	// We always encode nil as just null (never in quotes)
 	// This allows us to easily decode if a nil in the json stream
 	// ie if initial token is n.
-	e.e.encWr.writeb(jsonLiteralNull)
+
+	// e.e.encWr.writeb(jsonLiteralNull)
+	e.e.encWr.writen([6]byte{'n', 'u', 'l', 'l'}, 4)
 
 	// if e.h.MapKeyAsString && e.e.c == containerMapKey {
 	// 	e.e.encWr.writeb(jsonLiterals[jsonLitNullQ : jsonLitNullQ+6])
@@ -740,25 +744,25 @@ func (d *jsonDecDriver) ReadMapEnd() {
 // }
 
 func (d *jsonDecDriver) readLit4True() {
-	bs := d.d.decRd.readn3()
+	bs := d.d.decRd.readn(3)
 	d.tok = 0
-	if jsonValidateSymbols && bs != [3]byte{'r', 'u', 'e'} { // !bytes.Equal(bs, jsonLiteral4True)
+	if jsonValidateSymbols && bs != [6]byte{'r', 'u', 'e'} { // !bytes.Equal(bs, jsonLiteral4True)
 		d.d.errorf("expecting %s: got %s", jsonLiteral4True, bs)
 	}
 }
 
 func (d *jsonDecDriver) readLit4False() {
-	bs := d.d.decRd.readn4()
+	bs := d.d.decRd.readn(4)
 	d.tok = 0
-	if jsonValidateSymbols && bs != [4]byte{'a', 'l', 's', 'e'} { // !bytes.Equal(bs, jsonLiteral4False)
+	if jsonValidateSymbols && bs != [6]byte{'a', 'l', 's', 'e'} { // !bytes.Equal(bs, jsonLiteral4False)
 		d.d.errorf("expecting %s: got %s", jsonLiteral4False, bs)
 	}
 }
 
 func (d *jsonDecDriver) readLit4Null() {
-	bs := d.d.decRd.readn3() // readx(3)
+	bs := d.d.decRd.readn(3) // readx(3)
 	d.tok = 0
-	if jsonValidateSymbols && bs != [3]byte{'u', 'l', 'l'} { // !bytes.Equal(bs, jsonLiteral4Null)
+	if jsonValidateSymbols && bs != [6]byte{'u', 'l', 'l'} { // !bytes.Equal(bs, jsonLiteral4Null)
 		d.d.errorf("expecting %s: got %s", jsonLiteral4Null, bs)
 	}
 	d.fnil = true

+ 28 - 56
codec/reader.go

@@ -15,8 +15,7 @@ type decReader interface {
 	readx(n uint) []byte
 	readb([]byte)
 	readn1() uint8
-	readn3() [3]byte
-	readn4() [4]byte
+	readn(num uint8) (v [6]byte)
 	numread() uint // number of bytes read
 	track()
 	stopTrack() []byte
@@ -192,15 +191,9 @@ func (z *ioDecReader) UnreadByte() (err error) {
 	return
 }
 
-func (z *ioDecReader) readn3() (bs [3]byte) {
-	z.readb(bs[:])
-	// copy(bs[:], z.readx(3))
-	return
-}
-
-func (z *ioDecReader) readn4() (bs [4]byte) {
-	z.readb(bs[:])
-	// copy(bs[:], z.readx(4))
+func (z *ioDecReader) readn(num uint8) (bs [6]byte) {
+	z.readb(bs[:num])
+	// copy(bs[:], z.readx(uint(num)))
 	return
 }
 
@@ -474,14 +467,9 @@ func (z *bufioDecReader) unreadn1() {
 	}
 }
 
-func (z *bufioDecReader) readn3() (bs [3]byte) {
-	z.readb(bs[:])
-	return
-}
-
-func (z *bufioDecReader) readn4() (bs [4]byte) {
-	z.readb(bs[:])
-	// copy(bs[:], z.readx(4))
+func (z *bufioDecReader) readn(num uint8) (bs [6]byte) {
+	z.readb(bs[:num])
+	// copy(bs[:], z.readx(uint(num)))
 	return
 }
 
@@ -849,32 +837,29 @@ func (z *bytesDecReader) readn1() (v uint8) {
 	return
 }
 
-func (z *bytesDecReader) readn3() (bs [3]byte) {
+func (z *bytesDecReader) readn(num uint8) (bs [6]byte) {
 	// if z.c+2 >= uint(len(z.b)) {
 	// 	panic(io.EOF)
 	// }
 
-	// copy(bs[:], z.b[z.c:z.c+3])
-	bs[2] = z.b[z.c+2]
-	bs[1] = z.b[z.c+1]
-	bs[0] = z.b[z.c]
-	z.c += 3
+	copy(bs[:], z.b[z.c:z.c+uint(num)])
+	z.c += uint(num)
 	return
 }
 
-func (z *bytesDecReader) readn4() (bs [4]byte) {
-	// if z.c+3 >= uint(len(z.b)) {
-	// 	panic(io.EOF)
-	// }
+// func (z *bytesDecReader) readn4() (bs [4]byte) {
+// 	// if z.c+3 >= uint(len(z.b)) {
+// 	// 	panic(io.EOF)
+// 	// }
 
-	// copy(bs[:], z.b[z.c:z.c+4])
-	bs[3] = z.b[z.c+3]
-	bs[2] = z.b[z.c+2]
-	bs[1] = z.b[z.c+1]
-	bs[0] = z.b[z.c]
-	z.c += 4
-	return
-}
+// 	// copy(bs[:], z.b[z.c:z.c+4])
+// 	bs[3] = z.b[z.c+3]
+// 	bs[2] = z.b[z.c+2]
+// 	bs[1] = z.b[z.c+1]
+// 	bs[0] = z.b[z.c]
+// 	z.c += 4
+// 	return
+// }
 
 // func (z *bytesDecReader) readn1eof() (v uint8, eof bool) {
 // 	if z.a == 0 {
@@ -1215,30 +1200,17 @@ func (z *decRd) unreadn1() {
 	}
 }
 
-func (z *decRd) readn3() [3]byte {
-	if z.bytes {
-		return z.rb.readn3()
-	}
-	return z.readn3IO()
-}
-func (z *decRd) readn3IO() [3]byte {
-	if z.bufio {
-		return z.bi.readn3()
-	}
-	return z.ri.readn3()
-}
-
-func (z *decRd) readn4() [4]byte {
+func (z *decRd) readn(num uint8) [6]byte {
 	if z.bytes {
-		return z.rb.readn4()
+		return z.rb.readn(num)
 	}
-	return z.readn4IO()
+	return z.readnIO(num)
 }
-func (z *decRd) readn4IO() [4]byte {
+func (z *decRd) readnIO(num uint8) [6]byte {
 	if z.bufio {
-		return z.bi.readn4()
+		return z.bi.readn(num)
 	}
-	return z.ri.readn4()
+	return z.ri.readn(num)
 }
 
 func (z *decRd) readx(n uint) []byte {

+ 24 - 0
codec/writer.go

@@ -12,6 +12,8 @@ type encWriter interface {
 	writeqstr(string) // write string wrapped in quotes ie "..."
 	writen1(byte)
 	writen2(byte, byte)
+	// writen will write up to 6 bytes at a time.
+	writen(b [6]byte, num uint8)
 	end()
 }
 
@@ -150,6 +152,10 @@ func (z *bufioEncWriter) reset(w io.Writer, bufsize int, blist *bytesFreelist) {
 	if bufsize <= 0 {
 		bufsize = defEncByteBufSize
 	}
+	// bufsize must be >= 8, to accomodate writen methods (where n <= 8)
+	if bufsize <= 8 {
+		bufsize = 8
+	}
 	// z.sz = bufsize
 	if cap(z.buf) < bufsize {
 		if len(z.buf) > 0 && &z.buf[0] != &z.b[0] {
@@ -269,6 +275,14 @@ func (z *bufioEncWriter) writen2(b1, b2 byte) {
 	z.n += 2
 }
 
+func (z *bufioEncWriter) writen(b [6]byte, num uint8) {
+	if int(num) > len(z.buf)-z.n {
+		z.flush()
+	}
+	copy(z.buf[z.n:], b[:num])
+	z.n += int(num)
+}
+
 func (z *bufioEncWriter) endErr() (err error) {
 	if z.n > 0 {
 		err = z.flushErr()
@@ -310,6 +324,9 @@ func (z *bytesEncAppender) writen2(b1, b2 byte) {
 	// z.b = append(z.b, []byte{b1, b2}...) // cost: 83
 	// z.b = append(append(z.b, b1), b2) // cost 82
 }
+func (z *bytesEncAppender) writen(s [6]byte, num uint8) {
+	z.b = append(z.b, s[:num]...)
+}
 func (z *bytesEncAppender) endErr() error {
 	*(z.out) = z.b
 	return nil
@@ -376,6 +393,13 @@ func (z *encWr) writen2(b1, b2 byte) {
 		z.wf.writen2(b1, b2)
 	}
 }
+func (z *encWr) writen(b [6]byte, num uint8) {
+	if z.bytes {
+		z.wb.writen(b, num)
+	} else {
+		z.wf.writen(b, num)
+	}
+}
 func (z *encWr) endErr() error {
 	if z.bytes {
 		return z.wb.endErr()