package jsonwire
import (
)
var escapeASCII = [...]uint8{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
}
func ( []byte) bool {
var int
for uint(len()) > uint() {
if := []; < utf8.RuneSelf {
if escapeASCII[] > 0 {
return true
}
++
} else {
, := utf8.DecodeRune([:])
if == utf8.RuneError || == '\u2028' || == '\u2029' {
return true
}
+=
}
}
return false
}
func (, []byte, *jsonflags.Flags) ([]byte, error) {
var , int
var bool
= slices.Grow(, len(`"`)+len()+len(`"`))
= append(, '"')
for uint(len()) > uint() {
if := []; < utf8.RuneSelf {
++
if escapeASCII[] == 0 {
continue
}
if !( == '<' || == '>' || == '&') || .Get(jsonflags.EscapeForHTML) {
= append(, [:-1]...)
= appendEscapedASCII(, )
=
}
} else {
, := utf8.DecodeRune([:])
+=
if != utf8.RuneError && != '\u2028' && != '\u2029' {
continue
}
switch {
case isInvalidUTF8(, ):
= true
= append(, [:-]...)
= append(, "\ufffd"...)
=
case ( == '\u2028' || == '\u2029') && .Get(jsonflags.EscapeForJS):
= append(, [:-]...)
= appendEscapedUnicode(, )
=
}
}
}
= append(, [:]...)
= append(, '"')
if && !.Get(jsonflags.AllowInvalidUTF8) {
return , ErrInvalidUTF8
}
return , nil
}
func ( []byte, byte) []byte {
switch {
case '"', '\\':
= append(, '\\', )
case '\b':
= append(, "\\b"...)
case '\f':
= append(, "\\f"...)
case '\n':
= append(, "\\n"...)
case '\r':
= append(, "\\r"...)
case '\t':
= append(, "\\t"...)
default:
= appendEscapedUTF16(, uint16())
}
return
}
func ( []byte, rune) []byte {
if , := utf16.EncodeRune(); != '\ufffd' && != '\ufffd' {
= appendEscapedUTF16(, uint16())
= appendEscapedUTF16(, uint16())
} else {
= appendEscapedUTF16(, uint16())
}
return
}
func ( []byte, uint16) []byte {
const = "0123456789abcdef"
return append(, '\\', 'u', [(>>12)&0xf], [(>>8)&0xf], [(>>4)&0xf], [(>>0)&0xf])
}
func (, []byte, *jsonflags.Flags) ([]byte, int, error) {
var ValueFlags
, := ConsumeString(&, , !.Get(jsonflags.AllowInvalidUTF8))
if != nil {
return , ,
}
if !.Get(jsonflags.AnyEscape) &&
(.IsCanonical() || .Get(jsonflags.PreserveRawStrings)) {
= append(, [:]...)
return , , nil
}
if .Get(jsonflags.PreserveRawStrings) {
var , int
for < {
if := []; < utf8.RuneSelf {
if ( == '<' || == '>' || == '&') && .Get(jsonflags.EscapeForHTML) {
= append(, [:]...)
= appendEscapedASCII(, )
= + 1
}
++
} else {
, := utf8.DecodeRune([:])
if ( == '\u2028' || == '\u2029') && .Get(jsonflags.EscapeForJS) {
= append(, [:]...)
= appendEscapedUnicode(, )
= +
}
+=
}
}
return append(, [:]...), , nil
}
, := AppendUnquote(nil, [:])
, _ = AppendQuote(, , )
return , , nil
}
func ( []byte, float64, int) []byte {
if == 32 {
= float64(float32())
}
:= math.Abs()
:= byte('f')
if != 0 {
if == 64 && (float64() < 1e-6 || float64() >= 1e21) ||
== 32 && (float32() < 1e-6 || float32() >= 1e21) {
= 'e'
}
}
= strconv.AppendFloat(, , , -1, )
if == 'e' {
:= len()
if >= 4 && [-4] == 'e' && [-3] == '-' && [-2] == '0' {
[-2] = [-1]
= [:-1]
}
}
return
}
func (, []byte, *jsonflags.Flags) ([]byte, int, error) {
, := ConsumeNumber()
if != nil {
return , ,
}
if !.Get(jsonflags.CanonicalizeNumbers) {
= append(, [:]...)
return , , nil
}
var bool
for , := range [:] {
if == '.' || == 'e' || == 'E' {
= true
break
}
}
switch {
case string([:]) == "-0":
break
case :
if !.Get(jsonflags.CanonicalizeRawFloats) {
= append(, [:]...)
return , , nil
}
default:
const = 16
if !.Get(jsonflags.CanonicalizeRawInts) || < {
= append(, [:]...)
return , , nil
}
}
, := strconv.ParseFloat(string([:]), 64)
switch {
case == 0:
= 0
case math.IsInf(, +1):
= +math.MaxFloat64
case math.IsInf(, -1):
= -math.MaxFloat64
}
return AppendFloat(, , 64), , nil
}