github.com/v2fly/v2ray-core/v4@v4.45.2/common/buf/buffer.go (about)

     1  package buf
     2  
     3  import (
     4  	"io"
     5  
     6  	"github.com/v2fly/v2ray-core/v4/common/bytespool"
     7  )
     8  
     9  const (
    10  	// Size of a regular buffer.
    11  	Size = 2048
    12  )
    13  
    14  var pool = bytespool.GetPool(Size)
    15  
    16  // Buffer is a recyclable allocation of a byte array. Buffer.Release() recycles
    17  // the buffer into an internal buffer pool, in order to recreate a buffer more
    18  // quickly.
    19  type Buffer struct {
    20  	v     []byte
    21  	start int32
    22  	end   int32
    23  }
    24  
    25  // New creates a Buffer with 0 length and 2K capacity.
    26  func New() *Buffer {
    27  	return &Buffer{
    28  		v: pool.Get().([]byte),
    29  	}
    30  }
    31  
    32  // StackNew creates a new Buffer object on stack.
    33  // This method is for buffers that is released in the same function.
    34  func StackNew() Buffer {
    35  	return Buffer{
    36  		v: pool.Get().([]byte),
    37  	}
    38  }
    39  
    40  // Release recycles the buffer into an internal buffer pool.
    41  func (b *Buffer) Release() {
    42  	if b == nil || b.v == nil {
    43  		return
    44  	}
    45  
    46  	p := b.v
    47  	b.v = nil
    48  	b.Clear()
    49  	pool.Put(p) // nolint: staticcheck
    50  }
    51  
    52  // Clear clears the content of the buffer, results an empty buffer with
    53  // Len() = 0.
    54  func (b *Buffer) Clear() {
    55  	b.start = 0
    56  	b.end = 0
    57  }
    58  
    59  // Byte returns the bytes at index.
    60  func (b *Buffer) Byte(index int32) byte {
    61  	return b.v[b.start+index]
    62  }
    63  
    64  // SetByte sets the byte value at index.
    65  func (b *Buffer) SetByte(index int32, value byte) {
    66  	b.v[b.start+index] = value
    67  }
    68  
    69  // Bytes returns the content bytes of this Buffer.
    70  func (b *Buffer) Bytes() []byte {
    71  	return b.v[b.start:b.end]
    72  }
    73  
    74  // Extend increases the buffer size by n bytes, and returns the extended part.
    75  // It panics if result size is larger than buf.Size.
    76  func (b *Buffer) Extend(n int32) []byte {
    77  	end := b.end + n
    78  	if end > int32(len(b.v)) {
    79  		panic("extending out of bound")
    80  	}
    81  	ext := b.v[b.end:end]
    82  	b.end = end
    83  	return ext
    84  }
    85  
    86  // BytesRange returns a slice of this buffer with given from and to boundary.
    87  func (b *Buffer) BytesRange(from, to int32) []byte {
    88  	if from < 0 {
    89  		from += b.Len()
    90  	}
    91  	if to < 0 {
    92  		to += b.Len()
    93  	}
    94  	return b.v[b.start+from : b.start+to]
    95  }
    96  
    97  // BytesFrom returns a slice of this Buffer starting from the given position.
    98  func (b *Buffer) BytesFrom(from int32) []byte {
    99  	if from < 0 {
   100  		from += b.Len()
   101  	}
   102  	return b.v[b.start+from : b.end]
   103  }
   104  
   105  // BytesTo returns a slice of this Buffer from start to the given position.
   106  func (b *Buffer) BytesTo(to int32) []byte {
   107  	if to < 0 {
   108  		to += b.Len()
   109  	}
   110  	return b.v[b.start : b.start+to]
   111  }
   112  
   113  // Resize cuts the buffer at the given position.
   114  func (b *Buffer) Resize(from, to int32) {
   115  	if from < 0 {
   116  		from += b.Len()
   117  	}
   118  	if to < 0 {
   119  		to += b.Len()
   120  	}
   121  	if to < from {
   122  		panic("Invalid slice")
   123  	}
   124  	b.end = b.start + to
   125  	b.start += from
   126  }
   127  
   128  // Advance cuts the buffer at the given position.
   129  func (b *Buffer) Advance(from int32) {
   130  	if from < 0 {
   131  		from += b.Len()
   132  	}
   133  	b.start += from
   134  }
   135  
   136  // Len returns the length of the buffer content.
   137  func (b *Buffer) Len() int32 {
   138  	if b == nil {
   139  		return 0
   140  	}
   141  	return b.end - b.start
   142  }
   143  
   144  // IsEmpty returns true if the buffer is empty.
   145  func (b *Buffer) IsEmpty() bool {
   146  	return b.Len() == 0
   147  }
   148  
   149  // IsFull returns true if the buffer has no more room to grow.
   150  func (b *Buffer) IsFull() bool {
   151  	return b != nil && b.end == int32(len(b.v))
   152  }
   153  
   154  // Write implements Write method in io.Writer.
   155  func (b *Buffer) Write(data []byte) (int, error) {
   156  	nBytes := copy(b.v[b.end:], data)
   157  	b.end += int32(nBytes)
   158  	return nBytes, nil
   159  }
   160  
   161  // WriteByte writes a single byte into the buffer.
   162  func (b *Buffer) WriteByte(v byte) error {
   163  	if b.IsFull() {
   164  		return newError("buffer full")
   165  	}
   166  	b.v[b.end] = v
   167  	b.end++
   168  	return nil
   169  }
   170  
   171  // WriteString implements io.StringWriter.
   172  func (b *Buffer) WriteString(s string) (int, error) {
   173  	return b.Write([]byte(s))
   174  }
   175  
   176  // Read implements io.Reader.Read().
   177  func (b *Buffer) Read(data []byte) (int, error) {
   178  	if b.Len() == 0 {
   179  		return 0, io.EOF
   180  	}
   181  	nBytes := copy(data, b.v[b.start:b.end])
   182  	if int32(nBytes) == b.Len() {
   183  		b.Clear()
   184  	} else {
   185  		b.start += int32(nBytes)
   186  	}
   187  	return nBytes, nil
   188  }
   189  
   190  // ReadFrom implements io.ReaderFrom.
   191  func (b *Buffer) ReadFrom(reader io.Reader) (int64, error) {
   192  	n, err := reader.Read(b.v[b.end:])
   193  	b.end += int32(n)
   194  	return int64(n), err
   195  }
   196  
   197  // ReadFullFrom reads exact size of bytes from given reader, or until error occurs.
   198  func (b *Buffer) ReadFullFrom(reader io.Reader, size int32) (int64, error) {
   199  	end := b.end + size
   200  	if end > int32(len(b.v)) {
   201  		v := end
   202  		return 0, newError("out of bound: ", v)
   203  	}
   204  	n, err := io.ReadFull(reader, b.v[b.end:end])
   205  	b.end += int32(n)
   206  	return int64(n), err
   207  }
   208  
   209  // String returns the string form of this Buffer.
   210  func (b *Buffer) String() string {
   211  	return string(b.Bytes())
   212  }