2016-01-23 22:41:55 +00:00
|
|
|
package backend
|
|
|
|
|
2016-08-29 17:18:57 +00:00
|
|
|
import (
|
|
|
|
"io"
|
2016-08-31 20:39:36 +00:00
|
|
|
"restic"
|
2016-08-29 17:18:57 +00:00
|
|
|
|
2016-09-01 20:17:37 +00:00
|
|
|
"restic/errors"
|
2016-08-29 17:18:57 +00:00
|
|
|
)
|
2016-02-04 18:37:33 +00:00
|
|
|
|
2016-01-23 22:41:55 +00:00
|
|
|
// LoadAll reads all data stored in the backend for the handle. The buffer buf
|
2016-02-04 18:37:33 +00:00
|
|
|
// is resized to accomodate all data in the blob. Errors returned by be.Load()
|
|
|
|
// are passed on, except io.ErrUnexpectedEOF is silenced and nil returned
|
|
|
|
// instead, since it means this function is working properly.
|
2016-08-31 20:39:36 +00:00
|
|
|
func LoadAll(be restic.Backend, h restic.Handle, buf []byte) ([]byte, error) {
|
2016-01-23 22:41:55 +00:00
|
|
|
fi, err := be.Stat(h)
|
|
|
|
if err != nil {
|
2016-08-29 19:54:50 +00:00
|
|
|
return nil, errors.Wrap(err, "Stat")
|
2016-01-23 22:41:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if fi.Size > int64(len(buf)) {
|
|
|
|
buf = make([]byte, int(fi.Size))
|
|
|
|
}
|
|
|
|
|
|
|
|
n, err := be.Load(h, buf, 0)
|
2016-08-29 17:18:57 +00:00
|
|
|
if errors.Cause(err) == io.ErrUnexpectedEOF {
|
2016-02-04 18:37:33 +00:00
|
|
|
err = nil
|
|
|
|
}
|
2016-01-23 22:41:55 +00:00
|
|
|
buf = buf[:n]
|
|
|
|
return buf, err
|
|
|
|
}
|
2017-01-22 21:01:12 +00:00
|
|
|
|
|
|
|
// Closer wraps an io.Reader and adds a Close() method that does nothing.
|
|
|
|
type Closer struct {
|
|
|
|
io.Reader
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close is a no-op.
|
|
|
|
func (c Closer) Close() error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// LimitedReadCloser wraps io.LimitedReader and exposes the Close() method.
|
|
|
|
type LimitedReadCloser struct {
|
|
|
|
io.ReadCloser
|
|
|
|
io.Reader
|
|
|
|
}
|
|
|
|
|
|
|
|
// Read reads data from the limited reader.
|
|
|
|
func (l *LimitedReadCloser) Read(p []byte) (int, error) {
|
|
|
|
return l.Reader.Read(p)
|
|
|
|
}
|
|
|
|
|
|
|
|
// LimitReadCloser returns a new reader wraps r in an io.LimitReader, but also
|
|
|
|
// exposes the Close() method.
|
|
|
|
func LimitReadCloser(r io.ReadCloser, n int64) *LimitedReadCloser {
|
|
|
|
return &LimitedReadCloser{ReadCloser: r, Reader: io.LimitReader(r, n)}
|
|
|
|
}
|