diff --git a/iox/docs.go b/iox/docs.go new file mode 100644 index 0000000..a1c3bf1 --- /dev/null +++ b/iox/docs.go @@ -0,0 +1,4 @@ +/* +Package iox includes extensions to the stdlib `io` module. +*/ +package iox diff --git a/iox/errs.go b/iox/errs.go new file mode 100644 index 0000000..659357c --- /dev/null +++ b/iox/errs.go @@ -0,0 +1,9 @@ +package iox + +import ( + `errors` +) + +var ( + ErrBufTooSmall error = errors.New("buffer too small; buffer size must be > 0") +) diff --git a/iox/funcs.go b/iox/funcs.go new file mode 100644 index 0000000..9104c48 --- /dev/null +++ b/iox/funcs.go @@ -0,0 +1,41 @@ +package iox + +import ( + `io` +) + +/* +CopyBufN is a mix between io.CopyN and io.CopyBuffer. + +Despite what the docs may suggest, io.CopyN does NOT *read* n bytes from src AND write n bytes to dst. +Instead, it always reads 32 KiB from src, and writes n bytes to dst. + +There are, of course, cases where this is deadfully undesired. + +One can, of course, use io.CopyBuffer, but this is a bit annoying since you then have to provide a buffer yourself. + +This convenience-wraps io.CopyBuffer to have a similar signature to io.CopyN but properly uses n for both reading and writing. +*/ +func CopyBufN(dst io.Writer, src io.Reader, n int64) (written int64, err error) { + + var b []byte + + if n <= 0 { + err = ErrBufTooSmall + return + } + + b = make([]byte, n) + + written, err = io.CopyBuffer(dst, src, b) + + return +} + +// CopyBufWith allows for specifying a buffer allocator function, otherwise acts as CopyBufN. +func CopyBufWith(dst io.Writer, src io.Reader, bufFunc func() (b []byte)) (written int64, err error) { + + written, err = io.CopyBuffer(dst, src, bufFunc()) + + return +} diff --git a/iox/types.go b/iox/types.go new file mode 100644 index 0000000..7f92ca1 --- /dev/null +++ b/iox/types.go @@ -0,0 +1,8 @@ +package iox + +type ( + // RuneWriter matches the behavior of *(bytes.Buffer).WriteRune and *(bufio.Writer).WriteRune + RuneWriter interface { + WriteRune(r rune) (n int, err error) + } +) diff --git a/logging/doc.go b/logging/doc.go index 951b351..2943d08 100644 --- a/logging/doc.go +++ b/logging/doc.go @@ -57,7 +57,7 @@ In addition. all have a ToRaw() method, which extends a Logger even further and - io.WriteCloser (Shutdown() on the Logger backend is called during Close(), rendering the underlying Logger unsafe to use afterwards) - io.StringWriter -and, if stdlib io ever defines an e.g. RuneWriter (WriteRune(r rune) (n int, err error)), it will conform to that too. +and, if stdlib io ever defines an e.g. RuneWriter (WriteRune(r rune) (n int, err error)), it will conform to that too (see (r00t2.io/goutils/iox).RuneWriter). Obviously this and io.ByteWriter are fairly silly, as they're intended to be high-speed throughput-optimized methods, but if you wanted to e.g. log every single byte on a wire as a separate log message, go ahead; I'm not your dad. */