| // Copyright 2017 The Go Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style | 
 | // license that can be found in the LICENSE file. | 
 |  | 
 | package strings | 
 |  | 
 | import ( | 
 | 	"unicode/utf8" | 
 | 	"unsafe" | 
 | ) | 
 |  | 
 | // A Builder is used to efficiently build a string using Write methods. | 
 | // It minimizes memory copying. The zero value is ready to use. | 
 | // Do not copy a non-zero Builder. | 
 | type Builder struct { | 
 | 	addr *Builder // of receiver, to detect copies by value | 
 | 	buf  []byte | 
 | } | 
 |  | 
 | // noescape hides a pointer from escape analysis.  noescape is | 
 | // the identity function but escape analysis doesn't think the | 
 | // output depends on the input. noescape is inlined and currently | 
 | // compiles down to zero instructions. | 
 | // USE CAREFULLY! | 
 | // This was copied from the runtime; see issues 23382 and 7921. | 
 | //go:nosplit | 
 | func noescape(p unsafe.Pointer) unsafe.Pointer { | 
 | 	x := uintptr(p) | 
 | 	return unsafe.Pointer(x ^ 0) | 
 | } | 
 |  | 
 | func (b *Builder) copyCheck() { | 
 | 	if b.addr == nil { | 
 | 		// This hack works around a failing of Go's escape analysis | 
 | 		// that was causing b to escape and be heap allocated. | 
 | 		// See issue 23382. | 
 | 		// TODO: once issue 7921 is fixed, this should be reverted to | 
 | 		// just "b.addr = b". | 
 | 		b.addr = (*Builder)(noescape(unsafe.Pointer(b))) | 
 | 	} else if b.addr != b { | 
 | 		panic("strings: illegal use of non-zero Builder copied by value") | 
 | 	} | 
 | } | 
 |  | 
 | // String returns the accumulated string. | 
 | func (b *Builder) String() string { | 
 | 	return *(*string)(unsafe.Pointer(&b.buf)) | 
 | } | 
 |  | 
 | // Len returns the number of accumulated bytes; b.Len() == len(b.String()). | 
 | func (b *Builder) Len() int { return len(b.buf) } | 
 |  | 
 | // Reset resets the Builder to be empty. | 
 | func (b *Builder) Reset() { | 
 | 	b.addr = nil | 
 | 	b.buf = nil | 
 | } | 
 |  | 
 | // grow copies the buffer to a new, larger buffer so that there are at least n | 
 | // bytes of capacity beyond len(b.buf). | 
 | func (b *Builder) grow(n int) { | 
 | 	buf := make([]byte, len(b.buf), 2*cap(b.buf)+n) | 
 | 	copy(buf, b.buf) | 
 | 	b.buf = buf | 
 | } | 
 |  | 
 | // Grow grows b's capacity, if necessary, to guarantee space for | 
 | // another n bytes. After Grow(n), at least n bytes can be written to b | 
 | // without another allocation. If n is negative, Grow panics. | 
 | func (b *Builder) Grow(n int) { | 
 | 	b.copyCheck() | 
 | 	if n < 0 { | 
 | 		panic("strings.Builder.Grow: negative count") | 
 | 	} | 
 | 	if cap(b.buf)-len(b.buf) < n { | 
 | 		b.grow(n) | 
 | 	} | 
 | } | 
 |  | 
 | // Write appends the contents of p to b's buffer. | 
 | // Write always returns len(p), nil. | 
 | func (b *Builder) Write(p []byte) (int, error) { | 
 | 	b.copyCheck() | 
 | 	b.buf = append(b.buf, p...) | 
 | 	return len(p), nil | 
 | } | 
 |  | 
 | // WriteByte appends the byte c to b's buffer. | 
 | // The returned error is always nil. | 
 | func (b *Builder) WriteByte(c byte) error { | 
 | 	b.copyCheck() | 
 | 	b.buf = append(b.buf, c) | 
 | 	return nil | 
 | } | 
 |  | 
 | // WriteRune appends the UTF-8 encoding of Unicode code point r to b's buffer. | 
 | // It returns the length of r and a nil error. | 
 | func (b *Builder) WriteRune(r rune) (int, error) { | 
 | 	b.copyCheck() | 
 | 	if r < utf8.RuneSelf { | 
 | 		b.buf = append(b.buf, byte(r)) | 
 | 		return 1, nil | 
 | 	} | 
 | 	l := len(b.buf) | 
 | 	if cap(b.buf)-l < utf8.UTFMax { | 
 | 		b.grow(utf8.UTFMax) | 
 | 	} | 
 | 	n := utf8.EncodeRune(b.buf[l:l+utf8.UTFMax], r) | 
 | 	b.buf = b.buf[:l+n] | 
 | 	return n, nil | 
 | } | 
 |  | 
 | // WriteString appends the contents of s to b's buffer. | 
 | // It returns the length of s and a nil error. | 
 | func (b *Builder) WriteString(s string) (int, error) { | 
 | 	b.copyCheck() | 
 | 	b.buf = append(b.buf, s...) | 
 | 	return len(s), nil | 
 | } |