The following code is extracted from https://github.com/go-json-experiment/json at commit 3fecd76f5acdb9037c6c96eb6b869c69293f9c21 (Nov 7, 2022). appendString appends src to dst as a JSON string per RFC 7159, section 7. This rejects input that contains invalid UTF-8.
(dst []byte, src string)
| 24 | // appendString appends src to dst as a JSON string per RFC 7159, section 7. |
| 25 | // This rejects input that contains invalid UTF-8. |
| 26 | func AppendString(dst []byte, src string) ([]byte, error) { |
| 27 | var i, n int |
| 28 | dst = append(dst, '"') |
| 29 | for uint(len(src)) > uint(n) { |
| 30 | // Handle single-byte ASCII. |
| 31 | if c := src[n]; c < utf8.RuneSelf { |
| 32 | n++ |
| 33 | if c < ' ' || c == '"' || c == '\\' { |
| 34 | dst = append(dst, src[i:n-1]...) |
| 35 | dst = appendEscapedASCII(dst, c) |
| 36 | i = n |
| 37 | } |
| 38 | continue |
| 39 | } |
| 40 | |
| 41 | // Handle multi-byte Unicode. |
| 42 | _, rn := utf8.DecodeRuneInString(src[n:]) |
| 43 | n += rn |
| 44 | if rn == 1 { // must be utf8.RuneError since we already checked for single-byte ASCII |
| 45 | dst = append(dst, src[i:n-rn]...) |
| 46 | return dst, ErrInvalidUTF8 |
| 47 | } |
| 48 | } |
| 49 | dst = append(dst, src[i:n]...) |
| 50 | dst = append(dst, '"') |
| 51 | return dst, nil |
| 52 | } |
| 53 | |
| 54 | func appendEscapedASCII(dst []byte, c byte) []byte { |
| 55 | switch c { |