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  }