20318: Comment about error handling.
[arvados.git] / sdk / go / arvados / fs_getternode.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 package arvados
6
7 import (
8         "bytes"
9         "os"
10         "time"
11 )
12
13 // A getternode is a read-only character device that returns whatever
14 // data is returned by the supplied function.
15 type getternode struct {
16         Getter func() ([]byte, error)
17
18         treenode
19         data *bytes.Reader
20 }
21
22 func (*getternode) IsDir() bool {
23         return false
24 }
25
26 func (*getternode) Child(string, func(inode) (inode, error)) (inode, error) {
27         return nil, ErrInvalidOperation
28 }
29
30 func (gn *getternode) get() error {
31         if gn.data != nil {
32                 return nil
33         }
34         data, err := gn.Getter()
35         if err != nil {
36                 return err
37         }
38         gn.data = bytes.NewReader(data)
39         return nil
40 }
41
42 func (gn *getternode) Size() int64 {
43         return gn.FileInfo().Size()
44 }
45
46 func (gn *getternode) FileInfo() os.FileInfo {
47         gn.Lock()
48         defer gn.Unlock()
49         var size int64
50         if gn.get() == nil {
51                 size = gn.data.Size()
52         }
53         return fileinfo{
54                 modTime: time.Now(),
55                 mode:    0444,
56                 size:    size,
57         }
58 }
59
60 func (gn *getternode) Read(p []byte, ptr filenodePtr) (int, filenodePtr, error) {
61         if err := gn.get(); err != nil {
62                 return 0, ptr, err
63         }
64         n, err := gn.data.ReadAt(p, ptr.off)
65         return n, filenodePtr{off: ptr.off + int64(n)}, err
66 }