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 4b33cdd0 2015-11-30 stephen.d "golang.org/x/net/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 4b33cdd0 2015-11-30 stephen.d func NewReaddir(codec Codec, next func() (Dir, error)) *Readdir {
24 4b33cdd0 2015-11-30 stephen.d return &Readdir{
25 4b33cdd0 2015-11-30 stephen.d nextfn: next,
26 4b33cdd0 2015-11-30 stephen.d codec: codec,
27 4b33cdd0 2015-11-30 stephen.d }
28 4b33cdd0 2015-11-30 stephen.d }
29 4b33cdd0 2015-11-30 stephen.d
30 4b33cdd0 2015-11-30 stephen.d func NewFixedReaddir(codec Codec, dir []Dir) *Readdir {
31 4b33cdd0 2015-11-30 stephen.d dirs := make([]Dir, len(dir))
32 4b33cdd0 2015-11-30 stephen.d copy(dirs, dir) // make our own copy!
33 4b33cdd0 2015-11-30 stephen.d
34 4b33cdd0 2015-11-30 stephen.d return NewReaddir(codec,
35 4b33cdd0 2015-11-30 stephen.d func() (Dir, error) {
36 4b33cdd0 2015-11-30 stephen.d if len(dirs) == 0 {
37 4b33cdd0 2015-11-30 stephen.d return Dir{}, io.EOF
38 4b33cdd0 2015-11-30 stephen.d }
39 4b33cdd0 2015-11-30 stephen.d
40 4b33cdd0 2015-11-30 stephen.d d := dirs[0]
41 4b33cdd0 2015-11-30 stephen.d dirs = dirs[1:]
42 4b33cdd0 2015-11-30 stephen.d return d, nil
43 4b33cdd0 2015-11-30 stephen.d })
44 4b33cdd0 2015-11-30 stephen.d }
45 4b33cdd0 2015-11-30 stephen.d
46 4b33cdd0 2015-11-30 stephen.d func (rd *Readdir) Read(ctx context.Context, p []byte, offset int64) (n int, err error) {
47 4b33cdd0 2015-11-30 stephen.d if rd.offset != offset {
48 4b33cdd0 2015-11-30 stephen.d return 0, ErrBadoffset
49 4b33cdd0 2015-11-30 stephen.d }
50 4b33cdd0 2015-11-30 stephen.d
51 4b33cdd0 2015-11-30 stephen.d p = p[:0:len(p)]
52 4b33cdd0 2015-11-30 stephen.d for len(p) < cap(p) {
53 4b33cdd0 2015-11-30 stephen.d var d Dir
54 4b33cdd0 2015-11-30 stephen.d if rd.buf != nil {
55 4b33cdd0 2015-11-30 stephen.d d = *rd.buf
56 4b33cdd0 2015-11-30 stephen.d rd.buf = nil
57 4b33cdd0 2015-11-30 stephen.d } else {
58 4b33cdd0 2015-11-30 stephen.d d, err = rd.nextfn()
59 4b33cdd0 2015-11-30 stephen.d if err != nil {
60 4b33cdd0 2015-11-30 stephen.d goto done
61 4b33cdd0 2015-11-30 stephen.d }
62 4b33cdd0 2015-11-30 stephen.d }
63 4b33cdd0 2015-11-30 stephen.d
64 4b33cdd0 2015-11-30 stephen.d var dp []byte
65 4b33cdd0 2015-11-30 stephen.d dp, err = rd.codec.Marshal(d)
66 4b33cdd0 2015-11-30 stephen.d if err != nil {
67 4b33cdd0 2015-11-30 stephen.d goto done
68 4b33cdd0 2015-11-30 stephen.d }
69 4b33cdd0 2015-11-30 stephen.d
70 4b33cdd0 2015-11-30 stephen.d if len(p)+len(dp) > cap(p) {
71 4b33cdd0 2015-11-30 stephen.d // will over fill buffer. save item and exit.
72 4b33cdd0 2015-11-30 stephen.d rd.buf = &d
73 4b33cdd0 2015-11-30 stephen.d goto done
74 4b33cdd0 2015-11-30 stephen.d }
75 4b33cdd0 2015-11-30 stephen.d
76 4b33cdd0 2015-11-30 stephen.d p = append(p, dp...)
77 4b33cdd0 2015-11-30 stephen.d }
78 4b33cdd0 2015-11-30 stephen.d
79 4b33cdd0 2015-11-30 stephen.d done:
80 4b33cdd0 2015-11-30 stephen.d if err == io.EOF && len(p) > 0 {
81 4b33cdd0 2015-11-30 stephen.d // Don't let io.EOF escape if we've written to p. 9p doesn't handle
82 4b33cdd0 2015-11-30 stephen.d // this like Go.
83 4b33cdd0 2015-11-30 stephen.d err = nil
84 4b33cdd0 2015-11-30 stephen.d }
85 4b33cdd0 2015-11-30 stephen.d
86 4b33cdd0 2015-11-30 stephen.d rd.offset += int64(len(p))
87 4b33cdd0 2015-11-30 stephen.d return len(p), err
88 4b33cdd0 2015-11-30 stephen.d }