-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtypes.go
90 lines (80 loc) · 1.78 KB
/
types.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
package nsdp
import (
"bytes"
"encoding/binary"
"encoding/hex"
"io"
"sort"
)
type Header struct {
Version byte
Command Command
Status uint16
FailureTLV [4]byte
ManagerID [6]byte
AgentID [6]byte
Sequence uint32
Signature [4]byte
}
type Tag uint16
func (t Tag) String() string {
var tag [2]byte
binary.BigEndian.PutUint16(tag[:], uint16(t))
return hex.EncodeToString(tag[:])
}
type Tags map[Tag][]byte
func (t *Tags) WriteTo(w io.Writer) (n int64, err error) {
keys := make([]int, 0)
for tag := range *t {
keys = append(keys, int(tag))
}
sort.Ints(keys)
var buf bytes.Buffer
for _, key := range keys {
block := (*t)[Tag(key)]
_ = binary.Write(&buf, binary.BigEndian, uint16(key))
_ = binary.Write(&buf, binary.BigEndian, uint16(len(block)))
buf.Write(block)
}
return buf.WriteTo(w)
}
func (t *Tags) ReadFrom(r io.Reader) (n int64, err error) {
*t = make(map[Tag][]byte)
var tag Tag
var length uint16
for err != io.EOF {
err = binary.Read(r, binary.BigEndian, &tag)
if err == nil {
err = binary.Read(r, binary.BigEndian, &length)
}
if err == nil {
block := make([]byte, length)
_, err = r.Read(block)
(*t)[tag] = block
}
}
return
}
type Message struct {
Header
Tags Tags
}
func (m *Message) WriteTo(w io.Writer) (n int64, err error) {
var buf bytes.Buffer
_ = binary.Write(&buf, binary.BigEndian, &m.Header)
m.Tags[0x0000] = nil // start marker
m.Tags[0xffff] = nil // end marker
_, _ = m.Tags.WriteTo(&buf)
delete(m.Tags, 0x0000)
delete(m.Tags, 0xffff)
return buf.WriteTo(w)
}
func (m *Message) ReadFrom(r io.Reader) (n int64, err error) {
err = binary.Read(r, binary.BigEndian, &m.Header)
if err == nil {
_, err = m.Tags.ReadFrom(r)
}
delete(m.Tags, 0x0000) // start marker
delete(m.Tags, 0xffff) // end marker
return
}