Use strings.Builder in unpackString (#746)
* Add test case and benchmark for unpackString helper * Use strings.Builder in unpackString
This commit is contained in:
parent
f4db2ca6ed
commit
5debfeec63
|
@ -7,6 +7,7 @@ import (
|
|||
"encoding/hex"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// helper functions called from the generated zmsg.go
|
||||
|
@ -267,29 +268,27 @@ func unpackString(msg []byte, off int) (string, int, error) {
|
|||
if off+l+1 > len(msg) {
|
||||
return "", off, &Error{err: "overflow unpacking txt"}
|
||||
}
|
||||
s := make([]byte, 0, l)
|
||||
var s strings.Builder
|
||||
s.Grow(l)
|
||||
for _, b := range msg[off+1 : off+1+l] {
|
||||
switch b {
|
||||
case '"', '\\':
|
||||
s = append(s, '\\', b)
|
||||
default:
|
||||
if b < 32 || b > 127 { // unprintable
|
||||
var buf [3]byte
|
||||
bufs := strconv.AppendInt(buf[:0], int64(b), 10)
|
||||
s = append(s, '\\')
|
||||
for i := 0; i < 3-len(bufs); i++ {
|
||||
s = append(s, '0')
|
||||
}
|
||||
for _, r := range bufs {
|
||||
s = append(s, r)
|
||||
}
|
||||
} else {
|
||||
s = append(s, b)
|
||||
switch {
|
||||
case b == '"' || b == '\\':
|
||||
s.WriteByte('\\')
|
||||
s.WriteByte(b)
|
||||
case b < 32 || b > 127: // unprintable
|
||||
var buf [3]byte
|
||||
bufs := strconv.AppendInt(buf[:0], int64(b), 10)
|
||||
s.WriteByte('\\')
|
||||
for i := len(bufs); i < 3; i++ {
|
||||
s.WriteByte('0')
|
||||
}
|
||||
s.Write(bufs)
|
||||
default:
|
||||
s.WriteByte(b)
|
||||
}
|
||||
}
|
||||
off += 1 + l
|
||||
return string(s), off, nil
|
||||
return s.String(), off, nil
|
||||
}
|
||||
|
||||
func packString(s string, msg []byte, off int) (int, error) {
|
||||
|
|
|
@ -106,3 +106,33 @@ func TestPackDataNsec(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnpackString(t *testing.T) {
|
||||
msg := []byte("\x00abcdef\x0f\\\"ghi\x04mmm")
|
||||
msg[0] = byte(len(msg) - 1)
|
||||
|
||||
got, _, err := unpackString(msg, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if want := `abcdef\015\\\"ghi\004mmm`; want != got {
|
||||
t.Errorf("expected %q, got %q", want, got)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkUnpackString(b *testing.B) {
|
||||
msg := []byte("\x00abcdef\x0f\\\"ghi\x04mmm")
|
||||
msg[0] = byte(len(msg) - 1)
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
got, _, err := unpackString(msg, 0)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
if want := `abcdef\015\\\"ghi\004mmm`; want != got {
|
||||
b.Errorf("expected %q, got %q", want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue