Source File
builder.go
Belonging Package
strings
// 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 stringsimport ()// 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 valuebuf []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//go:nocheckptrfunc ( unsafe.Pointer) unsafe.Pointer {:= uintptr()return unsafe.Pointer( ^ 0)}func ( *Builder) () {if .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"..addr = (*Builder)(noescape(unsafe.Pointer()))} else if .addr != {panic("strings: illegal use of non-zero Builder copied by value")}}// String returns the accumulated string.func ( *Builder) () string {return *(*string)(unsafe.Pointer(&.buf))}// Len returns the number of accumulated bytes; b.Len() == len(b.String()).func ( *Builder) () int { return len(.buf) }// Cap returns the capacity of the builder's underlying byte slice. It is the// total space allocated for the string being built and includes any bytes// already written.func ( *Builder) () int { return cap(.buf) }// Reset resets the Builder to be empty.func ( *Builder) () {.addr = nil.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 ( *Builder) ( int) {:= make([]byte, len(.buf), 2*cap(.buf)+)copy(, .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 ( *Builder) ( int) {.copyCheck()if < 0 {panic("strings.Builder.Grow: negative count")}if cap(.buf)-len(.buf) < {.grow()}}// Write appends the contents of p to b's buffer.// Write always returns len(p), nil.func ( *Builder) ( []byte) (int, error) {.copyCheck().buf = append(.buf, ...)return len(), nil}// WriteByte appends the byte c to b's buffer.// The returned error is always nil.func ( *Builder) ( byte) error {.copyCheck().buf = append(.buf, )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 ( *Builder) ( rune) (int, error) {.copyCheck()if < utf8.RuneSelf {.buf = append(.buf, byte())return 1, nil}:= len(.buf)if cap(.buf)- < utf8.UTFMax {.grow(utf8.UTFMax)}:= utf8.EncodeRune(.buf[:+utf8.UTFMax], ).buf = .buf[:+]return , nil}// WriteString appends the contents of s to b's buffer.// It returns the length of s and a nil error.func ( *Builder) ( string) (int, error) {.copyCheck().buf = append(.buf, ...)return len(), nil}