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  }