1 30803980 2015-11-30 stephen.d package p9p
3 4b33cdd0 2015-11-30 stephen.d import (
6 4b33cdd0 2015-11-30 stephen.d "golang.org/x/net/context"
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")
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
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,
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!
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
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
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
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
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
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
76 4b33cdd0 2015-11-30 stephen.d p = append(p, dp...)
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
86 4b33cdd0 2015-11-30 stephen.d rd.offset += int64(len(p))
87 4b33cdd0 2015-11-30 stephen.d return len(p), err