1 // Copyright 2017 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
12 // A Builder is used to efficiently build a string using Write methods.
13 // It minimizes memory copying. The zero value is ready to use.
14 // Do not copy a non-zero Builder.
16 addr
*Builder
// of receiver, to detect copies by value
20 // noescape hides a pointer from escape analysis. It is the identity function
21 // but escape analysis doesn't think the output depends on the input.
22 // noescape is inlined and currently compiles down to zero instructions.
24 // This was copied from the runtime; see issues 23382 and 7921.
27 func noescape(p unsafe
.Pointer
) unsafe
.Pointer
{
29 return unsafe
.Pointer(x
^ 0)
32 func (b
*Builder
) copyCheck() {
34 // This hack works around a failing of Go's escape analysis
35 // that was causing b to escape and be heap allocated.
37 // TODO: once issue 7921 is fixed, this should be reverted to
39 b
.addr
= (*Builder
)(noescape(unsafe
.Pointer(b
)))
40 } else if b
.addr
!= b
{
41 panic("strings: illegal use of non-zero Builder copied by value")
45 // String returns the accumulated string.
46 func (b
*Builder
) String() string {
47 return *(*string)(unsafe
.Pointer(&b
.buf
))
50 // Len returns the number of accumulated bytes; b.Len() == len(b.String()).
51 func (b
*Builder
) Len() int { return len(b
.buf
) }
53 // Cap returns the capacity of the builder's underlying byte slice. It is the
54 // total space allocated for the string being built and includes any bytes
56 func (b
*Builder
) Cap() int { return cap(b
.buf
) }
58 // Reset resets the Builder to be empty.
59 func (b
*Builder
) Reset() {
64 // grow copies the buffer to a new, larger buffer so that there are at least n
65 // bytes of capacity beyond len(b.buf).
66 func (b
*Builder
) grow(n
int) {
67 buf
:= make([]byte, len(b
.buf
), 2*cap(b
.buf
)+n
)
72 // Grow grows b's capacity, if necessary, to guarantee space for
73 // another n bytes. After Grow(n), at least n bytes can be written to b
74 // without another allocation. If n is negative, Grow panics.
75 func (b
*Builder
) Grow(n
int) {
78 panic("strings.Builder.Grow: negative count")
80 if cap(b
.buf
)-len(b
.buf
) < n
{
85 // Write appends the contents of p to b's buffer.
86 // Write always returns len(p), nil.
87 func (b
*Builder
) Write(p
[]byte) (int, error
) {
89 b
.buf
= append(b
.buf
, p
...)
93 // WriteByte appends the byte c to b's buffer.
94 // The returned error is always nil.
95 func (b
*Builder
) WriteByte(c
byte) error
{
97 b
.buf
= append(b
.buf
, c
)
101 // WriteRune appends the UTF-8 encoding of Unicode code point r to b's buffer.
102 // It returns the length of r and a nil error.
103 func (b
*Builder
) WriteRune(r rune
) (int, error
) {
105 // Compare as uint32 to correctly handle negative runes.
106 if uint32(r
) < utf8
.RuneSelf
{
107 b
.buf
= append(b
.buf
, byte(r
))
111 if cap(b
.buf
)-l
< utf8
.UTFMax
{
114 n
:= utf8
.EncodeRune(b
.buf
[l
:l
+utf8
.UTFMax
], r
)
119 // WriteString appends the contents of s to b's buffer.
120 // It returns the length of s and a nil error.
121 func (b
*Builder
) WriteString(s
string) (int, error
) {
123 b
.buf
= append(b
.buf
, s
...)