mihomo/common/net/bufconn.go

107 lines
2.1 KiB
Go
Raw Permalink Normal View History

2021-06-15 17:13:40 +08:00
package net
import (
"bufio"
"net"
2023-01-16 09:42:03 +08:00
2023-11-03 21:01:45 +08:00
"github.com/metacubex/mihomo/common/buf"
)
var _ ExtendedConn = (*BufferedConn)(nil)
2023-01-16 09:42:03 +08:00
type BufferedConn struct {
r *bufio.Reader
ExtendedConn
peeked bool
}
func NewBufferedConn(c net.Conn) *BufferedConn {
2021-09-28 23:15:53 +08:00
if bc, ok := c.(*BufferedConn); ok {
return bc
}
return &BufferedConn{bufio.NewReader(c), NewExtendedConn(c), false}
}
2023-11-02 10:31:58 +08:00
func WarpConnWithBioReader(c net.Conn, br *bufio.Reader) net.Conn {
if br != nil && br.Buffered() > 0 {
if bc, ok := c.(*BufferedConn); ok && bc.r == br {
return bc
}
return &BufferedConn{br, NewExtendedConn(c), true}
}
return c
}
// Reader returns the internal bufio.Reader.
func (c *BufferedConn) Reader() *bufio.Reader {
return c.r
}
2023-02-25 19:41:01 +08:00
func (c *BufferedConn) ResetPeeked() {
c.peeked = false
}
func (c *BufferedConn) Peeked() bool {
return c.peeked
}
// Peek returns the next n bytes without advancing the reader.
func (c *BufferedConn) Peek(n int) ([]byte, error) {
c.peeked = true
return c.r.Peek(n)
}
func (c *BufferedConn) Discard(n int) (discarded int, err error) {
return c.r.Discard(n)
}
func (c *BufferedConn) Read(p []byte) (int, error) {
return c.r.Read(p)
}
func (c *BufferedConn) ReadByte() (byte, error) {
return c.r.ReadByte()
}
func (c *BufferedConn) UnreadByte() error {
return c.r.UnreadByte()
}
func (c *BufferedConn) Buffered() int {
return c.r.Buffered()
}
2023-01-16 09:42:03 +08:00
func (c *BufferedConn) ReadBuffer(buffer *buf.Buffer) (err error) {
if c.r != nil && c.r.Buffered() > 0 {
2023-01-16 09:42:03 +08:00
_, err = buffer.ReadOnceFrom(c.r)
return
}
return c.ExtendedConn.ReadBuffer(buffer)
}
func (c *BufferedConn) ReadCached() *buf.Buffer { // call in sing/common/bufio.Copy
if c.r != nil && c.r.Buffered() > 0 {
length := c.r.Buffered()
b, _ := c.r.Peek(length)
_, _ = c.r.Discard(length)
return buf.As(b)
}
c.r = nil // drop bufio.Reader to let gc can clean up its internal buf
return nil
}
2023-01-16 09:42:03 +08:00
func (c *BufferedConn) Upstream() any {
return c.ExtendedConn
}
func (c *BufferedConn) ReaderReplaceable() bool {
if c.r != nil && c.r.Buffered() > 0 {
return false
}
return true
}
func (c *BufferedConn) WriterReplaceable() bool {
return true
}