|  | @@ -3,9 +3,6 @@ package buf
 | 
	
		
			
				|  |  |  import (
 | 
	
		
			
				|  |  |  	"io"
 | 
	
		
			
				|  |  |  	"time"
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	"v2ray.com/core/common/errors"
 | 
	
		
			
				|  |  | -	"v2ray.com/core/common/signal"
 | 
	
		
			
				|  |  |  )
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // Reader extends io.Reader with alloc.Buffer.
 | 
	
	
		
			
				|  | @@ -47,91 +44,6 @@ func ReadAtLeastFrom(reader io.Reader, size int) Supplier {
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -type copyHandler struct {
 | 
	
		
			
				|  |  | -	onReadError  func(error) error
 | 
	
		
			
				|  |  | -	onData       func()
 | 
	
		
			
				|  |  | -	onWriteError func(error) error
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func (h *copyHandler) readFrom(reader Reader) (MultiBuffer, error) {
 | 
	
		
			
				|  |  | -	mb, err := reader.Read()
 | 
	
		
			
				|  |  | -	if err != nil && h.onReadError != nil {
 | 
	
		
			
				|  |  | -		err = h.onReadError(err)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return mb, err
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func (h *copyHandler) writeTo(writer Writer, mb MultiBuffer) error {
 | 
	
		
			
				|  |  | -	err := writer.Write(mb)
 | 
	
		
			
				|  |  | -	if err != nil && h.onWriteError != nil {
 | 
	
		
			
				|  |  | -		err = h.onWriteError(err)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return err
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -type CopyOption func(*copyHandler)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func IgnoreReaderError() CopyOption {
 | 
	
		
			
				|  |  | -	return func(handler *copyHandler) {
 | 
	
		
			
				|  |  | -		handler.onReadError = func(err error) error {
 | 
	
		
			
				|  |  | -			return nil
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func IgnoreWriterError() CopyOption {
 | 
	
		
			
				|  |  | -	return func(handler *copyHandler) {
 | 
	
		
			
				|  |  | -		handler.onWriteError = func(err error) error {
 | 
	
		
			
				|  |  | -			return nil
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func UpdateActivity(timer signal.ActivityTimer) CopyOption {
 | 
	
		
			
				|  |  | -	return func(handler *copyHandler) {
 | 
	
		
			
				|  |  | -		handler.onData = func() {
 | 
	
		
			
				|  |  | -			timer.Update()
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -func copyInternal(reader Reader, writer Writer, handler *copyHandler) error {
 | 
	
		
			
				|  |  | -	for {
 | 
	
		
			
				|  |  | -		buffer, err := handler.readFrom(reader)
 | 
	
		
			
				|  |  | -		if err != nil {
 | 
	
		
			
				|  |  | -			return err
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		if buffer.IsEmpty() {
 | 
	
		
			
				|  |  | -			buffer.Release()
 | 
	
		
			
				|  |  | -			continue
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		if handler.onData != nil {
 | 
	
		
			
				|  |  | -			handler.onData()
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		if err := handler.writeTo(writer, buffer); err != nil {
 | 
	
		
			
				|  |  | -			buffer.Release()
 | 
	
		
			
				|  |  | -			return err
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -// Copy dumps all payload from reader to writer or stops when an error occurs.
 | 
	
		
			
				|  |  | -// ActivityTimer gets updated as soon as there is a payload.
 | 
	
		
			
				|  |  | -func Copy(reader Reader, writer Writer, options ...CopyOption) error {
 | 
	
		
			
				|  |  | -	handler := new(copyHandler)
 | 
	
		
			
				|  |  | -	for _, option := range options {
 | 
	
		
			
				|  |  | -		option(handler)
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	err := copyInternal(reader, writer, handler)
 | 
	
		
			
				|  |  | -	if err != nil && errors.Cause(err) != io.EOF {
 | 
	
		
			
				|  |  | -		return err
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return nil
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  // NewReader creates a new Reader.
 | 
	
		
			
				|  |  |  // The Reader instance doesn't take the ownership of reader.
 | 
	
		
			
				|  |  |  func NewReader(reader io.Reader) Reader {
 |