89 lines
2.6 KiB
Go
89 lines
2.6 KiB
Go
package ctxio
|
|
|
|
// // CopyN copies n bytes (or until an error) from src to dst.
|
|
// // It returns the number of bytes copied and the earliest
|
|
// // error encountered while copying.
|
|
// // On return, written == n if and only if err == nil.
|
|
// //
|
|
// // If dst implements [ReaderFrom], the copy is implemented using it.
|
|
// func CopyN(ctx context.Context, dst Writer, src Reader, n int64) (written int64, err error) {
|
|
// written, err = Copy(ctx, dst, LimitReader(src, n))
|
|
// if written == n {
|
|
// return n, nil
|
|
// }
|
|
// if written < n && err == nil {
|
|
// // src stopped early; must have been EOF.
|
|
// err = io.EOF
|
|
// }
|
|
|
|
// return
|
|
// }
|
|
|
|
// // Copy copies from src to dst until either EOF is reached
|
|
// // on src or an error occurs. It returns the number of bytes
|
|
// // copied and the first error encountered while copying, if any.
|
|
// //
|
|
// // A successful Copy returns err == nil, not err == EOF.
|
|
// // Because Copy is defined to read from src until EOF, it does
|
|
// // not treat an EOF from Read as an error to be reported.
|
|
// //
|
|
// // If src implements [WriterTo],
|
|
// // the copy is implemented by calling src.WriteTo(dst).
|
|
// // Otherwise, if dst implements [ReaderFrom],
|
|
// // the copy is implemented by calling dst.ReadFrom(src).
|
|
// func Copy(ctx context.Context, dst Writer, src Reader) (written int64, err error) {
|
|
// return copyBuffer(ctx, dst, src, nil)
|
|
// }
|
|
|
|
// // copyBuffer is the actual implementation of Copy and CopyBuffer.
|
|
// // if buf is nil, one is allocated.
|
|
// func copyBuffer(ctx context.Context, dst Writer, src Reader, buf []byte) (written int64, err error) {
|
|
// // If the reader has a WriteTo method, use it to do the copy.
|
|
// // Avoids an allocation and a copy.
|
|
// if wt, ok := src.(WriterTo); ok {
|
|
// return wt.WriteTo(dst)
|
|
// }
|
|
// // Similarly, if the writer has a ReadFrom method, use it to do the copy.
|
|
// if rt, ok := dst.(ReaderFrom); ok {
|
|
// return rt.ReadFrom(src)
|
|
// }
|
|
// if buf == nil {
|
|
// size := 32 * 1024
|
|
// if l, ok := src.(*LimitedReader); ok && int64(size) > l.N {
|
|
// if l.N < 1 {
|
|
// size = 1
|
|
// } else {
|
|
// size = int(l.N)
|
|
// }
|
|
// }
|
|
// buf = make([]byte, size)
|
|
// }
|
|
// for {
|
|
// nr, er := src.Read(ctx, buf)
|
|
// if nr > 0 {
|
|
// nw, ew := dst.Write(ctx, buf[0:nr])
|
|
// if nw < 0 || nr < nw {
|
|
// nw = 0
|
|
// if ew == nil {
|
|
// ew = errInvalidWrite
|
|
// }
|
|
// }
|
|
// written += int64(nw)
|
|
// if ew != nil {
|
|
// err = ew
|
|
// break
|
|
// }
|
|
// if nr != nw {
|
|
// err = io.ErrShortWrite
|
|
// break
|
|
// }
|
|
// }
|
|
// if er != nil {
|
|
// if er != io.EOF {
|
|
// err = er
|
|
// }
|
|
// break
|
|
// }
|
|
// }
|
|
// return written, err
|
|
// }
|