@@ -14,6 +14,9 @@ import (
1414var (
1515 errNoPipe = errors .New ("pipe: src or dst nil" )
1616 errNoStream = errors .New ("stream: reader or writer nil" )
17+
18+ // errInvalidWrite means that a write returned an impossible count.
19+ errInvalidWrite = errors .New ("invalid write result" )
1720)
1821
1922// Pipe copies data from src to dst, and returns the number of bytes copied.
@@ -37,7 +40,7 @@ func Pipe(dst io.Writer, src io.Reader) (int64, error) {
3740// Stream reads data from src in to dst until error, and returns the no. of bytes read.
3841// Internally, it bypasses io.ReaderFrom and io.WriterTo but uses io.CopyBuffer,
3942// recycling buffers from a global pool.
40- func Stream (dst io.Writer , src io.Reader ) (int64 , error ) {
43+ func Stream (dst io.Writer , src io.Reader ) (written int64 , err error ) {
4144 if IsNil (src ) || IsNil (dst ) {
4245 return 0 , errNoStream
4346 }
@@ -52,13 +55,41 @@ func Stream(dst io.Writer, src io.Reader) (int64, error) {
5255 }
5356
5457 bptr := Alloc ()
55- b := * bptr
56- b = b [:cap (b )]
58+ buf := * bptr
59+ buf = buf [:cap (buf )]
5760 defer func () {
58- * bptr = b
61+ * bptr = buf
5962 Recycle (bptr )
6063 }()
61- return io .CopyBuffer (dst , src , b )
64+ // implementation from: io.CopyBuffer
65+ for {
66+ nr , er := src .Read (buf )
67+ if nr > 0 {
68+ nw , ew := dst .Write (buf [0 :nr ])
69+ if nw < 0 || nr < nw {
70+ nw = 0
71+ if ew == nil {
72+ ew = errInvalidWrite
73+ }
74+ }
75+ written += int64 (nw )
76+ if ew != nil {
77+ err = ew
78+ break
79+ }
80+ if nr != nw {
81+ err = io .ErrShortWrite
82+ break
83+ }
84+ }
85+ if er != nil {
86+ if er != io .EOF {
87+ err = er
88+ }
89+ break
90+ }
91+ }
92+ return written , err
6293}
6394
6495// ref: github.com/golang/go/issues/58808
0 commit comments