diff options
author | mugisoba <51015092+mugisoba@users.noreply.github.com> | 2020-02-11 10:43:36 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-10 17:43:36 -0800 |
commit | 173e10fdf14884376eb6ed4590142394d69f62c6 (patch) | |
tree | ab138c851c87f04a604edc1a5d63db96853915f7 | |
parent | 8f56990f6cbb2ea260c9da3a2985568d5408d4dd (diff) | |
download | flatbuffers-173e10fdf14884376eb6ed4590142394d69f62c6.tar.gz flatbuffers-173e10fdf14884376eb6ed4590142394d69f62c6.tar.bz2 flatbuffers-173e10fdf14884376eb6ed4590142394d69f62c6.zip |
[C#] support Json Serialization (#5752)
* support json serialization
* fix invalid json format.
* string must be written with double quotes.
* remove commma after the last object member.
* fix indent
* Revert "fix invalid json format."
This reverts commit d6820ed50c8e3d3cda3aa1849b3079f853608619.
* quated string value.
* add cs-gen-json-serializer flag.
* fix preprocessor indent
* ENABLE_JSON_SERIALIZATION -> ENABLE_JSON_SERIALIZATION_TEST
* share TestBuffer method
* remove ENABLE_JSON_SERIALIZATION
* remove duplicated test data
* [windows] add nuget restore and copy test data.
* [docker mono] share msbuild settings with windows. add nuget restore and copy test data.
* add some note for json api.
43 files changed, 680 insertions, 42 deletions
diff --git a/appveyor.yml b/appveyor.yml index ee6930f6..e42feceb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -105,6 +105,11 @@ test_script: # Have to compile this here rather than in "build" above because AppVeyor only # supports building one project?? - "cd FlatBuffers.Test" + - "copy ..\\monsterdata_test.mon Resources\\" + - "copy ..\\monsterdata_test.json Resources\\" + - "dotnet new sln" + - "dotnet sln add FlatBuffers.Test.csproj" + - "nuget restore" - "msbuild.exe /property:Configuration=Release;OutputPath=tempcs /verbosity:minimal FlatBuffers.Test.csproj" - "tempcs\\FlatBuffers.Test.exe" # Run tests with UNSAFE_BYTEBUFFER diff --git a/docs/source/CsharpUsage.md b/docs/source/CsharpUsage.md index 90a757fb..f7f585db 100644 --- a/docs/source/CsharpUsage.md +++ b/docs/source/CsharpUsage.md @@ -151,4 +151,25 @@ To use: fbb.Finish(Monster.Pack(fbb, monsterobj).Value); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +### Json Serialization + +An additional feature of the object API is the ability to allow you to +serialize & deserialize a JSON text. +To use Json Serialization, add `--gen-json-serializer` option to `flatc` and +add `Newtonsoft.Json` nuget package to csproj. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs} + // Deserialize MonsterT from json + string jsonText = File.ReadAllText(@"Resources/monsterdata_test.json"); + MonsterT mon = MonsterT.DeserializeFromJson(jsonText); + + // Serialize MonsterT to json + string jsonText2 = mon.SerializeToJson(); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Limitation + * `hash` attribute currentry not supported. +* NuGet package Dependency + * [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) + <br> diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 2e2d4685..dbdacc8e 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -556,6 +556,7 @@ struct IDLOptions { std::string root_type; bool force_defaults; bool java_primitive_has_method; + bool cs_gen_json_serializer; std::vector<std::string> cpp_includes; std::string cpp_std; std::string proto_namespace_suffix; @@ -592,12 +593,12 @@ struct IDLOptions { // for code generation. unsigned long lang_to_generate; - // If set (default behavior), empty string fields will be set to nullptr to make - // the flatbuffer more compact. + // If set (default behavior), empty string fields will be set to nullptr to + // make the flatbuffer more compact. bool set_empty_strings_to_null; - // If set (default behavior), empty vector fields will be set to nullptr to make - // the flatbuffer more compact. + // If set (default behavior), empty vector fields will be set to nullptr to + // make the flatbuffer more compact. bool set_empty_vectors_to_null; IDLOptions() @@ -641,6 +642,7 @@ struct IDLOptions { size_prefixed(false), force_defaults(false), java_primitive_has_method(false), + cs_gen_json_serializer(false), lang(IDLOptions::kJava), mini_reflect(IDLOptions::kNone), lang_to_generate(0), @@ -1119,9 +1121,8 @@ bool GenerateJavaGRPC(const Parser &parser, const std::string &path, // Generate GRPC Python interfaces. // See idl_gen_grpc.cpp. -bool GeneratePythonGRPC(const Parser &parser, - const std::string &path, - const std::string &file_name); +bool GeneratePythonGRPC(const Parser &parser, const std::string &path, + const std::string &file_name); } // namespace flatbuffers diff --git a/src/flatc.cpp b/src/flatc.cpp index bac3411a..1be81753 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -325,7 +325,7 @@ int FlatCompiler::Compile(int argc, const char **argv) { } else if (arg == "--bfbs-builtins") { opts.binary_schema_builtins = true; } else if (arg == "--bfbs-gen-embed") { - opts.binary_schema_gen_embed= true; + opts.binary_schema_gen_embed = true; } else if (arg == "--no-fb-import") { opts.skip_flatbuffers_import = true; } else if (arg == "--no-ts-reexport") { @@ -348,10 +348,13 @@ int FlatCompiler::Compile(int argc, const char **argv) { opts.set_empty_vectors_to_null = false; } else if (arg == "--java-primitive-has-method") { opts.java_primitive_has_method = true; + } else if (arg == "--cs-gen-json-serializer") { + opts.cs_gen_json_serializer = true; } else if (arg == "--flexbuffers") { opts.use_flexbuffers = true; - } else if(arg == "--cpp-std") { - if (++argi >= argc) Error("missing C++ standard specification" + arg, true); + } else if (arg == "--cpp-std") { + if (++argi >= argc) + Error("missing C++ standard specification" + arg, true); opts.cpp_std = argv[argi]; } else { for (size_t i = 0; i < params_.num_generators; ++i) { diff --git a/src/idl_gen_csharp.cpp b/src/idl_gen_csharp.cpp index a97ae6b0..4bcde6c1 100644 --- a/src/idl_gen_csharp.cpp +++ b/src/idl_gen_csharp.cpp @@ -271,6 +271,11 @@ class CSharpGenerator : public BaseGenerator { // That, and Java Enums are expensive, and not universally liked. GenComment(enum_def.doc_comment, code_ptr, &comment_config); + if (opts.cs_gen_json_serializer && opts.generate_object_based_api) { + code += + "[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters." + "StringEnumConverter))]\n"; + } // In C# this indicates enumeration values can be treated as bit flags. if (enum_def.attributes.Lookup("bit_flags")) { code += "[System.FlagsAttribute]\n"; @@ -1274,6 +1279,89 @@ class CSharpGenerator : public BaseGenerator { code += " }\n"; code += " }\n"; code += "}\n\n"; + // JsonConverter + if (opts.cs_gen_json_serializer) { + if (enum_def.attributes.Lookup("private")) { + code += "internal "; + } else { + code += "public "; + } + code += "class " + union_name + + "_JsonConverter : Newtonsoft.Json.JsonConverter {\n"; + code += " public override bool CanConvert(System.Type objectType) {\n"; + code += " return objectType == typeof(" + union_name + + ") || objectType == typeof(System.Collections.Generic.List<" + + union_name + ">);\n"; + code += " }\n"; + code += + " public override void WriteJson(Newtonsoft.Json.JsonWriter writer, " + "object value, " + "Newtonsoft.Json.JsonSerializer serializer) {\n"; + code += " var _olist = value as System.Collections.Generic.List<" + + union_name + ">;\n"; + code += " if (_olist != null) {\n"; + code += " writer.WriteStartArray();\n"; + code += + " foreach (var _o in _olist) { this.WriteJson(writer, _o, " + "serializer); }\n"; + code += " writer.WriteEndArray();\n"; + code += " } else {\n"; + code += " this.WriteJson(writer, value as " + union_name + + ", serializer);\n"; + code += " }\n"; + code += " }\n"; + code += " public void WriteJson(Newtonsoft.Json.JsonWriter writer, " + + union_name + + " _o, " + "Newtonsoft.Json.JsonSerializer serializer) {\n"; + code += " if (_o == null) return;\n"; + code += " serializer.Serialize(writer, _o.Value);\n"; + code += " }\n"; + code += + " public override object ReadJson(Newtonsoft.Json.JsonReader " + "reader, " + "System.Type objectType, " + "object existingValue, Newtonsoft.Json.JsonSerializer serializer) " + "{\n"; + code += + " var _olist = existingValue as System.Collections.Generic.List<" + + union_name + ">;\n"; + code += " if (_olist != null) {\n"; + code += " for (var _j = 0; _j < _olist.Count; ++_j) {\n"; + code += " reader.Read();\n"; + code += + " _olist[_j] = this.ReadJson(reader, _olist[_j], " + "serializer);\n"; + code += " }\n"; + code += " reader.Read();\n"; + code += " return _olist;\n"; + code += " } else {\n"; + code += " return this.ReadJson(reader, existingValue as " + + union_name + ", serializer);\n"; + code += " }\n"; + code += " }\n"; + code += " public " + union_name + + " ReadJson(Newtonsoft.Json.JsonReader reader, " + union_name + + " _o, Newtonsoft.Json.JsonSerializer serializer) {\n"; + code += " if (_o == null) return null;\n"; + code += " switch (_o.Type) {\n"; + for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); + ++it) { + auto &ev = **it; + if (ev.union_type.base_type == BASE_TYPE_NONE) { + code += " default: break;\n"; + } else { + auto type_name = GenTypeGet_ObjectAPI(ev.union_type, opts); + code += " case " + enum_def.name + "." + ev.name + + ": _o.Value = serializer.Deserialize<" + type_name + + ">(reader); break;\n"; + } + } + code += " }\n"; + code += " return _o;\n"; + code += " }\n"; + code += "}\n\n"; + } } std::string GenTypeName_ObjectAPI(const std::string &name, @@ -1794,8 +1882,62 @@ class CSharpGenerator : public BaseGenerator { if (field.value.type.base_type == BASE_TYPE_UTYPE) continue; if (field.value.type.element == BASE_TYPE_UTYPE) continue; auto type_name = GenTypeGet_ObjectAPI(field.value.type, opts); - code += " public " + type_name + " " + MakeCamel(field.name, true) + - " { get; set; }\n"; + auto camel_name = MakeCamel(field.name, true); + if (opts.cs_gen_json_serializer) { + if (IsUnion(field.value.type)) { + auto utype_name = WrapInNameSpace(*field.value.type.enum_def); + code += + " [Newtonsoft.Json.JsonProperty(\"" + field.name + "_type\")]\n"; + if (field.value.type.base_type == BASE_TYPE_VECTOR) { + code += " private " + utype_name + "[] " + camel_name + "Type {\n"; + code += " get {\n"; + code += " if (this." + camel_name + " == null) return null;\n"; + code += " var _o = new " + utype_name + "[this." + camel_name + + ".Count];\n"; + code += + " for (var _j = 0; _j < _o.Length; ++_j) { _o[_j] = " + "this." + + camel_name + "[_j].Type; }\n"; + code += " return _o;\n"; + code += " }\n"; + code += " set {\n"; + code += " this." + camel_name + " = new List<" + utype_name + + "Union>();\n"; + code += " for (var _j = 0; _j < value.Length; ++_j) {\n"; + code += " var _o = new " + utype_name + "Union();\n"; + code += " _o.Type = value[_j];\n"; + code += " this." + camel_name + ".Add(_o);\n"; + code += " }\n"; + code += " }\n"; + code += " }\n"; + } else { + code += " private " + utype_name + " " + camel_name + "Type {\n"; + code += " get {\n"; + code += " return this." + camel_name + " != null ? this." + + camel_name + ".Type : " + utype_name + ".NONE;\n"; + code += " }\n"; + code += " set {\n"; + code += " this." + camel_name + " = new " + utype_name + + "Union();\n"; + code += " this." + camel_name + ".Type = value;\n"; + code += " }\n"; + code += " }\n"; + } + } + code += " [Newtonsoft.Json.JsonProperty(\"" + field.name + "\")]\n"; + if (IsUnion(field.value.type)) { + auto union_name = + (field.value.type.base_type == BASE_TYPE_VECTOR) + ? GenTypeGet_ObjectAPI(field.value.type.VectorType(), opts) + : type_name; + code += " [Newtonsoft.Json.JsonConverter(typeof(" + union_name + + "_JsonConverter))]\n"; + } + if (field.attributes.Lookup("hash")) { + code += " [Newtonsoft.Json.JsonIgnore()]\n"; + } + } + code += " public " + type_name + " " + camel_name + " { get; set; }\n"; } // Generate Constructor code += "\n"; @@ -1833,6 +1975,21 @@ class CSharpGenerator : public BaseGenerator { } } code += " }\n"; + // Generate Serialization + if (opts.cs_gen_json_serializer && + parser_.root_struct_def_ == &struct_def) { + code += "\n"; + code += " public static " + class_name + + " DeserializeFromJson(string jsonText) {\n"; + code += " return Newtonsoft.Json.JsonConvert.DeserializeObject<" + + class_name + ">(jsonText);\n"; + code += " }\n"; + code += " public string SerializeToJson() {\n"; + code += + " return Newtonsoft.Json.JsonConvert.SerializeObject(this, " + "Newtonsoft.Json.Formatting.Indented);\n"; + code += " }\n"; + } code += "}\n\n"; } diff --git a/tests/FlatBuffers.Test/FlatBuffers.Test.csproj b/tests/FlatBuffers.Test/FlatBuffers.Test.csproj index 3f064b46..c917d2f1 100644 --- a/tests/FlatBuffers.Test/FlatBuffers.Test.csproj +++ b/tests/FlatBuffers.Test/FlatBuffers.Test.csproj @@ -17,7 +17,7 @@ <DebugType>full</DebugType> <Optimize>false</Optimize> <OutputPath>bin\Debug\</OutputPath> - <DefineConstants>DEBUG;TRACE</DefineConstants> + <DefineConstants>TRACE;DEBUG</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> @@ -37,6 +37,9 @@ <DefineConstants>$(DefineConstants);UNSAFE_BYTEBUFFER</DefineConstants> </PropertyGroup> <ItemGroup> + <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> + <HintPath>packages\Newtonsoft.Json.12.0.3\lib\net35\Newtonsoft.Json.dll</HintPath> + </Reference> <Reference Include="System" /> <Reference Include="System.Core"> <RequiredTargetFramework>3.5</RequiredTargetFramework> @@ -169,6 +172,13 @@ <Link>Resources\monsterdata_test.mon</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> + <Content Include="..\monsterdata_test.json"> + <Link>Resources\monsterdata_test.json</Link> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </Content> + </ItemGroup> + <ItemGroup> + <None Include="packages.config" /> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. diff --git a/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs b/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs index abe08572..7bdc5022 100644 --- a/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs +++ b/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs @@ -111,18 +111,18 @@ namespace FlatBuffers.Test } // Dump to output directory so we can inspect later, if needed -#if ENABLE_SPAN_T + #if ENABLE_SPAN_T var data = fbb.DataBuffer.ToSizedArray(); string filename = @"Resources/monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon"; File.WriteAllBytes(filename, data); -#else + #else using (var ms = fbb.DataBuffer.ToMemoryStream(fbb.DataBuffer.Position, fbb.Offset)) { var data = ms.ToArray(); string filename = @"Resources/monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon"; File.WriteAllBytes(filename, data); } -#endif + #endif // Remove the size prefix if necessary for further testing ByteBuffer dataBuffer = fbb.DataBuffer; @@ -245,7 +245,7 @@ namespace FlatBuffers.Test Assert.AreEqual(true, monster.Testbool); -#if ENABLE_SPAN_T + #if ENABLE_SPAN_T var nameBytes = monster.GetNameBytes(); Assert.AreEqual("MyMonster", Encoding.UTF8.GetString(nameBytes.ToArray(), 0, nameBytes.Length)); @@ -263,7 +263,7 @@ namespace FlatBuffers.Test var doubleArrayBytes = monster.GetVectorOfDoublesBytes(); Assert.IsTrue(monster.VectorOfDoublesLength * 8 == doubleArrayBytes.Length); -#else + #else var nameBytes = monster.GetNameBytes().Value; Assert.AreEqual("MyMonster", Encoding.UTF8.GetString(nameBytes.Array, nameBytes.Offset, nameBytes.Count)); @@ -275,7 +275,7 @@ namespace FlatBuffers.Test { Assert.IsTrue(monster.GetTestarrayofboolsBytes().HasValue); } -#endif + #endif } [FlatBuffersTestMethod] @@ -288,6 +288,16 @@ namespace FlatBuffers.Test } [FlatBuffersTestMethod] + public void CanReadJsonFile() + { + var jsonText = File.ReadAllText(@"Resources/monsterdata_test.json"); + var mon = MonsterT.DeserializeFromJson(jsonText); + var fbb = new FlatBufferBuilder(1); + fbb.Finish(Monster.Pack(fbb, mon).Value); + TestBuffer(fbb.DataBuffer); + } + + [FlatBuffersTestMethod] public void TestEnums() { Assert.AreEqual("Red", Color.Red.ToString()); @@ -659,6 +669,10 @@ namespace FlatBuffers.Test fbb.Finish(Monster.Pack(fbb, b).Value); var c = Monster.GetRootAsMonster(fbb.DataBuffer); AreEqual(a, c); + + var jsonText = b.SerializeToJson(); + var d = MonsterT.DeserializeFromJson(jsonText); + AreEqual(a, d); } private void AreEqual(ArrayTable a, ArrayTableT b) @@ -754,6 +768,10 @@ namespace FlatBuffers.Test fbb.Finish(ArrayTable.Pack(fbb, b).Value); var c = ArrayTable.GetRootAsArrayTable(fbb.DataBuffer); AreEqual(a, c); + + var jsonText = b.SerializeToJson(); + var d = ArrayTableT.DeserializeFromJson(jsonText); + AreEqual(a, d); } private void AreEqual(Movie a, MovieT b) @@ -793,6 +811,10 @@ namespace FlatBuffers.Test fbb.Finish(Movie.Pack(fbb, b).Value); var c = Movie.GetRootAsMovie(fbb.DataBuffer); AreEqual(a, c); + + var jsonText = b.SerializeToJson(); + var d = MovieT.DeserializeFromJson(jsonText); + AreEqual(a, d); } } } diff --git a/tests/FlatBuffers.Test/NetTest.sh b/tests/FlatBuffers.Test/NetTest.sh index f03d97fb..10d5cddf 100644 --- a/tests/FlatBuffers.Test/NetTest.sh +++ b/tests/FlatBuffers.Test/NetTest.sh @@ -1,23 +1,41 @@ #!/bin/sh +# Restore nuget packages +mkdir dotnet_tmp +curl -OL https://dot.net/v1/dotnet-install.sh +chmod +x dotnet-install.sh +./dotnet-install.sh --version 3.1.101 --install-dir dotnet_tmp +dotnet_tmp/dotnet new sln +dotnet_tmp/dotnet sln add FlatBuffers.Test.csproj +curl -OL https://dist.nuget.org/win-x86-commandline/v5.4.0/nuget.exe +mono nuget.exe restore + +# Copy Test Files +cp ../monsterdata_test.mon Resources/ +cp ../monsterdata_test.json Resources/ + # Testing C# on Linux using Mono. -mcs -debug -out:./fbnettest.exe \ - ../../net/FlatBuffers/*.cs ../MyGame/Example/*.cs ../MyGame/Example2/*.cs ../MyGame/*.cs ../union_vector/*.cs \ - FlatBuffersTestClassAttribute.cs FlatBuffersTestMethodAttribute.cs Assert.cs FlatBuffersExampleTests.cs Program.cs ByteBufferTests.cs FlatBufferBuilderTests.cs FlatBuffersFuzzTests.cs FuzzTestData.cs Lcg.cs TestTable.cs -mono --debug ./fbnettest.exe -rm fbnettest.exe +msbuild -property:Configuration=Release,OutputPath=tempcs -verbosity:minimal FlatBuffers.Test.csproj +mono tempcs/FlatBuffers.Test.exe +rm -fr tempcs rm Resources/monsterdata_cstest.mon rm Resources/monsterdata_cstest_sp.mon # Repeat with unsafe versions -mcs -debug -out:./fbnettest.exe \ - -unsafe -d:UNSAFE_BYTEBUFFER \ - ../../net/FlatBuffers/*.cs ../MyGame/Example/*.cs ../MyGame/Example2/*.cs ../MyGame/*.cs ../union_vector/*.cs\ - FlatBuffersTestClassAttribute.cs FlatBuffersTestMethodAttribute.cs Assert.cs FlatBuffersExampleTests.cs Program.cs ByteBufferTests.cs FlatBufferBuilderTests.cs FlatBuffersFuzzTests.cs FuzzTestData.cs Lcg.cs TestTable.cs -mono --debug ./fbnettest.exe -rm fbnettest.exe +msbuild -property:Configuration=Release,UnsafeByteBuffer=true,OutputPath=tempcsUnsafe -verbosity:minimal FlatBuffers.Test.csproj +mono tempcsUnsafe/FlatBuffers.Test.exe +rm -fr tempcsUnsafe rm Resources/monsterdata_cstest.mon rm Resources/monsterdata_cstest_sp.mon +# Remove Temp Files +rm -fr dotnet_tmp +rm -fr packages +rm dotnet-install.sh +rm nuget.exe +rm FlatBuffers.Test.sln +rm Resources/monsterdata_test.mon +rm Resources/monsterdata_test.json + diff --git a/tests/FlatBuffers.Test/Resources/.gitkeep b/tests/FlatBuffers.Test/Resources/.gitkeep new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/tests/FlatBuffers.Test/Resources/.gitkeep diff --git a/tests/FlatBuffers.Test/Resources/monsterdata_test.mon b/tests/FlatBuffers.Test/Resources/monsterdata_test.mon Binary files differdeleted file mode 100644 index 3f839723..00000000 --- a/tests/FlatBuffers.Test/Resources/monsterdata_test.mon +++ /dev/null diff --git a/tests/FlatBuffers.Test/packages.config b/tests/FlatBuffers.Test/packages.config new file mode 100644 index 00000000..d766d047 --- /dev/null +++ b/tests/FlatBuffers.Test/packages.config @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="Newtonsoft.Json" version="12.0.3" targetFramework="net35" /> +</packages>
\ No newline at end of file diff --git a/tests/MyGame/Example/Ability.cs b/tests/MyGame/Example/Ability.cs index 1db6a025..bd49ccd9 100644 --- a/tests/MyGame/Example/Ability.cs +++ b/tests/MyGame/Example/Ability.cs @@ -47,7 +47,9 @@ public struct Ability : IFlatbufferObject public class AbilityT { + [Newtonsoft.Json.JsonProperty("id")] public uint Id { get; set; } + [Newtonsoft.Json.JsonProperty("distance")] public uint Distance { get; set; } public AbilityT() { diff --git a/tests/MyGame/Example/Any.cs b/tests/MyGame/Example/Any.cs index a3312094..edf98ef5 100644 --- a/tests/MyGame/Example/Any.cs +++ b/tests/MyGame/Example/Any.cs @@ -5,6 +5,7 @@ namespace MyGame.Example { +[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] public enum Any : byte { NONE = 0, @@ -37,5 +38,48 @@ public class AnyUnion { } } +public class AnyUnion_JsonConverter : Newtonsoft.Json.JsonConverter { + public override bool CanConvert(System.Type objectType) { + return objectType == typeof(AnyUnion) || objectType == typeof(System.Collections.Generic.List<AnyUnion>); + } + public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) { + var _olist = value as System.Collections.Generic.List<AnyUnion>; + if (_olist != null) { + writer.WriteStartArray(); + foreach (var _o in _olist) { this.WriteJson(writer, _o, serializer); } + writer.WriteEndArray(); + } else { + this.WriteJson(writer, value as AnyUnion, serializer); + } + } + public void WriteJson(Newtonsoft.Json.JsonWriter writer, AnyUnion _o, Newtonsoft.Json.JsonSerializer serializer) { + if (_o == null) return; + serializer.Serialize(writer, _o.Value); + } + public override object ReadJson(Newtonsoft.Json.JsonReader reader, System.Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) { + var _olist = existingValue as System.Collections.Generic.List<AnyUnion>; + if (_olist != null) { + for (var _j = 0; _j < _olist.Count; ++_j) { + reader.Read(); + _olist[_j] = this.ReadJson(reader, _olist[_j], serializer); + } + reader.Read(); + return _olist; + } else { + return this.ReadJson(reader, existingValue as AnyUnion, serializer); + } + } + public AnyUnion ReadJson(Newtonsoft.Json.JsonReader reader, AnyUnion _o, Newtonsoft.Json.JsonSerializer serializer) { + if (_o == null) return null; + switch (_o.Type) { + default: break; + case Any.Monster: _o.Value = serializer.Deserialize<MyGame.Example.MonsterT>(reader); break; + case Any.TestSimpleTableWithEnum: _o.Value = serializer.Deserialize<MyGame.Example.TestSimpleTableWithEnumT>(reader); break; + case Any.MyGame_Example2_Monster: _o.Value = serializer.Deserialize<MyGame.Example2.MonsterT>(reader); break; + } + return _o; + } +} + } diff --git a/tests/MyGame/Example/AnyAmbiguousAliases.cs b/tests/MyGame/Example/AnyAmbiguousAliases.cs index 3c24a77d..07deadc2 100644 --- a/tests/MyGame/Example/AnyAmbiguousAliases.cs +++ b/tests/MyGame/Example/AnyAmbiguousAliases.cs @@ -5,6 +5,7 @@ namespace MyGame.Example { +[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] public enum AnyAmbiguousAliases : byte { NONE = 0, @@ -37,5 +38,48 @@ public class AnyAmbiguousAliasesUnion { } } +public class AnyAmbiguousAliasesUnion_JsonConverter : Newtonsoft.Json.JsonConverter { + public override bool CanConvert(System.Type objectType) { + return objectType == typeof(AnyAmbiguousAliasesUnion) || objectType == typeof(System.Collections.Generic.List<AnyAmbiguousAliasesUnion>); + } + public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) { + var _olist = value as System.Collections.Generic.List<AnyAmbiguousAliasesUnion>; + if (_olist != null) { + writer.WriteStartArray(); + foreach (var _o in _olist) { this.WriteJson(writer, _o, serializer); } + writer.WriteEndArray(); + } else { + this.WriteJson(writer, value as AnyAmbiguousAliasesUnion, serializer); + } + } + public void WriteJson(Newtonsoft.Json.JsonWriter writer, AnyAmbiguousAliasesUnion _o, Newtonsoft.Json.JsonSerializer serializer) { + if (_o == null) return; + serializer.Serialize(writer, _o.Value); + } + public override object ReadJson(Newtonsoft.Json.JsonReader reader, System.Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) { + var _olist = existingValue as System.Collections.Generic.List<AnyAmbiguousAliasesUnion>; + if (_olist != null) { + for (var _j = 0; _j < _olist.Count; ++_j) { + reader.Read(); + _olist[_j] = this.ReadJson(reader, _olist[_j], serializer); + } + reader.Read(); + return _olist; + } else { + return this.ReadJson(reader, existingValue as AnyAmbiguousAliasesUnion, serializer); + } + } + public AnyAmbiguousAliasesUnion ReadJson(Newtonsoft.Json.JsonReader reader, AnyAmbiguousAliasesUnion _o, Newtonsoft.Json.JsonSerializer serializer) { + if (_o == null) return null; + switch (_o.Type) { + default: break; + case AnyAmbiguousAliases.M1: _o.Value = serializer.Deserialize<MyGame.Example.MonsterT>(reader); break; + case AnyAmbiguousAliases.M2: _o.Value = serializer.Deserialize<MyGame.Example.MonsterT>(reader); break; + case AnyAmbiguousAliases.M3: _o.Value = serializer.Deserialize<MyGame.Example.MonsterT>(reader); break; + } + return _o; + } +} + } diff --git a/tests/MyGame/Example/AnyUniqueAliases.cs b/tests/MyGame/Example/AnyUniqueAliases.cs index 518e4662..35949528 100644 --- a/tests/MyGame/Example/AnyUniqueAliases.cs +++ b/tests/MyGame/Example/AnyUniqueAliases.cs @@ -5,6 +5,7 @@ namespace MyGame.Example { +[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] public enum AnyUniqueAliases : byte { NONE = 0, @@ -37,5 +38,48 @@ public class AnyUniqueAliasesUnion { } } +public class AnyUniqueAliasesUnion_JsonConverter : Newtonsoft.Json.JsonConverter { + public override bool CanConvert(System.Type objectType) { + return objectType == typeof(AnyUniqueAliasesUnion) || objectType == typeof(System.Collections.Generic.List<AnyUniqueAliasesUnion>); + } + public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) { + var _olist = value as System.Collections.Generic.List<AnyUniqueAliasesUnion>; + if (_olist != null) { + writer.WriteStartArray(); + foreach (var _o in _olist) { this.WriteJson(writer, _o, serializer); } + writer.WriteEndArray(); + } else { + this.WriteJson(writer, value as AnyUniqueAliasesUnion, serializer); + } + } + public void WriteJson(Newtonsoft.Json.JsonWriter writer, AnyUniqueAliasesUnion _o, Newtonsoft.Json.JsonSerializer serializer) { + if (_o == null) return; + serializer.Serialize(writer, _o.Value); + } + public override object ReadJson(Newtonsoft.Json.JsonReader reader, System.Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) { + var _olist = existingValue as System.Collections.Generic.List<AnyUniqueAliasesUnion>; + if (_olist != null) { + for (var _j = 0; _j < _olist.Count; ++_j) { + reader.Read(); + _olist[_j] = this.ReadJson(reader, _olist[_j], serializer); + } + reader.Read(); + return _olist; + } else { + return this.ReadJson(reader, existingValue as AnyUniqueAliasesUnion, serializer); + } + } + public AnyUniqueAliasesUnion ReadJson(Newtonsoft.Json.JsonReader reader, AnyUniqueAliasesUnion _o, Newtonsoft.Json.JsonSerializer serializer) { + if (_o == null) return null; + switch (_o.Type) { + default: break; + case AnyUniqueAliases.M: _o.Value = serializer.Deserialize<MyGame.Example.MonsterT>(reader); break; + case AnyUniqueAliases.TS: _o.Value = serializer.Deserialize<MyGame.Example.TestSimpleTableWithEnumT>(reader); break; + case AnyUniqueAliases.M2: _o.Value = serializer.Deserialize<MyGame.Example2.MonsterT>(reader); break; + } + return _o; + } +} + } diff --git a/tests/MyGame/Example/ArrayStruct.cs b/tests/MyGame/Example/ArrayStruct.cs index 1290d417..41c088db 100644 --- a/tests/MyGame/Example/ArrayStruct.cs +++ b/tests/MyGame/Example/ArrayStruct.cs @@ -101,11 +101,17 @@ public struct ArrayStruct : IFlatbufferObject public class ArrayStructT { + [Newtonsoft.Json.JsonProperty("a")] public float A { get; set; } + [Newtonsoft.Json.JsonProperty("b")] public int[] B { get; set; } + [Newtonsoft.Json.JsonProperty("c")] public sbyte C { get; set; } + [Newtonsoft.Json.JsonProperty("d")] public MyGame.Example.NestedStructT[] D { get; set; } + [Newtonsoft.Json.JsonProperty("e")] public int E { get; set; } + [Newtonsoft.Json.JsonProperty("f")] public long[] F { get; set; } public ArrayStructT() { diff --git a/tests/MyGame/Example/ArrayTable.cs b/tests/MyGame/Example/ArrayTable.cs index 759e5115..faa83c68 100644 --- a/tests/MyGame/Example/ArrayTable.cs +++ b/tests/MyGame/Example/ArrayTable.cs @@ -48,11 +48,19 @@ public struct ArrayTable : IFlatbufferObject public class ArrayTableT { + [Newtonsoft.Json.JsonProperty("a")] public MyGame.Example.ArrayStructT A { get; set; } public ArrayTableT() { this.A = new MyGame.Example.ArrayStructT(); } + + public static ArrayTableT DeserializeFromJson(string jsonText) { + return Newtonsoft.Json.JsonConvert.DeserializeObject<ArrayTableT>(jsonText); + } + public string SerializeToJson() { + return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented); + } } diff --git a/tests/MyGame/Example/Color.cs b/tests/MyGame/Example/Color.cs index 5981cf84..1137a276 100644 --- a/tests/MyGame/Example/Color.cs +++ b/tests/MyGame/Example/Color.cs @@ -6,6 +6,7 @@ namespace MyGame.Example { /// Composite components of Monster color. +[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] [System.FlagsAttribute] public enum Color : byte { diff --git a/tests/MyGame/Example/Monster.cs b/tests/MyGame/Example/Monster.cs index 13bcb82f..43111120 100644 --- a/tests/MyGame/Example/Monster.cs +++ b/tests/MyGame/Example/Monster.cs @@ -593,50 +593,142 @@ public struct Monster : IFlatbufferObject public class MonsterT { + [Newtonsoft.Json.JsonProperty("pos")] public MyGame.Example.Vec3T Pos { get; set; } + [Newtonsoft.Json.JsonProperty("mana")] public short Mana { get; set; } + [Newtonsoft.Json.JsonProperty("hp")] public short Hp { get; set; } + [Newtonsoft.Json.JsonProperty("name")] public string Name { get; set; } + [Newtonsoft.Json.JsonProperty("inventory")] public List<byte> Inventory { get; set; } + [Newtonsoft.Json.JsonProperty("color")] public MyGame.Example.Color Color { get; set; } + [Newtonsoft.Json.JsonProperty("test_type")] + private MyGame.Example.Any TestType { + get { + return this.Test != null ? this.Test.Type : MyGame.Example.Any.NONE; + } + set { + this.Test = new MyGame.Example.AnyUnion(); + this.Test.Type = value; + } + } + [Newtonsoft.Json.JsonProperty("test")] + [Newtonsoft.Json.JsonConverter(typeof(MyGame.Example.AnyUnion_JsonConverter))] public MyGame.Example.AnyUnion Test { get; set; } + [Newtonsoft.Json.JsonProperty("test4")] public List<MyGame.Example.TestT> Test4 { get; set; } + [Newtonsoft.Json.JsonProperty("testarrayofstring")] public List<string> Testarrayofstring { get; set; } + [Newtonsoft.Json.JsonProperty("testarrayoftables")] public List<MyGame.Example.MonsterT> Testarrayoftables { get; set; } + [Newtonsoft.Json.JsonProperty("enemy")] public MyGame.Example.MonsterT Enemy { get; set; } + [Newtonsoft.Json.JsonProperty("testnestedflatbuffer")] public List<byte> Testnestedflatbuffer { get; set; } + [Newtonsoft.Json.JsonProperty("testempty")] public MyGame.Example.StatT Testempty { get; set; } + [Newtonsoft.Json.JsonProperty("testbool")] public bool Testbool { get; set; } + [Newtonsoft.Json.JsonProperty("testhashs32_fnv1")] + [Newtonsoft.Json.JsonIgnore()] public int Testhashs32Fnv1 { get; set; } + [Newtonsoft.Json.JsonProperty("testhashu32_fnv1")] + [Newtonsoft.Json.JsonIgnore()] public uint Testhashu32Fnv1 { get; set; } + [Newtonsoft.Json.JsonProperty("testhashs64_fnv1")] + [Newtonsoft.Json.JsonIgnore()] public long Testhashs64Fnv1 { get; set; } + [Newtonsoft.Json.JsonProperty("testhashu64_fnv1")] + [Newtonsoft.Json.JsonIgnore()] public ulong Testhashu64Fnv1 { get; set; } + [Newtonsoft.Json.JsonProperty("testhashs32_fnv1a")] + [Newtonsoft.Json.JsonIgnore()] public int Testhashs32Fnv1a { get; set; } + [Newtonsoft.Json.JsonProperty("testhashu32_fnv1a")] + [Newtonsoft.Json.JsonIgnore()] public uint Testhashu32Fnv1a { get; set; } + [Newtonsoft.Json.JsonProperty("testhashs64_fnv1a")] + [Newtonsoft.Json.JsonIgnore()] public long Testhashs64Fnv1a { get; set; } + [Newtonsoft.Json.JsonProperty("testhashu64_fnv1a")] + [Newtonsoft.Json.JsonIgnore()] public ulong Testhashu64Fnv1a { get; set; } + [Newtonsoft.Json.JsonProperty("testarrayofbools")] public List<bool> Testarrayofbools { get; set; } + [Newtonsoft.Json.JsonProperty("testf")] public float Testf { get; set; } + [Newtonsoft.Json.JsonProperty("testf2")] public float Testf2 { get; set; } + [Newtonsoft.Json.JsonProperty("testf3")] public float Testf3 { get; set; } + [Newtonsoft.Json.JsonProperty("testarrayofstring2")] public List<string> Testarrayofstring2 { get; set; } + [Newtonsoft.Json.JsonProperty("testarrayofsortedstruct")] public List<MyGame.Example.AbilityT> Testarrayofsortedstruct { get; set; } + [Newtonsoft.Json.JsonProperty("flex")] public List<byte> Flex { get; set; } + [Newtonsoft.Json.JsonProperty("test5")] public List<MyGame.Example.TestT> Test5 { get; set; } + [Newtonsoft.Json.JsonProperty("vector_of_longs")] public List<long> VectorOfLongs { get; set; } + [Newtonsoft.Json.JsonProperty("vector_of_doubles")] public List<double> VectorOfDoubles { get; set; } + [Newtonsoft.Json.JsonProperty("parent_namespace_test")] public MyGame.InParentNamespaceT ParentNamespaceTest { get; set; } + [Newtonsoft.Json.JsonProperty("vector_of_referrables")] public List<MyGame.Example.ReferrableT> VectorOfReferrables { get; set; } + [Newtonsoft.Json.JsonProperty("single_weak_reference")] + [Newtonsoft.Json.JsonIgnore()] public ulong SingleWeakReference { get; set; } + [Newtonsoft.Json.JsonProperty("vector_of_weak_references")] + [Newtonsoft.Json.JsonIgnore()] public List<ulong> VectorOfWeakReferences { get; set; } + [Newtonsoft.Json.JsonProperty("vector_of_strong_referrables")] public List<MyGame.Example.ReferrableT> VectorOfStrongReferrables { get; set; } + [Newtonsoft.Json.JsonProperty("co_owning_reference")] + [Newtonsoft.Json.JsonIgnore()] public ulong CoOwningReference { get; set; } + [Newtonsoft.Json.JsonProperty("vector_of_co_owning_references")] + [Newtonsoft.Json.JsonIgnore()] public List<ulong> VectorOfCoOwningReferences { get; set; } + [Newtonsoft.Json.JsonProperty("non_owning_reference")] + [Newtonsoft.Json.JsonIgnore()] public ulong NonOwningReference { get; set; } + [Newtonsoft.Json.JsonProperty("vector_of_non_owning_references")] + [Newtonsoft.Json.JsonIgnore()] public List<ulong> VectorOfNonOwningReferences { get; set; } + [Newtonsoft.Json.JsonProperty("any_unique_type")] + private MyGame.Example.AnyUniqueAliases AnyUniqueType { + get { + return this.AnyUnique != null ? this.AnyUnique.Type : MyGame.Example.AnyUniqueAliases.NONE; + } + set { + this.AnyUnique = new MyGame.Example.AnyUniqueAliasesUnion(); + this.AnyUnique.Type = value; + } + } + [Newtonsoft.Json.JsonProperty("any_unique")] + [Newtonsoft.Json.JsonConverter(typeof(MyGame.Example.AnyUniqueAliasesUnion_JsonConverter))] public MyGame.Example.AnyUniqueAliasesUnion AnyUnique { get; set; } + [Newtonsoft.Json.JsonProperty("any_ambiguous_type")] + private MyGame.Example.AnyAmbiguousAliases AnyAmbiguousType { + get { + return this.AnyAmbiguous != null ? this.AnyAmbiguous.Type : MyGame.Example.AnyAmbiguousAliases.NONE; + } + set { + this.AnyAmbiguous = new MyGame.Example.AnyAmbiguousAliasesUnion(); + this.AnyAmbiguous.Type = value; + } + } + [Newtonsoft.Json.JsonProperty("any_ambiguous")] + [Newtonsoft.Json.JsonConverter(typeof(MyGame.Example.AnyAmbiguousAliasesUnion_JsonConverter))] public MyGame.Example.AnyAmbiguousAliasesUnion AnyAmbiguous { get; set; } + [Newtonsoft.Json.JsonProperty("vector_of_enums")] public List<MyGame.Example.Color> VectorOfEnums { get; set; } + [Newtonsoft.Json.JsonProperty("signed_enum")] public MyGame.Example.Race SignedEnum { get; set; } public MonsterT() { @@ -686,6 +778,13 @@ public class MonsterT this.VectorOfEnums = null; this.SignedEnum = MyGame.Example.Race.None; } + + public static MonsterT DeserializeFromJson(string jsonText) { + return Newtonsoft.Json.JsonConvert.DeserializeObject<MonsterT>(jsonText); + } + public string SerializeToJson() { + return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented); + } } diff --git a/tests/MyGame/Example/NestedStruct.cs b/tests/MyGame/Example/NestedStruct.cs index 190ffa02..13e34984 100644 --- a/tests/MyGame/Example/NestedStruct.cs +++ b/tests/MyGame/Example/NestedStruct.cs @@ -70,9 +70,13 @@ public struct NestedStruct : IFlatbufferObject public class NestedStructT { + [Newtonsoft.Json.JsonProperty("a")] public int[] A { get; set; } + [Newtonsoft.Json.JsonProperty("b")] public MyGame.Example.TestEnum B { get; set; } + [Newtonsoft.Json.JsonProperty("c")] public MyGame.Example.TestEnum[] C { get; set; } + [Newtonsoft.Json.JsonProperty("d")] public long[] D { get; set; } public NestedStructT() { diff --git a/tests/MyGame/Example/Race.cs b/tests/MyGame/Example/Race.cs index 8fa21782..8a1959a8 100644 --- a/tests/MyGame/Example/Race.cs +++ b/tests/MyGame/Example/Race.cs @@ -5,6 +5,7 @@ namespace MyGame.Example { +[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] public enum Race : sbyte { None = -1, diff --git a/tests/MyGame/Example/Referrable.cs b/tests/MyGame/Example/Referrable.cs index 43382a0e..520af932 100644 --- a/tests/MyGame/Example/Referrable.cs +++ b/tests/MyGame/Example/Referrable.cs @@ -78,6 +78,8 @@ public struct Referrable : IFlatbufferObject public class ReferrableT { + [Newtonsoft.Json.JsonProperty("id")] + [Newtonsoft.Json.JsonIgnore()] public ulong Id { get; set; } public ReferrableT() { diff --git a/tests/MyGame/Example/Stat.cs b/tests/MyGame/Example/Stat.cs index 0c7160d2..9f98d616 100644 --- a/tests/MyGame/Example/Stat.cs +++ b/tests/MyGame/Example/Stat.cs @@ -73,8 +73,11 @@ public struct Stat : IFlatbufferObject public class StatT { + [Newtonsoft.Json.JsonProperty("id")] public string Id { get; set; } + [Newtonsoft.Json.JsonProperty("val")] public long Val { get; set; } + [Newtonsoft.Json.JsonProperty("count")] public ushort Count { get; set; } public StatT() { diff --git a/tests/MyGame/Example/Test.cs b/tests/MyGame/Example/Test.cs index caac6fec..a6419ed2 100644 --- a/tests/MyGame/Example/Test.cs +++ b/tests/MyGame/Example/Test.cs @@ -48,7 +48,9 @@ public struct Test : IFlatbufferObject public class TestT { + [Newtonsoft.Json.JsonProperty("a")] public short A { get; set; } + [Newtonsoft.Json.JsonProperty("b")] public sbyte B { get; set; } public TestT() { diff --git a/tests/MyGame/Example/TestEnum.cs b/tests/MyGame/Example/TestEnum.cs index 22e83b33..6dfd6b54 100644 --- a/tests/MyGame/Example/TestEnum.cs +++ b/tests/MyGame/Example/TestEnum.cs @@ -5,6 +5,7 @@ namespace MyGame.Example { +[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] public enum TestEnum : sbyte { A = 0, diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.cs b/tests/MyGame/Example/TestSimpleTableWithEnum.cs index 98d56d1f..82c86cbe 100644 --- a/tests/MyGame/Example/TestSimpleTableWithEnum.cs +++ b/tests/MyGame/Example/TestSimpleTableWithEnum.cs @@ -53,6 +53,7 @@ internal partial struct TestSimpleTableWithEnum : IFlatbufferObject internal partial class TestSimpleTableWithEnumT { + [Newtonsoft.Json.JsonProperty("color")] public MyGame.Example.Color Color { get; set; } public TestSimpleTableWithEnumT() { diff --git a/tests/MyGame/Example/TypeAliases.cs b/tests/MyGame/Example/TypeAliases.cs index b74b8c91..49876401 100644 --- a/tests/MyGame/Example/TypeAliases.cs +++ b/tests/MyGame/Example/TypeAliases.cs @@ -162,17 +162,29 @@ public struct TypeAliases : IFlatbufferObject public class TypeAliasesT { + [Newtonsoft.Json.JsonProperty("i8")] public sbyte I8 { get; set; } + [Newtonsoft.Json.JsonProperty("u8")] public byte U8 { get; set; } + [Newtonsoft.Json.JsonProperty("i16")] public short I16 { get; set; } + [Newtonsoft.Json.JsonProperty("u16")] public ushort U16 { get; set; } + [Newtonsoft.Json.JsonProperty("i32")] public int I32 { get; set; } + [Newtonsoft.Json.JsonProperty("u32")] public uint U32 { get; set; } + [Newtonsoft.Json.JsonProperty("i64")] public long I64 { get; set; } + [Newtonsoft.Json.JsonProperty("u64")] public ulong U64 { get; set; } + [Newtonsoft.Json.JsonProperty("f32")] public float F32 { get; set; } + [Newtonsoft.Json.JsonProperty("f64")] public double F64 { get; set; } + [Newtonsoft.Json.JsonProperty("v8")] public List<sbyte> V8 { get; set; } + [Newtonsoft.Json.JsonProperty("vf64")] public List<double> Vf64 { get; set; } public TypeAliasesT() { diff --git a/tests/MyGame/Example/Vec3.cs b/tests/MyGame/Example/Vec3.cs index 9c106f52..4a9bf0d1 100644 --- a/tests/MyGame/Example/Vec3.cs +++ b/tests/MyGame/Example/Vec3.cs @@ -73,11 +73,17 @@ public struct Vec3 : IFlatbufferObject public class Vec3T { + [Newtonsoft.Json.JsonProperty("x")] public float X { get; set; } + [Newtonsoft.Json.JsonProperty("y")] public float Y { get; set; } + [Newtonsoft.Json.JsonProperty("z")] public float Z { get; set; } + [Newtonsoft.Json.JsonProperty("test1")] public double Test1 { get; set; } + [Newtonsoft.Json.JsonProperty("test2")] public MyGame.Example.Color Test2 { get; set; } + [Newtonsoft.Json.JsonProperty("test3")] public MyGame.Example.TestT Test3 { get; set; } public Vec3T() { diff --git a/tests/MyGame/MonsterExtra.cs b/tests/MyGame/MonsterExtra.cs index b85426d9..7005736a 100644 --- a/tests/MyGame/MonsterExtra.cs +++ b/tests/MyGame/MonsterExtra.cs @@ -151,15 +151,25 @@ public struct MonsterExtra : IFlatbufferObject public class MonsterExtraT { + [Newtonsoft.Json.JsonProperty("d0")] public double D0 { get; set; } + [Newtonsoft.Json.JsonProperty("d1")] public double D1 { get; set; } + [Newtonsoft.Json.JsonProperty("d2")] public double D2 { get; set; } + [Newtonsoft.Json.JsonProperty("d3")] public double D3 { get; set; } + [Newtonsoft.Json.JsonProperty("f0")] public float F0 { get; set; } + [Newtonsoft.Json.JsonProperty("f1")] public float F1 { get; set; } + [Newtonsoft.Json.JsonProperty("f2")] public float F2 { get; set; } + [Newtonsoft.Json.JsonProperty("f3")] public float F3 { get; set; } + [Newtonsoft.Json.JsonProperty("dvec")] public List<double> Dvec { get; set; } + [Newtonsoft.Json.JsonProperty("fvec")] public List<float> Fvec { get; set; } public MonsterExtraT() { @@ -174,6 +184,13 @@ public class MonsterExtraT this.Dvec = null; this.Fvec = null; } + + public static MonsterExtraT DeserializeFromJson(string jsonText) { + return Newtonsoft.Json.JsonConvert.DeserializeObject<MonsterExtraT>(jsonText); + } + public string SerializeToJson() { + return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented); + } } diff --git a/tests/generate_code.bat b/tests/generate_code.bat index 7980f046..d8d18ce7 100644 --- a/tests/generate_code.bat +++ b/tests/generate_code.bat @@ -28,31 +28,32 @@ if NOT "%commandline%"=="%commandline:--cpp-std c++0x=%" ( ) set TEST_CPP_FLAGS=--gen-compare --cpp-ptr-type flatbuffers::unique_ptr %TEST_CPP_FLAGS% +set TEST_CS_FLAGS=--cs-gen-json-serializer set TEST_BASE_FLAGS=--reflect-names --gen-mutable --gen-object-api set TEST_NOINCL_FLAGS=%TEST_BASE_FLAGS% --no-includes --no-fb-import ..\%buildtype%\flatc.exe --binary --cpp --java --kotlin --csharp --dart --go --lobster --lua --js --ts --php --rust --grpc ^ -%TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% -I include_test monster_test.fbs monsterdata_test.json || goto FAIL +%TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% %TEST_CS_FLAGS% -I include_test monster_test.fbs monsterdata_test.json || goto FAIL ..\%buildtype%\flatc.exe --python %TEST_BASE_FLAGS% --no-fb-import -I include_test monster_test.fbs monsterdata_test.json || goto FAIL ..\%buildtype%\flatc.exe --binary --cpp --java --csharp --dart --go --lobster --lua --js --ts --php --python --rust ^ -%TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs || goto FAIL +%TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% %TEST_CS_FLAGS% -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs || goto FAIL -..\%buildtype%\flatc.exe --cpp --java --csharp --js --ts --php %TEST_BASE_FLAGS% %TEST_CPP_FLAGS% -o union_vector ./union_vector/union_vector.fbs || goto FAIL +..\%buildtype%\flatc.exe --cpp --java --csharp --js --ts --php %TEST_BASE_FLAGS% %TEST_CPP_FLAGS% %TEST_CS_FLAGS% -o union_vector ./union_vector/union_vector.fbs || goto FAIL ..\%buildtype%\flatc.exe --rust -I include_test -o include_test include_test/include_test1.fbs || goto FAIL ..\%buildtype%\flatc.exe --rust -I include_test -o include_test/sub include_test/sub/include_test2.fbs || goto FAIL ..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins -I include_test monster_test.fbs || goto FAIL ..\%buildtype%\flatc.exe --cpp --bfbs-comments --bfbs-builtins --bfbs-gen-embed %TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% -I include_test monster_test.fbs || goto FAIL ..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs || goto FAIL ..\%buildtype%\flatc.exe --jsonschema --schema -I include_test monster_test.fbs || goto FAIL -..\%buildtype%\flatc.exe --cpp --java --csharp --jsonschema %TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% --scoped-enums arrays_test.fbs || goto FAIL +..\%buildtype%\flatc.exe --cpp --java --csharp --jsonschema %TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% %TEST_CS_FLAGS% --scoped-enums arrays_test.fbs || goto FAIL ..\%buildtype%\flatc.exe --python %TEST_BASE_FLAGS% arrays_test.fbs || goto FAIL ..\%buildtype%\flatc.exe --cpp %TEST_BASE_FLAGS% --cpp-ptr-type flatbuffers::unique_ptr native_type_test.fbs || goto FAIL if NOT "%MONSTER_EXTRA%"=="skip" ( @echo Generate MosterExtra - ..\%buildtype%\flatc.exe --cpp --java --csharp %TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% monster_extra.fbs monsterdata_extra.json || goto FAIL + ..\%buildtype%\flatc.exe --cpp --java --csharp %TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% %TEST_CS_FLAGS% monster_extra.fbs monsterdata_extra.json || goto FAIL ..\%buildtype%\flatc.exe --python %TEST_BASE_FLAGS% monster_extra.fbs monsterdata_extra.json || goto FAIL ) else ( @echo monster_extra.fbs skipped (the strtod function from MSVC2013 or older doesn't support NaN/Inf arguments) diff --git a/tests/generate_code.sh b/tests/generate_code.sh index 04c4e62f..bce52746 100755 --- a/tests/generate_code.sh +++ b/tests/generate_code.sh @@ -25,26 +25,27 @@ else fi TEST_CPP_FLAGS="--gen-compare --cpp-ptr-type flatbuffers::unique_ptr $TEST_CPP_FLAGS" +TEST_CS_FLAGS="--cs-gen-json-serializer" TEST_BASE_FLAGS="--reflect-names --gen-mutable --gen-object-api" TEST_NOINCL_FLAGS="$TEST_BASE_FLAGS --no-includes --no-fb-import" ../flatc --binary --cpp --java --kotlin --csharp --dart --go --lobster --lua --js --ts --php --rust --grpc \ -$TEST_NOINCL_FLAGS $TEST_CPP_FLAGS -I include_test monster_test.fbs monsterdata_test.json +$TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS -I include_test monster_test.fbs monsterdata_test.json ../flatc --python $TEST_BASE_FLAGS -I include_test monster_test.fbs monsterdata_test.json ../flatc --cpp --java --kotlin --csharp --dart --go --binary --lobster --lua --js --ts --php --python --rust \ -$TEST_NOINCL_FLAGS $TEST_CPP_FLAGS -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs +$TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs -../flatc --cpp --java --kotlin --csharp --js --ts --php $TEST_BASE_FLAGS $TEST_CPP_FLAGS -o union_vector ./union_vector/union_vector.fbs +../flatc --cpp --java --kotlin --csharp --js --ts --php $TEST_BASE_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS -o union_vector ./union_vector/union_vector.fbs ../flatc --rust -I include_test -o include_test include_test/include_test1.fbs ../flatc --rust -I include_test -o include_test/sub include_test/sub/include_test2.fbs ../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test monster_test.fbs ../flatc --cpp --bfbs-comments --bfbs-builtins --bfbs-gen-embed $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS -I include_test monster_test.fbs ../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs ../flatc --jsonschema --schema -I include_test monster_test.fbs -../flatc --cpp --java --kotlin --csharp --python $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS monster_extra.fbs monsterdata_extra.json -../flatc --cpp --java --csharp --jsonschema $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS --scoped-enums arrays_test.fbs +../flatc --cpp --java --kotlin --csharp --python $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS monster_extra.fbs monsterdata_extra.json +../flatc --cpp --java --csharp --jsonschema $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS --scoped-enums arrays_test.fbs ../flatc --python $TEST_BASE_FLAGS arrays_test.fbs ../flatc --dart monster_extra.fbs diff --git a/tests/monsterdata_test.json b/tests/monsterdata_test.json index d3028b55..eb400801 100644 --- a/tests/monsterdata_test.json +++ b/tests/monsterdata_test.json @@ -4,7 +4,7 @@ y: "2", z: 3, test1: 3, - test2: Green, + test2: "Green", test3: { a: 5, b: 6 @@ -31,7 +31,7 @@ 0, 1.7976931348623157e+308 ], - test_type: Monster, + test_type: "Monster", test: { name: "Fred", pos: null diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs index ff44023f..bb17d7b3 100644 --- a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs +++ b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs @@ -5,6 +5,7 @@ namespace NamespaceA.NamespaceB { +[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] public enum EnumInNestedNS : sbyte { A = 0, diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs index 9f6d8dc7..6fa9dd3c 100644 --- a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs +++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs @@ -47,7 +47,9 @@ public struct StructInNestedNS : IFlatbufferObject public class StructInNestedNST { + [Newtonsoft.Json.JsonProperty("a")] public int A { get; set; } + [Newtonsoft.Json.JsonProperty("b")] public int B { get; set; } public StructInNestedNST() { diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs index 88d03425..da0e6b7a 100644 --- a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs +++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs @@ -53,6 +53,7 @@ public struct TableInNestedNS : IFlatbufferObject public class TableInNestedNST { + [Newtonsoft.Json.JsonProperty("foo")] public int Foo { get; set; } public TableInNestedNST() { diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.cs b/tests/namespace_test/NamespaceA/SecondTableInA.cs index 57d7741d..9c381344 100644 --- a/tests/namespace_test/NamespaceA/SecondTableInA.cs +++ b/tests/namespace_test/NamespaceA/SecondTableInA.cs @@ -53,6 +53,7 @@ public struct SecondTableInA : IFlatbufferObject public class SecondTableInAT { + [Newtonsoft.Json.JsonProperty("refer_to_c")] public NamespaceC.TableInCT ReferToC { get; set; } public SecondTableInAT() { diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.cs b/tests/namespace_test/NamespaceA/TableInFirstNS.cs index 759e53e6..84842410 100644 --- a/tests/namespace_test/NamespaceA/TableInFirstNS.cs +++ b/tests/namespace_test/NamespaceA/TableInFirstNS.cs @@ -55,8 +55,11 @@ public struct TableInFirstNS : IFlatbufferObject public class TableInFirstNST { + [Newtonsoft.Json.JsonProperty("foo_table")] public NamespaceA.NamespaceB.TableInNestedNST FooTable { get; set; } + [Newtonsoft.Json.JsonProperty("foo_enum")] public NamespaceA.NamespaceB.EnumInNestedNS FooEnum { get; set; } + [Newtonsoft.Json.JsonProperty("foo_struct")] public NamespaceA.NamespaceB.StructInNestedNST FooStruct { get; set; } public TableInFirstNST() { diff --git a/tests/namespace_test/NamespaceC/TableInC.cs b/tests/namespace_test/NamespaceC/TableInC.cs index 358ca59c..040a9162 100644 --- a/tests/namespace_test/NamespaceC/TableInC.cs +++ b/tests/namespace_test/NamespaceC/TableInC.cs @@ -60,7 +60,9 @@ public struct TableInC : IFlatbufferObject public class TableInCT { + [Newtonsoft.Json.JsonProperty("refer_to_a1")] public NamespaceA.TableInFirstNST ReferToA1 { get; set; } + [Newtonsoft.Json.JsonProperty("refer_to_a2")] public NamespaceA.SecondTableInAT ReferToA2 { get; set; } public TableInCT() { diff --git a/tests/union_vector/Attacker.cs b/tests/union_vector/Attacker.cs index d36555d3..cebc0c72 100644 --- a/tests/union_vector/Attacker.cs +++ b/tests/union_vector/Attacker.cs @@ -50,6 +50,7 @@ public struct Attacker : IFlatbufferObject public class AttackerT { + [Newtonsoft.Json.JsonProperty("sword_attack_damage")] public int SwordAttackDamage { get; set; } public AttackerT() { diff --git a/tests/union_vector/BookReader.cs b/tests/union_vector/BookReader.cs index c40c0df4..3f80cdf5 100644 --- a/tests/union_vector/BookReader.cs +++ b/tests/union_vector/BookReader.cs @@ -39,6 +39,7 @@ public struct BookReader : IFlatbufferObject public class BookReaderT { + [Newtonsoft.Json.JsonProperty("books_read")] public int BooksRead { get; set; } public BookReaderT() { diff --git a/tests/union_vector/Character.cs b/tests/union_vector/Character.cs index cb16e6f8..d067e222 100644 --- a/tests/union_vector/Character.cs +++ b/tests/union_vector/Character.cs @@ -2,6 +2,7 @@ // automatically generated by the FlatBuffers compiler, do not modify // </auto-generated> +[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] public enum Character : byte { NONE = 0, @@ -43,3 +44,49 @@ public class CharacterUnion { } } +public class CharacterUnion_JsonConverter : Newtonsoft.Json.JsonConverter { + public override bool CanConvert(System.Type objectType) { + return objectType == typeof(CharacterUnion) || objectType == typeof(System.Collections.Generic.List<CharacterUnion>); + } + public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) { + var _olist = value as System.Collections.Generic.List<CharacterUnion>; + if (_olist != null) { + writer.WriteStartArray(); + foreach (var _o in _olist) { this.WriteJson(writer, _o, serializer); } + writer.WriteEndArray(); + } else { + this.WriteJson(writer, value as CharacterUnion, serializer); + } + } + public void WriteJson(Newtonsoft.Json.JsonWriter writer, CharacterUnion _o, Newtonsoft.Json.JsonSerializer serializer) { + if (_o == null) return; + serializer.Serialize(writer, _o.Value); + } + public override object ReadJson(Newtonsoft.Json.JsonReader reader, System.Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) { + var _olist = existingValue as System.Collections.Generic.List<CharacterUnion>; + if (_olist != null) { + for (var _j = 0; _j < _olist.Count; ++_j) { + reader.Read(); + _olist[_j] = this.ReadJson(reader, _olist[_j], serializer); + } + reader.Read(); + return _olist; + } else { + return this.ReadJson(reader, existingValue as CharacterUnion, serializer); + } + } + public CharacterUnion ReadJson(Newtonsoft.Json.JsonReader reader, CharacterUnion _o, Newtonsoft.Json.JsonSerializer serializer) { + if (_o == null) return null; + switch (_o.Type) { + default: break; + case Character.MuLan: _o.Value = serializer.Deserialize<AttackerT>(reader); break; + case Character.Rapunzel: _o.Value = serializer.Deserialize<RapunzelT>(reader); break; + case Character.Belle: _o.Value = serializer.Deserialize<BookReaderT>(reader); break; + case Character.BookFan: _o.Value = serializer.Deserialize<BookReaderT>(reader); break; + case Character.Other: _o.Value = serializer.Deserialize<string>(reader); break; + case Character.Unused: _o.Value = serializer.Deserialize<string>(reader); break; + } + return _o; + } +} + diff --git a/tests/union_vector/Movie.cs b/tests/union_vector/Movie.cs index 7fc10388..a19bb25f 100644 --- a/tests/union_vector/Movie.cs +++ b/tests/union_vector/Movie.cs @@ -146,12 +146,50 @@ public struct Movie : IFlatbufferObject public class MovieT { + [Newtonsoft.Json.JsonProperty("main_character_type")] + private Character MainCharacterType { + get { + return this.MainCharacter != null ? this.MainCharacter.Type : Character.NONE; + } + set { + this.MainCharacter = new CharacterUnion(); + this.MainCharacter.Type = value; + } + } + [Newtonsoft.Json.JsonProperty("main_character")] + [Newtonsoft.Json.JsonConverter(typeof(CharacterUnion_JsonConverter))] public CharacterUnion MainCharacter { get; set; } + [Newtonsoft.Json.JsonProperty("characters_type")] + private Character[] CharactersType { + get { + if (this.Characters == null) return null; + var _o = new Character[this.Characters.Count]; + for (var _j = 0; _j < _o.Length; ++_j) { _o[_j] = this.Characters[_j].Type; } + return _o; + } + set { + this.Characters = new List<CharacterUnion>(); + for (var _j = 0; _j < value.Length; ++_j) { + var _o = new CharacterUnion(); + _o.Type = value[_j]; + this.Characters.Add(_o); + } + } + } + [Newtonsoft.Json.JsonProperty("characters")] + [Newtonsoft.Json.JsonConverter(typeof(CharacterUnion_JsonConverter))] public List<CharacterUnion> Characters { get; set; } public MovieT() { this.MainCharacter = null; this.Characters = null; } + + public static MovieT DeserializeFromJson(string jsonText) { + return Newtonsoft.Json.JsonConvert.DeserializeObject<MovieT>(jsonText); + } + public string SerializeToJson() { + return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented); + } } diff --git a/tests/union_vector/Rapunzel.cs b/tests/union_vector/Rapunzel.cs index 3cb6f196..e5ffff8e 100644 --- a/tests/union_vector/Rapunzel.cs +++ b/tests/union_vector/Rapunzel.cs @@ -39,6 +39,7 @@ public struct Rapunzel : IFlatbufferObject public class RapunzelT { + [Newtonsoft.Json.JsonProperty("hair_length")] public int HairLength { get; set; } public RapunzelT() { |