mirror of
https://github.com/SagerNet/sing.git
synced 2025-04-05 12:57:38 +03:00
Refine buffered reader
This commit is contained in:
parent
857116b2cc
commit
82cc7d29b8
2 changed files with 34 additions and 1 deletions
|
@ -29,6 +29,10 @@ func (r *BufferedReader) Read(p []byte) (n int, err error) {
|
||||||
return r.buffer.Read(p)
|
return r.buffer.Read(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *BufferedReader) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
|
return CopyExtendedBuffer(NewExtendedWriter(w), NewExtendedReader(r.upstream), r.buffer)
|
||||||
|
}
|
||||||
|
|
||||||
func (w *BufferedReader) Upstream() any {
|
func (w *BufferedReader) Upstream() any {
|
||||||
return w.upstream
|
return w.upstream
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
|
@ -14,6 +15,27 @@ import (
|
||||||
"github.com/sagernet/sing/common/task"
|
"github.com/sagernet/sing/common/task"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type readOnlyReader struct {
|
||||||
|
io.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *readOnlyReader) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
|
return Copy(w, r.Reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
func needReadFromWrapper(dst io.ReaderFrom, src io.Reader) bool {
|
||||||
|
_, isTCPConn := dst.(*net.TCPConn)
|
||||||
|
if !isTCPConn {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
switch src.(type) {
|
||||||
|
case *net.TCPConn, *net.UnixConn, *os.File:
|
||||||
|
return false
|
||||||
|
default:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Copy(dst io.Writer, src io.Reader) (n int64, err error) {
|
func Copy(dst io.Writer, src io.Reader) (n int64, err error) {
|
||||||
src = N.UnwrapReader(src)
|
src = N.UnwrapReader(src)
|
||||||
dst = N.UnwrapWriter(dst)
|
dst = N.UnwrapWriter(dst)
|
||||||
|
@ -21,6 +43,9 @@ func Copy(dst io.Writer, src io.Reader) (n int64, err error) {
|
||||||
return wt.WriteTo(dst)
|
return wt.WriteTo(dst)
|
||||||
}
|
}
|
||||||
if rt, ok := dst.(io.ReaderFrom); ok {
|
if rt, ok := dst.(io.ReaderFrom); ok {
|
||||||
|
if needReadFromWrapper(rt, src) {
|
||||||
|
src = &readOnlyReader{src}
|
||||||
|
}
|
||||||
return rt.ReadFrom(src)
|
return rt.ReadFrom(src)
|
||||||
}
|
}
|
||||||
return CopyExtended(NewExtendedWriter(dst), NewExtendedReader(src))
|
return CopyExtended(NewExtendedWriter(dst), NewExtendedReader(src))
|
||||||
|
@ -37,7 +62,11 @@ func CopyExtended(dst N.ExtendedWriter, src N.ExtendedReader) (n int64, err erro
|
||||||
|
|
||||||
_buffer := buf.StackNew()
|
_buffer := buf.StackNew()
|
||||||
defer common.KeepAlive(_buffer)
|
defer common.KeepAlive(_buffer)
|
||||||
buffer := common.Dup(_buffer)
|
|
||||||
|
return CopyExtendedBuffer(dst, src, common.Dup(_buffer))
|
||||||
|
}
|
||||||
|
|
||||||
|
func CopyExtendedBuffer(dst N.ExtendedWriter, src N.ExtendedReader, buffer *buf.Buffer) (n int64, err error) {
|
||||||
buffer.IncRef()
|
buffer.IncRef()
|
||||||
defer buffer.DecRef()
|
defer buffer.DecRef()
|
||||||
for {
|
for {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue