Blame


1 7cd259a2 2015-11-11 stephen.d package p9pnew
2 7cd259a2 2015-11-11 stephen.d
3 7cd259a2 2015-11-11 stephen.d import (
4 7cd259a2 2015-11-11 stephen.d "io"
5 7cd259a2 2015-11-11 stephen.d
6 7cd259a2 2015-11-11 stephen.d "golang.org/x/net/context"
7 7cd259a2 2015-11-11 stephen.d )
8 7cd259a2 2015-11-11 stephen.d
9 7cd259a2 2015-11-11 stephen.d // ReaddirAll reads all the directory entries for the resource fid.
10 7cd259a2 2015-11-11 stephen.d func ReaddirAll(session Session, fid Fid) ([]Dir, error) {
11 7cd259a2 2015-11-11 stephen.d panic("not implemented")
12 7cd259a2 2015-11-11 stephen.d }
13 7cd259a2 2015-11-11 stephen.d
14 7cd259a2 2015-11-11 stephen.d // Readdir helps one to implement the server-side of Session.Read on
15 7cd259a2 2015-11-11 stephen.d // directories.
16 7cd259a2 2015-11-11 stephen.d type Readdir struct {
17 7cd259a2 2015-11-11 stephen.d nextfn func() (Dir, error)
18 7cd259a2 2015-11-11 stephen.d buf *Dir // one-item buffer
19 7cd259a2 2015-11-11 stephen.d codec Codec
20 7cd259a2 2015-11-11 stephen.d offset int64
21 7cd259a2 2015-11-11 stephen.d }
22 7cd259a2 2015-11-11 stephen.d
23 7cd259a2 2015-11-11 stephen.d func NewReaddir(codec Codec, next func() (Dir, error)) *Readdir {
24 7cd259a2 2015-11-11 stephen.d return &Readdir{
25 7cd259a2 2015-11-11 stephen.d nextfn: next,
26 7cd259a2 2015-11-11 stephen.d codec: codec,
27 7cd259a2 2015-11-11 stephen.d }
28 7cd259a2 2015-11-11 stephen.d }
29 7cd259a2 2015-11-11 stephen.d
30 7cd259a2 2015-11-11 stephen.d func NewFixedReaddir(codec Codec, dir []Dir) *Readdir {
31 7cd259a2 2015-11-11 stephen.d dirs := make([]Dir, len(dir))
32 7cd259a2 2015-11-11 stephen.d copy(dirs, dir) // make our own copy!
33 7cd259a2 2015-11-11 stephen.d
34 7cd259a2 2015-11-11 stephen.d return NewReaddir(codec,
35 7cd259a2 2015-11-11 stephen.d func() (Dir, error) {
36 7cd259a2 2015-11-11 stephen.d if len(dirs) == 0 {
37 7cd259a2 2015-11-11 stephen.d return Dir{}, io.EOF
38 7cd259a2 2015-11-11 stephen.d }
39 7cd259a2 2015-11-11 stephen.d
40 7cd259a2 2015-11-11 stephen.d d := dirs[0]
41 7cd259a2 2015-11-11 stephen.d dirs = dirs[1:]
42 7cd259a2 2015-11-11 stephen.d return d, nil
43 7cd259a2 2015-11-11 stephen.d })
44 7cd259a2 2015-11-11 stephen.d }
45 7cd259a2 2015-11-11 stephen.d
46 7cd259a2 2015-11-11 stephen.d func (rd *Readdir) Read(ctx context.Context, p []byte, offset int64) (n int, err error) {
47 7cd259a2 2015-11-11 stephen.d if rd.offset != offset {
48 7cd259a2 2015-11-11 stephen.d return 0, ErrBadoffset
49 7cd259a2 2015-11-11 stephen.d }
50 7cd259a2 2015-11-11 stephen.d
51 7cd259a2 2015-11-11 stephen.d p = p[:0:len(p)]
52 7cd259a2 2015-11-11 stephen.d for len(p) < cap(p) {
53 7cd259a2 2015-11-11 stephen.d var d Dir
54 7cd259a2 2015-11-11 stephen.d if rd.buf != nil {
55 7cd259a2 2015-11-11 stephen.d d = *rd.buf
56 7cd259a2 2015-11-11 stephen.d rd.buf = nil
57 7cd259a2 2015-11-11 stephen.d } else {
58 7cd259a2 2015-11-11 stephen.d d, err = rd.nextfn()
59 7cd259a2 2015-11-11 stephen.d if err != nil {
60 7cd259a2 2015-11-11 stephen.d goto done
61 7cd259a2 2015-11-11 stephen.d }
62 7cd259a2 2015-11-11 stephen.d }
63 7cd259a2 2015-11-11 stephen.d
64 7cd259a2 2015-11-11 stephen.d var dp []byte
65 7cd259a2 2015-11-11 stephen.d dp, err = rd.codec.Marshal(d)
66 7cd259a2 2015-11-11 stephen.d if err != nil {
67 7cd259a2 2015-11-11 stephen.d goto done
68 7cd259a2 2015-11-11 stephen.d }
69 7cd259a2 2015-11-11 stephen.d
70 7cd259a2 2015-11-11 stephen.d if len(p)+len(dp) > cap(p) {
71 7cd259a2 2015-11-11 stephen.d // will over fill buffer. save item and exit.
72 7cd259a2 2015-11-11 stephen.d rd.buf = &d
73 7cd259a2 2015-11-11 stephen.d goto done
74 7cd259a2 2015-11-11 stephen.d }
75 7cd259a2 2015-11-11 stephen.d
76 7cd259a2 2015-11-11 stephen.d p = append(p, dp...)
77 7cd259a2 2015-11-11 stephen.d }
78 7cd259a2 2015-11-11 stephen.d
79 7cd259a2 2015-11-11 stephen.d done:
80 7cd259a2 2015-11-11 stephen.d if err == io.EOF && len(p) > 0 {
81 7cd259a2 2015-11-11 stephen.d // Don't let io.EOF escape if we've written to p. 9p doesn't handle
82 7cd259a2 2015-11-11 stephen.d // this like Go.
83 7cd259a2 2015-11-11 stephen.d err = nil
84 7cd259a2 2015-11-11 stephen.d }
85 7cd259a2 2015-11-11 stephen.d
86 7cd259a2 2015-11-11 stephen.d rd.offset += int64(len(p))
87 7cd259a2 2015-11-11 stephen.d return len(p), err
88 7cd259a2 2015-11-11 stephen.d }