var ( // ErrSeekBeyondBound is returned when a seek is requested beyond the // statically-given file-size. No writes or seeks beyond boundaries are // supported with a statically-given file size. ErrSeekBeyondBound = errors.New("seek beyond boundary") )
func CalculateSeek(currentOffset int64, delta int64, whence int, fileSize int64) (finalOffset int64, err error)
CalculateSeek calculates an offset in a file-stream given the parameters.
func CopyBytesBetweenPositions(rws io.ReadWriteSeeker, fromPosition, toPosition int64, count int) (n int, err error)
CopyBytesBetweenPositions will copy bytes from one position in the given RWS to an earlier position in the same RWS.
func DoesExist(filepath string) bool
DoesExist returns true if we can open the given file/path without error. We can't simply use `os.IsNotExist()` because we'll get a different error when the parent directory doesn't exist, and really the only important thing is if it exists *and* it's readable.
func GetOffset(s io.Seeker) int64
GetOffset returns the current offset of the Seeker and just panics if unable to find it.
func GracefulCopy(w io.Writer, r io.Reader, buffer []byte) (copyCount int, err error)
GracefulCopy willcopy while enduring lesser normal issues.
func ListFiles(rootPath string, cb FileListFilterPredicate) (filesC chan VisitedFile, count int, errC chan error)
ListFiles feeds a continuous list of files from a recursive folder scan. An optional predicate can be provided in order to filter. When done, the `filesC` channel is closed. If there's an error, the `errC` channel will receive it.
func NewReadProgressWrapper(r io.Reader, progressCb ProgressFunc) io.Reader
NewReadProgressWrapper returns a new RPW instance.
func NewWriteProgressWrapper(w io.Writer, progressCb ProgressFunc) io.Writer
NewWriteProgressWrapper returns a new WPW instance.
BouncebackReader wraps a ReadSeeker, keeps track of our position, and seeks back to it before writing. This allows an underlying ReadWriteSeeker with an unstable position can still be used for a prolonged series of writes.
type BouncebackReader struct {
// contains filtered or unexported fields
}
func NewBouncebackReader(rs io.ReadSeeker) (br *BouncebackReader, err error)
NewBouncebackReader returns a `*BouncebackReader` struct.
func (bb *BouncebackReader) Position() int64
Position returns the position that we're supposed to be at.
func (br *BouncebackReader) Read(p []byte) (n int, err error)
Seek does a standard read.
func (br *BouncebackReader) Seek(offset int64, whence int) (newPosition int64, err error)
Seek does a seek to an arbitrary place in the `io.ReadSeeker`.
func (bb *BouncebackReader) StatsReads() int
StatsReads returns the number of reads that have been attempted.
func (bb *BouncebackReader) StatsSeeks() int
StatsSeeks returns the number of seeks.
func (bb *BouncebackReader) StatsSyncs() int
StatsSyncs returns the number of corrective seeks ("bounce-backs").
func (bb *BouncebackReader) StatsWrites() int
StatsWrites returns the number of write operations.
BouncebackStats describes operation counts.
type BouncebackStats struct {
// contains filtered or unexported fields
}
func (bbs BouncebackStats) String() string
BouncebackWriter wraps a WriteSeeker, keeps track of our position, and seeks back to it before writing. This allows an underlying ReadWriteSeeker with an unstable position can still be used for a prolonged series of writes.
type BouncebackWriter struct {
// contains filtered or unexported fields
}
func NewBouncebackWriter(ws io.WriteSeeker) (bw *BouncebackWriter, err error)
NewBouncebackWriter returns a new `BouncebackWriter` struct.
func (bb *BouncebackWriter) Position() int64
Position returns the position that we're supposed to be at.
func (bw *BouncebackWriter) Seek(offset int64, whence int) (newPosition int64, err error)
Seek puts us at a specific position in the internal writer for the next write/seek.
func (bb *BouncebackWriter) StatsReads() int
StatsReads returns the number of reads that have been attempted.
func (bb *BouncebackWriter) StatsSeeks() int
StatsSeeks returns the number of seeks.
func (bb *BouncebackWriter) StatsSyncs() int
StatsSyncs returns the number of corrective seeks ("bounce-backs").
func (bb *BouncebackWriter) StatsWrites() int
StatsWrites returns the number of write operations.
func (bw *BouncebackWriter) Write(p []byte) (n int, err error)
Write performs a write against the internal `WriteSeeker` starting at the position that we're supposed to be at.
BoundedReadWriteSeekCloser wraps a RWS that is also a closer with boundaries. This proxies the RWS methods to the inner BRWS inside.
type BoundedReadWriteSeekCloser struct { io.Closer *BoundedReadWriteSeeker }
func NewBoundedReadWriteSeekCloser(rwsc ReadWriteSeekCloser, minimumOffset int64, staticFileSize int64) (brwsc *BoundedReadWriteSeekCloser, err error)
NewBoundedReadWriteSeekCloser returns a new BoundedReadWriteSeekCloser.
func (rwsc *BoundedReadWriteSeekCloser) Close() (err error)
Close forwards calls to the inner RWS.
func (rwsc *BoundedReadWriteSeekCloser) Read(buffer []byte) (readCount int, err error)
Read forwards calls to the inner RWS.
func (rwsc *BoundedReadWriteSeekCloser) Seek(offset int64, whence int) (newOffset int64, err error)
Seek forwards calls to the inner RWS.
func (rwsc *BoundedReadWriteSeekCloser) Write(buffer []byte) (writtenCount int, err error)
Write forwards calls to the inner RWS.
BoundedReadWriteSeeker is a thin filter that ensures that no seeks can be done to offsets smaller than the one we were given. This supports libraries that might be expecting to read from the front of the stream being used on data that is in the middle of a stream instead.
type BoundedReadWriteSeeker struct { io.ReadWriteSeeker // contains filtered or unexported fields }
func NewBoundedReadWriteSeeker(rws io.ReadWriteSeeker, minimumOffset int64, staticFileSize int64) (brws *BoundedReadWriteSeeker, err error)
NewBoundedReadWriteSeeker returns a new BoundedReadWriteSeeker instance.
func (brws *BoundedReadWriteSeeker) MinimumOffset() int64
MinimumOffset returns the configured minimum-offset.
func (brws *BoundedReadWriteSeeker) Read(buffer []byte) (readCount int, err error)
Read forwards writes to the inner RWS.
func (brws *BoundedReadWriteSeeker) Seek(offset int64, whence int) (updatedOffset int64, err error)
Seek moves the offset to the given offset. Prevents offset from ever being moved left of `brws.minimumOffset`.
func (brws *BoundedReadWriteSeeker) Write(buffer []byte) (writtenCount int, err error)
Write forwards writes to the inner RWS.
FileListFilterPredicate is the callback predicate used for filtering.
type FileListFilterPredicate func(parent string, child os.FileInfo) (hit bool, err error)
ProgressFunc receives progress updates.
type ProgressFunc func(n int, duration time.Duration, isEof bool) error
ReadCounter proxies read requests and maintains a counter of bytes read.
type ReadCounter struct {
// contains filtered or unexported fields
}
func NewReadCounter(r io.Reader) *ReadCounter
NewReadCounter returns a new `ReadCounter` struct wrapping a `Reader`.
func (rc *ReadCounter) Count() int
Count returns the total number of bytes read.
func (rc *ReadCounter) Read(b []byte) (n int, err error)
Read forwards a read to the underlying `Reader` while bumping the counter.
func (rc *ReadCounter) Reset()
Reset resets the counter to zero.
ReadProgressWrapper wraps a reader and calls a callback after each read with count and duration info.
type ReadProgressWrapper struct {
// contains filtered or unexported fields
}
func (rpw *ReadProgressWrapper) Read(buffer []byte) (n int, err error)
Read reads data and calls the callback.
ReadSeekerToReaderAt is a wrapper that allows a ReadSeeker to masquerade as a ReaderAt.
type ReadSeekerToReaderAt struct {
// contains filtered or unexported fields
}
func NewReadSeekerToReaderAt(rs io.ReadSeeker) *ReadSeekerToReaderAt
NewReadSeekerToReaderAt returns a new ReadSeekerToReaderAt instance.
func (rstra *ReadSeekerToReaderAt) ReadAt(p []byte, offset int64) (n int, err error)
ReadAt is a wrapper that satisfies the ReaderAt interface.
Note that a requirement of ReadAt is that it doesn't have an effect on the offset in the underlying resource as well as that concurrent calls can be made to it. Since we're capturing the current offset in the underlying resource and then seeking back to it before returning, it is the responsibility of the caller to serialize (i.e. use a mutex with) these requests in order to eliminate race-conditions in the parallel-usage scenario.
Note also that, since ReadAt() is going to be called on a particular instance, that instance is going to internalize a file resource, that file- resource is provided by the OS, and [most] OSs are only gonna support one file-position per resource, locking is already going to be a necessary internal semantic of a ReaderAt implementation.
ReadWriteSeekCloser satisfies `io.ReadWriteSeeker` and `io.Closer` interfaces.
type ReadWriteSeekCloser interface { io.ReadWriteSeeker io.Closer }
func ReadWriteSeekNoopCloser(rws io.ReadWriteSeeker) ReadWriteSeekCloser
ReadWriteSeekNoopCloser wraps a `io.ReadWriteSeeker` with a no-op Close() call.
SeekType is a convenience type to associate the different seek-types with printable descriptions.
type SeekType int
func (n SeekType) String() string
String returns a descriptive string.
SeekableBuffer is a simple memory structure that satisfies `io.ReadWriteSeeker`.
type SeekableBuffer struct {
// contains filtered or unexported fields
}
func NewSeekableBuffer() *SeekableBuffer
NewSeekableBuffer is a factory that returns a `*SeekableBuffer`.
func NewSeekableBufferWithBytes(originalData []byte) *SeekableBuffer
NewSeekableBufferWithBytes is a factory that returns a `*SeekableBuffer`.
func (sb *SeekableBuffer) Bytes() []byte
Bytes returns the underlying slice.
func (sb *SeekableBuffer) Len() int
Len returns the number of bytes currently stored.
func (sb *SeekableBuffer) Read(p []byte) (n int, err error)
Read does a standard read against the internal slice.
func (sb *SeekableBuffer) Seek(offset int64, whence int) (n int64, err error)
Seek does a standard seek on the internal slice.
func (sb *SeekableBuffer) Truncate(size int64) (err error)
Truncate either chops or extends the internal buffer.
func (sb *SeekableBuffer) Write(p []byte) (n int, err error)
Write does a standard write to the internal slice.
SimpleFileInfo is a simple `os.FileInfo` implementation useful for testing with the bare minimum.
type SimpleFileInfo struct {
// contains filtered or unexported fields
}
func NewSimpleFileInfoWithDirectory(filename string, modTime time.Time) *SimpleFileInfo
NewSimpleFileInfoWithDirectory returns a new directory-specific SimpleFileInfo.
func NewSimpleFileInfoWithFile(filename string, size int64, mode os.FileMode, modTime time.Time) *SimpleFileInfo
NewSimpleFileInfoWithFile returns a new file-specific SimpleFileInfo.
func (sfi *SimpleFileInfo) IsDir() bool
IsDir returns true if a directory.
func (sfi *SimpleFileInfo) ModTime() time.Time
ModTime returns the modification time.
func (sfi *SimpleFileInfo) Mode() os.FileMode
Mode returns the file mode bits.
func (sfi *SimpleFileInfo) Name() string
Name returns the base name of the file.
func (sfi *SimpleFileInfo) Size() int64
Size returns the length in bytes for regular files; system-dependent for others.
func (sfi *SimpleFileInfo) Sys() interface{}
Sys returns internal state.
VisitedFile is one visited file.
type VisitedFile struct { Filepath string Info os.FileInfo Index int }
WriteCounter proxies write requests and maintains a counter of bytes written.
type WriteCounter struct {
// contains filtered or unexported fields
}
func NewWriteCounter(w io.Writer) *WriteCounter
NewWriteCounter returns a new `WriteCounter` struct wrapping a `Writer`.
func (wc *WriteCounter) Count() int
Count returns the total number of bytes read.
func (wc *WriteCounter) Reset()
Reset resets the counter to zero.
func (wc *WriteCounter) Write(b []byte) (n int, err error)
Write forwards a write to the underlying `Writer` while bumping the counter.
WriteProgressWrapper wraps a reader and calls a callback after each read with count and duration info.
type WriteProgressWrapper struct {
// contains filtered or unexported fields
}
func (wpw *WriteProgressWrapper) Write(buffer []byte) (n int, err error)
Write does a write and calls the callback.