// "Seeking to an offset before the start of the file is an error."
invalidOffset:=r.relativeOffset
r.relativeOffset=0
return0,fmt.Errorf("Seek resulted in invalid offset %d, using 0",invalidOffset)
}
ifr.relativeOffset>maxRelativeOffset{
// "Seeking to any positive offset is legal, but the behavior of subsequent
// I/O operations on the underlying object is implementation-dependent."
// We'll choose to set the offset to the EOF.
log.Printf("blob.Reader.Seek set an offset after EOF (base offset/length from NewRangeReader %d, %d; actual blob size %d; relative offset %d -> absolute offset %d).",r.baseOffset,r.baseLength,r.Size(),r.relativeOffset,r.baseOffset+r.relativeOffset)
r.relativeOffset=maxRelativeOffset
}
returnr.relativeOffset,nil
}
// Close implements io.Closer (https://golang.org/pkg/io/#Closer).
func(r*Reader)Close()error{
r.closed=true
err:=wrapError(r.drv,r.r.Close(),r.key)
returnerr
}
// ContentType returns the MIME type of the blob.
func(r*Reader)ContentType()string{
returnr.r.Attributes().ContentType
}
// ModTime returns the time the blob was last modified.
func(r*Reader)ModTime()time.Time{
returnr.r.Attributes().ModTime
}
// Size returns the size of the blob content in bytes.
func(r*Reader)Size()int64{
returnr.r.Attributes().Size
}
// WriteTo reads from r and writes to w until there's no more data or
// an error occurs.
// The return value is the number of bytes written to w.
//
// It implements the io.WriterTo interface.
func(r*Reader)WriteTo(wio.Writer)(int64,error){
// If the writer has a ReaderFrom method, use it to do the copy.
// Don't do this for our own *Writer to avoid infinite recursion.
// Avoids an allocation and a copy.
switchw.(type){
case*Writer:
default:
ifrf,ok:=w.(io.ReaderFrom);ok{
n,err:=rf.ReadFrom(r)
returnn,err
}
}
_,nw,err:=readFromWriteTo(r,w)
returnnw,err
}
// readFromWriteTo is a helper for ReadFrom and WriteTo.
// It reads data from r and writes to w, until EOF or a read/write error.
// It returns the number of bytes read from r and the number of bytes