-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.go
173 lines (132 loc) · 3.67 KB
/
utils.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package gokwallet
import (
"bytes"
"encoding/binary"
"strings"
"github.com/godbus/dbus/v5"
)
/*
resultCheck checks the result code from a Dbus call and returns an error if not successful.
See also resultPassed.
*/
func resultCheck(result int32) (err error) {
// This is technically way more complex than it needs to be, but is extendable for future use.
switch i := result; i {
case DbusSuccess:
err = nil
case DbusFailure:
err = ErrOperationFailed
default:
err = ErrOperationFailed
}
return
}
/*
resultPassed checks the result code from a Dbus call and returns a boolean as to whether the result is pass or not.
See also resultCheck.
*/
func resultPassed(result int32) (passed bool) {
// This is technically way more complex than it needs to be, but is extendable for future use.
switch i := result; i {
case DbusSuccess:
passed = true
case DbusFailure:
passed = false
default:
passed = false
}
return
}
// bytemapKeys is used to parse out Map names when fetching from Dbus.
func bytemapKeys(variant dbus.Variant) (keyNames []string) {
var d map[string]dbus.Variant
d = variant.Value().(map[string]dbus.Variant)
keyNames = make([]string, len(d))
idx := 0
for k, _ := range d {
keyNames[idx] = k
idx++
}
return
}
// bytesToMap takes a byte slice and returns a map[string]string based on a Dbus QMap struct(ure).
func bytesToMap(raw []byte) (m map[string]string, numEntries uint32, err error) {
var buf *bytes.Reader
var kLen uint32
var vLen uint32
var k []byte
var v []byte
/*
I considered using:
- https://github.com/lunixbochs/struc
- https://github.com/roman-kachanovsky/go-binary-pack
- https://github.com/go-restruct/restruct
The second hasn't been updated in quite some time, the first or third would have been a headache due to the variable length,
and ultimately I felt it was silly to add a dependency for only a single piece of data (Map).
So sticking to stdlib.
*/
buf = bytes.NewReader(raw)
if err = binary.Read(buf, binary.BigEndian, &numEntries); err != nil {
return
}
m = make(map[string]string, numEntries)
for i := uint32(0); i < numEntries; i++ {
if err = binary.Read(buf, binary.BigEndian, &kLen); err != nil {
return
}
k = make([]byte, kLen)
if err = binary.Read(buf, binary.BigEndian, &k); err != nil {
return
}
if err = binary.Read(buf, binary.BigEndian, &vLen); err != nil {
return
}
v = make([]byte, vLen)
if err = binary.Read(buf, binary.BigEndian, &v); err != nil {
return
}
// QMap does this infuriating thing where it separates each character with a null byte. So we need to strip them out.
k = bytes.ReplaceAll(k, []byte{0x0}, []byte{})
v = bytes.ReplaceAll(v, []byte{0x0}, []byte{})
m[string(k)] = string(v)
}
return
}
// mapToBytes performs the inverse of bytesToMap.
func mapToBytes(m map[string]string) (raw []byte, err error) {
var numEntries uint32
var buf *bytes.Buffer
var kLen uint32
var vLen uint32
var kB []byte
var vB []byte
if m == nil {
err = ErrInvalidMap
return
}
numEntries = uint32(len(m))
buf = &bytes.Buffer{}
if err = binary.Write(buf, binary.BigEndian, &numEntries); err != nil {
return
}
for k, v := range m {
kB = []byte(strings.Join(strings.Split(k, ""), "\x00"))
vB = []byte(strings.Join(strings.Split(v, ""), "\x00"))
kLen = uint32(len(kB))
vLen = uint32(len(vB))
if err = binary.Write(buf, binary.BigEndian, &kLen); err != nil {
return
}
if err = binary.Write(buf, binary.BigEndian, &kB); err != nil {
return
}
if err = binary.Write(buf, binary.BigEndian, &vLen); err != nil {
return
}
if err = binary.Write(buf, binary.BigEndian, &vB); err != nil {
return
}
}
raw = buf.Bytes()
return
}