github.com/kelleygo/clashcore@v1.0.2/common/net/bufconn.go (about)

     1  package net
     2  
     3  import (
     4  	"bufio"
     5  	"net"
     6  
     7  	"github.com/kelleygo/clashcore/common/buf"
     8  )
     9  
    10  var _ ExtendedConn = (*BufferedConn)(nil)
    11  
    12  type BufferedConn struct {
    13  	r *bufio.Reader
    14  	ExtendedConn
    15  	peeked bool
    16  }
    17  
    18  func NewBufferedConn(c net.Conn) *BufferedConn {
    19  	if bc, ok := c.(*BufferedConn); ok {
    20  		return bc
    21  	}
    22  	return &BufferedConn{bufio.NewReader(c), NewExtendedConn(c), false}
    23  }
    24  
    25  func WarpConnWithBioReader(c net.Conn, br *bufio.Reader) net.Conn {
    26  	if br != nil && br.Buffered() > 0 {
    27  		if bc, ok := c.(*BufferedConn); ok && bc.r == br {
    28  			return bc
    29  		}
    30  		return &BufferedConn{br, NewExtendedConn(c), true}
    31  	}
    32  	return c
    33  }
    34  
    35  // Reader returns the internal bufio.Reader.
    36  func (c *BufferedConn) Reader() *bufio.Reader {
    37  	return c.r
    38  }
    39  
    40  func (c *BufferedConn) ResetPeeked() {
    41  	c.peeked = false
    42  }
    43  
    44  func (c *BufferedConn) Peeked() bool {
    45  	return c.peeked
    46  }
    47  
    48  // Peek returns the next n bytes without advancing the reader.
    49  func (c *BufferedConn) Peek(n int) ([]byte, error) {
    50  	c.peeked = true
    51  	return c.r.Peek(n)
    52  }
    53  
    54  func (c *BufferedConn) Discard(n int) (discarded int, err error) {
    55  	return c.r.Discard(n)
    56  }
    57  
    58  func (c *BufferedConn) Read(p []byte) (int, error) {
    59  	return c.r.Read(p)
    60  }
    61  
    62  func (c *BufferedConn) ReadByte() (byte, error) {
    63  	return c.r.ReadByte()
    64  }
    65  
    66  func (c *BufferedConn) UnreadByte() error {
    67  	return c.r.UnreadByte()
    68  }
    69  
    70  func (c *BufferedConn) Buffered() int {
    71  	return c.r.Buffered()
    72  }
    73  
    74  func (c *BufferedConn) ReadBuffer(buffer *buf.Buffer) (err error) {
    75  	if c.r != nil && c.r.Buffered() > 0 {
    76  		_, err = buffer.ReadOnceFrom(c.r)
    77  		return
    78  	}
    79  	return c.ExtendedConn.ReadBuffer(buffer)
    80  }
    81  
    82  func (c *BufferedConn) ReadCached() *buf.Buffer { // call in sing/common/bufio.Copy
    83  	if c.r != nil && c.r.Buffered() > 0 {
    84  		length := c.r.Buffered()
    85  		b, _ := c.r.Peek(length)
    86  		_, _ = c.r.Discard(length)
    87  		return buf.As(b)
    88  	}
    89  	c.r = nil // drop bufio.Reader to let gc can clean up its internal buf
    90  	return nil
    91  }
    92  
    93  func (c *BufferedConn) Upstream() any {
    94  	return c.ExtendedConn
    95  }
    96  
    97  func (c *BufferedConn) ReaderReplaceable() bool {
    98  	if c.r != nil && c.r.Buffered() > 0 {
    99  		return false
   100  	}
   101  	return true
   102  }
   103  
   104  func (c *BufferedConn) WriterReplaceable() bool {
   105  	return true
   106  }