/
read.go
124 lines (103 loc) · 2.59 KB
/
read.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright 2009 The Go9p Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package clnt
import (
"io"
"k8s.io/minikube/third_party/go9p/p"
)
// Reads count bytes starting from offset from the file associated with the fid.
// Returns a slice with the data read, if the operation was successful, or an
// Error.
func (clnt *Clnt) Read(fid *Fid, offset uint64, count uint32) ([]byte, error) {
if count > fid.Iounit {
count = fid.Iounit
}
tc := clnt.NewFcall()
err := p.PackTread(tc, fid.Fid, offset, count)
if err != nil {
return nil, err
}
rc, err := clnt.Rpc(tc)
if err != nil {
return nil, err
}
return rc.Data, nil
}
// Reads up to len(buf) bytes from the File. Returns the number
// of bytes read, or an Error.
func (file *File) Read(buf []byte) (int, error) {
n, err := file.ReadAt(buf, int64(file.offset))
if err == nil {
file.offset += uint64(n)
}
return n, err
}
// Reads up to len(buf) bytes from the file starting from offset.
// Returns the number of bytes read, or an Error.
func (file *File) ReadAt(buf []byte, offset int64) (int, error) {
b, err := file.fid.Clnt.Read(file.fid, uint64(offset), uint32(len(buf)))
if err != nil {
return 0, err
}
if len(b) == 0 {
return 0, io.EOF
}
copy(buf, b)
return len(b), nil
}
// Reads exactly len(buf) bytes from the File starting from offset.
// Returns the number of bytes read (could be less than len(buf) if
// end-of-file is reached), or an Error.
func (file *File) Readn(buf []byte, offset uint64) (int, error) {
ret := 0
for len(buf) > 0 {
n, err := file.ReadAt(buf, int64(offset))
if err != nil {
return 0, err
}
if n == 0 {
break
}
buf = buf[n:]
offset += uint64(n)
ret += n
}
return ret, nil
}
// Reads the content of the directory associated with the File.
// Returns an array of maximum num entries (if num is 0, returns
// all entries from the directory). If the operation fails, returns
// an Error.
func (file *File) Readdir(num int) ([]*p.Dir, error) {
buf := make([]byte, file.fid.Clnt.Msize-p.IOHDRSZ)
dirs := make([]*p.Dir, 32)
pos := 0
for {
n, err := file.Read(buf)
if err != nil && err != io.EOF {
return nil, err
}
if n == 0 {
break
}
for b := buf[0:n]; len(b) > 0; {
d, perr := p.UnpackDir(b, file.fid.Clnt.Dotu)
if perr != nil {
return nil, perr
}
b = b[d.Size+2:]
if pos >= len(dirs) {
s := make([]*p.Dir, len(dirs)+32)
copy(s, dirs)
dirs = s
}
dirs[pos] = d
pos++
if num != 0 && pos >= num {
break
}
}
}
return dirs[0:pos], nil
}