[Python/JS/TS] Codegen SizeOf method for structs (#6136)
* [Python] Codegen SizeOf classmethod for structs
This codegens a `SizeOf()` classmethod for all structs since we can't
determine the size of a FlatBuffer generated struct from Python otherwise.
* [JS/TS] Codegen sizeOf static method for structs
This codegens a `sizeOf()` static method for all structs since we can't
determine the size of a FlatBuffer generated struct from JavaScript or
TypeScript otherwise.
diff --git a/src/idl_gen_js_ts.cpp b/src/idl_gen_js_ts.cpp
index 8be06df..02b85bd 100644
--- a/src/idl_gen_js_ts.cpp
+++ b/src/idl_gen_js_ts.cpp
@@ -1795,6 +1795,18 @@
code += "}\n\n";
}
+ // Emit the size of the struct.
+ if (struct_def.fixed) {
+ GenDocComment(code_ptr, GenTypeAnnotation(kReturns, "number", "", false));
+ if (lang_.language == IDLOptions::kTs) {
+ code += "static sizeOf():number {\n";
+ } else {
+ code += object_name + ".sizeOf = function() {\n";
+ }
+ code += " return " + NumToString(struct_def.bytesize) + ";\n";
+ code += "}\n\n";
+ }
+
// Emit a factory constructor
if (struct_def.fixed) {
std::string annotations =
diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp
index c64357e..95b4490 100644
--- a/src/idl_gen_python.cpp
+++ b/src/idl_gen_python.cpp
@@ -621,6 +621,16 @@
}
}
+ // Generate struct sizeof.
+ void GenStructSizeOf(const StructDef &struct_def, std::string *code_ptr) {
+ auto &code = *code_ptr;
+ code += Indent + "@classmethod\n";
+ code += Indent + "def SizeOf(cls):\n";
+ code +=
+ Indent + Indent + "return " + NumToString(struct_def.bytesize) + "\n";
+ code += "\n";
+ }
+
// Generate table constructors, conditioned on its members' types.
void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
GetStartOfTable(struct_def, code_ptr);
@@ -678,6 +688,9 @@
// Generate a special function to test file_identifier
GenHasFileIdentifier(struct_def, code_ptr);
}
+ } else {
+ // Generates the SizeOf method for all structs.
+ GenStructSizeOf(struct_def, code_ptr);
}
// Generates the Init method that sets the field in a pre-existing
// accessor object. This is to allow object reuse.
diff --git a/tests/MyGame/Example/Ability.py b/tests/MyGame/Example/Ability.py
index 2cc916b..e57dfd7 100644
--- a/tests/MyGame/Example/Ability.py
+++ b/tests/MyGame/Example/Ability.py
@@ -9,6 +9,10 @@
class Ability(object):
__slots__ = ['_tab']
+ @classmethod
+ def SizeOf(cls):
+ return 8
+
# Ability
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
diff --git a/tests/MyGame/Example/ArrayStruct.py b/tests/MyGame/Example/ArrayStruct.py
index 50f136d..c80bf68 100644
--- a/tests/MyGame/Example/ArrayStruct.py
+++ b/tests/MyGame/Example/ArrayStruct.py
@@ -9,6 +9,10 @@
class ArrayStruct(object):
__slots__ = ['_tab']
+ @classmethod
+ def SizeOf(cls):
+ return 160
+
# ArrayStruct
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
diff --git a/tests/MyGame/Example/NestedStruct.py b/tests/MyGame/Example/NestedStruct.py
index a66cee0..a9db014 100644
--- a/tests/MyGame/Example/NestedStruct.py
+++ b/tests/MyGame/Example/NestedStruct.py
@@ -9,6 +9,10 @@
class NestedStruct(object):
__slots__ = ['_tab']
+ @classmethod
+ def SizeOf(cls):
+ return 32
+
# NestedStruct
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
diff --git a/tests/MyGame/Example/Test.py b/tests/MyGame/Example/Test.py
index 576a656..8357ec2 100644
--- a/tests/MyGame/Example/Test.py
+++ b/tests/MyGame/Example/Test.py
@@ -9,6 +9,10 @@
class Test(object):
__slots__ = ['_tab']
+ @classmethod
+ def SizeOf(cls):
+ return 4
+
# Test
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
diff --git a/tests/MyGame/Example/Vec3.py b/tests/MyGame/Example/Vec3.py
index 5c91a7d..69cd511 100644
--- a/tests/MyGame/Example/Vec3.py
+++ b/tests/MyGame/Example/Vec3.py
@@ -9,6 +9,10 @@
class Vec3(object):
__slots__ = ['_tab']
+ @classmethod
+ def SizeOf(cls):
+ return 32
+
# Vec3
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
diff --git a/tests/monster_test_generated.js b/tests/monster_test_generated.js
index fedc2c0..bab8547 100644
--- a/tests/monster_test_generated.js
+++ b/tests/monster_test_generated.js
@@ -343,6 +343,13 @@
};
/**
+ * @returns {number}
+ */
+MyGame.Example.Test.sizeOf = function() {
+ return 4;
+}
+
+/**
* @param {flatbuffers.Builder} builder
* @param {number} a
* @param {number} b
@@ -574,6 +581,13 @@
};
/**
+ * @returns {number}
+ */
+MyGame.Example.Vec3.sizeOf = function() {
+ return 32;
+}
+
+/**
* @param {flatbuffers.Builder} builder
* @param {number} x
* @param {number} y
@@ -660,6 +674,13 @@
};
/**
+ * @returns {number}
+ */
+MyGame.Example.Ability.sizeOf = function() {
+ return 8;
+}
+
+/**
* @param {flatbuffers.Builder} builder
* @param {number} id
* @param {number} distance
diff --git a/tests/monster_test_generated.ts b/tests/monster_test_generated.ts
index afdaeab..9ba7254 100644
--- a/tests/monster_test_generated.ts
+++ b/tests/monster_test_generated.ts
@@ -377,6 +377,13 @@
};
/**
+ * @returns number
+ */
+static sizeOf():number {
+ return 4;
+}
+
+/**
* @param flatbuffers.Builder builder
* @param number a
* @param number b
@@ -669,6 +676,13 @@
};
/**
+ * @returns number
+ */
+static sizeOf():number {
+ return 32;
+}
+
+/**
* @param flatbuffers.Builder builder
* @param number x
* @param number y
@@ -812,6 +826,13 @@
};
/**
+ * @returns number
+ */
+static sizeOf():number {
+ return 8;
+}
+
+/**
* @param flatbuffers.Builder builder
* @param number id
* @param number distance
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py
index 9df52bd..f49495b 100644
--- a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py
+++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py
@@ -9,6 +9,10 @@
class StructInNestedNS(object):
__slots__ = ['_tab']
+ @classmethod
+ def SizeOf(cls):
+ return 8
+
# StructInNestedNS
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
diff --git a/tests/namespace_test/namespace_test1_generated.js b/tests/namespace_test/namespace_test1_generated.js
index fe1c0a7..7331f64 100644
--- a/tests/namespace_test/namespace_test1_generated.js
+++ b/tests/namespace_test/namespace_test1_generated.js
@@ -206,6 +206,13 @@
}
/**
+ * @returns {number}
+ */
+NamespaceA.NamespaceB.StructInNestedNS.sizeOf = function() {
+ return 8;
+}
+
+/**
* @param {flatbuffers.Builder} builder
* @param {number} a
* @param {number} b
diff --git a/tests/namespace_test/namespace_test1_generated.ts b/tests/namespace_test/namespace_test1_generated.ts
index 47f8942..933a43d 100644
--- a/tests/namespace_test/namespace_test1_generated.ts
+++ b/tests/namespace_test/namespace_test1_generated.ts
@@ -205,6 +205,13 @@
}
/**
+ * @returns number
+ */
+static sizeOf():number {
+ return 8;
+}
+
+/**
* @param flatbuffers.Builder builder
* @param number a
* @param number b
diff --git a/tests/union_vector/union_vector_generated.js b/tests/union_vector/union_vector_generated.js
index 01f883c..9e8b76e 100644
--- a/tests/union_vector/union_vector_generated.js
+++ b/tests/union_vector/union_vector_generated.js
@@ -186,6 +186,13 @@
}
/**
+ * @returns {number}
+ */
+Rapunzel.sizeOf = function() {
+ return 4;
+}
+
+/**
* @param {flatbuffers.Builder} builder
* @param {number} hair_length
* @returns {flatbuffers.Offset}
@@ -246,6 +253,13 @@
}
/**
+ * @returns {number}
+ */
+BookReader.sizeOf = function() {
+ return 4;
+}
+
+/**
* @param {flatbuffers.Builder} builder
* @param {number} books_read
* @returns {flatbuffers.Offset}
diff --git a/tests/union_vector/union_vector_generated.ts b/tests/union_vector/union_vector_generated.ts
index eb74fcb..806c07f 100644
--- a/tests/union_vector/union_vector_generated.ts
+++ b/tests/union_vector/union_vector_generated.ts
@@ -222,6 +222,13 @@
}
/**
+ * @returns number
+ */
+static sizeOf():number {
+ return 4;
+}
+
+/**
* @param flatbuffers.Builder builder
* @param number hair_length
* @returns flatbuffers.Offset
@@ -311,6 +318,13 @@
}
/**
+ * @returns number
+ */
+static sizeOf():number {
+ return 4;
+}
+
+/**
* @param flatbuffers.Builder builder
* @param number books_read
* @returns flatbuffers.Offset