VictoriaMetrics/vendor/github.com/valyala/quicktemplate/jsonstring.go

94 lines
1.8 KiB
Go
Raw Normal View History

2019-05-22 23:16:55 +02:00
package quicktemplate
import (
"io"
"strings"
)
func writeJSONString(w io.Writer, s string) {
if len(s) > 24 &&
strings.IndexByte(s, '"') < 0 &&
strings.IndexByte(s, '\\') < 0 &&
strings.IndexByte(s, '\n') < 0 &&
strings.IndexByte(s, '\r') < 0 &&
strings.IndexByte(s, '\t') < 0 &&
strings.IndexByte(s, '\f') < 0 &&
strings.IndexByte(s, '\b') < 0 &&
strings.IndexByte(s, '<') < 0 &&
strings.IndexByte(s, '\'') < 0 &&
strings.IndexByte(s, 0) < 0 {
// fast path - nothing to escape
w.Write(unsafeStrToBytes(s))
return
}
// slow path
write := w.Write
b := unsafeStrToBytes(s)
j := 0
n := len(b)
if n > 0 {
// Hint the compiler to remove bounds checks in the loop below.
_ = b[n-1]
}
for i := 0; i < n; i++ {
switch b[i] {
case '"':
write(b[j:i])
write(strBackslashQuote)
j = i + 1
case '\\':
write(b[j:i])
write(strBackslashBackslash)
j = i + 1
case '\n':
write(b[j:i])
write(strBackslashN)
j = i + 1
case '\r':
write(b[j:i])
write(strBackslashR)
j = i + 1
case '\t':
write(b[j:i])
write(strBackslashT)
j = i + 1
case '\f':
write(b[j:i])
write(strBackslashF)
j = i + 1
case '\b':
write(b[j:i])
write(strBackslashB)
j = i + 1
case '<':
write(b[j:i])
write(strBackslashLT)
j = i + 1
case '\'':
write(b[j:i])
write(strBackslashQ)
j = i + 1
case 0:
write(b[j:i])
write(strBackslashZero)
j = i + 1
}
}
write(b[j:])
}
var (
strBackslashQuote = []byte(`\"`)
strBackslashBackslash = []byte(`\\`)
strBackslashN = []byte(`\n`)
strBackslashR = []byte(`\r`)
strBackslashT = []byte(`\t`)
strBackslashF = []byte(`\u000c`)
strBackslashB = []byte(`\u0008`)
strBackslashLT = []byte(`\u003c`)
strBackslashQ = []byte(`\u0027`)
strBackslashZero = []byte(`\u0000`)
)