2023-09-20 03:05:44 +02:00
|
|
|
package messages
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"hash/fnv"
|
|
|
|
"reflect"
|
|
|
|
|
|
|
|
"github.com/quexten/goldwarden/logging"
|
|
|
|
)
|
|
|
|
|
|
|
|
var log = logging.GetLogger("Goldwarden", "IPC Messages")
|
|
|
|
|
|
|
|
type IPCMessageType int64
|
|
|
|
type IPCMessage struct {
|
|
|
|
Type IPCMessageType `json:"type"`
|
|
|
|
Payload []byte `json:"payload"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type parsePayload func([]byte) (interface{}, error)
|
|
|
|
|
|
|
|
var messages = map[string]parsePayload{}
|
|
|
|
var messageTypes = map[IPCMessageType]string{}
|
|
|
|
|
|
|
|
func MessageTypeForEmptyPayload(emptyPayload interface{}) IPCMessageType {
|
|
|
|
return hash(reflect.TypeOf(emptyPayload).Name())
|
|
|
|
}
|
|
|
|
|
|
|
|
func hash(s string) IPCMessageType {
|
|
|
|
h := fnv.New64()
|
|
|
|
h.Write([]byte(s))
|
|
|
|
return IPCMessageType(h.Sum64())
|
|
|
|
}
|
|
|
|
|
|
|
|
func registerPayloadParser(payloadParser parsePayload, emptyPayload interface{}) {
|
|
|
|
messages[reflect.TypeOf(emptyPayload).Name()] = payloadParser
|
|
|
|
messageTypes[hash(reflect.TypeOf(emptyPayload).Name())] = reflect.TypeOf(emptyPayload).Name()
|
|
|
|
}
|
|
|
|
|
|
|
|
func ParsePayload(message IPCMessage) interface{} {
|
|
|
|
if _, ok := messageTypes[message.Type]; !ok {
|
2023-09-20 03:52:43 +02:00
|
|
|
log.Error("Unregistered message type %d", int(message.Type))
|
2023-09-20 03:05:44 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if payload, err := messages[messageTypes[message.Type]](message.Payload); err != nil {
|
|
|
|
log.Error("Error parsing payload: %s", err.Error())
|
|
|
|
return nil
|
|
|
|
} else {
|
|
|
|
return payload
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func IPCMessageFromPayload(payload interface{}) (IPCMessage, error) {
|
|
|
|
payloadTypeName := reflect.TypeOf(payload).Name()
|
|
|
|
if _, ok := messages[payloadTypeName]; !ok {
|
|
|
|
return IPCMessage{}, errors.New("Unregistered payload type " + payloadTypeName)
|
|
|
|
}
|
|
|
|
payloadJSON, err := json.Marshal(payload)
|
|
|
|
if err != nil {
|
|
|
|
return IPCMessage{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
messageType := hash(payloadTypeName)
|
|
|
|
return IPCMessage{
|
|
|
|
Type: messageType,
|
|
|
|
Payload: payloadJSON,
|
|
|
|
}, nil
|
|
|
|
}
|