github.com/iDigitalFlame/xmt@v0.5.4/util/builder.go (about) 1 // Copyright (C) 2020 - 2023 iDigitalFlame 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License for more details. 12 // 13 // You should have received a copy of the GNU General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 // 16 17 package util 18 19 import "unsafe" 20 21 // A Builder is used to efficiently build a string using Write methods. It 22 // minimizes memory copying. The zero value is ready to use. Do not copy a 23 // non-zero Builder. 24 // 25 // Re-implemented to remove UTF8 dependency and added some useful functions. 26 // Copy-check was also removed. 27 type Builder struct { 28 b []byte 29 } 30 31 // Reset resets the Builder to be empty. 32 func (b *Builder) Reset() { 33 b.b = nil 34 } 35 36 // Len returns the number of accumulated bytes; b.Len() == len(b.String()). 37 func (b *Builder) Len() int { 38 return len(b.b) 39 } 40 41 // Cap returns the capacity of the builder's underlying byte slice. It is the 42 // total space allocated for the string being built and includes any bytes 43 // already written. 44 func (b *Builder) Cap() int { 45 return cap(b.b) 46 } 47 48 // Grow grows b's capacity, if necessary, to guarantee space for another n bytes. 49 // 50 // After Grow(n), at least n bytes can be written to b without another allocation. 51 // If n is negative, Grow is a NOP. 52 func (b *Builder) Grow(n int) { 53 if n < 0 || cap(b.b)-len(b.b) >= n { 54 return 55 } 56 v := make([]byte, len(b.b), 2*cap(b.b)+n) 57 copy(v, b.b) 58 b.b, v = v, nil 59 } 60 61 // String returns the accumulated string. 62 func (b *Builder) String() string { 63 return *(*string)(unsafe.Pointer(&b.b)) 64 } 65 66 // Output returns the accumulated string, then resets the value of this Builder. 67 func (b *Builder) Output() string { 68 s := *(*string)(unsafe.Pointer(&b.b)) 69 b.Reset() 70 return s 71 } 72 73 // WriteByte appends the byte c to b's buffer. 74 // 75 // The returned error is always nil. 76 func (b *Builder) WriteByte(c byte) error { 77 b.b = append(b.b, c) 78 return nil 79 } 80 81 // InsertByte appends the byte c to b's buffer at the zero position. 82 // 83 // The returned error is always nil. 84 func (b *Builder) InsertByte(c byte) error { 85 b.b = append(b.b, 0) 86 copy(b.b[1:], b.b) 87 b.b[0] = c 88 return nil 89 } 90 91 // Write appends the contents of p to b's buffer. 92 // 93 // Write always returns len(p), nil. 94 func (b *Builder) Write(p []byte) (int, error) { 95 b.b = append(b.b, p...) 96 return len(p), nil 97 } 98 99 // WriteString appends the contents of s to b's buffer. 100 // 101 // It returns the length of s and a nil error. 102 func (b *Builder) WriteString(s string) (int, error) { 103 b.b = append(b.b, s...) 104 return len(s), nil 105 }