Files
go_goutils/iox/funcs_ctxio.go
brent saner 145c32268e v1.14.0
ADDED:
* iox package
* mapsx package
* netx/inetcksum package
2025-12-18 04:47:31 -05:00

174 lines
3.1 KiB
Go

package iox
import (
`bytes`
`context`
`io`
`math`
)
func (c *CtxIO) Copy(dst io.Writer, src io.Reader) (written int64, err error) {
if c.l.chunkLen > math.MaxInt64 {
err = ErrChunkTooBig
}
return CopyCtxBufN(c.ctx, dst, src, int64(c.l.chunkLen))
}
func (c *CtxIO) CopyBufN(dst io.Writer, src io.Reader, n int64) (written int64, err error) {
if n <= 0 {
err = ErrBufTooSmall
return
}
return CopyCtxBufN(c.ctx, dst, src, n)
}
func (c *CtxIO) GetChunkLen() (size uint) {
return c.l.GetChunkLen()
}
func (c *CtxIO) Read(p []byte) (n int, err error) {
var nr int64
if nr, err = c.ReadWithContext(c.ctx, p); err != nil {
if nr > math.MaxInt {
n = math.MaxInt
} else {
n = int(nr)
}
return
}
if nr > math.MaxInt {
n = math.MaxInt
} else {
n = int(nr)
}
return
}
func (c *CtxIO) ReadWithContext(ctx context.Context, p []byte) (n int64, err error) {
var nr int
var off int
var buf []byte
if p == nil || len(p) == 0 {
return
}
if c.buf.Len() == 0 {
err = io.EOF
return
}
if c.l.chunkLen > uint(len(p)) {
// Would normally be a single chunk, so one-shot it.
nr, err = c.buf.Read(p)
n = int64(nr)
return
}
// Chunk over it.
endRead:
for {
select {
case <-ctx.Done():
err = ctx.Err()
return
default:
/*
off(set) is the index of the *next position* to write to.
Therefore the last offset == len(p),
therefore:
* if off == len(p), "done" (return no error, do *not* read from buf)
* if off + c.l.chunkLen > len(p), buf should be len(p) - off instead
*/
if off == len(p) {
break endRead
}
if uint(off)+c.l.chunkLen > uint(len(p)) {
buf = make([]byte, len(p)-off)
} else {
buf = make([]byte, c.l.chunkLen)
}
nr, err = c.buf.Read(buf)
n += int64(nr)
if nr > 0 {
off += nr
copy(p[off:], buf[:nr])
}
if err == io.EOF {
break endRead
} else if err != nil {
return
}
}
}
return
}
func (c *CtxIO) SetChunkLen(size uint) (err error) {
return c.l.SetChunkLen(size)
}
func (c *CtxIO) SetContext(ctx context.Context) (err error) {
if ctx == nil {
err = ErrNilCtx
return
}
c.ctx = ctx
return
}
func (c *CtxIO) Write(p []byte) (n int, err error) {
var nw int64
if c.l.chunkLen > math.MaxInt64 {
err = ErrChunkTooBig
return
}
if nw, err = c.WriteNWithContext(c.ctx, p, int64(c.l.chunkLen)); err != nil {
if nw > math.MaxInt {
n = math.MaxInt
} else {
n = int(nw)
}
return
}
if nw > math.MaxInt {
n = math.MaxInt
} else {
n = int(nw)
}
return
}
func (c *CtxIO) WriteNWithContext(ctx context.Context, p []byte, n int64) (written int64, err error) {
return CopyCtxBufN(ctx, &c.buf, bytes.NewReader(p), n)
}
func (c *CtxIO) WriteRune(r rune) (n int, err error) {
// We don't even bother listening for the ctx.Done because it's a single rune.
n, err = c.buf.WriteRune(r)
return
}
func (c *CtxIO) WriteWithContext(ctx context.Context, p []byte) (n int64, err error) {
if c.l.chunkLen > math.MaxInt64 {
err = ErrChunkTooBig
return
}
return CopyCtxBufN(ctx, &c.buf, bytes.NewReader(p), int64(c.l.chunkLen))
}