github.com/nikandfor/tlog@v0.21.5-0.20231108111739-3ef89426a96d/low/safeadd.go (about) 1 package low 2 3 import "unicode/utf8" 4 5 const tohex = "0123456789abcdef" 6 7 // AppendSafe appends string to buffer with JSON compatible esaping. 8 // It does NOT add quotes. 9 func AppendSafe(b, s []byte) []byte { 10 return AppendSafeString(b, UnsafeBytesToString(s)) 11 } 12 13 func AppendSafeString(b []byte, s string) []byte { 14 again: 15 i := 0 16 l := len(s) 17 for i < l { 18 c := s[i] 19 if c == '"' || c == '\\' || c < 0x20 || c > 0x7e { 20 break 21 } 22 i++ 23 } 24 b = append(b, s[:i]...) 25 if i == l { 26 return b 27 } 28 29 switch s[i] { 30 case '"', '\\': 31 b = append(b, '\\', s[i]) 32 case '\n': 33 b = append(b, '\\', 'n') 34 case '\t': 35 b = append(b, '\\', 't') 36 case '\v': 37 b = append(b, '\\', 'v') 38 case '\r': 39 b = append(b, '\\', 'r') 40 case '\a': 41 b = append(b, '\\', 'a') 42 case '\b': 43 b = append(b, '\\', 'b') 44 case '\f': 45 b = append(b, '\\', 'f') 46 default: 47 goto hardway 48 } 49 50 s = s[i+1:] 51 52 goto again 53 54 hardway: 55 r, width := utf8.DecodeRuneInString(s[i:]) 56 57 if r == utf8.RuneError && width == 1 { 58 b = append(b, '\\', 'x', tohex[s[i]>>4], tohex[s[i]&0xf]) 59 } else { 60 b = append(b, s[i:i+width]...) 61 } 62 63 s = s[i+width:] 64 65 goto again 66 } 67 68 func AppendQuote(b, s []byte) []byte { 69 b = append(b, '"') 70 b = AppendSafe(b, s) 71 b = append(b, '"') 72 73 return b 74 } 75 76 func AppendQuoteString(b []byte, s string) []byte { 77 b = append(b, '"') 78 b = AppendSafeString(b, s) 79 b = append(b, '"') 80 81 return b 82 }