9fans.net/go@v0.0.5/plan9/client/fid.go (about) 1 package client 2 3 import ( 4 "io" 5 6 "9fans.net/go/plan9" 7 ) 8 9 func (fid *Fid) Dirread() ([]*plan9.Dir, error) { 10 buf := make([]byte, plan9.STATMAX) 11 n, err := fid.Read(buf) 12 if err != nil { 13 return nil, err 14 } 15 return dirUnpack(buf[0:n]) 16 } 17 18 func (fid *Fid) Dirreadall() ([]*plan9.Dir, error) { 19 // Note: Cannot use ioutil.ReadAll / io.ReadAll here 20 // because it assumes it can read small amounts. 21 // Plan 9 requires providing a buffer big enough for 22 // at least a single directory entry. 23 var dirs []*plan9.Dir 24 for { 25 d, err := fid.Dirread() 26 dirs = append(dirs, d...) 27 if err != nil { 28 if err == io.EOF { 29 err = nil 30 } 31 return dirs, err 32 } 33 } 34 } 35 36 func dirUnpack(b []byte) ([]*plan9.Dir, error) { 37 var err error 38 dirs := make([]*plan9.Dir, 0, 10) 39 for len(b) > 0 { 40 if len(b) < 2 { 41 err = io.ErrUnexpectedEOF 42 break 43 } 44 n := int(b[0]) | int(b[1])<<8 45 if len(b) < n+2 { 46 err = io.ErrUnexpectedEOF 47 break 48 } 49 var d *plan9.Dir 50 d, err = plan9.UnmarshalDir(b[0 : n+2]) 51 if err != nil { 52 break 53 } 54 b = b[n+2:] 55 if len(dirs) >= cap(dirs) { 56 ndirs := make([]*plan9.Dir, len(dirs), 2*cap(dirs)) 57 copy(ndirs, dirs) 58 dirs = ndirs 59 } 60 n = len(dirs) 61 dirs = dirs[0 : n+1] 62 dirs[n] = d 63 } 64 return dirs, err 65 } 66 67 func (fid *Fid) ReadFull(b []byte) (n int, err error) { 68 return io.ReadFull(fid, b) 69 }