khenaidoo | ac63710 | 2019-01-14 15:44:34 -0500 | [diff] [blame^] | 1 | package json |
| 2 | |
| 3 | import "unicode/utf8" |
| 4 | |
| 5 | // AppendBytes is a mirror of appendString with []byte arg |
| 6 | func (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. |
| 23 | func (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 |
| 33 | func 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 | } |