github.com/ncruces/go-sqlite3@v0.15.1-0.20240520133447-53eef1510ff0/util/ioutil/size.go (about) 1 package ioutil 2 3 import ( 4 "io" 5 "io/fs" 6 7 "github.com/ncruces/go-sqlite3" 8 ) 9 10 // A SizeReaderAt is a ReaderAt with a Size method. 11 // Use [NewSizeReaderAt] to adapt different Size interfaces. 12 type SizeReaderAt interface { 13 Size() (int64, error) 14 io.ReaderAt 15 } 16 17 // NewSizeReaderAt returns a SizeReaderAt given an io.ReaderAt 18 // that implements one of: 19 // - Size() (int64, error) 20 // - Size() int64 21 // - Len() int 22 // - Stat() (fs.FileInfo, error) 23 // - Seek(offset int64, whence int) (int64, error) 24 func NewSizeReaderAt(r io.ReaderAt) SizeReaderAt { 25 return sizer{r} 26 } 27 28 type sizer struct{ io.ReaderAt } 29 30 func (s sizer) Size() (int64, error) { 31 switch s := s.ReaderAt.(type) { 32 case interface{ Size() (int64, error) }: 33 return s.Size() 34 case interface{ Size() int64 }: 35 return s.Size(), nil 36 case interface{ Len() int }: 37 return int64(s.Len()), nil 38 case interface{ Stat() (fs.FileInfo, error) }: 39 fi, err := s.Stat() 40 if err != nil { 41 return 0, err 42 } 43 return fi.Size(), nil 44 case io.Seeker: 45 return s.Seek(0, io.SeekEnd) 46 } 47 return 0, sqlite3.IOERR_SEEK 48 }