all Dbus methods covered.
Now to add some niceties and add tests.
This commit is contained in:
112
utils.go
112
utils.go
@@ -1,6 +1,10 @@
|
||||
package gokwallet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"strings"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
@@ -59,3 +63,111 @@ func bytemapKeys(variant dbus.Variant) (keyNames []string) {
|
||||
|
||||
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, &k); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = binary.Write(buf, binary.BigEndian, &vLen); err != nil {
|
||||
return
|
||||
}
|
||||
if err = binary.Write(buf, binary.BigEndian, &v); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
raw = buf.Bytes()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user