From 16b88f60c669730b11cd3728b863ee99b3aec674 Mon Sep 17 00:00:00 2001 From: Sylwester Lachiewicz Date: Sat, 14 Nov 2026 12:17:55 +0100 Subject: [PATCH] [Go] Escape single char fields in generated flyweight String output. A single char field is written as a JSON string with quote and backslash escaped and control characters as \u00XX, as the C++ display now does. Do not go back to formatting the byte with %c. --- .gitignore | 2 +- .../src/otf/flyweight_single_char_test.go | 47 +++++++++++++++++++ .../flyweight/GolangFlyweightGenerator.java | 13 ++++- .../flyweight-single-char-schema.xml | 27 +++++++++++ 4 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 gocode/flyweight/src/otf/flyweight_single_char_test.go create mode 100644 sbe-tool/src/test/resources/flyweight-single-char-schema.xml diff --git a/.gitignore b/.gitignore index 02c31be8a8..8fd57d676e 100644 --- a/.gitignore +++ b/.gitignore @@ -79,7 +79,7 @@ gocode/flyweight/src/*/*.go !gocode/flyweight/src/*/*_test.go gocode/flyweight/src/*/*/*.go !gocode/flyweight/src/*/*/*_test.go -gocode/flyweight/src/otf/code-generation-schema.sbeir +gocode/flyweight/src/otf/*.sbeir # csharp csharp/*/bin diff --git a/gocode/flyweight/src/otf/flyweight_single_char_test.go b/gocode/flyweight/src/otf/flyweight_single_char_test.go new file mode 100644 index 0000000000..60996a4ebf --- /dev/null +++ b/gocode/flyweight/src/otf/flyweight_single_char_test.go @@ -0,0 +1,47 @@ +package otf + +import ( + stdjson "encoding/json" + "github.com/real-logic/simple-binary-encoding/otf/test/flyweight_single_char" + "github.com/stretchr/testify/assert" + "testing" +) + +//go:generate java --add-opens java.base/jdk.internal.misc=ALL-UNNAMED -Dsbe.output.dir=. -Dsbe.target.language=golang -Dsbe.go.generate.generate.flyweights=true -Dsbe.generate.ir=true -Dsbe.keyword.append.token=X -jar ../../../${SBE_JAR} ../../../../sbe-tool/src/test/resources/flyweight-single-char-schema.xml + +func TestSingleCharFieldsRenderAsValidJson(t *testing.T) { + cases := []struct { + name string + value byte + expected string + }{ + {"letter", 'A', "A"}, + {"quote", '"', "\""}, + {"backslash", '\\', "\\"}, + {"newline", '\n', "\n"}, + {"control", 0x01, "\x01"}, + {"high", 0xe9, "é"}, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + buffer := make([]byte, 64) + var letter flyweight_single_char.Letter + letter.WrapAndApplyHeader(buffer, 0, uint64(len(buffer))).SetCode(c.value) + letter.EntriesCount(1).Next().SetSide(c.value) + + var decoder flyweight_single_char.Letter + decoder.WrapForDecode(buffer, 8, uint64(letter.SbeBlockLength()), 0, uint64(len(buffer))) + + var decoded struct { + Code string + Entries []struct{ Side string } + } + if err := stdjson.Unmarshal([]byte(decoder.String()), &decoded); err != nil { + t.Fatalf("invalid JSON: %v\n%s", err, decoder.String()) + } + assert.Equal(t, c.expected, decoded.Code) + assert.Equal(t, c.expected, decoded.Entries[0].Side) + }) + } +} diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/golang/flyweight/GolangFlyweightGenerator.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/golang/flyweight/GolangFlyweightGenerator.java index 8fa84c80c6..2116a39963 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/golang/flyweight/GolangFlyweightGenerator.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/golang/flyweight/GolangFlyweightGenerator.java @@ -2947,8 +2947,17 @@ private void writeTokenDisplay( if (typeToken.encoding().primitiveType() == PrimitiveType.CHAR) { - sb.append(indent).append("builder.WriteString(fmt.Sprintf(`\"%c\"`, ").append(fieldName) - .append("()))\n"); + sb.append( + indent + "builder.WriteString(`\"`)\n" + + indent + "switch c := " + fieldName + "(); {\n" + + indent + "case c == '\"' || c == '\\\\':\n" + + indent + "\tbuilder.WriteString(\"\\\\\" + string(rune(c)))\n" + + indent + "case c < 0x20:\n" + + indent + "\tbuilder.WriteString(fmt.Sprintf(\"\\\\u%04x\", c))\n" + + indent + "default:\n" + + indent + "\tbuilder.WriteString(string(rune(c)))\n" + + indent + "}\n" + + indent + "builder.WriteString(`\"`)\n"); } else { diff --git a/sbe-tool/src/test/resources/flyweight-single-char-schema.xml b/sbe-tool/src/test/resources/flyweight-single-char-schema.xml new file mode 100644 index 0000000000..20a991fedb --- /dev/null +++ b/sbe-tool/src/test/resources/flyweight-single-char-schema.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + +