From a9b2aed0a3034ab9cd75836cd1dc5fd6b66cbc7a Mon Sep 17 00:00:00 2001 From: Zachary Taylor Date: Tue, 29 Nov 2016 16:20:54 -0800 Subject: [PATCH 1/4] maps and c++ support. --- backends/cpp/init.go | 34 ++++ backends/cpp/schema.go | 38 ++++ backends/cpp/stringbuilder.go | 31 +++ backends/cpp/struct.go | 123 ++++++++++++ backends/cpp/type_array.go | 122 ++++++++++++ backends/cpp/type_bool.go | 60 ++++++ backends/cpp/type_byte.go | 56 ++++++ backends/cpp/type_defer.go | 19 ++ backends/cpp/type_float.go | 61 ++++++ backends/cpp/type_int.go | 130 ++++++++++++ backends/cpp/type_map.go | 168 ++++++++++++++++ backends/cpp/type_pointer.go | 122 ++++++++++++ backends/cpp/type_slice.go | 185 ++++++++++++++++++ backends/cpp/type_string.go | 95 +++++++++ backends/cpp/type_struct.go | 64 ++++++ backends/cpp/types.go | 117 +++++++++++ backends/golang/golang_test.go | 4 +- backends/golang/init.go | 2 +- backends/golang/schema.go | 6 +- backends/golang/struct.go | 25 +-- .../golang/testdata/array.schema.golden.go | 12 +- backends/golang/testdata/int.schema.golden.go | 4 +- backends/golang/type_array.go | 2 +- backends/golang/type_bool.go | 2 +- backends/golang/type_byte.go | 2 +- backends/golang/type_defer.go | 2 +- backends/golang/type_float.go | 2 +- backends/golang/type_int.go | 17 +- backends/golang/type_map.go | 167 ++++++++++++++++ backends/golang/type_pointer.go | 2 +- backends/golang/type_slice.go | 40 ++-- backends/golang/type_string.go | 2 +- backends/golang/type_struct.go | 4 +- backends/golang/type_time.go | 2 +- backends/golang/type_union.go | 2 +- backends/golang/types.go | 10 +- main.go | 5 +- schema/parser.go | 34 +++- schema/schema.go | 27 ++- 39 files changed, 1734 insertions(+), 66 deletions(-) create mode 100644 backends/cpp/init.go create mode 100644 backends/cpp/schema.go create mode 100644 backends/cpp/stringbuilder.go create mode 100644 backends/cpp/struct.go create mode 100644 backends/cpp/type_array.go create mode 100644 backends/cpp/type_bool.go create mode 100644 backends/cpp/type_byte.go create mode 100644 backends/cpp/type_defer.go create mode 100644 backends/cpp/type_float.go create mode 100644 backends/cpp/type_int.go create mode 100644 backends/cpp/type_map.go create mode 100644 backends/cpp/type_pointer.go create mode 100644 backends/cpp/type_slice.go create mode 100644 backends/cpp/type_string.go create mode 100644 backends/cpp/type_struct.go create mode 100644 backends/cpp/types.go create mode 100644 backends/golang/type_map.go diff --git a/backends/cpp/init.go b/backends/cpp/init.go new file mode 100644 index 0000000..68b9b18 --- /dev/null +++ b/backends/cpp/init.go @@ -0,0 +1,34 @@ +package cpp + +import ( + "flag" + + "github.com/eyrie-io/gencode/schema" +) + +type CppBackend struct { + Namespace string +} + +func (cb *CppBackend) Generate(s *schema.Schema) (string, error) { + w := &Walker{} + def, err := w.WalkSchema(s, cb.Namespace) + if err != nil { + return "", err + } + return def.String(), nil +} + +func (cb *CppBackend) Flags() *flag.FlagSet { + flags := flag.NewFlagSet("Cpp", flag.ExitOnError) + flags.StringVar(&cb.Namespace, "namespace", "main", "namespace to build the gencode system for") + return flags +} + +func (cb *CppBackend) GeneratedFilename(filename string) string { + return filename + ".gen.hpp" +} + +func init() { + schema.Register("cpp", &CppBackend{}) +} diff --git a/backends/cpp/schema.go b/backends/cpp/schema.go new file mode 100644 index 0000000..e4b1322 --- /dev/null +++ b/backends/cpp/schema.go @@ -0,0 +1,38 @@ +package cpp + +import ( + "fmt" + + "github.com/eyrie-io/gencode/schema" +) + +type Walker struct { + Needs []string + Offset int + IAdjusted bool + Unsafe bool +} + +func (w *Walker) WalkSchema(s *schema.Schema, Namespace string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + parts.Append(fmt.Sprintf(`#pragma once + +#include +#include +#include + +namespace %s { + +`, Namespace)) + for _, st := range s.Structs { + p, err := w.WalkStruct(st) + if err != nil { + return nil, err + } + parts.Join(p) + } + parts.Append(` +} +`) + return +} diff --git a/backends/cpp/stringbuilder.go b/backends/cpp/stringbuilder.go new file mode 100644 index 0000000..db41a4d --- /dev/null +++ b/backends/cpp/stringbuilder.go @@ -0,0 +1,31 @@ +package cpp + +import ( + "bytes" + "strings" + "text/template" +) + +type StringBuilder []string + +func (sb *StringBuilder) Append(s string) { + *sb = append(*sb, s) +} + +func (sb *StringBuilder) Join(s *StringBuilder) { + *sb = append(*sb, *s...) +} + +func (sb *StringBuilder) String() string { + return strings.Join(*sb, "") +} + +func (sb *StringBuilder) AddTemplate(t *template.Template, name string, data interface{}) error { + buf := &bytes.Buffer{} + err := t.ExecuteTemplate(buf, name, data) + if err != nil { + return err + } + sb.Append(buf.String()) + return nil +} diff --git a/backends/cpp/struct.go b/backends/cpp/struct.go new file mode 100644 index 0000000..6e1f842 --- /dev/null +++ b/backends/cpp/struct.go @@ -0,0 +1,123 @@ +package cpp + +import ( + "fmt" + + "github.com/eyrie-io/gencode/schema" +) + +func (w *Walker) WalkStruct(s *schema.Struct) (parts *StringBuilder, err error) { + if s.Framed { + err = fmt.Errorf("Framed structs are not supported in cpp") + return + } + parts = &StringBuilder{} + parts.Append(fmt.Sprintf(`class %s { +public: +`, s.Name)) + for _, f := range s.Fields { + p, err := w.WalkFieldDef(f) + if err != nil { + return nil, err + } + parts.Join(p) + parts.Append(` +`) + } + parts.Append(fmt.Sprintf(` +public: + uint64_t MarshalSize(); + uint64_t Marshal(uint8_t* buf); + uint64_t Unmarshal(uint8_t* buf); +}; + +uint64_t %s::MarshalSize() { + uint64_t s = 0; +`, s.Name)) + for _, f := range s.Fields { + p, err := w.WalkFieldSize(f) + if err != nil { + return nil, err + } + parts.Join(p) + } + if w.Offset > 0 { + parts.Append(fmt.Sprintf(` + s += %d;`, w.Offset)) + w.Offset = 0 + } + w.IAdjusted = false + + parts.Append(fmt.Sprintf(` + return s; +} + +uint64_t %s::Marshal(uint8_t* buf) {`, s.Name)) + parts.Append(` + uint64_t size = this->MarshalSize();`) + parts.Append(` + uint64_t i = 0; + `) + for _, f := range s.Fields { + p, err := w.WalkFieldMarshal(f) + if err != nil { + return nil, err + } + parts.Join(p) + } + parts.Append(fmt.Sprintf(` + return i+%d; +} + +uint64_t %s::Unmarshal(uint8_t* buf) { + uint64_t i = 0; + `, w.Offset, s.Name)) + w.Offset = 0 + for _, f := range s.Fields { + p, err := w.WalkFieldUnmarshal(f) + if err != nil { + return nil, err + } + parts.Join(p) + } + parts.Append(fmt.Sprintf(` + return i + %d; +} + +`, w.Offset)) + w.Offset = 0 + w.IAdjusted = false + return +} + +func (w *Walker) WalkFieldDef(s *schema.Field) (parts *StringBuilder, err error) { + switch t := s.Type.(type) { + case *schema.ArrayType: + subp, err := w.WalkTypeDef(t.SubType) + if err != nil { + return nil, err + } + parts = &StringBuilder{} + parts.Append(fmt.Sprintf(` %s %s[%d];`, subp.String(), s.Name, t.Count)) + default: + subp, err := w.WalkTypeDef(s.Type) + if err != nil { + return nil, err + } + parts = &StringBuilder{} + parts.Append(fmt.Sprintf(` %s %s;`, subp.String(), s.Name)) + } + return +} + +func (w *Walker) WalkFieldSize(s *schema.Field) (parts *StringBuilder, err error) { + return w.WalkTypeSize(s.Type, "this->"+s.Name) +} + +func (w *Walker) WalkFieldMarshal(s *schema.Field) (parts *StringBuilder, err error) { + return w.WalkTypeMarshal(s.Type, "this->"+s.Name) +} + +func (w *Walker) WalkFieldUnmarshal(s *schema.Field) (parts *StringBuilder, err error) { + return w.WalkTypeUnmarshal(s.Type, "this->"+s.Name) +} diff --git a/backends/cpp/type_array.go b/backends/cpp/type_array.go new file mode 100644 index 0000000..c9a9945 --- /dev/null +++ b/backends/cpp/type_array.go @@ -0,0 +1,122 @@ +package cpp + +import ( + "text/template" + + "github.com/eyrie-io/gencode/schema" +) + +var ( + ArrayTemps *template.Template +) + +func init() { + ArrayTemps = template.New("ArrayTemps") + template.Must(ArrayTemps.New("marshal").Parse(` + { + for (uint64_t k = 0; k < {{.Count}}; k++) { + {{.SubTypeCode}} + {{if gt .SubOffset 0 }}i += {{.SubOffset}};{{end}} + } + }`)) + template.Must(ArrayTemps.New("unmarshal").Parse(` + { + for (uint64_t k = 0; k < {{.Count}}; k++) { + {{.SubTypeCode}} + {{if gt .SubOffset 0 }}i += {{.SubOffset}};{{end}} + } + }`)) + template.Must(ArrayTemps.New("bytemarshal").Parse(` + { + memcpy(&buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}], &{{.Target}}[0], {{.Count}}); + i += {{.Count}}; + }`)) + template.Must(ArrayTemps.New("byteunmarshal").Parse(` + { + memcpy(&{{.Target}}[0], &buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}], {{.Count}}); + i += {{.Count}}; + }`)) + template.Must(ArrayTemps.New("size").Parse(` + { + for (uint64_t k = 0; k < {{.Count}}; k++) { + {{.SubTypeCode}} + {{if gt .SubOffset 0 }}s += {{.SubOffset}};{{end}} + } + }`)) + template.Must(ArrayTemps.New("bytesize").Parse(` + { + s += {{.Count}}; + }`)) + template.Must(ArrayTemps.New("field").Parse(`[{{.Count}}]`)) +} + +type ArrayTemp struct { + *schema.ArrayType + W *Walker + SubOffset int + Target string + SubTypeCode string + SubField string +} + +func (w *Walker) WalkArraySize(at *schema.ArrayType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + w.IAdjusted = true + offset := w.Offset + subtypecode, err := w.WalkTypeSize(at.SubType, target+"[k]") + if err != nil { + return nil, err + } + SubOffset := w.Offset - offset + w.Offset = offset + if _, ok := at.SubType.(*schema.ByteType); ok { + err = parts.AddTemplate(ArrayTemps, "bytesize", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), ""}) + } else { + err = parts.AddTemplate(ArrayTemps, "size", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), ""}) + } + return +} + +func (w *Walker) WalkArrayMarshal(at *schema.ArrayType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + w.IAdjusted = true + offset := w.Offset + subtypecode, err := w.WalkTypeMarshal(at.SubType, target+"[k]") + if err != nil { + return nil, err + } + SubOffset := w.Offset - offset + w.Offset = offset + subfield, err := w.WalkTypeDef(at.SubType) + if err != nil { + return nil, err + } + if _, ok := at.SubType.(*schema.ByteType); ok { + err = parts.AddTemplate(ArrayTemps, "bytemarshal", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), subfield.String()}) + } else { + err = parts.AddTemplate(ArrayTemps, "marshal", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), subfield.String()}) + } + return +} + +func (w *Walker) WalkArrayUnmarshal(at *schema.ArrayType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + w.IAdjusted = true + offset := w.Offset + subtypecode, err := w.WalkTypeUnmarshal(at.SubType, target+"[k]") + if err != nil { + return nil, err + } + SubOffset := w.Offset - offset + w.Offset = offset + subfield, err := w.WalkTypeDef(at.SubType) + if err != nil { + return nil, err + } + if _, ok := at.SubType.(*schema.ByteType); ok { + err = parts.AddTemplate(ArrayTemps, "byteunmarshal", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), subfield.String()}) + } else { + err = parts.AddTemplate(ArrayTemps, "unmarshal", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), subfield.String()}) + } + return +} diff --git a/backends/cpp/type_bool.go b/backends/cpp/type_bool.go new file mode 100644 index 0000000..e17973f --- /dev/null +++ b/backends/cpp/type_bool.go @@ -0,0 +1,60 @@ +package cpp + +import ( + "text/template" + + "github.com/eyrie-io/gencode/schema" +) + +var ( + BoolTemps *template.Template +) + +func init() { + BoolTemps = template.New("BoolTemps") + + template.Must(BoolTemps.New("marshal").Parse(` + { + if ({{.Target}}) { + buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] = 1; + } else { + buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] = 0; + } + }`)) + template.Must(BoolTemps.New("unmarshal").Parse(` + { + {{.Target}} = buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] == 1; + }`)) +} + +type BoolTemp struct { + *schema.BoolType + W *Walker + Target string +} + +func (w *Walker) WalkBoolDef(bt *schema.BoolType) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + parts.Append("bool") + return +} + +func (w *Walker) WalkBoolSize(bt *schema.BoolType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + w.Offset++ + return +} + +func (w *Walker) WalkBoolMarshal(bt *schema.BoolType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + err = parts.AddTemplate(BoolTemps, "marshal", BoolTemp{bt, w, target}) + w.Offset++ + return +} + +func (w *Walker) WalkBoolUnmarshal(bt *schema.BoolType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + err = parts.AddTemplate(BoolTemps, "unmarshal", BoolTemp{bt, w, target}) + w.Offset++ + return +} diff --git a/backends/cpp/type_byte.go b/backends/cpp/type_byte.go new file mode 100644 index 0000000..b3eaea0 --- /dev/null +++ b/backends/cpp/type_byte.go @@ -0,0 +1,56 @@ +package cpp + +import ( + "text/template" + + "github.com/eyrie-io/gencode/schema" +) + +var ( + ByteTemps *template.Template +) + +func init() { + ByteTemps = template.New("ByteTemps") + + template.Must(ByteTemps.New("marshal").Parse(` + { + buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] = {{.Target}}; + }`)) + template.Must(ByteTemps.New("unmarshal").Parse(` + { + {{.Target}} = buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}]; + }`)) +} + +type ByteTemp struct { + *schema.ByteType + W *Walker + Target string +} + +func (w *Walker) WalkByteDef(bt *schema.ByteType) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + parts.Append("uint8_t") + return +} + +func (w *Walker) WalkByteSize(bt *schema.ByteType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + w.Offset++ + return +} + +func (w *Walker) WalkByteMarshal(bt *schema.ByteType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + err = parts.AddTemplate(ByteTemps, "marshal", ByteTemp{bt, w, target}) + w.Offset++ + return +} + +func (w *Walker) WalkByteUnmarshal(bt *schema.ByteType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + err = parts.AddTemplate(ByteTemps, "unmarshal", ByteTemp{bt, w, target}) + w.Offset++ + return +} diff --git a/backends/cpp/type_defer.go b/backends/cpp/type_defer.go new file mode 100644 index 0000000..20ded84 --- /dev/null +++ b/backends/cpp/type_defer.go @@ -0,0 +1,19 @@ +package cpp + +import "github.com/eyrie-io/gencode/schema" + +func (w *Walker) WalkDeferDef(dt *schema.DeferType) (parts *StringBuilder, err error) { + return w.WalkTypeDef(dt.Resolved) +} + +func (w *Walker) WalkDeferSize(dt *schema.DeferType, target string) (parts *StringBuilder, err error) { + return w.WalkTypeSize(dt.Resolved, target) +} + +func (w *Walker) WalkDeferMarshal(dt *schema.DeferType, target string) (parts *StringBuilder, err error) { + return w.WalkTypeMarshal(dt.Resolved, target) +} + +func (w *Walker) WalkDeferUnmarshal(dt *schema.DeferType, target string) (parts *StringBuilder, err error) { + return w.WalkTypeUnmarshal(dt.Resolved, target) +} diff --git a/backends/cpp/type_float.go b/backends/cpp/type_float.go new file mode 100644 index 0000000..e12359f --- /dev/null +++ b/backends/cpp/type_float.go @@ -0,0 +1,61 @@ +package cpp + +import ( + "text/template" + + "github.com/eyrie-io/gencode/schema" +) + +var ( + FloatTemps *template.Template +) + +func init() { + FloatTemps = template.New("FloatTemps").Funcs(template.FuncMap{ + "Bytes": func(bits int) int { + return bits / 8 + }, + "BitRange": func(bits int) []int { + return []int{0, 8, 16, 24, 32, 40, 48, 56, 64}[0:(bits / 8)] + }, + }) + + template.Must(FloatTemps.New("marshal").Parse(` + memcpy(&buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}], &{{.Target}}, {{.Bits}}/8);`)) + template.Must(FloatTemps.New("unmarshal").Parse(` + memcpy(&{{.Target}}, &buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}], {{.Bits}}/8);`)) + template.Must(FloatTemps.New("field").Parse(`{{if .IsFloat}}float{{else}}double{{end}}`)) +} + +type FloatTemp struct { + *schema.FloatType + W *Walker + Target string + IsFloat bool +} + +func (w *Walker) WalkFloatDef(ft *schema.FloatType) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + err = parts.AddTemplate(FloatTemps, "field", FloatTemp{ft, w, "", ft.Bits == 32}) + return +} + +func (w *Walker) WalkFloatSize(ft *schema.FloatType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + w.Offset += ft.Bits / 8 + return +} + +func (w *Walker) WalkFloatMarshal(ft *schema.FloatType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + err = parts.AddTemplate(FloatTemps, "marshal", FloatTemp{ft, w, target, ft.Bits == 32}) + w.Offset += ft.Bits / 8 + return +} + +func (w *Walker) WalkFloatUnmarshal(ft *schema.FloatType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + err = parts.AddTemplate(FloatTemps, "unmarshal", FloatTemp{ft, w, target, ft.Bits == 32}) + w.Offset += ft.Bits / 8 + return +} diff --git a/backends/cpp/type_int.go b/backends/cpp/type_int.go new file mode 100644 index 0000000..73d6bbe --- /dev/null +++ b/backends/cpp/type_int.go @@ -0,0 +1,130 @@ +package cpp + +import ( + "text/template" + + "github.com/eyrie-io/gencode/schema" +) + +var ( + IntTemps *template.Template +) + +func init() { + IntTemps = template.New("IntTemps").Funcs(template.FuncMap{ + "Bytes": func(bits int) int { + return bits / 8 + }, + "BitRange": func(bits int) []int { + return []int{0, 8, 16, 24, 32, 40, 48, 56, 64}[0:(bits / 8)] + }, + }) + + template.Must(IntTemps.New("marshal").Parse(` + { + {{if .VarInt}}uint{{.Bits}}_t t = {{.Target}}; + {{if .Signed}}t <<= 1; + if ({{.Target}} < 0) { t = ^t; }{{end}} + while (t >= 0x80) { + buf[i + {{.W.Offset}}] = uint8_t(t) | 0x80; + t >>= 7; + i++; + } + buf[i + {{.W.Offset}}] = uint8_t(t); + i++;{{else}}memcpy(&buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}], &{{.Target}}, {{.Bits}}/8);{{end}} + }`)) + template.Must(IntTemps.New("unmarshal").Parse(` + { + {{if .VarInt}} + uint8_t bs = 7; + uint{{.Bits}}_t t = buf[i + {{.W.Offset}}] & 0x7F; + while ((buf[i + {{.W.Offset}}] & 0x80) == 0x80) { + i++; + t |= ((uint{{.Bits}}_t)buf[i + {{.W.Offset}}] & 0x7F) << bs; + bs += 7; + } + i++; + {{if .Signed}} + {{.Target}} = (int{{.Bits}}_t)(t >> 1); + if (t&1 != 0) { + {{.Target}} = ^{{.Target}}; + } + {{else}} + {{.Target}} = t; + {{end}} + {{else}} + memcpy(&{{.Target}}, &buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}], {{.Bits}}/8); + {{end}} + }`)) + template.Must(IntTemps.New("field").Parse(`{{if not .Signed}}u{{end}}int{{.Bits}}_t`)) + template.Must(IntTemps.New("size").Parse(` + { + {{if .VarInt}} + {{if .Signed}} + uint{{.Bits}}_t t := {{.Target}}; + t <<= 1; + if ({{.Target}}) < 0 { + t = ^t; + } + while (t >= 0x80) { + t >>= 7; + s++; + } + s++; + {{else}} + uint{{.Bits}}_t t = {{.Target}}; + while (t >= 0x80) { + t >>= 7; + s++; + } + s++; + {{end}} + {{end}} + }`)) +} + +type IntTemp struct { + *schema.IntType + W *Walker + Target string +} + +func (w *Walker) WalkIntDef(it *schema.IntType) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + err = parts.AddTemplate(IntTemps, "field", it) + return +} + +func (w *Walker) WalkIntSize(it *schema.IntType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + if !it.VarInt { + w.Offset += it.Bits / 8 + return + } else { + w.IAdjusted = true + } + err = parts.AddTemplate(IntTemps, "size", IntTemp{it, w, target}) + return +} + +func (w *Walker) WalkIntMarshal(it *schema.IntType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + err = parts.AddTemplate(IntTemps, "marshal", IntTemp{it, w, target}) + if !it.VarInt { + w.Offset += it.Bits / 8 + } else { + w.IAdjusted = true + } + return +} + +func (w *Walker) WalkIntUnmarshal(it *schema.IntType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + err = parts.AddTemplate(IntTemps, "unmarshal", IntTemp{it, w, target}) + if !it.VarInt { + w.Offset += it.Bits / 8 + } else { + w.IAdjusted = true + } + return +} diff --git a/backends/cpp/type_map.go b/backends/cpp/type_map.go new file mode 100644 index 0000000..05e85a3 --- /dev/null +++ b/backends/cpp/type_map.go @@ -0,0 +1,168 @@ +package cpp + +import ( + "fmt" + "text/template" + + "github.com/eyrie-io/gencode/schema" +) + +var ( + MapTemps *template.Template +) + +func init() { + MapTemps = template.New("MapTemps") + template.Must(MapTemps.New("marshal").Parse(` + { + uint64_t l = {{.Target}}.size(); + {{.VarIntCode}} + for (std::map<{{.KeySubField}}, {{.ValueSubField}}>::iterator it = {{.Target}}.begin(); it != {{.Target}}.end(); it++) { + const {{.KeySubField}}& k = it->first; + {{.KeySubTypeCode}} + const {{.ValueSubField}}& v = it->second; + {{.ValueSubTypeCode}} + } + }`)) + template.Must(MapTemps.New("unmarshal").Parse(` + { + uint64_t l = 0; + {{.VarIntCode}} + for (uint64_t x = 0; x < l; x++) { + {{.KeySubField}} k; + {{.KeySubTypeCode}} + {{.ValueSubField}} v; + {{.ValueSubTypeCode}} + {{.Target}}[k] = v; + } + }`)) + template.Must(MapTemps.New("size").Parse(` + { + uint64_t l = {{.Target}}.size(); + {{.VarIntCode}} + for (std::map<{{.KeySubField}}, {{.ValueSubField}}>::iterator it = {{.Target}}.begin(); it != {{.Target}}.end(); it++) { + const {{.KeySubField}}& k = it->first; + {{.KeySubTypeCode}} + const {{.ValueSubField}}& v = it->second; + {{.ValueSubTypeCode}} + } + }`)) +} + +type MapTemp struct { + *schema.MapType + W *Walker + Target string + KeySubTypeCode string + KeySubField string + ValueSubTypeCode string + ValueSubField string + VarIntCode string +} + +func (w *Walker) WalkMapDef(st *schema.MapType) (parts *StringBuilder, err error) { + ksub, err := w.WalkTypeDef(st.KeySubType) + if err != nil { + return nil, err + } + vsub, err := w.WalkTypeDef(st.ValueSubType) + if err != nil { + return nil, err + } + parts = &StringBuilder{} + parts.Append(fmt.Sprintf("std::map<%s, %s>", ksub.String(), vsub.String())) + return +} + +func (w *Walker) WalkMapSize(st *schema.MapType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + intHandler := &schema.IntType{ + Bits: 64, + Signed: false, + VarInt: true, + } + intcode, err := w.WalkIntSize(intHandler, "l") + if err != nil { + return nil, err + } + keysubtype, err := w.WalkTypeDef(st.KeySubType) + if err != nil { + return nil, err + } + keysubtypecode, err := w.WalkTypeSize(st.KeySubType, "k") + if err != nil { + return nil, err + } + valuesubtype, err := w.WalkTypeDef(st.ValueSubType) + if err != nil { + return nil, err + } + valuesubtypecode, err := w.WalkTypeSize(st.ValueSubType, "v") + if err != nil { + return nil, err + } + err = parts.AddTemplate(MapTemps, "size", MapTemp{st, w, target, keysubtypecode.String(), keysubtype.String(), valuesubtypecode.String(), valuesubtype.String(), intcode.String()}) + return +} + +func (w *Walker) WalkMapMarshal(st *schema.MapType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + intHandler := &schema.IntType{ + Bits: 64, + Signed: false, + VarInt: true, + } + intcode, err := w.WalkIntMarshal(intHandler, "l") + if err != nil { + return nil, err + } + keysubtype, err := w.WalkTypeDef(st.KeySubType) + if err != nil { + return nil, err + } + keysubtypecode, err := w.WalkTypeMarshal(st.KeySubType, "k") + if err != nil { + return nil, err + } + valuesubtype, err := w.WalkTypeDef(st.ValueSubType) + if err != nil { + return nil, err + } + valuesubtypecode, err := w.WalkTypeMarshal(st.ValueSubType, "v") + if err != nil { + return nil, err + } + err = parts.AddTemplate(MapTemps, "marshal", MapTemp{st, w, target, keysubtypecode.String(), keysubtype.String(), valuesubtypecode.String(), valuesubtype.String(), intcode.String()}) + return +} + +func (w *Walker) WalkMapUnmarshal(st *schema.MapType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + intHandler := &schema.IntType{ + Bits: 64, + Signed: false, + VarInt: true, + } + intcode, err := w.WalkIntUnmarshal(intHandler, "l") + if err != nil { + return nil, err + } + keysubtype, err := w.WalkTypeDef(st.KeySubType) + if err != nil { + return nil, err + } + keysubtypecode, err := w.WalkTypeUnmarshal(st.KeySubType, "k") + if err != nil { + return nil, err + } + valuesubtype, err := w.WalkTypeDef(st.ValueSubType) + if err != nil { + return nil, err + } + valuesubtypecode, err := w.WalkTypeUnmarshal(st.ValueSubType, "v") + if err != nil { + return nil, err + } + err = parts.AddTemplate(MapTemps, "unmarshal", MapTemp{st, w, target, keysubtypecode.String(), keysubtype.String(), valuesubtypecode.String(), valuesubtype.String(), intcode.String()}) + return +} diff --git a/backends/cpp/type_pointer.go b/backends/cpp/type_pointer.go new file mode 100644 index 0000000..ce6d68a --- /dev/null +++ b/backends/cpp/type_pointer.go @@ -0,0 +1,122 @@ +package cpp + +import ( + "fmt" + "text/template" + + "github.com/eyrie-io/gencode/schema" +) + +var ( + PointerTemps *template.Template +) + +func init() { + PointerTemps = template.New("PointerTemps") + template.Must(PointerTemps.New("marshal").Parse(` + { + if ({{.Target}} == NULL) { + buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] = 0; + } else { + buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] = 1; + {{.SubTypeCode}} + i += {{.SubOffset}}; + } + }`)) + template.Must(PointerTemps.New("unmarshal").Parse(` + { + if (buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] == 1) { + if ({{.Target}} == NULL) { + {{.Target}} = new class {{.SubField}}(); + } + {{.SubTypeCode}} + i += {{.SubOffset}}; + } else { + {{.Target}} = NULL; + } + }`)) + template.Must(PointerTemps.New("size").Parse(` + { + if ({{.Target}} != NULL) { + {{.SubTypeCode}} + s += {{.SubOffset}}; + } + }`)) + + template.Must(PointerTemps.New("field").Parse(`*`)) +} + +type PointerTemp struct { + *schema.PointerType + W *Walker + SubOffset int + Target string + SubTypeCode string + SubField string +} + +func (w *Walker) WalkPointerDef(pt *schema.PointerType) (parts *StringBuilder, err error) { + sub, err := w.WalkTypeDef(pt.SubType) + if err != nil { + return nil, err + } + parts = &StringBuilder{} + parts.Append(fmt.Sprintf("%s*", sub.String())) + return +} + +func (w *Walker) WalkPointerSize(pt *schema.PointerType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + Offset := w.Offset + w.Offset++ + subtypecode, err := w.WalkTypeSize(pt.SubType, "(*"+target+")") + if err != nil { + return nil, err + } + SubOffset := w.Offset - (Offset + 1) + w.Offset = Offset + err = parts.AddTemplate(PointerTemps, "size", PointerTemp{pt, w, SubOffset, target, subtypecode.String(), ""}) + w.Offset++ + w.IAdjusted = true + return +} + +func (w *Walker) WalkPointerMarshal(pt *schema.PointerType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + Offset := w.Offset + w.Offset++ + subtypecode, err := w.WalkTypeMarshal(pt.SubType, "(*"+target+")") + if err != nil { + return nil, err + } + subfield, err := w.WalkTypeDef(pt.SubType) + if err != nil { + return nil, err + } + SubOffset := w.Offset - (Offset + 1) + w.Offset = Offset + err = parts.AddTemplate(PointerTemps, "marshal", PointerTemp{pt, w, SubOffset, target, subtypecode.String(), subfield.String()}) + w.IAdjusted = true + w.Offset++ + return +} + +func (w *Walker) WalkPointerUnmarshal(pt *schema.PointerType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + Offset := w.Offset + w.Offset++ + subtypecode, err := w.WalkTypeUnmarshal(pt.SubType, "(*"+target+")") + if err != nil { + return nil, err + } + subfield, err := w.WalkTypeDef(pt.SubType) + if err != nil { + return nil, err + } + SubOffset := w.Offset - (Offset + 1) + w.Offset = Offset + err = parts.AddTemplate(PointerTemps, "unmarshal", PointerTemp{pt, w, SubOffset, target, subtypecode.String(), subfield.String()}) + w.IAdjusted = true + w.Offset++ + return +} diff --git a/backends/cpp/type_slice.go b/backends/cpp/type_slice.go new file mode 100644 index 0000000..c27c125 --- /dev/null +++ b/backends/cpp/type_slice.go @@ -0,0 +1,185 @@ +package cpp + +import ( + "fmt" + "strconv" + "strings" + "text/template" + + "github.com/eyrie-io/gencode/schema" +) + +var ( + SliceTemps *template.Template +) + +func init() { + SliceTemps = template.New("SliceTemps") + template.Must(SliceTemps.New("marshal").Parse(` + { + uint64_t l{{.Depth}} = {{.Target}}.size(); + {{.VarIntCode}} + for (uint64_t k{{.Depth}} = 0; k{{.Depth}} < l{{.Depth}}; k{{.Depth}}++) { + {{.SubTypeCode}} + {{if gt .SubOffset 0 }}i += {{.SubOffset}};{{end}} + } + }`)) + template.Must(SliceTemps.New("unmarshal").Parse(` + { + uint64_t l{{.Depth}} = 0; + {{.VarIntCode}} + {{.Target}}.resize(l{{.Depth}}); + for (uint64_t k{{.Depth}} = 0; k{{.Depth}} < l{{.Depth}}; k{{.Depth}}++) { + {{.SubTypeCode}} + {{if gt .SubOffset 0 }}i += {{.SubOffset}};{{end}} + } + }`)) + template.Must(SliceTemps.New("bytemarshal").Parse(` + { + uint64_t l{{.Depth}} = {{.Target}}.size(); + {{.VarIntCode}} + memcpy(&buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}], &{{.Target}}[0], l{{.Depth}}); + i += l{{.Depth}}; + }`)) + template.Must(SliceTemps.New("byteunmarshal").Parse(` + { + uint64_t l{{.Depth}} = 0; + {{.VarIntCode}} + {{.Target}}.resize(l{{.Depth}}); + memcpy(&{{.Target}}[0], &buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}], l); + i += l{{.Depth}}; + }`)) + template.Must(SliceTemps.New("size").Parse(` + { + uint64_t l{{.Depth}} = {{.Target}}.size(); + {{.VarIntCode}} + {{if eq .SubTypeCode "" }} + {{if gt .SubOffset 0 }} + s += {{.SubOffset}}*l{{.Depth}}; + {{end}} + {{else}} + for (uint64_t k{{.Depth}} = 0; k{{.Depth}} < l{{.Depth}}; k{{.Depth}}++) { + {{.SubTypeCode}} + {{if gt .SubOffset 0 }}s += {{.SubOffset}};{{end}} + } + {{end}} + }`)) + template.Must(SliceTemps.New("bytesize").Parse(` + { + uint64_t l{{.Depth}} = {{.Target}}.size(); + {{.VarIntCode}} + s += l{{.Depth}}; + }`)) + template.Must(SliceTemps.New("field").Parse(`[]`)) +} + +type SliceTemp struct { + *schema.SliceType + W *Walker + SubOffset int + Target string + SubTypeCode string + SubField string + VarIntCode string + Depth int +} + +func (w *Walker) WalkSliceDef(st *schema.SliceType) (parts *StringBuilder, err error) { + sub, err := w.WalkTypeDef(st.SubType) + if err != nil { + return nil, err + } + parts = &StringBuilder{} + x := sub.String() + if strings.HasSuffix(x, ">") { + x = x + " " + } + parts.Append(fmt.Sprintf("std::vector<%s>", x)) + return +} + +func (w *Walker) WalkSliceSize(st *schema.SliceType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + intHandler := &schema.IntType{ + Bits: 64, + Signed: false, + VarInt: true, + } + intcode, err := w.WalkIntSize(intHandler, "l"+strconv.Itoa(st.Depth)) + if err != nil { + return nil, err + } + offset := w.Offset + subtypecode, err := w.WalkTypeSize(st.SubType, target+"[k"+strconv.Itoa(st.Depth)+"]") + if err != nil { + return nil, err + } + SubOffset := w.Offset - offset + w.Offset = offset + if _, ok := st.SubType.(*schema.ByteType); ok { + err = parts.AddTemplate(SliceTemps, "bytesize", SliceTemp{st, w, SubOffset, target, subtypecode.String(), "", intcode.String(), st.Depth}) + } else { + err = parts.AddTemplate(SliceTemps, "size", SliceTemp{st, w, SubOffset, target, subtypecode.String(), "", intcode.String(), st.Depth}) + } + return +} + +func (w *Walker) WalkSliceMarshal(st *schema.SliceType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + intHandler := &schema.IntType{ + Bits: 64, + Signed: false, + VarInt: true, + } + intcode, err := w.WalkIntMarshal(intHandler, "l"+strconv.Itoa(st.Depth)) + if err != nil { + return nil, err + } + offset := w.Offset + subtypecode, err := w.WalkTypeMarshal(st.SubType, target+"[k"+strconv.Itoa(st.Depth)+"]") + if err != nil { + return nil, err + } + SubOffset := w.Offset - offset + w.Offset = offset + subfield, err := w.WalkTypeDef(st.SubType) + if err != nil { + return nil, err + } + if _, ok := st.SubType.(*schema.ByteType); ok { + err = parts.AddTemplate(SliceTemps, "bytemarshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), st.Depth}) + } else { + err = parts.AddTemplate(SliceTemps, "marshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), st.Depth}) + } + return +} + +func (w *Walker) WalkSliceUnmarshal(st *schema.SliceType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + intHandler := &schema.IntType{ + Bits: 64, + Signed: false, + VarInt: true, + } + intcode, err := w.WalkIntUnmarshal(intHandler, "l"+strconv.Itoa(st.Depth)) + if err != nil { + return nil, err + } + offset := w.Offset + subtypecode, err := w.WalkTypeUnmarshal(st.SubType, target+"[k"+strconv.Itoa(st.Depth)+"]") + if err != nil { + return nil, err + } + SubOffset := w.Offset - offset + w.Offset = offset + subfield, err := w.WalkTypeDef(st.SubType) + if err != nil { + return nil, err + } + if _, ok := st.SubType.(*schema.ByteType); ok { + err = parts.AddTemplate(SliceTemps, "byteunmarshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), st.Depth}) + } else { + err = parts.AddTemplate(SliceTemps, "unmarshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), st.Depth}) + } + return +} diff --git a/backends/cpp/type_string.go b/backends/cpp/type_string.go new file mode 100644 index 0000000..77f72e5 --- /dev/null +++ b/backends/cpp/type_string.go @@ -0,0 +1,95 @@ +package cpp + +import ( + "text/template" + + "github.com/eyrie-io/gencode/schema" +) + +var ( + StringTemps *template.Template +) + +func init() { + StringTemps = template.New("StringTemps") + + template.Must(StringTemps.New("marshal").Parse(` + { + uint64_t l = {{.Target}}.length(); + {{.VarIntCode}} + memcpy(&buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}], {{.Target}}.c_str(), l); + i += l; + }`)) + template.Must(StringTemps.New("unmarshal").Parse(` + { + uint64_t l = 0; + {{.VarIntCode}} + {{.Target}}.assign((const char*)&buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}], l); + i += l; + }`)) + template.Must(StringTemps.New("size").Parse(` + { + uint64_t l = {{.Target}}.length(); + {{.VarIntCode}} + s += l; + }`)) + template.Must(StringTemps.New("field").Parse(`std::string`)) +} + +type StringTemp struct { + *schema.StringType + W *Walker + Target string + VarIntCode string +} + +func (w *Walker) WalkStringDef(st *schema.StringType) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + err = parts.AddTemplate(StringTemps, "field", st) + return +} + +func (w *Walker) WalkStringSize(st *schema.StringType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + intHandler := &schema.IntType{ + Bits: 64, + Signed: false, + VarInt: true, + } + intcode, err := w.WalkIntSize(intHandler, "l") + if err != nil { + return nil, err + } + err = parts.AddTemplate(StringTemps, "size", StringTemp{st, w, target, intcode.String()}) + return +} + +func (w *Walker) WalkStringMarshal(st *schema.StringType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + intHandler := &schema.IntType{ + Bits: 64, + Signed: false, + VarInt: true, + } + intcode, err := w.WalkIntMarshal(intHandler, "l") + if err != nil { + return nil, err + } + err = parts.AddTemplate(StringTemps, "marshal", StringTemp{st, w, target, intcode.String()}) + return +} + +func (w *Walker) WalkStringUnmarshal(st *schema.StringType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + intHandler := &schema.IntType{ + Bits: 64, + Signed: false, + VarInt: true, + } + intcode, err := w.WalkIntUnmarshal(intHandler, "l") + if err != nil { + return nil, err + } + err = parts.AddTemplate(StringTemps, "unmarshal", StringTemp{st, w, target, intcode.String()}) + return +} diff --git a/backends/cpp/type_struct.go b/backends/cpp/type_struct.go new file mode 100644 index 0000000..346814c --- /dev/null +++ b/backends/cpp/type_struct.go @@ -0,0 +1,64 @@ +package cpp + +import ( + "text/template" + + "github.com/eyrie-io/gencode/schema" +) + +var ( + StructTemps *template.Template +) + +func init() { + StructTemps = template.New("StructTemps") + + template.Must(StructTemps.New("marshal").Parse(` + { + uint64_t nbuf = {{.Target}}.Marshal(&buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}]); + i += nbuf; + }`)) + template.Must(StructTemps.New("unmarshal").Parse(` + { + uint64_t ni = {{.Target}}.Unmarshal(&buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}]); + i += ni; + }`)) + template.Must(StructTemps.New("size").Parse(` + { + s += {{.Target}}.MarshalSize(); + }`)) + template.Must(StructTemps.New("field").Parse(`{{.Struct}}`)) +} + +type StructTemp struct { + *schema.StructType + W *Walker + Target string +} + +func (w *Walker) WalkStructDef(st *schema.StructType) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + err = parts.AddTemplate(StructTemps, "field", st) + return +} + +func (w *Walker) WalkStructSize(st *schema.StructType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + err = parts.AddTemplate(StructTemps, "size", StructTemp{st, w, target}) + w.IAdjusted = true + return +} + +func (w *Walker) WalkStructMarshal(st *schema.StructType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + err = parts.AddTemplate(StructTemps, "marshal", StructTemp{st, w, target}) + w.IAdjusted = true + return +} + +func (w *Walker) WalkStructUnmarshal(st *schema.StructType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + err = parts.AddTemplate(StructTemps, "unmarshal", StructTemp{st, w, target}) + w.IAdjusted = true + return +} diff --git a/backends/cpp/types.go b/backends/cpp/types.go new file mode 100644 index 0000000..0c3011e --- /dev/null +++ b/backends/cpp/types.go @@ -0,0 +1,117 @@ +package cpp + +import ( + "fmt" + + "github.com/eyrie-io/gencode/schema" +) + +func (w *Walker) WalkTypeDef(t schema.Type) (*StringBuilder, error) { + switch tt := t.(type) { + case *schema.BoolType: + return w.WalkBoolDef(tt) + case *schema.ByteType: + return w.WalkByteDef(tt) + case *schema.DeferType: + return w.WalkDeferDef(tt) + case *schema.FloatType: + return w.WalkFloatDef(tt) + case *schema.IntType: + return w.WalkIntDef(tt) + case *schema.PointerType: + return w.WalkPointerDef(tt) + case *schema.SliceType: + return w.WalkSliceDef(tt) + case *schema.MapType: + return w.WalkMapDef(tt) + case *schema.StringType: + return w.WalkStringDef(tt) + case *schema.StructType: + return w.WalkStructDef(tt) + } + return nil, fmt.Errorf("No such type %T", t) +} + +func (w *Walker) WalkTypeSize(t schema.Type, target string) (*StringBuilder, error) { + switch tt := t.(type) { + case *schema.ArrayType: + return w.WalkArraySize(tt, target) + case *schema.BoolType: + return w.WalkBoolSize(tt, target) + case *schema.ByteType: + return w.WalkByteSize(tt, target) + case *schema.DeferType: + return w.WalkDeferSize(tt, target) + case *schema.FloatType: + return w.WalkFloatSize(tt, target) + case *schema.IntType: + return w.WalkIntSize(tt, target) + case *schema.PointerType: + return w.WalkPointerSize(tt, target) + case *schema.SliceType: + return w.WalkSliceSize(tt, target) + case *schema.MapType: + return w.WalkMapSize(tt, target) + case *schema.StringType: + return w.WalkStringSize(tt, target) + case *schema.StructType: + return w.WalkStructSize(tt, target) + } + return nil, fmt.Errorf("No such type %T", t) +} + +func (w *Walker) WalkTypeMarshal(t schema.Type, target string) (*StringBuilder, error) { + switch tt := t.(type) { + case *schema.ArrayType: + return w.WalkArrayMarshal(tt, target) + case *schema.BoolType: + return w.WalkBoolMarshal(tt, target) + case *schema.ByteType: + return w.WalkByteMarshal(tt, target) + case *schema.DeferType: + return w.WalkDeferMarshal(tt, target) + case *schema.FloatType: + return w.WalkFloatMarshal(tt, target) + case *schema.IntType: + return w.WalkIntMarshal(tt, target) + case *schema.PointerType: + return w.WalkPointerMarshal(tt, target) + case *schema.SliceType: + return w.WalkSliceMarshal(tt, target) + case *schema.MapType: + return w.WalkMapMarshal(tt, target) + case *schema.StringType: + return w.WalkStringMarshal(tt, target) + case *schema.StructType: + return w.WalkStructMarshal(tt, target) + } + return nil, fmt.Errorf("No such type %T", t) +} + +func (w *Walker) WalkTypeUnmarshal(t schema.Type, target string) (*StringBuilder, error) { + switch tt := t.(type) { + case *schema.ArrayType: + return w.WalkArrayUnmarshal(tt, target) + case *schema.BoolType: + return w.WalkBoolUnmarshal(tt, target) + case *schema.ByteType: + return w.WalkByteUnmarshal(tt, target) + case *schema.DeferType: + return w.WalkDeferUnmarshal(tt, target) + case *schema.FloatType: + return w.WalkFloatUnmarshal(tt, target) + case *schema.IntType: + return w.WalkIntUnmarshal(tt, target) + case *schema.PointerType: + return w.WalkPointerUnmarshal(tt, target) + case *schema.SliceType: + return w.WalkSliceUnmarshal(tt, target) + case *schema.MapType: + return w.WalkMapUnmarshal(tt, target) + case *schema.StringType: + return w.WalkStringUnmarshal(tt, target) + case *schema.StructType: + return w.WalkStructUnmarshal(tt, target) + } + return nil, fmt.Errorf("No such type %T", t) +} diff --git a/backends/golang/golang_test.go b/backends/golang/golang_test.go index 70a6f1c..50bbd76 100644 --- a/backends/golang/golang_test.go +++ b/backends/golang/golang_test.go @@ -10,7 +10,7 @@ import ( "strings" "testing" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" "github.com/kr/pretty" ) @@ -29,7 +29,7 @@ func TestGolangBackend(t *testing.T) { } { inputF := filepath.Join("./testdata", tc) outputF := filepath.Join(dir, tc+".go") - goldenF := inputF+".golden.go" + goldenF := inputF + ".golden.go" in, err := ioutil.ReadFile(inputF) if err != nil { diff --git a/backends/golang/init.go b/backends/golang/init.go index 0e0cf01..26b5579 100644 --- a/backends/golang/init.go +++ b/backends/golang/init.go @@ -4,7 +4,7 @@ import ( "flag" "go/format" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" ) type GolangBackend struct { diff --git a/backends/golang/schema.go b/backends/golang/schema.go index d8a854e..99e032f 100644 --- a/backends/golang/schema.go +++ b/backends/golang/schema.go @@ -3,7 +3,7 @@ package golang import ( "fmt" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" ) type Walker struct { @@ -16,13 +16,13 @@ type Walker struct { func (w *Walker) WalkSchema(s *schema.Schema, Package string) (parts *StringBuilder, err error) { parts = &StringBuilder{} parts.Append(fmt.Sprintf(`package %s - + import ( "unsafe" "io" "time" ) - + var ( _ = unsafe.Sizeof(0) _ = io.ReadFull diff --git a/backends/golang/struct.go b/backends/golang/struct.go index 7818ec6..3184af8 100644 --- a/backends/golang/struct.go +++ b/backends/golang/struct.go @@ -3,7 +3,7 @@ package golang import ( "fmt" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" ) func (w *Walker) WalkStruct(s *schema.Struct) (parts *StringBuilder, err error) { @@ -26,13 +26,13 @@ func (w *Walker) WalkStruct(s *schema.Struct) (parts *StringBuilder, err error) } if !s.Framed { parts.Append(fmt.Sprintf(`} - -func (d *%s) Size() (s uint64) { + +func (d *%s) MarshalSize() (s uint64) { `, s.Name)) } else { parts.Append(fmt.Sprintf(`} - -func (d *%s) FramedSize() (s uint64, us uint64) { + +func (d *%s) MarshalFramedSize() (s uint64, us uint64) { `, s.Name)) } for _, f := range s.Fields { @@ -60,13 +60,13 @@ func (d *%s) FramedSize() (s uint64, us uint64) { parts.Join(intcode) } parts.Append(fmt.Sprintf(` - return + return }`)) if s.Framed { parts.Append(fmt.Sprintf(` -func (d *%s) Size() (s uint64) { - s, _ = d.FramedSize() +func (d *%s) MarshalSize() (s uint64) { + s, _ = d.MarshalFramedSize() return } `, s.Name)) @@ -76,10 +76,10 @@ func (d *%s) Size() (s uint64) { func (d *%s) Marshal(buf []byte) ([]byte, error) {`, s.Name)) if s.Framed { parts.Append(` - size, usize := d.FramedSize()`) + size, usize := d.MarshalFramedSize()`) } else { parts.Append(` - size := d.Size()`) + size := d.MarshalSize()`) } parts.Append(` { @@ -108,7 +108,7 @@ func (d *%s) Marshal(buf []byte) ([]byte, error) {`, s.Name)) parts.Append(fmt.Sprintf(` return buf[:i+%d], nil } - + func (d *%s) Unmarshal(buf []byte) (uint64, error) { i := uint64(0) `, w.Offset, s.Name)) @@ -206,6 +206,9 @@ func (w *Walker) WalkFieldDef(s *schema.Field) (parts *StringBuilder, err error) return nil, err } parts.Join(subp) + if s.Attribute != "" { + parts.Append(fmt.Sprintf(` %s`, s.Attribute)) + } return } diff --git a/backends/golang/testdata/array.schema.golden.go b/backends/golang/testdata/array.schema.golden.go index 891e9d5..d8f9183 100755 --- a/backends/golang/testdata/array.schema.golden.go +++ b/backends/golang/testdata/array.schema.golden.go @@ -19,7 +19,7 @@ type Array struct { D []Nested } -func (d *Array) Size() (s uint64) { +func (d *Array) MarshalSize() (s uint64) { { for k := range d.A { @@ -34,7 +34,7 @@ func (d *Array) Size() (s uint64) { _ = k // make compiler happy in case k is unused { - s += d.B[k].Size() + s += d.B[k].MarshalSize() } } @@ -73,7 +73,7 @@ func (d *Array) Size() (s uint64) { for k := range d.D { { - s += d.D[k].Size() + s += d.D[k].MarshalSize() } } @@ -82,7 +82,7 @@ func (d *Array) Size() (s uint64) { return } func (d *Array) Marshal(buf []byte) ([]byte, error) { - size := d.Size() + size := d.MarshalSize() { if uint64(cap(buf)) >= size { buf = buf[:size] @@ -294,7 +294,7 @@ type Nested struct { B []string } -func (d *Nested) Size() (s uint64) { +func (d *Nested) MarshalSize() (s uint64) { { for k := range d.A { @@ -356,7 +356,7 @@ func (d *Nested) Size() (s uint64) { return } func (d *Nested) Marshal(buf []byte) ([]byte, error) { - size := d.Size() + size := d.MarshalSize() { if uint64(cap(buf)) >= size { buf = buf[:size] diff --git a/backends/golang/testdata/int.schema.golden.go b/backends/golang/testdata/int.schema.golden.go index 1387101..a20292b 100755 --- a/backends/golang/testdata/int.schema.golden.go +++ b/backends/golang/testdata/int.schema.golden.go @@ -31,7 +31,7 @@ type Ints struct { Uint64 uint64 } -func (d *Ints) Size() (s uint64) { +func (d *Ints) MarshalSize() (s uint64) { { @@ -133,7 +133,7 @@ func (d *Ints) Size() (s uint64) { return } func (d *Ints) Marshal(buf []byte) ([]byte, error) { - size := d.Size() + size := d.MarshalSize() { if uint64(cap(buf)) >= size { buf = buf[:size] diff --git a/backends/golang/type_array.go b/backends/golang/type_array.go index 474bc71..d38c68d 100644 --- a/backends/golang/type_array.go +++ b/backends/golang/type_array.go @@ -4,7 +4,7 @@ import ( "fmt" "text/template" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" ) var ( diff --git a/backends/golang/type_bool.go b/backends/golang/type_bool.go index 6acf067..1fa668a 100644 --- a/backends/golang/type_bool.go +++ b/backends/golang/type_bool.go @@ -3,7 +3,7 @@ package golang import ( "text/template" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" ) var ( diff --git a/backends/golang/type_byte.go b/backends/golang/type_byte.go index 43b2896..7307536 100644 --- a/backends/golang/type_byte.go +++ b/backends/golang/type_byte.go @@ -3,7 +3,7 @@ package golang import ( "text/template" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" ) var ( diff --git a/backends/golang/type_defer.go b/backends/golang/type_defer.go index f2fd2ba..9d36db7 100644 --- a/backends/golang/type_defer.go +++ b/backends/golang/type_defer.go @@ -1,6 +1,6 @@ package golang -import "github.com/andyleap/gencode/schema" +import "github.com/eyrie-io/gencode/schema" func (w *Walker) WalkDeferDef(dt *schema.DeferType) (parts *StringBuilder, err error) { return w.WalkTypeDef(dt.Resolved) diff --git a/backends/golang/type_float.go b/backends/golang/type_float.go index 5a42bcf..7b80284 100644 --- a/backends/golang/type_float.go +++ b/backends/golang/type_float.go @@ -3,7 +3,7 @@ package golang import ( "text/template" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" ) var ( diff --git a/backends/golang/type_int.go b/backends/golang/type_int.go index a1fd3ff..ce38a9e 100644 --- a/backends/golang/type_int.go +++ b/backends/golang/type_int.go @@ -3,7 +3,7 @@ package golang import ( "text/template" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" ) var ( @@ -23,7 +23,7 @@ func init() { template.Must(IntTemps.New("marshal").Parse(` { {{if .VarInt }} - + t := uint{{.Bits}}({{.Target}}) {{if .Signed}} t <<= 1 @@ -38,9 +38,9 @@ func init() { } buf[i + {{.W.Offset}}] = byte(t) i++ - + {{else}} - + {{if .W.Unsafe}} *(*{{if not .Signed}}u{{end}}int{{.Bits}})(unsafe.Pointer(&buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}])) = {{.Target}} {{else}} @@ -48,7 +48,7 @@ func init() { buf[{{if $.W.IAdjusted}}i + {{end}}{{Bytes .}} + {{$.W.Offset}}] = byte({{$.Target}} >> {{.}}) {{end}} {{end}} - + {{end}} }`)) template.Must(IntTemps.New("unmarshal").Parse(` @@ -70,15 +70,15 @@ func init() { {{else}} {{.Target}} = t {{end}} - + {{else}} - + {{if .W.Unsafe}} {{.Target}} = *(*{{if not .Signed}}u{{end}}int{{.Bits}})(unsafe.Pointer(&buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}])) {{else}} {{$.Target}} = 0{{range BitRange .Bits}} | ({{if not $.Signed}}u{{end}}int{{$.Bits}}(buf[{{if $.W.IAdjusted}}i + {{end}}{{Bytes .}} + {{$.W.Offset}}]) << {{.}}){{end}} {{end}} - + {{end}} }`)) template.Must(IntTemps.New("field").Parse(`{{if not .Signed}}u{{end}}int{{.Bits}}`)) @@ -104,6 +104,7 @@ func init() { } s++ {{end}} + s += {{.Bits}}/8 {{end}} }`)) } diff --git a/backends/golang/type_map.go b/backends/golang/type_map.go new file mode 100644 index 0000000..70e2e7a --- /dev/null +++ b/backends/golang/type_map.go @@ -0,0 +1,167 @@ +package golang + +import ( + "fmt" + "text/template" + + "github.com/eyrie-io/gencode/schema" +) + +var ( + MapTemps *template.Template +) + +func init() { + MapTemps = template.New("MapTemps") + template.Must(MapTemps.New("marshal").Parse(` + { + l := uint64(len({{.Target}})) + {{.VarIntCode}} + for k, v := range {{.Target}} { + {{.KeySubTypeCode}} + {{.ValueSubTypeCode}} + } + }`)) + template.Must(MapTemps.New("unmarshal").Parse(` + { + l := uint64(0) + {{.VarIntCode}} + {{.Target}} = make(map[{{.KeySubField}}]{{.ValueSubField}}) + for x := uint64(0); x < l; x++ { + var k {{.KeySubField}} + {{.KeySubTypeCode}} + var v {{.ValueSubField}} + {{.ValueSubTypeCode}} + {{.Target}}[k] = v + } + }`)) + template.Must(MapTemps.New("size").Parse(` + { + l := uint64(len({{.Target}})) + {{.VarIntCode}} + for k, v := range {{.Target}} { + _ = k + {{.KeySubTypeCode}} + _ = v + {{.ValueSubTypeCode}} + } + }`)) +} + +type MapTemp struct { + *schema.MapType + W *Walker + Target string + KeySubTypeCode string + KeySubField string + ValueSubTypeCode string + ValueSubField string + VarIntCode string +} + +func (w *Walker) WalkMapDef(st *schema.MapType) (parts *StringBuilder, err error) { + ksub, err := w.WalkTypeDef(st.KeySubType) + if err != nil { + return nil, err + } + vsub, err := w.WalkTypeDef(st.ValueSubType) + if err != nil { + return nil, err + } + parts = &StringBuilder{} + parts.Append(fmt.Sprintf("map[%s]%s", ksub.String(), vsub.String())) + return +} + +func (w *Walker) WalkMapSize(st *schema.MapType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + intHandler := &schema.IntType{ + Bits: 64, + Signed: false, + VarInt: true, + } + intcode, err := w.WalkIntSize(intHandler, "l") + if err != nil { + return nil, err + } + keysubtype, err := w.WalkTypeDef(st.KeySubType) + if err != nil { + return nil, err + } + keysubtypecode, err := w.WalkTypeSize(st.KeySubType, "k") + if err != nil { + return nil, err + } + valuesubtype, err := w.WalkTypeDef(st.ValueSubType) + if err != nil { + return nil, err + } + valuesubtypecode, err := w.WalkTypeSize(st.ValueSubType, "v") + if err != nil { + return nil, err + } + err = parts.AddTemplate(MapTemps, "size", MapTemp{st, w, target, keysubtypecode.String(), keysubtype.String(), valuesubtypecode.String(), valuesubtype.String(), intcode.String()}) + return +} + +func (w *Walker) WalkMapMarshal(st *schema.MapType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + intHandler := &schema.IntType{ + Bits: 64, + Signed: false, + VarInt: true, + } + intcode, err := w.WalkIntMarshal(intHandler, "l") + if err != nil { + return nil, err + } + keysubtype, err := w.WalkTypeDef(st.KeySubType) + if err != nil { + return nil, err + } + keysubtypecode, err := w.WalkTypeMarshal(st.KeySubType, "k") + if err != nil { + return nil, err + } + valuesubtype, err := w.WalkTypeDef(st.ValueSubType) + if err != nil { + return nil, err + } + valuesubtypecode, err := w.WalkTypeMarshal(st.ValueSubType, "v") + if err != nil { + return nil, err + } + err = parts.AddTemplate(MapTemps, "marshal", MapTemp{st, w, target, keysubtypecode.String(), keysubtype.String(), valuesubtypecode.String(), valuesubtype.String(), intcode.String()}) + return +} + +func (w *Walker) WalkMapUnmarshal(st *schema.MapType, target string) (parts *StringBuilder, err error) { + parts = &StringBuilder{} + intHandler := &schema.IntType{ + Bits: 64, + Signed: false, + VarInt: true, + } + intcode, err := w.WalkIntUnmarshal(intHandler, "l") + if err != nil { + return nil, err + } + keysubtype, err := w.WalkTypeDef(st.KeySubType) + if err != nil { + return nil, err + } + keysubtypecode, err := w.WalkTypeUnmarshal(st.KeySubType, "k") + if err != nil { + return nil, err + } + valuesubtype, err := w.WalkTypeDef(st.ValueSubType) + if err != nil { + return nil, err + } + valuesubtypecode, err := w.WalkTypeUnmarshal(st.ValueSubType, "v") + if err != nil { + return nil, err + } + err = parts.AddTemplate(MapTemps, "unmarshal", MapTemp{st, w, target, keysubtypecode.String(), keysubtype.String(), valuesubtypecode.String(), valuesubtype.String(), intcode.String()}) + return +} diff --git a/backends/golang/type_pointer.go b/backends/golang/type_pointer.go index 1663a51..c57cfc7 100644 --- a/backends/golang/type_pointer.go +++ b/backends/golang/type_pointer.go @@ -3,7 +3,7 @@ package golang import ( "text/template" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" ) var ( diff --git a/backends/golang/type_slice.go b/backends/golang/type_slice.go index bdea967..39c6b8b 100644 --- a/backends/golang/type_slice.go +++ b/backends/golang/type_slice.go @@ -1,9 +1,10 @@ package golang import ( + "strconv" "text/template" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" ) var ( @@ -16,7 +17,7 @@ func init() { { l := uint64(len({{.Target}})) {{.VarIntCode}} - for k := range {{.Target}} { + for {{.Variable}} := range {{.Target}} { {{.SubTypeCode}} {{if gt .SubOffset 0 }} i += {{.SubOffset}} @@ -32,7 +33,7 @@ func init() { } else { {{.Target}} = make([]{{.SubField}}, l) } - for k := range {{.Target}} { + for {{.Variable}} := range {{.Target}} { {{.SubTypeCode}} {{if gt .SubOffset 0 }} i += {{.SubOffset}} @@ -67,7 +68,7 @@ func init() { s += {{.SubOffset}}*l {{end}} {{else}} - for k := range {{.Target}} { + for {{.Variable}} := range {{.Target}} { {{.SubTypeCode}} {{if gt .SubOffset 0 }} s += {{.SubOffset}} @@ -92,6 +93,7 @@ type SliceTemp struct { SubTypeCode string SubField string VarIntCode string + Variable string } func (w *Walker) WalkSliceDef(st *schema.SliceType) (parts *StringBuilder, err error) { @@ -116,17 +118,21 @@ func (w *Walker) WalkSliceSize(st *schema.SliceType, target string) (parts *Stri if err != nil { return nil, err } + variable := "k" + if st.Depth > 0 { + variable += strconv.Itoa(st.Depth) + } offset := w.Offset - subtypecode, err := w.WalkTypeSize(st.SubType, target+"[k]") + subtypecode, err := w.WalkTypeSize(st.SubType, target+"["+variable+"]") if err != nil { return nil, err } SubOffset := w.Offset - offset w.Offset = offset if _, ok := st.SubType.(*schema.ByteType); ok { - err = parts.AddTemplate(SliceTemps, "bytesize", SliceTemp{st, w, SubOffset, target, subtypecode.String(), "", intcode.String()}) + err = parts.AddTemplate(SliceTemps, "bytesize", SliceTemp{st, w, SubOffset, target, subtypecode.String(), "", intcode.String(), variable}) } else { - err = parts.AddTemplate(SliceTemps, "size", SliceTemp{st, w, SubOffset, target, subtypecode.String(), "", intcode.String()}) + err = parts.AddTemplate(SliceTemps, "size", SliceTemp{st, w, SubOffset, target, subtypecode.String(), "", intcode.String(), variable}) } return } @@ -142,8 +148,12 @@ func (w *Walker) WalkSliceMarshal(st *schema.SliceType, target string) (parts *S if err != nil { return nil, err } + variable := "k" + if st.Depth > 0 { + variable += strconv.Itoa(st.Depth) + } offset := w.Offset - subtypecode, err := w.WalkTypeMarshal(st.SubType, target+"[k]") + subtypecode, err := w.WalkTypeMarshal(st.SubType, target+"["+variable+"]") if err != nil { return nil, err } @@ -154,9 +164,9 @@ func (w *Walker) WalkSliceMarshal(st *schema.SliceType, target string) (parts *S return nil, err } if _, ok := st.SubType.(*schema.ByteType); ok { - err = parts.AddTemplate(SliceTemps, "bytemarshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String()}) + err = parts.AddTemplate(SliceTemps, "bytemarshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), variable}) } else { - err = parts.AddTemplate(SliceTemps, "marshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String()}) + err = parts.AddTemplate(SliceTemps, "marshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), variable}) } return } @@ -172,8 +182,12 @@ func (w *Walker) WalkSliceUnmarshal(st *schema.SliceType, target string) (parts if err != nil { return nil, err } + variable := "k" + if st.Depth > 0 { + variable += strconv.Itoa(st.Depth) + } offset := w.Offset - subtypecode, err := w.WalkTypeUnmarshal(st.SubType, target+"[k]") + subtypecode, err := w.WalkTypeUnmarshal(st.SubType, target+"["+variable+"]") if err != nil { return nil, err } @@ -184,9 +198,9 @@ func (w *Walker) WalkSliceUnmarshal(st *schema.SliceType, target string) (parts return nil, err } if _, ok := st.SubType.(*schema.ByteType); ok { - err = parts.AddTemplate(SliceTemps, "byteunmarshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String()}) + err = parts.AddTemplate(SliceTemps, "byteunmarshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), variable}) } else { - err = parts.AddTemplate(SliceTemps, "unmarshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String()}) + err = parts.AddTemplate(SliceTemps, "unmarshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), variable}) } return } diff --git a/backends/golang/type_string.go b/backends/golang/type_string.go index 6aace37..a3d364b 100644 --- a/backends/golang/type_string.go +++ b/backends/golang/type_string.go @@ -3,7 +3,7 @@ package golang import ( "text/template" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" ) var ( diff --git a/backends/golang/type_struct.go b/backends/golang/type_struct.go index c096d5c..2895bc3 100644 --- a/backends/golang/type_struct.go +++ b/backends/golang/type_struct.go @@ -3,7 +3,7 @@ package golang import ( "text/template" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" ) var ( @@ -31,7 +31,7 @@ func init() { }`)) template.Must(StructTemps.New("size").Parse(` { - s += {{.Target}}.Size() + s += {{.Target}}.MarshalSize() }`)) template.Must(StructTemps.New("field").Parse(`{{.Struct}}`)) } diff --git a/backends/golang/type_time.go b/backends/golang/type_time.go index 81adcad..c409e53 100644 --- a/backends/golang/type_time.go +++ b/backends/golang/type_time.go @@ -3,7 +3,7 @@ package golang import ( "text/template" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" ) var ( diff --git a/backends/golang/type_union.go b/backends/golang/type_union.go index eb8a968..8f8a489 100644 --- a/backends/golang/type_union.go +++ b/backends/golang/type_union.go @@ -3,7 +3,7 @@ package golang import ( "text/template" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" ) var ( diff --git a/backends/golang/types.go b/backends/golang/types.go index bb60769..d7be563 100644 --- a/backends/golang/types.go +++ b/backends/golang/types.go @@ -3,7 +3,7 @@ package golang import ( "fmt" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" ) func (w *Walker) WalkTypeDef(t schema.Type) (*StringBuilder, error) { @@ -24,6 +24,8 @@ func (w *Walker) WalkTypeDef(t schema.Type) (*StringBuilder, error) { return w.WalkPointerDef(tt) case *schema.SliceType: return w.WalkSliceDef(tt) + case *schema.MapType: + return w.WalkMapDef(tt) case *schema.StringType: return w.WalkStringDef(tt) case *schema.StructType: @@ -54,6 +56,8 @@ func (w *Walker) WalkTypeSize(t schema.Type, target string) (*StringBuilder, err return w.WalkPointerSize(tt, target) case *schema.SliceType: return w.WalkSliceSize(tt, target) + case *schema.MapType: + return w.WalkMapSize(tt, target) case *schema.StringType: return w.WalkStringSize(tt, target) case *schema.StructType: @@ -84,6 +88,8 @@ func (w *Walker) WalkTypeMarshal(t schema.Type, target string) (*StringBuilder, return w.WalkPointerMarshal(tt, target) case *schema.SliceType: return w.WalkSliceMarshal(tt, target) + case *schema.MapType: + return w.WalkMapMarshal(tt, target) case *schema.StringType: return w.WalkStringMarshal(tt, target) case *schema.StructType: @@ -114,6 +120,8 @@ func (w *Walker) WalkTypeUnmarshal(t schema.Type, target string) (*StringBuilder return w.WalkPointerUnmarshal(tt, target) case *schema.SliceType: return w.WalkSliceUnmarshal(tt, target) + case *schema.MapType: + return w.WalkMapUnmarshal(tt, target) case *schema.StringType: return w.WalkStringUnmarshal(tt, target) case *schema.StructType: diff --git a/main.go b/main.go index 71a5b12..c7990ca 100644 --- a/main.go +++ b/main.go @@ -7,10 +7,11 @@ import ( "log" "os" - "github.com/andyleap/gencode/schema" + "github.com/eyrie-io/gencode/schema" "github.com/kr/pretty" - _ "github.com/andyleap/gencode/backends/golang" + _ "github.com/eyrie-io/gencode/backends/cpp" + _ "github.com/eyrie-io/gencode/backends/golang" ) func main() { diff --git a/schema/parser.go b/schema/parser.go index 0e3de6e..e40803a 100644 --- a/schema/parser.go +++ b/schema/parser.go @@ -13,6 +13,11 @@ func MakeGrammar() *Grammar { RWS := Ignore(Mult(1, 0, Set("\t\n\f\r "))) NL := Ignore(And(Mult(0, 0, Set("\t\f\r ")), Mult(1, 0, And(Lit("\n"), WS)))) + gAttribute := And(Set("`"), Mult(0, 0, Or(Letter, Digit, Set("\":,"))), Set("`")) + gAttribute.Node(func(m Match) (Match, error) { + return String(m), nil + }) + gIdentifier := And(Letter, Mult(0, 0, Or(Letter, Digit))) gIdentifier.Node(func(m Match) (Match, error) { return String(m), nil @@ -97,10 +102,27 @@ func MakeGrammar() *Grammar { return u, nil }) - gSlice := And(Lit("[]"), Require(Tag("SubType", gType))) + gSlice := And(Lit("[]"), Mult(0, 0, Tag("Brackets", Lit("[]"))), Require(Tag("SubType", gType))) gSlice.Node(func(m Match) (Match, error) { - return &SliceType{ + st := &SliceType{ SubType: GetTag(m, "SubType").(Type), + } + n := len(GetTags(m, "Brackets")) + for n > 0 { + st = &SliceType{ + SubType: st, + Depth: st.Depth + 1, + } + n-- + } + return st, nil + }) + + gMap := And(Lit("map["), Require(Tag("KeySubType", gType)), Lit("]"), Require(Tag("ValueSubType", gType))) + gMap.Node(func(m Match) (Match, error) { + return &MapType{ + KeySubType: GetTag(m, "KeySubType").(Type), + ValueSubType: GetTag(m, "ValueSubType").(Type), }, nil }) @@ -123,14 +145,18 @@ func MakeGrammar() *Grammar { }, nil }) - gType.Set(Or(gSlice, gArray, gPointer, gIntField, gByteField, gBoolField, gStringField, gTimeField, gFloatField, gUnion, gDeferField)) + gType.Set(Or(gMap, gSlice, gArray, gPointer, gIntField, gByteField, gBoolField, gStringField, gTimeField, gFloatField, gUnion, gDeferField)) - gField := And(Tag("Name", gIdentifier), Require(RWS, Tag("Type", gType), NL)) + gField := And(Tag("Name", gIdentifier), Require(RWS, Tag("Type", gType)), Optional(And(RWS, Tag("Attribute", gAttribute))), Require(NL)) gField.Node(func(m Match) (Match, error) { f := &Field{ Name: GetTag(m, "Name").(string), Type: GetTag(m, "Type").(Type), } + a := GetTag(m, "Attribute") + if a != nil { + f.Attribute = a.(string) + } return TagMatch("Field", f), nil }) diff --git a/schema/schema.go b/schema/schema.go index 0b9b739..aa85d61 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -27,8 +27,9 @@ type ResolveType interface { } type Field struct { - Name string - Type Type + Name string + Type Type + Attribute string } type Struct struct { @@ -142,6 +143,7 @@ func (p *PointerType) Resolve(s *Schema) error { type SliceType struct { SubType Type + Depth int } func (st *SliceType) Resolve(s *Schema) error { @@ -154,6 +156,27 @@ func (st *SliceType) Resolve(s *Schema) error { return nil } +type MapType struct { + KeySubType Type + ValueSubType Type +} + +func (st *MapType) Resolve(s *Schema) error { + if rt, ok := st.KeySubType.(ResolveType); ok { + err := rt.Resolve(s) + if err != nil { + return err + } + } + if rt, ok := st.ValueSubType.(ResolveType); ok { + err := rt.Resolve(s) + if err != nil { + return err + } + } + return nil +} + type StringType struct { } From 82a92880fb43ece390eda5ac88dbfffd2bf78ad3 Mon Sep 17 00:00:00 2001 From: Zachary Taylor Date: Wed, 30 Nov 2016 10:15:53 -0800 Subject: [PATCH 2/4] Couple more fixes to non-varints. --- backends/cpp/type_int.go | 9 ++++++++- backends/golang/type_int.go | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/backends/cpp/type_int.go b/backends/cpp/type_int.go index 73d6bbe..6f36c53 100644 --- a/backends/cpp/type_int.go +++ b/backends/cpp/type_int.go @@ -31,7 +31,11 @@ func init() { i++; } buf[i + {{.W.Offset}}] = uint8_t(t); - i++;{{else}}memcpy(&buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}], &{{.Target}}, {{.Bits}}/8);{{end}} + i++; + {{else}} + memcpy(&buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}], &{{.Target}}, {{.Bits}}/8); + i += {{.Bits}}/8; + {{end}} }`)) template.Must(IntTemps.New("unmarshal").Parse(` { @@ -54,6 +58,7 @@ func init() { {{end}} {{else}} memcpy(&{{.Target}}, &buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}], {{.Bits}}/8); + i += {{.Bits}}/8; {{end}} }`)) template.Must(IntTemps.New("field").Parse(`{{if not .Signed}}u{{end}}int{{.Bits}}_t`)) @@ -79,6 +84,8 @@ func init() { } s++; {{end}} + {{else}} + s += {{.Bits}}/8; {{end}} }`)) } diff --git a/backends/golang/type_int.go b/backends/golang/type_int.go index ce38a9e..b50dc00 100644 --- a/backends/golang/type_int.go +++ b/backends/golang/type_int.go @@ -48,7 +48,7 @@ func init() { buf[{{if $.W.IAdjusted}}i + {{end}}{{Bytes .}} + {{$.W.Offset}}] = byte({{$.Target}} >> {{.}}) {{end}} {{end}} - + i += {{.Bits}}/8 {{end}} }`)) template.Must(IntTemps.New("unmarshal").Parse(` @@ -78,7 +78,7 @@ func init() { {{else}} {{$.Target}} = 0{{range BitRange .Bits}} | ({{if not $.Signed}}u{{end}}int{{$.Bits}}(buf[{{if $.W.IAdjusted}}i + {{end}}{{Bytes .}} + {{$.W.Offset}}]) << {{.}}){{end}} {{end}} - + i += {{.Bits}}/8 {{end}} }`)) template.Must(IntTemps.New("field").Parse(`{{if not .Signed}}u{{end}}int{{.Bits}}`)) From f219644d2e8dd67437157df314ed12164d559dbd Mon Sep 17 00:00:00 2001 From: Zachary Taylor Date: Thu, 1 Dec 2016 07:48:24 -0800 Subject: [PATCH 3/4] Adding destructors and prefix-ing class names. --- backends/cpp/schema.go | 1 + backends/cpp/struct.go | 28 ++++++++++++++++++++++++---- backends/cpp/type_struct.go | 2 +- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/backends/cpp/schema.go b/backends/cpp/schema.go index e4b1322..1a5535a 100644 --- a/backends/cpp/schema.go +++ b/backends/cpp/schema.go @@ -20,6 +20,7 @@ func (w *Walker) WalkSchema(s *schema.Schema, Namespace string) (parts *StringBu #include #include #include +#include namespace %s { diff --git a/backends/cpp/struct.go b/backends/cpp/struct.go index 6e1f842..cd5c00c 100644 --- a/backends/cpp/struct.go +++ b/backends/cpp/struct.go @@ -12,7 +12,7 @@ func (w *Walker) WalkStruct(s *schema.Struct) (parts *StringBuilder, err error) return } parts = &StringBuilder{} - parts.Append(fmt.Sprintf(`class %s { + parts.Append(fmt.Sprintf(`class C%s { public: `, s.Name)) for _, f := range s.Fields { @@ -26,12 +26,32 @@ public: } parts.Append(fmt.Sprintf(` public: + ~C%s(); uint64_t MarshalSize(); uint64_t Marshal(uint8_t* buf); uint64_t Unmarshal(uint8_t* buf); }; -uint64_t %s::MarshalSize() { +C%s::~C%s() {`, s.Name, s.Name, s.Name)) + for _, f := range s.Fields { + switch t := f.Type.(type) { + case *schema.PointerType: + parts.Append(fmt.Sprintf(` delete this->%s;"`, s.Name)) + case *schema.SliceType: + pt, ok := t.SubType.(*schema.PointerType) + if ok { + dt := pt.SubType.(*schema.DeferType) + parts.Append(fmt.Sprintf(` + for (std::vector::iterator i = %s.begin(); i != %s.end(); i++) { + delete (*i); + }`, dt.Defer, f.Name, f.Name)) + } + } + } + parts.Append(fmt.Sprintf(` +} + +uint64_t C%s::MarshalSize() { uint64_t s = 0; `, s.Name)) for _, f := range s.Fields { @@ -52,7 +72,7 @@ uint64_t %s::MarshalSize() { return s; } -uint64_t %s::Marshal(uint8_t* buf) {`, s.Name)) +uint64_t C%s::Marshal(uint8_t* buf) {`, s.Name)) parts.Append(` uint64_t size = this->MarshalSize();`) parts.Append(` @@ -69,7 +89,7 @@ uint64_t %s::Marshal(uint8_t* buf) {`, s.Name)) return i+%d; } -uint64_t %s::Unmarshal(uint8_t* buf) { +uint64_t C%s::Unmarshal(uint8_t* buf) { uint64_t i = 0; `, w.Offset, s.Name)) w.Offset = 0 diff --git a/backends/cpp/type_struct.go b/backends/cpp/type_struct.go index 346814c..85f467b 100644 --- a/backends/cpp/type_struct.go +++ b/backends/cpp/type_struct.go @@ -27,7 +27,7 @@ func init() { { s += {{.Target}}.MarshalSize(); }`)) - template.Must(StructTemps.New("field").Parse(`{{.Struct}}`)) + template.Must(StructTemps.New("field").Parse(`C{{.Struct}}`)) } type StructTemp struct { From 24a1f2f8decaff3288654bbdc3550c946f6b60be Mon Sep 17 00:00:00 2001 From: Zachary Taylor Date: Thu, 1 Dec 2016 11:36:49 -0800 Subject: [PATCH 4/4] Heh, no going back now, offset was silly and confusing. --- backends/cpp/schema.go | 4 - backends/cpp/struct.go | 18 +-- backends/cpp/type_array.go | 32 ++---- backends/cpp/type_bool.go | 16 ++- backends/cpp/type_byte.go | 14 ++- backends/cpp/type_float.go | 12 +- backends/cpp/type_int.go | 30 ++--- backends/cpp/type_pointer.go | 39 ++----- backends/cpp/type_slice.go | 41 ++----- backends/cpp/type_string.go | 4 +- backends/cpp/type_struct.go | 7 +- backends/golang/schema.go | 5 +- backends/golang/struct.go | 17 +-- backends/golang/type_array.go | 47 ++------ backends/golang/type_bool.go | 16 ++- backends/golang/type_byte.go | 14 ++- backends/golang/type_float.go | 18 +-- backends/golang/type_int.go | 40 ++----- backends/golang/type_pointer.go | 39 ++----- backends/golang/type_slice.go | 42 ++----- backends/golang/type_string.go | 4 +- backends/golang/type_struct.go | 7 +- backends/golang/type_time.go | 61 ---------- backends/golang/type_union.go | 198 -------------------------------- backends/golang/types.go | 16 --- 25 files changed, 145 insertions(+), 596 deletions(-) delete mode 100644 backends/golang/type_time.go delete mode 100644 backends/golang/type_union.go diff --git a/backends/cpp/schema.go b/backends/cpp/schema.go index 1a5535a..198c164 100644 --- a/backends/cpp/schema.go +++ b/backends/cpp/schema.go @@ -7,10 +7,6 @@ import ( ) type Walker struct { - Needs []string - Offset int - IAdjusted bool - Unsafe bool } func (w *Walker) WalkSchema(s *schema.Schema, Namespace string) (parts *StringBuilder, err error) { diff --git a/backends/cpp/struct.go b/backends/cpp/struct.go index cd5c00c..fa5ada3 100644 --- a/backends/cpp/struct.go +++ b/backends/cpp/struct.go @@ -61,13 +61,6 @@ uint64_t C%s::MarshalSize() { } parts.Join(p) } - if w.Offset > 0 { - parts.Append(fmt.Sprintf(` - s += %d;`, w.Offset)) - w.Offset = 0 - } - w.IAdjusted = false - parts.Append(fmt.Sprintf(` return s; } @@ -86,13 +79,12 @@ uint64_t C%s::Marshal(uint8_t* buf) {`, s.Name)) parts.Join(p) } parts.Append(fmt.Sprintf(` - return i+%d; + return i; } uint64_t C%s::Unmarshal(uint8_t* buf) { uint64_t i = 0; - `, w.Offset, s.Name)) - w.Offset = 0 + `, s.Name)) for _, f := range s.Fields { p, err := w.WalkFieldUnmarshal(f) if err != nil { @@ -101,12 +93,10 @@ uint64_t C%s::Unmarshal(uint8_t* buf) { parts.Join(p) } parts.Append(fmt.Sprintf(` - return i + %d; + return i; } -`, w.Offset)) - w.Offset = 0 - w.IAdjusted = false +`)) return } diff --git a/backends/cpp/type_array.go b/backends/cpp/type_array.go index c9a9945..90f2e3e 100644 --- a/backends/cpp/type_array.go +++ b/backends/cpp/type_array.go @@ -16,31 +16,28 @@ func init() { { for (uint64_t k = 0; k < {{.Count}}; k++) { {{.SubTypeCode}} - {{if gt .SubOffset 0 }}i += {{.SubOffset}};{{end}} } }`)) template.Must(ArrayTemps.New("unmarshal").Parse(` { for (uint64_t k = 0; k < {{.Count}}; k++) { {{.SubTypeCode}} - {{if gt .SubOffset 0 }}i += {{.SubOffset}};{{end}} } }`)) template.Must(ArrayTemps.New("bytemarshal").Parse(` { - memcpy(&buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}], &{{.Target}}[0], {{.Count}}); + memcpy(&buf[i], &{{.Target}}[0], {{.Count}}); i += {{.Count}}; }`)) template.Must(ArrayTemps.New("byteunmarshal").Parse(` { - memcpy(&{{.Target}}[0], &buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}], {{.Count}}); + memcpy(&{{.Target}}[0], &buf[i], {{.Count}}); i += {{.Count}}; }`)) template.Must(ArrayTemps.New("size").Parse(` { for (uint64_t k = 0; k < {{.Count}}; k++) { {{.SubTypeCode}} - {{if gt .SubOffset 0 }}s += {{.SubOffset}};{{end}} } }`)) template.Must(ArrayTemps.New("bytesize").Parse(` @@ -53,7 +50,6 @@ func init() { type ArrayTemp struct { *schema.ArrayType W *Walker - SubOffset int Target string SubTypeCode string SubField string @@ -61,62 +57,50 @@ type ArrayTemp struct { func (w *Walker) WalkArraySize(at *schema.ArrayType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - w.IAdjusted = true - offset := w.Offset subtypecode, err := w.WalkTypeSize(at.SubType, target+"[k]") if err != nil { return nil, err } - SubOffset := w.Offset - offset - w.Offset = offset if _, ok := at.SubType.(*schema.ByteType); ok { - err = parts.AddTemplate(ArrayTemps, "bytesize", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), ""}) + err = parts.AddTemplate(ArrayTemps, "bytesize", ArrayTemp{at, w, target, subtypecode.String(), ""}) } else { - err = parts.AddTemplate(ArrayTemps, "size", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), ""}) + err = parts.AddTemplate(ArrayTemps, "size", ArrayTemp{at, w, target, subtypecode.String(), ""}) } return } func (w *Walker) WalkArrayMarshal(at *schema.ArrayType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - w.IAdjusted = true - offset := w.Offset subtypecode, err := w.WalkTypeMarshal(at.SubType, target+"[k]") if err != nil { return nil, err } - SubOffset := w.Offset - offset - w.Offset = offset subfield, err := w.WalkTypeDef(at.SubType) if err != nil { return nil, err } if _, ok := at.SubType.(*schema.ByteType); ok { - err = parts.AddTemplate(ArrayTemps, "bytemarshal", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), subfield.String()}) + err = parts.AddTemplate(ArrayTemps, "bytemarshal", ArrayTemp{at, w, target, subtypecode.String(), subfield.String()}) } else { - err = parts.AddTemplate(ArrayTemps, "marshal", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), subfield.String()}) + err = parts.AddTemplate(ArrayTemps, "marshal", ArrayTemp{at, w, target, subtypecode.String(), subfield.String()}) } return } func (w *Walker) WalkArrayUnmarshal(at *schema.ArrayType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - w.IAdjusted = true - offset := w.Offset subtypecode, err := w.WalkTypeUnmarshal(at.SubType, target+"[k]") if err != nil { return nil, err } - SubOffset := w.Offset - offset - w.Offset = offset subfield, err := w.WalkTypeDef(at.SubType) if err != nil { return nil, err } if _, ok := at.SubType.(*schema.ByteType); ok { - err = parts.AddTemplate(ArrayTemps, "byteunmarshal", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), subfield.String()}) + err = parts.AddTemplate(ArrayTemps, "byteunmarshal", ArrayTemp{at, w, target, subtypecode.String(), subfield.String()}) } else { - err = parts.AddTemplate(ArrayTemps, "unmarshal", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), subfield.String()}) + err = parts.AddTemplate(ArrayTemps, "unmarshal", ArrayTemp{at, w, target, subtypecode.String(), subfield.String()}) } return } diff --git a/backends/cpp/type_bool.go b/backends/cpp/type_bool.go index e17973f..91238d8 100644 --- a/backends/cpp/type_bool.go +++ b/backends/cpp/type_bool.go @@ -16,14 +16,20 @@ func init() { template.Must(BoolTemps.New("marshal").Parse(` { if ({{.Target}}) { - buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] = 1; + buf[i] = 1; } else { - buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] = 0; + buf[i] = 0; } + i++; }`)) template.Must(BoolTemps.New("unmarshal").Parse(` { - {{.Target}} = buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] == 1; + {{.Target}} = buf[i] == 1; + i++; + }`)) + template.Must(BoolTemps.New("size").Parse(` + { + s++; }`)) } @@ -41,20 +47,18 @@ func (w *Walker) WalkBoolDef(bt *schema.BoolType) (parts *StringBuilder, err err func (w *Walker) WalkBoolSize(bt *schema.BoolType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - w.Offset++ + err = parts.AddTemplate(BoolTemps, "size", BoolTemp{bt, w, target}) return } func (w *Walker) WalkBoolMarshal(bt *schema.BoolType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(BoolTemps, "marshal", BoolTemp{bt, w, target}) - w.Offset++ return } func (w *Walker) WalkBoolUnmarshal(bt *schema.BoolType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(BoolTemps, "unmarshal", BoolTemp{bt, w, target}) - w.Offset++ return } diff --git a/backends/cpp/type_byte.go b/backends/cpp/type_byte.go index b3eaea0..dceb865 100644 --- a/backends/cpp/type_byte.go +++ b/backends/cpp/type_byte.go @@ -15,11 +15,17 @@ func init() { template.Must(ByteTemps.New("marshal").Parse(` { - buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] = {{.Target}}; + buf[i] = {{.Target}}; + i++; }`)) template.Must(ByteTemps.New("unmarshal").Parse(` { - {{.Target}} = buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}]; + {{.Target}} = buf[i]; + i++; + }`)) + template.Must(ByteTemps.New("size").Parse(` + { + s++; }`)) } @@ -37,20 +43,18 @@ func (w *Walker) WalkByteDef(bt *schema.ByteType) (parts *StringBuilder, err err func (w *Walker) WalkByteSize(bt *schema.ByteType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - w.Offset++ + err = parts.AddTemplate(ByteTemps, "size", ByteTemp{bt, w, target}) return } func (w *Walker) WalkByteMarshal(bt *schema.ByteType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(ByteTemps, "marshal", ByteTemp{bt, w, target}) - w.Offset++ return } func (w *Walker) WalkByteUnmarshal(bt *schema.ByteType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(ByteTemps, "unmarshal", ByteTemp{bt, w, target}) - w.Offset++ return } diff --git a/backends/cpp/type_float.go b/backends/cpp/type_float.go index e12359f..9be3a69 100644 --- a/backends/cpp/type_float.go +++ b/backends/cpp/type_float.go @@ -21,10 +21,14 @@ func init() { }) template.Must(FloatTemps.New("marshal").Parse(` - memcpy(&buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}], &{{.Target}}, {{.Bits}}/8);`)) + memcpy(&buf[i], &{{.Target}}, {{.Bits}}/8); + i += {{.Bits}}/8;`)) template.Must(FloatTemps.New("unmarshal").Parse(` - memcpy(&{{.Target}}, &buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}], {{.Bits}}/8);`)) + memcpy(&{{.Target}}, &buf[i], {{.Bits}}/8); + i += {{.Bits}}/8;`)) template.Must(FloatTemps.New("field").Parse(`{{if .IsFloat}}float{{else}}double{{end}}`)) + template.Must(FloatTemps.New("size").Parse(` + s += {{.Bits}}/8;`)) } type FloatTemp struct { @@ -42,20 +46,18 @@ func (w *Walker) WalkFloatDef(ft *schema.FloatType) (parts *StringBuilder, err e func (w *Walker) WalkFloatSize(ft *schema.FloatType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - w.Offset += ft.Bits / 8 + err = parts.AddTemplate(FloatTemps, "size", FloatTemp{ft, w, "", ft.Bits == 32}) return } func (w *Walker) WalkFloatMarshal(ft *schema.FloatType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(FloatTemps, "marshal", FloatTemp{ft, w, target, ft.Bits == 32}) - w.Offset += ft.Bits / 8 return } func (w *Walker) WalkFloatUnmarshal(ft *schema.FloatType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(FloatTemps, "unmarshal", FloatTemp{ft, w, target, ft.Bits == 32}) - w.Offset += ft.Bits / 8 return } diff --git a/backends/cpp/type_int.go b/backends/cpp/type_int.go index 6f36c53..558b06c 100644 --- a/backends/cpp/type_int.go +++ b/backends/cpp/type_int.go @@ -26,14 +26,14 @@ func init() { {{if .Signed}}t <<= 1; if ({{.Target}} < 0) { t = ^t; }{{end}} while (t >= 0x80) { - buf[i + {{.W.Offset}}] = uint8_t(t) | 0x80; + buf[i] = uint8_t(t) | 0x80; t >>= 7; i++; } - buf[i + {{.W.Offset}}] = uint8_t(t); + buf[i] = uint8_t(t); i++; {{else}} - memcpy(&buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}], &{{.Target}}, {{.Bits}}/8); + memcpy(&buf[i], &{{.Target}}, {{.Bits}}/8); i += {{.Bits}}/8; {{end}} }`)) @@ -41,10 +41,10 @@ func init() { { {{if .VarInt}} uint8_t bs = 7; - uint{{.Bits}}_t t = buf[i + {{.W.Offset}}] & 0x7F; - while ((buf[i + {{.W.Offset}}] & 0x80) == 0x80) { + uint{{.Bits}}_t t = buf[i] & 0x7F; + while ((buf[i] & 0x80) == 0x80) { i++; - t |= ((uint{{.Bits}}_t)buf[i + {{.W.Offset}}] & 0x7F) << bs; + t |= ((uint{{.Bits}}_t)buf[i] & 0x7F) << bs; bs += 7; } i++; @@ -57,7 +57,7 @@ func init() { {{.Target}} = t; {{end}} {{else}} - memcpy(&{{.Target}}, &buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}], {{.Bits}}/8); + memcpy(&{{.Target}}, &buf[i], {{.Bits}}/8); i += {{.Bits}}/8; {{end}} }`)) @@ -104,12 +104,6 @@ func (w *Walker) WalkIntDef(it *schema.IntType) (parts *StringBuilder, err error func (w *Walker) WalkIntSize(it *schema.IntType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - if !it.VarInt { - w.Offset += it.Bits / 8 - return - } else { - w.IAdjusted = true - } err = parts.AddTemplate(IntTemps, "size", IntTemp{it, w, target}) return } @@ -117,21 +111,11 @@ func (w *Walker) WalkIntSize(it *schema.IntType, target string) (parts *StringBu func (w *Walker) WalkIntMarshal(it *schema.IntType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(IntTemps, "marshal", IntTemp{it, w, target}) - if !it.VarInt { - w.Offset += it.Bits / 8 - } else { - w.IAdjusted = true - } return } func (w *Walker) WalkIntUnmarshal(it *schema.IntType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(IntTemps, "unmarshal", IntTemp{it, w, target}) - if !it.VarInt { - w.Offset += it.Bits / 8 - } else { - w.IAdjusted = true - } return } diff --git a/backends/cpp/type_pointer.go b/backends/cpp/type_pointer.go index ce6d68a..c42aaa4 100644 --- a/backends/cpp/type_pointer.go +++ b/backends/cpp/type_pointer.go @@ -16,30 +16,32 @@ func init() { template.Must(PointerTemps.New("marshal").Parse(` { if ({{.Target}} == NULL) { - buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] = 0; + buf[i] = 0; + i++; } else { - buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] = 1; + buf[i] = 1; + i++; {{.SubTypeCode}} - i += {{.SubOffset}}; } }`)) template.Must(PointerTemps.New("unmarshal").Parse(` { - if (buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] == 1) { + if (buf[i] == 1) { + i++; if ({{.Target}} == NULL) { {{.Target}} = new class {{.SubField}}(); } {{.SubTypeCode}} - i += {{.SubOffset}}; } else { + i++; {{.Target}} = NULL; } }`)) template.Must(PointerTemps.New("size").Parse(` { + s++; if ({{.Target}} != NULL) { {{.SubTypeCode}} - s += {{.SubOffset}}; } }`)) @@ -49,7 +51,6 @@ func init() { type PointerTemp struct { *schema.PointerType W *Walker - SubOffset int Target string SubTypeCode string SubField string @@ -67,24 +68,16 @@ func (w *Walker) WalkPointerDef(pt *schema.PointerType) (parts *StringBuilder, e func (w *Walker) WalkPointerSize(pt *schema.PointerType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - Offset := w.Offset - w.Offset++ subtypecode, err := w.WalkTypeSize(pt.SubType, "(*"+target+")") if err != nil { return nil, err } - SubOffset := w.Offset - (Offset + 1) - w.Offset = Offset - err = parts.AddTemplate(PointerTemps, "size", PointerTemp{pt, w, SubOffset, target, subtypecode.String(), ""}) - w.Offset++ - w.IAdjusted = true + err = parts.AddTemplate(PointerTemps, "size", PointerTemp{pt, w, target, subtypecode.String(), ""}) return } func (w *Walker) WalkPointerMarshal(pt *schema.PointerType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - Offset := w.Offset - w.Offset++ subtypecode, err := w.WalkTypeMarshal(pt.SubType, "(*"+target+")") if err != nil { return nil, err @@ -93,18 +86,12 @@ func (w *Walker) WalkPointerMarshal(pt *schema.PointerType, target string) (part if err != nil { return nil, err } - SubOffset := w.Offset - (Offset + 1) - w.Offset = Offset - err = parts.AddTemplate(PointerTemps, "marshal", PointerTemp{pt, w, SubOffset, target, subtypecode.String(), subfield.String()}) - w.IAdjusted = true - w.Offset++ + err = parts.AddTemplate(PointerTemps, "marshal", PointerTemp{pt, w, target, subtypecode.String(), subfield.String()}) return } func (w *Walker) WalkPointerUnmarshal(pt *schema.PointerType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - Offset := w.Offset - w.Offset++ subtypecode, err := w.WalkTypeUnmarshal(pt.SubType, "(*"+target+")") if err != nil { return nil, err @@ -113,10 +100,6 @@ func (w *Walker) WalkPointerUnmarshal(pt *schema.PointerType, target string) (pa if err != nil { return nil, err } - SubOffset := w.Offset - (Offset + 1) - w.Offset = Offset - err = parts.AddTemplate(PointerTemps, "unmarshal", PointerTemp{pt, w, SubOffset, target, subtypecode.String(), subfield.String()}) - w.IAdjusted = true - w.Offset++ + err = parts.AddTemplate(PointerTemps, "unmarshal", PointerTemp{pt, w, target, subtypecode.String(), subfield.String()}) return } diff --git a/backends/cpp/type_slice.go b/backends/cpp/type_slice.go index c27c125..da1d42f 100644 --- a/backends/cpp/type_slice.go +++ b/backends/cpp/type_slice.go @@ -21,7 +21,6 @@ func init() { {{.VarIntCode}} for (uint64_t k{{.Depth}} = 0; k{{.Depth}} < l{{.Depth}}; k{{.Depth}}++) { {{.SubTypeCode}} - {{if gt .SubOffset 0 }}i += {{.SubOffset}};{{end}} } }`)) template.Must(SliceTemps.New("unmarshal").Parse(` @@ -31,14 +30,13 @@ func init() { {{.Target}}.resize(l{{.Depth}}); for (uint64_t k{{.Depth}} = 0; k{{.Depth}} < l{{.Depth}}; k{{.Depth}}++) { {{.SubTypeCode}} - {{if gt .SubOffset 0 }}i += {{.SubOffset}};{{end}} } }`)) template.Must(SliceTemps.New("bytemarshal").Parse(` { uint64_t l{{.Depth}} = {{.Target}}.size(); {{.VarIntCode}} - memcpy(&buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}], &{{.Target}}[0], l{{.Depth}}); + memcpy(&buf[i], &{{.Target}}[0], l{{.Depth}}); i += l{{.Depth}}; }`)) template.Must(SliceTemps.New("byteunmarshal").Parse(` @@ -46,7 +44,7 @@ func init() { uint64_t l{{.Depth}} = 0; {{.VarIntCode}} {{.Target}}.resize(l{{.Depth}}); - memcpy(&{{.Target}}[0], &buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}], l); + memcpy(&{{.Target}}[0], &buf[i], l{{.Depth}}); i += l{{.Depth}}; }`)) template.Must(SliceTemps.New("size").Parse(` @@ -54,13 +52,9 @@ func init() { uint64_t l{{.Depth}} = {{.Target}}.size(); {{.VarIntCode}} {{if eq .SubTypeCode "" }} - {{if gt .SubOffset 0 }} - s += {{.SubOffset}}*l{{.Depth}}; - {{end}} {{else}} for (uint64_t k{{.Depth}} = 0; k{{.Depth}} < l{{.Depth}}; k{{.Depth}}++) { {{.SubTypeCode}} - {{if gt .SubOffset 0 }}s += {{.SubOffset}};{{end}} } {{end}} }`)) @@ -76,10 +70,8 @@ func init() { type SliceTemp struct { *schema.SliceType W *Walker - SubOffset int Target string SubTypeCode string - SubField string VarIntCode string Depth int } @@ -109,17 +101,14 @@ func (w *Walker) WalkSliceSize(st *schema.SliceType, target string) (parts *Stri if err != nil { return nil, err } - offset := w.Offset subtypecode, err := w.WalkTypeSize(st.SubType, target+"[k"+strconv.Itoa(st.Depth)+"]") if err != nil { return nil, err } - SubOffset := w.Offset - offset - w.Offset = offset if _, ok := st.SubType.(*schema.ByteType); ok { - err = parts.AddTemplate(SliceTemps, "bytesize", SliceTemp{st, w, SubOffset, target, subtypecode.String(), "", intcode.String(), st.Depth}) + err = parts.AddTemplate(SliceTemps, "bytesize", SliceTemp{st, w, target, subtypecode.String(), intcode.String(), st.Depth}) } else { - err = parts.AddTemplate(SliceTemps, "size", SliceTemp{st, w, SubOffset, target, subtypecode.String(), "", intcode.String(), st.Depth}) + err = parts.AddTemplate(SliceTemps, "size", SliceTemp{st, w, target, subtypecode.String(), intcode.String(), st.Depth}) } return } @@ -135,21 +124,14 @@ func (w *Walker) WalkSliceMarshal(st *schema.SliceType, target string) (parts *S if err != nil { return nil, err } - offset := w.Offset subtypecode, err := w.WalkTypeMarshal(st.SubType, target+"[k"+strconv.Itoa(st.Depth)+"]") if err != nil { return nil, err } - SubOffset := w.Offset - offset - w.Offset = offset - subfield, err := w.WalkTypeDef(st.SubType) - if err != nil { - return nil, err - } if _, ok := st.SubType.(*schema.ByteType); ok { - err = parts.AddTemplate(SliceTemps, "bytemarshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), st.Depth}) + err = parts.AddTemplate(SliceTemps, "bytemarshal", SliceTemp{st, w, target, subtypecode.String(), intcode.String(), st.Depth}) } else { - err = parts.AddTemplate(SliceTemps, "marshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), st.Depth}) + err = parts.AddTemplate(SliceTemps, "marshal", SliceTemp{st, w, target, subtypecode.String(), intcode.String(), st.Depth}) } return } @@ -165,21 +147,14 @@ func (w *Walker) WalkSliceUnmarshal(st *schema.SliceType, target string) (parts if err != nil { return nil, err } - offset := w.Offset subtypecode, err := w.WalkTypeUnmarshal(st.SubType, target+"[k"+strconv.Itoa(st.Depth)+"]") if err != nil { return nil, err } - SubOffset := w.Offset - offset - w.Offset = offset - subfield, err := w.WalkTypeDef(st.SubType) - if err != nil { - return nil, err - } if _, ok := st.SubType.(*schema.ByteType); ok { - err = parts.AddTemplate(SliceTemps, "byteunmarshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), st.Depth}) + err = parts.AddTemplate(SliceTemps, "byteunmarshal", SliceTemp{st, w, target, subtypecode.String(), intcode.String(), st.Depth}) } else { - err = parts.AddTemplate(SliceTemps, "unmarshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), st.Depth}) + err = parts.AddTemplate(SliceTemps, "unmarshal", SliceTemp{st, w, target, subtypecode.String(), intcode.String(), st.Depth}) } return } diff --git a/backends/cpp/type_string.go b/backends/cpp/type_string.go index 77f72e5..6b69ba9 100644 --- a/backends/cpp/type_string.go +++ b/backends/cpp/type_string.go @@ -17,14 +17,14 @@ func init() { { uint64_t l = {{.Target}}.length(); {{.VarIntCode}} - memcpy(&buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}], {{.Target}}.c_str(), l); + memcpy(&buf[i], {{.Target}}.c_str(), l); i += l; }`)) template.Must(StringTemps.New("unmarshal").Parse(` { uint64_t l = 0; {{.VarIntCode}} - {{.Target}}.assign((const char*)&buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}], l); + {{.Target}}.assign((const char*)&buf[i], l); i += l; }`)) template.Must(StringTemps.New("size").Parse(` diff --git a/backends/cpp/type_struct.go b/backends/cpp/type_struct.go index 85f467b..a8e610e 100644 --- a/backends/cpp/type_struct.go +++ b/backends/cpp/type_struct.go @@ -15,12 +15,12 @@ func init() { template.Must(StructTemps.New("marshal").Parse(` { - uint64_t nbuf = {{.Target}}.Marshal(&buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}]); + uint64_t nbuf = {{.Target}}.Marshal(&buf[i]); i += nbuf; }`)) template.Must(StructTemps.New("unmarshal").Parse(` { - uint64_t ni = {{.Target}}.Unmarshal(&buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}]); + uint64_t ni = {{.Target}}.Unmarshal(&buf[i]); i += ni; }`)) template.Must(StructTemps.New("size").Parse(` @@ -45,20 +45,17 @@ func (w *Walker) WalkStructDef(st *schema.StructType) (parts *StringBuilder, err func (w *Walker) WalkStructSize(st *schema.StructType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(StructTemps, "size", StructTemp{st, w, target}) - w.IAdjusted = true return } func (w *Walker) WalkStructMarshal(st *schema.StructType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(StructTemps, "marshal", StructTemp{st, w, target}) - w.IAdjusted = true return } func (w *Walker) WalkStructUnmarshal(st *schema.StructType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(StructTemps, "unmarshal", StructTemp{st, w, target}) - w.IAdjusted = true return } diff --git a/backends/golang/schema.go b/backends/golang/schema.go index 99e032f..2d4a64f 100644 --- a/backends/golang/schema.go +++ b/backends/golang/schema.go @@ -7,10 +7,7 @@ import ( ) type Walker struct { - Needs []string - Offset int - IAdjusted bool - Unsafe bool + Unsafe bool } func (w *Walker) WalkSchema(s *schema.Schema, Package string) (parts *StringBuilder, err error) { diff --git a/backends/golang/struct.go b/backends/golang/struct.go index 3184af8..20fdb64 100644 --- a/backends/golang/struct.go +++ b/backends/golang/struct.go @@ -42,12 +42,6 @@ func (d *%s) MarshalFramedSize() (s uint64, us uint64) { } parts.Join(p) } - if w.Offset > 0 { - parts.Append(fmt.Sprintf(` - s += %d`, w.Offset)) - w.Offset = 0 - } - w.IAdjusted = false if s.Framed { intcode, err := w.WalkIntSize(intHandler, "l") if err != nil { @@ -106,13 +100,12 @@ func (d *%s) Marshal(buf []byte) ([]byte, error) {`, s.Name)) parts.Join(p) } parts.Append(fmt.Sprintf(` - return buf[:i+%d], nil + return buf[:i], nil } func (d *%s) Unmarshal(buf []byte) (uint64, error) { i := uint64(0) - `, w.Offset, s.Name)) - w.Offset = 0 + `, s.Name)) if s.Framed { parts.Append(`usize := uint64(0) `) @@ -134,11 +127,9 @@ func (d *%s) Unmarshal(buf []byte) (uint64, error) { parts.Join(p) } parts.Append(fmt.Sprintf(` - return i + %d, nil + return i, nil } -`, w.Offset)) - w.Offset = 0 - w.IAdjusted = false +`)) if s.Framed { parts.Append(fmt.Sprintf(` func (d *%s) Serialize(w io.Writer) (error) { diff --git a/backends/golang/type_array.go b/backends/golang/type_array.go index d38c68d..ec7e0ff 100644 --- a/backends/golang/type_array.go +++ b/backends/golang/type_array.go @@ -17,28 +17,22 @@ func init() { { for k := range {{.Target}} { {{.SubTypeCode}} - {{if gt .SubOffset 0 }} - i += {{.SubOffset}} - {{end}} } }`)) template.Must(ArrayTemps.New("unmarshal").Parse(` { for k := range {{.Target}} { {{.SubTypeCode}} - {{if gt .SubOffset 0 }} - i += {{.SubOffset}} - {{end}} } }`)) template.Must(ArrayTemps.New("bytemarshal").Parse(` { - copy(buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}:], {{.Target}}[:]) + copy(buf[i:], {{.Target}}[:]) i += {{.Count}} }`)) template.Must(ArrayTemps.New("byteunmarshal").Parse(` { - copy({{.Target}}[:], buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}:]) + copy({{.Target}}[:], buf[i:]) i += {{.Count}} }`)) template.Must(ArrayTemps.New("size").Parse(` @@ -46,9 +40,6 @@ func init() { for k := range {{.Target}} { _ = k // make compiler happy in case k is unused {{.SubTypeCode}} - {{if gt .SubOffset 0 }} - s += {{.SubOffset}} - {{end}} } }`)) template.Must(ArrayTemps.New("bytesize").Parse(` @@ -61,10 +52,8 @@ func init() { type ArrayTemp struct { *schema.ArrayType W *Walker - SubOffset int Target string SubTypeCode string - SubField string } func (w *Walker) WalkArrayDef(at *schema.ArrayType) (parts *StringBuilder, err error) { @@ -80,62 +69,42 @@ func (w *Walker) WalkArrayDef(at *schema.ArrayType) (parts *StringBuilder, err e func (w *Walker) WalkArraySize(at *schema.ArrayType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - w.IAdjusted = true - offset := w.Offset subtypecode, err := w.WalkTypeSize(at.SubType, target+"[k]") if err != nil { return nil, err } - SubOffset := w.Offset - offset - w.Offset = offset if _, ok := at.SubType.(*schema.ByteType); ok { - err = parts.AddTemplate(ArrayTemps, "bytesize", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), ""}) + err = parts.AddTemplate(ArrayTemps, "bytesize", ArrayTemp{at, w, target, subtypecode.String()}) } else { - err = parts.AddTemplate(ArrayTemps, "size", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), ""}) + err = parts.AddTemplate(ArrayTemps, "size", ArrayTemp{at, w, target, subtypecode.String()}) } return } func (w *Walker) WalkArrayMarshal(at *schema.ArrayType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - w.IAdjusted = true - offset := w.Offset subtypecode, err := w.WalkTypeMarshal(at.SubType, target+"[k]") if err != nil { return nil, err } - SubOffset := w.Offset - offset - w.Offset = offset - subfield, err := w.WalkTypeDef(at.SubType) - if err != nil { - return nil, err - } if _, ok := at.SubType.(*schema.ByteType); ok { - err = parts.AddTemplate(ArrayTemps, "bytemarshal", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), subfield.String()}) + err = parts.AddTemplate(ArrayTemps, "bytemarshal", ArrayTemp{at, w, target, subtypecode.String()}) } else { - err = parts.AddTemplate(ArrayTemps, "marshal", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), subfield.String()}) + err = parts.AddTemplate(ArrayTemps, "marshal", ArrayTemp{at, w, target, subtypecode.String()}) } return } func (w *Walker) WalkArrayUnmarshal(at *schema.ArrayType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - w.IAdjusted = true - offset := w.Offset subtypecode, err := w.WalkTypeUnmarshal(at.SubType, target+"[k]") if err != nil { return nil, err } - SubOffset := w.Offset - offset - w.Offset = offset - subfield, err := w.WalkTypeDef(at.SubType) - if err != nil { - return nil, err - } if _, ok := at.SubType.(*schema.ByteType); ok { - err = parts.AddTemplate(ArrayTemps, "byteunmarshal", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), subfield.String()}) + err = parts.AddTemplate(ArrayTemps, "byteunmarshal", ArrayTemp{at, w, target, subtypecode.String()}) } else { - err = parts.AddTemplate(ArrayTemps, "unmarshal", ArrayTemp{at, w, SubOffset, target, subtypecode.String(), subfield.String()}) + err = parts.AddTemplate(ArrayTemps, "unmarshal", ArrayTemp{at, w, target, subtypecode.String()}) } return } diff --git a/backends/golang/type_bool.go b/backends/golang/type_bool.go index 1fa668a..d423dd8 100644 --- a/backends/golang/type_bool.go +++ b/backends/golang/type_bool.go @@ -16,14 +16,20 @@ func init() { template.Must(BoolTemps.New("marshal").Parse(` { if {{.Target}} { - buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] = 1 + buf[i] = 1 } else { - buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] = 0 + buf[i] = 0 } + i++ }`)) template.Must(BoolTemps.New("unmarshal").Parse(` { - {{.Target}} = buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] == 1 + {{.Target}} = buf[i] == 1 + i++ + }`)) + template.Must(BoolTemps.New("size").Parse(` + { + s++ }`)) } @@ -41,20 +47,18 @@ func (w *Walker) WalkBoolDef(bt *schema.BoolType) (parts *StringBuilder, err err func (w *Walker) WalkBoolSize(bt *schema.BoolType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - w.Offset++ + err = parts.AddTemplate(BoolTemps, "size", BoolTemp{bt, w, target}) return } func (w *Walker) WalkBoolMarshal(bt *schema.BoolType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(BoolTemps, "marshal", BoolTemp{bt, w, target}) - w.Offset++ return } func (w *Walker) WalkBoolUnmarshal(bt *schema.BoolType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(BoolTemps, "unmarshal", BoolTemp{bt, w, target}) - w.Offset++ return } diff --git a/backends/golang/type_byte.go b/backends/golang/type_byte.go index 7307536..caf9be9 100644 --- a/backends/golang/type_byte.go +++ b/backends/golang/type_byte.go @@ -15,11 +15,17 @@ func init() { template.Must(ByteTemps.New("marshal").Parse(` { - buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] = {{.Target}}; + buf[i] = {{.Target}}; + i++ }`)) template.Must(ByteTemps.New("unmarshal").Parse(` { - {{.Target}} = buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}]; + {{.Target}} = buf[i]; + i++ + }`)) + template.Must(ByteTemps.New("size").Parse(` + { + s++ }`)) } @@ -37,20 +43,18 @@ func (w *Walker) WalkByteDef(bt *schema.ByteType) (parts *StringBuilder, err err func (w *Walker) WalkByteSize(bt *schema.ByteType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - w.Offset++ + err = parts.AddTemplate(ByteTemps, "size", ByteTemp{bt, w, target}) return } func (w *Walker) WalkByteMarshal(bt *schema.ByteType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(ByteTemps, "marshal", ByteTemp{bt, w, target}) - w.Offset++ return } func (w *Walker) WalkByteUnmarshal(bt *schema.ByteType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(ByteTemps, "unmarshal", ByteTemp{bt, w, target}) - w.Offset++ return } diff --git a/backends/golang/type_float.go b/backends/golang/type_float.go index 7b80284..d01a8c3 100644 --- a/backends/golang/type_float.go +++ b/backends/golang/type_float.go @@ -23,22 +23,28 @@ func init() { template.Must(FloatTemps.New("marshal").Parse(` { {{if .W.Unsafe}} - *(*float{{.Bits}})(unsafe.Pointer(&buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}])) = {{.Target}} + *(*float{{.Bits}})(unsafe.Pointer(&buf[i])) = {{.Target}} {{else}} v := *(*uint{{.Bits}})(unsafe.Pointer(&({{.Target}}))) {{range BitRange .Bits}} - buf[{{if $.W.IAdjusted}}i + {{end}}{{Bytes .}} + {{$.W.Offset}}] = byte(v >> {{.}}) + buf[i + {{Bytes .}}] = byte(v >> {{.}}) {{end}} {{end}} + i += {{.Bits}}/8 }`)) template.Must(FloatTemps.New("unmarshal").Parse(` { {{if .W.Unsafe}} - {{.Target}} = *(*float{{.Bits}})(unsafe.Pointer(&buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}])) + {{.Target}} = *(*float{{.Bits}})(unsafe.Pointer(&buf[i])) {{else}} - v := 0{{range BitRange .Bits}} | (uint{{$.Bits}}(buf[{{if $.W.IAdjusted}}i + {{end}}{{Bytes .}} + {{$.W.Offset}}]) << {{.}}){{end}} + v := 0{{range BitRange .Bits}} | (uint{{$.Bits}}(buf[i + {{Bytes .}}]) << {{.}}){{end}} {{.Target}} = *(*float{{.Bits}})(unsafe.Pointer(&v)) {{end}} + i += {{.Bits}}/8 + }`)) + template.Must(FloatTemps.New("size").Parse(` + { + s += {{.Bits}}/8 }`)) template.Must(FloatTemps.New("field").Parse(`float{{.Bits}}`)) } @@ -57,20 +63,18 @@ func (w *Walker) WalkFloatDef(ft *schema.FloatType) (parts *StringBuilder, err e func (w *Walker) WalkFloatSize(ft *schema.FloatType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - w.Offset += ft.Bits / 8 + err = parts.AddTemplate(FloatTemps, "size", FloatTemp{ft, w, target}) return } func (w *Walker) WalkFloatMarshal(ft *schema.FloatType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(FloatTemps, "marshal", FloatTemp{ft, w, target}) - w.Offset += ft.Bits / 8 return } func (w *Walker) WalkFloatUnmarshal(ft *schema.FloatType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(FloatTemps, "unmarshal", FloatTemp{ft, w, target}) - w.Offset += ft.Bits / 8 return } diff --git a/backends/golang/type_int.go b/backends/golang/type_int.go index b50dc00..262dd4d 100644 --- a/backends/golang/type_int.go +++ b/backends/golang/type_int.go @@ -23,7 +23,6 @@ func init() { template.Must(IntTemps.New("marshal").Parse(` { {{if .VarInt }} - t := uint{{.Bits}}({{.Target}}) {{if .Signed}} t <<= 1 @@ -32,20 +31,18 @@ func init() { } {{end}} for t >= 0x80 { - buf[i + {{.W.Offset}}] = byte(t) | 0x80 + buf[i] = byte(t) | 0x80 t >>= 7 i++ } - buf[i + {{.W.Offset}}] = byte(t) + buf[i] = byte(t) i++ - {{else}} - {{if .W.Unsafe}} - *(*{{if not .Signed}}u{{end}}int{{.Bits}})(unsafe.Pointer(&buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}])) = {{.Target}} + *(*{{if not .Signed}}u{{end}}int{{.Bits}})(unsafe.Pointer(&buf[i])) = {{.Target}} {{else}} {{range BitRange .Bits}} - buf[{{if $.W.IAdjusted}}i + {{end}}{{Bytes .}} + {{$.W.Offset}}] = byte({{$.Target}} >> {{.}}) + buf[i + {{Bytes .}}] = byte({{$.Target}} >> {{.}}) {{end}} {{end}} i += {{.Bits}}/8 @@ -55,10 +52,10 @@ func init() { { {{if .VarInt}} bs := uint8(7) - t := uint{{.Bits}}(buf[i + {{.W.Offset}}] & 0x7F) - for buf[i + {{.W.Offset}}] & 0x80 == 0x80 { + t := uint{{.Bits}}(buf[i] & 0x7F) + for buf[i] & 0x80 == 0x80 { i++ - t |= uint{{.Bits}}(buf[i + {{.W.Offset}}]&0x7F) << bs + t |= uint{{.Bits}}(buf[i]&0x7F) << bs bs += 7 } i++ @@ -70,13 +67,11 @@ func init() { {{else}} {{.Target}} = t {{end}} - {{else}} - {{if .W.Unsafe}} - {{.Target}} = *(*{{if not .Signed}}u{{end}}int{{.Bits}})(unsafe.Pointer(&buf[{{if $.W.IAdjusted}}i + {{end}}{{$.W.Offset}}])) + {{.Target}} = *(*{{if not .Signed}}u{{end}}int{{.Bits}})(unsafe.Pointer(&buf[i])) {{else}} - {{$.Target}} = 0{{range BitRange .Bits}} | ({{if not $.Signed}}u{{end}}int{{$.Bits}}(buf[{{if $.W.IAdjusted}}i + {{end}}{{Bytes .}} + {{$.W.Offset}}]) << {{.}}){{end}} + {{$.Target}} = 0{{range BitRange .Bits}} | ({{if not $.Signed}}u{{end}}int{{$.Bits}}(buf[i + {{Bytes .}}]) << {{.}}){{end}} {{end}} i += {{.Bits}}/8 {{end}} @@ -104,6 +99,7 @@ func init() { } s++ {{end}} + {{else}} s += {{.Bits}}/8 {{end}} }`)) @@ -123,12 +119,6 @@ func (w *Walker) WalkIntDef(it *schema.IntType) (parts *StringBuilder, err error func (w *Walker) WalkIntSize(it *schema.IntType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - if !it.VarInt { - w.Offset += it.Bits / 8 - return - } else { - w.IAdjusted = true - } err = parts.AddTemplate(IntTemps, "size", IntTemp{it, w, target}) return } @@ -136,21 +126,11 @@ func (w *Walker) WalkIntSize(it *schema.IntType, target string) (parts *StringBu func (w *Walker) WalkIntMarshal(it *schema.IntType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(IntTemps, "marshal", IntTemp{it, w, target}) - if !it.VarInt { - w.Offset += it.Bits / 8 - } else { - w.IAdjusted = true - } return } func (w *Walker) WalkIntUnmarshal(it *schema.IntType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(IntTemps, "unmarshal", IntTemp{it, w, target}) - if !it.VarInt { - w.Offset += it.Bits / 8 - } else { - w.IAdjusted = true - } return } diff --git a/backends/golang/type_pointer.go b/backends/golang/type_pointer.go index c57cfc7..0afb0fd 100644 --- a/backends/golang/type_pointer.go +++ b/backends/golang/type_pointer.go @@ -15,30 +15,32 @@ func init() { template.Must(PointerTemps.New("marshal").Parse(` { if {{.Target}} == nil { - buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] = 0 + buf[i] = 0 + i++ } else { - buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] = 1 + buf[i] = 1 + i++ {{.SubTypeCode}} - i += {{.SubOffset}} } }`)) template.Must(PointerTemps.New("unmarshal").Parse(` { - if buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}] == 1 { + if buf[i] == 1 { if {{.Target}} == nil { {{.Target}} = new({{.SubField}}) } + i++ {{.SubTypeCode}} - i += {{.SubOffset}} } else { {{.Target}} = nil + i++ } }`)) template.Must(PointerTemps.New("size").Parse(` { + s++ if {{.Target}} != nil { {{.SubTypeCode}} - s += {{.SubOffset}} } }`)) @@ -48,7 +50,6 @@ func init() { type PointerTemp struct { *schema.PointerType W *Walker - SubOffset int Target string SubTypeCode string SubField string @@ -67,24 +68,16 @@ func (w *Walker) WalkPointerDef(pt *schema.PointerType) (parts *StringBuilder, e func (w *Walker) WalkPointerSize(pt *schema.PointerType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - Offset := w.Offset - w.Offset++ subtypecode, err := w.WalkTypeSize(pt.SubType, "(*"+target+")") if err != nil { return nil, err } - SubOffset := w.Offset - (Offset + 1) - w.Offset = Offset - err = parts.AddTemplate(PointerTemps, "size", PointerTemp{pt, w, SubOffset, target, subtypecode.String(), ""}) - w.Offset++ - w.IAdjusted = true + err = parts.AddTemplate(PointerTemps, "size", PointerTemp{pt, w, target, subtypecode.String(), ""}) return } func (w *Walker) WalkPointerMarshal(pt *schema.PointerType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - Offset := w.Offset - w.Offset++ subtypecode, err := w.WalkTypeMarshal(pt.SubType, "(*"+target+")") if err != nil { return nil, err @@ -93,18 +86,12 @@ func (w *Walker) WalkPointerMarshal(pt *schema.PointerType, target string) (part if err != nil { return nil, err } - SubOffset := w.Offset - (Offset + 1) - w.Offset = Offset - err = parts.AddTemplate(PointerTemps, "marshal", PointerTemp{pt, w, SubOffset, target, subtypecode.String(), subfield.String()}) - w.IAdjusted = true - w.Offset++ + err = parts.AddTemplate(PointerTemps, "marshal", PointerTemp{pt, w, target, subtypecode.String(), subfield.String()}) return } func (w *Walker) WalkPointerUnmarshal(pt *schema.PointerType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} - Offset := w.Offset - w.Offset++ subtypecode, err := w.WalkTypeUnmarshal(pt.SubType, "(*"+target+")") if err != nil { return nil, err @@ -113,10 +100,6 @@ func (w *Walker) WalkPointerUnmarshal(pt *schema.PointerType, target string) (pa if err != nil { return nil, err } - SubOffset := w.Offset - (Offset + 1) - w.Offset = Offset - err = parts.AddTemplate(PointerTemps, "unmarshal", PointerTemp{pt, w, SubOffset, target, subtypecode.String(), subfield.String()}) - w.IAdjusted = true - w.Offset++ + err = parts.AddTemplate(PointerTemps, "unmarshal", PointerTemp{pt, w, target, subtypecode.String(), subfield.String()}) return } diff --git a/backends/golang/type_slice.go b/backends/golang/type_slice.go index 39c6b8b..03d677a 100644 --- a/backends/golang/type_slice.go +++ b/backends/golang/type_slice.go @@ -19,9 +19,6 @@ func init() { {{.VarIntCode}} for {{.Variable}} := range {{.Target}} { {{.SubTypeCode}} - {{if gt .SubOffset 0 }} - i += {{.SubOffset}} - {{end}} } }`)) template.Must(SliceTemps.New("unmarshal").Parse(` @@ -35,16 +32,13 @@ func init() { } for {{.Variable}} := range {{.Target}} { {{.SubTypeCode}} - {{if gt .SubOffset 0 }} - i += {{.SubOffset}} - {{end}} } }`)) template.Must(SliceTemps.New("bytemarshal").Parse(` { l := uint64(len({{.Target}})) {{.VarIntCode}} - copy(buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}:], {{.Target}}) + copy(buf[i:], {{.Target}}) i += l }`)) template.Must(SliceTemps.New("byteunmarshal").Parse(` @@ -56,25 +50,17 @@ func init() { } else { {{.Target}} = make([]{{.SubField}}, l) } - copy({{.Target}}, buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}:]) + copy({{.Target}}, buf[i:]) i += l }`)) template.Must(SliceTemps.New("size").Parse(` { l := uint64(len({{.Target}})) {{.VarIntCode}} - {{if eq .SubTypeCode "" }} - {{if gt .SubOffset 0 }} - s += {{.SubOffset}}*l - {{end}} - {{else}} for {{.Variable}} := range {{.Target}} { + _ = {{.Variable}} {{.SubTypeCode}} - {{if gt .SubOffset 0 }} - s += {{.SubOffset}} - {{end}} } - {{end}} }`)) template.Must(SliceTemps.New("bytesize").Parse(` { @@ -88,7 +74,6 @@ func init() { type SliceTemp struct { *schema.SliceType W *Walker - SubOffset int Target string SubTypeCode string SubField string @@ -122,17 +107,14 @@ func (w *Walker) WalkSliceSize(st *schema.SliceType, target string) (parts *Stri if st.Depth > 0 { variable += strconv.Itoa(st.Depth) } - offset := w.Offset subtypecode, err := w.WalkTypeSize(st.SubType, target+"["+variable+"]") if err != nil { return nil, err } - SubOffset := w.Offset - offset - w.Offset = offset if _, ok := st.SubType.(*schema.ByteType); ok { - err = parts.AddTemplate(SliceTemps, "bytesize", SliceTemp{st, w, SubOffset, target, subtypecode.String(), "", intcode.String(), variable}) + err = parts.AddTemplate(SliceTemps, "bytesize", SliceTemp{st, w, target, subtypecode.String(), "", intcode.String(), variable}) } else { - err = parts.AddTemplate(SliceTemps, "size", SliceTemp{st, w, SubOffset, target, subtypecode.String(), "", intcode.String(), variable}) + err = parts.AddTemplate(SliceTemps, "size", SliceTemp{st, w, target, subtypecode.String(), "", intcode.String(), variable}) } return } @@ -152,21 +134,18 @@ func (w *Walker) WalkSliceMarshal(st *schema.SliceType, target string) (parts *S if st.Depth > 0 { variable += strconv.Itoa(st.Depth) } - offset := w.Offset subtypecode, err := w.WalkTypeMarshal(st.SubType, target+"["+variable+"]") if err != nil { return nil, err } - SubOffset := w.Offset - offset - w.Offset = offset subfield, err := w.WalkTypeDef(st.SubType) if err != nil { return nil, err } if _, ok := st.SubType.(*schema.ByteType); ok { - err = parts.AddTemplate(SliceTemps, "bytemarshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), variable}) + err = parts.AddTemplate(SliceTemps, "bytemarshal", SliceTemp{st, w, target, subtypecode.String(), subfield.String(), intcode.String(), variable}) } else { - err = parts.AddTemplate(SliceTemps, "marshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), variable}) + err = parts.AddTemplate(SliceTemps, "marshal", SliceTemp{st, w, target, subtypecode.String(), subfield.String(), intcode.String(), variable}) } return } @@ -186,21 +165,18 @@ func (w *Walker) WalkSliceUnmarshal(st *schema.SliceType, target string) (parts if st.Depth > 0 { variable += strconv.Itoa(st.Depth) } - offset := w.Offset subtypecode, err := w.WalkTypeUnmarshal(st.SubType, target+"["+variable+"]") if err != nil { return nil, err } - SubOffset := w.Offset - offset - w.Offset = offset subfield, err := w.WalkTypeDef(st.SubType) if err != nil { return nil, err } if _, ok := st.SubType.(*schema.ByteType); ok { - err = parts.AddTemplate(SliceTemps, "byteunmarshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), variable}) + err = parts.AddTemplate(SliceTemps, "byteunmarshal", SliceTemp{st, w, target, subtypecode.String(), subfield.String(), intcode.String(), variable}) } else { - err = parts.AddTemplate(SliceTemps, "unmarshal", SliceTemp{st, w, SubOffset, target, subtypecode.String(), subfield.String(), intcode.String(), variable}) + err = parts.AddTemplate(SliceTemps, "unmarshal", SliceTemp{st, w, target, subtypecode.String(), subfield.String(), intcode.String(), variable}) } return } diff --git a/backends/golang/type_string.go b/backends/golang/type_string.go index a3d364b..5f2c252 100644 --- a/backends/golang/type_string.go +++ b/backends/golang/type_string.go @@ -17,14 +17,14 @@ func init() { { l := uint64(len({{.Target}})) {{.VarIntCode}} - copy(buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}:], {{.Target}}) + copy(buf[i:], {{.Target}}) i += l }`)) template.Must(StringTemps.New("unmarshal").Parse(` { l := uint64(0) {{.VarIntCode}} - {{.Target}} = string(buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}:{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}+l]) + {{.Target}} = string(buf[i:i+l]) i += l }`)) template.Must(StringTemps.New("size").Parse(` diff --git a/backends/golang/type_struct.go b/backends/golang/type_struct.go index 2895bc3..68ba32f 100644 --- a/backends/golang/type_struct.go +++ b/backends/golang/type_struct.go @@ -15,7 +15,7 @@ func init() { template.Must(StructTemps.New("marshal").Parse(` { - nbuf, err := {{.Target}}.Marshal(buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}:]) + nbuf, err := {{.Target}}.Marshal(buf[i:]) if err != nil { return nil, err } @@ -23,7 +23,7 @@ func init() { }`)) template.Must(StructTemps.New("unmarshal").Parse(` { - ni, err := {{.Target}}.Unmarshal(buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}:]) + ni, err := {{.Target}}.Unmarshal(buf[i:]) if err != nil { return 0, err } @@ -51,20 +51,17 @@ func (w *Walker) WalkStructDef(st *schema.StructType) (parts *StringBuilder, err func (w *Walker) WalkStructSize(st *schema.StructType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(StructTemps, "size", StructTemp{st, w, target}) - w.IAdjusted = true return } func (w *Walker) WalkStructMarshal(st *schema.StructType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(StructTemps, "marshal", StructTemp{st, w, target}) - w.IAdjusted = true return } func (w *Walker) WalkStructUnmarshal(st *schema.StructType, target string) (parts *StringBuilder, err error) { parts = &StringBuilder{} err = parts.AddTemplate(StructTemps, "unmarshal", StructTemp{st, w, target}) - w.IAdjusted = true return } diff --git a/backends/golang/type_time.go b/backends/golang/type_time.go deleted file mode 100644 index c409e53..0000000 --- a/backends/golang/type_time.go +++ /dev/null @@ -1,61 +0,0 @@ -package golang - -import ( - "text/template" - - "github.com/eyrie-io/gencode/schema" -) - -var ( - TimeTemps *template.Template -) - -func init() { - TimeTemps = template.New("TimeTemps") - - template.Must(TimeTemps.New("marshal").Parse(` - { - b, err := {{.Target}}.MarshalBinary() - if err != nil { - return nil, err - } - copy(buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}:], b) - }`)) - template.Must(TimeTemps.New("unmarshal").Parse(` - { - {{.Target}}.UnmarshalBinary(buf[{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}}:{{if .W.IAdjusted}}i + {{end}}{{.W.Offset}} + 15]) - }`)) - template.Must(TimeTemps.New("field").Parse(`time.Time`)) -} - -type TimeTemp struct { - *schema.TimeType - W *Walker - Target string -} - -func (w *Walker) WalkTimeDef(tt *schema.TimeType) (parts *StringBuilder, err error) { - parts = &StringBuilder{} - err = parts.AddTemplate(TimeTemps, "field", tt) - return -} - -func (w *Walker) WalkTimeSize(tt *schema.TimeType, target string) (parts *StringBuilder, err error) { - parts = &StringBuilder{} - w.Offset += 15 - return -} - -func (w *Walker) WalkTimeMarshal(tt *schema.TimeType, target string) (parts *StringBuilder, err error) { - parts = &StringBuilder{} - err = parts.AddTemplate(TimeTemps, "marshal", TimeTemp{tt, w, target}) - w.Offset += 15 - return -} - -func (w *Walker) WalkTimeUnmarshal(tt *schema.TimeType, target string) (parts *StringBuilder, err error) { - parts = &StringBuilder{} - err = parts.AddTemplate(TimeTemps, "unmarshal", TimeTemp{tt, w, target}) - w.Offset += 15 - return -} diff --git a/backends/golang/type_union.go b/backends/golang/type_union.go deleted file mode 100644 index 8f8a489..0000000 --- a/backends/golang/type_union.go +++ /dev/null @@ -1,198 +0,0 @@ -package golang - -import ( - "text/template" - - "github.com/eyrie-io/gencode/schema" -) - -var ( - UnionTemps *template.Template -) - -func init() { - UnionTemps = template.New("UnionTemps") - - template.Must(UnionTemps.New("marshal").Parse(` - { - var v uint64 - switch {{.Target}}.(type) { - {{range $id, $type := .SubTypeField}} - case {{$type}}: - v = {{$id}} + 1 - {{end}} - } - {{.VarIntCode}} - switch tt := {{.Target}}.(type) { - {{range $id, $type := .SubTypeField}} - case {{$type}}: - {{index $.SubTypeCode $id}} - {{if gt (index $.SubTypeOffset $id) 0 }} - i += {{index $.SubTypeOffset $id}} - {{end}} - {{end}} - } - }`)) - template.Must(UnionTemps.New("unmarshal").Parse(` - { - v := uint64(0) - {{.VarIntCode}} - switch v { - {{range $id, $type := .SubTypeField}} - case {{$id}} + 1: - var tt {{$type}} - {{index $.SubTypeCode $id}} - {{if gt (index $.SubTypeOffset $id) 0 }} - i += {{index $.SubTypeOffset $id}} - {{end}} - {{$.Target}} = tt - {{end}} - default: - {{.Target}} = nil - } - }`)) - template.Must(UnionTemps.New("size").Parse(` - { - var v uint64 - switch {{.Target}}.(type) { - {{range $id, $type := .SubTypeField}} - case {{$type}}: - v = {{$id}} + 1 - {{end}} - } - {{.VarIntCode}} - switch tt := {{.Target}}.(type) { - {{range $id, $type := .SubTypeField}} - case {{$type}}: - {{index $.SubTypeCode $id}} - {{if gt (index $.SubTypeOffset $id) 0 }} - s += {{index $.SubTypeOffset $id}} - {{end}} - {{end}} - } - }`)) - template.Must(UnionTemps.New("field").Parse(`{{if .Interface}}{{.Interface}}{{else}}interface{}{{end}}`)) -} - -type UnionTemp struct { - *schema.UnionType - Target string - VarIntCode string - SubTypeCode []string - SubTypeField []string - SubTypeOffset []int -} - -func (w *Walker) WalkUnionDef(ut *schema.UnionType) (parts *StringBuilder, err error) { - parts = &StringBuilder{} - err = parts.AddTemplate(UnionTemps, "field", ut) - return -} - -func (w *Walker) WalkUnionSize(ut *schema.UnionType, target string) (parts *StringBuilder, err error) { - parts = &StringBuilder{} - intHandler := &schema.IntType{ - Bits: 64, - Signed: false, - VarInt: true, - } - intcode, err := w.WalkIntSize(intHandler, "v") - if err != nil { - return nil, err - } - subtypecodes := []string{} - subtypeoffsets := []int{} - for _, st := range ut.Types { - offset := w.Offset - subType, err := w.WalkTypeSize(st, "tt") - if err != nil { - return nil, err - } - SubOffset := w.Offset - offset - w.Offset = offset - subtypeoffsets = append(subtypeoffsets, SubOffset) - subtypecodes = append(subtypecodes, subType.String()) - } - subtypefields := []string{} - for _, st := range ut.Types { - subType, err := w.WalkTypeDef(st) - if err != nil { - return nil, err - } - subtypefields = append(subtypefields, subType.String()) - } - err = parts.AddTemplate(UnionTemps, "size", UnionTemp{ut, target, intcode.String(), subtypecodes, subtypefields, subtypeoffsets}) - return -} - -func (w *Walker) WalkUnionMarshal(ut *schema.UnionType, target string) (parts *StringBuilder, err error) { - parts = &StringBuilder{} - intHandler := &schema.IntType{ - Bits: 64, - Signed: false, - VarInt: true, - } - intcode, err := w.WalkIntMarshal(intHandler, "v") - if err != nil { - return nil, err - } - subtypecodes := []string{} - subtypeoffsets := []int{} - for _, st := range ut.Types { - offset := w.Offset - subType, err := w.WalkTypeMarshal(st, "tt") - if err != nil { - return nil, err - } - SubOffset := w.Offset - offset - w.Offset = offset - subtypeoffsets = append(subtypeoffsets, SubOffset) - subtypecodes = append(subtypecodes, subType.String()) - } - subtypefields := []string{} - for _, st := range ut.Types { - subType, err := w.WalkTypeDef(st) - if err != nil { - return nil, err - } - subtypefields = append(subtypefields, subType.String()) - } - err = parts.AddTemplate(UnionTemps, "marshal", UnionTemp{ut, target, intcode.String(), subtypecodes, subtypefields, subtypeoffsets}) - return -} - -func (w *Walker) WalkUnionUnmarshal(ut *schema.UnionType, target string) (parts *StringBuilder, err error) { - parts = &StringBuilder{} - intHandler := &schema.IntType{ - Bits: 64, - Signed: false, - VarInt: true, - } - intcode, err := w.WalkIntUnmarshal(intHandler, "v") - if err != nil { - return nil, err - } - subtypecodes := []string{} - subtypeoffsets := []int{} - for _, st := range ut.Types { - offset := w.Offset - subType, err := w.WalkTypeUnmarshal(st, "tt") - if err != nil { - return nil, err - } - SubOffset := w.Offset - offset - w.Offset = offset - subtypeoffsets = append(subtypeoffsets, SubOffset) - subtypecodes = append(subtypecodes, subType.String()) - } - subtypefields := []string{} - for _, st := range ut.Types { - subType, err := w.WalkTypeDef(st) - if err != nil { - return nil, err - } - subtypefields = append(subtypefields, subType.String()) - } - err = parts.AddTemplate(UnionTemps, "unmarshal", UnionTemp{ut, target, intcode.String(), subtypecodes, subtypefields, subtypeoffsets}) - return -} diff --git a/backends/golang/types.go b/backends/golang/types.go index d7be563..617a10e 100644 --- a/backends/golang/types.go +++ b/backends/golang/types.go @@ -30,10 +30,6 @@ func (w *Walker) WalkTypeDef(t schema.Type) (*StringBuilder, error) { return w.WalkStringDef(tt) case *schema.StructType: return w.WalkStructDef(tt) - case *schema.TimeType: - return w.WalkTimeDef(tt) - case *schema.UnionType: - return w.WalkUnionDef(tt) } return nil, fmt.Errorf("No such type %T", t) } @@ -62,10 +58,6 @@ func (w *Walker) WalkTypeSize(t schema.Type, target string) (*StringBuilder, err return w.WalkStringSize(tt, target) case *schema.StructType: return w.WalkStructSize(tt, target) - case *schema.TimeType: - return w.WalkTimeSize(tt, target) - case *schema.UnionType: - return w.WalkUnionSize(tt, target) } return nil, fmt.Errorf("No such type %T", t) } @@ -94,10 +86,6 @@ func (w *Walker) WalkTypeMarshal(t schema.Type, target string) (*StringBuilder, return w.WalkStringMarshal(tt, target) case *schema.StructType: return w.WalkStructMarshal(tt, target) - case *schema.TimeType: - return w.WalkTimeMarshal(tt, target) - case *schema.UnionType: - return w.WalkUnionMarshal(tt, target) } return nil, fmt.Errorf("No such type %T", t) } @@ -126,10 +114,6 @@ func (w *Walker) WalkTypeUnmarshal(t schema.Type, target string) (*StringBuilder return w.WalkStringUnmarshal(tt, target) case *schema.StructType: return w.WalkStructUnmarshal(tt, target) - case *schema.TimeType: - return w.WalkTimeUnmarshal(tt, target) - case *schema.UnionType: - return w.WalkUnionUnmarshal(tt, target) } return nil, fmt.Errorf("No such type %T", t) }