From 80352c7ae952c2a7bce727c18d2a1e7b9776f786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 13 Feb 2020 02:34:05 +0100 Subject: [PATCH 1/2] int64 support in map encoders --- gen.go | 12 +++++++--- testing/cbor_map_gen.go | 50 ++++++++++++++++++++++++++++++++++++++++- testing/types.go | 11 ++++----- 3 files changed, 64 insertions(+), 9 deletions(-) diff --git a/gen.go b/gen.go index ac2c9f1..2a5ba9a 100644 --- a/gen.go +++ b/gen.go @@ -73,7 +73,6 @@ func (f Field) ElemName() string { return typeName(f.Pkg, f.Type.Elem()) } - type GenTypeInfo struct { Name string Fields []Field @@ -592,8 +591,7 @@ func emitCborUnmarshalStructField(w io.Writer, f Field) error { } } -func -emitCborUnmarshalInt64Field(w io.Writer, f Field) error { +func emitCborUnmarshalInt64Field(w io.Writer, f Field) error { return doTemplate(w, f, `{ maj, extra, err := cbg.CborReadHeader(br) var extraI int64 @@ -1010,6 +1008,10 @@ func emitCborMarshalStructMap(w io.Writer, gti *GenTypeInfo) error { if err := emitCborMarshalUint64Field(w, f); err != nil { return err } + case reflect.Int64: + if err := emitCborMarshalInt64Field(w, f); err != nil { + return err + } case reflect.Uint8: if err := emitCborMarshalUint8Field(w, f); err != nil { return err @@ -1097,6 +1099,10 @@ func (t *{{ .Name}}) UnmarshalCBOR(r io.Reader) error { if err := emitCborUnmarshalUint64Field(w, f); err != nil { return err } + case reflect.Int64: + if err := emitCborUnmarshalInt64Field(w, f); err != nil { + return err + } case reflect.Uint8: if err := emitCborUnmarshalUint8Field(w, f); err != nil { return err diff --git a/testing/cbor_map_gen.go b/testing/cbor_map_gen.go index 6780285..c67f4fa 100644 --- a/testing/cbor_map_gen.go +++ b/testing/cbor_map_gen.go @@ -17,7 +17,7 @@ func (t *SimpleTypeTree) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{165}); err != nil { + if _, err := w.Write([]byte{166}); err != nil { return err } @@ -110,6 +110,28 @@ func (t *SimpleTypeTree) MarshalCBOR(w io.Writer) error { } } + // t.SixtyThreeBitIntegerWithASignBit (int64) (int64) + if len("SixtyThreeBitIntegerWithASignBit") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"SixtyThreeBitIntegerWithASignBit\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SixtyThreeBitIntegerWithASignBit")))); err != nil { + return err + } + if _, err := w.Write([]byte("SixtyThreeBitIntegerWithASignBit")); err != nil { + return err + } + + if t.SixtyThreeBitIntegerWithASignBit >= 0 { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SixtyThreeBitIntegerWithASignBit))); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.SixtyThreeBitIntegerWithASignBit)-1)); err != nil { + return err + } + } + // t.Dog (string) (string) if len("Dog") > cbg.MaxLength { return xerrors.Errorf("Value in field \"Dog\" was too long") @@ -283,6 +305,32 @@ func (t *SimpleTypeTree) UnmarshalCBOR(r io.Reader) error { } } + // t.SixtyThreeBitIntegerWithASignBit (int64) (int64) + case "SixtyThreeBitIntegerWithASignBit": + { + maj, extra, err := cbg.CborReadHeader(br) + var extraI int64 + if err != nil { + return err + } + switch maj { + case cbg.MajUnsignedInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 positive overflow") + } + case cbg.MajNegativeInt: + extraI = int64(extra) + if extraI < 0 { + return fmt.Errorf("int64 negative oveflow") + } + extraI = -1 - extraI + default: + return fmt.Errorf("wrong type for int64 field: %d", maj) + } + + t.SixtyThreeBitIntegerWithASignBit = int64(extraI) + } // t.Dog (string) (string) case "Dog": diff --git a/testing/types.go b/testing/types.go index 0f28b64..a77ea55 100644 --- a/testing/types.go +++ b/testing/types.go @@ -23,9 +23,10 @@ type SimpleTypeTwo struct { } type SimpleTypeTree struct { - Stuff *SimpleTypeTree - Stufff *SimpleTypeTwo - Others []uint64 - Test [][]byte - Dog string + Stuff *SimpleTypeTree + Stufff *SimpleTypeTwo + Others []uint64 + Test [][]byte + SixtyThreeBitIntegerWithASignBit int64 + Dog string } From 51052a1e8191f28256f25fe27ace7224cbf40ec9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Sat, 22 Feb 2020 17:07:27 +0100 Subject: [PATCH 2/2] Support uint64 pointers --- gen.go | 40 ++++++++++++++-- testing/cbor_gen.go | 100 ++++++++++++++++++++++++++++++++++++---- testing/cbor_map_gen.go | 86 ++++++++++++++++++++++++++-------- testing/types.go | 5 +- 4 files changed, 200 insertions(+), 31 deletions(-) diff --git a/gen.go b/gen.go index 2a5ba9a..c9108b2 100644 --- a/gen.go +++ b/gen.go @@ -211,13 +211,22 @@ func emitCborMarshalStructField(w io.Writer, f Field) error { } func emitCborMarshalUint64Field(w io.Writer, f Field) error { - if f.Pointer { - return fmt.Errorf("pointers to integers not supported") - } return doTemplate(w, f, ` +{{ if .Pointer }} + if {{ .Name }} == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(*{{ .Name }}))); err != nil { + return err + } + } +{{ else }} if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64({{ .Name }}))); err != nil { return err } +{{ end }} `) } @@ -621,6 +630,29 @@ func emitCborUnmarshalInt64Field(w io.Writer, f Field) error { func emitCborUnmarshalUint64Field(w io.Writer, f Field) error { return doTemplate(w, f, ` + { +{{ if .Pointer }} + pb, err := br.PeekByte() + if err != nil { + return err + } + if pb == cbg.CborNull[0] { + var nbuf [1]byte + if _, err := br.Read(nbuf[:]); err != nil { + return err + } + } else { + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + typed := {{ .TypeName }}(extra) + {{ .Name }} = &typed + } +{{ else }} maj, extra, err = cbg.CborReadHeader(br) if err != nil { return err @@ -629,6 +661,8 @@ func emitCborUnmarshalUint64Field(w io.Writer, f Field) error { return fmt.Errorf("wrong type for uint64 field") } {{ .Name }} = {{ .TypeName }}(extra) +{{ end }} + } `) } diff --git a/testing/cbor_gen.go b/testing/cbor_gen.go index 80ac168..02fa57a 100644 --- a/testing/cbor_gen.go +++ b/testing/cbor_gen.go @@ -108,6 +108,7 @@ func (t *SimpleTypeOne) MarshalCBOR(w io.Writer) error { } // t.Value (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.Value))); err != nil { return err } @@ -164,14 +165,18 @@ func (t *SimpleTypeOne) UnmarshalCBOR(r io.Reader) error { } // t.Value (uint64) (uint64) - maj, extra, err = cbg.CborReadHeader(br) - if err != nil { - return err - } - if maj != cbg.MajUnsignedInt { - return fmt.Errorf("wrong type for uint64 field") + { + + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Value = uint64(extra) + } - t.Value = uint64(extra) // t.Binary ([]uint8) (slice) maj, extra, err = cbg.CborReadHeader(br) @@ -222,7 +227,7 @@ func (t *SimpleTypeTwo) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{134}); err != nil { + if _, err := w.Write([]byte{136}); err != nil { return err } @@ -311,6 +316,31 @@ func (t *SimpleTypeTwo) MarshalCBOR(w io.Writer) error { return err } } + + // t.Pizza (uint64) (uint64) + + if t.Pizza == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(*t.Pizza))); err != nil { + return err + } + } + + // t.PointyPizza (testing.NaturalNumber) (uint64) + + if t.PointyPizza == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(*t.PointyPizza))); err != nil { + return err + } + } + return nil } @@ -325,7 +355,7 @@ func (t *SimpleTypeTwo) UnmarshalCBOR(r io.Reader) error { return fmt.Errorf("cbor input should be of type array") } - if extra != 6 { + if extra != 8 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -507,5 +537,57 @@ func (t *SimpleTypeTwo) UnmarshalCBOR(r io.Reader) error { t.Numbers[i] = NaturalNumber(val) } + // t.Pizza (uint64) (uint64) + + { + + pb, err := br.PeekByte() + if err != nil { + return err + } + if pb == cbg.CborNull[0] { + var nbuf [1]byte + if _, err := br.Read(nbuf[:]); err != nil { + return err + } + } else { + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + typed := uint64(extra) + t.Pizza = &typed + } + + } + // t.PointyPizza (testing.NaturalNumber) (uint64) + + { + + pb, err := br.PeekByte() + if err != nil { + return err + } + if pb == cbg.CborNull[0] { + var nbuf [1]byte + if _, err := br.Read(nbuf[:]); err != nil { + return err + } + } else { + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + typed := NaturalNumber(extra) + t.PointyPizza = &typed + } + + } return nil } diff --git a/testing/cbor_map_gen.go b/testing/cbor_map_gen.go index c67f4fa..0d5c6ec 100644 --- a/testing/cbor_map_gen.go +++ b/testing/cbor_map_gen.go @@ -17,7 +17,7 @@ func (t *SimpleTypeTree) MarshalCBOR(w io.Writer) error { _, err := w.Write(cbg.CborNull) return err } - if _, err := w.Write([]byte{166}); err != nil { + if _, err := w.Write([]byte{167}); err != nil { return err } @@ -110,6 +110,29 @@ func (t *SimpleTypeTree) MarshalCBOR(w io.Writer) error { } } + // t.Dog (string) (string) + if len("Dog") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"Dog\" was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Dog")))); err != nil { + return err + } + if _, err := w.Write([]byte("Dog")); err != nil { + return err + } + + if len(t.Dog) > cbg.MaxLength { + return xerrors.Errorf("Value in field t.Dog was too long") + } + + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Dog)))); err != nil { + return err + } + if _, err := w.Write([]byte(t.Dog)); err != nil { + return err + } + // t.SixtyThreeBitIntegerWithASignBit (int64) (int64) if len("SixtyThreeBitIntegerWithASignBit") > cbg.MaxLength { return xerrors.Errorf("Value in field \"SixtyThreeBitIntegerWithASignBit\" was too long") @@ -132,28 +155,28 @@ func (t *SimpleTypeTree) MarshalCBOR(w io.Writer) error { } } - // t.Dog (string) (string) - if len("Dog") > cbg.MaxLength { - return xerrors.Errorf("Value in field \"Dog\" was too long") + // t.NotPizza (uint64) (uint64) + if len("NotPizza") > cbg.MaxLength { + return xerrors.Errorf("Value in field \"NotPizza\" was too long") } - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Dog")))); err != nil { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("NotPizza")))); err != nil { return err } - if _, err := w.Write([]byte("Dog")); err != nil { + if _, err := w.Write([]byte("NotPizza")); err != nil { return err } - if len(t.Dog) > cbg.MaxLength { - return xerrors.Errorf("Value in field t.Dog was too long") + if t.NotPizza == nil { + if _, err := w.Write(cbg.CborNull); err != nil { + return err + } + } else { + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(*t.NotPizza))); err != nil { + return err + } } - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len(t.Dog)))); err != nil { - return err - } - if _, err := w.Write([]byte(t.Dog)); err != nil { - return err - } return nil } @@ -305,6 +328,17 @@ func (t *SimpleTypeTree) UnmarshalCBOR(r io.Reader) error { } } + // t.Dog (string) (string) + case "Dog": + + { + sval, err := cbg.ReadString(br) + if err != nil { + return err + } + + t.Dog = string(sval) + } // t.SixtyThreeBitIntegerWithASignBit (int64) (int64) case "SixtyThreeBitIntegerWithASignBit": { @@ -331,16 +365,32 @@ func (t *SimpleTypeTree) UnmarshalCBOR(r io.Reader) error { t.SixtyThreeBitIntegerWithASignBit = int64(extraI) } - // t.Dog (string) (string) - case "Dog": + // t.NotPizza (uint64) (uint64) + case "NotPizza": { - sval, err := cbg.ReadString(br) + + pb, err := br.PeekByte() if err != nil { return err } + if pb == cbg.CborNull[0] { + var nbuf [1]byte + if _, err := br.Read(nbuf[:]); err != nil { + return err + } + } else { + maj, extra, err = cbg.CborReadHeader(br) + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + typed := uint64(extra) + t.NotPizza = &typed + } - t.Dog = string(sval) } default: diff --git a/testing/types.go b/testing/types.go index a77ea55..db0b2e4 100644 --- a/testing/types.go +++ b/testing/types.go @@ -20,6 +20,8 @@ type SimpleTypeTwo struct { Test [][]byte Dog string Numbers []NaturalNumber + Pizza *uint64 + PointyPizza *NaturalNumber } type SimpleTypeTree struct { @@ -27,6 +29,7 @@ type SimpleTypeTree struct { Stufff *SimpleTypeTwo Others []uint64 Test [][]byte - SixtyThreeBitIntegerWithASignBit int64 Dog string + SixtyThreeBitIntegerWithASignBit int64 + NotPizza *uint64 }