MCPcopy
hub / github.com/uber-go/zap / safeAppendStringLike

Function safeAppendStringLike

zapcore/json_encoder.go:509–583  ·  view source on GitHub ↗

safeAppendStringLike is a generic implementation of safeAddString and safeAddByteString. It appends a string or byte slice to the buffer, escaping all special characters.

(
	// appendTo appends this string-like object to the buffer.
	appendTo func(*buffer.Buffer, S),
	// decodeRune decodes the next rune from the string-like object
	// and returns its value and width in bytes.
	decodeRune func(S) (rune, int),
	buf *buffer.Buffer,
	s S,
)

Source from the content-addressed store, hash-verified

507// safeAppendStringLike is a generic implementation of safeAddString and safeAddByteString.
508// It appends a string or byte slice to the buffer, escaping all special characters.
509func safeAppendStringLike[S []byte | string](
510 // appendTo appends this string-like object to the buffer.
511 appendTo func(*buffer.Buffer, S),
512 // decodeRune decodes the next rune from the string-like object
513 // and returns its value and width in bytes.
514 decodeRune func(S) (rune, int),
515 buf *buffer.Buffer,
516 s S,
517) {
518 // The encoding logic below works by skipping over characters
519 // that can be safely copied as-is,
520 // until a character is found that needs special handling.
521 // At that point, we copy everything we've seen so far,
522 // and then handle that special character.
523 //
524 // last is the index of the last byte that was copied to the buffer.
525 last := 0
526 for i := 0; i < len(s); {
527 if s[i] >= utf8.RuneSelf {
528 // Character >= RuneSelf may be part of a multi-byte rune.
529 // They need to be decoded before we can decide how to handle them.
530 r, size := decodeRune(s[i:])
531 if r != utf8.RuneError || size != 1 {
532 // No special handling required.
533 // Skip over this rune and continue.
534 i += size
535 continue
536 }
537
538 // Invalid UTF-8 sequence.
539 // Replace it with the Unicode replacement character.
540 appendTo(buf, s[last:i])
541 buf.AppendString(`\ufffd`)
542
543 i++
544 last = i
545 } else {
546 // Character < RuneSelf is a single-byte UTF-8 rune.
547 if s[i] >= 0x20 && s[i] != '\\' && s[i] != '"' {
548 // No escaping necessary.
549 // Skip over this character and continue.
550 i++
551 continue
552 }
553
554 // This character needs to be escaped.
555 appendTo(buf, s[last:i])
556 switch s[i] {
557 case '\\', '"':
558 buf.AppendByte('\\')
559 buf.AppendByte(s[i])
560 case '\n':
561 buf.AppendByte('\\')
562 buf.AppendByte('n')
563 case '\r':
564 buf.AppendByte('\\')
565 buf.AppendByte('r')
566 case '\t':

Callers 4

safeAddStringMethod · 0.85
safeAddByteStringMethod · 0.85

Calls 2

AppendByteMethod · 0.80
AppendStringMethod · 0.65

Tested by 2