Blame


1 30803980 2015-11-30 stephen.d package p9p
2 4b33cdd0 2015-11-30 stephen.d
3 4b33cdd0 2015-11-30 stephen.d import (
4 4b33cdd0 2015-11-30 stephen.d "io"
5 4b33cdd0 2015-11-30 stephen.d
6 529e2b2e 2016-11-14 noreply "context"
7 4b33cdd0 2015-11-30 stephen.d )
8 4b33cdd0 2015-11-30 stephen.d
9 4b33cdd0 2015-11-30 stephen.d // ReaddirAll reads all the directory entries for the resource fid.
10 4b33cdd0 2015-11-30 stephen.d func ReaddirAll(session Session, fid Fid) ([]Dir, error) {
11 4b33cdd0 2015-11-30 stephen.d panic("not implemented")
12 4b33cdd0 2015-11-30 stephen.d }
13 4b33cdd0 2015-11-30 stephen.d
14 4b33cdd0 2015-11-30 stephen.d // Readdir helps one to implement the server-side of Session.Read on
15 4b33cdd0 2015-11-30 stephen.d // directories.
16 4b33cdd0 2015-11-30 stephen.d type Readdir struct {
17 4b33cdd0 2015-11-30 stephen.d nextfn func() (Dir, error)
18 4b33cdd0 2015-11-30 stephen.d buf *Dir // one-item buffer
19 4b33cdd0 2015-11-30 stephen.d codec Codec
20 4b33cdd0 2015-11-30 stephen.d offset int64
21 4b33cdd0 2015-11-30 stephen.d }
22 4b33cdd0 2015-11-30 stephen.d
23 a0568195 2016-05-23 stevvooe // NewReaddir returns a new Readdir to assist implementing server-side Readdir.
24 a0568195 2016-05-23 stevvooe // The codec will be used to decode messages with Dir entries. The provided
25 a0568195 2016-05-23 stevvooe // function next will be called until io.EOF is returned.
26 4b33cdd0 2015-11-30 stephen.d func NewReaddir(codec Codec, next func() (Dir, error)) *Readdir {
27 4b33cdd0 2015-11-30 stephen.d return &Readdir{
28 4b33cdd0 2015-11-30 stephen.d nextfn: next,
29 4b33cdd0 2015-11-30 stephen.d codec: codec,
30 4b33cdd0 2015-11-30 stephen.d }
31 4b33cdd0 2015-11-30 stephen.d }
32 4b33cdd0 2015-11-30 stephen.d
33 a0568195 2016-05-23 stevvooe // NewFixedReaddir returns a Readdir that will returned a fixed set of
34 a0568195 2016-05-23 stevvooe // directory entries.
35 4b33cdd0 2015-11-30 stephen.d func NewFixedReaddir(codec Codec, dir []Dir) *Readdir {
36 4b33cdd0 2015-11-30 stephen.d dirs := make([]Dir, len(dir))
37 4b33cdd0 2015-11-30 stephen.d copy(dirs, dir) // make our own copy!
38 4b33cdd0 2015-11-30 stephen.d
39 4b33cdd0 2015-11-30 stephen.d return NewReaddir(codec,
40 4b33cdd0 2015-11-30 stephen.d func() (Dir, error) {
41 4b33cdd0 2015-11-30 stephen.d if len(dirs) == 0 {
42 4b33cdd0 2015-11-30 stephen.d return Dir{}, io.EOF
43 4b33cdd0 2015-11-30 stephen.d }
44 4b33cdd0 2015-11-30 stephen.d
45 4b33cdd0 2015-11-30 stephen.d d := dirs[0]
46 4b33cdd0 2015-11-30 stephen.d dirs = dirs[1:]
47 4b33cdd0 2015-11-30 stephen.d return d, nil
48 4b33cdd0 2015-11-30 stephen.d })
49 4b33cdd0 2015-11-30 stephen.d }
50 4b33cdd0 2015-11-30 stephen.d
51 4b33cdd0 2015-11-30 stephen.d func (rd *Readdir) Read(ctx context.Context, p []byte, offset int64) (n int, err error) {
52 4b33cdd0 2015-11-30 stephen.d if rd.offset != offset {
53 4b33cdd0 2015-11-30 stephen.d return 0, ErrBadoffset
54 4b33cdd0 2015-11-30 stephen.d }
55 4b33cdd0 2015-11-30 stephen.d
56 4b33cdd0 2015-11-30 stephen.d p = p[:0:len(p)]
57 4b33cdd0 2015-11-30 stephen.d for len(p) < cap(p) {
58 4b33cdd0 2015-11-30 stephen.d var d Dir
59 4b33cdd0 2015-11-30 stephen.d if rd.buf != nil {
60 4b33cdd0 2015-11-30 stephen.d d = *rd.buf
61 4b33cdd0 2015-11-30 stephen.d rd.buf = nil
62 4b33cdd0 2015-11-30 stephen.d } else {
63 4b33cdd0 2015-11-30 stephen.d d, err = rd.nextfn()
64 4b33cdd0 2015-11-30 stephen.d if err != nil {
65 4b33cdd0 2015-11-30 stephen.d goto done
66 4b33cdd0 2015-11-30 stephen.d }
67 4b33cdd0 2015-11-30 stephen.d }
68 4b33cdd0 2015-11-30 stephen.d
69 4b33cdd0 2015-11-30 stephen.d var dp []byte
70 4b33cdd0 2015-11-30 stephen.d dp, err = rd.codec.Marshal(d)
71 4b33cdd0 2015-11-30 stephen.d if err != nil {
72 4b33cdd0 2015-11-30 stephen.d goto done
73 4b33cdd0 2015-11-30 stephen.d }
74 4b33cdd0 2015-11-30 stephen.d
75 4b33cdd0 2015-11-30 stephen.d if len(p)+len(dp) > cap(p) {
76 4b33cdd0 2015-11-30 stephen.d // will over fill buffer. save item and exit.
77 4b33cdd0 2015-11-30 stephen.d rd.buf = &d
78 4b33cdd0 2015-11-30 stephen.d goto done
79 4b33cdd0 2015-11-30 stephen.d }
80 4b33cdd0 2015-11-30 stephen.d
81 4b33cdd0 2015-11-30 stephen.d p = append(p, dp...)
82 4b33cdd0 2015-11-30 stephen.d }
83 4b33cdd0 2015-11-30 stephen.d
84 4b33cdd0 2015-11-30 stephen.d done:
85 a96bd10f 2018-02-28 noreply if err == io.EOF {
86 a96bd10f 2018-02-28 noreply // Don't let io.EOF escape. EOF is indicated by a zero-length result
87 a96bd10f 2018-02-28 noreply // with no error.
88 4b33cdd0 2015-11-30 stephen.d err = nil
89 4b33cdd0 2015-11-30 stephen.d }
90 4b33cdd0 2015-11-30 stephen.d
91 4b33cdd0 2015-11-30 stephen.d rd.offset += int64(len(p))
92 4b33cdd0 2015-11-30 stephen.d return len(p), err
93 4b33cdd0 2015-11-30 stephen.d }