~rbn/neinp

ref: 280ca11dc4f314d4bb506de2f219eb70dd959227 neinp/message/read.go -rw-r--r-- 2.5 KiB
280ca11dRuben Schuller update go.mod 1 year, 2 months ago
                                                                                
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
package message

import (
	"git.sr.ht/~rbn/neinp/basic"
	"git.sr.ht/~rbn/neinp/fid"
	"io"
)

/*TRead requests data from a file.

The file is identified by Fid, which must be opened before reading.
Count bytes are read from the file, starting at Offset bytes after the
beginning of the file.

The count Field in the reply indicates the number of bytes
returned.  This may be less than the requested amount.  If
the Offset field is greater than or equal to the number of
bytes in the file, a Count of zero will be returned.

For directories, the read request message must have
Offset equal to zero or the value of Offset in the previous
read on the directory, plus the number of bytes returned in
the previous read. In other words, seeking other than to
the beginning is illegal in a directory.

See also: http://man.cat-v.org/inferno/5/read
*/
type TRead struct {
	Fid    fid.Fid
	Offset uint64
	Count  uint32
}

func (m *TRead) encode(w io.Writer) (int64, error) {
	n1, err := basic.Uint32Encode(w, uint32(m.Fid))
	if err != nil {
		return n1, err
	}

	n2, err := basic.Uint64Encode(w, m.Offset)
	if err != nil {
		return n1 + n2, err
	}

	n3, err := basic.Uint32Encode(w, m.Count)
	if err != nil {
		return n1 + n2 + n3, err
	}

	return n1 + n2 + n3, nil
}

func (m *TRead) decode(r io.Reader) (int64, error) {
	f, n1, err := basic.Uint32Decode(r)
	if err != nil {
		return n1, err
	}

	offset, n2, err := basic.Uint64Decode(r)
	if err != nil {
		return n1 + n2, err
	}

	count, n3, err := basic.Uint32Decode(r)
	if err != nil {
		return n1 + n2 + n3, err
	}

	m.Fid = fid.Fid(f)
	m.Offset = offset
	m.Count = count

	return n1 + n2 + n3, nil
}

/*RRead is the reply to a TRead.

The data read is stored in Data, Count being the length
of Data in bytes.

For directories, read returns an integral number of directory
entries exactly as in RStat, one for each member of the directory.
To help with this StatReader can be used.

See also: http://man.cat-v.org/inferno/5/read
*/
type RRead struct {
	Count uint32
	Data  []byte
}

func (m *RRead) encode(w io.Writer) (int64, error) {
	n1, err := basic.Uint32Encode(w, m.Count)
	if err != nil {
		return n1, err
	}

	n2, err := w.Write(m.Data)
	if err != nil {
		return n1 + int64(n2), err
	}

	return n1 + int64(n2), nil
}

func (m *RRead) decode(r io.Reader) (int64, error) {
	count, n1, err := basic.Uint32Decode(r)
	if err != nil {
		return n1, err
	}

	m.Count = count
	m.Data = make([]byte, count)

	n2, err := r.Read(m.Data)
	if err != nil {
		return n1 + int64(n2), err
	}

	return n1 + int64(n2), nil
}