github.com/sagernet/sing@v0.2.6/common/bufio/io.go (about)

     1  package bufio
     2  
     3  import (
     4  	"io"
     5  	"net"
     6  
     7  	"github.com/sagernet/sing/common"
     8  	"github.com/sagernet/sing/common/buf"
     9  	M "github.com/sagernet/sing/common/metadata"
    10  	N "github.com/sagernet/sing/common/network"
    11  )
    12  
    13  // Deprecated: bad usage
    14  func ReadBuffer(reader N.ExtendedReader, buffer *buf.Buffer) (n int, err error) {
    15  	n, err = reader.Read(buffer.FreeBytes())
    16  	buffer.Truncate(n)
    17  	return
    18  }
    19  
    20  // Deprecated: bad usage
    21  func ReadPacket(reader N.PacketReader, buffer *buf.Buffer) (n int, addr net.Addr, err error) {
    22  	startLen := buffer.Len()
    23  	addr, err = reader.ReadPacket(buffer)
    24  	n = buffer.Len() - startLen
    25  	return
    26  }
    27  
    28  func Write(writer io.Writer, data []byte) (n int, err error) {
    29  	if extendedWriter, isExtended := writer.(N.ExtendedWriter); isExtended {
    30  		return WriteBuffer(extendedWriter, buf.As(data))
    31  	} else {
    32  		return writer.Write(data)
    33  	}
    34  }
    35  
    36  func WriteBuffer(writer N.ExtendedWriter, buffer *buf.Buffer) (n int, err error) {
    37  	frontHeadroom := N.CalculateFrontHeadroom(writer)
    38  	rearHeadroom := N.CalculateRearHeadroom(writer)
    39  	if frontHeadroom > buffer.Start() || rearHeadroom > buffer.FreeLen() {
    40  		bufferSize := N.CalculateMTU(nil, writer)
    41  		if bufferSize > 0 {
    42  			bufferSize += frontHeadroom + rearHeadroom
    43  		} else {
    44  			bufferSize = buf.BufferSize
    45  		}
    46  		newBuffer := buf.NewSize(bufferSize)
    47  		newBuffer.Resize(frontHeadroom, 0)
    48  		common.Must1(newBuffer.Write(buffer.Bytes()))
    49  		buffer.Release()
    50  		buffer = newBuffer
    51  	}
    52  	dataLen := buffer.Len()
    53  	err = writer.WriteBuffer(buffer)
    54  	if err == nil {
    55  		n = dataLen
    56  	}
    57  	return
    58  }
    59  
    60  func WritePacket(writer N.NetPacketWriter, data []byte, addr net.Addr) (n int, err error) {
    61  	if extendedWriter, isExtended := writer.(N.PacketWriter); isExtended {
    62  		return WritePacketBuffer(extendedWriter, buf.As(data), M.SocksaddrFromNet(addr))
    63  	} else {
    64  		return writer.WriteTo(data, addr)
    65  	}
    66  }
    67  
    68  func WritePacketBuffer(writer N.PacketWriter, buffer *buf.Buffer, destination M.Socksaddr) (n int, err error) {
    69  	frontHeadroom := N.CalculateFrontHeadroom(writer)
    70  	rearHeadroom := N.CalculateRearHeadroom(writer)
    71  	if frontHeadroom > buffer.Start() || rearHeadroom > buffer.FreeLen() {
    72  		bufferSize := N.CalculateMTU(nil, writer)
    73  		if bufferSize > 0 {
    74  			bufferSize += frontHeadroom + rearHeadroom
    75  		} else {
    76  			bufferSize = buf.BufferSize
    77  		}
    78  		newBuffer := buf.NewSize(bufferSize)
    79  		newBuffer.Resize(frontHeadroom, 0)
    80  		common.Must1(newBuffer.Write(buffer.Bytes()))
    81  		buffer.Release()
    82  		buffer = newBuffer
    83  	}
    84  	dataLen := buffer.Len()
    85  	err = writer.WritePacket(buffer, destination)
    86  	if err == nil {
    87  		n = dataLen
    88  	}
    89  	return
    90  }
    91  
    92  func WriteVectorised(writer N.VectorisedWriter, data [][]byte) (n int, err error) {
    93  	var dataLen int
    94  	buffers := make([]*buf.Buffer, 0, len(data))
    95  	for _, p := range data {
    96  		dataLen += len(p)
    97  		buffers = append(buffers, buf.As(p))
    98  	}
    99  	err = writer.WriteVectorised(buffers)
   100  	if err == nil {
   101  		n = dataLen
   102  	}
   103  	return
   104  }
   105  
   106  func WriteVectorisedPacket(writer N.VectorisedPacketWriter, data [][]byte, destination M.Socksaddr) (n int, err error) {
   107  	var dataLen int
   108  	buffers := make([]*buf.Buffer, 0, len(data))
   109  	for _, p := range data {
   110  		dataLen += len(p)
   111  		buffers = append(buffers, buf.As(p))
   112  	}
   113  	err = writer.WriteVectorisedPacket(buffers, destination)
   114  	if err == nil {
   115  		n = dataLen
   116  	}
   117  	return
   118  }