Documentation ¶
Index ¶
- Constants
- func NewlineCounter(ior io.Reader) (int, error)
- func NopCloseReader(ior io.Reader) io.ReadCloser
- func NopCloseWriter(iow io.Writer) io.WriteCloser
- func ReadAllThenClose(rc io.ReadCloser) ([]byte, error)
- func ShortWriteCloser(iowc io.WriteCloser, max int) io.WriteCloser
- func ShortWriter(w io.Writer, max int) io.Writer
- func SlowReader(r io.Reader, d time.Duration) io.Reader
- func SlowWriter(w io.Writer, d time.Duration) io.Writer
- type ErrList
- type ErrReadAfterClose
- type ErrTimeout
- type ErrWriteAfterClose
- type EscrowReader
- type FilesReader
- type LineTerminatedReader
- type LockingWriteCloser
- type MultiWriteCloserFanIn
- type MultiWriteCloserFanOut
- func (mwc *MultiWriteCloserFanOut) Add(w io.WriteCloser) int
- func (mwc *MultiWriteCloserFanOut) Close() error
- func (mwc *MultiWriteCloserFanOut) Count() int
- func (mwc *MultiWriteCloserFanOut) IsEmpty() bool
- func (mwc *MultiWriteCloserFanOut) Remove(w io.WriteCloser) int
- func (mwc *MultiWriteCloserFanOut) Write(data []byte) (int, error)
- type NopCloseBuffer
- type ShortReadWriteCloser
- type ShortReadWriter
- type SpooledWriteCloser
- type SpooledWriteCloserSetter
- type TimedReadCloser
- type TimedWriteCloser
Constants ¶
const DefaultBufSize = 4096
DefaultBufSize is the default size of the underlying bufio.Writer buffer.
const DefaultFlushPeriod = 15 * time.Second
DefaultFlushPeriod is the default frequency of buffer flushes.
Variables ¶
This section is empty.
Functions ¶
func NewlineCounter ¶ added in v1.9.0
NewlineCounter counts the number of lines from the io.Reader, returning the same number of lines read regardless of whether the final Read terminated in a newline character.
func NopCloseReader ¶
func NopCloseReader(ior io.Reader) io.ReadCloser
NopCloseReader returns a structure that implements io.ReadCloser, but provides a no-op Close method. It is useful when you have an io.Reader that you must pass to a method that requires an io.ReadCloser. It is the same as ioutil.NopCloser, but for provided here for symmetry with NopCloseWriter.
iorc := gorill.NopCloseReader(ior) iorc.Close() // does nothing
func NopCloseWriter ¶
func NopCloseWriter(iow io.Writer) io.WriteCloser
NopCloseWriter returns a structure that implements io.WriteCloser, but provides a no-op Close method. It is useful when you have an io.Writer that you must pass to a method that requires an io.WriteCloser. It is the counter-part to ioutil.NopCloser, but for io.Writer.
iowc := gorill.NopCloseWriter(iow) iowc.Close() // does nothing
func ReadAllThenClose ¶ added in v1.8.0
func ReadAllThenClose(rc io.ReadCloser) ([]byte, error)
ReadAllThenClose reads all bytes from rc then closes it. It returns any errors that occurred when either reading or closing rc.
func ShortWriteCloser ¶
func ShortWriteCloser(iowc io.WriteCloser, max int) io.WriteCloser
ShortWriteCloser returns a structure that wraps an io.WriteCloser, but returns io.ErrShortWrite when the number of bytes to write exceeds a preset limit.
bb := gorill.NopCloseBuffer() sw := gorill.ShortWriteCloser(bb, 16) n, err := sw.Write([]byte("short write")) // n == 11, err == nil n, err := sw.Write([]byte("a somewhat longer write")) // n == 16, err == io.ErrShortWrite
func ShortWriter ¶
ShortWriter returns a structure that wraps an io.Writer, but returns io.ErrShortWrite when the number of bytes to write exceeds a preset limit.
bb := gorill.NopCloseBuffer() sw := gorill.ShortWriter(bb, 16) n, err := sw.Write([]byte("short write")) // n == 11, err == nil n, err := sw.Write([]byte("a somewhat longer write")) // n == 16, err == io.ErrShortWrite
func SlowReader ¶
SlowReader returns a structure that wraps an io.Reader, but sleeps prior to writing data to the underlying io.Reader.
bb := gorill.NopCloseBuffer() sr := gorill.SlowReader(bb, 10*time.Second) buf := make([]byte, 1000) n, err := sr.Read(buf) // this call takes at least 10 seconds to return // n == 7, err == nil
func SlowWriter ¶
SlowWriter returns a structure that wraps an io.Writer, but sleeps prior to writing data to the underlying io.Writer.
bb := gorill.NopCloseBuffer() sw := gorill.SlowWriter(bb, 10*time.Second) n, err := sw.Write([]byte("example")) // this call takes at least 10 seconds to return // n == 7, err == nil
Types ¶
type ErrList ¶
type ErrList []error
ErrList is a slice of errors, useful when a function must return a single error, but has multiple independent errors to return.
type ErrReadAfterClose ¶
type ErrReadAfterClose struct{}
ErrReadAfterClose is returned if a Read is attempted after Close called.
func (ErrReadAfterClose) Error ¶
func (e ErrReadAfterClose) Error() string
Error returns a string representation of a ErrReadAfterClose error instance.
type ErrTimeout ¶
ErrTimeout error is returned whenever a Write operation exceeds the preset timeout period. Even after a timeout takes place, the write may still independantly complete.
func (ErrTimeout) Error ¶
func (e ErrTimeout) Error() string
Error returns a string representing the ErrTimeout.
type ErrWriteAfterClose ¶
type ErrWriteAfterClose struct{}
ErrWriteAfterClose is returned if a Write is attempted after Close called.
func (ErrWriteAfterClose) Error ¶
func (e ErrWriteAfterClose) Error() string
Error returns a string representation of a ErrWriteAfterClose error instance.
type EscrowReader ¶ added in v1.4.0
type EscrowReader struct {
// contains filtered or unexported fields
}
EscrowReader is a structure that mimics the io.ReadCloser interface, yet already has all the payload bytes stored in memory along with any read error that took place while reading the payload. The benefit of using it is that other code may re-read the payload without an additional penalty, as the bytes are already buffered in memory.
func NewEscrowReader ¶ added in v1.4.0
func NewEscrowReader(iorc io.ReadCloser, bb *bytes.Buffer) *EscrowReader
NewEscrowReader reads and consumes all the data from the specified io.ReadCloser into either a new bytes.Buffer or a specified bytes.Buffer, then returns an io.ReadCloser that allows the data to be read multiple times. It always closes the provided io.ReadCloser.
It does not return any errors during instantiation, because any read error encountered will be returned after the last byte is read from the provided io.ReadCloser. Likewise any close error will be returned by the structure's Close method.
func someHandler(w http.ResponseWriter, r *http.Request) { // Get a scratch buffer for the example. For production code, consider using // a free-list of buffers, such as https://github.com/karrick/gobp bb := new(bytes.Buffer) r.Body = NewEscrowReader(r.Body, bb) // ... }
func (*EscrowReader) Bytes ¶ added in v1.4.0
func (er *EscrowReader) Bytes() []byte
Bytes returns the slice of bytes read from the original data source.
func (*EscrowReader) Close ¶ added in v1.4.0
func (er *EscrowReader) Close() error
Close returns the error that took place when closing the original io.ReadCloser. Under normal circumstances it will be nil.
func (*EscrowReader) Err ¶ added in v1.10.0
func (er *EscrowReader) Err() error
Err returns the error encountered while reading from the source io.ReadCloser if not io.EOF; otherwise it returns the error encountered while closing it. This method comes in handy when you know you have an EscrowReader, and you want to know whether the entire payload was slurped in.
func example(iorc io.ReadCloser) ([]byte, error) { if er, ok := iorc.(*gorill.EscrowReader); ok { return er.Bytes(), er.Err() } }
func (*EscrowReader) Read ¶ added in v1.4.0
func (er *EscrowReader) Read(b []byte) (int, error)
Read reads up to len(p) bytes into p. It returns the number of bytes read (0 <= n <= len(p)) and any error encountered. Even if Read returns n < len(p), it may use all of p as scratch space during the call. If some data is available but not len(p) bytes, Read conventionally returns what is available instead of waiting for more.
When there are no more bytes to be read from the buffer, it will return any error encountered when reading the original io.ReadCloser data source. That error value is normally nil, but could be any other error other than io.EOF.
func (*EscrowReader) Reset ¶ added in v1.4.0
func (er *EscrowReader) Reset()
Reset will cause the next Read to read from the beginning of the buffer.
type FilesReader ¶ added in v1.2.0
type FilesReader struct { // Pathnames is a list of remaining files to read. It is kept up to date // where when a file is opened, its name is removed from the head of the // list. Pathnames []string // contains filtered or unexported fields }
FilesReader is an io.ReadCloser that can be used to read over the contents of all of the files specified by pathnames. It only opens a single file handle at a time. When reading from the currently open file handle returns io.EOF, it closes that file handle, and the next Read will cause the following file in the series to be opened and read from.
func (*FilesReader) Close ¶ added in v1.2.0
func (fr *FilesReader) Close() error
Close forgets the list of remaining files in the series, then closes the currently open file handle, returning any error from the operating system.
func (*FilesReader) Next ¶ added in v1.2.0
func (fr *FilesReader) Next() error
Next closes the currently open file handle and opens the next file in the series. If there are no files left it returns io.EOF. It can be used to skip the remaining contents of the currently open file. Additional Read operations will be invoked against the following file in the series, if non empty.
type LineTerminatedReader ¶ added in v1.7.0
LineTerminatedReader reads from the source io.Reader and ensures the final byte from this is a newline.
type LockingWriteCloser ¶
type LockingWriteCloser struct {
// contains filtered or unexported fields
}
LockingWriteCloser is an io.WriteCloser that allows only exclusive access to its Write and Close method.
func NewLockingWriteCloser ¶
func NewLockingWriteCloser(iowc io.WriteCloser) *LockingWriteCloser
NewLockingWriteCloser returns a LockingWriteCloser, that allows only exclusive access to its Write and Close method.
lwc := gorill.NewLockingWriteCloser(os.Stdout) for i := 0; i < 1000; i++ { go func(iow io.Writer, i int) { for j := 0; j < 100; j++ { _, err := iow.Write([]byte("Hello, World, from %d!\n", i)) if err != nil { return } } }(lwc, i) }
func (*LockingWriteCloser) Close ¶
func (lwc *LockingWriteCloser) Close() error
Close closes the underlying io.WriteCloser.
type MultiWriteCloserFanIn ¶
type MultiWriteCloserFanIn struct {
// contains filtered or unexported fields
}
MultiWriteCloserFanIn is a structure that provides multiple io.WriteClosers to write to same underlying io.WriteCloser. When the final io.WriteCloser that MultiWriteCloserFanIn provides is closed, then the underlying io.WriteCloser will be closed.
func NewMultiWriteCloserFanIn ¶
func NewMultiWriteCloserFanIn(iowc io.WriteCloser) *MultiWriteCloserFanIn
NewMultiWriteCloserFanIn creates a MultiWriteCloserFanIn instance where writes to any of the provided io.WriteCloser instances will be funneled to the underlying io.WriteCloser instance. The client ought to call Close on all provided io.WriteCloser instances, after which, MultiWriteCloserFanIn will close the underlying io.WriteCloser.
func Example(largeBuf []byte) { bb := NewNopCloseBufferSize(16384) first := NewMultiWriteCloserFanIn(bb) second := first.Add() first.Write(largeBuf) first.Close() second.Write(largeBuf) second.Close() }
func (*MultiWriteCloserFanIn) Add ¶
func (fanin *MultiWriteCloserFanIn) Add() *MultiWriteCloserFanIn
Add returns a new MultiWriteCloserFanIn that redirects all writes to the underlying io.WriteCloser. The client ought to call Close on the returned MultiWriteCloserFanIn to signify intent to no longer Write to the MultiWriteCloserFanIn.
func (*MultiWriteCloserFanIn) Close ¶
func (fanin *MultiWriteCloserFanIn) Close() error
Close marks the MultiWriteCloserFanIn as finished. The last Close method invoked for a group of MultiWriteCloserFanIn instances will trigger a close of the underlying io.WriteCloser.
type MultiWriteCloserFanOut ¶
type MultiWriteCloserFanOut struct {
// contains filtered or unexported fields
}
MultiWriteCloserFanOut is a structure that allows additions to and removals from the list of io.WriteCloser objects that will be written to.
func NewMultiWriteCloserFanOut ¶
func NewMultiWriteCloserFanOut(writers ...io.WriteCloser) *MultiWriteCloserFanOut
NewMultiWriteCloserFanOut returns a MultiWriteCloserFanOut that is go-routine safe.
bb1 = gorill.NewNopCloseBuffer() bb2 = gorill.NewNopCloseBuffer() mw = gorill.NewMultiWriteCloserFanOut(bb1, bb2) n, err := mw.Write([]byte("blob")) if want := 4; n != want { t.Errorf("Actual: %#v; Expected: %#v", n, want) } if err != nil { t.Errorf("Actual: %#v; Expected: %#v", err, nil) } if want := "blob"; bb1.String() != want { t.Errorf("Actual: %#v; Expected: %#v", bb1.String(), want) } if want := "blob"; bb2.String() != want { t.Errorf("Actual: %#v; Expected: %#v", bb2.String(), want) }
func (*MultiWriteCloserFanOut) Add ¶
func (mwc *MultiWriteCloserFanOut) Add(w io.WriteCloser) int
Add adds an io.WriteCloser to the list of writers to be written to whenever this MultiWriteCloserFanOut is written to. It returns the number of io.WriteCloser instances attached to the MultiWriteCloserFanOut instance.
bb1 = gorill.NewNopCloseBuffer() mw = gorill.NewMultiWriteCloserFanOut(bb1) bb2 = gorill.NewNopCloseBuffer() mw.Add(bb2)
func (*MultiWriteCloserFanOut) Close ¶
func (mwc *MultiWriteCloserFanOut) Close() error
Close will close the underlying io.WriteCloser, and releases resources.
func (*MultiWriteCloserFanOut) Count ¶
func (mwc *MultiWriteCloserFanOut) Count() int
Count returns the number of io.WriteCloser instances attached to the MultiWriteCloserFanOut instance.
mw = gorill.NewMultiWriteCloserFanOut() count := mw.Count() // returns 1 mw.Add(gorill.NewNopCloseBuffer()) count = mw.Count() // returns 2
func (*MultiWriteCloserFanOut) IsEmpty ¶
func (mwc *MultiWriteCloserFanOut) IsEmpty() bool
IsEmpty returns true if and only if there are no writers in the list of writers to be written to.
mw = gorill.NewMultiWriteCloserFanOut() mw.IsEmpty() // returns true mw.Add(gorill.NewNopCloseBuffer()) mw.IsEmpty() // returns false
func (*MultiWriteCloserFanOut) Remove ¶
func (mwc *MultiWriteCloserFanOut) Remove(w io.WriteCloser) int
Remove removes an io.WriteCloser from the list of writers to be written to whenever this MultiWriteCloserFanOut is written to. It returns the number of io.WriteCloser instances attached to the MultiWriteCloserFanOut instance.
bb1 = gorill.NewNopCloseBuffer() bb2 = gorill.NewNopCloseBuffer() mw = gorill.NewMultiWriteCloserFanOut(bb1, bb2) remaining := mw.Remove(bb1) // returns 1
func (*MultiWriteCloserFanOut) Write ¶
func (mwc *MultiWriteCloserFanOut) Write(data []byte) (int, error)
Write writes the data to all the writers in the MultiWriteCloserFanOut. It removes and invokes Close method for all io.WriteClosers that returns an error when written to.
bb1 = gorill.NewNopCloseBuffer() bb2 = gorill.NewNopCloseBuffer() mw = gorill.NewMultiWriteCloserFanOut(bb1, bb2) n, err := mw.Write([]byte("blob")) if want := 4; n != want { t.Errorf("Actual: %#v; Expected: %#v", n, want) } if err != nil { t.Errorf("Actual: %#v; Expected: %#v", err, nil) }
type NopCloseBuffer ¶
NopCloseBuffer is a structure that wraps a buffer, but also provides a no-op Close method.
func NewNopCloseBuffer ¶
func NewNopCloseBuffer() *NopCloseBuffer
NewNopCloseBuffer returns a structure that wraps bytes.Buffer with a no-op Close method. It can be used in tests that need a bytes.Buffer, but need to provide a Close method.
bb := gorill.NopCloseBuffer() bb.Write([]byte("example")) bb.Close() // does nothing
func NewNopCloseBufferSize ¶
func NewNopCloseBufferSize(size int) *NopCloseBuffer
NewNopCloseBufferSize returns a structure that wraps bytes.Buffer with a no-op Close method, using a specified buffer size. It can be used in tests that need a bytes.Buffer, but need to provide a Close method.
bb := gorill.NopCloseBufferSize(8192) bb.Write([]byte("example")) bb.Close() // does nothing
func (*NopCloseBuffer) IsClosed ¶
func (m *NopCloseBuffer) IsClosed() bool
IsClosed returns false, unless NopCloseBuffer's Close method has been invoked
type ShortReadWriteCloser ¶
ShortReadWriteCloser wraps a io.ReadWriteCloser, but the Read and Write operations cannot exceed the MaxRead and MaxWrite sizes.
type ShortReadWriter ¶
ShortReadWriter wraps a io.Reader and io.Writer, but the Read and Write operations cannot exceed the MaxRead and MaxWrite sizes.
type SpooledWriteCloser ¶
type SpooledWriteCloser struct {
// contains filtered or unexported fields
}
SpooledWriteCloser spools bytes written to it through a bufio.Writer, periodically flushing data written to underlying io.WriteCloser.
func NewSpooledWriteCloser ¶
func NewSpooledWriteCloser(iowc io.WriteCloser, setters ...SpooledWriteCloserSetter) (*SpooledWriteCloser, error)
NewSpooledWriteCloser returns a SpooledWriteCloser that spools bytes written to it through a bufio.Writer, periodically forcing the bufio.Writer to flush its contents.
func (*SpooledWriteCloser) Close ¶
func (w *SpooledWriteCloser) Close() error
Close frees resources when a SpooledWriteCloser is no longer needed.
func (*SpooledWriteCloser) Flush ¶
func (w *SpooledWriteCloser) Flush() error
Flush causes all data not yet written to the output stream to be flushed.
type SpooledWriteCloserSetter ¶
type SpooledWriteCloserSetter func(*SpooledWriteCloser) error
SpooledWriteCloserSetter is any function that modifies a SpooledWriteCloser being instantiated.
func BufSize ¶
func BufSize(size int) SpooledWriteCloserSetter
BufSize is used to configure a new SpooledWriteCloser's buffer size.
func Flush ¶
func Flush(periodicity time.Duration) SpooledWriteCloserSetter
Flush is used to configure a new SpooledWriteCloser to periodically flush.
type TimedReadCloser ¶
type TimedReadCloser struct {
// contains filtered or unexported fields
}
TimedReadCloser is an io.Reader that enforces a preset timeout period on every Read operation.
func NewTimedReadCloser ¶
func NewTimedReadCloser(iowc io.ReadCloser, timeout time.Duration) *TimedReadCloser
NewTimedReadCloser returns a TimedReadCloser that enforces a preset timeout period on every Read operation. It panics when timeout is less than or equal to 0.
func (*TimedReadCloser) Close ¶
func (rc *TimedReadCloser) Close() error
Close frees resources when a SpooledReadCloser is no longer needed.
func (*TimedReadCloser) Read ¶
func (rc *TimedReadCloser) Read(data []byte) (int, error)
Read reads data to the underlying io.Reader, but returns ErrTimeout if the Read operation exceeds a preset timeout duration.
Even after a timeout takes place, the read may still independently complete as reads are queued from a different go-routine. Race condition for the data slice is prevented by reading into a temporary byte slice, and copying the results to the client's slice when the actual read returns.
type TimedWriteCloser ¶
type TimedWriteCloser struct {
// contains filtered or unexported fields
}
TimedWriteCloser is an io.Writer that enforces a preset timeout period on every Write operation.
func NewTimedWriteCloser ¶
func NewTimedWriteCloser(iowc io.WriteCloser, timeout time.Duration) *TimedWriteCloser
NewTimedWriteCloser returns a TimedWriteCloser that enforces a preset timeout period on every Write operation. It panics when timeout is less than or equal to 0.
func (*TimedWriteCloser) Close ¶
func (wc *TimedWriteCloser) Close() error
Close frees resources when a SpooledWriteCloser is no longer needed.
func (*TimedWriteCloser) Write ¶
func (wc *TimedWriteCloser) Write(data []byte) (int, error)
Write writes data to the underlying io.Writer, but returns ErrTimeout if the Write operation exceeds a preset timeout duration. Even after a timeout takes place, the write may still independantly complete as writes are queued from a different go routine.