~rbn/neinp

ref: 280ca11dc4f314d4bb506de2f219eb70dd959227 neinp/message/version.go -rw-r--r-- 2.3 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
package message

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

/*TVersion initializes a new connection.

Msize is the maximum message size the client will ever create, and
includes _all_ protocol data (also 9p type, tag and size fields).
As the contents of these fields are handled by neinp.Server, the msize
has to include the length of the size (4 octets) type (1 octet) and tag (2 octets) fields,
even if not visible to neinp.P2000 implementers. The msize returned with RVersion
will be read by neinp.Server to setup a io.LimitReader for message reception.

Version identifies the level of the protocol, it must always start with
"9P" (though not enforced here).

See also: http://man.cat-v.org/inferno/5/version
*/
type TVersion struct {
	Msize   uint32
	Version string
}

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

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

	return n1 + n2, nil
}

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

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

	m.Msize = msize
	m.Version = version
	return n1 + n2, nil
}

/*RVersion is the servers reply to a TVersionMessage.

Msize must be lower or equal of what the client requested.

Version may be set to the clients version string or a string
of an earlier protocol version. If the server doesn't understand
the requested version, it replies with the version string "unknown".

A version request starts a new session, so any remaining I/O operations
are aborted and allocated fids are clunked.

See also: http://man.cat-v.org/inferno/5/version
*/
type RVersion struct {
	Msize   uint32
	Version string
}

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

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

	return n1 + n2, nil
}

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

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

	m.Msize = msize
	m.Version = version
	return n1 + n2, nil
}