github.com/oarkflow/sio@v0.0.6/internal/bpool/bytebuffer.go (about)

     1  package bpool
     2  
     3  import (
     4  	"io"
     5  	"unsafe"
     6  )
     7  
     8  // ByteBuffer provides byte buffer, which can be used for minimizing
     9  // memory allocations.
    10  //
    11  // ByteBuffer may be used with functions appending data to the given []byte
    12  // slice. See example code for details.
    13  //
    14  // Use Get for obtaining an empty byte buffer.
    15  type ByteBuffer struct {
    16  
    17  	// B is a byte buffer to use in append-like workloads.
    18  	// See example code for details.
    19  	B []byte
    20  }
    21  
    22  // Len returns the size of the byte buffer.
    23  func (b *ByteBuffer) Len() int {
    24  	return len(b.B)
    25  }
    26  
    27  // ReadFrom implements io.ReaderFrom.
    28  //
    29  // The function appends all the data read from r to b.
    30  func (b *ByteBuffer) ReadFrom(r io.Reader) (int64, error) {
    31  	p := b.B
    32  	nStart := int64(len(p))
    33  	nMax := int64(cap(p))
    34  	n := nStart
    35  	if nMax == 0 {
    36  		nMax = 64
    37  		p = make([]byte, nMax)
    38  	} else {
    39  		p = p[:nMax]
    40  	}
    41  	for {
    42  		if n == nMax {
    43  			nMax *= 2
    44  			bNew := make([]byte, nMax)
    45  			copy(bNew, p)
    46  			p = bNew
    47  		}
    48  		nn, err := r.Read(p[n:])
    49  		n += int64(nn)
    50  		if err != nil {
    51  			b.B = p[:n]
    52  			n -= nStart
    53  			if err == io.EOF {
    54  				return n, nil
    55  			}
    56  			return n, err
    57  		}
    58  	}
    59  }
    60  
    61  // WriteTo implements io.WriterTo.
    62  func (b *ByteBuffer) WriteTo(w io.Writer) (int64, error) {
    63  	n, err := w.Write(b.B)
    64  	return int64(n), err
    65  }
    66  
    67  // Bytes returns b.B, i.e. all the bytes accumulated in the buffer.
    68  //
    69  // The purpose of this function is bytes.Buffer compatibility.
    70  func (b *ByteBuffer) Bytes() []byte {
    71  	return b.B
    72  }
    73  
    74  // Write implements io.Writer - it appends p to ByteBuffer.B
    75  func (b *ByteBuffer) Write(p []byte) (int, error) {
    76  	b.B = append(b.B, p...)
    77  	return len(p), nil
    78  }
    79  
    80  // WriteByte appends the byte c to the buffer.
    81  //
    82  // The purpose of this function is bytes.Buffer compatibility.
    83  //
    84  // The function always returns nil.
    85  func (b *ByteBuffer) WriteByte(c byte) error {
    86  	b.B = append(b.B, c)
    87  	return nil
    88  }
    89  
    90  // WriteString appends s to ByteBuffer.B.
    91  func (b *ByteBuffer) WriteString(s string) (int, error) {
    92  	b.B = append(b.B, s...)
    93  	return len(s), nil
    94  }
    95  
    96  // Set sets ByteBuffer.B to p.
    97  func (b *ByteBuffer) Set(p []byte) {
    98  	b.B = append(b.B[:0], p...)
    99  }
   100  
   101  // SetString sets ByteBuffer.B to s.
   102  func (b *ByteBuffer) SetString(s string) {
   103  	b.B = append(b.B[:0], s...)
   104  }
   105  
   106  // String returns string representation of ByteBuffer.B.
   107  func (b *ByteBuffer) String() string {
   108  	return *(*string)(unsafe.Pointer(&b.B))
   109  }
   110  
   111  // Reset makes ByteBuffer.B empty.
   112  func (b *ByteBuffer) Reset() {
   113  	b.B = b.B[:0]
   114  }