1package json
2
3import "unicode/utf8"
4
5// AppendBytes is a mirror of appendString with []byte arg
6func (Encoder) AppendBytes(dst, s []byte) []byte {
7	dst = append(dst, '"')
8	for i := 0; i < len(s); i++ {
9		if !noEscapeTable[s[i]] {
10			dst = appendBytesComplex(dst, s, i)
11			return append(dst, '"')
12		}
13	}
14	dst = append(dst, s...)
15	return append(dst, '"')
16}
17
18// AppendHex encodes the input bytes to a hex string and appends
19// the encoded string to the input byte slice.
20//
21// The operation loops though each byte and encodes it as hex using
22// the hex lookup table.
23func (Encoder) AppendHex(dst, s []byte) []byte {
24	dst = append(dst, '"')
25	for _, v := range s {
26		dst = append(dst, hex[v>>4], hex[v&0x0f])
27	}
28	return append(dst, '"')
29}
30
31// appendBytesComplex is a mirror of the appendStringComplex
32// with []byte arg
33func appendBytesComplex(dst, s []byte, i int) []byte {
34	start := 0
35	for i < len(s) {
36		b := s[i]
37		if b >= utf8.RuneSelf {
38			r, size := utf8.DecodeRune(s[i:])
39			if r == utf8.RuneError && size == 1 {
40				if start < i {
41					dst = append(dst, s[start:i]...)
42				}
43				dst = append(dst, `\ufffd`...)
44				i += size
45				start = i
46				continue
47			}
48			i += size
49			continue
50		}
51		if noEscapeTable[b] {
52			i++
53			continue
54		}
55		// We encountered a character that needs to be encoded.
56		// Let's append the previous simple characters to the byte slice
57		// and switch our operation to read and encode the remainder
58		// characters byte-by-byte.
59		if start < i {
60			dst = append(dst, s[start:i]...)
61		}
62		switch b {
63		case '"', '\\':
64			dst = append(dst, '\\', b)
65		case '\b':
66			dst = append(dst, '\\', 'b')
67		case '\f':
68			dst = append(dst, '\\', 'f')
69		case '\n':
70			dst = append(dst, '\\', 'n')
71		case '\r':
72			dst = append(dst, '\\', 'r')
73		case '\t':
74			dst = append(dst, '\\', 't')
75		default:
76			dst = append(dst, '\\', 'u', '0', '0', hex[b>>4], hex[b&0xF])
77		}
78		i++
79		start = i
80	}
81	if start < len(s) {
82		dst = append(dst, s[start:]...)
83	}
84	return dst
85}
86