~rbn/neinp

ref: f0b91981560c6d7f112692b0479d8d28cc062ba7 neinp/message/write.go -rw-r--r-- 2.0 KiB
f0b91981Ruben Schuller add build badge 2 years 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
package message // import "go.rbn.im/neinp/message"

import (
	"go.rbn.im/neinp/basic"
	"go.rbn.im/neinp/fid"
	"io"
)

/*TWrite requests data to be written to a file.

Write Count bytes of Data at Offset bytes from the beginning
of the file. The file which is represented by Fid must be
opened for writing before this request, when opened in append
mode, the write will be to the end of the file, ignoring Offset.
Writes to directories are forbidden.

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

func (m *TWrite) 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
	}

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

	return n1 + n2 + n3 + int64(n4), nil
}

func (m *TWrite) 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

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

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

	return n1 + n2 + n3 + int64(n4), nil
}

/*RWrite is the reply to a TWrite.

Count is the number of bytes written. It usually should be
the same as requested.

See also: http://man.cat-v.org/inferno/5/read
*/
type RWrite struct {
	Count uint32
}

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

	return n, nil
}

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

	m.Count = count

	return n, nil
}