github.com/sagernet/sing@v0.4.0-beta.19.0.20240518125136-f67a0988a636/common/buf/buffer.go (about)

     1  package buf
     2  
     3  import (
     4  	"crypto/rand"
     5  	"io"
     6  	"net"
     7  
     8  	"github.com/sagernet/sing/common"
     9  	"github.com/sagernet/sing/common/atomic"
    10  	"github.com/sagernet/sing/common/debug"
    11  	E "github.com/sagernet/sing/common/exceptions"
    12  	F "github.com/sagernet/sing/common/format"
    13  )
    14  
    15  type Buffer struct {
    16  	data     []byte
    17  	start    int
    18  	end      int
    19  	capacity int
    20  	refs     atomic.Int32
    21  	managed  bool
    22  }
    23  
    24  func New() *Buffer {
    25  	return &Buffer{
    26  		data:     Get(BufferSize),
    27  		capacity: BufferSize,
    28  		managed:  true,
    29  	}
    30  }
    31  
    32  func NewPacket() *Buffer {
    33  	return &Buffer{
    34  		data:     Get(UDPBufferSize),
    35  		capacity: UDPBufferSize,
    36  		managed:  true,
    37  	}
    38  }
    39  
    40  func NewSize(size int) *Buffer {
    41  	if size == 0 {
    42  		return &Buffer{}
    43  	} else if size > 65535 {
    44  		return &Buffer{
    45  			data:     make([]byte, size),
    46  			capacity: size,
    47  		}
    48  	}
    49  	return &Buffer{
    50  		data:     Get(size),
    51  		capacity: size,
    52  		managed:  true,
    53  	}
    54  }
    55  
    56  func As(data []byte) *Buffer {
    57  	return &Buffer{
    58  		data:     data,
    59  		end:      len(data),
    60  		capacity: len(data),
    61  	}
    62  }
    63  
    64  func With(data []byte) *Buffer {
    65  	return &Buffer{
    66  		data:     data,
    67  		capacity: len(data),
    68  	}
    69  }
    70  
    71  func (b *Buffer) Byte(index int) byte {
    72  	return b.data[b.start+index]
    73  }
    74  
    75  func (b *Buffer) SetByte(index int, value byte) {
    76  	b.data[b.start+index] = value
    77  }
    78  
    79  func (b *Buffer) Extend(n int) []byte {
    80  	end := b.end + n
    81  	if end > b.capacity {
    82  		panic(F.ToString("buffer overflow: capacity ", b.capacity, ",end ", b.end, ", need ", n))
    83  	}
    84  	ext := b.data[b.end:end]
    85  	b.end = end
    86  	return ext
    87  }
    88  
    89  func (b *Buffer) Advance(from int) {
    90  	b.start += from
    91  }
    92  
    93  func (b *Buffer) Truncate(to int) {
    94  	b.end = b.start + to
    95  }
    96  
    97  func (b *Buffer) Write(data []byte) (n int, err error) {
    98  	if len(data) == 0 {
    99  		return
   100  	}
   101  	if b.IsFull() {
   102  		return 0, io.ErrShortBuffer
   103  	}
   104  	n = copy(b.data[b.end:b.capacity], data)
   105  	b.end += n
   106  	return
   107  }
   108  
   109  func (b *Buffer) ExtendHeader(n int) []byte {
   110  	if b.start < n {
   111  		panic(F.ToString("buffer overflow: capacity ", b.capacity, ",start ", b.start, ", need ", n))
   112  	}
   113  	b.start -= n
   114  	return b.data[b.start : b.start+n]
   115  }
   116  
   117  func (b *Buffer) WriteRandom(size int) []byte {
   118  	buffer := b.Extend(size)
   119  	common.Must1(io.ReadFull(rand.Reader, buffer))
   120  	return buffer
   121  }
   122  
   123  func (b *Buffer) WriteByte(d byte) error {
   124  	if b.IsFull() {
   125  		return io.ErrShortBuffer
   126  	}
   127  	b.data[b.end] = d
   128  	b.end++
   129  	return nil
   130  }
   131  
   132  func (b *Buffer) ReadOnceFrom(r io.Reader) (int, error) {
   133  	if b.IsFull() {
   134  		return 0, io.ErrShortBuffer
   135  	}
   136  	n, err := r.Read(b.FreeBytes())
   137  	b.end += n
   138  	return n, err
   139  }
   140  
   141  func (b *Buffer) ReadPacketFrom(r net.PacketConn) (int64, net.Addr, error) {
   142  	if b.IsFull() {
   143  		return 0, nil, io.ErrShortBuffer
   144  	}
   145  	n, addr, err := r.ReadFrom(b.FreeBytes())
   146  	b.end += n
   147  	return int64(n), addr, err
   148  }
   149  
   150  func (b *Buffer) ReadAtLeastFrom(r io.Reader, min int) (int64, error) {
   151  	if min <= 0 {
   152  		n, err := b.ReadOnceFrom(r)
   153  		return int64(n), err
   154  	}
   155  	if b.IsFull() {
   156  		return 0, io.ErrShortBuffer
   157  	}
   158  	n, err := io.ReadAtLeast(r, b.FreeBytes(), min)
   159  	b.end += n
   160  	return int64(n), err
   161  }
   162  
   163  func (b *Buffer) ReadFullFrom(r io.Reader, size int) (n int, err error) {
   164  	if b.end+size > b.capacity {
   165  		return 0, io.ErrShortBuffer
   166  	}
   167  	n, err = io.ReadFull(r, b.data[b.end:b.end+size])
   168  	b.end += n
   169  	return
   170  }
   171  
   172  func (b *Buffer) ReadFrom(reader io.Reader) (n int64, err error) {
   173  	for {
   174  		if b.IsFull() {
   175  			return 0, io.ErrShortBuffer
   176  		}
   177  		var readN int
   178  		readN, err = reader.Read(b.FreeBytes())
   179  		b.end += readN
   180  		n += int64(readN)
   181  		if err != nil {
   182  			if E.IsMulti(err, io.EOF) {
   183  				err = nil
   184  			}
   185  			return
   186  		}
   187  	}
   188  }
   189  
   190  func (b *Buffer) WriteRune(s rune) (int, error) {
   191  	return b.Write([]byte{byte(s)})
   192  }
   193  
   194  func (b *Buffer) WriteString(s string) (n int, err error) {
   195  	if len(s) == 0 {
   196  		return
   197  	}
   198  	if b.IsFull() {
   199  		return 0, io.ErrShortBuffer
   200  	}
   201  	n = copy(b.data[b.end:b.capacity], s)
   202  	b.end += n
   203  	return
   204  }
   205  
   206  func (b *Buffer) WriteZero() error {
   207  	if b.IsFull() {
   208  		return io.ErrShortBuffer
   209  	}
   210  	b.data[b.end] = 0
   211  	b.end++
   212  	return nil
   213  }
   214  
   215  func (b *Buffer) WriteZeroN(n int) error {
   216  	if b.end+n > b.capacity {
   217  		return io.ErrShortBuffer
   218  	}
   219  	common.ClearArray(b.Extend(n))
   220  	return nil
   221  }
   222  
   223  func (b *Buffer) ReadByte() (byte, error) {
   224  	if b.IsEmpty() {
   225  		return 0, io.EOF
   226  	}
   227  
   228  	nb := b.data[b.start]
   229  	b.start++
   230  	return nb, nil
   231  }
   232  
   233  func (b *Buffer) ReadBytes(n int) ([]byte, error) {
   234  	if b.end-b.start < n {
   235  		return nil, io.EOF
   236  	}
   237  
   238  	nb := b.data[b.start : b.start+n]
   239  	b.start += n
   240  	return nb, nil
   241  }
   242  
   243  func (b *Buffer) Read(data []byte) (n int, err error) {
   244  	if b.IsEmpty() {
   245  		return 0, io.EOF
   246  	}
   247  	n = copy(data, b.data[b.start:b.end])
   248  	b.start += n
   249  	return
   250  }
   251  
   252  func (b *Buffer) WriteTo(w io.Writer) (int64, error) {
   253  	n, err := w.Write(b.Bytes())
   254  	return int64(n), err
   255  }
   256  
   257  func (b *Buffer) Resize(start, end int) {
   258  	b.start = start
   259  	b.end = b.start + end
   260  }
   261  
   262  func (b *Buffer) Reserve(n int) {
   263  	if n > b.capacity {
   264  		panic(F.ToString("buffer overflow: capacity ", b.capacity, ", need ", n))
   265  	}
   266  	b.capacity -= n
   267  }
   268  
   269  func (b *Buffer) OverCap(n int) {
   270  	if b.capacity+n > len(b.data) {
   271  		panic(F.ToString("buffer overflow: capacity ", len(b.data), ", need ", b.capacity+n))
   272  	}
   273  	b.capacity += n
   274  }
   275  
   276  func (b *Buffer) Reset() {
   277  	b.start = 0
   278  	b.end = 0
   279  	b.capacity = len(b.data)
   280  }
   281  
   282  // Deprecated: use Reset instead.
   283  func (b *Buffer) FullReset() {
   284  	b.Reset()
   285  }
   286  
   287  func (b *Buffer) IncRef() {
   288  	b.refs.Add(1)
   289  }
   290  
   291  func (b *Buffer) DecRef() {
   292  	b.refs.Add(-1)
   293  }
   294  
   295  func (b *Buffer) Release() {
   296  	if b == nil || !b.managed {
   297  		return
   298  	}
   299  	if b.refs.Load() > 0 {
   300  		return
   301  	}
   302  	common.Must(Put(b.data))
   303  	*b = Buffer{}
   304  }
   305  
   306  func (b *Buffer) Leak() {
   307  	if debug.Enabled {
   308  		if b == nil || !b.managed {
   309  			return
   310  		}
   311  		refs := b.refs.Load()
   312  		if refs == 0 {
   313  			panic("leaking buffer")
   314  		} else {
   315  			panic(F.ToString("leaking buffer with ", refs, " references"))
   316  		}
   317  	} else {
   318  		b.Release()
   319  	}
   320  }
   321  
   322  func (b *Buffer) Start() int {
   323  	return b.start
   324  }
   325  
   326  func (b *Buffer) Len() int {
   327  	return b.end - b.start
   328  }
   329  
   330  func (b *Buffer) Cap() int {
   331  	return b.capacity
   332  }
   333  
   334  func (b *Buffer) RawCap() int {
   335  	return len(b.data)
   336  }
   337  
   338  func (b *Buffer) Bytes() []byte {
   339  	return b.data[b.start:b.end]
   340  }
   341  
   342  func (b *Buffer) From(n int) []byte {
   343  	return b.data[b.start+n : b.end]
   344  }
   345  
   346  func (b *Buffer) To(n int) []byte {
   347  	return b.data[b.start : b.start+n]
   348  }
   349  
   350  func (b *Buffer) Range(start, end int) []byte {
   351  	return b.data[b.start+start : b.start+end]
   352  }
   353  
   354  func (b *Buffer) Index(start int) []byte {
   355  	return b.data[b.start+start : b.start+start]
   356  }
   357  
   358  func (b *Buffer) FreeLen() int {
   359  	return b.capacity - b.end
   360  }
   361  
   362  func (b *Buffer) FreeBytes() []byte {
   363  	return b.data[b.end:b.capacity]
   364  }
   365  
   366  func (b *Buffer) IsEmpty() bool {
   367  	return b.end-b.start == 0
   368  }
   369  
   370  func (b *Buffer) IsFull() bool {
   371  	return b.end == b.capacity
   372  }
   373  
   374  func (b *Buffer) ToOwned() *Buffer {
   375  	n := NewSize(len(b.data))
   376  	copy(n.data[b.start:b.end], b.data[b.start:b.end])
   377  	n.start = b.start
   378  	n.end = b.end
   379  	n.capacity = b.capacity
   380  	return n
   381  }