From 553469230b1c8a7002bc12dc205117aa1a788e2e Mon Sep 17 00:00:00 2001 From: saji Date: Tue, 16 May 2023 10:48:30 -0500 Subject: [PATCH] misc fixes and JSON stuff --- skylab/gen_skylab.go | 38 +++++++++++++++++++++++++++++++++++--- skylab/skylab.go | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/skylab/gen_skylab.go b/skylab/gen_skylab.go index c6e8a05..e0659aa 100644 --- a/skylab/gen_skylab.go +++ b/skylab/gen_skylab.go @@ -169,7 +169,7 @@ func (d *DataField) MakeUnmarshal(offset int) string { return fmt.Sprintf("p.%s = float32FromBytes(b[%d:], false)", fieldName, offset) } else if t ,ok := typeMap[d.Type]; ok { - // it's uint or int of some kind, use endian to write it. + // it's uint or int of some kind, use endian to read it. // FIXME: support big endian return fmt.Sprintf("p.%s = binary.LittleEndian.%s(b[%d:])", fieldName, toCamelInitCase(t, true), offset) } @@ -310,6 +310,7 @@ package skylab import ( "errors" "encoding/binary" + "encoding/json" ) type SkylabId uint32 @@ -343,7 +344,7 @@ func FromCanFrame(id uint32, data []byte) (Packet, error) { case {{ Nx (int $p.Id) $p.Repeat $p.Offset | mapf "0x%X" | strJoin ", " -}}: var res *{{camelCase $p.Name true}} res.UnmarshalPacket(data) - res.Idx = id - uint32({{camelCase $p.Name true}}Id) + res.Idx = id - {{$p.Id | printf "0x%X" }} return res, nil {{- else }} case {{ $p.Id | printf "0x%X" }}: @@ -356,6 +357,34 @@ func FromCanFrame(id uint32, data []byte) (Packet, error) { return nil, errors.New("failed to match Id, something is really wrong!") } + +func FromJson (raw []byte) (Packet, error) { + // attempt to parse the JSON to a JSONPacket + jp := &JSONPacket{} + err := json.Unmarshal(raw, jp) + if err != nil { + return nil, err + } + switch jp.Id { +{{- range $p := .Packets }} + {{- if $p.Repeat }} + case {{ Nx (int $p.Id) $p.Repeat $p.Offset | mapf "0x%X" | strJoin ", " -}}: + var res *{{camelCase $p.Name true}} + err := json.Unmarshal(jp.Data, res) + res.Idx = jp.Id - {{ $p.Id | printf "0x%X" }} + return res, err + {{- else }} + case {{ $p.Id | printf "0x%X" }}: + var res *{{camelCase $p.Name true}} + err := json.Unmarshal(jp.Data, res) + return res, err + {{- end }} +{{- end }} + } + + return nil, errors.New("aaa") + +} {{range .Packets -}} {{template "packet" .}} {{- end}} @@ -432,7 +461,8 @@ func uint32ToInt(i uint32) (o int) { // strJoin is a remapping of strings.Join so that we can use -// it in a pipeline more easily. +// it in a pipeline. +// {{.Names | strJoin ", " }} func strJoin(delim string, elems []string) string { return strings.Join(elems, delim) } @@ -447,6 +477,7 @@ func mapf(format string, els []int) []string { return resp } + func main() { // read path as the first arg, glob it for yamls, read each yaml into a skylabFile. // then take each skylab file, put all the packets into one big array. @@ -458,6 +489,7 @@ func main() { fmt.Printf("err %v", err) } + // we add any functions mapping we need here. fnMap := template.FuncMap{ "camelCase": toCamelInitCase, "Time": time.Now, diff --git a/skylab/skylab.go b/skylab/skylab.go index 183f26d..c44715c 100644 --- a/skylab/skylab.go +++ b/skylab/skylab.go @@ -2,6 +2,7 @@ package skylab import ( "encoding/binary" + "encoding/json" "math" ) @@ -10,7 +11,7 @@ This file provides helpers used for serializing and deserializing skylab packets It contains common code and interfaces. */ - +// float32ToBytes is an internal function used to encode a float value to bytes func float32ToBytes(b []byte, f float32, bigEndian bool) { bits := math.Float32bits(f) if bigEndian { @@ -20,6 +21,7 @@ func float32ToBytes(b []byte, f float32, bigEndian bool) { } } +// float32FromBytes is an internal function used to decode float value from bytes func float32FromBytes(b []byte, bigEndian bool) (f float32) { var bits uint32 if bigEndian { @@ -36,20 +38,24 @@ type Packet interface { UnmarshalPacket(p []byte) error Id() uint32 Size() uint - String() string } +// Marshaler is a packet that can be marshalled into bytes. type Marshaler interface { MarshalPacket() ([]byte, error) } + +// Unmarshaler is a packet that can be unmarshalled from bytes. type Unmarshaler interface { UnmarshalPacket(p []byte) error } +// Ider is a packet that can get its ID, based on the index of the packet, if any. type Ider interface { Id() uint32 } +// Sizer allows for fast allocation. type Sizer interface { Size() uint } @@ -59,3 +65,31 @@ func CanSend(p Packet) error { return nil } + + + +// ---- JSON encoding business ---- + + +type JSONPacket struct { + Id uint32 + Data json.RawMessage +} + +func ToJson(p Packet) (*JSONPacket, error) { + + d, err := json.Marshal(p) + + if err != nil { + return nil, err + } + + jp := &JSONPacket{ + Id: p.Id(), + Data: d, + } + return jp, nil +} + +// we need to be able to parse the JSON as well. +// this is done using the generator since we can use the switch/case thing.