Skip to content

Commit a794174

Browse files
deadprogrambgould
authored andcommitted
net: add back Buffers implementation which got lost along the way to the switchover to this package
Signed-off-by: deadprogram <ron@hybridgroup.com>
1 parent fcee4f5 commit a794174

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

net.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package net
88

99
import (
1010
"errors"
11+
"io"
1112
"time"
1213
)
1314

@@ -318,3 +319,77 @@ var errClosed = errNetClosing{}
318319
// in another error, and should normally be tested using
319320
// errors.Is(err, net.ErrClosed).
320321
var ErrClosed error = errClosed
322+
323+
// buffersWriter is the interface implemented by Conns that support a
324+
// "writev"-like batch write optimization.
325+
// writeBuffers should fully consume and write all chunks from the
326+
// provided Buffers, else it should report a non-nil error.
327+
type buffersWriter interface {
328+
writeBuffers(*Buffers) (int64, error)
329+
}
330+
331+
// Buffers contains zero or more runs of bytes to write.
332+
//
333+
// On certain machines, for certain types of connections, this is
334+
// optimized into an OS-specific batch write operation (such as
335+
// "writev").
336+
type Buffers [][]byte
337+
338+
var (
339+
_ io.WriterTo = (*Buffers)(nil)
340+
_ io.Reader = (*Buffers)(nil)
341+
)
342+
343+
// WriteTo writes contents of the buffers to w.
344+
//
345+
// WriteTo implements [io.WriterTo] for [Buffers].
346+
//
347+
// WriteTo modifies the slice v as well as v[i] for 0 <= i < len(v),
348+
// but does not modify v[i][j] for any i, j.
349+
func (v *Buffers) WriteTo(w io.Writer) (n int64, err error) {
350+
if wv, ok := w.(buffersWriter); ok {
351+
return wv.writeBuffers(v)
352+
}
353+
for _, b := range *v {
354+
nb, err := w.Write(b)
355+
n += int64(nb)
356+
if err != nil {
357+
v.consume(n)
358+
return n, err
359+
}
360+
}
361+
v.consume(n)
362+
return n, nil
363+
}
364+
365+
// Read from the buffers.
366+
//
367+
// Read implements [io.Reader] for [Buffers].
368+
//
369+
// Read modifies the slice v as well as v[i] for 0 <= i < len(v),
370+
// but does not modify v[i][j] for any i, j.
371+
func (v *Buffers) Read(p []byte) (n int, err error) {
372+
for len(p) > 0 && len(*v) > 0 {
373+
n0 := copy(p, (*v)[0])
374+
v.consume(int64(n0))
375+
p = p[n0:]
376+
n += n0
377+
}
378+
if len(*v) == 0 {
379+
err = io.EOF
380+
}
381+
return
382+
}
383+
384+
func (v *Buffers) consume(n int64) {
385+
for len(*v) > 0 {
386+
ln0 := int64(len((*v)[0]))
387+
if ln0 > n {
388+
(*v)[0] = (*v)[0][n:]
389+
return
390+
}
391+
n -= ln0
392+
(*v)[0] = nil
393+
*v = (*v)[1:]
394+
}
395+
}

0 commit comments

Comments
 (0)