diff --git a/common/buf/reader.go b/common/buf/reader.go index dbc96844..6b08d40c 100644 --- a/common/buf/reader.go +++ b/common/buf/reader.go @@ -24,7 +24,8 @@ func readOneUDP(r io.Reader) (*Buffer, error) { return nil, newError("Reader returns too many empty payloads.") } -func readOne(r io.Reader) (*Buffer, error) { +// ReadBuffer reads a Buffer from the given reader, without allocating large buffer in advance. +func ReadBuffer(r io.Reader) (*Buffer, error) { // Use an one-byte buffer to wait for incoming payload. var firstByte [1]byte nBytes, err := r.Read(firstByte[:]) @@ -163,7 +164,7 @@ type SingleReader struct { // ReadMultiBuffer implements Reader. func (r *SingleReader) ReadMultiBuffer() (MultiBuffer, error) { - b, err := readOne(r.Reader) + b, err := ReadBuffer(r.Reader) if err != nil { return nil, err } diff --git a/common/buf/readv_reader.go b/common/buf/readv_reader.go index cf3bd49b..66e03c27 100644 --- a/common/buf/readv_reader.go +++ b/common/buf/readv_reader.go @@ -119,7 +119,7 @@ func (r *ReadVReader) readMulti() (MultiBuffer, error) { // ReadMultiBuffer implements Reader. func (r *ReadVReader) ReadMultiBuffer() (MultiBuffer, error) { if r.alloc.Current() == 1 { - b, err := readOne(r.Reader) + b, err := ReadBuffer(r.Reader) if err != nil { return nil, err } diff --git a/transport/internet/quic/conn.go b/transport/internet/quic/conn.go index 5123414e..631954f3 100644 --- a/transport/internet/quic/conn.go +++ b/transport/internet/quic/conn.go @@ -150,17 +150,14 @@ func (c *interConn) Read(b []byte) (int, error) { } func (c *interConn) ReadMultiBuffer() (buf.MultiBuffer, error) { - const BufferCount = 16 - mb := make(buf.MultiBuffer, 0, BufferCount) - { - b := buf.New() - if _, err := b.ReadFrom(c.stream); err != nil { - b.Release() - return nil, err - } - mb = append(mb, b) + firstBuffer, err := buf.ReadBuffer(c) + if err != nil { + return nil, err } + const BufferCount = 16 + mb := make(buf.MultiBuffer, 0, BufferCount) + mb = append(mb, firstBuffer) for len(mb) < BufferCount && c.stream.HasMoreData() { b := buf.New() if _, err := b.ReadFrom(c.stream); err != nil {