-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinfo.go
146 lines (122 loc) · 3.35 KB
/
info.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
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package airport
import (
"bytes"
"encoding/binary"
)
// Info TODO
type Info struct {
records map[string]*InfoRecord
}
// NewInfo TODO
func NewInfo(retrievedBytes []byte) *Info {
info := &Info{
records: GetAllInfoRecords(),
}
if 0 == len(retrievedBytes) {
return info
}
invalidBytes := []byte{0xFF, 0xFF, 0xFF, 0xF6}
byteReader := bytes.NewReader(retrievedBytes)
for byteReader.Len() > 0 {
// read the tag
tagBytes := make([]byte, 4)
byteReader.Read(tagBytes)
// Convert to string
tag := string(tagBytes[:])
if tag == "" {
break
}
// get the corresponding element
element := info.Get(tag)
// check to make sure the element's not null, in case have received
// unknown tag: just ignore if null
if nil != element {
//read the encryption
encryptionBytes := make([]byte, 4)
byteReader.Read(encryptionBytes)
element.Encryption = RecordEncryption(info.GetIntegerValue(encryptionBytes))
//read the length
lengthBytes := make([]byte, 4)
byteReader.Read(lengthBytes)
length := info.GetIntegerValue(lengthBytes)
//read the value
valueBytes := make([]byte, length)
byteReader.Read(valueBytes)
if element.Encryption == EncryptionEncrypted {
valueBytes = DecryptBytes(CipherBytes, valueBytes)
}
// check if the value being sent is 0xFFFFFF6; this indicates
// the current value is invalid - just leave as 0. Ignore for
// IP addresses, though...
if bytes.Compare(valueBytes, invalidBytes) != 0 || element.DataType == TypeIPAddress {
element.Value = valueBytes
}
} else {
// just add an entry in hashtable
element := &InfoRecord{}
// assign the tag
element.Tag = tag
//read the encryption
encryptionBytes := make([]byte, 4)
byteReader.Read(encryptionBytes)
element.Encryption = RecordEncryption(info.GetIntegerValue(encryptionBytes))
//read the length
lengthBytes := make([]byte, 4)
byteReader.Read(lengthBytes)
length := info.GetIntegerValue(lengthBytes)
element.MaxLength = length
//read the value
valueBytes := make([]byte, length)
byteReader.Read(valueBytes)
if element.Encryption == EncryptionEncrypted {
valueBytes = DecryptBytes(CipherBytes, valueBytes)
}
// check if the value being sent is 0xFFFFFF6; this indicates
// the current value is invalid - just leave as 0. Ignore for
// IP addresses, though...
if bytes.Compare(valueBytes, invalidBytes) != 0 || element.DataType == TypeIPAddress {
element.Value = valueBytes
} else {
element.Value = make([]byte, element.MaxLength)
}
// add the element
info.Put(tag, element)
}
}
return info
}
// GetUpdateBytes TODO
func (i *Info) GetUpdateBytes() []byte {
var arr []byte
for _, element := range i.records {
arr = append(arr, element.GetUpdateBytes()...)
}
return arr
}
// GetRequestBytes TODO
func (i *Info) GetRequestBytes() []byte {
var arr []byte
for _, element := range i.records {
arr = append(arr, element.GetRequestBytes()...)
}
return arr
}
// GetIntegerValue TODO
func (i *Info) GetIntegerValue(valueBytes []byte) int32 {
var val int32
buf := bytes.NewReader(valueBytes)
binary.Read(buf, binary.BigEndian, &val)
return val
}
// Put TODO
func (i *Info) Put(tag string, record *InfoRecord) {
i.records[tag] = record
}
// Get TODO
func (i *Info) Get(tag string) *InfoRecord {
record, ok := i.records[tag]
if !ok {
return nil
}
return record
}