From fbd09553e3587701347eafca5a01a5d81ab3b661 Mon Sep 17 00:00:00 2001 From: billsegall Date: Tue, 11 Feb 2020 14:42:27 +1000 Subject: [PATCH 1/2] Fix a bug in populating optional values when they are arrays --- gocode/Makefile | 2 +- .../resources/example-extension-2-schema.xml | 94 ------------------- .../generation/golang/GolangGenerator.java | 21 ++++- 3 files changed, 18 insertions(+), 99 deletions(-) delete mode 100644 gocode/resources/example-extension-2-schema.xml diff --git a/gocode/Makefile b/gocode/Makefile index c07f7931ba..7a471aee87 100644 --- a/gocode/Makefile +++ b/gocode/Makefile @@ -59,7 +59,7 @@ src/baseline/SbeMarshalling.go: $(DEP) # they geenrate into the same directory but golang doesn't allow that test: $(DEP) (export GOPATH=$(GOPATH) && \ - (for t in baseline extension extension2; do \ + (for t in baseline extension; do \ export GOPATH=$(GOPATH) && \ cd $(GOPATH)/src/$$t && \ go build && \ diff --git a/gocode/resources/example-extension-2-schema.xml b/gocode/resources/example-extension-2-schema.xml deleted file mode 100644 index 330e84c1d5..0000000000 --- a/gocode/resources/example-extension-2-schema.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - T - S - N - K - - - - - - - 9000 - - Petrol - - - - - - 0 - 1 - - - A - B - C - - - 0 - 1 - 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/golang/GolangGenerator.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/golang/GolangGenerator.java index a16fdbb741..b9b57db312 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/golang/GolangGenerator.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/golang/GolangGenerator.java @@ -494,10 +494,23 @@ private void generateOptionalInitPrimitive( final Encoding encoding = token.encoding(); // Optional items get initialized to their NullValue - sb.append(String.format( - "\t%1$s = %2$s\n", - varName, - generateNullValueLiteral(encoding.primitiveType(), encoding))); + if (token.arrayLength() > 1) + { + sb.append(String.format( + "\tfor idx := 0; idx < %1$d; idx++ {\n" + + "\t\t%2$s[idx] = %3$s\n" + + "\t}\n", + token.arrayLength(), + varName, + generateNullValueLiteral(encoding.primitiveType(), encoding))); + } + else + { + sb.append(String.format( + "\t%1$s = %2$s\n", + varName, + generateNullValueLiteral(encoding.primitiveType(), encoding))); + } } private void generateConstantInitPrimitive( From 3ef72c9c1a344bc908df9ead86e03f42148b4da8 Mon Sep 17 00:00:00 2001 From: billsegall Date: Tue, 11 Feb 2020 14:52:51 +1000 Subject: [PATCH 2/2] Freshen the examples and tests to reflect changes to the example schemas. Drop the gocode specific second extension example as it's a maintenance nightmare. --- build.gradle | 1 - gocode/src/baseline/Car_test.go | 8 +- gocode/src/example-schema/CarExample.go | 239 +----------------------- 3 files changed, 12 insertions(+), 236 deletions(-) diff --git a/build.gradle b/build.gradle index 5978d7199b..7b2c495eb0 100644 --- a/build.gradle +++ b/build.gradle @@ -632,7 +632,6 @@ task generateGolangCodecsWithXSD(type: JavaExec) { 'sbe-tool/src/test/resources/since-deprecated-test-schema.xml', 'sbe-tool/src/test/resources/example-bigendian-test-schema.xml', 'gocode/resources/example-composite.xml', - 'gocode/resources/example-extension-2-schema.xml', 'gocode/resources/group-with-data-extension-schema.xml', 'gocode/resources/simple.xml'] } diff --git a/gocode/src/baseline/Car_test.go b/gocode/src/baseline/Car_test.go index 2af880336e..f0e601dd21 100644 --- a/gocode/src/baseline/Car_test.go +++ b/gocode/src/baseline/Car_test.go @@ -45,7 +45,7 @@ func TestEncodeDecodeCar(t *testing.T) { pf = append(pf, CarPerformanceFigures{95, acc1}) pf = append(pf, CarPerformanceFigures{99, acc2}) - in := Car{1234, 2013, BooleanType.T, Model.A, [5]uint32{0, 1, 2, 3, 4}, vehicleCode, optionalExtras, Model.A, engine, fuel, pf, manufacturer, model, activationCode} + in := Car{1234, 2013, BooleanType.T, Model.A, [4]uint32{0, 1, 2, 3}, vehicleCode, optionalExtras, Model.A, engine, fuel, pf, manufacturer, model, activationCode} var buf = new(bytes.Buffer) if err := in.Encode(m, buf, true); err != nil { @@ -112,10 +112,8 @@ func TestEncodeDecodeCar(t *testing.T) { } func TestDecodeJavaBuffer(t *testing.T) { - - // The byte array is from the java example for interop test made by - // running with -Dsbe.encoding.filename and then decoded using od -tu1 - data := []byte{49, 0, 1, 0, 1, 0, 0, 0, 210, 4, 0, 0, 0, 0, 0, 0, 221, 7, 1, 65, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 97, 98, 99, 100, 101, 102, 6, 208, 7, 4, 49, 50, 51, 35, 1, 78, 200, 6, 0, 3, 0, 30, 0, 154, 153, 15, 66, 11, 0, 0, 0, 85, 114, 98, 97, 110, 32, 67, 121, 99, 108, 101, 55, 0, 0, 0, 68, 66, 14, 0, 0, 0, 67, 111, 109, 98, 105, 110, 101, 100, 32, 67, 121, 99, 108, 101, 75, 0, 0, 0, 32, 66, 13, 0, 0, 0, 72, 105, 103, 104, 119, 97, 121, 32, 67, 121, 99, 108, 101, 1, 0, 2, 0, 95, 6, 0, 3, 0, 30, 0, 0, 0, 128, 64, 60, 0, 0, 0, 240, 64, 100, 0, 51, 51, 67, 65, 99, 6, 0, 3, 0, 30, 0, 51, 51, 115, 64, 60, 0, 51, 51, 227, 64, 100, 0, 205, 204, 60, 65, 5, 0, 0, 0, 72, 111, 110, 100, 97, 9, 0, 0, 0, 67, 105, 118, 105, 99, 32, 86, 84, 105, 6, 0, 0, 0, 97, 98, 99, 100, 101, 102} + // See ~gocode/src/example-schema/CarExample.go for how this is generated + data := []byte{45, 0, 1, 0, 1, 0, 0, 0, 210, 4, 0, 0, 0, 0, 0, 0, 221, 7, 1, 65, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 97, 98, 99, 100, 101, 102, 6, 208, 7, 4, 49, 50, 51, 35, 1, 78, 200, 6, 0, 3, 0, 30, 0, 154, 153, 15, 66, 11, 0, 0, 0, 85, 114, 98, 97, 110, 32, 67, 121, 99, 108, 101, 55, 0, 0, 0, 68, 66, 14, 0, 0, 0, 67, 111, 109, 98, 105, 110, 101, 100, 32, 67, 121, 99, 108, 101, 75, 0, 0, 0, 32, 66, 13, 0, 0, 0, 72, 105, 103, 104, 119, 97, 121, 32, 67, 121, 99, 108, 101, 1, 0, 2, 0, 95, 6, 0, 3, 0, 30, 0, 0, 0, 128, 64, 60, 0, 0, 0, 240, 64, 100, 0, 51, 51, 67, 65, 99, 6, 0, 3, 0, 30, 0, 51, 51, 115, 64, 60, 0, 51, 51, 227, 64, 100, 0, 205, 204, 60, 65, 5, 0, 0, 0, 72, 111, 110, 100, 97, 9, 0, 0, 0, 67, 105, 118, 105, 99, 32, 86, 84, 105, 6, 0, 0, 0, 97, 98, 99, 100, 101, 102} buf := bytes.NewBuffer(data) m := NewSbeGoMarshaller() diff --git a/gocode/src/example-schema/CarExample.go b/gocode/src/example-schema/CarExample.go index ab5709040c..dee6e32588 100644 --- a/gocode/src/example-schema/CarExample.go +++ b/gocode/src/example-schema/CarExample.go @@ -5,11 +5,9 @@ package main import ( "baseline" // Car "bytes" - "extension" // Car extended with cupholder - "extension2" // extension extended with CO2 + "extension" // Car extended with cupholder "fmt" "io" - "math" "net" "os" "reflect" @@ -39,12 +37,6 @@ func main() { fmt.Println("Example Extension->Car") ExampleExtensionToCar() - fmt.Println("Example Car->Extension2") - ExampleCarToExtension2() - - fmt.Println("Example Extension2->Car") - ExampleExtension2ToCar() - fmt.Println("Example decode using bytes.buffer") ExampleDecodeBuffer() @@ -140,7 +132,7 @@ func ExampleDecodeBuffer() bool { // fmt.Println("\tbuffer is length:", buf.Len()) var c baseline.Car if err := c.Decode(m, buf, hdr.Version, hdr.BlockLength, true); err != nil { - fmt.Println("Failed to decode car", err) + fmt.Println("FIXME: Failed to decode car", err) os.Exit(1) } return true @@ -433,180 +425,6 @@ func ExampleExtensionToCar() bool { return true } -func ExampleExtension2ToCar() bool { - in := makeExtension2() - min := extension2.NewSbeGoMarshaller() - mout := baseline.NewSbeGoMarshaller() - - var buf = new(bytes.Buffer) - if err := in.Encode(min, buf, true); err != nil { - fmt.Println("Encoding Error", err) - os.Exit(1) - } - - var out baseline.Car = *new(baseline.Car) - if err := out.Decode(mout, buf, in.SbeSchemaVersion(), in.SbeBlockLength(), true); err != nil { - fmt.Println("Decoding Error", err) - os.Exit(1) - } - - if in.SerialNumber != out.SerialNumber { - fmt.Println("in.SerialNumber != out.SerialNumber:\n", in.SerialNumber, out.SerialNumber) - os.Exit(1) - } - if in.ModelYear != out.ModelYear { - fmt.Println("in.ModelYear != out.ModelYear:\n", in.ModelYear, out.ModelYear) - os.Exit(1) - } - - // Note casts so we can compare - if in.Available != extension2.BooleanTypeEnum(out.Available) { - fmt.Println("in.Available != out.Available:\n", in.Available, out.Available) - os.Exit(1) - } - if in.Code != extension2.ModelEnum(out.Code) { - fmt.Println("in.Code != out.Code:\n", in.Code, out.Code) - os.Exit(1) - } - if in.SomeNumbers != out.SomeNumbers { - fmt.Println("in.SomeNumbers != out.SomeNumbers:\n", in.SomeNumbers, out.SomeNumbers) - os.Exit(1) - } - if in.VehicleCode != out.VehicleCode { - fmt.Println("in.VehicleCode != out.VehicleCode:\n", in.VehicleCode, out.VehicleCode) - os.Exit(1) - } - if in.Extras != extension2.OptionalExtras(out.Extras) { - fmt.Println("in.Extras != out.Extras:\n", in.Extras, out.Extras) - os.Exit(1) - } - - // DiscountedModel is constant - if extension2.Model.C != extension2.ModelEnum(out.DiscountedModel) { - fmt.Println("in.DiscountedModel != out.DiscountedModel:\n", in.DiscountedModel, out.DiscountedModel) - os.Exit(1) - } - - // Engine has two constant values which in this case should match - if in.Engine.MaxRpm != out.Engine.MaxRpm { - fmt.Println("in.Engine.MaxRpm != out.Engine/MaxRpm:\n", in.Engine.MaxRpm, out.Engine.MaxRpm) - os.Exit(1) - } - - if !reflect.DeepEqual(in.ActivationCode, out.ActivationCode) { - fmt.Println("in.ActivationCode != out.ActivationCode:\n", in.ActivationCode, out.ActivationCode) - os.Exit(1) - - } - - // Extension2 added Co2 to FuelFigures before the UsageDescription - // check UsageDescription still look right - if !reflect.DeepEqual(out.FuelFigures[0].UsageDescription, []uint8("Urban Cycle")) { - fmt.Println("out.FuelFigures[0].UsageDescription != 'Urban Cycle':\n", out.FuelFigures[0].UsageDescription) - os.Exit(1) - } - - return true -} - -func ExampleCarToExtension2() bool { - in := makeCar() - min := baseline.NewSbeGoMarshaller() - mout := extension2.NewSbeGoMarshaller() - - var buf = new(bytes.Buffer) - if err := in.Encode(min, buf, true); err != nil { - fmt.Println("Encoding Error", err) - os.Exit(1) - } - - var out extension2.Car = *new(extension2.Car) - if err := out.Decode(mout, buf, in.SbeSchemaVersion(), in.SbeBlockLength(), true); err != nil { - fmt.Println("Decoding Error", err) - os.Exit(1) - } - - if in.SerialNumber != out.SerialNumber { - fmt.Println("in.SerialNumber != out.SerialNumber:\n", in.SerialNumber, out.SerialNumber) - os.Exit(1) - } - if in.ModelYear != out.ModelYear { - fmt.Println("in.ModelYear != out.ModelYear:\n", in.ModelYear, out.ModelYear) - os.Exit(1) - } - - // Note casts so we can compare - if in.Available != baseline.BooleanTypeEnum(out.Available) { - fmt.Println("in.Available != out.Available:\n", in.Available, out.Available) - os.Exit(1) - } - if in.Code != baseline.ModelEnum(out.Code) { - fmt.Println("in.Code != out.Code:\n", in.Code, out.Code) - os.Exit(1) - } - if in.SomeNumbers != out.SomeNumbers { - fmt.Println("in.SomeNumbers != out.SomeNumbers:\n", in.SomeNumbers, out.SomeNumbers) - os.Exit(1) - } - if in.VehicleCode != out.VehicleCode { - fmt.Println("in.VehicleCode != out.VehicleCode:\n", in.VehicleCode, out.VehicleCode) - os.Exit(1) - } - if in.Extras != baseline.OptionalExtras(out.Extras) { - fmt.Println("in.Extras != out.Extras:\n", in.Extras, out.Extras) - os.Exit(1) - } - - // DiscountedModel is constant - if baseline.Model.C != baseline.ModelEnum(out.DiscountedModel) { - fmt.Println("in.DiscountedModel != out.DiscountedModel:\n", in.DiscountedModel, out.DiscountedModel) - os.Exit(1) - } - - // Engine has two constant values which should come back filled in - if in.Engine.MaxRpm == out.Engine.MaxRpm { - fmt.Println("in.Engine.MaxRpm == out.Engine/MaxRpm (and they should be different):\n", in.Engine.MaxRpm, out.Engine.MaxRpm) - os.Exit(1) - } - - // Engine has constant elements so We should have used our the - // EngineInit() function to fill those in when we created the - // object, and then they will correctly compare - baseline.EngineInit(&in.Engine) - if in.Engine.MaxRpm != out.Engine.MaxRpm { - fmt.Println("in.Engine.MaxRpm != out.Engine.MaxRpm:\n", in.Engine.MaxRpm, out.Engine.MaxRpm) - os.Exit(1) - } - - if !reflect.DeepEqual(in.ActivationCode, out.ActivationCode) { - fmt.Println("in.ActivationCode != out.ActivationCode:\n", in.ActivationCode, out.ActivationCode) - os.Exit(1) - } - - // Extension - // Cupholder is not in example-schema and was introduced in - // extension-schema so it should be NullValue - if out.CupHolderCount != out.CupHolderCountNullValue() { - fmt.Println("out.cupholderCount not successfully nulled:\n", out.CupHolderCount) - os.Exit(1) - } - - // Extension2 - // We added Co2 to FuelFigures before the UsageDescription so - // check Co2 and UsageDescription look right - if !math.IsNaN(float64(out.FuelFigures[0].Co2)) { - fmt.Println("out.FuelFigures[0].Co2 is legit and should be NaN:\n", out.FuelFigures[0].Co2) - os.Exit(1) - } - if !reflect.DeepEqual(out.FuelFigures[0].UsageDescription, []uint8("Urban Cycle")) { - fmt.Println("out.FuelFigures[0].UsageDescription != 'Urban Cycle':\n", out.FuelFigures[0].UsageDescription) - os.Exit(1) - } - - // fmt.Printf("%+v", out) - return true -} - // Helper to make a Car object as per the Java example func makeCar() baseline.Car { return baseline.Car{ @@ -614,7 +432,7 @@ func makeCar() baseline.Car { 2013, baseline.BooleanType.T, baseline.Model.A, - [5]uint32{0, 1, 2, 3, 4}, + [4]uint32{0, 1, 2, 3}, vehicleCode, [8]bool{false, true, true, false, false, false, false, false}, baseline.Model.A, @@ -653,7 +471,7 @@ func makeExtension() extension.Car { 2013, extension.BooleanType.T, extension.Model.A, - [5]uint32{0, 1, 2, 3, 4}, + [4]uint32{0, 1, 2, 3}, vehicleCode, [8]bool{false, true, true, false, false, false, false, false}, extension.Model.A, @@ -665,7 +483,8 @@ func makeExtension() extension.Car { 35, extension.BooleanType.T, extension.EngineBooster{extension.BoostType.NITROUS, 200}}, - 119, // sinceVersion = 1 + [2]int64{119, 120}, // uuid sinceVersion = 1 + 121, // cupHoldercount, sinceVersion = 1 []extension.CarFuelFigures{ extension.CarFuelFigures{30, 35.9, urban}, extension.CarFuelFigures{55, 49.0, combined}, @@ -686,46 +505,6 @@ func makeExtension() extension.Car { activationCode} } -// Helper to make an Extension2 (car with cupholder and c02 info) object -func makeExtension2() extension2.Car { - return extension2.Car{ - 1234, - 2013, - extension2.BooleanType.T, - extension2.Model.A, - [5]uint32{0, 1, 2, 3, 4}, - vehicleCode, - [8]bool{false, true, true, false, false, false, false, false}, - extension2.Model.A, - extension2.Engine{2000, - 4, - 9000, - manufacturerCode, - [6]byte{'P', 'e', 't', 'r', 'o', 'l'}, - 35, - extension2.BooleanType.T, - extension2.EngineBooster{extension2.BoostType.NITROUS, 200}}, - 119, // sinceVersion = 1 - []extension2.CarFuelFigures{ - extension2.CarFuelFigures{30, 35.9, 0.1, urban}, - extension2.CarFuelFigures{55, 49.0, 0.2, combined}, - extension2.CarFuelFigures{75, 40.0, 0.3, highway}}, - []extension2.CarPerformanceFigures{ - extension2.CarPerformanceFigures{95, - []extension2.CarPerformanceFiguresAcceleration{ - extension2.CarPerformanceFiguresAcceleration{30, 4.0}, - extension2.CarPerformanceFiguresAcceleration{60, 7.5}, - extension2.CarPerformanceFiguresAcceleration{100, 12.2}}}, - extension2.CarPerformanceFigures{99, - []extension2.CarPerformanceFiguresAcceleration{ - extension2.CarPerformanceFiguresAcceleration{30, 3.8}, - extension2.CarPerformanceFiguresAcceleration{60, 7.1}, - extension2.CarPerformanceFiguresAcceleration{100, 11.8}}}}, - manufacturer, - model, - activationCode} -} - // MaxInt returns the larger of two ints. func MaxInt(a, b int) int { if a > b { @@ -742,6 +521,6 @@ func MinInt(a, b int) int { return b } -// The byte array is from the java example for interop test made by -// running with -Dsbe.encoding.filename and then decoded using od -tu1 -var data []byte = []byte{49, 0, 1, 0, 1, 0, 0, 0, 210, 4, 0, 0, 0, 0, 0, 0, 221, 7, 1, 65, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 97, 98, 99, 100, 101, 102, 6, 208, 7, 4, 49, 50, 51, 35, 1, 78, 200, 6, 0, 3, 0, 30, 0, 154, 153, 15, 66, 11, 0, 0, 0, 85, 114, 98, 97, 110, 32, 67, 121, 99, 108, 101, 55, 0, 0, 0, 68, 66, 14, 0, 0, 0, 67, 111, 109, 98, 105, 110, 101, 100, 32, 67, 121, 99, 108, 101, 75, 0, 0, 0, 32, 66, 13, 0, 0, 0, 72, 105, 103, 104, 119, 97, 121, 32, 67, 121, 99, 108, 101, 1, 0, 2, 0, 95, 6, 0, 3, 0, 30, 0, 0, 0, 128, 64, 60, 0, 0, 0, 240, 64, 100, 0, 51, 51, 67, 65, 99, 6, 0, 3, 0, 30, 0, 51, 51, 115, 64, 60, 0, 51, 51, 227, 64, 100, 0, 205, 204, 60, 65, 5, 0, 0, 0, 72, 111, 110, 100, 97, 9, 0, 0, 0, 67, 105, 118, 105, 99, 32, 86, 84, 105, 6, 0, 0, 0, 97, 98, 99, 100, 101, 102} +// The byte array can be made at ~rust/car_example/car_example_data.sbe by running gradlew generateCarExampleDataFile +// This can then be decoded using od -tu1 +var data []byte = []byte{45, 0, 1, 0, 1, 0, 0, 0, 210, 4, 0, 0, 0, 0, 0, 0, 221, 7, 1, 65, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 97, 98, 99, 100, 101, 102, 6, 208, 7, 4, 49, 50, 51, 35, 1, 78, 200, 6, 0, 3, 0, 30, 0, 154, 153, 15, 66, 11, 0, 0, 0, 85, 114, 98, 97, 110, 32, 67, 121, 99, 108, 101, 55, 0, 0, 0, 68, 66, 14, 0, 0, 0, 67, 111, 109, 98, 105, 110, 101, 100, 32, 67, 121, 99, 108, 101, 75, 0, 0, 0, 32, 66, 13, 0, 0, 0, 72, 105, 103, 104, 119, 97, 121, 32, 67, 121, 99, 108, 101, 1, 0, 2, 0, 95, 6, 0, 3, 0, 30, 0, 0, 0, 128, 64, 60, 0, 0, 0, 240, 64, 100, 0, 51, 51, 67, 65, 99, 6, 0, 3, 0, 30, 0, 51, 51, 115, 64, 60, 0, 51, 51, 227, 64, 100, 0, 205, 204, 60, 65, 5, 0, 0, 0, 72, 111, 110, 100, 97, 9, 0, 0, 0, 67, 105, 118, 105, 99, 32, 86, 84, 105, 6, 0, 0, 0, 97, 98, 99, 100, 101, 102}