From c73c4ae55d90a007ceb3b73d5d9ab747dbe631a5 Mon Sep 17 00:00:00 2001 From: Matt Bell Date: Wed, 21 Jan 2015 18:38:09 -0800 Subject: [PATCH] commands/files: Added SizeFile interface --- commands/files/file.go | 8 +++++++- commands/files/readerfile.go | 8 ++++++++ commands/files/serialfile.go | 30 ++++++++++++++++++++++++++++++ commands/files/slicefile.go | 24 +++++++++++++++++++++++- 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/commands/files/file.go b/commands/files/file.go index 8f76ea71d..f1196257d 100644 --- a/commands/files/file.go +++ b/commands/files/file.go @@ -38,8 +38,14 @@ type StatFile interface { } type PeekFile interface { - File + SizeFile Peek(n int) File Length() int } + +type SizeFile interface { + File + + Size() (int64, error) +} diff --git a/commands/files/readerfile.go b/commands/files/readerfile.go index 38c28efe3..741042881 100644 --- a/commands/files/readerfile.go +++ b/commands/files/readerfile.go @@ -1,6 +1,7 @@ package files import ( + "errors" "io" "os" ) @@ -40,3 +41,10 @@ func (f *ReaderFile) Close() error { func (f *ReaderFile) Stat() os.FileInfo { return f.stat } + +func (f *ReaderFile) Size() (int64, error) { + if f.stat == nil { + return 0, errors.New("File size unknown") + } + return f.stat.Size(), nil +} diff --git a/commands/files/serialfile.go b/commands/files/serialfile.go index 9a81f8bd1..aeba01fa7 100644 --- a/commands/files/serialfile.go +++ b/commands/files/serialfile.go @@ -118,3 +118,33 @@ func (f *serialFile) Close() error { func (f *serialFile) Stat() os.FileInfo { return f.stat } + +func (f *serialFile) Size() (int64, error) { + return size(f.stat, f.FileName()) +} + +func size(stat os.FileInfo, filename string) (int64, error) { + if !stat.IsDir() { + return stat.Size(), nil + } + + file, err := os.Open(filename) + if err != nil { + return 0, err + } + files, err := file.Readdir(0) + if err != nil { + return 0, err + } + file.Close() + + var output int64 + for _, child := range files { + s, err := size(child, fp.Join(filename, child.Name())) + if err != nil { + return 0, err + } + output += s + } + return output, nil +} diff --git a/commands/files/slicefile.go b/commands/files/slicefile.go index fe0332d59..f6e204812 100644 --- a/commands/files/slicefile.go +++ b/commands/files/slicefile.go @@ -1,6 +1,9 @@ package files -import "io" +import ( + "errors" + "io" +) // SliceFile implements File, and provides simple directory handling. // It contains children files, and is created from a `[]File`. @@ -47,3 +50,22 @@ func (f *SliceFile) Peek(n int) File { func (f *SliceFile) Length() int { return len(f.files) } + +func (f *SliceFile) Size() (int64, error) { + var size int64 + + for _, file := range f.files { + sizeFile, ok := file.(SizeFile) + if !ok { + return 0, errors.New("Could not get size of child file") + } + + s, err := sizeFile.Size() + if err != nil { + return 0, err + } + size += s + } + + return size, nil +}