github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libdokan/special_read_file.go (about) 1 // Copyright 2016 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package libdokan 6 7 import ( 8 "time" 9 10 "github.com/keybase/client/go/kbfs/dokan" 11 "golang.org/x/net/context" 12 ) 13 14 // SpecialReadFile represents a file whose contents are determined by 15 // a function. 16 type SpecialReadFile struct { 17 read func(context.Context) ([]byte, time.Time, error) 18 fs *FS 19 emptyFile 20 } 21 22 // GetFileInformation does stats for dokan. 23 func (f *SpecialReadFile) GetFileInformation(ctx context.Context, fi *dokan.FileInfo) (*dokan.Stat, error) { 24 f.fs.logEnter(ctx, "SpecialReadFile GetFileInformation") 25 data, t, err := f.read(ctx) 26 if err != nil { 27 return nil, err 28 } 29 30 // Some apps (e.g., Chrome) get confused if we use a 0 size 31 // here, as is usual for pseudofiles. So return the actual 32 // size, even though it may be racy. 33 a, err := defaultFileInformation() 34 if err != nil { 35 return nil, err 36 } 37 a.FileAttributes |= dokan.FileAttributeReadonly 38 a.FileSize = int64(len(data)) 39 a.LastWrite = t 40 a.LastAccess = t 41 a.Creation = t 42 return a, nil 43 } 44 45 // ReadFile does reads for dokan. 46 func (f *SpecialReadFile) ReadFile(ctx context.Context, fi *dokan.FileInfo, bs []byte, offset int64) (int, error) { 47 f.fs.logEnter(ctx, "SpecialReadFile ReadFile") 48 data, _, err := f.read(ctx) 49 if err != nil { 50 return 0, err 51 } 52 53 if offset >= int64(len(data)) { 54 return 0, nil 55 } 56 57 data = data[int(offset):] 58 59 return copy(bs, data), nil 60 }