Commit 46bb05d9 authored by Kamil Rojewski's avatar Kamil Rojewski Committed by Wouter van Oortmerssen

Vector of unions for TS/JS and PHP (#4404)

* Eclipse ignore

* TypeScript support

* Prefixing enums

* Test results

* Merged JS and TS generators

* Fixed AppVeyor build problems

* Fixed more AppVeyor build problems

* Fixed more AppVeyor build problems

* Changed TS flag to options struct

* Storing options by value

* Removed unneeded const

* Re-export support for unions

* Uint support

* Casting bools to numbers for mutation

* TS shell tests

* Reverted generates js test file to original version

* Backing up js tests and properly generating test data

* Not importing flatbuffers for TS test generation

* Not overwriting generated js for tests

* AppVeyor test fixes

* Generating the most strict TS code possible

* Not returning null when creating vectors

* Not returning null from struct contructors

* Vector of unions for ts/js

* Sanity check for languages

* Indentation fix + output test files

* Vectors of unions for php

* Fixes to union vector handling + tests
parent 7cc72e4b
...@@ -49,6 +49,7 @@ tests/monsterdata_go_wire.mon ...@@ -49,6 +49,7 @@ tests/monsterdata_go_wire.mon
tests/monsterdata_javascript_wire.mon tests/monsterdata_javascript_wire.mon
tests/unicode_test.mon tests/unicode_test.mon
tests/ts/ tests/ts/
tests/php/
CMakeLists.txt.user CMakeLists.txt.user
CMakeScripts/** CMakeScripts/**
CTestTestfile.cmake CTestTestfile.cmake
......
...@@ -647,6 +647,8 @@ private: ...@@ -647,6 +647,8 @@ private:
const char *suffix, const char *suffix,
BaseType baseType); BaseType baseType);
bool SupportsVectorOfUnions() const;
public: public:
SymbolTable<Type> types_; SymbolTable<Type> types_;
SymbolTable<StructDef> structs_; SymbolTable<StructDef> structs_;
......
...@@ -28,4 +28,14 @@ abstract class Struct ...@@ -28,4 +28,14 @@ abstract class Struct
* @var ByteBuffer $bb * @var ByteBuffer $bb
*/ */
protected $bb; protected $bb;
public function setByteBufferPos($pos)
{
$this->bb_pos = $pos;
}
public function setByteBuffer($bb)
{
$this->bb = $bb;
}
} }
...@@ -32,6 +32,16 @@ abstract class Table ...@@ -32,6 +32,16 @@ abstract class Table
{ {
} }
public function setByteBufferPos($pos)
{
$this->bb_pos = $pos;
}
public function setByteBuffer($bb)
{
$this->bb = $bb;
}
/** /**
* returns actual vtable offset * returns actual vtable offset
* *
...@@ -107,8 +117,8 @@ abstract class Table ...@@ -107,8 +117,8 @@ abstract class Table
protected function __union($table, $offset) protected function __union($table, $offset)
{ {
$offset += $this->bb_pos; $offset += $this->bb_pos;
$table->bb_pos = $offset + $this->bb->getInt($offset); $table->setByteBufferPos($offset + $this->bb->getInt($offset));
$table->bb = $this->bb; $table->setByteBuffer($this->bb);
return $table; return $table;
} }
......
...@@ -289,9 +289,12 @@ void GenEnum(EnumDef &enum_def, std::string *code_ptr, ...@@ -289,9 +289,12 @@ void GenEnum(EnumDef &enum_def, std::string *code_ptr,
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string &exports = *exports_ptr; std::string &exports = *exports_ptr;
GenDocComment(enum_def.doc_comment, code_ptr, "@enum"); GenDocComment(enum_def.doc_comment, code_ptr, "@enum");
std::string ns = GetNameSpace(enum_def);
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += "export namespace " + GetNameSpace(enum_def) + "{\n" + if (!ns.empty()) {
"export enum " + enum_def.name + "{\n"; code += "export namespace " + ns + "{\n";
}
code += "export enum " + enum_def.name + "{\n";
} else { } else {
if (enum_def.defined_namespace->components.empty()) { if (enum_def.defined_namespace->components.empty()) {
code += "var "; code += "var ";
...@@ -329,11 +332,10 @@ void GenEnum(EnumDef &enum_def, std::string *code_ptr, ...@@ -329,11 +332,10 @@ void GenEnum(EnumDef &enum_def, std::string *code_ptr,
} }
} }
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs && !ns.empty()) {
code += "}};\n\n"; code += "}";
} else {
code += "};\n\n";
} }
code += "};\n\n";
} }
static std::string GenType(const Type &type) { static std::string GenType(const Type &type) {
...@@ -554,13 +556,15 @@ void GenStruct(const Parser &parser, StructDef &struct_def, ...@@ -554,13 +556,15 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
std::string &exports = *exports_ptr; std::string &exports = *exports_ptr;
std::string object_name; std::string object_name;
std::string object_namespace = GetNameSpace(struct_def);
// Emit constructor // Emit constructor
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
object_name = struct_def.name; object_name = struct_def.name;
std::string object_namespace = GetNameSpace(struct_def);
GenDocComment(struct_def.doc_comment, code_ptr, "@constructor"); GenDocComment(struct_def.doc_comment, code_ptr, "@constructor");
if (!object_namespace.empty()) {
code += "export namespace " + object_namespace + "{\n"; code += "export namespace " + object_namespace + "{\n";
}
code += "export class " + struct_def.name; code += "export class " + struct_def.name;
code += " {\n"; code += " {\n";
code += " /**\n"; code += " /**\n";
...@@ -754,17 +758,37 @@ void GenStruct(const Parser &parser, StructDef &struct_def, ...@@ -754,17 +758,37 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
auto index = "this.bb.__vector(this.bb_pos + offset) + index" + auto index = "this.bb.__vector(this.bb_pos + offset) + index" +
MaybeScale(inline_size); MaybeScale(inline_size);
std::string args = "@param {number} index\n"; std::string args = "@param {number} index\n";
if (vectortype.base_type == BASE_TYPE_STRUCT) { std::string ret_type;
bool is_union = false;
switch (vectortype.base_type) {
case BASE_TYPE_STRUCT:
args += "@param {" + vectortypename + "=} obj\n"; args += "@param {" + vectortypename + "=} obj\n";
} else if (vectortype.base_type == BASE_TYPE_STRING) { ret_type = vectortypename;
break;
case BASE_TYPE_STRING:
args += "@param {flatbuffers.Encoding=} optionalEncoding\n"; args += "@param {flatbuffers.Encoding=} optionalEncoding\n";
ret_type = vectortypename;
break;
case BASE_TYPE_UNION:
args += "@param {flatbuffers.Table=} obj\n";
ret_type = "?flatbuffers.Table";
is_union = true;
break;
default:
ret_type = vectortypename;
} }
GenDocComment(field.doc_comment, code_ptr, args + GenDocComment(field.doc_comment, code_ptr, args +
"@returns {" + vectortypename + "}"); "@returns {" + ret_type + "}");
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
std::string prefix = MakeCamel(field.name, false); std::string prefix = MakeCamel(field.name, false);
if (is_union) {
prefix += "<T extends flatbuffers.Table>";
}
prefix += "(index: number"; prefix += "(index: number";
if (vectortype.base_type == BASE_TYPE_STRUCT) { if (is_union) {
vectortypename = "T";
code += prefix + ", obj:T";
} else if (vectortype.base_type == BASE_TYPE_STRUCT) {
vectortypename = GenPrefixedTypeName(vectortypename, vectortypename = GenPrefixedTypeName(vectortypename,
vectortype.struct_def->file); vectortype.struct_def->file);
code += prefix + ", obj?:" + vectortypename; code += prefix + ", obj?:" + vectortypename;
...@@ -781,7 +805,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def, ...@@ -781,7 +805,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
} else { } else {
code += object_name + ".prototype." + MakeCamel(field.name, false); code += object_name + ".prototype." + MakeCamel(field.name, false);
code += " = function(index"; code += " = function(index";
if (vectortype.base_type == BASE_TYPE_STRUCT) { if (vectortype.base_type == BASE_TYPE_STRUCT || is_union) {
code += ", obj"; code += ", obj";
} else if (vectortype.base_type == BASE_TYPE_STRING) { } else if (vectortype.base_type == BASE_TYPE_STRING) {
code += ", optionalEncoding"; code += ", optionalEncoding";
...@@ -797,7 +821,9 @@ void GenStruct(const Parser &parser, StructDef &struct_def, ...@@ -797,7 +821,9 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
: "this.bb.__indirect(" + index + ")"; : "this.bb.__indirect(" + index + ")";
code += ", this.bb)"; code += ", this.bb)";
} else { } else {
if (vectortype.base_type == BASE_TYPE_STRING) { if (is_union) {
index = "obj, " + index;
} else if (vectortype.base_type == BASE_TYPE_STRING) {
index += ", optionalEncoding"; index += ", optionalEncoding";
} }
code += offset_prefix + GenGetter(vectortype, "(" + index + ")"); code += offset_prefix + GenGetter(vectortype, "(" + index + ")");
...@@ -1137,7 +1163,10 @@ void GenStruct(const Parser &parser, StructDef &struct_def, ...@@ -1137,7 +1163,10 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
} }
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += "}\n}\n"; if (!object_namespace.empty()) {
code += "}\n";
}
code += "}\n";
} }
} }
}; };
......
...@@ -67,7 +67,10 @@ namespace php { ...@@ -67,7 +67,10 @@ namespace php {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "<?php\n"; code += "<?php\n";
code = code + "// " + FlatBuffersGeneratedWarning() + "\n\n"; code = code + "// " + FlatBuffersGeneratedWarning() + "\n\n";
if (!name_space_name.empty()) {
code += "namespace " + name_space_name + ";\n\n"; code += "namespace " + name_space_name + ";\n\n";
}
if (needs_imports) { if (needs_imports) {
code += "use \\Google\\FlatBuffers\\Struct;\n"; code += "use \\Google\\FlatBuffers\\Struct;\n";
...@@ -428,6 +431,31 @@ namespace php { ...@@ -428,6 +431,31 @@ namespace php {
code += Indent + "}\n\n"; code += Indent + "}\n\n";
} }
// Get the value of a vector's union member. Uses a named return
// argument to conveniently set the zero value for the result.
void GetMemberOfVectorOfUnion(const FieldDef &field,
std::string *code_ptr) {
std::string &code = *code_ptr;
auto vectortype = field.value.type.VectorType();
code += Indent + "/**\n";
code += Indent + " * @param int offset\n";
code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n";
code += Indent + " */\n";
code += Indent + "public function get";
code += MakeCamel(field.name);
code += "($j, $obj)\n";
code += Indent + "{\n";
code += Indent + Indent +
"$o = $this->__offset(" +
NumToString(field.value.offset) +
");\n";
code += Indent + Indent + "return $o != 0 ? ";
code += "$this->__union($obj, $this->__vector($o) + $j * ";
code += NumToString(InlineSize(vectortype)) + " - $this->bb_pos) : null;\n";
code += Indent + "}\n\n";
}
// Recursively generate arguments for a constructor, to deal with nested // Recursively generate arguments for a constructor, to deal with nested
// structs. // structs.
static void StructBuilderArgs(const StructDef &struct_def, static void StructBuilderArgs(const StructDef &struct_def,
...@@ -703,7 +731,9 @@ namespace php { ...@@ -703,7 +731,9 @@ namespace php {
break; break;
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
auto vectortype = field.value.type.VectorType(); auto vectortype = field.value.type.VectorType();
if (vectortype.base_type == BASE_TYPE_STRUCT) { if (vectortype.base_type == BASE_TYPE_UNION) {
GetMemberOfVectorOfUnion(field, code_ptr);
} else if (vectortype.base_type == BASE_TYPE_STRUCT) {
GetMemberOfVectorOfStruct(struct_def, field, code_ptr); GetMemberOfVectorOfStruct(struct_def, field, code_ptr);
} else { } else {
GetMemberOfVectorOfNonStruct(field, code_ptr); GetMemberOfVectorOfNonStruct(field, code_ptr);
......
...@@ -628,8 +628,8 @@ CheckedError Parser::ParseField(StructDef &struct_def) { ...@@ -628,8 +628,8 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
type.enum_def->underlying_type, &typefield)); type.enum_def->underlying_type, &typefield));
} else if (type.base_type == BASE_TYPE_VECTOR && } else if (type.base_type == BASE_TYPE_VECTOR &&
type.element == BASE_TYPE_UNION) { type.element == BASE_TYPE_UNION) {
// Only cpp supports the union vector feature so far. // Only cpp, js and ts supports the union vector feature so far.
if (opts.lang_to_generate != IDLOptions::kCpp) { if (!SupportsVectorOfUnions()) {
return Error("Vectors of unions are not yet supported in all " return Error("Vectors of unions are not yet supported in all "
"the specified programming languages."); "the specified programming languages.");
} }
...@@ -1571,6 +1571,11 @@ CheckedError Parser::CheckClash(std::vector<FieldDef*> &fields, ...@@ -1571,6 +1571,11 @@ CheckedError Parser::CheckClash(std::vector<FieldDef*> &fields,
return NoError(); return NoError();
} }
bool Parser::SupportsVectorOfUnions() const {
return opts.lang_to_generate != 0 && (opts.lang_to_generate &
~(IDLOptions::kCpp | IDLOptions::kJs | IDLOptions::kTs | IDLOptions::kPhp)) == 0;
}
static bool compareFieldDefs(const FieldDef *a, const FieldDef *b) { static bool compareFieldDefs(const FieldDef *a, const FieldDef *b) {
auto a_id = atoi(a->attributes.Lookup("id")->constant.c_str()); auto a_id = atoi(a->attributes.Lookup("id")->constant.c_str());
auto b_id = atoi(b->attributes.Lookup("id")->constant.c_str()); auto b_id = atoi(b->attributes.Lookup("id")->constant.c_str());
...@@ -2141,7 +2146,7 @@ CheckedError Parser::ParseRoot(const char *source, const char **include_paths, ...@@ -2141,7 +2146,7 @@ CheckedError Parser::ParseRoot(const char *source, const char **include_paths,
val_it != enum_def.vals.vec.end(); val_it != enum_def.vals.vec.end();
++val_it) { ++val_it) {
auto &val = **val_it; auto &val = **val_it;
if (opts.lang_to_generate != IDLOptions::kCpp && if (!SupportsVectorOfUnions() &&
val.union_type.struct_def && val.union_type.struct_def->fixed) val.union_type.struct_def && val.union_type.struct_def->fixed)
return Error( return Error(
"only tables can be union elements in the generated language: " "only tables can be union elements in the generated language: "
......
var assert = require('assert');
var flatbuffers = require('../js/flatbuffers').flatbuffers;
var Test = require(process.argv[2]);
function main() {
var fbb = new flatbuffers.Builder();
var charTypes = [
Test.Character.Belle,
Test.Character.MuLan,
Test.Character.BookFan,
];
Test.Attacker.startAttacker(fbb);
Test.Attacker.addSwordAttackDamage(fbb, 5);
var attackerOffset = Test.Attacker.endAttacker(fbb);
var charTypesOffset = Test.Movie.createCharactersTypeVector(fbb, charTypes);
var charsOffset = Test.Movie.createCharactersVector(
fbb,
[
Test.BookReader.createBookReader(fbb, 7),
attackerOffset,
Test.BookReader.createBookReader(fbb, 2),
]
);
Test.Movie.startMovie(fbb);
Test.Movie.addCharactersType(fbb, charTypesOffset);
Test.Movie.addCharacters(fbb, charsOffset);
Test.Movie.finishMovieBuffer(fbb, Test.Movie.endMovie(fbb));
var buf = new flatbuffers.ByteBuffer(fbb.asUint8Array());
var movie = Test.Movie.getRootAsMovie(buf);
assert.strictEqual(movie.charactersTypeLength(), charTypes.length);
assert.strictEqual(movie.charactersLength(), movie.charactersTypeLength());
for (var i = 0; i < charTypes.length; ++i) {
assert.strictEqual(movie.charactersType(i), charTypes[i]);
}
var bookReader7 = movie.characters(0, new Test.BookReader());
assert.strictEqual(bookReader7.booksRead(), 7);
var attacker = movie.characters(1, new Test.Attacker());
assert.strictEqual(attacker.swordAttackDamage(), 5);
var bookReader2 = movie.characters(2, new Test.BookReader());
assert.strictEqual(bookReader2.booksRead(), 2);
console.log('FlatBuffers union vector test: completed successfully');
}
main();
...@@ -13,6 +13,7 @@ sh PythonTest.sh ...@@ -13,6 +13,7 @@ sh PythonTest.sh
echo "************************ JavaScript:" echo "************************ JavaScript:"
sh JavaScriptTest.sh sh JavaScriptTest.sh
sh JavaScriptUnionVectorTest.sh
echo "************************ TypeScript:" echo "************************ TypeScript:"
...@@ -33,6 +34,7 @@ cd .. ...@@ -33,6 +34,7 @@ cd ..
echo "************************ PHP:" echo "************************ PHP:"
php phpTest.php php phpTest.php
sh phpUnionVectorTest.sh
echo "************************ C:" echo "************************ C:"
......
...@@ -15,9 +15,19 @@ ...@@ -15,9 +15,19 @@
# limitations under the License. # limitations under the License.
pushd "$(dirname $0)" >/dev/null pushd "$(dirname $0)" >/dev/null
npm install @types/flatbuffers
../flatc --ts --no-fb-import --gen-mutable -o ts -I include_test monster_test.fbs ../flatc --ts --no-fb-import --gen-mutable -o ts -I include_test monster_test.fbs
../flatc -b -I include_test monster_test.fbs unicode_test.json ../flatc -b -I include_test monster_test.fbs unicode_test.json
npm install @types/flatbuffers
tsc --strict --noUnusedParameters --noUnusedLocals --noImplicitReturns --strictNullChecks ts/monster_test_generated.ts tsc --strict --noUnusedParameters --noUnusedLocals --noImplicitReturns --strictNullChecks ts/monster_test_generated.ts
npm uninstall @types/flatbuffers
node JavaScriptTest ./ts/monster_test_generated node JavaScriptTest ./ts/monster_test_generated
../flatc --ts --js --no-fb-import -o ts union_vector/union_vector.fbs
# test JS version first, then transpile and rerun for TS
node JavaScriptUnionVectorTest ./ts/union_vector_generated
tsc --strict --noUnusedParameters --noUnusedLocals --noImplicitReturns --strictNullChecks ts/union_vector_generated.ts
node JavaScriptUnionVectorTest ./ts/union_vector_generated
npm uninstall @types/flatbuffers
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
../flatc --cpp --java --csharp --go --binary --python --js --ts --php --grpc --gen-mutable --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json ../flatc --cpp --java --csharp --go --binary --python --js --ts --php --grpc --gen-mutable --gen-object-api --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
../flatc --cpp --java --csharp --go --binary --python --js --ts --php --gen-mutable --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs ../flatc --cpp --java --csharp --go --binary --python --js --ts --php --gen-mutable --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
../flatc --cpp --gen-mutable --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs ../flatc --cpp --js --ts --php --gen-mutable --gen-object-api --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
../flatc -b --schema --bfbs-comments -I include_test monster_test.fbs ../flatc -b --schema --bfbs-comments -I include_test monster_test.fbs
../flatc --jsonschema --schema -I include_test monster_test.fbs ../flatc --jsonschema --schema -I include_test monster_test.fbs
cd ../samples cd ../samples
......
<?php
require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Constants.php"));
require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "ByteBuffer.php"));
require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "FlatbufferBuilder.php"));
require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Table.php"));
require join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)), "php", "Struct.php"));
require join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "php", 'Attacker.php'));
require join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "php", 'BookReader.php'));
require join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "php", 'Character.php'));
require join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "php", 'Movie.php'));
class Assert {
public function ok($result, $message = "") {
if (!$result){
throw new Exception(!empty($message) ? $message : "{$result} is not true.");
}
}
public function Equal($result, $expected, $message = "") {
if ($result != $expected) {
throw new Exception(!empty($message) ? $message : "given the result {$result} is not equals as {$expected}");
}
}
public function strictEqual($result, $expected, $message = "") {
if ($result !== $expected) {
throw new Exception(!empty($message) ? $message : "given the result {$result} is not strict equals as {$expected}");
}
}
public function Throws($class, Callable $callback) {
try {
$callback();
throw new \Exception("passed statement don't throw an exception.");
} catch (\Exception $e) {
if (get_class($e) != get_class($class)) {
throw new Exception("passed statement doesn't throw " . get_class($class) . ". throwws " . get_class($e));
}
}
}
}
function main()
{
$assert = new Assert();
$fbb = new Google\FlatBuffers\FlatBufferBuilder(1);
$charTypes = [
Character::Belle,
Character::MuLan,
Character::BookFan,
];
Attacker::startAttacker($fbb);
Attacker::addSwordAttackDamage($fbb, 5);
$attackerOffset = Attacker::endAttacker($fbb);
$charTypesOffset = Movie::createCharactersTypeVector($fbb, $charTypes);
$charsOffset = Movie::createCharactersVector(
$fbb,
[
BookReader::createBookReader($fbb, 7),
$attackerOffset,
BookReader::createBookReader($fbb, 2),
]
);
Movie::startMovie($fbb);
Movie::addCharactersType($fbb, $charTypesOffset);
Movie::addCharacters($fbb, $charsOffset);
Movie::finishMovieBuffer($fbb, Movie::endMovie($fbb));
$buf = Google\FlatBuffers\ByteBuffer::wrap($fbb->dataBuffer()->data());
$movie = Movie::getRootAsMovie($buf);
$assert->strictEqual($movie->getCharactersTypeLength(), count($charTypes));
$assert->strictEqual($movie->getCharactersLength(), $movie->getCharactersTypeLength());
for ($i = 0; $i < count($charTypes); ++$i) {
$assert->strictEqual($movie->getCharactersType($i), $charTypes[$i]);
}
$bookReader7 = $movie->getCharacters(0, new BookReader());
$assert->strictEqual($bookReader7->getBooksRead(), 7);
$attacker = $movie->getCharacters(1, new Attacker());
$assert->strictEqual($attacker->getSwordAttackDamage(), 5);
$bookReader2 = $movie->getCharacters(2, new BookReader());
$assert->strictEqual($bookReader2->getBooksRead(), 2);
}
try {
main();
exit(0);
} catch(Exception $e) {
printf("Fatal error: Uncaught exception '%s' with message '%s. in %s:%d\n", get_class($e), $e->getMessage(), $e->getFile(), $e->getLine());
printf("Stack trace:\n");
echo $e->getTraceAsString() . PHP_EOL;
printf(" thrown in in %s:%d\n", $e->getFile(), $e->getLine());
die(-1);
}
#!/bin/bash
set -e
../flatc --php -o php union_vector/union_vector.fbs
php phpUnionVectorTest.php
echo 'PHP union vector test passed'
<?php
// automatically generated by the FlatBuffers compiler, do not modify
namespace ;
use \Google\FlatBuffers\Struct;
use \Google\FlatBuffers\Table;
use \Google\FlatBuffers\ByteBuffer;
use \Google\FlatBuffers\FlatBufferBuilder;
class Attacker extends Table
{
/**
* @param ByteBuffer $bb
* @return Attacker
*/
public static function getRootAsAttacker(ByteBuffer $bb)
{
$obj = new Attacker();
return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
}
public static function AttackerIdentifier()
{
return "MOVI";
}
public static function AttackerBufferHasIdentifier(ByteBuffer $buf)
{
return self::__has_identifier($buf, self::AttackerIdentifier());
}
/**
* @param int $_i offset
* @param ByteBuffer $_bb
* @return Attacker
**/
public function init($_i, ByteBuffer $_bb)
{
$this->bb_pos = $_i;
$this->bb = $_bb;
return $this;
}
/**
* @return int
*/
public function getSwordAttackDamage()
{
$o = $this->__offset(4);
return $o != 0 ? $this->bb->getInt($o + $this->bb_pos) : 0;
}
/**
* @param FlatBufferBuilder $builder
* @return void
*/
public static function startAttacker(FlatBufferBuilder $builder)
{
$builder->StartObject(1);
}
/**
* @param FlatBufferBuilder $builder
* @return Attacker
*/
public static function createAttacker(FlatBufferBuilder $builder, $sword_attack_damage)
{
$builder->startObject(1);
self::addSwordAttackDamage($builder, $sword_attack_damage);
$o = $builder->endObject();
return $o;
}
/**
* @param FlatBufferBuilder $builder
* @param int
* @return void
*/
public static function addSwordAttackDamage(FlatBufferBuilder $builder, $swordAttackDamage)
{
$builder->addIntX(0, $swordAttackDamage, 0);
}
/**
* @param FlatBufferBuilder $builder
* @return int table offset
*/
public static function endAttacker(FlatBufferBuilder $builder)
{
$o = $builder->endObject();
return $o;
}
}
<?php
// automatically generated by the FlatBuffers compiler, do not modify
namespace ;
use \Google\FlatBuffers\Struct;
use \Google\FlatBuffers\Table;
use \Google\FlatBuffers\ByteBuffer;
use \Google\FlatBuffers\FlatBufferBuilder;
class BookReader extends Struct
{
/**
* @param int $_i offset
* @param ByteBuffer $_bb
* @return BookReader
**/
public function init($_i, ByteBuffer $_bb)
{
$this->bb_pos = $_i;
$this->bb = $_bb;
return $this;
}
/**
* @return int
*/
public function GetBooksRead()
{
return $this->bb->getInt($this->bb_pos + 0);
}
/**
* @return int offset
*/
public static function createBookReader(FlatBufferBuilder $builder, $booksRead)
{
$builder->prep(4, 4);
$builder->putInt($booksRead);
return $builder->offset();
}
}
<?php
// automatically generated by the FlatBuffers compiler, do not modify
namespace ;
class Character
{
const NONE = 0;
const MuLan = 1;
const Rapunzel = 2;
const Belle = 3;
const BookFan = 4;
const Other = 5;
const Unused = 6;
private static $names = array(
"NONE",
"MuLan",
"Rapunzel",
"Belle",
"BookFan",
"Other",
"Unused",
);
public static function Name($e)
{
if (!isset(self::$names[$e])) {
throw new \Exception();
}
return self::$names[$e];
}
}
<?php
// automatically generated by the FlatBuffers compiler, do not modify
namespace ;
use \Google\FlatBuffers\Struct;
use \Google\FlatBuffers\Table;
use \Google\FlatBuffers\ByteBuffer;
use \Google\FlatBuffers\FlatBufferBuilder;
class Movie extends Table
{
/**
* @param ByteBuffer $bb
* @return Movie
*/
public static function getRootAsMovie(ByteBuffer $bb)
{
$obj = new Movie();
return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
}
public static function MovieIdentifier()
{
return "MOVI";
}
public static function MovieBufferHasIdentifier(ByteBuffer $buf)
{
return self::__has_identifier($buf, self::MovieIdentifier());
}
/**
* @param int $_i offset
* @param ByteBuffer $_bb
* @return Movie
**/
public function init($_i, ByteBuffer $_bb)
{
$this->bb_pos = $_i;
$this->bb = $_bb;
return $this;
}
/**
* @return byte
*/
public function getMainCharacterType()
{
$o = $this->__offset(4);
return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \Character::NONE;
}
/**
* @returnint
*/
public function getMainCharacter($obj)
{
$o = $this->__offset(6);
return $o != 0 ? $this->__union($obj, $o) : null;
}
/**
* @param int offset
* @return byte
*/
public function getCharactersType($j)
{
$o = $this->__offset(8);
return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : \Character::NONE;
}
/**
* @return int
*/
public function getCharactersTypeLength()
{
$o = $this->__offset(8);
return $o != 0 ? $this->__vector_len($o) : 0;
}
/**
* @param int offset
* @return Table
*/
public function getCharacters($j, $obj)
{
$o = $this->__offset(10);
return $o != 0 ? $this->__union($obj, $this->__vector($o) + $j * 4 - $this->bb_pos) : null;
}
/**
* @return int
*/
public function getCharactersLength()
{
$o = $this->__offset(10);
return $o != 0 ? $this->__vector_len($o) : 0;
}
/**
* @param FlatBufferBuilder $builder
* @return void
*/
public static function startMovie(FlatBufferBuilder $builder)
{
$builder->StartObject(4);
}
/**
* @param FlatBufferBuilder $builder
* @return Movie
*/
public static function createMovie(FlatBufferBuilder $builder, $main_character_type, $main_character, $characters_type, $characters)
{
$builder->startObject(4);
self::addMainCharacterType($builder, $main_character_type);
self::addMainCharacter($builder, $main_character);
self::addCharactersType($builder, $characters_type);
self::addCharacters($builder, $characters);
$o = $builder->endObject();
return $o;
}
/**
* @param FlatBufferBuilder $builder
* @param byte
* @return void
*/
public static function addMainCharacterType(FlatBufferBuilder $builder, $mainCharacterType)
{
$builder->addByteX(0, $mainCharacterType, 0);
}
public static function addMainCharacter(FlatBufferBuilder $builder, $offset)
{
$builder->addOffsetX(1, $offset, 0);
}
/**
* @param FlatBufferBuilder $builder
* @param VectorOffset
* @return void
*/
public static function addCharactersType(FlatBufferBuilder $builder, $charactersType)
{
$builder->addOffsetX(2, $charactersType, 0);
}
/**
* @param FlatBufferBuilder $builder
* @param array offset array
* @return int vector offset
*/
public static function createCharactersTypeVector(FlatBufferBuilder $builder, array $data)
{
$builder->startVector(1, count($data), 1);
for ($i = count($data) - 1; $i >= 0; $i--) {
$builder->addByte($data[$i]);
}
return $builder->endVector();
}
/**
* @param FlatBufferBuilder $builder
* @param int $numElems
* @return void
*/
public static function startCharactersTypeVector(FlatBufferBuilder $builder, $numElems)
{
$builder->startVector(1, $numElems, 1);
}
/**
* @param FlatBufferBuilder $builder
* @param VectorOffset
* @return void
*/
public static function addCharacters(FlatBufferBuilder $builder, $characters)
{
$builder->addOffsetX(3, $characters, 0);
}
/**
* @param FlatBufferBuilder $builder
* @param array offset array
* @return int vector offset
*/
public static function createCharactersVector(FlatBufferBuilder $builder, array $data)
{
$builder->startVector(4, count($data), 4);
for ($i = count($data) - 1; $i >= 0; $i--) {
$builder->addOffset($data[$i]);
}
return $builder->endVector();
}
/**
* @param FlatBufferBuilder $builder
* @param int $numElems
* @return void
*/
public static function startCharactersVector(FlatBufferBuilder $builder, $numElems)
{
$builder->startVector(4, $numElems, 4);
}
/**
* @param FlatBufferBuilder $builder
* @return int table offset
*/
public static function endMovie(FlatBufferBuilder $builder)
{
$o = $builder->endObject();
return $o;
}
public static function finishMovieBuffer(FlatBufferBuilder $builder, $offset)
{
$builder->finish($offset, "MOVI");
}
}
<?php
// automatically generated by the FlatBuffers compiler, do not modify
namespace ;
use \Google\FlatBuffers\Struct;
use \Google\FlatBuffers\Table;
use \Google\FlatBuffers\ByteBuffer;
use \Google\FlatBuffers\FlatBufferBuilder;
class Rapunzel extends Struct
{
/**
* @param int $_i offset
* @param ByteBuffer $_bb
* @return Rapunzel
**/
public function init($_i, ByteBuffer $_bb)
{
$this->bb_pos = $_i;
$this->bb = $_bb;
return $this;
}
/**
* @return int
*/
public function GetHairLength()
{
return $this->bb->getInt($this->bb_pos + 0);
}
/**
* @return int offset
*/
public static function createRapunzel(FlatBufferBuilder $builder, $hairLength)
{
$builder->prep(4, 4);
$builder->putInt($hairLength);
return $builder->offset();
}
}
// automatically generated by the FlatBuffers compiler, do not modify
/**
* @enum
*/
var Character = {
NONE: 0,
MuLan: 1,
Rapunzel: 2,
Belle: 3,
BookFan: 4,
Other: 5,
Unused: 6
};
/**
* @constructor
*/
function Attacker() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
}
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {Attacker}
*/
Attacker.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {Attacker=} obj
* @returns {Attacker}
*/
Attacker.getRootAsAttacker = function(bb, obj) {
return (obj || new Attacker).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @returns {number}
*/
Attacker.prototype.swordAttackDamage = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
};
/**
* @param {number} value
* @returns {boolean}
*/
Attacker.prototype.mutate_sword_attack_damage = function(value) {
var offset = this.bb.__offset(this.bb_pos, 4);
if (offset === 0) {
return false;
}
this.bb.writeInt32(this.bb_pos + offset, value);
return true;
};
/**
* @param {flatbuffers.Builder} builder
*/
Attacker.startAttacker = function(builder) {
builder.startObject(1);
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} swordAttackDamage
*/
Attacker.addSwordAttackDamage = function(builder, swordAttackDamage) {
builder.addFieldInt32(0, swordAttackDamage, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
Attacker.endAttacker = function(builder) {
var offset = builder.endObject();
return offset;
};
/**
* @constructor
*/
function Rapunzel() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
}
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {Rapunzel}
*/
Rapunzel.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @returns {number}
*/
Rapunzel.prototype.hairLength = function() {
return this.bb.readInt32(this.bb_pos);
};
/**
* @param {number} value
* @returns {boolean}
*/
Rapunzel.prototype.mutate_hair_length = function(value) {
var offset = this.bb.__offset(this.bb_pos, 0);
if (offset === 0) {
return false;
}
this.bb.writeInt32(this.bb_pos + offset, value);
return true;
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} hair_length
* @returns {flatbuffers.Offset}
*/
Rapunzel.createRapunzel = function(builder, hair_length) {
builder.prep(4, 4);
builder.writeInt32(hair_length);
return builder.offset();
};
/**
* @constructor
*/
function BookReader() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
}
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {BookReader}
*/
BookReader.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @returns {number}
*/
BookReader.prototype.booksRead = function() {
return this.bb.readInt32(this.bb_pos);
};
/**
* @param {number} value
* @returns {boolean}
*/
BookReader.prototype.mutate_books_read = function(value) {
var offset = this.bb.__offset(this.bb_pos, 0);
if (offset === 0) {
return false;
}
this.bb.writeInt32(this.bb_pos + offset, value);
return true;
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} books_read
* @returns {flatbuffers.Offset}
*/
BookReader.createBookReader = function(builder, books_read) {
builder.prep(4, 4);
builder.writeInt32(books_read);
return builder.offset();
};
/**
* @constructor
*/
function Movie() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
}
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {Movie}
*/
Movie.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {Movie=} obj
* @returns {Movie}
*/
Movie.getRootAsMovie = function(bb, obj) {
return (obj || new Movie).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @returns {boolean}
*/
Movie.bufferHasIdentifier = function(bb) {
return bb.__has_identifier('MOVI');
};
/**
* @returns {Character}
*/
Movie.prototype.mainCharacterType = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? /** @type {Character} */ (this.bb.readUint8(this.bb_pos + offset)) : Character.NONE;
};
/**
* @param {Character} value
* @returns {boolean}
*/
Movie.prototype.mutate_main_character_type = function(value) {
var offset = this.bb.__offset(this.bb_pos, 4);
if (offset === 0) {
return false;
}
this.bb.writeUint8(this.bb_pos + offset, value);
return true;
};
/**
* @param {flatbuffers.Table} obj
* @returns {?flatbuffers.Table}
*/
Movie.prototype.mainCharacter = function(obj) {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__union(obj, this.bb_pos + offset) : null;
};
/**
* @param {number} index
* @returns {Character}
*/
Movie.prototype.charactersType = function(index) {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? /** @type {Character} */ (this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index)) : /** @type {Character} */ (0);
};
/**
* @returns {number}
*/
Movie.prototype.charactersTypeLength = function() {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @returns {Uint8Array}
*/
Movie.prototype.charactersTypeArray = function() {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
};
/**
* @param {number} index
* @param {flatbuffers.Table=} obj
* @returns {?flatbuffers.Table}
*/
Movie.prototype.characters = function(index) {
var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.__union(obj, this.bb.__vector(this.bb_pos + offset) + index * 4) : null;
};
/**
* @returns {number}
*/
Movie.prototype.charactersLength = function() {
var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {flatbuffers.Builder} builder
*/
Movie.startMovie = function(builder) {
builder.startObject(4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Character} mainCharacterType
*/
Movie.addMainCharacterType = function(builder, mainCharacterType) {
builder.addFieldInt8(0, mainCharacterType, Character.NONE);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} mainCharacterOffset
*/
Movie.addMainCharacter = function(builder, mainCharacterOffset) {
builder.addFieldOffset(1, mainCharacterOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} charactersTypeOffset
*/
Movie.addCharactersType = function(builder, charactersTypeOffset) {
builder.addFieldOffset(2, charactersTypeOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<Character>} data
* @returns {flatbuffers.Offset}
*/
Movie.createCharactersTypeVector = function(builder, data) {
builder.startVector(1, data.length, 1);
for (var i = data.length - 1; i >= 0; i--) {
builder.addInt8(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
Movie.startCharactersTypeVector = function(builder, numElems) {
builder.startVector(1, numElems, 1);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} charactersOffset
*/
Movie.addCharacters = function(builder, charactersOffset) {
builder.addFieldOffset(3, charactersOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Offset>} data
* @returns {flatbuffers.Offset}
*/
Movie.createCharactersVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
Movie.startCharactersVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
Movie.endMovie = function(builder) {
var offset = builder.endObject();
return offset;
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} offset
*/
Movie.finishMovieBuffer = function(builder, offset) {
builder.finish(offset, 'MOVI');
};
// Exports for Node.js and RequireJS
this.Character = Character;
this.Attacker = Attacker;
this.Rapunzel = Rapunzel;
this.BookReader = BookReader;
this.Movie = Movie;
// automatically generated by the FlatBuffers compiler, do not modify
/**
* @enum
*/
export namespace {
export enum Character{
NONE= 0,
MuLan= 1,
Rapunzel= 2,
Belle= 3,
BookFan= 4,
Other= 5,
Unused= 6
}};
/**
* @constructor
*/
export namespace {
export class Attacker {
/**
* @type {flatbuffers.ByteBuffer}
*/
bb: flatbuffers.ByteBuffer;
/**
* @type {number}
*/
bb_pos:number = 0;
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {Attacker}
*/
__init(i:number, bb:flatbuffers.ByteBuffer):Attacker {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {Attacker=} obj
* @returns {Attacker}
*/
static getRootAsAttacker(bb:flatbuffers.ByteBuffer, obj?:Attacker):Attacker {
return (obj || new Attacker).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @returns {number}
*/
swordAttackDamage():number {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
};
/**
* @param {number} value
* @returns {boolean}
*/
mutate_sword_attack_damage(value:number):boolean {
var offset = this.bb.__offset(this.bb_pos, 4);
if (offset === 0) {
return false;
}
this.bb.writeInt32(this.bb_pos + offset, value);
return true;
};
/**
* @param {flatbuffers.Builder} builder
*/
static startAttacker(builder:flatbuffers.Builder) {
builder.startObject(1);
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} swordAttackDamage
*/
static addSwordAttackDamage(builder:flatbuffers.Builder, swordAttackDamage:number) {
builder.addFieldInt32(0, swordAttackDamage, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
static endAttacker(builder:flatbuffers.Builder):flatbuffers.Offset {
var offset = builder.endObject();
return offset;
};
}
}
/**
* @constructor
*/
export namespace {
export class Rapunzel {
/**
* @type {flatbuffers.ByteBuffer}
*/
bb: flatbuffers.ByteBuffer;
/**
* @type {number}
*/
bb_pos:number = 0;
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {Rapunzel}
*/
__init(i:number, bb:flatbuffers.ByteBuffer):Rapunzel {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @returns {number}
*/
hairLength():number {
return this.bb.readInt32(this.bb_pos);
};
/**
* @param {number} value
* @returns {boolean}
*/
mutate_hair_length(value:number):boolean {
var offset = this.bb.__offset(this.bb_pos, 0);
if (offset === 0) {
return false;
}
this.bb.writeInt32(this.bb_pos + offset, value);
return true;
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} hair_length
* @returns {flatbuffers.Offset}
*/
static createRapunzel(builder:flatbuffers.Builder, hair_length: number):flatbuffers.Offset {
builder.prep(4, 4);
builder.writeInt32(hair_length);
return builder.offset();
};
}
}
/**
* @constructor
*/
export namespace {
export class BookReader {
/**
* @type {flatbuffers.ByteBuffer}
*/
bb: flatbuffers.ByteBuffer;
/**
* @type {number}
*/
bb_pos:number = 0;
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {BookReader}
*/
__init(i:number, bb:flatbuffers.ByteBuffer):BookReader {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @returns {number}
*/
booksRead():number {
return this.bb.readInt32(this.bb_pos);
};
/**
* @param {number} value
* @returns {boolean}
*/
mutate_books_read(value:number):boolean {
var offset = this.bb.__offset(this.bb_pos, 0);
if (offset === 0) {
return false;
}
this.bb.writeInt32(this.bb_pos + offset, value);
return true;
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} books_read
* @returns {flatbuffers.Offset}
*/
static createBookReader(builder:flatbuffers.Builder, books_read: number):flatbuffers.Offset {
builder.prep(4, 4);
builder.writeInt32(books_read);
return builder.offset();
};
}
}
/**
* @constructor
*/
export namespace {
export class Movie {
/**
* @type {flatbuffers.ByteBuffer}
*/
bb: flatbuffers.ByteBuffer;
/**
* @type {number}
*/
bb_pos:number = 0;
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {Movie}
*/
__init(i:number, bb:flatbuffers.ByteBuffer):Movie {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {Movie=} obj
* @returns {Movie}
*/
static getRootAsMovie(bb:flatbuffers.ByteBuffer, obj?:Movie):Movie {
return (obj || new Movie).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @returns {boolean}
*/
static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean {
return bb.__has_identifier('MOVI');
};
/**
* @returns {Character}
*/
mainCharacterType():Character {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? /** @type {Character} */ (this.bb.readUint8(this.bb_pos + offset)) : Character.NONE;
};
/**
* @param {Character} value
* @returns {boolean}
*/
mutate_main_character_type(value:Character):boolean {
var offset = this.bb.__offset(this.bb_pos, 4);
if (offset === 0) {
return false;
}
this.bb.writeUint8(this.bb_pos + offset, value);
return true;
};
/**
* @param {flatbuffers.Table} obj
* @returns {?flatbuffers.Table}
*/
mainCharacter<T extends flatbuffers.Table>(obj:T):T|null {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__union(obj, this.bb_pos + offset) : null;
};
/**
* @param {number} index
* @returns {Character}
*/
charactersType(index: number):Character|null {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? /** @type {Character} */ (this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index)) : /** @type {Character} */ (0);
};
/**
* @returns {number}
*/
charactersTypeLength():number {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @returns {Uint8Array}
*/
charactersTypeArray():Uint8Array|null {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
};
/**
* @param {number} index
* @param {flatbuffers.Table=} obj
* @returns {?flatbuffers.Table}
*/
characters<T extends flatbuffers.Table>(index: number, obj:T):T|null {
var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.__union(obj, this.bb.__vector(this.bb_pos + offset) + index * 4) : null;
};
/**
* @returns {number}
*/
charactersLength():number {
var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {flatbuffers.Builder} builder
*/
static startMovie(builder:flatbuffers.Builder) {
builder.startObject(4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Character} mainCharacterType
*/
static addMainCharacterType(builder:flatbuffers.Builder, mainCharacterType:Character) {
builder.addFieldInt8(0, mainCharacterType, Character.NONE);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} mainCharacterOffset
*/
static addMainCharacter(builder:flatbuffers.Builder, mainCharacterOffset:flatbuffers.Offset) {
builder.addFieldOffset(1, mainCharacterOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} charactersTypeOffset
*/
static addCharactersType(builder:flatbuffers.Builder, charactersTypeOffset:flatbuffers.Offset) {
builder.addFieldOffset(2, charactersTypeOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<Character>} data
* @returns {flatbuffers.Offset}
*/
static createCharactersTypeVector(builder:flatbuffers.Builder, data:Character[]):flatbuffers.Offset {
builder.startVector(1, data.length, 1);
for (var i = data.length - 1; i >= 0; i--) {
builder.addInt8(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
static startCharactersTypeVector(builder:flatbuffers.Builder, numElems:number) {
builder.startVector(1, numElems, 1);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} charactersOffset
*/
static addCharacters(builder:flatbuffers.Builder, charactersOffset:flatbuffers.Offset) {
builder.addFieldOffset(3, charactersOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Offset>} data
* @returns {flatbuffers.Offset}
*/
static createCharactersVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
static startCharactersVector(builder:flatbuffers.Builder, numElems:number) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
static endMovie(builder:flatbuffers.Builder):flatbuffers.Offset {
var offset = builder.endObject();
return offset;
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} offset
*/
static finishMovieBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
builder.finish(offset, 'MOVI');
};
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment