github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/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  }