diff --git a/.gitignore b/.gitignore index a51ef478d..e07fbae9a 100755 --- a/.gitignore +++ b/.gitignore @@ -57,9 +57,10 @@ build/Xcode/FlatBuffers.xcodeproj/xcuserdata/** FlatBuffers.xcodeproj/ java/.idea java/*.iml -java/target -**/*.pyc .idea +*.iml +target +**/*.pyc build/VS2010/FlatBuffers.sdf build/VS2010/FlatBuffers.opensdf build/VS2010/ipch/**/*.ipch diff --git a/build_ide/VS2010/flatc.vcxproj b/build_ide/VS2010/flatc.vcxproj index 31cd01345..5aef2384a 100755 --- a/build_ide/VS2010/flatc.vcxproj +++ b/build_ide/VS2010/flatc.vcxproj @@ -81,7 +81,7 @@ - ../../include;%(AdditionalIncludeDirectories) + ../../include;../../grpc;%(AdditionalIncludeDirectories) EnableFastChecks CompileAsCpp ProgramDatabase @@ -127,7 +127,7 @@ - ../../include;%(AdditionalIncludeDirectories) + ../../include;../../grpc;%(AdditionalIncludeDirectories) EnableFastChecks CompileAsCpp ProgramDatabase @@ -173,7 +173,7 @@ - ../../include;%(AdditionalIncludeDirectories) + ../../include;../../grpc;%(AdditionalIncludeDirectories) CompileAsCpp Sync AnySuitable @@ -219,7 +219,7 @@ - ../../include;%(AdditionalIncludeDirectories) + ../../include;../../grpc;%(AdditionalIncludeDirectories) CompileAsCpp Sync AnySuitable @@ -263,6 +263,8 @@ + + diff --git a/build_ide/Xcode/FlatBuffers.xcodeproj/project.pbxproj b/build_ide/Xcode/FlatBuffers.xcodeproj/project.pbxproj index ee18e9e29..e67f73565 100644 --- a/build_ide/Xcode/FlatBuffers.xcodeproj/project.pbxproj +++ b/build_ide/Xcode/FlatBuffers.xcodeproj/project.pbxproj @@ -11,10 +11,12 @@ 5AC48C391ACA9A0A008132C5 /* idl_gen_general.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CD8717A19CB937D0012A827 /* idl_gen_general.cpp */; }; 61823BBC53544106B6DBC38E /* idl_parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3709AC883348409592530AE6 /* idl_parser.cpp */; settings = {COMPILER_FLAGS = ""; }; }; 61FF3C34FBEC4819A1C30F92 /* sample_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ECCEBFFA6977404F858F9739 /* sample_text.cpp */; settings = {COMPILER_FLAGS = ""; }; }; - 8C2AAE0A1CB338A8000CC78D /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2AAE091CB338A8000CC78D /* util.cpp */; settings = {ASSET_TAGS = (); }; }; - 8C2AAE0B1CB338CD000CC78D /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2AAE091CB338A8000CC78D /* util.cpp */; settings = {ASSET_TAGS = (); }; }; - 8C2AAE0C1CB338CE000CC78D /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2AAE091CB338A8000CC78D /* util.cpp */; settings = {ASSET_TAGS = (); }; }; + 8C2AAE0A1CB338A8000CC78D /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2AAE091CB338A8000CC78D /* util.cpp */; }; + 8C2AAE0B1CB338CD000CC78D /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2AAE091CB338A8000CC78D /* util.cpp */; }; + 8C2AAE0C1CB338CE000CC78D /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2AAE091CB338A8000CC78D /* util.cpp */; }; 8C303C591975D6A700D7C1C5 /* idl_gen_go.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C303C581975D6A700D7C1C5 /* idl_gen_go.cpp */; }; + 8C547D661D3FF05C00AE7A25 /* idl_gen_grpc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C547D651D3FF05C00AE7A25 /* idl_gen_grpc.cpp */; }; + 8C547D681D3FF07D00AE7A25 /* cpp_generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8C547D671D3FF07D00AE7A25 /* cpp_generator.cc */; }; 8C6905FD19F835B400CB8866 /* idl_gen_fbs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C6905EC19F8357300CB8866 /* idl_gen_fbs.cpp */; }; 8C78573E1BD5AE2C00C53C34 /* idl_gen_js.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C78573D1BD5AE2C00C53C34 /* idl_gen_js.cpp */; }; 8C8774631B703D4800E693F5 /* reflection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C8774621B703D4800E693F5 /* reflection.cpp */; }; @@ -43,6 +45,8 @@ 6AD24EEB3D024825A37741FF /* test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = test.cpp; path = tests/test.cpp; sourceTree = SOURCE_ROOT; }; 8C2AAE091CB338A8000CC78D /* util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = util.cpp; path = src/util.cpp; sourceTree = ""; }; 8C303C581975D6A700D7C1C5 /* idl_gen_go.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = idl_gen_go.cpp; path = src/idl_gen_go.cpp; sourceTree = ""; }; + 8C547D651D3FF05C00AE7A25 /* idl_gen_grpc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = idl_gen_grpc.cpp; path = src/idl_gen_grpc.cpp; sourceTree = ""; }; + 8C547D671D3FF07D00AE7A25 /* cpp_generator.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpp_generator.cc; path = grpc/src/compiler/cpp_generator.cc; sourceTree = ""; }; 8C6905EC19F8357300CB8866 /* idl_gen_fbs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = idl_gen_fbs.cpp; path = src/idl_gen_fbs.cpp; sourceTree = ""; }; 8C78573D1BD5AE2C00C53C34 /* idl_gen_js.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = idl_gen_js.cpp; path = src/idl_gen_js.cpp; sourceTree = ""; }; 8C8774621B703D4800E693F5 /* reflection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = reflection.cpp; path = src/reflection.cpp; sourceTree = ""; }; @@ -62,6 +66,8 @@ 28237E300FE042DEADA302D3 /* Source Files */ = { isa = PBXGroup; children = ( + 8C547D671D3FF07D00AE7A25 /* cpp_generator.cc */, + 8C547D651D3FF05C00AE7A25 /* idl_gen_grpc.cpp */, 8C2AAE091CB338A8000CC78D /* util.cpp */, D2DA271C1BFFBC06000F9168 /* idl_gen_php.cpp */, 8C78573D1BD5AE2C00C53C34 /* idl_gen_js.cpp */, @@ -267,12 +273,14 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 8C547D681D3FF07D00AE7A25 /* cpp_generator.cc in Sources */, 8C303C591975D6A700D7C1C5 /* idl_gen_go.cpp in Sources */, AA9BACF55EB3456BA2F633BB /* flatc.cpp in Sources */, BE03D7B0C9584DD58B50ED34 /* idl_gen_cpp.cpp in Sources */, AD71FEBEE4E846529002C1F0 /* idl_gen_text.cpp in Sources */, 8C2AAE0A1CB338A8000CC78D /* util.cpp in Sources */, 8C8774641B703E1200E693F5 /* idl_gen_fbs.cpp in Sources */, + 8C547D661D3FF05C00AE7A25 /* idl_gen_grpc.cpp in Sources */, A9C9A99F719A4ED58DC2D2FC /* idl_parser.cpp in Sources */, 8CA854B31B04244A00040A06 /* idl_gen_python.cpp in Sources */, 8CD8717B19CB937D0012A827 /* idl_gen_general.cpp in Sources */, @@ -715,7 +723,10 @@ GCC_OPTIMIZATION_LEVEL = 3; GCC_PREPROCESSOR_DEFINITIONS = "'CMAKE_INTDIR=\"$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\"'"; GCC_SYMBOLS_PRIVATE_EXTERN = NO; - HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/include"; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)/include", + "$(PROJECT_DIR)/grpc", + ); INSTALL_PATH = ""; LIBRARY_SEARCH_PATHS = ""; OTHER_CFLAGS = ( @@ -754,7 +765,10 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = "'CMAKE_INTDIR=\"$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\"'"; GCC_SYMBOLS_PRIVATE_EXTERN = NO; - HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/include"; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)/include", + "$(PROJECT_DIR)/grpc", + ); INSTALL_PATH = ""; LIBRARY_SEARCH_PATHS = ""; OTHER_CFLAGS = " -std=c++0x"; @@ -787,7 +801,10 @@ GCC_OPTIMIZATION_LEVEL = 2; GCC_PREPROCESSOR_DEFINITIONS = "'CMAKE_INTDIR=\"$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\"'"; GCC_SYMBOLS_PRIVATE_EXTERN = NO; - HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/include"; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)/include", + "$(PROJECT_DIR)/grpc", + ); INSTALL_PATH = ""; LIBRARY_SEARCH_PATHS = ""; OTHER_CFLAGS = ( @@ -919,7 +936,10 @@ GCC_OPTIMIZATION_LEVEL = s; GCC_PREPROCESSOR_DEFINITIONS = "'CMAKE_INTDIR=\"$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\"'"; GCC_SYMBOLS_PRIVATE_EXTERN = NO; - HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/include"; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)/include", + "$(PROJECT_DIR)/grpc", + ); INSTALL_PATH = ""; LIBRARY_SEARCH_PATHS = ""; OTHER_CFLAGS = ( diff --git a/docs/source/GoUsage.md b/docs/source/GoUsage.md index a3a0e928a..ab6ddbd82 100644 --- a/docs/source/GoUsage.md +++ b/docs/source/GoUsage.md @@ -67,6 +67,29 @@ Now you can access values like this: pos := monster.Pos(nil) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In some cases it's necessary to modify values in an existing FlatBuffer in place (without creating a copy). For this reason, scalar fields of a Flatbuffer table or struct can be mutated. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.go} + monster := example.GetRootAsMonster(buf, 0) + + // Set table field. + if ok := monster.MutateHp(10); !ok { + panic("failed to mutate Hp") + } + + // Set struct field. + monster.Pos().MutateZ(4) + + // This mutation will fail because the mana field is not available in + // the buffer. It should be set when creating the buffer. + if ok := monster.MutateMana(20); !ok { + panic("failed to mutate Hp") + } +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The term `mutate` is used instead of `set` to indicate that this is a special use case. All mutate functions return a boolean value which is false if the field we're trying to mutate is not available in the buffer. + ## Text Parsing There currently is no support for parsing text (Schema's and JSON) directly diff --git a/docs/source/Tutorial.md b/docs/source/Tutorial.md index c457742a2..100191d7a 100644 --- a/docs/source/Tutorial.md +++ b/docs/source/Tutorial.md @@ -727,8 +727,8 @@ offsets. // Place the two weapons into an array, and pass it to the `createWeaponsVector()` method to // create a FlatBuffer vector. int[] weaps = new int[2]; - weaps[1] = sword; - weaps[2] = axe; + weaps[0] = sword; + weaps[1] = axe; // Pass the `weaps` array into the `createWeaponsVector()` method to create a FlatBuffer vector. int weapons = Monster.createWeaponsVector(builder, weaps); diff --git a/go/table.go b/go/table.go index 976a7dba1..01d3db122 100644 --- a/go/table.go +++ b/go/table.go @@ -293,3 +293,213 @@ func (t *Table) GetVOffsetTSlot(slot VOffsetT, d VOffsetT) VOffsetT { } return VOffsetT(off) } + +// MutateBool updates a bool at the given offset. +func (t *Table) MutateBool(off UOffsetT, n bool) bool { + WriteBool(t.Bytes[off:], n) + return true +} + +// MutateByte updates a Byte at the given offset. +func (t *Table) MutateByte(off UOffsetT, n byte) bool { + WriteByte(t.Bytes[off:], n) + return true +} + +// MutateUint8 updates a Uint8 at the given offset. +func (t *Table) MutateUint8(off UOffsetT, n uint8) bool { + WriteUint8(t.Bytes[off:], n) + return true +} + +// MutateUint16 updates a Uint16 at the given offset. +func (t *Table) MutateUint16(off UOffsetT, n uint16) bool { + WriteUint16(t.Bytes[off:], n) + return true +} + +// MutateUint32 updates a Uint32 at the given offset. +func (t *Table) MutateUint32(off UOffsetT, n uint32) bool { + WriteUint32(t.Bytes[off:], n) + return true +} + +// MutateUint64 updates a Uint64 at the given offset. +func (t *Table) MutateUint64(off UOffsetT, n uint64) bool { + WriteUint64(t.Bytes[off:], n) + return true +} + +// MutateInt8 updates a Int8 at the given offset. +func (t *Table) MutateInt8(off UOffsetT, n int8) bool { + WriteInt8(t.Bytes[off:], n) + return true +} + +// MutateInt16 updates a Int16 at the given offset. +func (t *Table) MutateInt16(off UOffsetT, n int16) bool { + WriteInt16(t.Bytes[off:], n) + return true +} + +// MutateInt32 updates a Int32 at the given offset. +func (t *Table) MutateInt32(off UOffsetT, n int32) bool { + WriteInt32(t.Bytes[off:], n) + return true +} + +// MutateInt64 updates a Int64 at the given offset. +func (t *Table) MutateInt64(off UOffsetT, n int64) bool { + WriteInt64(t.Bytes[off:], n) + return true +} + +// MutateFloat32 updates a Float32 at the given offset. +func (t *Table) MutateFloat32(off UOffsetT, n float32) bool { + WriteFloat32(t.Bytes[off:], n) + return true +} + +// MutateFloat64 updates a Float64 at the given offset. +func (t *Table) MutateFloat64(off UOffsetT, n float64) bool { + WriteFloat64(t.Bytes[off:], n) + return true +} + +// MutateUOffsetT updates a UOffsetT at the given offset. +func (t *Table) MutateUOffsetT(off UOffsetT, n UOffsetT) bool { + WriteUOffsetT(t.Bytes[off:], n) + return true +} + +// MutateVOffsetT updates a VOffsetT at the given offset. +func (t *Table) MutateVOffsetT(off UOffsetT, n VOffsetT) bool { + WriteVOffsetT(t.Bytes[off:], n) + return true +} + +// MutateSOffsetT updates a SOffsetT at the given offset. +func (t *Table) MutateSOffsetT(off UOffsetT, n SOffsetT) bool { + WriteSOffsetT(t.Bytes[off:], n) + return true +} + +// MutateBoolSlot updates the bool at given vtable location +func (t *Table) MutateBoolSlot(slot VOffsetT, n bool) bool { + if off := t.Offset(slot); off != 0 { + t.MutateBool(t.Pos+UOffsetT(off), n) + return true + } + + return false +} + +// MutateByteSlot updates the byte at given vtable location +func (t *Table) MutateByteSlot(slot VOffsetT, n byte) bool { + if off := t.Offset(slot); off != 0 { + t.MutateByte(t.Pos+UOffsetT(off), n) + return true + } + + return false +} + +// MutateInt8Slot updates the int8 at given vtable location +func (t *Table) MutateInt8Slot(slot VOffsetT, n int8) bool { + if off := t.Offset(slot); off != 0 { + t.MutateInt8(t.Pos+UOffsetT(off), n) + return true + } + + return false +} + +// MutateUint8Slot updates the uint8 at given vtable location +func (t *Table) MutateUint8Slot(slot VOffsetT, n uint8) bool { + if off := t.Offset(slot); off != 0 { + t.MutateUint8(t.Pos+UOffsetT(off), n) + return true + } + + return false +} + +// MutateInt16Slot updates the int16 at given vtable location +func (t *Table) MutateInt16Slot(slot VOffsetT, n int16) bool { + if off := t.Offset(slot); off != 0 { + t.MutateInt16(t.Pos+UOffsetT(off), n) + return true + } + + return false +} + +// MutateUint16Slot updates the uint16 at given vtable location +func (t *Table) MutateUint16Slot(slot VOffsetT, n uint16) bool { + if off := t.Offset(slot); off != 0 { + t.MutateUint16(t.Pos+UOffsetT(off), n) + return true + } + + return false +} + +// MutateInt32Slot updates the int32 at given vtable location +func (t *Table) MutateInt32Slot(slot VOffsetT, n int32) bool { + if off := t.Offset(slot); off != 0 { + t.MutateInt32(t.Pos+UOffsetT(off), n) + return true + } + + return false +} + +// MutateUint32Slot updates the uint32 at given vtable location +func (t *Table) MutateUint32Slot(slot VOffsetT, n uint32) bool { + if off := t.Offset(slot); off != 0 { + t.MutateUint32(t.Pos+UOffsetT(off), n) + return true + } + + return false +} + +// MutateInt64Slot updates the int64 at given vtable location +func (t *Table) MutateInt64Slot(slot VOffsetT, n int64) bool { + if off := t.Offset(slot); off != 0 { + t.MutateInt64(t.Pos+UOffsetT(off), n) + return true + } + + return false +} + +// MutateUint64Slot updates the uint64 at given vtable location +func (t *Table) MutateUint64Slot(slot VOffsetT, n uint64) bool { + if off := t.Offset(slot); off != 0 { + t.MutateUint64(t.Pos+UOffsetT(off), n) + return true + } + + return false +} + +// MutateFloat32Slot updates the float32 at given vtable location +func (t *Table) MutateFloat32Slot(slot VOffsetT, n float32) bool { + if off := t.Offset(slot); off != 0 { + t.MutateFloat32(t.Pos+UOffsetT(off), n) + return true + } + + return false +} + +// MutateFloat64Slot updates the float64 at given vtable location +func (t *Table) MutateFloat64Slot(slot VOffsetT, n float64) bool { + if off := t.Offset(slot); off != 0 { + t.MutateFloat64(t.Pos+UOffsetT(off), n) + return true + } + + return false +} diff --git a/include/flatbuffers/code_generators.h b/include/flatbuffers/code_generators.h index e7450a7a0..8b097ef7e 100644 --- a/include/flatbuffers/code_generators.h +++ b/include/flatbuffers/code_generators.h @@ -39,8 +39,8 @@ class BaseGenerator { protected: BaseGenerator(const Parser &parser, const std::string &path, - const std::string &file_name, - const std::string qualifying_start, + const std::string &file_name, + const std::string qualifying_start, const std::string qualifying_separator) : parser_(parser), path_(path), @@ -86,15 +86,18 @@ class BaseGenerator { const std::string LastNamespacePart(const Namespace &ns) { auto &namespaces = ns.components; - if (namespaces.size()) return *(namespaces.end() - 1); else return std::string(""); + if (namespaces.size()) + return *(namespaces.end() - 1); + else + return std::string(""); } // tracks the current namespace for early exit in WrapInNameSpace - // c++, java and csharp returns a different namespace from - // the following default (no early exit, always fully qualify), + // c++, java and csharp returns a different namespace from + // the following default (no early exit, always fully qualify), // which works for js and php virtual const Namespace *CurrentNameSpace() { return nullptr; } - + // Ensure that a type is prefixed with its namespace whenever it is used // outside of its namespace. std::string WrapInNameSpace(const Namespace *ns, const std::string &name) { diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h index a764d8640..5ea32ca99 100644 --- a/include/flatbuffers/flatbuffers.h +++ b/include/flatbuffers/flatbuffers.h @@ -1362,7 +1362,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS { size_t GetComputedSize() const { uintptr_t size = upper_bound_ - buf_; // Align the size to uoffset_t - size = (size - 1 + sizeof(uoffset_t)) & -uintptr_t(sizeof(uoffset_t)); + size = (size - 1 + sizeof(uoffset_t)) & ~(sizeof(uoffset_t) - 1); return (buf_ + size > end_) ? 0 : size; } #endif diff --git a/php/FlatbufferBuilder.php b/php/FlatbufferBuilder.php index 3738582e2..6f0ee4831 100644 --- a/php/FlatbufferBuilder.php +++ b/php/FlatbufferBuilder.php @@ -233,7 +233,7 @@ class FlatbufferBuilder public function putUint($x) { if ($x > PHP_INT_MAX) { - throw new \InvalidArgumentException("your platform can't handling uint correctly. use 64bit machine."); + throw new \InvalidArgumentException("your platform can't handle uint correctly. use 64bit machine."); } $this->bb->putUint($this->space -= 4, $x); @@ -245,7 +245,7 @@ class FlatbufferBuilder public function putLong($x) { if ($x > PHP_INT_MAX) { - throw new \InvalidArgumentException("your platform can't handling long correctly. use 64bit machine."); + throw new \InvalidArgumentException("Your platform can't handle long correctly. Use a 64bit machine."); } $this->bb->putLong($this->space -= 8, $x); @@ -257,7 +257,7 @@ class FlatbufferBuilder public function putUlong($x) { if ($x > PHP_INT_MAX) { - throw new \InvalidArgumentException("your platform can't handling ulong correctly. this is php limitations. please wait extension release."); + throw new \InvalidArgumentException("Your platform can't handle ulong correctly. This is a php limitation. Please wait for the extension release."); } $this->bb->putUlong($this->space -= 8, $x); diff --git a/java/pom.xml b/pom.xml similarity index 89% rename from java/pom.xml rename to pom.xml index dd92b9d55..8e32feec3 100644 --- a/java/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.google.flatbuffers flatbuffers-java 1.3.0-SNAPSHOT - jar + bundle FlatBuffers Java API Memory Efficient Serialization Library @@ -33,7 +33,7 @@ - ./ + java maven-compiler-plugin @@ -78,6 +78,12 @@ + + org.apache.felix + maven-bundle-plugin + 3.0.1 + true + diff --git a/readme.md b/readme.md index 15dd41b11..3a7f929ef 100755 --- a/readme.md +++ b/readme.md @@ -46,7 +46,7 @@ you would leave it in.
- [CONTRIBUTING]: http://github.com/google/flatbuffers/blob/master/CONTRIBUTING + [CONTRIBUTING]: http://github.com/google/flatbuffers/blob/master/CONTRIBUTING.md [`flatbuffers` tag]: https://stackoverflow.com/questions/tagged/flatbuffers [FlatBuffers Google Group]: https://groups.google.com/forum/#!forum/flatbuffers [FlatBuffers Issues Tracker]: http://github.com/google/flatbuffers/issues diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 1479ad9fb..890ab9298 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -24,9 +24,7 @@ namespace flatbuffers { struct IsAlnum { - bool operator()(char c) { - return !isalnum(c); - } + bool operator()(char c) { return !isalnum(c); } }; static std::string GeneratedFileName(const std::string &path, @@ -196,7 +194,6 @@ class CppGenerator : public BaseGenerator { code += "nullptr"; code += "); }\n\n"; - if (parser_.file_extension_.length()) { // Return the extension code += "inline const char *" + name; @@ -276,23 +273,21 @@ class CppGenerator : public BaseGenerator { // Return a C++ type for any type (scalar/pointer) specifically for // building a flatbuffer. - std::string GenTypeWire(const Type &type, - const char *postfix, bool user_facing_type) { + std::string GenTypeWire(const Type &type, const char *postfix, + bool user_facing_type) { return IsScalar(type.base_type) ? GenTypeBasic(type, user_facing_type) + postfix - : IsStruct(type) - ? "const " + GenTypePointer(type) + " *" - : "flatbuffers::Offset<" + GenTypePointer(type) + - ">" + postfix; + : IsStruct(type) ? "const " + GenTypePointer(type) + " *" + : "flatbuffers::Offset<" + + GenTypePointer(type) + ">" + postfix; } // Return a C++ type for any type (scalar/pointer) that reflects its // serialized size. std::string GenTypeSize(const Type &type) { - return IsScalar(type.base_type) - ? GenTypeBasic(type, false) - : IsStruct(type) ? GenTypePointer(type) - : "flatbuffers::uoffset_t"; + return IsScalar(type.base_type) ? GenTypeBasic(type, false) + : IsStruct(type) ? GenTypePointer(type) + : "flatbuffers::uoffset_t"; } // TODO(wvo): make this configurable. @@ -325,9 +320,9 @@ class CppGenerator : public BaseGenerator { // Return a C++ type for any type (scalar/pointer) specifically for // using a flatbuffer. - std::string GenTypeGet(const Type &type, - const char *afterbasic, const char *beforeptr, - const char *afterptr, bool user_facing_type) { + std::string GenTypeGet(const Type &type, const char *afterbasic, + const char *beforeptr, const char *afterptr, + bool user_facing_type) { return IsScalar(type.base_type) ? GenTypeBasic(type, user_facing_type) + afterbasic : beforeptr + GenTypePointer(type) + afterptr; @@ -483,8 +478,8 @@ class CppGenerator : public BaseGenerator { code += "()[static_cast(e)"; if (enum_def.vals.vec.front()->value) { code += " - static_cast("; - code += - GetEnumVal(enum_def, *enum_def.vals.vec.front(), parser_.opts) + ")"; + code += GetEnumVal(enum_def, *enum_def.vals.vec.front(), parser_.opts) + + ")"; } code += "]; }\n\n"; } @@ -592,8 +587,7 @@ class CppGenerator : public BaseGenerator { return "VT_" + uname; } - void GenFullyQualifiedNameGetter(const std::string &name, - std::string &code) { + void GenFullyQualifiedNameGetter(const std::string &name, std::string &code) { if (parser_.opts.generate_name_strings) { code += " static FLATBUFFERS_CONSTEXPR const char *GetFullyQualifiedName() " @@ -615,21 +609,17 @@ class CppGenerator : public BaseGenerator { code += field.name + " = "; if (field.value.type.enum_def && IsScalar(field.value.type.base_type)) { auto ev = field.value.type.enum_def->ReverseLookup( - static_cast(StringToInt(field.value.constant.c_str())), - false); + static_cast(StringToInt(field.value.constant.c_str())), false); if (ev) { code += WrapInNameSpace( - field.value.type.enum_def->defined_namespace, - GetEnumVal(*field.value.type.enum_def, *ev, parser_.opts)); - } - else { + field.value.type.enum_def->defined_namespace, + GetEnumVal(*field.value.type.enum_def, *ev, parser_.opts)); + } else { code += GenUnderlyingCast(field, true, field.value.constant); } - } - else if (field.value.type.base_type == BASE_TYPE_BOOL) { + } else if (field.value.type.base_type == BASE_TYPE_BOOL) { code += field.value.constant == "0" ? "false" : "true"; - } - else { + } else { code += GenDefaultConstant(field); } } @@ -693,8 +683,7 @@ class CppGenerator : public BaseGenerator { if (!field.deprecated) { // Deprecated fields won't be accessible. auto is_scalar = IsScalar(field.value.type.base_type); GenComment(field.doc_comment, code_ptr, nullptr, " "); - code += " " + - GenTypeGet(field.value.type, " ", "const ", " *", true); + code += " " + GenTypeGet(field.value.type, " ", "const ", " *", true); code += field.name + "() const { return "; // Call a different accessor for pointers, that indirects. auto accessor = @@ -702,8 +691,8 @@ class CppGenerator : public BaseGenerator { ? "GetField<" : (IsStruct(field.value.type) ? "GetStruct<" : "GetPointer<"); auto offsetstr = GenFieldOffsetName(field); - auto call = accessor + GenTypeGet(field.value.type, "", - "const ", " *", false) + + auto call = accessor + + GenTypeGet(field.value.type, "", "const ", " *", false) + ">(" + offsetstr; // Default value as second arg for non-pointer types. if (IsScalar(field.value.type.base_type)) @@ -720,8 +709,7 @@ class CppGenerator : public BaseGenerator { code += GenUnderlyingCast(field, false, "_" + field.name); code += "); }\n"; } else { - auto type = - GenTypeGet(field.value.type, " ", "", " *", true); + auto type = GenTypeGet(field.value.type, " ", "", " *", true); code += " " + type + "mutable_" + field.name + "() { return "; code += GenUnderlyingCast(field, true, accessor + type + ">(" + offsetstr + ")"); @@ -909,20 +897,19 @@ class CppGenerator : public BaseGenerator { } code += " return builder_.Finish();\n}\n\n"; - //Generate a CreateX function with vector types as parameters + // Generate a CreateX function with vector types as parameters if (gen_vector_pars) { code += "inline flatbuffers::Offset<" + struct_def.name + "> Create"; code += struct_def.name; code += "(flatbuffers::FlatBufferBuilder &_fbb"; for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { + it != struct_def.fields.vec.end(); ++it) { auto &field = **it; if (!field.deprecated) { if (field.value.type.base_type == BASE_TYPE_STRING) { code += ",\n const char *"; code += field.name + " = nullptr"; - } - else if (field.value.type.base_type == BASE_TYPE_VECTOR) { + } else if (field.value.type.base_type == BASE_TYPE_VECTOR) { code += ",\n const std::vector<"; code += GenTypeWire(field.value.type.VectorType(), "", false); code += "> *" + field.name + " = nullptr"; @@ -936,7 +923,7 @@ class CppGenerator : public BaseGenerator { code += struct_def.name; code += "(_fbb"; for (auto it = struct_def.fields.vec.begin(); - it != struct_def.fields.vec.end(); ++it) { + it != struct_def.fields.vec.end(); ++it) { auto &field = **it; if (!field.deprecated) { if (field.value.type.base_type == BASE_TYPE_STRING) { @@ -947,7 +934,8 @@ class CppGenerator : public BaseGenerator { code += "_fbb.CreateVector<"; code += GenTypeWire(field.value.type.VectorType(), "", false); code += ">(*" + field.name + ")"; - } else code += ", " + field.name; + } else + code += ", " + field.name; } } code += ");\n}\n\n"; @@ -1216,8 +1204,7 @@ class CppGenerator : public BaseGenerator { auto &field = **it; GenComment(field.doc_comment, code_ptr, nullptr, " "); auto is_scalar = IsScalar(field.value.type.base_type); - code += " " + - GenTypeGet(field.value.type, " ", "const ", " &", true); + code += " " + GenTypeGet(field.value.type, " ", "const ", " &", true); code += field.name + "() const { return "; code += GenUnderlyingCast( field, true, is_scalar @@ -1286,19 +1273,16 @@ bool GenerateCPP(const Parser &parser, const std::string &path, return generator.generate(); } -std::string CPPMakeRule(const Parser &parser, - const std::string &path, +std::string CPPMakeRule(const Parser &parser, const std::string &path, const std::string &file_name) { - std::string filebase = flatbuffers::StripPath( - flatbuffers::StripExtension(file_name)); + std::string filebase = + flatbuffers::StripPath(flatbuffers::StripExtension(file_name)); std::string make_rule = GeneratedFileName(path, filebase) + ": "; auto included_files = parser.GetIncludedFilesRecursive(file_name); - for (auto it = included_files.begin(); - it != included_files.end(); ++it) { + for (auto it = included_files.begin(); it != included_files.end(); ++it) { make_rule += " " + *it; } return make_rule; } } // namespace flatbuffers - diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp index 34ca2c3e4..7e8e8c577 100644 --- a/src/idl_gen_general.cpp +++ b/src/idl_gen_general.cpp @@ -197,6 +197,7 @@ class GeneralGenerator : public BaseGenerator { lang_(language_parameters[parser_.opts.lang]) { assert(parser_.opts.lang <= IDLOptions::kMAX); }; + GeneralGenerator &operator=(const GeneralGenerator &); bool generate() { std::string one_file_code; @@ -235,7 +236,7 @@ class GeneralGenerator : public BaseGenerator { // Save out the generated code for a single class while adding // declaration boilerplate. - bool SaveType(const std::string &defname, const Namespace &ns, + bool SaveType(const std::string &defname, const Namespace &ns, const std::string &classcode, bool needs_includes) { if (!classcode.length()) return true; @@ -1133,7 +1134,7 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) { // Java does not need the closing semi-colon on class definitions. code += (lang_.language != IDLOptions::kJava) ? ";" : ""; code += "\n\n"; -} +} const LanguageParameters & lang_; }; } // namespace general diff --git a/src/idl_gen_go.cpp b/src/idl_gen_go.cpp index a04b6ba20..0920b7727 100644 --- a/src/idl_gen_go.cpp +++ b/src/idl_gen_go.cpp @@ -439,7 +439,7 @@ static void GenReceiver(const StructDef &struct_def, std::string *code_ptr) { code += "func (rcv *" + struct_def.name + ")"; } -// Generate a struct field, conditioned on its child type(s). +// Generate a struct field getter, conditioned on its child type(s). static void GenStructAccessor(const StructDef &struct_def, const FieldDef &field, std::string *code_ptr) { @@ -486,6 +486,48 @@ static void GenStructAccessor(const StructDef &struct_def, } } +// Mutate the value of a struct's scalar. +static void MutateScalarFieldOfStruct(const StructDef &struct_def, + const FieldDef &field, + std::string *code_ptr) { + std::string &code = *code_ptr; + std::string type = MakeCamel(GenTypeBasic(field.value.type)); + std::string setter = "rcv._tab.Mutate" + type; + GenReceiver(struct_def, code_ptr); + code += " Mutate" + MakeCamel(field.name); + code += "(n " + TypeName(field) + ") bool { return " + setter; + code += "(rcv._tab.Pos + flatbuffers.UOffsetT("; + code += NumToString(field.value.offset) + "), n) }\n\n"; +} + +// Mutate the value of a table's scalar. +static void MutateScalarFieldOfTable(const StructDef &struct_def, + const FieldDef &field, + std::string *code_ptr) { + std::string &code = *code_ptr; + std::string type = MakeCamel(GenTypeBasic(field.value.type)); + std::string setter = "rcv._tab.Mutate" + type + "Slot"; + GenReceiver(struct_def, code_ptr); + code += " Mutate" + MakeCamel(field.name); + code += "(n " + TypeName(field) + ") bool {\n\treturn "; + code += setter + "(" + NumToString(field.value.offset) + ", n)\n"; + code += "}\n\n"; +} + +// Generate a struct field setter, conditioned on its child type(s). +static void GenStructMutator(const StructDef &struct_def, + const FieldDef &field, + std::string *code_ptr) { + GenComment(field.doc_comment, code_ptr, nullptr, ""); + if (IsScalar(field.value.type.base_type)) { + if (struct_def.fixed) { + MutateScalarFieldOfStruct(struct_def, field, code_ptr); + } else { + MutateScalarFieldOfTable(struct_def, field, code_ptr); + } + } +} + // Generate table constructors, conditioned on its members' types. static void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) { @@ -530,6 +572,7 @@ static void GenStruct(const StructDef &struct_def, if (field.deprecated) continue; GenStructAccessor(struct_def, field, code_ptr); + GenStructMutator(struct_def, field, code_ptr); } if (struct_def.fixed) { @@ -681,4 +724,3 @@ bool GenerateGo(const Parser &parser, const std::string &path, } } // namespace flatbuffers - diff --git a/src/idl_gen_grpc.cpp b/src/idl_gen_grpc.cpp index 2bf0e911d..6ada3e873 100644 --- a/src/idl_gen_grpc.cpp +++ b/src/idl_gen_grpc.cpp @@ -137,6 +137,7 @@ class FlatBufFile : public grpc_cpp_generator::File { public: FlatBufFile(const Parser &parser, const std::string &file_name) : parser_(parser), file_name_(file_name) {} + FlatBufFile &operator=(const FlatBufFile &); std::string filename() const { return file_name_; } std::string filename_without_ext() const { diff --git a/tests/MyGame/Example/Any.java b/tests/MyGame/Example/Any.java index 25d74af55..6e4fb76ca 100644 --- a/tests/MyGame/Example/Any.java +++ b/tests/MyGame/Example/Any.java @@ -9,8 +9,8 @@ public final class Any { public static final byte TestSimpleTableWithEnum = 2; public static final byte MyGame_Example2_Monster = 3; - private static final String[] names = { "NONE", "Monster", "TestSimpleTableWithEnum", "MyGame_Example2_Monster", }; + public static final String[] names = { "NONE", "Monster", "TestSimpleTableWithEnum", "MyGame_Example2_Monster", }; public static String name(int e) { return names[e]; } -}; +} diff --git a/tests/MyGame/Example/Color.java b/tests/MyGame/Example/Color.java index 502ec9fbf..7c113b72f 100644 --- a/tests/MyGame/Example/Color.java +++ b/tests/MyGame/Example/Color.java @@ -8,8 +8,8 @@ public final class Color { public static final byte Green = 2; public static final byte Blue = 8; - private static final String[] names = { "Red", "Green", "", "", "", "", "", "Blue", }; + public static final String[] names = { "Red", "Green", "", "", "", "", "", "Blue", }; public static String name(int e) { return names[e - Red]; } -}; +} diff --git a/tests/MyGame/Example/Monster.go b/tests/MyGame/Example/Monster.go index 0c42f45a5..f4cd18c18 100644 --- a/tests/MyGame/Example/Monster.go +++ b/tests/MyGame/Example/Monster.go @@ -43,6 +43,10 @@ func (rcv *Monster) Mana() int16 { return 150 } +func (rcv *Monster) MutateMana(n int16) bool { + return rcv._tab.MutateInt16Slot(6, n) +} + func (rcv *Monster) Hp() int16 { o := flatbuffers.UOffsetT(rcv._tab.Offset(8)) if o != 0 { @@ -51,6 +55,10 @@ func (rcv *Monster) Hp() int16 { return 100 } +func (rcv *Monster) MutateHp(n int16) bool { + return rcv._tab.MutateInt16Slot(8, n) +} + func (rcv *Monster) Name() []byte { o := flatbuffers.UOffsetT(rcv._tab.Offset(10)) if o != 0 { @@ -92,6 +100,10 @@ func (rcv *Monster) Color() int8 { return 8 } +func (rcv *Monster) MutateColor(n int8) bool { + return rcv._tab.MutateInt8Slot(16, n) +} + func (rcv *Monster) TestType() byte { o := flatbuffers.UOffsetT(rcv._tab.Offset(18)) if o != 0 { @@ -100,6 +112,10 @@ func (rcv *Monster) TestType() byte { return 0 } +func (rcv *Monster) MutateTestType(n byte) bool { + return rcv._tab.MutateByteSlot(18, n) +} + func (rcv *Monster) Test(obj *flatbuffers.Table) bool { o := flatbuffers.UOffsetT(rcv._tab.Offset(20)) if o != 0 { @@ -173,6 +189,8 @@ func (rcv *Monster) TestarrayoftablesLength() int { return 0 } +/// an example documentation comment: this will end up in the generated code +/// multiline too func (rcv *Monster) Enemy(obj *Monster) *Monster { o := flatbuffers.UOffsetT(rcv._tab.Offset(28)) if o != 0 { @@ -232,6 +250,10 @@ func (rcv *Monster) Testbool() byte { return 0 } +func (rcv *Monster) MutateTestbool(n byte) bool { + return rcv._tab.MutateByteSlot(34, n) +} + func (rcv *Monster) Testhashs32Fnv1() int32 { o := flatbuffers.UOffsetT(rcv._tab.Offset(36)) if o != 0 { @@ -240,6 +262,10 @@ func (rcv *Monster) Testhashs32Fnv1() int32 { return 0 } +func (rcv *Monster) MutateTesthashs32Fnv1(n int32) bool { + return rcv._tab.MutateInt32Slot(36, n) +} + func (rcv *Monster) Testhashu32Fnv1() uint32 { o := flatbuffers.UOffsetT(rcv._tab.Offset(38)) if o != 0 { @@ -248,6 +274,10 @@ func (rcv *Monster) Testhashu32Fnv1() uint32 { return 0 } +func (rcv *Monster) MutateTesthashu32Fnv1(n uint32) bool { + return rcv._tab.MutateUint32Slot(38, n) +} + func (rcv *Monster) Testhashs64Fnv1() int64 { o := flatbuffers.UOffsetT(rcv._tab.Offset(40)) if o != 0 { @@ -256,6 +286,10 @@ func (rcv *Monster) Testhashs64Fnv1() int64 { return 0 } +func (rcv *Monster) MutateTesthashs64Fnv1(n int64) bool { + return rcv._tab.MutateInt64Slot(40, n) +} + func (rcv *Monster) Testhashu64Fnv1() uint64 { o := flatbuffers.UOffsetT(rcv._tab.Offset(42)) if o != 0 { @@ -264,6 +298,10 @@ func (rcv *Monster) Testhashu64Fnv1() uint64 { return 0 } +func (rcv *Monster) MutateTesthashu64Fnv1(n uint64) bool { + return rcv._tab.MutateUint64Slot(42, n) +} + func (rcv *Monster) Testhashs32Fnv1a() int32 { o := flatbuffers.UOffsetT(rcv._tab.Offset(44)) if o != 0 { @@ -272,6 +310,10 @@ func (rcv *Monster) Testhashs32Fnv1a() int32 { return 0 } +func (rcv *Monster) MutateTesthashs32Fnv1a(n int32) bool { + return rcv._tab.MutateInt32Slot(44, n) +} + func (rcv *Monster) Testhashu32Fnv1a() uint32 { o := flatbuffers.UOffsetT(rcv._tab.Offset(46)) if o != 0 { @@ -280,6 +322,10 @@ func (rcv *Monster) Testhashu32Fnv1a() uint32 { return 0 } +func (rcv *Monster) MutateTesthashu32Fnv1a(n uint32) bool { + return rcv._tab.MutateUint32Slot(46, n) +} + func (rcv *Monster) Testhashs64Fnv1a() int64 { o := flatbuffers.UOffsetT(rcv._tab.Offset(48)) if o != 0 { @@ -288,6 +334,10 @@ func (rcv *Monster) Testhashs64Fnv1a() int64 { return 0 } +func (rcv *Monster) MutateTesthashs64Fnv1a(n int64) bool { + return rcv._tab.MutateInt64Slot(48, n) +} + func (rcv *Monster) Testhashu64Fnv1a() uint64 { o := flatbuffers.UOffsetT(rcv._tab.Offset(50)) if o != 0 { @@ -296,6 +346,10 @@ func (rcv *Monster) Testhashu64Fnv1a() uint64 { return 0 } +func (rcv *Monster) MutateTesthashu64Fnv1a(n uint64) bool { + return rcv._tab.MutateUint64Slot(50, n) +} + func (rcv *Monster) Testarrayofbools(j int) byte { o := flatbuffers.UOffsetT(rcv._tab.Offset(52)) if o != 0 { @@ -321,6 +375,10 @@ func (rcv *Monster) Testf() float32 { return 3.14159 } +func (rcv *Monster) MutateTestf(n float32) bool { + return rcv._tab.MutateFloat32Slot(54, n) +} + func (rcv *Monster) Testf2() float32 { o := flatbuffers.UOffsetT(rcv._tab.Offset(56)) if o != 0 { @@ -329,6 +387,10 @@ func (rcv *Monster) Testf2() float32 { return 3.0 } +func (rcv *Monster) MutateTestf2(n float32) bool { + return rcv._tab.MutateFloat32Slot(56, n) +} + func (rcv *Monster) Testf3() float32 { o := flatbuffers.UOffsetT(rcv._tab.Offset(58)) if o != 0 { @@ -337,6 +399,10 @@ func (rcv *Monster) Testf3() float32 { return 0.0 } +func (rcv *Monster) MutateTestf3(n float32) bool { + return rcv._tab.MutateFloat32Slot(58, n) +} + func (rcv *Monster) Testarrayofstring2(j int) []byte { o := flatbuffers.UOffsetT(rcv._tab.Offset(60)) if o != 0 { diff --git a/tests/MyGame/Example/Monster.java b/tests/MyGame/Example/Monster.java index bfd4be1c9..dc27f8447 100644 --- a/tests/MyGame/Example/Monster.java +++ b/tests/MyGame/Example/Monster.java @@ -135,5 +135,5 @@ public final class Monster extends Table { return o; } public static void finishMonsterBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "MONS"); } -}; +} diff --git a/tests/MyGame/Example/Stat.go b/tests/MyGame/Example/Stat.go index 7c33716b4..4ccca3446 100644 --- a/tests/MyGame/Example/Stat.go +++ b/tests/MyGame/Example/Stat.go @@ -30,6 +30,10 @@ func (rcv *Stat) Val() int64 { return 0 } +func (rcv *Stat) MutateVal(n int64) bool { + return rcv._tab.MutateInt64Slot(6, n) +} + func (rcv *Stat) Count() uint16 { o := flatbuffers.UOffsetT(rcv._tab.Offset(8)) if o != 0 { @@ -38,6 +42,10 @@ func (rcv *Stat) Count() uint16 { return 0 } +func (rcv *Stat) MutateCount(n uint16) bool { + return rcv._tab.MutateUint16Slot(8, n) +} + func StatStart(builder *flatbuffers.Builder) { builder.StartObject(3) } func StatAddId(builder *flatbuffers.Builder, id flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(id), 0) } func StatAddVal(builder *flatbuffers.Builder, val int64) { builder.PrependInt64Slot(1, val, 0) } diff --git a/tests/MyGame/Example/Stat.java b/tests/MyGame/Example/Stat.java index 3cac509b7..cd339c62d 100644 --- a/tests/MyGame/Example/Stat.java +++ b/tests/MyGame/Example/Stat.java @@ -39,5 +39,5 @@ public final class Stat extends Table { int o = builder.endObject(); return o; } -}; +} diff --git a/tests/MyGame/Example/Test.go b/tests/MyGame/Example/Test.go index e849488d9..ee0d9aaec 100644 --- a/tests/MyGame/Example/Test.go +++ b/tests/MyGame/Example/Test.go @@ -15,7 +15,11 @@ func (rcv *Test) Init(buf []byte, i flatbuffers.UOffsetT) { } func (rcv *Test) A() int16 { return rcv._tab.GetInt16(rcv._tab.Pos + flatbuffers.UOffsetT(0)) } +func (rcv *Test) MutateA(n int16) bool { return rcv._tab.MutateInt16(rcv._tab.Pos + flatbuffers.UOffsetT(0), n) } + func (rcv *Test) B() int8 { return rcv._tab.GetInt8(rcv._tab.Pos + flatbuffers.UOffsetT(2)) } +func (rcv *Test) MutateB(n int8) bool { return rcv._tab.MutateInt8(rcv._tab.Pos + flatbuffers.UOffsetT(2), n) } + func CreateTest(builder *flatbuffers.Builder, a int16, b int8) flatbuffers.UOffsetT { builder.Prep(2, 4) diff --git a/tests/MyGame/Example/Test.java b/tests/MyGame/Example/Test.java index 52474152f..6e33da9b3 100644 --- a/tests/MyGame/Example/Test.java +++ b/tests/MyGame/Example/Test.java @@ -23,5 +23,5 @@ public final class Test extends Struct { builder.putShort(a); return builder.offset(); } -}; +} diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.go b/tests/MyGame/Example/TestSimpleTableWithEnum.go index fe9cf2dbb..d59fa6b19 100644 --- a/tests/MyGame/Example/TestSimpleTableWithEnum.go +++ b/tests/MyGame/Example/TestSimpleTableWithEnum.go @@ -22,6 +22,10 @@ func (rcv *TestSimpleTableWithEnum) Color() int8 { return 2 } +func (rcv *TestSimpleTableWithEnum) MutateColor(n int8) bool { + return rcv._tab.MutateInt8Slot(4, n) +} + func TestSimpleTableWithEnumStart(builder *flatbuffers.Builder) { builder.StartObject(1) } func TestSimpleTableWithEnumAddColor(builder *flatbuffers.Builder, color int8) { builder.PrependInt8Slot(0, color, 2) } func TestSimpleTableWithEnumEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { return builder.EndObject() } diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.java b/tests/MyGame/Example/TestSimpleTableWithEnum.java index 85e18c2b3..a1de020ea 100644 --- a/tests/MyGame/Example/TestSimpleTableWithEnum.java +++ b/tests/MyGame/Example/TestSimpleTableWithEnum.java @@ -29,5 +29,5 @@ public final class TestSimpleTableWithEnum extends Table { int o = builder.endObject(); return o; } -}; +} diff --git a/tests/MyGame/Example/Vec3.go b/tests/MyGame/Example/Vec3.go index 082945ed3..8bf97da32 100644 --- a/tests/MyGame/Example/Vec3.go +++ b/tests/MyGame/Example/Vec3.go @@ -15,10 +15,20 @@ func (rcv *Vec3) Init(buf []byte, i flatbuffers.UOffsetT) { } func (rcv *Vec3) X() float32 { return rcv._tab.GetFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(0)) } +func (rcv *Vec3) MutateX(n float32) bool { return rcv._tab.MutateFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(0), n) } + func (rcv *Vec3) Y() float32 { return rcv._tab.GetFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(4)) } +func (rcv *Vec3) MutateY(n float32) bool { return rcv._tab.MutateFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(4), n) } + func (rcv *Vec3) Z() float32 { return rcv._tab.GetFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(8)) } +func (rcv *Vec3) MutateZ(n float32) bool { return rcv._tab.MutateFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(8), n) } + func (rcv *Vec3) Test1() float64 { return rcv._tab.GetFloat64(rcv._tab.Pos + flatbuffers.UOffsetT(16)) } +func (rcv *Vec3) MutateTest1(n float64) bool { return rcv._tab.MutateFloat64(rcv._tab.Pos + flatbuffers.UOffsetT(16), n) } + func (rcv *Vec3) Test2() int8 { return rcv._tab.GetInt8(rcv._tab.Pos + flatbuffers.UOffsetT(24)) } +func (rcv *Vec3) MutateTest2(n int8) bool { return rcv._tab.MutateInt8(rcv._tab.Pos + flatbuffers.UOffsetT(24), n) } + func (rcv *Vec3) Test3(obj *Test) *Test { if obj == nil { obj = new(Test) diff --git a/tests/MyGame/Example/Vec3.java b/tests/MyGame/Example/Vec3.java index 7ae1ce209..261947cc3 100644 --- a/tests/MyGame/Example/Vec3.java +++ b/tests/MyGame/Example/Vec3.java @@ -40,5 +40,5 @@ public final class Vec3 extends Struct { builder.putFloat(x); return builder.offset(); } -}; +} diff --git a/tests/MyGame/Example2/Monster.java b/tests/MyGame/Example2/Monster.java index 6432494f3..968eee563 100644 --- a/tests/MyGame/Example2/Monster.java +++ b/tests/MyGame/Example2/Monster.java @@ -19,5 +19,5 @@ public final class Monster extends Table { int o = builder.endObject(); return o; } -}; +} diff --git a/tests/go_test.go b/tests/go_test.go index 9d94277f7..b816eb297 100644 --- a/tests/go_test.go +++ b/tests/go_test.go @@ -67,6 +67,7 @@ func TestAll(t *testing.T) { // Verify that the Go FlatBuffers runtime library generates the // expected bytes (does not use any schema): CheckByteLayout(t.Fatalf) + CheckMutateMethods(t.Fatalf) // Verify that panics are raised during exceptional conditions: CheckNotInObjectError(t.Fatalf) @@ -82,6 +83,7 @@ func TestAll(t *testing.T) { // Verify that the buffer generated by Go code is readable by the // generated Go code: CheckReadBuffer(generated, off, t.Fatalf) + CheckMutateBuffer(generated, off, t.Fatalf) // Verify that the buffer generated by C++ code is readable by the // generated Go code: @@ -90,6 +92,7 @@ func TestAll(t *testing.T) { t.Fatal(err) } CheckReadBuffer(monsterDataCpp, 0, t.Fatalf) + CheckMutateBuffer(monsterDataCpp, 0, t.Fatalf) // Verify that vtables are deduplicated when written: CheckVtableDeduplication(t.Fatalf) @@ -280,6 +283,120 @@ func CheckReadBuffer(buf []byte, offset flatbuffers.UOffsetT, fail func(string, } } +// CheckMutateBuffer checks that the given buffer can be mutated correctly +// as the example Monster. Only available scalar values are mutated. +func CheckMutateBuffer(org []byte, offset flatbuffers.UOffsetT, fail func(string, ...interface{})) { + // make a copy to mutate + buf := make([]byte, len(org)) + copy(buf, org) + + // load monster data from the buffer + monster := example.GetRootAsMonster(buf, offset) + + // test case struct + type testcase struct { + field string + testfn func() bool + } + + testForOriginalValues := []testcase{ + testcase{"Hp", func() bool { return monster.Hp() == 80 }}, + testcase{"Mana", func() bool { return monster.Mana() == 150 }}, + testcase{"Pos.X'", func() bool { return monster.Pos(nil).X() == float32(1.0) }}, + testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(2.0) }}, + testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(3.0) }}, + testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(3.0) }}, + testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == int8(2) }}, + testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(5) }}, + testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(6) }}, + } + + testMutability := []testcase{ + testcase{"Hp", func() bool { return monster.MutateHp(70) }}, + testcase{"Mana", func() bool { return !monster.MutateMana(140) }}, + testcase{"Pos.X", func() bool { return monster.Pos(nil).MutateX(10.0) }}, + testcase{"Pos.Y", func() bool { return monster.Pos(nil).MutateY(20.0) }}, + testcase{"Pos.Z", func() bool { return monster.Pos(nil).MutateZ(30.0) }}, + testcase{"Pos.Test1", func() bool { return monster.Pos(nil).MutateTest1(30.0) }}, + testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(20) }}, + testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).MutateA(50) }}, + testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).MutateB(60) }}, + } + + testForMutatedValues := []testcase{ + testcase{"Hp", func() bool { return monster.Hp() == 70 }}, + testcase{"Mana", func() bool { return monster.Mana() == 150 }}, + testcase{"Pos.X'", func() bool { return monster.Pos(nil).X() == float32(10.0) }}, + testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(20.0) }}, + testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(30.0) }}, + testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(30.0) }}, + testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == int8(20) }}, + testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(50) }}, + testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(60) }}, + } + + // make sure original values are okay + for _, t := range testForOriginalValues { + if !t.testfn() { + fail("field '" + t.field + "' doesn't have the expected original value") + } + } + + // try to mutate fields and check mutability + for _, t := range testMutability { + if !t.testfn() { + fail(FailString("field '"+t.field+"' failed mutability test", true, false)) + } + } + + // test whether values have changed + for _, t := range testForMutatedValues { + if !t.testfn() { + fail("field '" + t.field + "' doesn't have the expected mutated value") + } + } + + // make sure the buffer has changed + if reflect.DeepEqual(buf, org) { + fail("mutate buffer failed") + } + + // To make sure the buffer has changed accordingly + // Read data from the buffer and verify all fields + monster = example.GetRootAsMonster(buf, offset) + for _, t := range testForMutatedValues { + if !t.testfn() { + fail("field '" + t.field + "' doesn't have the expected mutated value") + } + } + + // reverting all fields to original values should + // re-create the original buffer. Mutate all fields + // back to their original values and compare buffers. + // This test is done to make sure mutations do not do + // any unnecessary changes to the buffer. + monster = example.GetRootAsMonster(buf, offset) + monster.MutateHp(80) + monster.Pos(nil).MutateX(1.0) + monster.Pos(nil).MutateY(2.0) + monster.Pos(nil).MutateZ(3.0) + monster.Pos(nil).MutateTest1(3.0) + monster.Pos(nil).MutateTest2(2) + monster.Pos(nil).Test3(nil).MutateA(5) + monster.Pos(nil).Test3(nil).MutateB(6) + + for _, t := range testForOriginalValues { + if !t.testfn() { + fail("field '" + t.field + "' doesn't have the expected original value") + } + } + + // buffer should have original values + if !reflect.DeepEqual(buf, org) { + fail("revert changes failed") + } +} + // Low level stress/fuzz test: serialize/deserialize a variety of // different kinds of data in different combinations func checkFuzz(fuzzFields, fuzzObjects int, fail func(string, ...interface{})) { @@ -1248,6 +1365,151 @@ func CheckByteEquality(a, b []byte, fail func(string, ...interface{})) { } } +// CheckMutateMethods checks all mutate methods one by one +func CheckMutateMethods(fail func(string, ...interface{})) { + b := flatbuffers.NewBuilder(0) + b.StartObject(15) + b.PrependBoolSlot(0, true, false) + b.PrependByteSlot(1, 1, 0) + b.PrependUint8Slot(2, 2, 0) + b.PrependUint16Slot(3, 3, 0) + b.PrependUint32Slot(4, 4, 0) + b.PrependUint64Slot(5, 5, 0) + b.PrependInt8Slot(6, 6, 0) + b.PrependInt16Slot(7, 7, 0) + b.PrependInt32Slot(8, 8, 0) + b.PrependInt64Slot(9, 9, 0) + b.PrependFloat32Slot(10, 10, 0) + b.PrependFloat64Slot(11, 11, 0) + + b.PrependUOffsetTSlot(12, 12, 0) + uoVal := b.Offset() - 12 + + b.PrependVOffsetT(13) + b.Slot(13) + + b.PrependSOffsetT(14) + b.Slot(14) + soVal := flatbuffers.SOffsetT(b.Offset() - 14) + + offset := b.EndObject() + + t := &flatbuffers.Table{ + Bytes: b.Bytes, + Pos: flatbuffers.UOffsetT(len(b.Bytes)) - offset, + } + + calcVOffsetT := func(slot int) (vtableOffset flatbuffers.VOffsetT) { + return flatbuffers.VOffsetT((flatbuffers.VtableMetadataFields + slot) * flatbuffers.SizeVOffsetT) + } + calcUOffsetT := func(vtableOffset flatbuffers.VOffsetT) (valueOffset flatbuffers.UOffsetT) { + return t.Pos + flatbuffers.UOffsetT(t.Offset(vtableOffset)) + } + + type testcase struct { + field string + testfn func() bool + } + + testForOriginalValues := []testcase{ + testcase{"BoolSlot", func() bool { return t.GetBoolSlot(calcVOffsetT(0), true) == true }}, + testcase{"ByteSlot", func() bool { return t.GetByteSlot(calcVOffsetT(1), 1) == 1 }}, + testcase{"Uint8Slot", func() bool { return t.GetUint8Slot(calcVOffsetT(2), 2) == 2 }}, + testcase{"Uint16Slot", func() bool { return t.GetUint16Slot(calcVOffsetT(3), 3) == 3 }}, + testcase{"Uint32Slot", func() bool { return t.GetUint32Slot(calcVOffsetT(4), 4) == 4 }}, + testcase{"Uint64Slot", func() bool { return t.GetUint64Slot(calcVOffsetT(5), 5) == 5 }}, + testcase{"Int8Slot", func() bool { return t.GetInt8Slot(calcVOffsetT(6), 6) == 6 }}, + testcase{"Int16Slot", func() bool { return t.GetInt16Slot(calcVOffsetT(7), 7) == 7 }}, + testcase{"Int32Slot", func() bool { return t.GetInt32Slot(calcVOffsetT(8), 8) == 8 }}, + testcase{"Int64Slot", func() bool { return t.GetInt64Slot(calcVOffsetT(9), 9) == 9 }}, + testcase{"Float32Slot", func() bool { return t.GetFloat32Slot(calcVOffsetT(10), 10) == 10 }}, + testcase{"Float64Slot", func() bool { return t.GetFloat64Slot(calcVOffsetT(11), 11) == 11 }}, + testcase{"UOffsetTSlot", func() bool { return t.GetUOffsetT(calcUOffsetT(calcVOffsetT(12))) == uoVal }}, + testcase{"VOffsetTSlot", func() bool { return t.GetVOffsetT(calcUOffsetT(calcVOffsetT(13))) == 13 }}, + testcase{"SOffsetTSlot", func() bool { return t.GetSOffsetT(calcUOffsetT(calcVOffsetT(14))) == soVal }}, + } + + testMutability := []testcase{ + testcase{"BoolSlot", func() bool { return t.MutateBoolSlot(calcVOffsetT(0), false) }}, + testcase{"ByteSlot", func() bool { return t.MutateByteSlot(calcVOffsetT(1), 2) }}, + testcase{"Uint8Slot", func() bool { return t.MutateUint8Slot(calcVOffsetT(2), 4) }}, + testcase{"Uint16Slot", func() bool { return t.MutateUint16Slot(calcVOffsetT(3), 6) }}, + testcase{"Uint32Slot", func() bool { return t.MutateUint32Slot(calcVOffsetT(4), 8) }}, + testcase{"Uint64Slot", func() bool { return t.MutateUint64Slot(calcVOffsetT(5), 10) }}, + testcase{"Int8Slot", func() bool { return t.MutateInt8Slot(calcVOffsetT(6), 12) }}, + testcase{"Int16Slot", func() bool { return t.MutateInt16Slot(calcVOffsetT(7), 14) }}, + testcase{"Int32Slot", func() bool { return t.MutateInt32Slot(calcVOffsetT(8), 16) }}, + testcase{"Int64Slot", func() bool { return t.MutateInt64Slot(calcVOffsetT(9), 18) }}, + testcase{"Float32Slot", func() bool { return t.MutateFloat32Slot(calcVOffsetT(10), 20) }}, + testcase{"Float64Slot", func() bool { return t.MutateFloat64Slot(calcVOffsetT(11), 22) }}, + testcase{"UOffsetTSlot", func() bool { return t.MutateUOffsetT(calcUOffsetT(calcVOffsetT(12)), 24) }}, + testcase{"VOffsetTSlot", func() bool { return t.MutateVOffsetT(calcUOffsetT(calcVOffsetT(13)), 26) }}, + testcase{"SOffsetTSlot", func() bool { return t.MutateSOffsetT(calcUOffsetT(calcVOffsetT(14)), 28) }}, + } + + testMutabilityWithoutSlot := []testcase{ + testcase{"BoolSlot", func() bool { return t.MutateBoolSlot(calcVOffsetT(16), false) }}, + testcase{"ByteSlot", func() bool { return t.MutateByteSlot(calcVOffsetT(16), 2) }}, + testcase{"Uint8Slot", func() bool { return t.MutateUint8Slot(calcVOffsetT(16), 2) }}, + testcase{"Uint16Slot", func() bool { return t.MutateUint16Slot(calcVOffsetT(16), 2) }}, + testcase{"Uint32Slot", func() bool { return t.MutateUint32Slot(calcVOffsetT(16), 2) }}, + testcase{"Uint64Slot", func() bool { return t.MutateUint64Slot(calcVOffsetT(16), 2) }}, + testcase{"Int8Slot", func() bool { return t.MutateInt8Slot(calcVOffsetT(16), 2) }}, + testcase{"Int16Slot", func() bool { return t.MutateInt16Slot(calcVOffsetT(16), 2) }}, + testcase{"Int32Slot", func() bool { return t.MutateInt32Slot(calcVOffsetT(16), 2) }}, + testcase{"Int64Slot", func() bool { return t.MutateInt64Slot(calcVOffsetT(16), 2) }}, + testcase{"Float32Slot", func() bool { return t.MutateFloat32Slot(calcVOffsetT(16), 2) }}, + testcase{"Float64Slot", func() bool { return t.MutateFloat64Slot(calcVOffsetT(16), 2) }}, + } + + testForMutatedValues := []testcase{ + testcase{"BoolSlot", func() bool { return t.GetBoolSlot(calcVOffsetT(0), true) == false }}, + testcase{"ByteSlot", func() bool { return t.GetByteSlot(calcVOffsetT(1), 1) == 2 }}, + testcase{"Uint8Slot", func() bool { return t.GetUint8Slot(calcVOffsetT(2), 1) == 4 }}, + testcase{"Uint16Slot", func() bool { return t.GetUint16Slot(calcVOffsetT(3), 1) == 6 }}, + testcase{"Uint32Slot", func() bool { return t.GetUint32Slot(calcVOffsetT(4), 1) == 8 }}, + testcase{"Uint64Slot", func() bool { return t.GetUint64Slot(calcVOffsetT(5), 1) == 10 }}, + testcase{"Int8Slot", func() bool { return t.GetInt8Slot(calcVOffsetT(6), 1) == 12 }}, + testcase{"Int16Slot", func() bool { return t.GetInt16Slot(calcVOffsetT(7), 1) == 14 }}, + testcase{"Int32Slot", func() bool { return t.GetInt32Slot(calcVOffsetT(8), 1) == 16 }}, + testcase{"Int64Slot", func() bool { return t.GetInt64Slot(calcVOffsetT(9), 1) == 18 }}, + testcase{"Float32Slot", func() bool { return t.GetFloat32Slot(calcVOffsetT(10), 1) == 20 }}, + testcase{"Float64Slot", func() bool { return t.GetFloat64Slot(calcVOffsetT(11), 1) == 22 }}, + testcase{"UOffsetTSlot", func() bool { return t.GetUOffsetT(calcUOffsetT(calcVOffsetT(12))) == 24 }}, + testcase{"VOffsetTSlot", func() bool { return t.GetVOffsetT(calcUOffsetT(calcVOffsetT(13))) == 26 }}, + testcase{"SOffsetTSlot", func() bool { return t.GetSOffsetT(calcUOffsetT(calcVOffsetT(14))) == 28 }}, + } + + // make sure original values are okay + for _, t := range testForOriginalValues { + if !t.testfn() { + fail(t.field + "' field doesn't have the expected original value") + } + } + + // try to mutate fields and check mutability + for _, t := range testMutability { + if !t.testfn() { + fail(FailString(t.field+"' field failed mutability test", "passed", "failed")) + } + } + + // try to mutate fields and check mutability + // these have wrong slots so should fail + for _, t := range testMutabilityWithoutSlot { + if t.testfn() { + fail(FailString(t.field+"' field failed no slot mutability test", "failed", "passed")) + } + } + + // test whether values have changed + for _, t := range testForMutatedValues { + if !t.testfn() { + fail(t.field + "' field doesn't have the expected mutated value") + } + } +} + // BenchmarkVtableDeduplication measures the speed of vtable deduplication // by creating prePop vtables, then populating b.N objects with a // different single vtable. diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.java b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.java index ff5559544..e23cecc06 100644 --- a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.java +++ b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.java @@ -8,8 +8,8 @@ public final class EnumInNestedNS { public static final byte B = 1; public static final byte C = 2; - private static final String[] names = { "A", "B", "C", }; + public static final String[] names = { "A", "B", "C", }; public static String name(int e) { return names[e]; } -}; +} diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java index 93f805224..fede07a02 100644 --- a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java +++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java @@ -22,5 +22,5 @@ public final class StructInNestedNS extends Struct { builder.putInt(a); return builder.offset(); } -}; +} diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java index 2cfb1bacc..fc518563d 100644 --- a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java +++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java @@ -29,5 +29,5 @@ public final class TableInNestedNS extends Table { int o = builder.endObject(); return o; } -}; +} diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.java b/tests/namespace_test/NamespaceA/SecondTableInA.java index acabc3931..e6f390a9f 100644 --- a/tests/namespace_test/NamespaceA/SecondTableInA.java +++ b/tests/namespace_test/NamespaceA/SecondTableInA.java @@ -29,5 +29,5 @@ public final class SecondTableInA extends Table { int o = builder.endObject(); return o; } -}; +} diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.java b/tests/namespace_test/NamespaceA/TableInFirstNS.java index 873979307..b44df9786 100644 --- a/tests/namespace_test/NamespaceA/TableInFirstNS.java +++ b/tests/namespace_test/NamespaceA/TableInFirstNS.java @@ -28,5 +28,5 @@ public final class TableInFirstNS extends Table { int o = builder.endObject(); return o; } -}; +} diff --git a/tests/namespace_test/NamespaceC/TableInC.java b/tests/namespace_test/NamespaceC/TableInC.java index cf1bca18c..19bb4cd57 100644 --- a/tests/namespace_test/NamespaceC/TableInC.java +++ b/tests/namespace_test/NamespaceC/TableInC.java @@ -34,5 +34,5 @@ public final class TableInC extends Table { int o = builder.endObject(); return o; } -}; +} diff --git a/tests/test.cpp b/tests/test.cpp index bcd54f564..c31fe8dcc 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -124,7 +124,9 @@ flatbuffers::unique_ptr_t CreateFlatBufferTest(std::string &buffer) { }); // Creating vectors of strings in one convenient call. - std::vector names2 = { "jane", "mary" }; + std::vector names2; + names2.push_back("jane"); + names2.push_back("mary"); auto vecofstrings2 = builder.CreateVectorOfStrings(names2); // Create an array of sorted tables, can be used with binary search when read: