diff --git a/skylab/gen_skylab.go b/skylab/gen_skylab.go index 905e13c..cf0fdcb 100644 --- a/skylab/gen_skylab.go +++ b/skylab/gen_skylab.go @@ -226,173 +226,6 @@ func (p PacketDef) MakeUnmarshal() string { return buf.String() } -var templ = ` -{{ define "packet" }} -{{- $structName := camelCase .Name true}} - -{{- /* generate any bitfield structs */ -}} -{{range .Data -}} -{{ if .Bits -}} -{{- $bfname := (printf "%s%s" $structName (camelCase .Name true)) }} -type {{$bfname}} struct { - {{- range $el := .Bits}} - {{camelCase $el.Name true}} bool - {{- end}} -} - -func (p *{{$bfname}}) Marshal() byte { - var b byte - {{- range $idx, $el := .Bits}} - {{- $bitName := camelCase $el.Name true}} - if p.{{$bitName}} { - b |= 1 << {{$idx}} - } - {{- end}} - return b -} - -func (p *{{$bfname}}) Unmarshal(b byte) { - {{- range $idx, $el := .Bits}} - {{- $bitName := camelCase $el.Name true }} - p.{{$bitName}} = (b & (1 << {{ $idx }})) != 0 - {{- end}} -} -{{end}} -{{- end}} - -// {{$structName}} is {{.Description}} -type {{$structName}} struct { -{{- range .Data}} - {{ if .Units -}} // {{.Conversion}} {{.Units}} {{- end }} - {{.ToStructMember $structName }} -{{- end}} -{{- if .Repeat }} - // Idx is the packet index. The accepted range is 0-{{.Repeat}} - Idx uint32 -{{- end }} -} - -func (p *{{$structName}}) Id() (uint32, error) { -{{- if .Repeat }} - if p.Idx >= {{.Repeat}} { - return 0, errors.New("invalid packet index") - } - return {{ printf "0x%X" .Id }} + p.Idx, nil -{{- else }} - return {{ printf "0x%X" .Id }}, nil -{{- end }} -} - -func (p *{{$structName}}) Size() uint { - return {{.CalcSize}} -} - -func (p *{{$structName}}) MarshalPacket() ([]byte, error) { - b := make([]byte, {{ .CalcSize }}) -{{.MakeMarshal}} - return b, nil -} - -func (p *{{$structName}}) UnmarshalPacket(b []byte) error { -{{.MakeUnmarshal}} - return nil -} - -func (p *{{$structName}}) String() string { - return "" -} - -{{ end }} - -{{- /* begin actual file template */ -}} - -// generated by gen_skylab.go at {{ Time }} DO NOT EDIT! - -package skylab - -import ( - "errors" - "encoding/binary" - "encoding/json" -) - -type SkylabId uint32 - -const ( -{{- range .Packets }} - {{camelCase .Name true}}Id SkylabId = {{.Id | printf "0x%X"}} -{{- end}} -) - -// list of every packet ID. can be used for O(1) checks. -var idMap = map[uint32]bool{ - {{ range $p := .Packets -}} - {{ if $p.Repeat }} - {{ range $idx := Nx (int $p.Id) $p.Repeat $p.Offset -}} - {{ $idx | printf "0x%X"}}: true, - {{ end }} - {{- else }} - {{ $p.Id | printf "0x%X" }}: true, - {{- end}} - {{- end}} -} - -func FromCanFrame(id uint32, data []byte) (Packet, error) { - if !idMap[id] { - return nil, errors.New("Unknown Id") - } - switch 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}} - res.UnmarshalPacket(data) - res.Idx = id - {{$p.Id | printf "0x%X" }} - return res, nil - {{- else }} - case {{ $p.Id | printf "0x%X" }}: - var res *{{camelCase $p.Name true}} - res.UnmarshalPacket(data) - return res, nil - {{- end}} -{{- end}} - } - - 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}} -` - // stolen camelCaser code. initCase = true means CamelCase, false means camelCase func toCamelInitCase(s string, initCase bool) string { @@ -502,13 +335,12 @@ func main() { "strJoin": strJoin, "mapf": mapf, } - tmpl, err := template.New("skylab").Funcs(fnMap).Parse(templ) + tmpl, err := template.New("golang.go.tmpl").Funcs(fnMap).ParseFiles("templates/golang.go.tmpl") if err != nil { panic(err) } - f, err := os.Create("skylab_gen.go") if err != nil { panic(err) diff --git a/skylab/templates/golang.go.tmpl b/skylab/templates/golang.go.tmpl new file mode 100644 index 0000000..7a4d4c8 --- /dev/null +++ b/skylab/templates/golang.go.tmpl @@ -0,0 +1,165 @@ +{{ define "packet" }} +{{- $structName := camelCase .Name true}} + +{{- /* generate any bitfield structs */ -}} +{{range .Data -}} +{{ if .Bits -}} +{{- $bfname := (printf "%s%s" $structName (camelCase .Name true)) }} +type {{$bfname}} struct { + {{- range $el := .Bits}} + {{camelCase $el.Name true}} bool `json:"{{$el.Name}}"` + {{- end}} +} + +func (p *{{$bfname}}) Marshal() byte { + var b byte + {{- range $idx, $el := .Bits}} + {{- $bitName := camelCase $el.Name true}} + if p.{{$bitName}} { + b |= 1 << {{$idx}} + } + {{- end}} + return b +} + +func (p *{{$bfname}}) Unmarshal(b byte) { + {{- range $idx, $el := .Bits}} + {{- $bitName := camelCase $el.Name true }} + p.{{$bitName}} = (b & (1 << {{ $idx }})) != 0 + {{- end}} +} +{{end}} +{{- end}} + +// {{$structName}} is {{.Description}} +type {{$structName}} struct { +{{- range .Data}} + {{- if .Units -}} // {{.Conversion}} {{.Units}} {{- end }} + {{ .ToStructMember $structName }} `json:"{{.Name}}"` +{{- end}} +{{- if .Repeat }} + // Idx is the packet index. The accepted range is 0-{{.Repeat}} + Idx uint32 +{{- end }} +} + +func (p *{{$structName}}) Id() (uint32, error) { +{{- if .Repeat }} + if p.Idx >= {{.Repeat}} { + return 0, errors.New("invalid packet index") + } + return {{ printf "0x%X" .Id }} + p.Idx, nil +{{- else }} + return {{ printf "0x%X" .Id }}, nil +{{- end }} +} + +func (p *{{$structName}}) Size() uint { + return {{.CalcSize}} +} + +func (p *{{$structName}}) MarshalPacket() ([]byte, error) { + b := make([]byte, {{ .CalcSize }}) +{{.MakeMarshal}} + return b, nil +} + +func (p *{{$structName}}) UnmarshalPacket(b []byte) error { +{{.MakeUnmarshal}} + return nil +} + +func (p *{{$structName}}) String() string { + return "" +} + +{{ end }} + +{{- /* begin actual file template */ -}} + +// generated by gen_skylab.go at {{ Time }} DO NOT EDIT! + +package skylab + +import ( + "errors" + "encoding/binary" + "encoding/json" +) + +type SkylabId uint32 + +const ( +{{- range .Packets }} + {{camelCase .Name true}}Id SkylabId = {{.Id | printf "0x%X"}} +{{- end}} +) + +// list of every packet ID. can be used for O(1) checks. +var idMap = map[uint32]bool{ + {{ range $p := .Packets -}} + {{ if $p.Repeat }} + {{ range $idx := Nx (int $p.Id) $p.Repeat $p.Offset -}} + {{ $idx | printf "0x%X"}}: true, + {{ end }} + {{- else }} + {{ $p.Id | printf "0x%X" }}: true, + {{- end}} + {{- end}} +} + +func FromCanFrame(id uint32, data []byte) (Packet, error) { + if !idMap[id] { + return nil, errors.New("Unknown Id") + } + switch 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}} + res.UnmarshalPacket(data) + res.Idx = id - {{$p.Id | printf "0x%X" }} + return res, nil + {{- else }} + case {{ $p.Id | printf "0x%X" }}: + var res *{{camelCase $p.Name true}} + res.UnmarshalPacket(data) + return res, nil + {{- end}} +{{- end}} + } + + 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}} +