github.com/yaling888/clash@v1.53.0/common/pool/bufferv2.go (about)

     1  package pool
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"io"
     7  	"net"
     8  	"net/netip"
     9  	"sync"
    10  	"unicode/utf8"
    11  )
    12  
    13  var buffer2Pool = sync.Pool{
    14  	New: func() any {
    15  		return &Buffer{
    16  			buf: new(bytes.Buffer),
    17  		}
    18  	},
    19  }
    20  
    21  type Buffer struct {
    22  	buf *bytes.Buffer
    23  }
    24  
    25  func NewBuffer() *Buffer {
    26  	return buffer2Pool.Get().(*Buffer)
    27  }
    28  
    29  func (b *Buffer) Release() {
    30  	b.buf.Reset()
    31  	buffer2Pool.Put(b)
    32  }
    33  
    34  func (b *Buffer) Reset() {
    35  	b.buf.Reset()
    36  }
    37  
    38  func (b *Buffer) Grow(n int) {
    39  	b.buf.Grow(n)
    40  }
    41  
    42  func (b *Buffer) Len() int {
    43  	return b.buf.Len()
    44  }
    45  
    46  func (b *Buffer) Cap() int {
    47  	return b.buf.Cap()
    48  }
    49  
    50  func (b *Buffer) Read(p []byte) (n int, err error) {
    51  	return b.buf.Read(p)
    52  }
    53  
    54  func (b *Buffer) ReadByte() (byte, error) {
    55  	return b.buf.ReadByte()
    56  }
    57  
    58  func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {
    59  	return b.buf.ReadFrom(r)
    60  }
    61  
    62  func (b *Buffer) ReadFullFrom(r io.Reader, size int64) (n int64, err error) {
    63  	n, err = b.buf.ReadFrom(io.LimitReader(r, size))
    64  	if err == nil && n != size {
    65  		err = io.ErrUnexpectedEOF
    66  		return
    67  	}
    68  	return
    69  }
    70  
    71  func (b *Buffer) ReadUint8(r io.Reader) (uint8, error) {
    72  	_, err := b.ReadFullFrom(r, 1)
    73  	if err != nil {
    74  		return 0, err
    75  	}
    76  	return b.buf.ReadByte()
    77  }
    78  
    79  func (b *Buffer) ReadUint16(r io.Reader) (uint16, error) {
    80  	_, err := b.ReadFullFrom(r, 2)
    81  	if err != nil {
    82  		return 0, err
    83  	}
    84  	return binary.NativeEndian.Uint16(b.buf.Next(2)), nil
    85  }
    86  
    87  func (b *Buffer) ReadUint32(r io.Reader) (uint32, error) {
    88  	_, err := b.ReadFullFrom(r, 4)
    89  	if err != nil {
    90  		return 0, err
    91  	}
    92  	return binary.NativeEndian.Uint32(b.buf.Next(4)), nil
    93  }
    94  
    95  func (b *Buffer) ReadUint64(r io.Reader) (uint64, error) {
    96  	_, err := b.ReadFullFrom(r, 8)
    97  	if err != nil {
    98  		return 0, err
    99  	}
   100  	return binary.NativeEndian.Uint64(b.buf.Next(8)), nil
   101  }
   102  
   103  func (b *Buffer) ReadUint16be(r io.Reader) (uint16, error) {
   104  	_, err := b.ReadFullFrom(r, 2)
   105  	if err != nil {
   106  		return 0, err
   107  	}
   108  	return binary.BigEndian.Uint16(b.buf.Next(2)), nil
   109  }
   110  
   111  func (b *Buffer) ReadUint32be(r io.Reader) (uint32, error) {
   112  	_, err := b.ReadFullFrom(r, 4)
   113  	if err != nil {
   114  		return 0, err
   115  	}
   116  	return binary.BigEndian.Uint32(b.buf.Next(4)), nil
   117  }
   118  
   119  func (b *Buffer) ReadUint64be(r io.Reader) (uint64, error) {
   120  	_, err := b.ReadFullFrom(r, 8)
   121  	if err != nil {
   122  		return 0, err
   123  	}
   124  	return binary.BigEndian.Uint64(b.buf.Next(8)), nil
   125  }
   126  
   127  func (b *Buffer) Write(p []byte) (n int, err error) {
   128  	return b.buf.Write(p)
   129  }
   130  
   131  func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) {
   132  	return b.buf.WriteTo(w)
   133  }
   134  
   135  func (b *Buffer) Next(n int) []byte {
   136  	return b.buf.Next(n)
   137  }
   138  
   139  func (b *Buffer) Bytes() []byte {
   140  	return b.buf.Bytes()
   141  }
   142  
   143  var bufferWriterPool = sync.Pool{New: func() any { return &BufferWriter{} }}
   144  
   145  func GetBufferWriter() *BufferWriter {
   146  	return bufferWriterPool.Get().(*BufferWriter)
   147  }
   148  
   149  func PutBufferWriter(buf *BufferWriter) {
   150  	buf.Reset()
   151  	bufferWriterPool.Put(buf)
   152  }
   153  
   154  const (
   155  	smallBufferSize = 64
   156  	maxInt          = int(^uint(0) >> 1)
   157  )
   158  
   159  type BufferReader []byte
   160  
   161  type BufferWriter []byte
   162  
   163  func (br *BufferReader) Len() int {
   164  	return len(*br)
   165  }
   166  
   167  func (br *BufferReader) Cap() int {
   168  	return cap(*br)
   169  }
   170  
   171  func (br *BufferReader) IsEmpty() bool {
   172  	return br.Len() == 0
   173  }
   174  
   175  func (br *BufferReader) SplitAt(n int) (BufferReader, BufferReader) {
   176  	n = min(n, br.Len())
   177  	buf := *br
   178  	return buf[:n], buf[n:]
   179  }
   180  
   181  func (br *BufferReader) SplitBy(f func(byte) bool) (BufferReader, BufferReader) {
   182  	for i, c := range *br {
   183  		if f(c) {
   184  			return br.SplitAt(i)
   185  		}
   186  	}
   187  	return *br, nil
   188  }
   189  
   190  func (br *BufferReader) ReadUint8() uint8 {
   191  	r := (*br)[0]
   192  	*br = (*br)[1:]
   193  	return r
   194  }
   195  
   196  func (br *BufferReader) ReadUint16() uint16 {
   197  	r := binary.NativeEndian.Uint16((*br)[:2])
   198  	*br = (*br)[2:]
   199  	return r
   200  }
   201  
   202  func (br *BufferReader) ReadUint32() uint32 {
   203  	r := binary.NativeEndian.Uint32((*br)[:4])
   204  	*br = (*br)[4:]
   205  	return r
   206  }
   207  
   208  func (br *BufferReader) ReadUint64() uint64 {
   209  	r := binary.NativeEndian.Uint64((*br)[:8])
   210  	*br = (*br)[8:]
   211  	return r
   212  }
   213  
   214  func (br *BufferReader) ReadUint16be() uint16 {
   215  	r := binary.BigEndian.Uint16((*br)[:2])
   216  	*br = (*br)[2:]
   217  	return r
   218  }
   219  
   220  func (br *BufferReader) ReadUint32be() uint32 {
   221  	r := binary.BigEndian.Uint32((*br)[:4])
   222  	*br = (*br)[4:]
   223  	return r
   224  }
   225  
   226  func (br *BufferReader) ReadUint64be() uint64 {
   227  	r := binary.BigEndian.Uint64((*br)[:8])
   228  	*br = (*br)[8:]
   229  	return r
   230  }
   231  
   232  func (br *BufferReader) ReadUvarint() (uint64, error) {
   233  	return binary.ReadUvarint(br)
   234  }
   235  
   236  func (br *BufferReader) ReadVarint() (int64, error) {
   237  	return binary.ReadVarint(br)
   238  }
   239  
   240  func (br *BufferReader) Skip(n int) {
   241  	*br = (*br)[n:]
   242  }
   243  
   244  func (br *BufferReader) Read(p []byte) (n int, err error) {
   245  	if br.IsEmpty() {
   246  		if len(p) == 0 {
   247  			return 0, nil
   248  		}
   249  		return 0, io.EOF
   250  	}
   251  
   252  	n = copy(p, *br)
   253  	*br = (*br)[n:]
   254  	return
   255  }
   256  
   257  func (br *BufferReader) ReadByte() (byte, error) {
   258  	if br.Len() == 0 {
   259  		return 0, io.EOF
   260  	}
   261  	return br.ReadUint8(), nil
   262  }
   263  
   264  func (br *BufferReader) ReadIPv4() netip.Addr {
   265  	ip := netip.AddrFrom4([4]byte((*br)[:4]))
   266  	*br = (*br)[4:]
   267  	return ip
   268  }
   269  
   270  func (br *BufferReader) ReadIPv6() netip.Addr {
   271  	ip := netip.AddrFrom16([16]byte((*br)[:16]))
   272  	*br = (*br)[16:]
   273  	return ip
   274  }
   275  
   276  func (bw *BufferWriter) Len() int {
   277  	return len(*bw)
   278  }
   279  
   280  func (bw *BufferWriter) Cap() int {
   281  	return cap(*bw)
   282  }
   283  
   284  // tryGrowByReslice is an inlineable version of grow for the fast-case where the
   285  // internal buffer only needs to be resliced.
   286  // It returns the index where bytes should be written and whether it succeeded.
   287  func (bw *BufferWriter) tryGrowByReslice(n int) (int, bool) {
   288  	if l := len(*bw); n <= cap(*bw)-l {
   289  		*bw = (*bw)[:l+n]
   290  		return l, true
   291  	}
   292  	return 0, false
   293  }
   294  
   295  // growSlice grows b by n, preserving the original content of b.
   296  // If the allocation fails, it panics with ErrTooLarge.
   297  func growSlice(b []byte, n int) []byte {
   298  	defer func() {
   299  		if recover() != nil {
   300  			panic(bytes.ErrTooLarge)
   301  		}
   302  	}()
   303  	// TODO(http://golang.org/issue/51462): We should rely on the append-make
   304  	// pattern so that the compiler can call runtime.growslice. For example:
   305  	//	return append(b, make([]byte, n)...)
   306  	// This avoids unnecessary zero-ing of the first len(b) bytes of the
   307  	// allocated slice, but this pattern causes b to escape onto the heap.
   308  	//
   309  	// Instead use the append-make pattern with a nil slice to ensure that
   310  	// we allocate buffers rounded up to the closest size class.
   311  	//
   312  	// ensure enough space for n elements
   313  	// The growth rate has historically always been 2x. In the future,
   314  	// we could rely purely on append to determine the growth rate.
   315  	c := max(len(b)+n, 2*cap(b))
   316  	b2 := append([]byte(nil), make([]byte, c)...)
   317  	copy(b2, b)
   318  	return b2[:len(b)]
   319  }
   320  
   321  // grow the buffer to guarantee space for n more bytes.
   322  // It returns the index where bytes should be written.
   323  // If the buffer can't grow it will panic with ErrTooLarge.
   324  func (bw *BufferWriter) grow(n int) int {
   325  	m := bw.Len()
   326  	// Try to grow by means of a reslice.
   327  	if i, ok := bw.tryGrowByReslice(n); ok {
   328  		return i
   329  	}
   330  	if *bw == nil && n <= smallBufferSize {
   331  		*bw = make([]byte, n, smallBufferSize)
   332  		return 0
   333  	}
   334  	c := cap(*bw)
   335  	if c > maxInt-c-n {
   336  		panic(bytes.ErrTooLarge)
   337  	} else if n > c/2-m {
   338  		// Add b.off to account for *b[:b.off] being sliced off the front.
   339  		*bw = growSlice((*bw)[:], n)
   340  	}
   341  	// Restore b.off and len(b.buf).
   342  	*bw = (*bw)[:m+n]
   343  	return m
   344  }
   345  
   346  func (bw *BufferWriter) Grow(n int) int {
   347  	m, ok := bw.tryGrowByReslice(n)
   348  	if !ok {
   349  		m = bw.grow(n)
   350  	}
   351  	return m
   352  }
   353  
   354  func (bw *BufferWriter) next(n int) []byte {
   355  	m := bw.Grow(n)
   356  	return (*bw)[m : m+n]
   357  }
   358  
   359  func (bw *BufferWriter) PutUint8(v uint8) {
   360  	m := bw.Grow(1)
   361  	(*bw)[m] = v
   362  }
   363  
   364  func (bw *BufferWriter) PutUint16(v uint16) {
   365  	binary.NativeEndian.PutUint16(bw.next(2), v)
   366  }
   367  
   368  func (bw *BufferWriter) PutUint32(v uint32) {
   369  	binary.NativeEndian.PutUint32(bw.next(4), v)
   370  }
   371  
   372  func (bw *BufferWriter) PutUint64(v uint64) {
   373  	binary.NativeEndian.PutUint64(bw.next(8), v)
   374  }
   375  
   376  func (bw *BufferWriter) PutUint16be(v uint16) {
   377  	binary.BigEndian.PutUint16(bw.next(2), v)
   378  }
   379  
   380  func (bw *BufferWriter) PutUint32be(v uint32) {
   381  	binary.BigEndian.PutUint32(bw.next(4), v)
   382  }
   383  
   384  func (bw *BufferWriter) PutUint64be(v uint64) {
   385  	binary.BigEndian.PutUint64(bw.next(8), v)
   386  }
   387  
   388  func (bw *BufferWriter) PutUvarint(v uint64) {
   389  	n := binary.MaxVarintLen64
   390  	m := bw.Grow(n)
   391  
   392  	n = binary.PutUvarint((*bw)[m:], v)
   393  	*bw = (*bw)[:m+n]
   394  }
   395  
   396  func (bw *BufferWriter) PutVarint(v int64) {
   397  	n := binary.MaxVarintLen64
   398  	m := bw.Grow(n)
   399  
   400  	n = binary.PutVarint((*bw)[m:], v)
   401  	*bw = (*bw)[:m+n]
   402  }
   403  
   404  func (bw *BufferWriter) PutSlice(p []byte) {
   405  	copy(bw.next(len(p)), p)
   406  }
   407  
   408  func (bw *BufferWriter) PutIPv4(ip net.IP) {
   409  	copy(bw.next(4), ip.To4())
   410  }
   411  
   412  func (bw *BufferWriter) PutIPv6(ip net.IP) {
   413  	copy(bw.next(16), ip.To16())
   414  }
   415  
   416  func (bw *BufferWriter) PutNetIPv4(addr netip.Addr) {
   417  	bw.PutIPv4(addr.AsSlice())
   418  }
   419  
   420  func (bw *BufferWriter) PutNetIPv6(addr netip.Addr) {
   421  	bw.PutIPv6(addr.AsSlice())
   422  }
   423  
   424  func (bw *BufferWriter) PutString(s string) {
   425  	copy(bw.next(len(s)), s)
   426  }
   427  
   428  func (bw *BufferWriter) PutRune(r rune) {
   429  	// Compare as uint32 to correctly handle negative runes.
   430  	if uint32(r) < utf8.RuneSelf {
   431  		bw.PutUint8(byte(r))
   432  		return
   433  	}
   434  	m := bw.Grow(utf8.UTFMax)
   435  	*bw = utf8.AppendRune((*bw)[:m], r)
   436  }
   437  
   438  func (bw *BufferWriter) ReadFull(r io.Reader, n int) error {
   439  	l := bw.Len()
   440  	_, err := io.ReadFull(r, bw.next(n))
   441  	if err != nil {
   442  		*bw = (*bw)[:l]
   443  	}
   444  	return err
   445  }
   446  
   447  func (bw *BufferWriter) WriteTo(w io.Writer) (n int64, err error) {
   448  	if nBytes := bw.Len(); nBytes > 0 {
   449  		m, e := w.Write((*bw)[:])
   450  		if m > nBytes {
   451  			panic("bytes.Buffer.WriteTo: invalid Write count")
   452  		}
   453  		n = int64(m)
   454  		if e != nil {
   455  			return n, e
   456  		}
   457  		// all bytes should have been written, by definition of
   458  		// Write method in io.Writer
   459  		if m != nBytes {
   460  			return n, io.ErrShortWrite
   461  		}
   462  	}
   463  	// Buffer is now empty; reset.
   464  	bw.Reset()
   465  	return n, nil
   466  }
   467  
   468  func (bw *BufferWriter) Slice(begin, end int) BufferWriter {
   469  	w := (*bw)[begin:end]
   470  	w.Reset()
   471  	return w
   472  }
   473  
   474  func (bw *BufferWriter) Truncate(n int) *BufferWriter {
   475  	*bw = (*bw)[:n]
   476  	return bw
   477  }
   478  
   479  func (bw *BufferWriter) Write(p []byte) (n int, err error) {
   480  	n = len(p)
   481  	bw.PutSlice(p)
   482  	return
   483  }
   484  
   485  func (bw *BufferWriter) Bytes() []byte {
   486  	return (*bw)[:]
   487  }
   488  
   489  func (bw *BufferWriter) String() string {
   490  	return string((*bw)[:])
   491  }
   492  
   493  func (bw *BufferWriter) Reset() {
   494  	*bw = (*bw)[:0]
   495  }