├── .npmignore ├── tests ├── example.bfbs ├── unicode.bfbs ├── example_input.example ├── unicode.fbs ├── unicode.json ├── example_input.json ├── test.js ├── example.fbs ├── example_output.json └── example.json ├── generate.sh ├── package.json ├── LICENSE.txt ├── README.md └── src ├── reflection.fbs ├── index.js ├── reflection_generated.js └── flatbuffers.js /.npmignore: -------------------------------------------------------------------------------- 1 | /generate.sh 2 | /src/reflection.fbs 3 | /tests 4 | -------------------------------------------------------------------------------- /tests/example.bfbs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evanw/node-flatbuffers/HEAD/tests/example.bfbs -------------------------------------------------------------------------------- /tests/unicode.bfbs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evanw/node-flatbuffers/HEAD/tests/unicode.bfbs -------------------------------------------------------------------------------- /tests/example_input.example: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evanw/node-flatbuffers/HEAD/tests/example_input.example -------------------------------------------------------------------------------- /tests/unicode.fbs: -------------------------------------------------------------------------------- 1 | table Table { 2 | text: string; 3 | vector_tables: [Table]; 4 | vector_strings: [string]; 5 | } 6 | 7 | root_type Table; 8 | -------------------------------------------------------------------------------- /generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | flatc -o src --js src/reflection.fbs 4 | flatc -o tests --binary --schema tests/example.fbs 5 | flatc -o tests --binary --schema tests/unicode.fbs 6 | flatc -o tests tests/example.fbs --binary tests/example_input.json 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flatbuffers", 3 | "version": "0.1.0", 4 | "description": "An implementation of FlatBuffers in pure JavaScript", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "node tests/test" 8 | }, 9 | "author": "Evan Wallace", 10 | "license": "Apache License, Version 2.0" 11 | } 12 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2016 Evan Wallace 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /tests/unicode.json: -------------------------------------------------------------------------------- 1 | { 2 | "text": "unicode_test", 3 | "vector_tables": [ 4 | { 5 | "text": "Цлїςσδε", 6 | "vector_tables": [], 7 | "vector_strings": [] 8 | }, 9 | { 10 | "text": "フムアムカモケモ", 11 | "vector_tables": [], 12 | "vector_strings": [] 13 | }, 14 | { 15 | "text": "フムヤムカモケモ", 16 | "vector_tables": [], 17 | "vector_strings": [] 18 | }, 19 | { 20 | "text": "㊀㊁㊂㊃㊄", 21 | "vector_tables": [], 22 | "vector_strings": [] 23 | }, 24 | { 25 | "text": "☳☶☲", 26 | "vector_tables": [], 27 | "vector_strings": [] 28 | }, 29 | { 30 | "text": "𡇙𝌆", 31 | "vector_tables": [], 32 | "vector_strings": [] 33 | } 34 | ], 35 | "vector_strings": [ 36 | "Цлїςσδε", 37 | "フムアムカモケモ", 38 | "フムヤムカモケモ", 39 | "㊀㊁㊂㊃㊄", 40 | "☳☶☲", 41 | "𡇙𝌆" 42 | ] 43 | } -------------------------------------------------------------------------------- /tests/example_input.json: -------------------------------------------------------------------------------- 1 | { 2 | "field_required": "field_required", 3 | 4 | "field_bool": true, 5 | 6 | "field_byte": -100, 7 | "field_ubyte": 200, 8 | 9 | "field_short": -10000, 10 | "field_ushort": 20000, 11 | 12 | "field_int": -10000000, 13 | "field_uint": 20000000, 14 | 15 | "field_float": 2.718281828459045, 16 | "field_double": 2.718281828459045, 17 | 18 | "field_enum": "SECOND", 19 | "field_string": "text", 20 | 21 | "field_struct": { 22 | "field_bool": false, 23 | "field_byte": -100, 24 | "field_short": -10000, 25 | "field_int": -10000000, 26 | "field_float": 2.718281828459045, 27 | "field_double": 2.718281828459045, 28 | "field_enum": "SECOND", 29 | "field_nested": { 30 | "x": 1.5, 31 | "y": -0.5 32 | } 33 | }, 34 | 35 | "field_example": { 36 | "field_required": "field_required" 37 | }, 38 | 39 | "field_bytes": [101, 102, 103, -101, -102, -103], 40 | "field_shorts": [10001, 10002, 10003, -10001, -10002, -10003], 41 | "field_ints": [10000001, 10000002, 10000003, -10000001, -10000002, -10000003], 42 | "field_floats": [1.5, -0.5], 43 | "field_doubles": [1.5, -0.5], 44 | "field_enums": ["FIRST", "SECOND"], 45 | "field_strings": ["a", "b", "c"], 46 | "field_structs": [{"x": 1.5, "y": -0.5}, {"x": -0.5, "y": 1.5}], 47 | "field_examples": [{"field_required": "a"}, {"field_required": "b"}] 48 | } 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FlatBuffers in JavaScript 2 | 3 | This is an implementation of [FlatBuffers](https://github.com/google/flatbuffers) in pure JavaScript. Unlike the official compiler, this implementation generates JavaScript code to convert between JavaScript objects and FlatBuffers at run time using the JIT. It currently requires binary schemas compiled with the `flatc` compiler, which is written in C++ and has to be built (see the [build instructions](http://google.github.io/flatbuffers/flatbuffers_guide_building.html)). 4 | 5 | ### Example Usage 6 | 7 | 1. Create a schema called `example.fbs`: 8 | 9 | ``` 10 | table Example { 11 | x: float; 12 | y: float; 13 | } 14 | 15 | root_type Example; 16 | ``` 17 | 18 | 2. Generate the binary schema called `example.bfbs`: 19 | 20 | ``` 21 | flatc --binary --schema example.fbs 22 | ``` 23 | 24 | 3. Install this library: 25 | 26 | ``` 27 | npm install flatbuffers 28 | ``` 29 | 30 | 4. Use the library: 31 | 32 | ``` 33 | var flatbuffers = require('flatbuffers'); 34 | var fs = require('fs'); 35 | 36 | var example = flatbuffers.compileSchema(fs.readFileSync('example.bfbs')); 37 | var generated = example.generate({ x: 1, y: 2 }); 38 | var parsed = example.parse(generated); 39 | 40 | console.log('generated:', Array.from(generated)); 41 | console.log('parsed:', parsed); 42 | ``` 43 | 44 | Running that code should print this: 45 | 46 | ``` 47 | generated: [ 12, 0, 0, 0, 8, 0, 12, 0, 8, 0, 4, 0, 8, 0, 0, 0, 0, 0, 0, 64, 0, 0, 128, 63 ] 48 | parsed: { x: 1, y: 2 } 49 | ``` 50 | -------------------------------------------------------------------------------- /tests/test.js: -------------------------------------------------------------------------------- 1 | var child_process = require('child_process'); 2 | var flatbuffers = require('../src/index'); 3 | var assert = require('assert'); 4 | var fs = require('fs'); 5 | 6 | function checkSame(name, expectedFile, string) { 7 | console.log('checking:', name); 8 | var diff = child_process.spawnSync('diff', [expectedFile, '/dev/stdin'], {input: string}).stdout.toString(); 9 | 10 | if (diff !== '') { 11 | console.log(diff); 12 | console.log('check failed:', name); 13 | process.exit(1); 14 | } 15 | } 16 | 17 | function checkCompiledExampleSchema(compiled) { 18 | // Check buffer parsing 19 | var parsed = compiled.parse(fs.readFileSync(__dirname + '/example_input.example')); 20 | checkSame('buffer parsing', __dirname + '/example_output.json', JSON.stringify(parsed, null, 2)); 21 | 22 | // Check buffer generation 23 | var generated = compiled.generate(JSON.parse(fs.readFileSync(__dirname + '/example_input.json', 'utf8'))); 24 | var parsed = compiled.parse(generated); 25 | checkSame('buffer generation', __dirname + '/example_output.json', JSON.stringify(parsed, null, 2)); 26 | } 27 | 28 | function main() { 29 | // Check support for different types 30 | var binarySchema = fs.readFileSync(__dirname + '/example.bfbs'); 31 | var parsedSchema = flatbuffers.parseSchema(binarySchema); 32 | checkSame('schema parsing', __dirname + '/example.json', JSON.stringify(parsedSchema, null, 2)); 33 | checkCompiledExampleSchema(flatbuffers.compileSchema(parsedSchema)); 34 | checkCompiledExampleSchema(flatbuffers.compileSchema(binarySchema)); 35 | 36 | // Check unicode serialization 37 | var unicodeSchema = fs.readFileSync(__dirname + '/unicode.bfbs'); 38 | var unicodeData = JSON.parse(fs.readFileSync(__dirname + '/unicode.json', 'utf8')); 39 | var compiled = flatbuffers.compileSchema(unicodeSchema); 40 | var parsed = compiled.parse(compiled.generate(unicodeData)); 41 | checkSame('unicode serialization', __dirname + '/unicode.json', JSON.stringify(parsed, null, 2)); 42 | 43 | console.log('all tests pass'); 44 | } 45 | 46 | main(); 47 | -------------------------------------------------------------------------------- /tests/example.fbs: -------------------------------------------------------------------------------- 1 | enum Enum : ubyte { 2 | FIRST, 3 | SECOND, 4 | } 5 | 6 | table A {} 7 | table B {} 8 | 9 | struct Nested { 10 | x: float; 11 | y: float; 12 | } 13 | 14 | struct Struct { 15 | field_bool: bool; 16 | field_byte: byte; 17 | field_short: short; 18 | field_int: int; 19 | field_float: float; 20 | field_double: double; 21 | field_enum: Enum; 22 | field_nested: Nested; 23 | } 24 | 25 | union Union { 26 | A, 27 | B, 28 | } 29 | 30 | table Example { 31 | field_bool: bool; 32 | field_bool_false: bool = false; 33 | field_bool_true: bool = true; 34 | 35 | field_byte: byte; 36 | field_byte_negative_0x80: byte = 0x80; 37 | 38 | field_ubyte: ubyte; 39 | field_ubyte_0xFF: ubyte = 0xFF; 40 | 41 | field_short: short; 42 | field_short_negative_0x8000: short = 0x8000; 43 | 44 | field_ushort: ushort; 45 | field_ushort_0xFFFF: ushort = 0xFFFF; 46 | 47 | field_int: int; 48 | field_int_negative_0x80000000: int = 0x80000000; 49 | 50 | field_uint: uint; 51 | field_uint_0xFFFFFFFF: uint = 0xFFFFFFFF; 52 | 53 | field_long: long; 54 | field_long_negative_0x8000000000000000: long = 0x8000000000000000; 55 | 56 | field_ulong: ulong; 57 | field_ulong_0xFFFFFFFFFFFFFFFF: ulong = 0xFFFFFFFFFFFFFFFF; 58 | 59 | field_float: float; 60 | field_float_pi: float = 3.14159265359; 61 | 62 | field_double: double; 63 | field_double_pi: double = 3.14159265359; 64 | 65 | field_enum: Enum; 66 | field_enum_second: Enum = SECOND; 67 | 68 | field_string: string; 69 | field_struct: Struct; 70 | field_example: Example; 71 | 72 | field_bytes: [byte]; 73 | field_shorts: [short]; 74 | field_ints: [int]; 75 | field_longs: [long]; 76 | field_floats: [float]; 77 | field_doubles: [double]; 78 | field_enums: [Enum]; 79 | field_strings: [string]; 80 | field_structs: [Nested]; 81 | field_examples: [Example]; 82 | 83 | field_deprecated: string (deprecated); 84 | field_required: string (required); 85 | 86 | // TODO: Support unions 87 | // field_union: Union; 88 | } 89 | 90 | root_type Example; 91 | 92 | file_identifier "EXAM"; 93 | file_extension "example"; 94 | -------------------------------------------------------------------------------- /src/reflection.fbs: -------------------------------------------------------------------------------- 1 | // This schema defines objects that represent a parsed schema, like 2 | // the binary version of a .fbs file. 3 | // This could be used to operate on unknown FlatBuffers at runtime. 4 | // It can even ... represent itself (!) 5 | 6 | namespace reflection; 7 | 8 | // These must correspond to the enum in idl.h. 9 | enum BaseType : byte { 10 | None, 11 | UType, 12 | Bool, 13 | Byte, 14 | UByte, 15 | Short, 16 | UShort, 17 | Int, 18 | UInt, 19 | Long, 20 | ULong, 21 | Float, 22 | Double, 23 | String, 24 | Vector, 25 | Obj, // Used for tables & structs. 26 | Union 27 | } 28 | 29 | table Type { 30 | base_type:BaseType; 31 | element:BaseType = None; // Only if base_type == Vector. 32 | index:int = -1; // If base_type == Object, index into "objects" below. 33 | // If base_type == Union, UnionType, or integral derived 34 | // from an enum, index into "enums" below. 35 | } 36 | 37 | table EnumVal { 38 | name:string (required); 39 | value:long (key); 40 | object:Object; // Only if part of a union. 41 | } 42 | 43 | table Enum { 44 | name:string (required, key); 45 | values:[EnumVal] (required); // In order of their values. 46 | is_union:bool = false; 47 | underlying_type:Type (required); 48 | } 49 | 50 | table Field { 51 | name:string (required, key); 52 | type:Type (required); 53 | id:ushort; 54 | offset:ushort; // Offset into the vtable for tables, or into the struct. 55 | default_integer:long = 0; 56 | default_real:double = 0.0; 57 | deprecated:bool = false; 58 | required:bool = false; 59 | key:bool = false; 60 | } 61 | 62 | table Object { // Used for both tables and structs. 63 | name:string (required, key); 64 | fields:[Field] (required); // Sorted. 65 | is_struct:bool = false; 66 | minalign:int; 67 | bytesize:int; // For structs. 68 | } 69 | 70 | table Schema { 71 | objects:[Object] (required); // Sorted. 72 | enums:[Enum] (required); // Sorted. 73 | file_ident:string; 74 | file_ext:string; 75 | root_table:Object; 76 | } 77 | 78 | root_type Schema; 79 | 80 | file_identifier "BFBS"; 81 | file_extension "bfbs"; 82 | -------------------------------------------------------------------------------- /tests/example_output.json: -------------------------------------------------------------------------------- 1 | { 2 | "field_bool": true, 3 | "field_bool_false": false, 4 | "field_bool_true": true, 5 | "field_byte": -100, 6 | "field_byte_negative_0x80": -128, 7 | "field_ubyte": 200, 8 | "field_ubyte_0xFF": 255, 9 | "field_short": -10000, 10 | "field_short_negative_0x8000": -32768, 11 | "field_ushort": 20000, 12 | "field_ushort_0xFFFF": 65535, 13 | "field_int": -10000000, 14 | "field_int_negative_0x80000000": -2147483648, 15 | "field_uint": 20000000, 16 | "field_uint_0xFFFFFFFF": 4294967295, 17 | "field_long": { 18 | "low": 0, 19 | "high": 0 20 | }, 21 | "field_long_negative_0x8000000000000000": { 22 | "low": 0, 23 | "high": -2147483648 24 | }, 25 | "field_ulong": { 26 | "low": 0, 27 | "high": 0 28 | }, 29 | "field_ulong_0xFFFFFFFFFFFFFFFF": { 30 | "low": 4294967295, 31 | "high": 4294967295 32 | }, 33 | "field_float": 2.7182817459106445, 34 | "field_float_pi": 3.14159265359, 35 | "field_double": 2.718281828459045, 36 | "field_double_pi": 3.14159265359, 37 | "field_enum": "SECOND", 38 | "field_enum_second": "SECOND", 39 | "field_string": "text", 40 | "field_struct": { 41 | "field_bool": false, 42 | "field_byte": -100, 43 | "field_short": -10000, 44 | "field_int": -10000000, 45 | "field_float": 2.7182817459106445, 46 | "field_double": 2.718281828459045, 47 | "field_enum": "SECOND", 48 | "field_nested": { 49 | "x": 1.5, 50 | "y": -0.5 51 | } 52 | }, 53 | "field_example": { 54 | "field_bool": false, 55 | "field_bool_false": false, 56 | "field_bool_true": true, 57 | "field_byte": 0, 58 | "field_byte_negative_0x80": -128, 59 | "field_ubyte": 0, 60 | "field_ubyte_0xFF": 255, 61 | "field_short": 0, 62 | "field_short_negative_0x8000": -32768, 63 | "field_ushort": 0, 64 | "field_ushort_0xFFFF": 65535, 65 | "field_int": 0, 66 | "field_int_negative_0x80000000": -2147483648, 67 | "field_uint": 0, 68 | "field_uint_0xFFFFFFFF": 4294967295, 69 | "field_long": { 70 | "low": 0, 71 | "high": 0 72 | }, 73 | "field_long_negative_0x8000000000000000": { 74 | "low": 0, 75 | "high": -2147483648 76 | }, 77 | "field_ulong": { 78 | "low": 0, 79 | "high": 0 80 | }, 81 | "field_ulong_0xFFFFFFFFFFFFFFFF": { 82 | "low": 4294967295, 83 | "high": 4294967295 84 | }, 85 | "field_float": 0, 86 | "field_float_pi": 3.14159265359, 87 | "field_double": 0, 88 | "field_double_pi": 3.14159265359, 89 | "field_enum": "FIRST", 90 | "field_enum_second": "SECOND", 91 | "field_string": null, 92 | "field_struct": null, 93 | "field_example": null, 94 | "field_bytes": [], 95 | "field_shorts": [], 96 | "field_ints": [], 97 | "field_longs": [], 98 | "field_floats": [], 99 | "field_doubles": [], 100 | "field_enums": [], 101 | "field_strings": [], 102 | "field_structs": [], 103 | "field_examples": [], 104 | "field_required": "field_required" 105 | }, 106 | "field_bytes": [ 107 | 101, 108 | 102, 109 | 103, 110 | -101, 111 | -102, 112 | -103 113 | ], 114 | "field_shorts": [ 115 | 10001, 116 | 10002, 117 | 10003, 118 | -10001, 119 | -10002, 120 | -10003 121 | ], 122 | "field_ints": [ 123 | 10000001, 124 | 10000002, 125 | 10000003, 126 | -10000001, 127 | -10000002, 128 | -10000003 129 | ], 130 | "field_longs": [], 131 | "field_floats": [ 132 | 1.5, 133 | -0.5 134 | ], 135 | "field_doubles": [ 136 | 1.5, 137 | -0.5 138 | ], 139 | "field_enums": [ 140 | "FIRST", 141 | "SECOND" 142 | ], 143 | "field_strings": [ 144 | "a", 145 | "b", 146 | "c" 147 | ], 148 | "field_structs": [ 149 | { 150 | "x": 1.5, 151 | "y": -0.5 152 | }, 153 | { 154 | "x": -0.5, 155 | "y": 1.5 156 | } 157 | ], 158 | "field_examples": [ 159 | { 160 | "field_bool": false, 161 | "field_bool_false": false, 162 | "field_bool_true": true, 163 | "field_byte": 0, 164 | "field_byte_negative_0x80": -128, 165 | "field_ubyte": 0, 166 | "field_ubyte_0xFF": 255, 167 | "field_short": 0, 168 | "field_short_negative_0x8000": -32768, 169 | "field_ushort": 0, 170 | "field_ushort_0xFFFF": 65535, 171 | "field_int": 0, 172 | "field_int_negative_0x80000000": -2147483648, 173 | "field_uint": 0, 174 | "field_uint_0xFFFFFFFF": 4294967295, 175 | "field_long": { 176 | "low": 0, 177 | "high": 0 178 | }, 179 | "field_long_negative_0x8000000000000000": { 180 | "low": 0, 181 | "high": -2147483648 182 | }, 183 | "field_ulong": { 184 | "low": 0, 185 | "high": 0 186 | }, 187 | "field_ulong_0xFFFFFFFFFFFFFFFF": { 188 | "low": 4294967295, 189 | "high": 4294967295 190 | }, 191 | "field_float": 0, 192 | "field_float_pi": 3.14159265359, 193 | "field_double": 0, 194 | "field_double_pi": 3.14159265359, 195 | "field_enum": "FIRST", 196 | "field_enum_second": "SECOND", 197 | "field_string": null, 198 | "field_struct": null, 199 | "field_example": null, 200 | "field_bytes": [], 201 | "field_shorts": [], 202 | "field_ints": [], 203 | "field_longs": [], 204 | "field_floats": [], 205 | "field_doubles": [], 206 | "field_enums": [], 207 | "field_strings": [], 208 | "field_structs": [], 209 | "field_examples": [], 210 | "field_required": "a" 211 | }, 212 | { 213 | "field_bool": false, 214 | "field_bool_false": false, 215 | "field_bool_true": true, 216 | "field_byte": 0, 217 | "field_byte_negative_0x80": -128, 218 | "field_ubyte": 0, 219 | "field_ubyte_0xFF": 255, 220 | "field_short": 0, 221 | "field_short_negative_0x8000": -32768, 222 | "field_ushort": 0, 223 | "field_ushort_0xFFFF": 65535, 224 | "field_int": 0, 225 | "field_int_negative_0x80000000": -2147483648, 226 | "field_uint": 0, 227 | "field_uint_0xFFFFFFFF": 4294967295, 228 | "field_long": { 229 | "low": 0, 230 | "high": 0 231 | }, 232 | "field_long_negative_0x8000000000000000": { 233 | "low": 0, 234 | "high": -2147483648 235 | }, 236 | "field_ulong": { 237 | "low": 0, 238 | "high": 0 239 | }, 240 | "field_ulong_0xFFFFFFFFFFFFFFFF": { 241 | "low": 4294967295, 242 | "high": 4294967295 243 | }, 244 | "field_float": 0, 245 | "field_float_pi": 3.14159265359, 246 | "field_double": 0, 247 | "field_double_pi": 3.14159265359, 248 | "field_enum": "FIRST", 249 | "field_enum_second": "SECOND", 250 | "field_string": null, 251 | "field_struct": null, 252 | "field_example": null, 253 | "field_bytes": [], 254 | "field_shorts": [], 255 | "field_ints": [], 256 | "field_longs": [], 257 | "field_floats": [], 258 | "field_doubles": [], 259 | "field_enums": [], 260 | "field_strings": [], 261 | "field_structs": [], 262 | "field_examples": [], 263 | "field_required": "b" 264 | } 265 | ], 266 | "field_required": "field_required" 267 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | var flatbuffers = require('./flatbuffers').flatbuffers; 2 | var reflection = require('./reflection_generated').reflection; 3 | 4 | var baseTypes = [ 5 | 'None', 6 | 'UType', 7 | 'Bool', 8 | 'Byte', 9 | 'UByte', 10 | 'Short', 11 | 'UShort', 12 | 'Int', 13 | 'UInt', 14 | 'Long', 15 | 'ULong', 16 | 'Float', 17 | 'Double', 18 | 'String', 19 | 'Vector', 20 | 'Obj', 21 | 'Union', 22 | ]; 23 | 24 | var scalarSizes = { 25 | 'Bool': 1, 26 | 'Byte': 1, 27 | 'UByte': 1, 28 | 'Short': 2, 29 | 'UShort': 2, 30 | 'Int': 4, 31 | 'UInt': 4, 32 | 'Long': 8, 33 | 'ULong': 8, 34 | 'Float': 4, 35 | 'Double': 8, 36 | }; 37 | 38 | var scalarGetters = { 39 | 'Bool': '!!bb.readUint8', 40 | 'Byte': 'bb.readInt8', 41 | 'UByte': 'bb.readUint8', 42 | 'Short': 'bb.readInt16', 43 | 'UShort': 'bb.readUint16', 44 | 'Int': 'bb.readInt32', 45 | 'UInt': 'bb.readUint32', 46 | 'Long': 'bb.readInt64', 47 | 'ULong': 'bb.readUint64', 48 | 'Float': 'bb.readFloat32', 49 | 'Double': 'bb.readFloat64', 50 | }; 51 | 52 | var scalarSetters = { 53 | 'Bool': 'fbb.writeInt8', 54 | 'Byte': 'fbb.writeInt8', 55 | 'UByte': 'fbb.writeInt8', 56 | 'Short': 'fbb.writeInt16', 57 | 'UShort': 'fbb.writeInt16', 58 | 'Int': 'fbb.writeInt32', 59 | 'UInt': 'fbb.writeInt32', 60 | 'Float': 'fbb.writeFloat32', 61 | 'Double': 'fbb.writeFloat64', 62 | }; 63 | 64 | var scalarAdders = { 65 | 'Bool': 'fbb.addFieldInt8', 66 | 'Byte': 'fbb.addFieldInt8', 67 | 'UByte': 'fbb.addFieldInt8', 68 | 'Short': 'fbb.addFieldInt16', 69 | 'UShort': 'fbb.addFieldInt16', 70 | 'Int': 'fbb.addFieldInt32', 71 | 'UInt': 'fbb.addFieldInt32', 72 | 'Float': 'fbb.addFieldFloat32', 73 | 'Double': 'fbb.addFieldFloat64', 74 | }; 75 | 76 | function notReached() { 77 | throw new Error('Internal error'); 78 | } 79 | 80 | function requireUint8Array(bytes) { 81 | if (bytes instanceof Uint8Array) { 82 | return bytes; 83 | } 84 | 85 | if (typeof Buffer !== 'undefined' && bytes instanceof Buffer) { 86 | return new Uint8Array(bytes); 87 | } 88 | 89 | throw new Error('Not a valid Uint8Array'); 90 | } 91 | 92 | function requireObject(json) { 93 | if (json instanceof Object) { 94 | return json; 95 | } 96 | 97 | throw new Error('Not a valid JSON object'); 98 | } 99 | 100 | function parseValue(integer, real, type) { 101 | switch (type.baseType) { 102 | case 'Bool': return !!integer.low; 103 | case 'Byte': return integer.low << 24 >> 24; 104 | case 'UByte': case 'UType': return integer.low & 0xFF; 105 | case 'Short': return integer.low << 16 >> 16; 106 | case 'UShort': return integer.low & 0xFFFF; 107 | case 'Int': return integer.low | 0; 108 | case 'UInt': return integer.low >>> 0; 109 | case 'Long': return { low: integer.low | 0, high: integer.high | 0 }; 110 | case 'ULong': return { low: integer.low >>> 0, high: integer.high >>> 0 }; 111 | case 'Float': case 'Double': return real; 112 | } 113 | 114 | return null; 115 | } 116 | 117 | function parseType(type) { 118 | return { 119 | baseType: baseTypes[type.baseType()], 120 | element: baseTypes[type.element()], 121 | index: type.index(), 122 | }; 123 | } 124 | 125 | function parseObject(object) { 126 | var result = { 127 | name: object.name(), 128 | isStruct: object.isStruct(), 129 | minalign: object.minalign(), 130 | bytesize: object.bytesize(), 131 | fields: [], 132 | }; 133 | 134 | for (var i = 0, fieldsLength = object.fieldsLength(); i < fieldsLength; i++) { 135 | var field = object.fields(i); 136 | var type = parseType(field.type()); 137 | 138 | result.fields.push({ 139 | name: field.name(), 140 | type: type, 141 | id: field.id(), 142 | offset: field.offset(), 143 | deprecated: field.deprecated(), 144 | required: field.required(), 145 | key: field.key(), 146 | default: parseValue(field.defaultInteger(), field.defaultReal(), type), 147 | }); 148 | } 149 | 150 | // Sort fields in order of id 151 | result.fields.sort(function(a, b) { 152 | return a.id - b.id; 153 | }); 154 | 155 | return result; 156 | } 157 | 158 | function parseEnum(enumDef) { 159 | var type = parseType(enumDef.underlyingType()); 160 | var result = { 161 | name: enumDef.name(), 162 | is_union: enumDef.isUnion(), 163 | underlying_type: type, 164 | values: [], 165 | }; 166 | 167 | for (var i = 0, valuesLength = enumDef.valuesLength(); i < valuesLength; i++) { 168 | var value = enumDef.values(i); 169 | var object = value.object(); 170 | 171 | result.values.push({ 172 | name: value.name(), 173 | value: parseValue(value.value(), 0, type), 174 | object: object === null ? null : parseObject(object), 175 | }); 176 | } 177 | 178 | // Sort values in order of value 179 | result.values.sort(function(a, b) { 180 | return a.value - b.value; 181 | }); 182 | 183 | return result; 184 | } 185 | 186 | exports.parseSchema = function(bytes) { 187 | var bb = new flatbuffers.ByteBuffer(requireUint8Array(bytes)); 188 | 189 | // Must conform to reflection.fbs 190 | if (!reflection.Schema.bufferHasIdentifier(bb)) { 191 | throw new Error('Not a valid binary FlatBuffers schema'); 192 | } 193 | 194 | var schema = reflection.Schema.getRootAsSchema(bb); 195 | var result = { 196 | fileIdent: schema.fileIdent(), 197 | fileExt: schema.fileExt(), 198 | rootTable: parseObject(schema.rootTable()), 199 | objects: [], 200 | enums: [], 201 | }; 202 | 203 | for (var i = 0, objectsLength = schema.objectsLength(); i < objectsLength; i++) { 204 | result.objects.push(parseObject(schema.objects(i))); 205 | } 206 | 207 | for (var i = 0, enumsLength = schema.enumsLength(); i < enumsLength; i++) { 208 | result.enums.push(parseEnum(schema.enums(i))); 209 | } 210 | 211 | return result; 212 | }; 213 | 214 | function compileEnumGenerator(schema, context, enumDef) { 215 | var key = 'enumMap' + enumDef.name; 216 | var code = ''; 217 | 218 | if (key in context) { 219 | return key; 220 | } 221 | 222 | var map = {}; 223 | 224 | for (var i = 0; i < enumDef.values.length; i++) { 225 | var value = enumDef.values[i]; 226 | map[value.name] = value.value; 227 | } 228 | 229 | context[key] = map; 230 | 231 | return key; 232 | } 233 | 234 | function compileObjectGenerator(schema, context, object) { 235 | var key = 'generate' + object.name; 236 | var code = ''; 237 | 238 | if (key in context) { 239 | return key; 240 | } 241 | 242 | context[key] = null; 243 | 244 | // Structs 245 | if (object.isStruct) { 246 | code += 'fbb.prep(' + object.minalign + ', ' + object.bytesize + ');\n'; 247 | 248 | // Write out fields backwards so they will be read in forwards 249 | for (var i = object.fields.length - 1; i >= 0; i--) { 250 | var field = object.fields[i]; 251 | var type = field.type; 252 | var baseType = type.baseType; 253 | var setter = scalarSetters[baseType]; 254 | var inlineSize = baseType === 'Obj' ? schema.objects[type.index].bytesize : scalarSizes[baseType]; 255 | var nextOffset = i + 1 < object.fields.length ? object.fields[i + 1].offset : object.bytesize; 256 | var padding = nextOffset - field.offset - inlineSize; 257 | 258 | // Padding after the value 259 | if (padding) { 260 | code += 'fbb.pad(' + padding + ');\n'; 261 | } 262 | 263 | // Scalars 264 | if (setter) { 265 | var enumDef = schema.enums[type.index]; 266 | if (enumDef) { 267 | var nested = compileEnumGenerator(schema, context, enumDef); 268 | code += setter + '(context.' + nested + '[json.' + field.name + ']);\n'; 269 | } else { 270 | code += setter + '(json.' + field.name + ');\n'; 271 | } 272 | } 273 | 274 | // Longs 275 | else if (baseType === 'Long' || baseType === 'ULong') { 276 | code += 'fbb.writeInt64(fbb.createLong(json.' + field.name + '.low, json.' + field.name + '.high));\n'; 277 | } 278 | 279 | // Structs 280 | else if (baseType === 'Obj') { 281 | var def = schema.objects[type.index]; 282 | var nested = compileObjectGenerator(schema, context, def); 283 | code += 'context.' + nested + '(fbb, context, json.' + field.name + ');\n'; 284 | } 285 | 286 | // Sanity check 287 | else { 288 | notReached(); 289 | } 290 | } 291 | 292 | code += 'return fbb.offset();\n'; 293 | } 294 | 295 | // Tables 296 | else { 297 | for (var i = 0; i < object.fields.length; i++) { 298 | var field = object.fields[i]; 299 | var type = field.type; 300 | var baseType = type.baseType; 301 | 302 | // Skip deprecated fields 303 | if (field.deprecated) { 304 | continue; 305 | } 306 | 307 | // Strings 308 | if (baseType === 'String') { 309 | code += 'var offset' + field.id + ' = json.' + field.name + ' ? fbb.createString(json.' + field.name + ') : 0;\n'; 310 | } 311 | 312 | // Tables 313 | else if (baseType === 'Obj' && !schema.objects[type.index].isStruct) { 314 | var def = schema.objects[type.index]; 315 | var nested = compileObjectGenerator(schema, context, def); 316 | code += 'var offset' + field.id + ' = json.' + field.name + ' ? context.' + nested + '(fbb, context, json.' + field.name + ') : 0;\n'; 317 | } 318 | 319 | // Vectors 320 | else if (baseType === 'Vector') { 321 | var element = type.element; 322 | var elementSetter = scalarSetters[element]; 323 | 324 | // Check value 325 | code += 'var values = json.' + field.name + ';\n'; 326 | code += 'var offset' + field.id + ' = 0;\n'; 327 | code += 'if (values && values.length) {\n'; 328 | 329 | // Vectors of strings 330 | if (element === 'String') { 331 | code += ' var offsets = [];\n'; 332 | code += ' for (var i = 0; i < values.length; i++) {\n'; 333 | code += ' offsets.push(fbb.createString(values[i]));\n'; 334 | code += ' }\n'; 335 | } 336 | 337 | // Vectors of tables 338 | else if (element === 'Obj' && !schema.objects[type.index].isStruct) { 339 | var def = schema.objects[type.index]; 340 | var nested = compileObjectGenerator(schema, context, def); 341 | code += ' var offsets = [];\n'; 342 | code += ' for (var i = 0; i < values.length; i++) {\n'; 343 | code += ' offsets.push(context.' + nested + '(fbb, context, values[i]));\n'; 344 | code += ' }\n'; 345 | } 346 | 347 | // Begin vector (write out elements backwards so they will be read in forwards) 348 | code += ' fbb.startVector(8, values.length, 4);\n'; 349 | code += ' for (var i = values.length - 1; i >= 0; i--) {\n'; 350 | 351 | // Vectors of scalars 352 | if (elementSetter) { 353 | var enumDef = schema.enums[type.index]; 354 | if (enumDef) { 355 | var nested = compileEnumGenerator(schema, context, enumDef); 356 | code += ' ' + elementSetter + '(context.' + nested + '[values[i]]);\n'; 357 | } else { 358 | code += ' ' + elementSetter + '(values[i]);\n'; 359 | } 360 | } 361 | 362 | // Vectors of longs 363 | else if (element === 'Long' || element === 'ULong') { 364 | code += ' fbb.writeInt64(fbb.createLong(values[i].low, values[i].high));\n'; 365 | } 366 | 367 | // Vectors of structs 368 | else if (element === 'Obj' && schema.objects[type.index].isStruct) { 369 | var def = schema.objects[type.index]; 370 | var nested = compileObjectGenerator(schema, context, def); 371 | code += ' context.' + nested + '(fbb, context, values[i]);\n'; 372 | } 373 | 374 | // Vectors of strings or tables 375 | else if (element === 'String' || element === 'Obj') { 376 | code += ' fbb.addOffset(offsets[i]);\n'; 377 | } 378 | 379 | // Sanity check 380 | else { 381 | notReached(); 382 | } 383 | 384 | // End loop 385 | code += ' }\n'; 386 | code += ' offset' + field.id + ' = fbb.endVector();\n'; 387 | code += '}\n'; 388 | } 389 | 390 | // Unions 391 | else if (baseType === 'Union') { 392 | throw new Error('Unions are not supported yet'); 393 | } 394 | } 395 | 396 | code += 'fbb.startObject(' + object.fields.length + ');\n'; 397 | 398 | for (var i = 0; i < object.fields.length; i++) { 399 | var field = object.fields[i]; 400 | var type = field.type; 401 | var baseType = type.baseType; 402 | var adder = scalarAdders[baseType]; 403 | 404 | // Skip deprecated fields 405 | if (field.deprecated) { 406 | continue; 407 | } 408 | 409 | // Scalars 410 | if (adder) { 411 | code += 'if (' + JSON.stringify(field.name) + ' in json) {\n'; 412 | var enumDef = schema.enums[type.index]; 413 | if (enumDef) { 414 | var nested = compileEnumGenerator(schema, context, enumDef); 415 | code += ' ' + adder + '(' + field.id + ', context.' + nested + '[json.' + field.name + '], ' + JSON.stringify(field.default) + ');\n'; 416 | } else { 417 | code += ' ' + adder + '(' + field.id + ', json.' + field.name + ', ' + JSON.stringify(field.default) + ');\n'; 418 | } 419 | code += '}\n'; 420 | } 421 | 422 | // Longs 423 | else if (baseType === 'Long' || baseType === 'ULong') { 424 | code += 'if (json.' + field.name + ') {\n'; 425 | code += ' fbb.addFieldInt64(' + field.id + ',\n'; 426 | code += ' fbb.createLong(json.' + field.name + '.low, json.' + field.name + '.high),\n'; 427 | code += ' fbb.createLong(' + field.default.low + ', ' + field.default.high + '));\n'; 428 | code += '}\n'; 429 | } 430 | 431 | // Structs 432 | else if (baseType === 'Obj' && schema.objects[type.index].isStruct) { 433 | var def = schema.objects[type.index]; 434 | var nested = compileObjectGenerator(schema, context, def); 435 | code += 'fbb.addFieldStruct(' + field.id + ', json.' + field.name + ' ? context.' + nested + '(fbb, context, json.' + field.name + ') : 0, 0);\n'; 436 | } 437 | 438 | // Strings or tables or vectors 439 | else if (baseType === 'String' || baseType === 'Obj' || baseType === 'Vector') { 440 | code += 'fbb.addFieldOffset(' + field.id + ', offset' + field.id + ', 0);\n'; 441 | } 442 | 443 | // Unions 444 | else if (baseType === 'UType' || baseType === 'Union') { 445 | throw new Error('Unions are not supported yet'); 446 | } 447 | 448 | // Sanity check 449 | else { 450 | notReached(); 451 | } 452 | } 453 | 454 | code += 'var offset = fbb.endObject();\n'; 455 | 456 | // Required fields 457 | for (var i = 0; i < object.fields.length; i++) { 458 | var field = object.fields[i]; 459 | if (field.required) { 460 | code += 'fbb.requiredField(offset, ' + field.offset + ', ' + JSON.stringify(field.name) + ');\n'; 461 | } 462 | } 463 | 464 | code += 'return offset;\n'; 465 | } 466 | 467 | // Compile this code using the JIT 468 | context[key] = new Function('fbb', 'context', 'json', code); 469 | 470 | return key; 471 | } 472 | 473 | function compileEnumParser(schema, context, enumDef) { 474 | var key = 'enumArray' + enumDef.name; 475 | var code = ''; 476 | 477 | if (key in context) { 478 | return key; 479 | } 480 | 481 | var array = []; 482 | 483 | for (var i = 0; i < enumDef.values.length; i++) { 484 | var value = enumDef.values[i]; 485 | array[value.value] = value.name; 486 | } 487 | 488 | context[key] = array; 489 | 490 | return key; 491 | } 492 | 493 | function compileObjectParser(schema, context, object) { 494 | var key = 'parse' + object.name; 495 | var code = ''; 496 | 497 | if (key in context) { 498 | return key; 499 | } 500 | 501 | context[key] = null; 502 | code += 'var json = {};\n'; 503 | 504 | // Structs 505 | if (object.isStruct) { 506 | for (var i = 0; i < object.fields.length; i++) { 507 | var field = object.fields[i]; 508 | var type = field.type; 509 | var baseType = type.baseType; 510 | var getter = scalarGetters[baseType]; 511 | 512 | // Scalars 513 | if (getter) { 514 | var value = getter + '(bb_pos + ' + field.offset + ')'; 515 | var enumDef = schema.enums[type.index]; 516 | if (enumDef) { 517 | var nested = compileEnumParser(schema, context, enumDef); 518 | code += 'json.' + field.name + ' = context.' + nested + '[' + value + '];\n'; 519 | } else { 520 | code += 'json.' + field.name + ' = ' + value + ';\n'; 521 | } 522 | } 523 | 524 | // Structs 525 | else if (baseType === 'Obj') { 526 | var def = schema.objects[type.index]; 527 | var nested = compileObjectParser(schema, context, def); 528 | code += 'json.' + field.name + ' = context.' + nested + '(bb, context, bb_pos + ' + field.offset + ');\n'; 529 | } 530 | 531 | // Sanity check 532 | else { 533 | notReached(); 534 | } 535 | } 536 | } 537 | 538 | // Tables 539 | else { 540 | for (var i = 0; i < object.fields.length; i++) { 541 | var field = object.fields[i]; 542 | var type = field.type; 543 | var baseType = type.baseType; 544 | var getter = scalarGetters[baseType]; 545 | 546 | // Skip deprecated fields 547 | if (field.deprecated) { 548 | continue; 549 | } 550 | 551 | // Common vtable offset lookup 552 | code += 'var offset = bb.__offset(bb_pos, ' + field.offset + ');\n'; 553 | 554 | // Scalars 555 | if (getter) { 556 | var value = 'offset ? ' + getter + '(bb_pos + offset) : ' + JSON.stringify(field.default); 557 | var enumDef = schema.enums[type.index]; 558 | if (enumDef) { 559 | var nested = compileEnumParser(schema, context, enumDef); 560 | code += 'json.' + field.name + ' = context.' + nested + '[' + value + '];\n'; 561 | } else { 562 | code += 'json.' + field.name + ' = ' + value + ';\n'; 563 | } 564 | } 565 | 566 | // Strings 567 | else if (baseType === 'String') { 568 | code += 'json.' + field.name + ' = offset ? bb.__string(bb_pos + offset) : null;\n'; 569 | } 570 | 571 | // Tables or structs 572 | else if (baseType === 'Obj') { 573 | var def = schema.objects[type.index]; 574 | var value = def.isStruct ? 'bb_pos + offset' : 'bb.__indirect(bb_pos + offset)'; 575 | var nested = compileObjectParser(schema, context, def); 576 | code += 'json.' + field.name + ' = offset ? context.' + nested + '(bb, context, ' + value + ') : null;\n'; 577 | } 578 | 579 | // Vectors 580 | else if (baseType === 'Vector') { 581 | var element = type.element; 582 | var elementGetter = scalarGetters[element]; 583 | 584 | // Begin loop 585 | code += 'var values = [];\n'; 586 | code += 'if (offset) {\n'; 587 | code += ' for (var i = 0, n = bb.__vector_len(bb_pos + offset), item = bb.__vector(bb_pos + offset); i < n; i++) {\n'; 588 | 589 | // Vectors of scalars 590 | if (elementGetter) { 591 | var enumDef = schema.enums[type.index]; 592 | if (enumDef) { 593 | var nested = compileEnumParser(schema, context, enumDef); 594 | code += ' values.push(context.' + nested + '[' + elementGetter + '(item)]);\n'; 595 | } else { 596 | code += ' values.push(' + elementGetter + '(item));\n'; 597 | } 598 | code += ' item += ' + scalarSizes[element] + ';\n'; 599 | } 600 | 601 | // Vectors of strings 602 | else if (element === 'String') { 603 | code += ' values.push(bb.__string(item));\n'; 604 | code += ' item += 4;\n'; 605 | } 606 | 607 | // Vectors of tables or structs 608 | else if (element === 'Obj') { 609 | var def = schema.objects[type.index]; 610 | var nested = compileObjectParser(schema, context, def); 611 | var value = def.isStruct ? 'item' : 'bb.__indirect(item)'; 612 | code += ' values.push(context.' + nested + '(bb, context, ' + value + '));\n'; 613 | code += ' item += ' + (def.bytesize || 4) + ';\n'; 614 | } 615 | 616 | // Sanity check 617 | else { 618 | notReached(); 619 | } 620 | 621 | // End loop 622 | code += ' }\n'; 623 | code += '}\n'; 624 | code += 'json.' + field.name + ' = values;\n'; 625 | } 626 | 627 | // Unions 628 | else if (baseType === 'UType' || baseType === 'Union') { 629 | throw new Error('Unions are not supported yet'); 630 | } 631 | 632 | // Sanity check 633 | else { 634 | notReached(); 635 | } 636 | } 637 | } 638 | 639 | // Compile this code using the JIT 640 | code += 'return json;\n'; 641 | context[key] = new Function('bb', 'context', 'bb_pos', code); 642 | 643 | return key; 644 | } 645 | 646 | exports.compileSchema = function(bytesOrJson) { 647 | var schema = bytesOrJson; 648 | var bytes; 649 | 650 | // Allow passing the schema either as raw bytes or as a pre-parsed object literal 651 | try { bytes = requireUint8Array(bytesOrJson); } catch (e) {} 652 | if (bytes) schema = exports.parseSchema(bytes); 653 | 654 | // Quick sanity check to catch mistakes 655 | if (!(schema instanceof Object) || !('rootTable' in schema)) { 656 | throw new Error('Not a valid schema'); 657 | } 658 | 659 | var context = {}; 660 | var rootGenerator = context[compileObjectGenerator(schema, context, schema.rootTable)]; 661 | var rootParser = context[compileObjectParser(schema, context, schema.rootTable)]; 662 | 663 | return { 664 | generate: function(json) { 665 | var fbb = new flatbuffers.Builder(); 666 | fbb.finish(rootGenerator(fbb, context, requireObject(json)), schema.fileIdent); 667 | return fbb.asUint8Array(); 668 | }, 669 | 670 | parse: function(bytes) { 671 | var bb = new flatbuffers.ByteBuffer(requireUint8Array(bytes)); 672 | return rootParser(bb, context, bb.readInt32(bb.position()) + bb.position()); 673 | }, 674 | }; 675 | }; 676 | -------------------------------------------------------------------------------- /src/reflection_generated.js: -------------------------------------------------------------------------------- 1 | // automatically generated by the FlatBuffers compiler, do not modify 2 | 3 | /** 4 | * @const 5 | */ 6 | var reflection = reflection || {}; 7 | 8 | /** 9 | * @enum 10 | */ 11 | reflection.BaseType = { 12 | None: 0, 13 | UType: 1, 14 | Bool: 2, 15 | Byte: 3, 16 | UByte: 4, 17 | Short: 5, 18 | UShort: 6, 19 | Int: 7, 20 | UInt: 8, 21 | Long: 9, 22 | ULong: 10, 23 | Float: 11, 24 | Double: 12, 25 | String: 13, 26 | Vector: 14, 27 | Obj: 15, 28 | Union: 16 29 | }; 30 | 31 | /** 32 | * @constructor 33 | */ 34 | reflection.Type = function() { 35 | /** 36 | * @type {flatbuffers.ByteBuffer} 37 | */ 38 | this.bb = null; 39 | 40 | /** 41 | * @type {number} 42 | */ 43 | this.bb_pos = 0; 44 | }; 45 | 46 | /** 47 | * @param {number} i 48 | * @param {flatbuffers.ByteBuffer} bb 49 | * @returns {reflection.Type} 50 | */ 51 | reflection.Type.prototype.__init = function(i, bb) { 52 | this.bb_pos = i; 53 | this.bb = bb; 54 | return this; 55 | }; 56 | 57 | /** 58 | * @param {flatbuffers.ByteBuffer} bb 59 | * @param {reflection.Type=} obj 60 | * @returns {reflection.Type} 61 | */ 62 | reflection.Type.getRootAsType = function(bb, obj) { 63 | return (obj || new reflection.Type).__init(bb.readInt32(bb.position()) + bb.position(), bb); 64 | }; 65 | 66 | /** 67 | * @returns {reflection.BaseType} 68 | */ 69 | reflection.Type.prototype.baseType = function() { 70 | var offset = this.bb.__offset(this.bb_pos, 4); 71 | return offset ? /** @type {reflection.BaseType} */ (this.bb.readInt8(this.bb_pos + offset)) : reflection.BaseType.None; 72 | }; 73 | 74 | /** 75 | * @returns {reflection.BaseType} 76 | */ 77 | reflection.Type.prototype.element = function() { 78 | var offset = this.bb.__offset(this.bb_pos, 6); 79 | return offset ? /** @type {reflection.BaseType} */ (this.bb.readInt8(this.bb_pos + offset)) : reflection.BaseType.None; 80 | }; 81 | 82 | /** 83 | * @returns {number} 84 | */ 85 | reflection.Type.prototype.index = function() { 86 | var offset = this.bb.__offset(this.bb_pos, 8); 87 | return offset ? this.bb.readInt32(this.bb_pos + offset) : -1; 88 | }; 89 | 90 | /** 91 | * @param {flatbuffers.Builder} builder 92 | */ 93 | reflection.Type.startType = function(builder) { 94 | builder.startObject(3); 95 | }; 96 | 97 | /** 98 | * @param {flatbuffers.Builder} builder 99 | * @param {reflection.BaseType} baseType 100 | */ 101 | reflection.Type.addBaseType = function(builder, baseType) { 102 | builder.addFieldInt8(0, baseType, reflection.BaseType.None); 103 | }; 104 | 105 | /** 106 | * @param {flatbuffers.Builder} builder 107 | * @param {reflection.BaseType} element 108 | */ 109 | reflection.Type.addElement = function(builder, element) { 110 | builder.addFieldInt8(1, element, reflection.BaseType.None); 111 | }; 112 | 113 | /** 114 | * @param {flatbuffers.Builder} builder 115 | * @param {number} index 116 | */ 117 | reflection.Type.addIndex = function(builder, index) { 118 | builder.addFieldInt32(2, index, -1); 119 | }; 120 | 121 | /** 122 | * @param {flatbuffers.Builder} builder 123 | * @returns {flatbuffers.Offset} 124 | */ 125 | reflection.Type.endType = function(builder) { 126 | var offset = builder.endObject(); 127 | return offset; 128 | }; 129 | 130 | /** 131 | * @constructor 132 | */ 133 | reflection.EnumVal = function() { 134 | /** 135 | * @type {flatbuffers.ByteBuffer} 136 | */ 137 | this.bb = null; 138 | 139 | /** 140 | * @type {number} 141 | */ 142 | this.bb_pos = 0; 143 | }; 144 | 145 | /** 146 | * @param {number} i 147 | * @param {flatbuffers.ByteBuffer} bb 148 | * @returns {reflection.EnumVal} 149 | */ 150 | reflection.EnumVal.prototype.__init = function(i, bb) { 151 | this.bb_pos = i; 152 | this.bb = bb; 153 | return this; 154 | }; 155 | 156 | /** 157 | * @param {flatbuffers.ByteBuffer} bb 158 | * @param {reflection.EnumVal=} obj 159 | * @returns {reflection.EnumVal} 160 | */ 161 | reflection.EnumVal.getRootAsEnumVal = function(bb, obj) { 162 | return (obj || new reflection.EnumVal).__init(bb.readInt32(bb.position()) + bb.position(), bb); 163 | }; 164 | 165 | /** 166 | * @param {flatbuffers.Encoding=} optionalEncoding 167 | * @returns {string|Uint8Array} 168 | */ 169 | reflection.EnumVal.prototype.name = function(optionalEncoding) { 170 | var offset = this.bb.__offset(this.bb_pos, 4); 171 | return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; 172 | }; 173 | 174 | /** 175 | * @returns {flatbuffers.Long} 176 | */ 177 | reflection.EnumVal.prototype.value = function() { 178 | var offset = this.bb.__offset(this.bb_pos, 6); 179 | return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0); 180 | }; 181 | 182 | /** 183 | * @param {reflection.Object=} obj 184 | * @returns {reflection.Object} 185 | */ 186 | reflection.EnumVal.prototype.object = function(obj) { 187 | var offset = this.bb.__offset(this.bb_pos, 8); 188 | return offset ? (obj || new reflection.Object).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; 189 | }; 190 | 191 | /** 192 | * @param {flatbuffers.Builder} builder 193 | */ 194 | reflection.EnumVal.startEnumVal = function(builder) { 195 | builder.startObject(3); 196 | }; 197 | 198 | /** 199 | * @param {flatbuffers.Builder} builder 200 | * @param {flatbuffers.Offset} nameOffset 201 | */ 202 | reflection.EnumVal.addName = function(builder, nameOffset) { 203 | builder.addFieldOffset(0, nameOffset, 0); 204 | }; 205 | 206 | /** 207 | * @param {flatbuffers.Builder} builder 208 | * @param {flatbuffers.Long} value 209 | */ 210 | reflection.EnumVal.addValue = function(builder, value) { 211 | builder.addFieldInt64(1, value, builder.createLong(0, 0)); 212 | }; 213 | 214 | /** 215 | * @param {flatbuffers.Builder} builder 216 | * @param {flatbuffers.Offset} objectOffset 217 | */ 218 | reflection.EnumVal.addObject = function(builder, objectOffset) { 219 | builder.addFieldOffset(2, objectOffset, 0); 220 | }; 221 | 222 | /** 223 | * @param {flatbuffers.Builder} builder 224 | * @returns {flatbuffers.Offset} 225 | */ 226 | reflection.EnumVal.endEnumVal = function(builder) { 227 | var offset = builder.endObject(); 228 | builder.requiredField(offset, 4); // name 229 | return offset; 230 | }; 231 | 232 | /** 233 | * @constructor 234 | */ 235 | reflection.Enum = function() { 236 | /** 237 | * @type {flatbuffers.ByteBuffer} 238 | */ 239 | this.bb = null; 240 | 241 | /** 242 | * @type {number} 243 | */ 244 | this.bb_pos = 0; 245 | }; 246 | 247 | /** 248 | * @param {number} i 249 | * @param {flatbuffers.ByteBuffer} bb 250 | * @returns {reflection.Enum} 251 | */ 252 | reflection.Enum.prototype.__init = function(i, bb) { 253 | this.bb_pos = i; 254 | this.bb = bb; 255 | return this; 256 | }; 257 | 258 | /** 259 | * @param {flatbuffers.ByteBuffer} bb 260 | * @param {reflection.Enum=} obj 261 | * @returns {reflection.Enum} 262 | */ 263 | reflection.Enum.getRootAsEnum = function(bb, obj) { 264 | return (obj || new reflection.Enum).__init(bb.readInt32(bb.position()) + bb.position(), bb); 265 | }; 266 | 267 | /** 268 | * @param {flatbuffers.Encoding=} optionalEncoding 269 | * @returns {string|Uint8Array} 270 | */ 271 | reflection.Enum.prototype.name = function(optionalEncoding) { 272 | var offset = this.bb.__offset(this.bb_pos, 4); 273 | return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; 274 | }; 275 | 276 | /** 277 | * @param {number} index 278 | * @param {reflection.EnumVal=} obj 279 | * @returns {reflection.EnumVal} 280 | */ 281 | reflection.Enum.prototype.values = function(index, obj) { 282 | var offset = this.bb.__offset(this.bb_pos, 6); 283 | return offset ? (obj || new reflection.EnumVal).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; 284 | }; 285 | 286 | /** 287 | * @returns {number} 288 | */ 289 | reflection.Enum.prototype.valuesLength = function() { 290 | var offset = this.bb.__offset(this.bb_pos, 6); 291 | return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; 292 | }; 293 | 294 | /** 295 | * @returns {boolean} 296 | */ 297 | reflection.Enum.prototype.isUnion = function() { 298 | var offset = this.bb.__offset(this.bb_pos, 8); 299 | return offset ? !!this.bb.readInt8(this.bb_pos + offset) : false; 300 | }; 301 | 302 | /** 303 | * @param {reflection.Type=} obj 304 | * @returns {reflection.Type} 305 | */ 306 | reflection.Enum.prototype.underlyingType = function(obj) { 307 | var offset = this.bb.__offset(this.bb_pos, 10); 308 | return offset ? (obj || new reflection.Type).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; 309 | }; 310 | 311 | /** 312 | * @param {flatbuffers.Builder} builder 313 | */ 314 | reflection.Enum.startEnum = function(builder) { 315 | builder.startObject(4); 316 | }; 317 | 318 | /** 319 | * @param {flatbuffers.Builder} builder 320 | * @param {flatbuffers.Offset} nameOffset 321 | */ 322 | reflection.Enum.addName = function(builder, nameOffset) { 323 | builder.addFieldOffset(0, nameOffset, 0); 324 | }; 325 | 326 | /** 327 | * @param {flatbuffers.Builder} builder 328 | * @param {flatbuffers.Offset} valuesOffset 329 | */ 330 | reflection.Enum.addValues = function(builder, valuesOffset) { 331 | builder.addFieldOffset(1, valuesOffset, 0); 332 | }; 333 | 334 | /** 335 | * @param {flatbuffers.Builder} builder 336 | * @param {Array.} data 337 | * @returns {flatbuffers.Offset} 338 | */ 339 | reflection.Enum.createValuesVector = function(builder, data) { 340 | builder.startVector(4, data.length, 4); 341 | for (var i = data.length - 1; i >= 0; i--) { 342 | builder.addOffset(data[i]); 343 | } 344 | return builder.endVector(); 345 | }; 346 | 347 | /** 348 | * @param {flatbuffers.Builder} builder 349 | * @param {number} numElems 350 | */ 351 | reflection.Enum.startValuesVector = function(builder, numElems) { 352 | builder.startVector(4, numElems, 4); 353 | }; 354 | 355 | /** 356 | * @param {flatbuffers.Builder} builder 357 | * @param {boolean} isUnion 358 | */ 359 | reflection.Enum.addIsUnion = function(builder, isUnion) { 360 | builder.addFieldInt8(2, +isUnion, +false); 361 | }; 362 | 363 | /** 364 | * @param {flatbuffers.Builder} builder 365 | * @param {flatbuffers.Offset} underlyingTypeOffset 366 | */ 367 | reflection.Enum.addUnderlyingType = function(builder, underlyingTypeOffset) { 368 | builder.addFieldOffset(3, underlyingTypeOffset, 0); 369 | }; 370 | 371 | /** 372 | * @param {flatbuffers.Builder} builder 373 | * @returns {flatbuffers.Offset} 374 | */ 375 | reflection.Enum.endEnum = function(builder) { 376 | var offset = builder.endObject(); 377 | builder.requiredField(offset, 4); // name 378 | builder.requiredField(offset, 6); // values 379 | builder.requiredField(offset, 10); // underlying_type 380 | return offset; 381 | }; 382 | 383 | /** 384 | * @constructor 385 | */ 386 | reflection.Field = function() { 387 | /** 388 | * @type {flatbuffers.ByteBuffer} 389 | */ 390 | this.bb = null; 391 | 392 | /** 393 | * @type {number} 394 | */ 395 | this.bb_pos = 0; 396 | }; 397 | 398 | /** 399 | * @param {number} i 400 | * @param {flatbuffers.ByteBuffer} bb 401 | * @returns {reflection.Field} 402 | */ 403 | reflection.Field.prototype.__init = function(i, bb) { 404 | this.bb_pos = i; 405 | this.bb = bb; 406 | return this; 407 | }; 408 | 409 | /** 410 | * @param {flatbuffers.ByteBuffer} bb 411 | * @param {reflection.Field=} obj 412 | * @returns {reflection.Field} 413 | */ 414 | reflection.Field.getRootAsField = function(bb, obj) { 415 | return (obj || new reflection.Field).__init(bb.readInt32(bb.position()) + bb.position(), bb); 416 | }; 417 | 418 | /** 419 | * @param {flatbuffers.Encoding=} optionalEncoding 420 | * @returns {string|Uint8Array} 421 | */ 422 | reflection.Field.prototype.name = function(optionalEncoding) { 423 | var offset = this.bb.__offset(this.bb_pos, 4); 424 | return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; 425 | }; 426 | 427 | /** 428 | * @param {reflection.Type=} obj 429 | * @returns {reflection.Type} 430 | */ 431 | reflection.Field.prototype.type = function(obj) { 432 | var offset = this.bb.__offset(this.bb_pos, 6); 433 | return offset ? (obj || new reflection.Type).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; 434 | }; 435 | 436 | /** 437 | * @returns {number} 438 | */ 439 | reflection.Field.prototype.id = function() { 440 | var offset = this.bb.__offset(this.bb_pos, 8); 441 | return offset ? this.bb.readUint16(this.bb_pos + offset) : 0; 442 | }; 443 | 444 | /** 445 | * @returns {number} 446 | */ 447 | reflection.Field.prototype.offset = function() { 448 | var offset = this.bb.__offset(this.bb_pos, 10); 449 | return offset ? this.bb.readUint16(this.bb_pos + offset) : 0; 450 | }; 451 | 452 | /** 453 | * @returns {flatbuffers.Long} 454 | */ 455 | reflection.Field.prototype.defaultInteger = function() { 456 | var offset = this.bb.__offset(this.bb_pos, 12); 457 | return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0); 458 | }; 459 | 460 | /** 461 | * @returns {number} 462 | */ 463 | reflection.Field.prototype.defaultReal = function() { 464 | var offset = this.bb.__offset(this.bb_pos, 14); 465 | return offset ? this.bb.readFloat64(this.bb_pos + offset) : 0.0; 466 | }; 467 | 468 | /** 469 | * @returns {boolean} 470 | */ 471 | reflection.Field.prototype.deprecated = function() { 472 | var offset = this.bb.__offset(this.bb_pos, 16); 473 | return offset ? !!this.bb.readInt8(this.bb_pos + offset) : false; 474 | }; 475 | 476 | /** 477 | * @returns {boolean} 478 | */ 479 | reflection.Field.prototype.required = function() { 480 | var offset = this.bb.__offset(this.bb_pos, 18); 481 | return offset ? !!this.bb.readInt8(this.bb_pos + offset) : false; 482 | }; 483 | 484 | /** 485 | * @returns {boolean} 486 | */ 487 | reflection.Field.prototype.key = function() { 488 | var offset = this.bb.__offset(this.bb_pos, 20); 489 | return offset ? !!this.bb.readInt8(this.bb_pos + offset) : false; 490 | }; 491 | 492 | /** 493 | * @param {flatbuffers.Builder} builder 494 | */ 495 | reflection.Field.startField = function(builder) { 496 | builder.startObject(9); 497 | }; 498 | 499 | /** 500 | * @param {flatbuffers.Builder} builder 501 | * @param {flatbuffers.Offset} nameOffset 502 | */ 503 | reflection.Field.addName = function(builder, nameOffset) { 504 | builder.addFieldOffset(0, nameOffset, 0); 505 | }; 506 | 507 | /** 508 | * @param {flatbuffers.Builder} builder 509 | * @param {flatbuffers.Offset} typeOffset 510 | */ 511 | reflection.Field.addType = function(builder, typeOffset) { 512 | builder.addFieldOffset(1, typeOffset, 0); 513 | }; 514 | 515 | /** 516 | * @param {flatbuffers.Builder} builder 517 | * @param {number} id 518 | */ 519 | reflection.Field.addId = function(builder, id) { 520 | builder.addFieldInt16(2, id, 0); 521 | }; 522 | 523 | /** 524 | * @param {flatbuffers.Builder} builder 525 | * @param {number} offset 526 | */ 527 | reflection.Field.addOffset = function(builder, offset) { 528 | builder.addFieldInt16(3, offset, 0); 529 | }; 530 | 531 | /** 532 | * @param {flatbuffers.Builder} builder 533 | * @param {flatbuffers.Long} defaultInteger 534 | */ 535 | reflection.Field.addDefaultInteger = function(builder, defaultInteger) { 536 | builder.addFieldInt64(4, defaultInteger, builder.createLong(0, 0)); 537 | }; 538 | 539 | /** 540 | * @param {flatbuffers.Builder} builder 541 | * @param {number} defaultReal 542 | */ 543 | reflection.Field.addDefaultReal = function(builder, defaultReal) { 544 | builder.addFieldFloat64(5, defaultReal, 0.0); 545 | }; 546 | 547 | /** 548 | * @param {flatbuffers.Builder} builder 549 | * @param {boolean} deprecated 550 | */ 551 | reflection.Field.addDeprecated = function(builder, deprecated) { 552 | builder.addFieldInt8(6, +deprecated, +false); 553 | }; 554 | 555 | /** 556 | * @param {flatbuffers.Builder} builder 557 | * @param {boolean} required 558 | */ 559 | reflection.Field.addRequired = function(builder, required) { 560 | builder.addFieldInt8(7, +required, +false); 561 | }; 562 | 563 | /** 564 | * @param {flatbuffers.Builder} builder 565 | * @param {boolean} key 566 | */ 567 | reflection.Field.addKey = function(builder, key) { 568 | builder.addFieldInt8(8, +key, +false); 569 | }; 570 | 571 | /** 572 | * @param {flatbuffers.Builder} builder 573 | * @returns {flatbuffers.Offset} 574 | */ 575 | reflection.Field.endField = function(builder) { 576 | var offset = builder.endObject(); 577 | builder.requiredField(offset, 4); // name 578 | builder.requiredField(offset, 6); // type 579 | return offset; 580 | }; 581 | 582 | /** 583 | * @constructor 584 | */ 585 | reflection.Object = function() { 586 | /** 587 | * @type {flatbuffers.ByteBuffer} 588 | */ 589 | this.bb = null; 590 | 591 | /** 592 | * @type {number} 593 | */ 594 | this.bb_pos = 0; 595 | }; 596 | 597 | /** 598 | * @param {number} i 599 | * @param {flatbuffers.ByteBuffer} bb 600 | * @returns {reflection.Object} 601 | */ 602 | reflection.Object.prototype.__init = function(i, bb) { 603 | this.bb_pos = i; 604 | this.bb = bb; 605 | return this; 606 | }; 607 | 608 | /** 609 | * @param {flatbuffers.ByteBuffer} bb 610 | * @param {reflection.Object=} obj 611 | * @returns {reflection.Object} 612 | */ 613 | reflection.Object.getRootAsObject = function(bb, obj) { 614 | return (obj || new reflection.Object).__init(bb.readInt32(bb.position()) + bb.position(), bb); 615 | }; 616 | 617 | /** 618 | * @param {flatbuffers.Encoding=} optionalEncoding 619 | * @returns {string|Uint8Array} 620 | */ 621 | reflection.Object.prototype.name = function(optionalEncoding) { 622 | var offset = this.bb.__offset(this.bb_pos, 4); 623 | return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; 624 | }; 625 | 626 | /** 627 | * @param {number} index 628 | * @param {reflection.Field=} obj 629 | * @returns {reflection.Field} 630 | */ 631 | reflection.Object.prototype.fields = function(index, obj) { 632 | var offset = this.bb.__offset(this.bb_pos, 6); 633 | return offset ? (obj || new reflection.Field).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; 634 | }; 635 | 636 | /** 637 | * @returns {number} 638 | */ 639 | reflection.Object.prototype.fieldsLength = function() { 640 | var offset = this.bb.__offset(this.bb_pos, 6); 641 | return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; 642 | }; 643 | 644 | /** 645 | * @returns {boolean} 646 | */ 647 | reflection.Object.prototype.isStruct = function() { 648 | var offset = this.bb.__offset(this.bb_pos, 8); 649 | return offset ? !!this.bb.readInt8(this.bb_pos + offset) : false; 650 | }; 651 | 652 | /** 653 | * @returns {number} 654 | */ 655 | reflection.Object.prototype.minalign = function() { 656 | var offset = this.bb.__offset(this.bb_pos, 10); 657 | return offset ? this.bb.readInt32(this.bb_pos + offset) : 0; 658 | }; 659 | 660 | /** 661 | * @returns {number} 662 | */ 663 | reflection.Object.prototype.bytesize = function() { 664 | var offset = this.bb.__offset(this.bb_pos, 12); 665 | return offset ? this.bb.readInt32(this.bb_pos + offset) : 0; 666 | }; 667 | 668 | /** 669 | * @param {flatbuffers.Builder} builder 670 | */ 671 | reflection.Object.startObject = function(builder) { 672 | builder.startObject(5); 673 | }; 674 | 675 | /** 676 | * @param {flatbuffers.Builder} builder 677 | * @param {flatbuffers.Offset} nameOffset 678 | */ 679 | reflection.Object.addName = function(builder, nameOffset) { 680 | builder.addFieldOffset(0, nameOffset, 0); 681 | }; 682 | 683 | /** 684 | * @param {flatbuffers.Builder} builder 685 | * @param {flatbuffers.Offset} fieldsOffset 686 | */ 687 | reflection.Object.addFields = function(builder, fieldsOffset) { 688 | builder.addFieldOffset(1, fieldsOffset, 0); 689 | }; 690 | 691 | /** 692 | * @param {flatbuffers.Builder} builder 693 | * @param {Array.} data 694 | * @returns {flatbuffers.Offset} 695 | */ 696 | reflection.Object.createFieldsVector = function(builder, data) { 697 | builder.startVector(4, data.length, 4); 698 | for (var i = data.length - 1; i >= 0; i--) { 699 | builder.addOffset(data[i]); 700 | } 701 | return builder.endVector(); 702 | }; 703 | 704 | /** 705 | * @param {flatbuffers.Builder} builder 706 | * @param {number} numElems 707 | */ 708 | reflection.Object.startFieldsVector = function(builder, numElems) { 709 | builder.startVector(4, numElems, 4); 710 | }; 711 | 712 | /** 713 | * @param {flatbuffers.Builder} builder 714 | * @param {boolean} isStruct 715 | */ 716 | reflection.Object.addIsStruct = function(builder, isStruct) { 717 | builder.addFieldInt8(2, +isStruct, +false); 718 | }; 719 | 720 | /** 721 | * @param {flatbuffers.Builder} builder 722 | * @param {number} minalign 723 | */ 724 | reflection.Object.addMinalign = function(builder, minalign) { 725 | builder.addFieldInt32(3, minalign, 0); 726 | }; 727 | 728 | /** 729 | * @param {flatbuffers.Builder} builder 730 | * @param {number} bytesize 731 | */ 732 | reflection.Object.addBytesize = function(builder, bytesize) { 733 | builder.addFieldInt32(4, bytesize, 0); 734 | }; 735 | 736 | /** 737 | * @param {flatbuffers.Builder} builder 738 | * @returns {flatbuffers.Offset} 739 | */ 740 | reflection.Object.endObject = function(builder) { 741 | var offset = builder.endObject(); 742 | builder.requiredField(offset, 4); // name 743 | builder.requiredField(offset, 6); // fields 744 | return offset; 745 | }; 746 | 747 | /** 748 | * @constructor 749 | */ 750 | reflection.Schema = function() { 751 | /** 752 | * @type {flatbuffers.ByteBuffer} 753 | */ 754 | this.bb = null; 755 | 756 | /** 757 | * @type {number} 758 | */ 759 | this.bb_pos = 0; 760 | }; 761 | 762 | /** 763 | * @param {number} i 764 | * @param {flatbuffers.ByteBuffer} bb 765 | * @returns {reflection.Schema} 766 | */ 767 | reflection.Schema.prototype.__init = function(i, bb) { 768 | this.bb_pos = i; 769 | this.bb = bb; 770 | return this; 771 | }; 772 | 773 | /** 774 | * @param {flatbuffers.ByteBuffer} bb 775 | * @param {reflection.Schema=} obj 776 | * @returns {reflection.Schema} 777 | */ 778 | reflection.Schema.getRootAsSchema = function(bb, obj) { 779 | return (obj || new reflection.Schema).__init(bb.readInt32(bb.position()) + bb.position(), bb); 780 | }; 781 | 782 | /** 783 | * @param {flatbuffers.ByteBuffer} bb 784 | * @returns {boolean} 785 | */ 786 | reflection.Schema.bufferHasIdentifier = function(bb) { 787 | return bb.__has_identifier('BFBS'); 788 | }; 789 | 790 | /** 791 | * @param {number} index 792 | * @param {reflection.Object=} obj 793 | * @returns {reflection.Object} 794 | */ 795 | reflection.Schema.prototype.objects = function(index, obj) { 796 | var offset = this.bb.__offset(this.bb_pos, 4); 797 | return offset ? (obj || new reflection.Object).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; 798 | }; 799 | 800 | /** 801 | * @returns {number} 802 | */ 803 | reflection.Schema.prototype.objectsLength = function() { 804 | var offset = this.bb.__offset(this.bb_pos, 4); 805 | return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; 806 | }; 807 | 808 | /** 809 | * @param {number} index 810 | * @param {reflection.Enum=} obj 811 | * @returns {reflection.Enum} 812 | */ 813 | reflection.Schema.prototype.enums = function(index, obj) { 814 | var offset = this.bb.__offset(this.bb_pos, 6); 815 | return offset ? (obj || new reflection.Enum).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null; 816 | }; 817 | 818 | /** 819 | * @returns {number} 820 | */ 821 | reflection.Schema.prototype.enumsLength = function() { 822 | var offset = this.bb.__offset(this.bb_pos, 6); 823 | return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0; 824 | }; 825 | 826 | /** 827 | * @param {flatbuffers.Encoding=} optionalEncoding 828 | * @returns {string|Uint8Array} 829 | */ 830 | reflection.Schema.prototype.fileIdent = function(optionalEncoding) { 831 | var offset = this.bb.__offset(this.bb_pos, 8); 832 | return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; 833 | }; 834 | 835 | /** 836 | * @param {flatbuffers.Encoding=} optionalEncoding 837 | * @returns {string|Uint8Array} 838 | */ 839 | reflection.Schema.prototype.fileExt = function(optionalEncoding) { 840 | var offset = this.bb.__offset(this.bb_pos, 10); 841 | return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null; 842 | }; 843 | 844 | /** 845 | * @param {reflection.Object=} obj 846 | * @returns {reflection.Object} 847 | */ 848 | reflection.Schema.prototype.rootTable = function(obj) { 849 | var offset = this.bb.__offset(this.bb_pos, 12); 850 | return offset ? (obj || new reflection.Object).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null; 851 | }; 852 | 853 | /** 854 | * @param {flatbuffers.Builder} builder 855 | */ 856 | reflection.Schema.startSchema = function(builder) { 857 | builder.startObject(5); 858 | }; 859 | 860 | /** 861 | * @param {flatbuffers.Builder} builder 862 | * @param {flatbuffers.Offset} objectsOffset 863 | */ 864 | reflection.Schema.addObjects = function(builder, objectsOffset) { 865 | builder.addFieldOffset(0, objectsOffset, 0); 866 | }; 867 | 868 | /** 869 | * @param {flatbuffers.Builder} builder 870 | * @param {Array.} data 871 | * @returns {flatbuffers.Offset} 872 | */ 873 | reflection.Schema.createObjectsVector = function(builder, data) { 874 | builder.startVector(4, data.length, 4); 875 | for (var i = data.length - 1; i >= 0; i--) { 876 | builder.addOffset(data[i]); 877 | } 878 | return builder.endVector(); 879 | }; 880 | 881 | /** 882 | * @param {flatbuffers.Builder} builder 883 | * @param {number} numElems 884 | */ 885 | reflection.Schema.startObjectsVector = function(builder, numElems) { 886 | builder.startVector(4, numElems, 4); 887 | }; 888 | 889 | /** 890 | * @param {flatbuffers.Builder} builder 891 | * @param {flatbuffers.Offset} enumsOffset 892 | */ 893 | reflection.Schema.addEnums = function(builder, enumsOffset) { 894 | builder.addFieldOffset(1, enumsOffset, 0); 895 | }; 896 | 897 | /** 898 | * @param {flatbuffers.Builder} builder 899 | * @param {Array.} data 900 | * @returns {flatbuffers.Offset} 901 | */ 902 | reflection.Schema.createEnumsVector = function(builder, data) { 903 | builder.startVector(4, data.length, 4); 904 | for (var i = data.length - 1; i >= 0; i--) { 905 | builder.addOffset(data[i]); 906 | } 907 | return builder.endVector(); 908 | }; 909 | 910 | /** 911 | * @param {flatbuffers.Builder} builder 912 | * @param {number} numElems 913 | */ 914 | reflection.Schema.startEnumsVector = function(builder, numElems) { 915 | builder.startVector(4, numElems, 4); 916 | }; 917 | 918 | /** 919 | * @param {flatbuffers.Builder} builder 920 | * @param {flatbuffers.Offset} fileIdentOffset 921 | */ 922 | reflection.Schema.addFileIdent = function(builder, fileIdentOffset) { 923 | builder.addFieldOffset(2, fileIdentOffset, 0); 924 | }; 925 | 926 | /** 927 | * @param {flatbuffers.Builder} builder 928 | * @param {flatbuffers.Offset} fileExtOffset 929 | */ 930 | reflection.Schema.addFileExt = function(builder, fileExtOffset) { 931 | builder.addFieldOffset(3, fileExtOffset, 0); 932 | }; 933 | 934 | /** 935 | * @param {flatbuffers.Builder} builder 936 | * @param {flatbuffers.Offset} rootTableOffset 937 | */ 938 | reflection.Schema.addRootTable = function(builder, rootTableOffset) { 939 | builder.addFieldOffset(4, rootTableOffset, 0); 940 | }; 941 | 942 | /** 943 | * @param {flatbuffers.Builder} builder 944 | * @returns {flatbuffers.Offset} 945 | */ 946 | reflection.Schema.endSchema = function(builder) { 947 | var offset = builder.endObject(); 948 | builder.requiredField(offset, 4); // objects 949 | builder.requiredField(offset, 6); // enums 950 | return offset; 951 | }; 952 | 953 | /** 954 | * @param {flatbuffers.Builder} builder 955 | * @param {flatbuffers.Offset} offset 956 | */ 957 | reflection.Schema.finishSchemaBuffer = function(builder, offset) { 958 | builder.finish(offset, 'BFBS'); 959 | }; 960 | 961 | // Exports for Node.js and RequireJS 962 | this.reflection = reflection; 963 | -------------------------------------------------------------------------------- /src/flatbuffers.js: -------------------------------------------------------------------------------- 1 | /// @file 2 | /// @addtogroup flatbuffers_javascript_api 3 | /// @{ 4 | /// @cond FLATBUFFERS_INTERNAL 5 | var flatbuffers = {}; 6 | 7 | /** 8 | * @typedef {number} 9 | */ 10 | flatbuffers.Offset; 11 | 12 | /** 13 | * @typedef {{ 14 | * bb: flatbuffers.ByteBuffer, 15 | * bb_pos: number 16 | * }} 17 | */ 18 | flatbuffers.Table; 19 | 20 | /** 21 | * @type {number} 22 | * @const 23 | */ 24 | flatbuffers.SIZEOF_SHORT = 2; 25 | 26 | /** 27 | * @type {number} 28 | * @const 29 | */ 30 | flatbuffers.SIZEOF_INT = 4; 31 | 32 | /** 33 | * @type {number} 34 | * @const 35 | */ 36 | flatbuffers.FILE_IDENTIFIER_LENGTH = 4; 37 | 38 | /** 39 | * @enum {number} 40 | */ 41 | flatbuffers.Encoding = { 42 | UTF8_BYTES: 1, 43 | UTF16_STRING: 2 44 | }; 45 | 46 | /** 47 | * @type {Int32Array} 48 | * @const 49 | */ 50 | flatbuffers.int32 = new Int32Array(2); 51 | 52 | /** 53 | * @type {Float32Array} 54 | * @const 55 | */ 56 | flatbuffers.float32 = new Float32Array(flatbuffers.int32.buffer); 57 | 58 | /** 59 | * @type {Float64Array} 60 | * @const 61 | */ 62 | flatbuffers.float64 = new Float64Array(flatbuffers.int32.buffer); 63 | 64 | /** 65 | * @type {boolean} 66 | * @const 67 | */ 68 | flatbuffers.isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1; 69 | 70 | //////////////////////////////////////////////////////////////////////////////// 71 | 72 | /** 73 | * @constructor 74 | * @param {number} high 75 | * @param {number} low 76 | */ 77 | flatbuffers.Long = function(low, high) { 78 | /** 79 | * @type {number} 80 | * @const 81 | */ 82 | this.low = low | 0; 83 | 84 | /** 85 | * @type {number} 86 | * @const 87 | */ 88 | this.high = high | 0; 89 | }; 90 | 91 | /** 92 | * @param {number} high 93 | * @param {number} low 94 | * @returns {flatbuffers.Long} 95 | */ 96 | flatbuffers.Long.create = function(low, high) { 97 | // Special-case zero to avoid GC overhead for default values 98 | return low == 0 && high == 0 ? flatbuffers.Long.ZERO : new flatbuffers.Long(low, high); 99 | }; 100 | 101 | /** 102 | * @returns {number} 103 | */ 104 | flatbuffers.Long.prototype.toFloat64 = function() { 105 | return this.low + this.high * 0x100000000; 106 | }; 107 | 108 | /** 109 | * @param {flatbuffers.Long} other 110 | * @returns {boolean} 111 | */ 112 | flatbuffers.Long.prototype.equals = function(other) { 113 | return this.low == other.low && this.high == other.high; 114 | }; 115 | 116 | /** 117 | * @type {flatbuffers.Long} 118 | * @const 119 | */ 120 | flatbuffers.Long.ZERO = new flatbuffers.Long(0, 0); 121 | 122 | /// @endcond 123 | //////////////////////////////////////////////////////////////////////////////// 124 | /** 125 | * Create a FlatBufferBuilder. 126 | * 127 | * @constructor 128 | * @param {number=} initial_size 129 | */ 130 | flatbuffers.Builder = function(initial_size) { 131 | if (!initial_size) { 132 | initial_size = 1024; 133 | } 134 | 135 | /** 136 | * @type {flatbuffers.ByteBuffer} 137 | * @private 138 | */ 139 | this.bb = flatbuffers.ByteBuffer.allocate(initial_size); 140 | 141 | /** 142 | * Remaining space in the ByteBuffer. 143 | * 144 | * @type {number} 145 | * @private 146 | */ 147 | this.space = initial_size; 148 | 149 | /** 150 | * Minimum alignment encountered so far. 151 | * 152 | * @type {number} 153 | * @private 154 | */ 155 | this.minalign = 1; 156 | 157 | /** 158 | * The vtable for the current table. 159 | * 160 | * @type {Array.} 161 | * @private 162 | */ 163 | this.vtable = null; 164 | 165 | /** 166 | * The amount of fields we're actually using. 167 | * 168 | * @type {number} 169 | * @private 170 | */ 171 | this.vtable_in_use = 0; 172 | 173 | /** 174 | * Whether we are currently serializing a table. 175 | * 176 | * @type {boolean} 177 | * @private 178 | */ 179 | this.isNested = false; 180 | 181 | /** 182 | * Starting offset of the current struct/table. 183 | * 184 | * @type {number} 185 | * @private 186 | */ 187 | this.object_start = 0; 188 | 189 | /** 190 | * List of offsets of all vtables. 191 | * 192 | * @type {Array.} 193 | * @private 194 | */ 195 | this.vtables = []; 196 | 197 | /** 198 | * For the current vector being built. 199 | * 200 | * @type {number} 201 | * @private 202 | */ 203 | this.vector_num_elems = 0; 204 | 205 | /** 206 | * False omits default values from the serialized data 207 | * 208 | * @type {boolean} 209 | * @private 210 | */ 211 | this.force_defaults = false; 212 | }; 213 | 214 | /** 215 | * In order to save space, fields that are set to their default value 216 | * don't get serialized into the buffer. Forcing defaults provides a 217 | * way to manually disable this optimization. 218 | * 219 | * @param {boolean} forceDefaults true always serializes default values 220 | */ 221 | flatbuffers.Builder.prototype.forceDefaults = function(forceDefaults) { 222 | this.force_defaults = forceDefaults; 223 | }; 224 | 225 | /** 226 | * Get the ByteBuffer representing the FlatBuffer. Only call this after you've 227 | * called finish(). The actual data starts at the ByteBuffer's current position, 228 | * not necessarily at 0. 229 | * 230 | * @returns {flatbuffers.ByteBuffer} 231 | */ 232 | flatbuffers.Builder.prototype.dataBuffer = function() { 233 | return this.bb; 234 | }; 235 | 236 | /** 237 | * Get the ByteBuffer representing the FlatBuffer. Only call this after you've 238 | * called finish(). The actual data starts at the ByteBuffer's current position, 239 | * not necessarily at 0. 240 | * 241 | * @returns {Uint8Array} 242 | */ 243 | flatbuffers.Builder.prototype.asUint8Array = function() { 244 | return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset()); 245 | }; 246 | 247 | /// @cond FLATBUFFERS_INTERNAL 248 | /** 249 | * Prepare to write an element of `size` after `additional_bytes` have been 250 | * written, e.g. if you write a string, you need to align such the int length 251 | * field is aligned to 4 bytes, and the string data follows it directly. If all 252 | * you need to do is alignment, `additional_bytes` will be 0. 253 | * 254 | * @param {number} size This is the of the new element to write 255 | * @param {number} additional_bytes The padding size 256 | */ 257 | flatbuffers.Builder.prototype.prep = function(size, additional_bytes) { 258 | // Track the biggest thing we've ever aligned to. 259 | if (size > this.minalign) { 260 | this.minalign = size; 261 | } 262 | 263 | // Find the amount of alignment needed such that `size` is properly 264 | // aligned after `additional_bytes` 265 | var align_size = ((~(this.bb.capacity() - this.space + additional_bytes)) + 1) & (size - 1); 266 | 267 | // Reallocate the buffer if needed. 268 | while (this.space < align_size + size + additional_bytes) { 269 | var old_buf_size = this.bb.capacity(); 270 | this.bb = flatbuffers.Builder.growByteBuffer(this.bb); 271 | this.space += this.bb.capacity() - old_buf_size; 272 | } 273 | 274 | this.pad(align_size); 275 | }; 276 | 277 | /** 278 | * @param {number} byte_size 279 | */ 280 | flatbuffers.Builder.prototype.pad = function(byte_size) { 281 | for (var i = 0; i < byte_size; i++) { 282 | this.bb.writeInt8(--this.space, 0); 283 | } 284 | }; 285 | 286 | /** 287 | * @param {number} value 288 | */ 289 | flatbuffers.Builder.prototype.writeInt8 = function(value) { 290 | this.bb.writeInt8(this.space -= 1, value); 291 | }; 292 | 293 | /** 294 | * @param {number} value 295 | */ 296 | flatbuffers.Builder.prototype.writeInt16 = function(value) { 297 | this.bb.writeInt16(this.space -= 2, value); 298 | }; 299 | 300 | /** 301 | * @param {number} value 302 | */ 303 | flatbuffers.Builder.prototype.writeInt32 = function(value) { 304 | this.bb.writeInt32(this.space -= 4, value); 305 | }; 306 | 307 | /** 308 | * @param {flatbuffers.Long} value 309 | */ 310 | flatbuffers.Builder.prototype.writeInt64 = function(value) { 311 | this.bb.writeInt64(this.space -= 8, value); 312 | }; 313 | 314 | /** 315 | * @param {number} value 316 | */ 317 | flatbuffers.Builder.prototype.writeFloat32 = function(value) { 318 | this.bb.writeFloat32(this.space -= 4, value); 319 | }; 320 | 321 | /** 322 | * @param {number} value 323 | */ 324 | flatbuffers.Builder.prototype.writeFloat64 = function(value) { 325 | this.bb.writeFloat64(this.space -= 8, value); 326 | }; 327 | /// @endcond 328 | 329 | /** 330 | * Add an `int8` to the buffer, properly aligned, and grows the buffer (if necessary). 331 | * @param {number} value The `int8` to add the the buffer. 332 | */ 333 | flatbuffers.Builder.prototype.addInt8 = function(value) { 334 | this.prep(1, 0); 335 | this.writeInt8(value); 336 | }; 337 | 338 | /** 339 | * Add an `int16` to the buffer, properly aligned, and grows the buffer (if necessary). 340 | * @param {number} value The `int16` to add the the buffer. 341 | */ 342 | flatbuffers.Builder.prototype.addInt16 = function(value) { 343 | this.prep(2, 0); 344 | this.writeInt16(value); 345 | }; 346 | 347 | /** 348 | * Add an `int32` to the buffer, properly aligned, and grows the buffer (if necessary). 349 | * @param {number} value The `int32` to add the the buffer. 350 | */ 351 | flatbuffers.Builder.prototype.addInt32 = function(value) { 352 | this.prep(4, 0); 353 | this.writeInt32(value); 354 | }; 355 | 356 | /** 357 | * Add an `int64` to the buffer, properly aligned, and grows the buffer (if necessary). 358 | * @param {flatbuffers.Long} value The `int64` to add the the buffer. 359 | */ 360 | flatbuffers.Builder.prototype.addInt64 = function(value) { 361 | this.prep(8, 0); 362 | this.writeInt64(value); 363 | }; 364 | 365 | /** 366 | * Add a `float32` to the buffer, properly aligned, and grows the buffer (if necessary). 367 | * @param {number} value The `float32` to add the the buffer. 368 | */ 369 | flatbuffers.Builder.prototype.addFloat32 = function(value) { 370 | this.prep(4, 0); 371 | this.writeFloat32(value); 372 | }; 373 | 374 | /** 375 | * Add a `float64` to the buffer, properly aligned, and grows the buffer (if necessary). 376 | * @param {number} value The `float64` to add the the buffer. 377 | */ 378 | flatbuffers.Builder.prototype.addFloat64 = function(value) { 379 | this.prep(8, 0); 380 | this.writeFloat64(value); 381 | }; 382 | 383 | /// @cond FLATBUFFERS_INTERNAL 384 | /** 385 | * @param {number} voffset 386 | * @param {number} value 387 | * @param {number} defaultValue 388 | */ 389 | flatbuffers.Builder.prototype.addFieldInt8 = function(voffset, value, defaultValue) { 390 | if (this.force_defaults || value != defaultValue) { 391 | this.addInt8(value); 392 | this.slot(voffset); 393 | } 394 | }; 395 | 396 | /** 397 | * @param {number} voffset 398 | * @param {number} value 399 | * @param {number} defaultValue 400 | */ 401 | flatbuffers.Builder.prototype.addFieldInt16 = function(voffset, value, defaultValue) { 402 | if (this.force_defaults || value != defaultValue) { 403 | this.addInt16(value); 404 | this.slot(voffset); 405 | } 406 | }; 407 | 408 | /** 409 | * @param {number} voffset 410 | * @param {number} value 411 | * @param {number} defaultValue 412 | */ 413 | flatbuffers.Builder.prototype.addFieldInt32 = function(voffset, value, defaultValue) { 414 | if (this.force_defaults || value != defaultValue) { 415 | this.addInt32(value); 416 | this.slot(voffset); 417 | } 418 | }; 419 | 420 | /** 421 | * @param {number} voffset 422 | * @param {flatbuffers.Long} value 423 | * @param {flatbuffers.Long} defaultValue 424 | */ 425 | flatbuffers.Builder.prototype.addFieldInt64 = function(voffset, value, defaultValue) { 426 | if (this.force_defaults || !value.equals(defaultValue)) { 427 | this.addInt64(value); 428 | this.slot(voffset); 429 | } 430 | }; 431 | 432 | /** 433 | * @param {number} voffset 434 | * @param {number} value 435 | * @param {number} defaultValue 436 | */ 437 | flatbuffers.Builder.prototype.addFieldFloat32 = function(voffset, value, defaultValue) { 438 | if (this.force_defaults || value != defaultValue) { 439 | this.addFloat32(value); 440 | this.slot(voffset); 441 | } 442 | }; 443 | 444 | /** 445 | * @param {number} voffset 446 | * @param {number} value 447 | * @param {number} defaultValue 448 | */ 449 | flatbuffers.Builder.prototype.addFieldFloat64 = function(voffset, value, defaultValue) { 450 | if (this.force_defaults || value != defaultValue) { 451 | this.addFloat64(value); 452 | this.slot(voffset); 453 | } 454 | }; 455 | 456 | /** 457 | * @param {number} voffset 458 | * @param {flatbuffers.Offset} value 459 | * @param {flatbuffers.Offset} defaultValue 460 | */ 461 | flatbuffers.Builder.prototype.addFieldOffset = function(voffset, value, defaultValue) { 462 | if (this.force_defaults || value != defaultValue) { 463 | this.addOffset(value); 464 | this.slot(voffset); 465 | } 466 | }; 467 | 468 | /** 469 | * Structs are stored inline, so nothing additional is being added. `d` is always 0. 470 | * 471 | * @param {number} voffset 472 | * @param {flatbuffers.Offset} value 473 | * @param {flatbuffers.Offset} defaultValue 474 | */ 475 | flatbuffers.Builder.prototype.addFieldStruct = function(voffset, value, defaultValue) { 476 | if (value != defaultValue) { 477 | this.nested(value); 478 | this.slot(voffset); 479 | } 480 | }; 481 | 482 | /** 483 | * Structures are always stored inline, they need to be created right 484 | * where they're used. You'll get this assertion failure if you 485 | * created it elsewhere. 486 | * 487 | * @param {flatbuffers.Offset} obj The offset of the created object 488 | */ 489 | flatbuffers.Builder.prototype.nested = function(obj) { 490 | if (obj != this.offset()) { 491 | throw new Error('FlatBuffers: struct must be serialized inline.'); 492 | } 493 | }; 494 | 495 | /** 496 | * Should not be creating any other object, string or vector 497 | * while an object is being constructed 498 | */ 499 | flatbuffers.Builder.prototype.notNested = function() { 500 | if (this.isNested) { 501 | throw new Error('FlatBuffers: object serialization must not be nested.'); 502 | } 503 | }; 504 | 505 | /** 506 | * Set the current vtable at `voffset` to the current location in the buffer. 507 | * 508 | * @param {number} voffset 509 | */ 510 | flatbuffers.Builder.prototype.slot = function(voffset) { 511 | this.vtable[voffset] = this.offset(); 512 | }; 513 | 514 | /** 515 | * @returns {flatbuffers.Offset} Offset relative to the end of the buffer. 516 | */ 517 | flatbuffers.Builder.prototype.offset = function() { 518 | return this.bb.capacity() - this.space; 519 | }; 520 | 521 | /** 522 | * Doubles the size of the backing ByteBuffer and copies the old data towards 523 | * the end of the new buffer (since we build the buffer backwards). 524 | * 525 | * @param {flatbuffers.ByteBuffer} bb The current buffer with the existing data 526 | * @returns {flatbuffers.ByteBuffer} A new byte buffer with the old data copied 527 | * to it. The data is located at the end of the buffer. 528 | */ 529 | flatbuffers.Builder.growByteBuffer = function(bb) { 530 | var old_buf_size = bb.capacity(); 531 | 532 | // Ensure we don't grow beyond what fits in an int. 533 | if (old_buf_size & 0xC0000000) { 534 | throw new Error('FlatBuffers: cannot grow buffer beyond 2 gigabytes.'); 535 | } 536 | 537 | var new_buf_size = old_buf_size << 1; 538 | var nbb = flatbuffers.ByteBuffer.allocate(new_buf_size); 539 | nbb.setPosition(new_buf_size - old_buf_size); 540 | nbb.bytes().set(bb.bytes(), new_buf_size - old_buf_size); 541 | return nbb; 542 | }; 543 | /// @endcond 544 | 545 | /** 546 | * Adds on offset, relative to where it will be written. 547 | * 548 | * @param {flatbuffers.Offset} offset The offset to add. 549 | */ 550 | flatbuffers.Builder.prototype.addOffset = function(offset) { 551 | this.prep(flatbuffers.SIZEOF_INT, 0); // Ensure alignment is already done. 552 | this.writeInt32(this.offset() - offset + flatbuffers.SIZEOF_INT); 553 | }; 554 | 555 | /// @cond FLATBUFFERS_INTERNAL 556 | /** 557 | * Start encoding a new object in the buffer. Users will not usually need to 558 | * call this directly. The FlatBuffers compiler will generate helper methods 559 | * that call this method internally. 560 | * 561 | * @param {number} numfields 562 | */ 563 | flatbuffers.Builder.prototype.startObject = function(numfields) { 564 | this.notNested(); 565 | if (this.vtable == null) { 566 | this.vtable = []; 567 | } 568 | this.vtable_in_use = numfields; 569 | for (var i = 0; i < numfields; i++) { 570 | this.vtable[i] = 0; // This will push additional elements as needed 571 | } 572 | this.isNested = true; 573 | this.object_start = this.offset(); 574 | }; 575 | 576 | /** 577 | * Finish off writing the object that is under construction. 578 | * 579 | * @returns {flatbuffers.Offset} The offset to the object inside `dataBuffer` 580 | */ 581 | flatbuffers.Builder.prototype.endObject = function() { 582 | if (this.vtable == null || !this.isNested) { 583 | throw new Error('FlatBuffers: endObject called without startObject'); 584 | } 585 | 586 | this.addInt32(0); 587 | var vtableloc = this.offset(); 588 | 589 | // Write out the current vtable. 590 | for (var i = this.vtable_in_use - 1; i >= 0; i--) { 591 | // Offset relative to the start of the table. 592 | this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0); 593 | } 594 | 595 | var standard_fields = 2; // The fields below: 596 | this.addInt16(vtableloc - this.object_start); 597 | this.addInt16((this.vtable_in_use + standard_fields) * flatbuffers.SIZEOF_SHORT); 598 | 599 | // Search for an existing vtable that matches the current one. 600 | var existing_vtable = 0; 601 | outer_loop: 602 | for (var i = 0; i < this.vtables.length; i++) { 603 | var vt1 = this.bb.capacity() - this.vtables[i]; 604 | var vt2 = this.space; 605 | var len = this.bb.readInt16(vt1); 606 | if (len == this.bb.readInt16(vt2)) { 607 | for (var j = flatbuffers.SIZEOF_SHORT; j < len; j += flatbuffers.SIZEOF_SHORT) { 608 | if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) { 609 | continue outer_loop; 610 | } 611 | } 612 | existing_vtable = this.vtables[i]; 613 | break; 614 | } 615 | } 616 | 617 | if (existing_vtable) { 618 | // Found a match: 619 | // Remove the current vtable. 620 | this.space = this.bb.capacity() - vtableloc; 621 | 622 | // Point table to existing vtable. 623 | this.bb.writeInt32(this.space, existing_vtable - vtableloc); 624 | } else { 625 | // No match: 626 | // Add the location of the current vtable to the list of vtables. 627 | this.vtables.push(this.offset()); 628 | 629 | // Point table to current vtable. 630 | this.bb.writeInt32(this.bb.capacity() - vtableloc, this.offset() - vtableloc); 631 | } 632 | 633 | this.isNested = false; 634 | return vtableloc; 635 | }; 636 | /// @endcond 637 | 638 | /** 639 | * Finalize a buffer, poiting to the given `root_table`. 640 | * 641 | * @param {flatbuffers.Offset} root_table 642 | * @param {string=} file_identifier 643 | */ 644 | flatbuffers.Builder.prototype.finish = function(root_table, file_identifier) { 645 | if (file_identifier) { 646 | this.prep(this.minalign, flatbuffers.SIZEOF_INT + 647 | flatbuffers.FILE_IDENTIFIER_LENGTH); 648 | if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) { 649 | throw new Error('FlatBuffers: file identifier must be length ' + 650 | flatbuffers.FILE_IDENTIFIER_LENGTH); 651 | } 652 | for (var i = flatbuffers.FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) { 653 | this.writeInt8(file_identifier.charCodeAt(i)); 654 | } 655 | } 656 | this.prep(this.minalign, flatbuffers.SIZEOF_INT); 657 | this.addOffset(root_table); 658 | this.bb.setPosition(this.space); 659 | }; 660 | 661 | /// @cond FLATBUFFERS_INTERNAL 662 | /** 663 | * This checks a required field has been set in a given table that has 664 | * just been constructed. 665 | * 666 | * @param {flatbuffers.Offset} table 667 | * @param {number} field 668 | * @param {string} name 669 | */ 670 | flatbuffers.Builder.prototype.requiredField = function(table, field, name) { 671 | var table_start = this.bb.capacity() - table; 672 | var vtable_start = table_start - this.bb.readInt32(table_start); 673 | var ok = this.bb.readInt16(vtable_start + field) != 0; 674 | 675 | // If this fails, the caller will show what field needs to be set. 676 | if (!ok) { 677 | throw new Error('FlatBuffers: field "' + name + '" must be set'); 678 | } 679 | }; 680 | 681 | /** 682 | * Start a new array/vector of objects. Users usually will not call 683 | * this directly. The FlatBuffers compiler will create a start/end 684 | * method for vector types in generated code. 685 | * 686 | * @param {number} elem_size The size of each element in the array 687 | * @param {number} num_elems The number of elements in the array 688 | * @param {number} alignment The alignment of the array 689 | */ 690 | flatbuffers.Builder.prototype.startVector = function(elem_size, num_elems, alignment) { 691 | this.notNested(); 692 | this.vector_num_elems = num_elems; 693 | this.prep(flatbuffers.SIZEOF_INT, elem_size * num_elems); 694 | this.prep(alignment, elem_size * num_elems); // Just in case alignment > int. 695 | }; 696 | 697 | /** 698 | * Finish off the creation of an array and all its elements. The array must be 699 | * created with `startVector`. 700 | * 701 | * @returns {flatbuffers.Offset} The offset at which the newly created array 702 | * starts. 703 | */ 704 | flatbuffers.Builder.prototype.endVector = function() { 705 | this.writeInt32(this.vector_num_elems); 706 | return this.offset(); 707 | }; 708 | /// @endcond 709 | 710 | /** 711 | * Encode the string `s` in the buffer using UTF-8. If a Uint8Array is passed 712 | * instead of a string, it is assumed to contain valid UTF-8 encoded data. 713 | * 714 | * @param {string|Uint8Array} s The string to encode 715 | * @return {flatbuffers.Offset} The offset in the buffer where the encoded string starts 716 | */ 717 | flatbuffers.Builder.prototype.createString = function(s) { 718 | if (s instanceof Uint8Array) { 719 | var utf8 = s; 720 | } else { 721 | var utf8 = []; 722 | var i = 0; 723 | 724 | while (i < s.length) { 725 | var codePoint; 726 | 727 | // Decode UTF-16 728 | var a = s.charCodeAt(i++); 729 | if (a < 0xD800 || a >= 0xDC00) { 730 | codePoint = a; 731 | } else { 732 | var b = s.charCodeAt(i++); 733 | codePoint = (a << 10) + b + (0x10000 - (0xD800 << 10) - 0xDC00); 734 | } 735 | 736 | // Encode UTF-8 737 | if (codePoint < 0x80) { 738 | utf8.push(codePoint); 739 | } else { 740 | if (codePoint < 0x800) { 741 | utf8.push(((codePoint >> 6) & 0x1F) | 0xC0); 742 | } else { 743 | if (codePoint < 0x10000) { 744 | utf8.push(((codePoint >> 12) & 0x0F) | 0xE0); 745 | } else { 746 | utf8.push( 747 | ((codePoint >> 18) & 0x07) | 0xF0, 748 | ((codePoint >> 12) & 0x3F) | 0x80); 749 | } 750 | utf8.push(((codePoint >> 6) & 0x3F) | 0x80); 751 | } 752 | utf8.push((codePoint & 0x3F) | 0x80); 753 | } 754 | } 755 | } 756 | 757 | this.addInt8(0); 758 | this.startVector(1, utf8.length, 1); 759 | this.bb.setPosition(this.space -= utf8.length); 760 | for (var i = 0, offset = this.space, bytes = this.bb.bytes(); i < utf8.length; i++) { 761 | bytes[offset++] = utf8[i]; 762 | } 763 | return this.endVector(); 764 | }; 765 | 766 | /** 767 | * A helper function to avoid generated code depending on this file directly. 768 | * 769 | * @param {number} low 770 | * @param {number} high 771 | * @returns {flatbuffers.Long} 772 | */ 773 | flatbuffers.Builder.prototype.createLong = function(low, high) { 774 | return flatbuffers.Long.create(low, high); 775 | }; 776 | //////////////////////////////////////////////////////////////////////////////// 777 | /// @cond FLATBUFFERS_INTERNAL 778 | /** 779 | * Create a new ByteBuffer with a given array of bytes (`Uint8Array`). 780 | * 781 | * @constructor 782 | * @param {Uint8Array} bytes 783 | */ 784 | flatbuffers.ByteBuffer = function(bytes) { 785 | /** 786 | * @type {Uint8Array} 787 | * @private 788 | */ 789 | this.bytes_ = bytes; 790 | 791 | /** 792 | * @type {number} 793 | * @private 794 | */ 795 | this.position_ = 0; 796 | }; 797 | 798 | /** 799 | * Create and allocate a new ByteBuffer with a given size. 800 | * 801 | * @param {number} byte_size 802 | * @returns {flatbuffers.ByteBuffer} 803 | */ 804 | flatbuffers.ByteBuffer.allocate = function(byte_size) { 805 | return new flatbuffers.ByteBuffer(new Uint8Array(byte_size)); 806 | }; 807 | 808 | /** 809 | * Get the underlying `Uint8Array`. 810 | * 811 | * @returns {Uint8Array} 812 | */ 813 | flatbuffers.ByteBuffer.prototype.bytes = function() { 814 | return this.bytes_; 815 | }; 816 | 817 | /** 818 | * Get the buffer's position. 819 | * 820 | * @returns {number} 821 | */ 822 | flatbuffers.ByteBuffer.prototype.position = function() { 823 | return this.position_; 824 | }; 825 | 826 | /** 827 | * Set the buffer's position. 828 | * 829 | * @param {number} position 830 | */ 831 | flatbuffers.ByteBuffer.prototype.setPosition = function(position) { 832 | this.position_ = position; 833 | }; 834 | 835 | /** 836 | * Get the buffer's capacity. 837 | * 838 | * @returns {number} 839 | */ 840 | flatbuffers.ByteBuffer.prototype.capacity = function() { 841 | return this.bytes_.length; 842 | }; 843 | 844 | /** 845 | * @param {number} offset 846 | * @returns {number} 847 | */ 848 | flatbuffers.ByteBuffer.prototype.readInt8 = function(offset) { 849 | return this.readUint8(offset) << 24 >> 24; 850 | }; 851 | 852 | /** 853 | * @param {number} offset 854 | * @returns {number} 855 | */ 856 | flatbuffers.ByteBuffer.prototype.readUint8 = function(offset) { 857 | return this.bytes_[offset]; 858 | }; 859 | 860 | /** 861 | * @param {number} offset 862 | * @returns {number} 863 | */ 864 | flatbuffers.ByteBuffer.prototype.readInt16 = function(offset) { 865 | return this.readUint16(offset) << 16 >> 16; 866 | }; 867 | 868 | /** 869 | * @param {number} offset 870 | * @returns {number} 871 | */ 872 | flatbuffers.ByteBuffer.prototype.readUint16 = function(offset) { 873 | return this.bytes_[offset] | this.bytes_[offset + 1] << 8; 874 | }; 875 | 876 | /** 877 | * @param {number} offset 878 | * @returns {number} 879 | */ 880 | flatbuffers.ByteBuffer.prototype.readInt32 = function(offset) { 881 | return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24; 882 | }; 883 | 884 | /** 885 | * @param {number} offset 886 | * @returns {number} 887 | */ 888 | flatbuffers.ByteBuffer.prototype.readUint32 = function(offset) { 889 | return this.readInt32(offset) >>> 0; 890 | }; 891 | 892 | /** 893 | * @param {number} offset 894 | * @returns {flatbuffers.Long} 895 | */ 896 | flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) { 897 | return new flatbuffers.Long(this.readInt32(offset), this.readInt32(offset + 4)); 898 | }; 899 | 900 | /** 901 | * @param {number} offset 902 | * @returns {flatbuffers.Long} 903 | */ 904 | flatbuffers.ByteBuffer.prototype.readUint64 = function(offset) { 905 | return new flatbuffers.Long(this.readUint32(offset), this.readUint32(offset + 4)); 906 | }; 907 | 908 | /** 909 | * @param {number} offset 910 | * @returns {number} 911 | */ 912 | flatbuffers.ByteBuffer.prototype.readFloat32 = function(offset) { 913 | flatbuffers.int32[0] = this.readInt32(offset); 914 | return flatbuffers.float32[0]; 915 | }; 916 | 917 | /** 918 | * @param {number} offset 919 | * @returns {number} 920 | */ 921 | flatbuffers.ByteBuffer.prototype.readFloat64 = function(offset) { 922 | flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1] = this.readInt32(offset); 923 | flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0] = this.readInt32(offset + 4); 924 | return flatbuffers.float64[0]; 925 | }; 926 | 927 | /** 928 | * @param {number} offset 929 | * @param {number} value 930 | */ 931 | flatbuffers.ByteBuffer.prototype.writeInt8 = function(offset, value) { 932 | this.bytes_[offset] = value; 933 | }; 934 | 935 | /** 936 | * @param {number} offset 937 | * @param {number} value 938 | */ 939 | flatbuffers.ByteBuffer.prototype.writeInt16 = function(offset, value) { 940 | this.bytes_[offset] = value; 941 | this.bytes_[offset + 1] = value >> 8; 942 | }; 943 | 944 | /** 945 | * @param {number} offset 946 | * @param {number} value 947 | */ 948 | flatbuffers.ByteBuffer.prototype.writeInt32 = function(offset, value) { 949 | this.bytes_[offset] = value; 950 | this.bytes_[offset + 1] = value >> 8; 951 | this.bytes_[offset + 2] = value >> 16; 952 | this.bytes_[offset + 3] = value >> 24; 953 | }; 954 | 955 | /** 956 | * @param {number} offset 957 | * @param {flatbuffers.Long} value 958 | */ 959 | flatbuffers.ByteBuffer.prototype.writeInt64 = function(offset, value) { 960 | this.writeInt32(offset, value.low); 961 | this.writeInt32(offset + 4, value.high); 962 | }; 963 | 964 | /** 965 | * @param {number} offset 966 | * @param {number} value 967 | */ 968 | flatbuffers.ByteBuffer.prototype.writeFloat32 = function(offset, value) { 969 | flatbuffers.float32[0] = value; 970 | this.writeInt32(offset, flatbuffers.int32[0]); 971 | }; 972 | 973 | /** 974 | * @param {number} offset 975 | * @param {number} value 976 | */ 977 | flatbuffers.ByteBuffer.prototype.writeFloat64 = function(offset, value) { 978 | flatbuffers.float64[0] = value; 979 | this.writeInt32(offset, flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1]); 980 | this.writeInt32(offset + 4, flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0]); 981 | }; 982 | 983 | /** 984 | * Look up a field in the vtable, return an offset into the object, or 0 if the 985 | * field is not present. 986 | * 987 | * @param {number} bb_pos 988 | * @param {number} vtable_offset 989 | * @returns {number} 990 | */ 991 | flatbuffers.ByteBuffer.prototype.__offset = function(bb_pos, vtable_offset) { 992 | var vtable = bb_pos - this.readInt32(bb_pos); 993 | return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0; 994 | }; 995 | 996 | /** 997 | * Initialize any Table-derived type to point to the union at the given offset. 998 | * 999 | * @param {flatbuffers.Table} t 1000 | * @param {number} offset 1001 | * @returns {flatbuffers.Table} 1002 | */ 1003 | flatbuffers.ByteBuffer.prototype.__union = function(t, offset) { 1004 | t.bb_pos = offset + this.readInt32(offset); 1005 | t.bb = this; 1006 | return t; 1007 | }; 1008 | 1009 | /** 1010 | * Create a JavaScript string from UTF-8 data stored inside the FlatBuffer. 1011 | * This allocates a new string and converts to wide chars upon each access. 1012 | * 1013 | * To avoid the conversion to UTF-16, pass flatbuffers.Encoding.UTF8_BYTES as 1014 | * the "optionalEncoding" argument. This is useful for avoiding conversion to 1015 | * and from UTF-16 when the data will just be packaged back up in another 1016 | * FlatBuffer later on. 1017 | * 1018 | * @param {number} offset 1019 | * @param {flatbuffers.Encoding=} optionalEncoding Defaults to UTF16_STRING 1020 | * @returns {string|Uint8Array} 1021 | */ 1022 | flatbuffers.ByteBuffer.prototype.__string = function(offset, optionalEncoding) { 1023 | offset += this.readInt32(offset); 1024 | 1025 | var length = this.readInt32(offset); 1026 | var result = ''; 1027 | var i = 0; 1028 | 1029 | offset += flatbuffers.SIZEOF_INT; 1030 | 1031 | if (optionalEncoding === flatbuffers.Encoding.UTF8_BYTES) { 1032 | return this.bytes_.subarray(offset, offset + length); 1033 | } 1034 | 1035 | while (i < length) { 1036 | var codePoint; 1037 | 1038 | // Decode UTF-8 1039 | var a = this.readUint8(offset + i++); 1040 | if (a < 0xC0) { 1041 | codePoint = a; 1042 | } else { 1043 | var b = this.readUint8(offset + i++); 1044 | if (a < 0xE0) { 1045 | codePoint = 1046 | ((a & 0x1F) << 6) | 1047 | (b & 0x3F); 1048 | } else { 1049 | var c = this.readUint8(offset + i++); 1050 | if (a < 0xF0) { 1051 | codePoint = 1052 | ((a & 0x0F) << 12) | 1053 | ((b & 0x3F) << 6) | 1054 | (c & 0x3F); 1055 | } else { 1056 | var d = this.readUint8(offset + i++); 1057 | codePoint = 1058 | ((a & 0x07) << 18) | 1059 | ((b & 0x3F) << 12) | 1060 | ((c & 0x3F) << 6) | 1061 | (d & 0x3F); 1062 | } 1063 | } 1064 | } 1065 | 1066 | // Encode UTF-16 1067 | if (codePoint < 0x10000) { 1068 | result += String.fromCharCode(codePoint); 1069 | } else { 1070 | codePoint -= 0x10000; 1071 | result += String.fromCharCode( 1072 | (codePoint >> 10) + 0xD800, 1073 | (codePoint & ((1 << 10) - 1)) + 0xDC00); 1074 | } 1075 | } 1076 | 1077 | return result; 1078 | }; 1079 | 1080 | /** 1081 | * Retrieve the relative offset stored at "offset" 1082 | * @param {number} offset 1083 | * @returns {number} 1084 | */ 1085 | flatbuffers.ByteBuffer.prototype.__indirect = function(offset) { 1086 | return offset + this.readInt32(offset); 1087 | }; 1088 | 1089 | /** 1090 | * Get the start of data of a vector whose offset is stored at "offset" in this object. 1091 | * 1092 | * @param {number} offset 1093 | * @returns {number} 1094 | */ 1095 | flatbuffers.ByteBuffer.prototype.__vector = function(offset) { 1096 | return offset + this.readInt32(offset) + flatbuffers.SIZEOF_INT; // data starts after the length 1097 | }; 1098 | 1099 | /** 1100 | * Get the length of a vector whose offset is stored at "offset" in this object. 1101 | * 1102 | * @param {number} offset 1103 | * @returns {number} 1104 | */ 1105 | flatbuffers.ByteBuffer.prototype.__vector_len = function(offset) { 1106 | return this.readInt32(offset + this.readInt32(offset)); 1107 | }; 1108 | 1109 | /** 1110 | * @param {string} ident 1111 | * @returns {boolean} 1112 | */ 1113 | flatbuffers.ByteBuffer.prototype.__has_identifier = function(ident) { 1114 | if (ident.length != flatbuffers.FILE_IDENTIFIER_LENGTH) { 1115 | throw new Error('FlatBuffers: file identifier must be length ' + 1116 | flatbuffers.FILE_IDENTIFIER_LENGTH); 1117 | } 1118 | for (var i = 0; i < flatbuffers.FILE_IDENTIFIER_LENGTH; i++) { 1119 | if (ident.charCodeAt(i) != this.readInt8(this.position_ + flatbuffers.SIZEOF_INT + i)) { 1120 | return false; 1121 | } 1122 | } 1123 | return true; 1124 | }; 1125 | 1126 | /** 1127 | * A helper function to avoid generated code depending on this file directly. 1128 | * 1129 | * @param {number} low 1130 | * @param {number} high 1131 | * @returns {flatbuffers.Long} 1132 | */ 1133 | flatbuffers.ByteBuffer.prototype.createLong = function(low, high) { 1134 | return flatbuffers.Long.create(low, high); 1135 | }; 1136 | 1137 | // Exports for Node.js and RequireJS 1138 | this.flatbuffers = flatbuffers; 1139 | 1140 | /// @endcond 1141 | /// @} 1142 | -------------------------------------------------------------------------------- /tests/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "fileIdent": "EXAM", 3 | "fileExt": "example", 4 | "rootTable": { 5 | "name": "Example", 6 | "isStruct": false, 7 | "minalign": 1, 8 | "bytesize": 0, 9 | "fields": [ 10 | { 11 | "name": "field_bool", 12 | "type": { 13 | "baseType": "Bool", 14 | "element": "None", 15 | "index": -1 16 | }, 17 | "id": 0, 18 | "offset": 4, 19 | "deprecated": false, 20 | "required": false, 21 | "key": false, 22 | "default": false 23 | }, 24 | { 25 | "name": "field_bool_false", 26 | "type": { 27 | "baseType": "Bool", 28 | "element": "None", 29 | "index": -1 30 | }, 31 | "id": 1, 32 | "offset": 6, 33 | "deprecated": false, 34 | "required": false, 35 | "key": false, 36 | "default": false 37 | }, 38 | { 39 | "name": "field_bool_true", 40 | "type": { 41 | "baseType": "Bool", 42 | "element": "None", 43 | "index": -1 44 | }, 45 | "id": 2, 46 | "offset": 8, 47 | "deprecated": false, 48 | "required": false, 49 | "key": false, 50 | "default": true 51 | }, 52 | { 53 | "name": "field_byte", 54 | "type": { 55 | "baseType": "Byte", 56 | "element": "None", 57 | "index": -1 58 | }, 59 | "id": 3, 60 | "offset": 10, 61 | "deprecated": false, 62 | "required": false, 63 | "key": false, 64 | "default": 0 65 | }, 66 | { 67 | "name": "field_byte_negative_0x80", 68 | "type": { 69 | "baseType": "Byte", 70 | "element": "None", 71 | "index": -1 72 | }, 73 | "id": 4, 74 | "offset": 12, 75 | "deprecated": false, 76 | "required": false, 77 | "key": false, 78 | "default": -128 79 | }, 80 | { 81 | "name": "field_ubyte", 82 | "type": { 83 | "baseType": "UByte", 84 | "element": "None", 85 | "index": -1 86 | }, 87 | "id": 5, 88 | "offset": 14, 89 | "deprecated": false, 90 | "required": false, 91 | "key": false, 92 | "default": 0 93 | }, 94 | { 95 | "name": "field_ubyte_0xFF", 96 | "type": { 97 | "baseType": "UByte", 98 | "element": "None", 99 | "index": -1 100 | }, 101 | "id": 6, 102 | "offset": 16, 103 | "deprecated": false, 104 | "required": false, 105 | "key": false, 106 | "default": 255 107 | }, 108 | { 109 | "name": "field_short", 110 | "type": { 111 | "baseType": "Short", 112 | "element": "None", 113 | "index": -1 114 | }, 115 | "id": 7, 116 | "offset": 18, 117 | "deprecated": false, 118 | "required": false, 119 | "key": false, 120 | "default": 0 121 | }, 122 | { 123 | "name": "field_short_negative_0x8000", 124 | "type": { 125 | "baseType": "Short", 126 | "element": "None", 127 | "index": -1 128 | }, 129 | "id": 8, 130 | "offset": 20, 131 | "deprecated": false, 132 | "required": false, 133 | "key": false, 134 | "default": -32768 135 | }, 136 | { 137 | "name": "field_ushort", 138 | "type": { 139 | "baseType": "UShort", 140 | "element": "None", 141 | "index": -1 142 | }, 143 | "id": 9, 144 | "offset": 22, 145 | "deprecated": false, 146 | "required": false, 147 | "key": false, 148 | "default": 0 149 | }, 150 | { 151 | "name": "field_ushort_0xFFFF", 152 | "type": { 153 | "baseType": "UShort", 154 | "element": "None", 155 | "index": -1 156 | }, 157 | "id": 10, 158 | "offset": 24, 159 | "deprecated": false, 160 | "required": false, 161 | "key": false, 162 | "default": 65535 163 | }, 164 | { 165 | "name": "field_int", 166 | "type": { 167 | "baseType": "Int", 168 | "element": "None", 169 | "index": -1 170 | }, 171 | "id": 11, 172 | "offset": 26, 173 | "deprecated": false, 174 | "required": false, 175 | "key": false, 176 | "default": 0 177 | }, 178 | { 179 | "name": "field_int_negative_0x80000000", 180 | "type": { 181 | "baseType": "Int", 182 | "element": "None", 183 | "index": -1 184 | }, 185 | "id": 12, 186 | "offset": 28, 187 | "deprecated": false, 188 | "required": false, 189 | "key": false, 190 | "default": -2147483648 191 | }, 192 | { 193 | "name": "field_uint", 194 | "type": { 195 | "baseType": "UInt", 196 | "element": "None", 197 | "index": -1 198 | }, 199 | "id": 13, 200 | "offset": 30, 201 | "deprecated": false, 202 | "required": false, 203 | "key": false, 204 | "default": 0 205 | }, 206 | { 207 | "name": "field_uint_0xFFFFFFFF", 208 | "type": { 209 | "baseType": "UInt", 210 | "element": "None", 211 | "index": -1 212 | }, 213 | "id": 14, 214 | "offset": 32, 215 | "deprecated": false, 216 | "required": false, 217 | "key": false, 218 | "default": 4294967295 219 | }, 220 | { 221 | "name": "field_long", 222 | "type": { 223 | "baseType": "Long", 224 | "element": "None", 225 | "index": -1 226 | }, 227 | "id": 15, 228 | "offset": 34, 229 | "deprecated": false, 230 | "required": false, 231 | "key": false, 232 | "default": { 233 | "low": 0, 234 | "high": 0 235 | } 236 | }, 237 | { 238 | "name": "field_long_negative_0x8000000000000000", 239 | "type": { 240 | "baseType": "Long", 241 | "element": "None", 242 | "index": -1 243 | }, 244 | "id": 16, 245 | "offset": 36, 246 | "deprecated": false, 247 | "required": false, 248 | "key": false, 249 | "default": { 250 | "low": 0, 251 | "high": -2147483648 252 | } 253 | }, 254 | { 255 | "name": "field_ulong", 256 | "type": { 257 | "baseType": "ULong", 258 | "element": "None", 259 | "index": -1 260 | }, 261 | "id": 17, 262 | "offset": 38, 263 | "deprecated": false, 264 | "required": false, 265 | "key": false, 266 | "default": { 267 | "low": 0, 268 | "high": 0 269 | } 270 | }, 271 | { 272 | "name": "field_ulong_0xFFFFFFFFFFFFFFFF", 273 | "type": { 274 | "baseType": "ULong", 275 | "element": "None", 276 | "index": -1 277 | }, 278 | "id": 18, 279 | "offset": 40, 280 | "deprecated": false, 281 | "required": false, 282 | "key": false, 283 | "default": { 284 | "low": 4294967295, 285 | "high": 4294967295 286 | } 287 | }, 288 | { 289 | "name": "field_float", 290 | "type": { 291 | "baseType": "Float", 292 | "element": "None", 293 | "index": -1 294 | }, 295 | "id": 19, 296 | "offset": 42, 297 | "deprecated": false, 298 | "required": false, 299 | "key": false, 300 | "default": 0 301 | }, 302 | { 303 | "name": "field_float_pi", 304 | "type": { 305 | "baseType": "Float", 306 | "element": "None", 307 | "index": -1 308 | }, 309 | "id": 20, 310 | "offset": 44, 311 | "deprecated": false, 312 | "required": false, 313 | "key": false, 314 | "default": 3.14159265359 315 | }, 316 | { 317 | "name": "field_double", 318 | "type": { 319 | "baseType": "Double", 320 | "element": "None", 321 | "index": -1 322 | }, 323 | "id": 21, 324 | "offset": 46, 325 | "deprecated": false, 326 | "required": false, 327 | "key": false, 328 | "default": 0 329 | }, 330 | { 331 | "name": "field_double_pi", 332 | "type": { 333 | "baseType": "Double", 334 | "element": "None", 335 | "index": -1 336 | }, 337 | "id": 22, 338 | "offset": 48, 339 | "deprecated": false, 340 | "required": false, 341 | "key": false, 342 | "default": 3.14159265359 343 | }, 344 | { 345 | "name": "field_enum", 346 | "type": { 347 | "baseType": "UByte", 348 | "element": "None", 349 | "index": 0 350 | }, 351 | "id": 23, 352 | "offset": 50, 353 | "deprecated": false, 354 | "required": false, 355 | "key": false, 356 | "default": 0 357 | }, 358 | { 359 | "name": "field_enum_second", 360 | "type": { 361 | "baseType": "UByte", 362 | "element": "None", 363 | "index": 0 364 | }, 365 | "id": 24, 366 | "offset": 52, 367 | "deprecated": false, 368 | "required": false, 369 | "key": false, 370 | "default": 1 371 | }, 372 | { 373 | "name": "field_string", 374 | "type": { 375 | "baseType": "String", 376 | "element": "None", 377 | "index": -1 378 | }, 379 | "id": 25, 380 | "offset": 54, 381 | "deprecated": false, 382 | "required": false, 383 | "key": false, 384 | "default": null 385 | }, 386 | { 387 | "name": "field_struct", 388 | "type": { 389 | "baseType": "Obj", 390 | "element": "None", 391 | "index": 4 392 | }, 393 | "id": 26, 394 | "offset": 56, 395 | "deprecated": false, 396 | "required": false, 397 | "key": false, 398 | "default": null 399 | }, 400 | { 401 | "name": "field_example", 402 | "type": { 403 | "baseType": "Obj", 404 | "element": "None", 405 | "index": 2 406 | }, 407 | "id": 27, 408 | "offset": 58, 409 | "deprecated": false, 410 | "required": false, 411 | "key": false, 412 | "default": null 413 | }, 414 | { 415 | "name": "field_bytes", 416 | "type": { 417 | "baseType": "Vector", 418 | "element": "Byte", 419 | "index": -1 420 | }, 421 | "id": 28, 422 | "offset": 60, 423 | "deprecated": false, 424 | "required": false, 425 | "key": false, 426 | "default": null 427 | }, 428 | { 429 | "name": "field_shorts", 430 | "type": { 431 | "baseType": "Vector", 432 | "element": "Short", 433 | "index": -1 434 | }, 435 | "id": 29, 436 | "offset": 62, 437 | "deprecated": false, 438 | "required": false, 439 | "key": false, 440 | "default": null 441 | }, 442 | { 443 | "name": "field_ints", 444 | "type": { 445 | "baseType": "Vector", 446 | "element": "Int", 447 | "index": -1 448 | }, 449 | "id": 30, 450 | "offset": 64, 451 | "deprecated": false, 452 | "required": false, 453 | "key": false, 454 | "default": null 455 | }, 456 | { 457 | "name": "field_longs", 458 | "type": { 459 | "baseType": "Vector", 460 | "element": "Long", 461 | "index": -1 462 | }, 463 | "id": 31, 464 | "offset": 66, 465 | "deprecated": false, 466 | "required": false, 467 | "key": false, 468 | "default": null 469 | }, 470 | { 471 | "name": "field_floats", 472 | "type": { 473 | "baseType": "Vector", 474 | "element": "Float", 475 | "index": -1 476 | }, 477 | "id": 32, 478 | "offset": 68, 479 | "deprecated": false, 480 | "required": false, 481 | "key": false, 482 | "default": null 483 | }, 484 | { 485 | "name": "field_doubles", 486 | "type": { 487 | "baseType": "Vector", 488 | "element": "Double", 489 | "index": -1 490 | }, 491 | "id": 33, 492 | "offset": 70, 493 | "deprecated": false, 494 | "required": false, 495 | "key": false, 496 | "default": null 497 | }, 498 | { 499 | "name": "field_enums", 500 | "type": { 501 | "baseType": "Vector", 502 | "element": "UByte", 503 | "index": 0 504 | }, 505 | "id": 34, 506 | "offset": 72, 507 | "deprecated": false, 508 | "required": false, 509 | "key": false, 510 | "default": null 511 | }, 512 | { 513 | "name": "field_strings", 514 | "type": { 515 | "baseType": "Vector", 516 | "element": "String", 517 | "index": -1 518 | }, 519 | "id": 35, 520 | "offset": 74, 521 | "deprecated": false, 522 | "required": false, 523 | "key": false, 524 | "default": null 525 | }, 526 | { 527 | "name": "field_structs", 528 | "type": { 529 | "baseType": "Vector", 530 | "element": "Obj", 531 | "index": 3 532 | }, 533 | "id": 36, 534 | "offset": 76, 535 | "deprecated": false, 536 | "required": false, 537 | "key": false, 538 | "default": null 539 | }, 540 | { 541 | "name": "field_examples", 542 | "type": { 543 | "baseType": "Vector", 544 | "element": "Obj", 545 | "index": 2 546 | }, 547 | "id": 37, 548 | "offset": 78, 549 | "deprecated": false, 550 | "required": false, 551 | "key": false, 552 | "default": null 553 | }, 554 | { 555 | "name": "field_deprecated", 556 | "type": { 557 | "baseType": "String", 558 | "element": "None", 559 | "index": -1 560 | }, 561 | "id": 38, 562 | "offset": 80, 563 | "deprecated": true, 564 | "required": false, 565 | "key": false, 566 | "default": null 567 | }, 568 | { 569 | "name": "field_required", 570 | "type": { 571 | "baseType": "String", 572 | "element": "None", 573 | "index": -1 574 | }, 575 | "id": 39, 576 | "offset": 82, 577 | "deprecated": false, 578 | "required": true, 579 | "key": false, 580 | "default": null 581 | } 582 | ] 583 | }, 584 | "objects": [ 585 | { 586 | "name": "A", 587 | "isStruct": false, 588 | "minalign": 1, 589 | "bytesize": 0, 590 | "fields": [] 591 | }, 592 | { 593 | "name": "B", 594 | "isStruct": false, 595 | "minalign": 1, 596 | "bytesize": 0, 597 | "fields": [] 598 | }, 599 | { 600 | "name": "Example", 601 | "isStruct": false, 602 | "minalign": 1, 603 | "bytesize": 0, 604 | "fields": [ 605 | { 606 | "name": "field_bool", 607 | "type": { 608 | "baseType": "Bool", 609 | "element": "None", 610 | "index": -1 611 | }, 612 | "id": 0, 613 | "offset": 4, 614 | "deprecated": false, 615 | "required": false, 616 | "key": false, 617 | "default": false 618 | }, 619 | { 620 | "name": "field_bool_false", 621 | "type": { 622 | "baseType": "Bool", 623 | "element": "None", 624 | "index": -1 625 | }, 626 | "id": 1, 627 | "offset": 6, 628 | "deprecated": false, 629 | "required": false, 630 | "key": false, 631 | "default": false 632 | }, 633 | { 634 | "name": "field_bool_true", 635 | "type": { 636 | "baseType": "Bool", 637 | "element": "None", 638 | "index": -1 639 | }, 640 | "id": 2, 641 | "offset": 8, 642 | "deprecated": false, 643 | "required": false, 644 | "key": false, 645 | "default": true 646 | }, 647 | { 648 | "name": "field_byte", 649 | "type": { 650 | "baseType": "Byte", 651 | "element": "None", 652 | "index": -1 653 | }, 654 | "id": 3, 655 | "offset": 10, 656 | "deprecated": false, 657 | "required": false, 658 | "key": false, 659 | "default": 0 660 | }, 661 | { 662 | "name": "field_byte_negative_0x80", 663 | "type": { 664 | "baseType": "Byte", 665 | "element": "None", 666 | "index": -1 667 | }, 668 | "id": 4, 669 | "offset": 12, 670 | "deprecated": false, 671 | "required": false, 672 | "key": false, 673 | "default": -128 674 | }, 675 | { 676 | "name": "field_ubyte", 677 | "type": { 678 | "baseType": "UByte", 679 | "element": "None", 680 | "index": -1 681 | }, 682 | "id": 5, 683 | "offset": 14, 684 | "deprecated": false, 685 | "required": false, 686 | "key": false, 687 | "default": 0 688 | }, 689 | { 690 | "name": "field_ubyte_0xFF", 691 | "type": { 692 | "baseType": "UByte", 693 | "element": "None", 694 | "index": -1 695 | }, 696 | "id": 6, 697 | "offset": 16, 698 | "deprecated": false, 699 | "required": false, 700 | "key": false, 701 | "default": 255 702 | }, 703 | { 704 | "name": "field_short", 705 | "type": { 706 | "baseType": "Short", 707 | "element": "None", 708 | "index": -1 709 | }, 710 | "id": 7, 711 | "offset": 18, 712 | "deprecated": false, 713 | "required": false, 714 | "key": false, 715 | "default": 0 716 | }, 717 | { 718 | "name": "field_short_negative_0x8000", 719 | "type": { 720 | "baseType": "Short", 721 | "element": "None", 722 | "index": -1 723 | }, 724 | "id": 8, 725 | "offset": 20, 726 | "deprecated": false, 727 | "required": false, 728 | "key": false, 729 | "default": -32768 730 | }, 731 | { 732 | "name": "field_ushort", 733 | "type": { 734 | "baseType": "UShort", 735 | "element": "None", 736 | "index": -1 737 | }, 738 | "id": 9, 739 | "offset": 22, 740 | "deprecated": false, 741 | "required": false, 742 | "key": false, 743 | "default": 0 744 | }, 745 | { 746 | "name": "field_ushort_0xFFFF", 747 | "type": { 748 | "baseType": "UShort", 749 | "element": "None", 750 | "index": -1 751 | }, 752 | "id": 10, 753 | "offset": 24, 754 | "deprecated": false, 755 | "required": false, 756 | "key": false, 757 | "default": 65535 758 | }, 759 | { 760 | "name": "field_int", 761 | "type": { 762 | "baseType": "Int", 763 | "element": "None", 764 | "index": -1 765 | }, 766 | "id": 11, 767 | "offset": 26, 768 | "deprecated": false, 769 | "required": false, 770 | "key": false, 771 | "default": 0 772 | }, 773 | { 774 | "name": "field_int_negative_0x80000000", 775 | "type": { 776 | "baseType": "Int", 777 | "element": "None", 778 | "index": -1 779 | }, 780 | "id": 12, 781 | "offset": 28, 782 | "deprecated": false, 783 | "required": false, 784 | "key": false, 785 | "default": -2147483648 786 | }, 787 | { 788 | "name": "field_uint", 789 | "type": { 790 | "baseType": "UInt", 791 | "element": "None", 792 | "index": -1 793 | }, 794 | "id": 13, 795 | "offset": 30, 796 | "deprecated": false, 797 | "required": false, 798 | "key": false, 799 | "default": 0 800 | }, 801 | { 802 | "name": "field_uint_0xFFFFFFFF", 803 | "type": { 804 | "baseType": "UInt", 805 | "element": "None", 806 | "index": -1 807 | }, 808 | "id": 14, 809 | "offset": 32, 810 | "deprecated": false, 811 | "required": false, 812 | "key": false, 813 | "default": 4294967295 814 | }, 815 | { 816 | "name": "field_long", 817 | "type": { 818 | "baseType": "Long", 819 | "element": "None", 820 | "index": -1 821 | }, 822 | "id": 15, 823 | "offset": 34, 824 | "deprecated": false, 825 | "required": false, 826 | "key": false, 827 | "default": { 828 | "low": 0, 829 | "high": 0 830 | } 831 | }, 832 | { 833 | "name": "field_long_negative_0x8000000000000000", 834 | "type": { 835 | "baseType": "Long", 836 | "element": "None", 837 | "index": -1 838 | }, 839 | "id": 16, 840 | "offset": 36, 841 | "deprecated": false, 842 | "required": false, 843 | "key": false, 844 | "default": { 845 | "low": 0, 846 | "high": -2147483648 847 | } 848 | }, 849 | { 850 | "name": "field_ulong", 851 | "type": { 852 | "baseType": "ULong", 853 | "element": "None", 854 | "index": -1 855 | }, 856 | "id": 17, 857 | "offset": 38, 858 | "deprecated": false, 859 | "required": false, 860 | "key": false, 861 | "default": { 862 | "low": 0, 863 | "high": 0 864 | } 865 | }, 866 | { 867 | "name": "field_ulong_0xFFFFFFFFFFFFFFFF", 868 | "type": { 869 | "baseType": "ULong", 870 | "element": "None", 871 | "index": -1 872 | }, 873 | "id": 18, 874 | "offset": 40, 875 | "deprecated": false, 876 | "required": false, 877 | "key": false, 878 | "default": { 879 | "low": 4294967295, 880 | "high": 4294967295 881 | } 882 | }, 883 | { 884 | "name": "field_float", 885 | "type": { 886 | "baseType": "Float", 887 | "element": "None", 888 | "index": -1 889 | }, 890 | "id": 19, 891 | "offset": 42, 892 | "deprecated": false, 893 | "required": false, 894 | "key": false, 895 | "default": 0 896 | }, 897 | { 898 | "name": "field_float_pi", 899 | "type": { 900 | "baseType": "Float", 901 | "element": "None", 902 | "index": -1 903 | }, 904 | "id": 20, 905 | "offset": 44, 906 | "deprecated": false, 907 | "required": false, 908 | "key": false, 909 | "default": 3.14159265359 910 | }, 911 | { 912 | "name": "field_double", 913 | "type": { 914 | "baseType": "Double", 915 | "element": "None", 916 | "index": -1 917 | }, 918 | "id": 21, 919 | "offset": 46, 920 | "deprecated": false, 921 | "required": false, 922 | "key": false, 923 | "default": 0 924 | }, 925 | { 926 | "name": "field_double_pi", 927 | "type": { 928 | "baseType": "Double", 929 | "element": "None", 930 | "index": -1 931 | }, 932 | "id": 22, 933 | "offset": 48, 934 | "deprecated": false, 935 | "required": false, 936 | "key": false, 937 | "default": 3.14159265359 938 | }, 939 | { 940 | "name": "field_enum", 941 | "type": { 942 | "baseType": "UByte", 943 | "element": "None", 944 | "index": 0 945 | }, 946 | "id": 23, 947 | "offset": 50, 948 | "deprecated": false, 949 | "required": false, 950 | "key": false, 951 | "default": 0 952 | }, 953 | { 954 | "name": "field_enum_second", 955 | "type": { 956 | "baseType": "UByte", 957 | "element": "None", 958 | "index": 0 959 | }, 960 | "id": 24, 961 | "offset": 52, 962 | "deprecated": false, 963 | "required": false, 964 | "key": false, 965 | "default": 1 966 | }, 967 | { 968 | "name": "field_string", 969 | "type": { 970 | "baseType": "String", 971 | "element": "None", 972 | "index": -1 973 | }, 974 | "id": 25, 975 | "offset": 54, 976 | "deprecated": false, 977 | "required": false, 978 | "key": false, 979 | "default": null 980 | }, 981 | { 982 | "name": "field_struct", 983 | "type": { 984 | "baseType": "Obj", 985 | "element": "None", 986 | "index": 4 987 | }, 988 | "id": 26, 989 | "offset": 56, 990 | "deprecated": false, 991 | "required": false, 992 | "key": false, 993 | "default": null 994 | }, 995 | { 996 | "name": "field_example", 997 | "type": { 998 | "baseType": "Obj", 999 | "element": "None", 1000 | "index": 2 1001 | }, 1002 | "id": 27, 1003 | "offset": 58, 1004 | "deprecated": false, 1005 | "required": false, 1006 | "key": false, 1007 | "default": null 1008 | }, 1009 | { 1010 | "name": "field_bytes", 1011 | "type": { 1012 | "baseType": "Vector", 1013 | "element": "Byte", 1014 | "index": -1 1015 | }, 1016 | "id": 28, 1017 | "offset": 60, 1018 | "deprecated": false, 1019 | "required": false, 1020 | "key": false, 1021 | "default": null 1022 | }, 1023 | { 1024 | "name": "field_shorts", 1025 | "type": { 1026 | "baseType": "Vector", 1027 | "element": "Short", 1028 | "index": -1 1029 | }, 1030 | "id": 29, 1031 | "offset": 62, 1032 | "deprecated": false, 1033 | "required": false, 1034 | "key": false, 1035 | "default": null 1036 | }, 1037 | { 1038 | "name": "field_ints", 1039 | "type": { 1040 | "baseType": "Vector", 1041 | "element": "Int", 1042 | "index": -1 1043 | }, 1044 | "id": 30, 1045 | "offset": 64, 1046 | "deprecated": false, 1047 | "required": false, 1048 | "key": false, 1049 | "default": null 1050 | }, 1051 | { 1052 | "name": "field_longs", 1053 | "type": { 1054 | "baseType": "Vector", 1055 | "element": "Long", 1056 | "index": -1 1057 | }, 1058 | "id": 31, 1059 | "offset": 66, 1060 | "deprecated": false, 1061 | "required": false, 1062 | "key": false, 1063 | "default": null 1064 | }, 1065 | { 1066 | "name": "field_floats", 1067 | "type": { 1068 | "baseType": "Vector", 1069 | "element": "Float", 1070 | "index": -1 1071 | }, 1072 | "id": 32, 1073 | "offset": 68, 1074 | "deprecated": false, 1075 | "required": false, 1076 | "key": false, 1077 | "default": null 1078 | }, 1079 | { 1080 | "name": "field_doubles", 1081 | "type": { 1082 | "baseType": "Vector", 1083 | "element": "Double", 1084 | "index": -1 1085 | }, 1086 | "id": 33, 1087 | "offset": 70, 1088 | "deprecated": false, 1089 | "required": false, 1090 | "key": false, 1091 | "default": null 1092 | }, 1093 | { 1094 | "name": "field_enums", 1095 | "type": { 1096 | "baseType": "Vector", 1097 | "element": "UByte", 1098 | "index": 0 1099 | }, 1100 | "id": 34, 1101 | "offset": 72, 1102 | "deprecated": false, 1103 | "required": false, 1104 | "key": false, 1105 | "default": null 1106 | }, 1107 | { 1108 | "name": "field_strings", 1109 | "type": { 1110 | "baseType": "Vector", 1111 | "element": "String", 1112 | "index": -1 1113 | }, 1114 | "id": 35, 1115 | "offset": 74, 1116 | "deprecated": false, 1117 | "required": false, 1118 | "key": false, 1119 | "default": null 1120 | }, 1121 | { 1122 | "name": "field_structs", 1123 | "type": { 1124 | "baseType": "Vector", 1125 | "element": "Obj", 1126 | "index": 3 1127 | }, 1128 | "id": 36, 1129 | "offset": 76, 1130 | "deprecated": false, 1131 | "required": false, 1132 | "key": false, 1133 | "default": null 1134 | }, 1135 | { 1136 | "name": "field_examples", 1137 | "type": { 1138 | "baseType": "Vector", 1139 | "element": "Obj", 1140 | "index": 2 1141 | }, 1142 | "id": 37, 1143 | "offset": 78, 1144 | "deprecated": false, 1145 | "required": false, 1146 | "key": false, 1147 | "default": null 1148 | }, 1149 | { 1150 | "name": "field_deprecated", 1151 | "type": { 1152 | "baseType": "String", 1153 | "element": "None", 1154 | "index": -1 1155 | }, 1156 | "id": 38, 1157 | "offset": 80, 1158 | "deprecated": true, 1159 | "required": false, 1160 | "key": false, 1161 | "default": null 1162 | }, 1163 | { 1164 | "name": "field_required", 1165 | "type": { 1166 | "baseType": "String", 1167 | "element": "None", 1168 | "index": -1 1169 | }, 1170 | "id": 39, 1171 | "offset": 82, 1172 | "deprecated": false, 1173 | "required": true, 1174 | "key": false, 1175 | "default": null 1176 | } 1177 | ] 1178 | }, 1179 | { 1180 | "name": "Nested", 1181 | "isStruct": true, 1182 | "minalign": 4, 1183 | "bytesize": 8, 1184 | "fields": [ 1185 | { 1186 | "name": "x", 1187 | "type": { 1188 | "baseType": "Float", 1189 | "element": "None", 1190 | "index": -1 1191 | }, 1192 | "id": 0, 1193 | "offset": 0, 1194 | "deprecated": false, 1195 | "required": false, 1196 | "key": false, 1197 | "default": 0 1198 | }, 1199 | { 1200 | "name": "y", 1201 | "type": { 1202 | "baseType": "Float", 1203 | "element": "None", 1204 | "index": -1 1205 | }, 1206 | "id": 1, 1207 | "offset": 4, 1208 | "deprecated": false, 1209 | "required": false, 1210 | "key": false, 1211 | "default": 0 1212 | } 1213 | ] 1214 | }, 1215 | { 1216 | "name": "Struct", 1217 | "isStruct": true, 1218 | "minalign": 8, 1219 | "bytesize": 40, 1220 | "fields": [ 1221 | { 1222 | "name": "field_bool", 1223 | "type": { 1224 | "baseType": "Bool", 1225 | "element": "None", 1226 | "index": -1 1227 | }, 1228 | "id": 0, 1229 | "offset": 0, 1230 | "deprecated": false, 1231 | "required": false, 1232 | "key": false, 1233 | "default": false 1234 | }, 1235 | { 1236 | "name": "field_byte", 1237 | "type": { 1238 | "baseType": "Byte", 1239 | "element": "None", 1240 | "index": -1 1241 | }, 1242 | "id": 1, 1243 | "offset": 1, 1244 | "deprecated": false, 1245 | "required": false, 1246 | "key": false, 1247 | "default": 0 1248 | }, 1249 | { 1250 | "name": "field_short", 1251 | "type": { 1252 | "baseType": "Short", 1253 | "element": "None", 1254 | "index": -1 1255 | }, 1256 | "id": 2, 1257 | "offset": 2, 1258 | "deprecated": false, 1259 | "required": false, 1260 | "key": false, 1261 | "default": 0 1262 | }, 1263 | { 1264 | "name": "field_int", 1265 | "type": { 1266 | "baseType": "Int", 1267 | "element": "None", 1268 | "index": -1 1269 | }, 1270 | "id": 3, 1271 | "offset": 4, 1272 | "deprecated": false, 1273 | "required": false, 1274 | "key": false, 1275 | "default": 0 1276 | }, 1277 | { 1278 | "name": "field_float", 1279 | "type": { 1280 | "baseType": "Float", 1281 | "element": "None", 1282 | "index": -1 1283 | }, 1284 | "id": 4, 1285 | "offset": 8, 1286 | "deprecated": false, 1287 | "required": false, 1288 | "key": false, 1289 | "default": 0 1290 | }, 1291 | { 1292 | "name": "field_double", 1293 | "type": { 1294 | "baseType": "Double", 1295 | "element": "None", 1296 | "index": -1 1297 | }, 1298 | "id": 5, 1299 | "offset": 16, 1300 | "deprecated": false, 1301 | "required": false, 1302 | "key": false, 1303 | "default": 0 1304 | }, 1305 | { 1306 | "name": "field_enum", 1307 | "type": { 1308 | "baseType": "UByte", 1309 | "element": "None", 1310 | "index": 0 1311 | }, 1312 | "id": 6, 1313 | "offset": 24, 1314 | "deprecated": false, 1315 | "required": false, 1316 | "key": false, 1317 | "default": 0 1318 | }, 1319 | { 1320 | "name": "field_nested", 1321 | "type": { 1322 | "baseType": "Obj", 1323 | "element": "None", 1324 | "index": 3 1325 | }, 1326 | "id": 7, 1327 | "offset": 28, 1328 | "deprecated": false, 1329 | "required": false, 1330 | "key": false, 1331 | "default": null 1332 | } 1333 | ] 1334 | } 1335 | ], 1336 | "enums": [ 1337 | { 1338 | "name": "Enum", 1339 | "is_union": false, 1340 | "underlying_type": { 1341 | "baseType": "UByte", 1342 | "element": "None", 1343 | "index": 0 1344 | }, 1345 | "values": [ 1346 | { 1347 | "name": "FIRST", 1348 | "value": 0, 1349 | "object": null 1350 | }, 1351 | { 1352 | "name": "SECOND", 1353 | "value": 1, 1354 | "object": null 1355 | } 1356 | ] 1357 | }, 1358 | { 1359 | "name": "Union", 1360 | "is_union": true, 1361 | "underlying_type": { 1362 | "baseType": "UType", 1363 | "element": "None", 1364 | "index": 1 1365 | }, 1366 | "values": [ 1367 | { 1368 | "name": "NONE", 1369 | "value": 0, 1370 | "object": null 1371 | }, 1372 | { 1373 | "name": "A", 1374 | "value": 1, 1375 | "object": { 1376 | "name": "A", 1377 | "isStruct": false, 1378 | "minalign": 1, 1379 | "bytesize": 0, 1380 | "fields": [] 1381 | } 1382 | }, 1383 | { 1384 | "name": "B", 1385 | "value": 2, 1386 | "object": { 1387 | "name": "B", 1388 | "isStruct": false, 1389 | "minalign": 1, 1390 | "bytesize": 0, 1391 | "fields": [] 1392 | } 1393 | } 1394 | ] 1395 | } 1396 | ] 1397 | } --------------------------------------------------------------------------------