github.com/sagernet/sing@v0.2.6/common/buf/buffer.go (about)

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