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  }