mirror of
https://github.com/golang/go
synced 2024-09-29 12:04:28 -06:00
fmt: rely on utf8.AppendRune
This is both simpler and more performant. The need for fmt.fmtC to manually check for utf8.MaxRune is subtle to avoid overflow when converting uint64 to rune, so a test case was added to exercise this edge case. Change-Id: I0f2e6cce91dcd4cc6b88190c29807ca1c58e999d Reviewed-on: https://go-review.googlesource.com/c/go/+/412335 Auto-Submit: Joseph Tsai <joetsai@digital-static.net> Auto-Submit: Robert Griesemer <gri@google.com> Run-TryBot: Joseph Tsai <joetsai@digital-static.net> Reviewed-by: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@google.com> Run-TryBot: Robert Griesemer <gri@google.com>
This commit is contained in:
parent
d11c58eedb
commit
9c916c7901
@ -249,6 +249,7 @@ var fmtTests = []struct {
|
||||
{"%.0c", '⌘', "⌘"}, // Specifying precision should have no effect.
|
||||
{"%3c", '⌘', " ⌘"},
|
||||
{"%-3c", '⌘', "⌘ "},
|
||||
{"%c", uint64(0x100000000), "\ufffd"},
|
||||
// Runes that are not printable.
|
||||
{"%c", '\U00000e00', "\u0e00"},
|
||||
{"%c", '\U0010ffff', "\U0010ffff"},
|
||||
|
@ -461,13 +461,14 @@ func (f *fmt) fmtQ(s string) {
|
||||
// fmtC formats an integer as a Unicode character.
|
||||
// If the character is not valid Unicode, it will print '\ufffd'.
|
||||
func (f *fmt) fmtC(c uint64) {
|
||||
// Explicitly check whether c exceeds utf8.MaxRune since the conversion
|
||||
// of a uint64 to a rune may lose precision that indicates an overflow.
|
||||
r := rune(c)
|
||||
if c > utf8.MaxRune {
|
||||
r = utf8.RuneError
|
||||
}
|
||||
buf := f.intbuf[:0]
|
||||
w := utf8.EncodeRune(buf[:utf8.UTFMax], r)
|
||||
f.pad(buf[:w])
|
||||
f.pad(utf8.AppendRune(buf, r))
|
||||
}
|
||||
|
||||
// fmtQc formats an integer as a single-quoted, escaped Go character constant.
|
||||
|
@ -113,18 +113,7 @@ func (b *buffer) writeByte(c byte) {
|
||||
}
|
||||
|
||||
func (bp *buffer) writeRune(r rune) {
|
||||
if r < utf8.RuneSelf {
|
||||
*bp = append(*bp, byte(r))
|
||||
return
|
||||
}
|
||||
|
||||
b := *bp
|
||||
n := len(b)
|
||||
for n+utf8.UTFMax > cap(b) {
|
||||
b = append(b, 0)
|
||||
}
|
||||
w := utf8.EncodeRune(b[n:n+utf8.UTFMax], r)
|
||||
*bp = b[:n+w]
|
||||
*bp = utf8.AppendRune(*bp, r)
|
||||
}
|
||||
|
||||
// pp is used to store a printer's state and is reused with sync.Pool to avoid allocations.
|
||||
|
Loading…
Reference in New Issue
Block a user