~rbn/neinp

ref: 062a107b140085acd6c48867e4328fb3f3466a87 neinp/message/write.go -rw-r--r-- 2.0 KiB
062a107bRuben Schuller use custom go.rbn.im import path 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
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
}