{"id":19297176,"url":"https://github.com/dvidelabs/flatcc","last_synced_at":"2025-10-21T04:43:20.719Z","repository":{"id":38419364,"uuid":"45867575","full_name":"dvidelabs/flatcc","owner":"dvidelabs","description":"FlatBuffers Compiler and Library in C for C","archived":false,"fork":false,"pushed_at":"2025-04-08T06:48:58.000Z","size":3965,"stargazers_count":672,"open_issues_count":20,"forks_count":194,"subscribers_count":33,"default_branch":"master","last_synced_at":"2025-04-08T07:38:24.084Z","etag":null,"topics":["c","flatbuffers","idl","json","json-parser","protocol","schema","serialization"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dvidelabs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-11-09T21:21:58.000Z","updated_at":"2025-04-08T06:48:55.000Z","dependencies_parsed_at":"2023-02-09T23:31:00.845Z","dependency_job_id":"83f8a1fb-46d6-4dbd-b2ca-be4b3db208fe","html_url":"https://github.com/dvidelabs/flatcc","commit_stats":{"total_commits":1145,"total_committers":39,"mean_commits":"29.358974358974358","dds":0.08296943231441045,"last_synced_commit":"da7cf25e8ec25c3f41ba8553e47c8f524fdefe4e"},"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvidelabs%2Fflatcc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvidelabs%2Fflatcc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvidelabs%2Fflatcc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvidelabs%2Fflatcc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dvidelabs","download_url":"https://codeload.github.com/dvidelabs/flatcc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250206141,"owners_count":21392193,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","flatbuffers","idl","json","json-parser","protocol","schema","serialization"],"created_at":"2024-11-09T23:01:46.536Z","updated_at":"2025-10-21T04:43:20.709Z","avatar_url":"https://github.com/dvidelabs.png","language":"C","readme":"Ubuntu, macOS and Windows: [![Build Status](https://github.com/dvidelabs/flatcc/actions/workflows/ci.yml/badge.svg)](https://github.com/dvidelabs/flatcc/actions/workflows/ci.yml)\nWindows: [![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/dvidelabs/flatcc?branch=master\u0026svg=true)](https://ci.appveyor.com/project/dvidelabs/flatcc)\nWeekly: [![Build Status](https://github.com/dvidelabs/flatcc/actions/workflows/weekly.yml/badge.svg)](https://github.com/dvidelabs/flatcc/actions/workflows/weekly.yml)\n\n\n_The JSON parser may change the interface for parsing union vectors in a\nfuture release which requires code generation to match library\nversions._\n\n# FlatCC FlatBuffers in C for C\n\n`flatcc` has no external dependencies except for build and compiler\ntools, and the C runtime library. With concurrent Ninja builds, a small client\nproject can build flatcc with libraries, generate schema code, link the project\nand execute a test case in a few seconds, produce binaries between 15K and 60K,\nread small buffers in 30ns, build FlatBuffers in about 600ns, and with a larger\nexecutable also handle optional json parsing or printing in less than 2 us for a\n10 field mixed type message.\n\n\n\u003c!-- vim-markdown-toc GFM --\u003e\n\n* [Online Forums](#online-forums)\n* [Introduction](#introduction)\n  * [Integrating FlatCC](#integrating-flatcc)\n* [Project Details](#project-details)\n* [Reporting Bugs](#reporting-bugs)\n* [Status](#status)\n  * [Main features supported as of 0.6.1](#main-features-supported-as-of-061)\n  * [Supported platforms (CI tested)](#supported-platforms-ci-tested)\n  * [Platforms reported to work by users](#platforms-reported-to-work-by-users)\n  * [Portability](#portability)\n* [Time / Space / Usability Tradeoff](#time--space--usability-tradeoff)\n* [Generated Files](#generated-files)\n  * [Use of Macros in Generated Code](#use-of-macros-in-generated-code)\n  * [Extracting Documentation](#extracting-documentation)\n* [Using flatcc](#using-flatcc)\n* [Trouble Shooting](#trouble-shooting)\n* [Quickstart](#quickstart)\n  * [Reading a Buffer](#reading-a-buffer)\n  * [Compiling for Read-Only](#compiling-for-read-only)\n  * [Building a Buffer](#building-a-buffer)\n  * [Verifying a Buffer](#verifying-a-buffer)\n  * [Potential Name Conflicts](#potential-name-conflicts)\n  * [Debugging a Buffer](#debugging-a-buffer)\n* [File and Type Identifiers](#file-and-type-identifiers)\n  * [File Identifiers](#file-identifiers)\n  * [Type Identifiers](#type-identifiers)\n* [JSON Parsing and Printing](#json-parsing-and-printing)\n  * [Base64 Encoding](#base64-encoding)\n  * [Parsing Fixed Length Arrays](#parsing-fixed-length-arrays)\n  * [Runtime Flags](#runtime-flags)\n  * [Generic Parsing and Printing.](#generic-parsing-and-printing)\n  * [Performance Notes](#performance-notes)\n* [Global Scope and Included Schema](#global-scope-and-included-schema)\n* [Required Fields and Duplicate Fields](#required-fields-and-duplicate-fields)\n* [Fast Buffers](#fast-buffers)\n* [Types](#types)\n* [Unions](#unions)\n  * [Union Scope Resolution](#union-scope-resolution)\n* [Fixed Length Arrays](#fixed-length-arrays)\n* [Optional Fields](#optional-fields)\n* [Endianness](#endianness)\n* [Pitfalls in Error Handling](#pitfalls-in-error-handling)\n* [Searching and Sorting](#searching-and-sorting)\n* [Null Values](#null-values)\n* [Portability Layer](#portability-layer)\n* [Building](#building)\n  * [Unix Build (OS-X, Linux, related)](#unix-build-os-x-linux-related)\n  * [Windows Build (MSVC)](#windows-build-msvc)\n  * [Docker](#docker)\n  * [Cross-compilation](#cross-compilation)\n  * [Custom Allocation](#custom-allocation)\n  * [Custom Asserts](#custom-asserts)\n  * [Shared Libraries](#shared-libraries)\n  * [Strict Aliasing](#strict-aliasing)\n* [Distribution](#distribution)\n  * [Unix Files](#unix-files)\n  * [Windows Files](#windows-files)\n* [Running Tests on Unix](#running-tests-on-unix)\n* [Running Tests on Windows](#running-tests-on-windows)\n* [Configuration](#configuration)\n* [Using the Compiler and Builder library](#using-the-compiler-and-builder-library)\n* [FlatBuffers Binary Format](#flatbuffers-binary-format)\n* [Security Considerations](#security-considerations)\n* [Style Guide](#style-guide)\n* [Benchmarks](#benchmarks)\n\n\u003c!-- vim-markdown-toc --\u003e\n\n## Online Forums\n\n- [Discord - FlatBuffers](https://discord.gg/6qgKs3R)\n- [Github - FlatCC Discussions](https://github.com/dvidelabs/flatcc/discussions)\n\n## Introduction\n\nThis project builds flatcc, a compiler that generates FlatBuffers code for\nC given a FlatBuffer schema file. This introduction also creates a separate test\nproject with the traditional monster example, here in a C version.\n\nFor now assume a Unix like system although that is not a general requirement -\nsee also [Building](#building). You will need git, cmake, bash, a C compiler,\nand either the ninja build system, or make.\n\n    git clone https://github.com/dvidelabs/flatcc.git\n    cd flatcc\n    # scripts/initbuild.sh ninja\n    scripts/initbuild.sh make\n    scripts/setup.sh -a ../mymonster\n    ls bin\n    ls lib\n    cd ../mymonster\n    ls src\n    scripts/build.sh\n    ls generated\n\n`scripts/initbuild.sh` is optional and chooses the build backend, which defaults\nto ninja.\n\nThe setup script builds flatcc using CMake, then creates a test project\ndirectory with the monster example, and a build script which is just a small\nshell script. The headers and libraries are symbolically linked into the test\nproject. You do not need CMake to build your own projects once flatcc is\ncompiled.\n\nTo create another test project named foobar, call `scripts/setup.sh -s -x\n../foobar`. This will avoid rebuilding the flatcc project from scratch.\n\n### Integrating FlatCC\n\nTo answer the question:\n\n\u003e \"How do I integrate FlatCC into my project with minimal dependencies\"\n\nYou do not need CMake and you do not need a prebuilt runtime library.\n\nYou do need the `flatcc` tool to initially generate your own schema files and\nthen you need to update your project to:\n\n- Include the generated header files.\n- Add `include/flatcc` (correct version) to the include path, e.g., using `-I include` if at flatcc root.\n- Link with zero or more files from `src/runtime/*.c` (correct version).\n- Possibly disable certain warnings (notably disable GCC pedantic).\n- Potentially work around platform limitations, e.g., using `-DPORTABLE_HAS_INCLUDE_STDALIGN=0` if `stdalign.h`\n  should be, but isn't, available on your platform. See `include/flatcc/portable/*.h` for details.\n\nYou should be able to compile a test project with just a single line like:\n\n```\ncc -I include src/runtime/build.c myprogram.c\n```\n\nIf you only read flatbuffer files, and do not build, verify, parse JSON, or print JSON,\nyou will not need any runtime `.c` files.\n\nIf you have a system installed `flatcc` package, it might have the wrong\nversion of header or library files. You need to somehow override that if you\nhave generated files from a more recent version of flatcc.\n\nThat said, you can also use the main CMake project to build libraries, or\njust look at it to see which warnings and flags are important to your compiler.\n\nSee also [Building](#building).\n\n\n## Project Details\n\nNOTE: see\n[CHANGELOG](https://github.com/dvidelabs/flatcc/blob/master/CHANGELOG.md).\nThere are occassionally minor breaking changes as API inconsistencies\nare discovered. Unless clearly stated, breaking changes will not affect\nthe compiled runtime library, only the header files. In case of trouble,\nmake sure the `flatcc` tool is same version as the `include/flatcc`\npath.\n\nThe project includes:\n\n- an executable `flatcc` FlatBuffers schema compiler for C and a\n  corresponding library `libflatcc.a`. The compiler generates C header\n  files or a binary flatbuffers schema.\n- a typeless runtime library `libflatccrt.a` for building and verifying\n  flatbuffers from C. Generated builder headers depend on this library.\n  It may also be useful for other language interfaces. The library\n  maintains a stack state to make it easy to build buffers from a parser\n  or similar.\n- a small `flatcc/portable` header only library for non-C11 compliant\n  compilers, and small helpers for all compilers including endian\n  handling and numeric printing and parsing.\n\n\nSee also:\n\n- [Reporting Bugs](https://github.com/dvidelabs/flatcc#reporting-bugs)\n\n- [Google FlatBuffers](http://google.github.io/flatbuffers/)\n\n- [Build Instructions](https://github.com/dvidelabs/flatcc#building)\n\n- [Quickstart](https://github.com/dvidelabs/flatcc#quickstart)\n\n- [Builder Interface Reference]\n\n- [Benchmarks]\n\nThe `flatcc` compiler is implemented as a standalone tool instead of\nextending Googles `flatc` compiler in order to have a pure portable C\nlibrary implementation of the schema compiler that is designed to fail\ngraciously on abusive input in long running processes. It is also\nbelieved a C version may help provide schema parsing to other language\ninterfaces that find interfacing with C easier than C++. The FlatBuffers\nteam at Googles FPL lab has been very helpful in providing feedback and\nanswering many questions to help ensure the best possible compatibility.\nNotice the name `flatcc` (FlatBuffers C Compiler) vs Googles `flatc`.\n\nThe JSON format is compatible with Googles `flatc` tool. The `flatc`\ntool converts JSON from the command line using a schema and a buffer as\ninput. `flatcc` generates schema specific code to read and write JSON\nat runtime. While the `flatcc` approach is likely much faster and also\neasier to deploy, the `flatc` approach is likely more convenient when\nmanually working with JSON such as editing game scenes. Both tools have\ntheir place.\n\n**NOTE: Big-endian platforms are only supported as of release 0.4.0.**\n\n\n## Reporting Bugs\n\nIf possible, please provide a short reproducible schema and source file\nwith a main program the returns 1 on error and 0 on success and a small\nbuild script. Preferably generate a hexdump and call the buffer verifier\nto ensure the input is valid and link with the debug library\n`flatccrt_d`.\n\nSee also [Debugging a Buffer](#debugging-a-buffer), and [readfile.h]\nuseful for reading an existing buffer for verification.\n\nExample:\n\n[samples/bugreport](samples/bugreport)\n\neclectic.fbs :\n\n```c\nnamespace Eclectic;\n\nenum Fruit : byte { Banana = -1, Orange = 42 }\ntable FooBar {\n    meal      : Fruit = Banana;\n    density   : long (deprecated);\n    say       : string;\n    height    : short;\n}\nfile_identifier \"NOOB\";\nroot_type FooBar;\n```\n\nmyissue.c :\n\n```c\n/* Minimal test with all headers generated into a single file. */\n#include \"build/myissue_generated.h\"\n#include \"flatcc/support/hexdump.h\"\n\nint main(int argc, char *argv[])\n{\n    int ret;\n    void *buf;\n    size_t size;\n    flatcc_builder_t builder, *B;\n\n    (void)argc;\n    (void)argv;\n\n    B = \u0026builder;\n    flatcc_builder_init(B);\n\n    Eclectic_FooBar_start_as_root(B);\n    Eclectic_FooBar_say_create_str(B, \"hello\");\n    Eclectic_FooBar_meal_add(B, Eclectic_Fruit_Orange);\n    Eclectic_FooBar_height_add(B, -8000);\n    Eclectic_FooBar_end_as_root(B);\n    buf = flatcc_builder_get_direct_buffer(B, \u0026size);\n#if defined(PROVOKE_ERROR) || 0\n    /* Provoke error for testing. */\n    ((char*)buf)[0] = 42;\n#endif\n    ret = Eclectic_FooBar_verify_as_root(buf, size);\n    if (ret) {\n        hexdump(\"Eclectic.FooBar buffer for myissue\", buf, size, stdout);\n        printf(\"could not verify Electic.FooBar table, got %s\\n\", flatcc_verify_error_string(ret));\n    }\n    flatcc_builder_clear(B);\n    return ret;\n}\n```\nbuild.sh :\n```sh\n#!/bin/sh\ncd $(dirname $0)\n\nFLATBUFFERS_DIR=../..\nNAME=myissue\nSCHEMA=eclectic.fbs\nOUT=build\n\nFLATCC_EXE=$FLATBUFFERS_DIR/bin/flatcc\nFLATCC_INCLUDE=$FLATBUFFERS_DIR/include\nFLATCC_LIB=$FLATBUFFERS_DIR/lib\n\nmkdir -p $OUT\n$FLATCC_EXE --outfile $OUT/${NAME}_generated.h -a $SCHEMA || exit 1\ncc -I$FLATCC_INCLUDE -g -o $OUT/$NAME $NAME.c -L$FLATCC_LIB -lflatccrt_d || exit 1\necho \"running $OUT/$NAME\"\nif $OUT/$NAME; then\n    echo \"success\"\nelse\n    echo \"failed\"\n    exit 1\nfi\n```\n\n## Status\n\nRelease 0.6.2 (in development) is primarily a bug fix release, refer to\nCHANGELOG for details. A long standing bug has been fixed where where objects\ncreated before a call to _create_as_root would not be properly aligned, and\nbuffer end is now also padded to largest object seen within the buffer. Note\nthat for clang debug builds, -fsanitize=undefined has been added and this may\nrequire dependent source code to also use that flag to avoid missing linker\nsymbols. The feature can be disabled in CMakeLists.txt. CMake has been bumped to\nversion 3.16 which is the latest version where Appveyor will build MVSC 2015.\nWarnings added for potential name conflicts in enum names and table fields\nthat could result in confusing C compiler errors. Not all warnigs are errors\nto the option `-s` was also added to silence warnings. The existing `-g`\noption can resolve some conflicts.\n\nRelease 0.6.1 contains primarily bug fixes and numerous contributions from the\ncommunity to handle platform edge cases. Additionally, pendantic GCC warnings\nare disabled, relying instead on clang, since GCC is too aggressive, breaks\nbuilds frequently and works against portability. An existing C++ test case\nensures that C code also works with common C++ compilers, but it can break some\nenvironments, so there is now a flag to disable that test without disabling\nall tests. Support for Optional Scalar Values in the FlatBuffer format has\nbeen added. There is also improved support for abstracting memory allocation\non various platforms. `\u003ctable\u003e_identifier` has been deprecated in favor\n`\u003ctable\u003e_file_identifier` in generated code due to `identifier` easily leading\nto name conflicts. `file_extension` constant in generated code is now without\nprefixed dot (.).\n\nRelease 0.6.0 introduces a \"primary\" attribute to be used together with a key\nattribute to chose default key for finding and sorting. If primary is absent,\nthe key with the lowest id becomes primary. Tables and vectors can now be sorted\nrecursively on primary keys. BREAKING: previously the first listed, not the\nlowest id, would be the primary key. Also introduces fixed length scalar arrays\nin struct fields (struct and enum elements are not supported). Structs support\nfixed length array fields, including char arrays. Empty structs never fully\nworked and are no longer supported, they are also no longer supported by flatc.\nNOTE: char arrays are not currently part of Googles flatc compiler - int8 arrays\nmay be used instead. BREAKING: empty structs are no longer supported - they are\nalso not valid in Googles flatc compiler. See CHANGELOG for additional changes.\nDEPRECATED: low-level `cast_to/from` from functions in `flatcc_accessors.h` will\nbe removed in favor of `read/write_from/to` because the cast interface breaks\nfloat conversion on some uncommon platforms. This should not affect normal use\nbut remains valid in this release.\n\nRelease 0.5.3 inlcudes various bug fixes (see changelog) and one\nbreaking but likely low impact change: BREAKING: 0.5.3 changes behavour\nof builder create calls so arguments are always ordered by field id when\nid attributes are being used, for example\n`MyGame_Example_Monster_create()` in `monster_test.fbs`\n([#81](https://github.com/dvidelabs/flatcc/issues/81)). Fixes undefined\nbehavior when sorting tables by a numeric key field.\n\nRelease 0.5.2 introduces optional `_get` suffix to reader methods. By\nusing `flatcc -g` only `_get` methods are valid. This removes potential\nname conficts for some field names. 0.5.2 also introduces the long\nawaited clone operation for tables and vectors. A C++ smoketest was\nadded to reduce the number void pointer assignment errors that kept\nsneaking in. The runtime library now needs an extra file `refmap.c`.\n\nRelease 0.5.1 fixes a buffer overrun in the JSON printer and improves\nthe portable libraries \u003cstdalign.h\u003e compatibility with C++ and the\nembedded `newlib` standard library. JSON printing and parsing has been\nmade more consistent to help parse and print tables other than the\nschema root as seen in the test driver in [test_json.c]. The\n[monster_test.fbs] file has been reorganized to keep the Monster table\nmore consistent with Googles flatc version and a minor schema namespace\ninconsistency has been resolved as a result. Explicit references to\nportable headers have been moved out of generated source. extern \"C\" C++\nguards added around generated headers. 0.5.1 also cleaned up the\nlow-level union interface so the terms { type, value } are used\nconsistently over { type, member } and { types, members }.\n\n\n### Main features supported as of 0.6.1\n\n- generated FlatBuffers reader and builder headers for C\n- generated FlatBuffers verifier headers for C\n- generated FlatBuffers JSON parser and printer for C\n- ability to concatenate all output into one file, or to stdout\n- robust dependency file generation for build systems\n- binary schema (.bfbs) generation\n- pre-generated reflection headers for handling .bfbs files\n- cli schema compiler and library for compiling schema\n- runtime library for builder, verifier and JSON support\n- thorough test cases\n- monster sample project\n- fast build times\n- support for big endian platforms (as of 0.4.0)\n- support for big endian encoded flatbuffers on both le and be platforms. Enabled on `be` branch.\n- size prefixed buffers - see also [Builder Interface Reference]\n- flexible configuration of malloc alternatives and runtime\n  aligned_alloc/free support in builder library.\n- feature parity with C++ FlatBuffers schema features added in 2017\n  adding support for union vectors and mixed type unions of strings,\n  structs, and tables, and type aliases for uint8, ..., float64.\n- base64(url) encoded binary data in JSON.\n- sort fields by primary key (as of 0.6.0)\n- char arrays (as of 0.6.0)\n- optional scalar values (as of 0.6.1)\n\nThere are no plans to make frequent updates once the project becomes\nstable, but input from the community will always be welcome and included\nin releases where relevant, especially with respect to testing on\ndifferent target platforms.\n\n\n### Supported platforms (CI tested)\n\nAs of flatcc v.0.6.2 the weekly build on github actions tests a range of\ngcc and clang versions on Ubuntu and macOS but the lists changes slightly\nas the underlying CI runners sometimes drop a compiler version. Windows\nis tested on Appveyor with MSVC 2025 and a later version on Github actions.\nSee the appveyour and github actions workflow files for details.\n\nIn the past (ca. \u003c flatcc-0.6.2) the following have been tested, and chances are\nthat an older version of flatcc is still useful if the latest version does not\ncompile on a given platform.\n\n- Ubuntu Trusty gcc 4.4, 4.6-4.9, 5, 6, 7 and clang 3.6, 3.8\n- OS-X current clang / gcc\n- Windows MSVC 2010, 2013, 2015, 2015 Win64, 2017, 2017 Win64\n- C++11/C++14 user code on the above platforms.\n\nC11/C++11 is the reference that is expected to always work.\n\nThe GCC `--pedantic` compiler option is not supported as of GCC-8+\nbecause it forces non-portable code changes and because it tends to\nbreak the code base with each new GCC release.\n\nOlder/non-standard versions of C++ compilers cause problems because\n`static_assert` and `alignas` behave in strange ways where they are\nneither absent nor fully working as expected. There are often\nworkarounds, but it is more reliable to use `-std=c++11` or\n`-std=c++14`.\n\nThe portably library does not support GCC C++ pre 4.7 because the\nportable library does not work around C++ limitations in stdalign.h and\nstdint.h before GCC 4.7. This could be fixed but is not a priority.\n\nThe monster sample does not work with MSVC 2010 because it intentionally\nuses C99 style code to better follow the C++ version.\n\nThe build option `FLATCC_TEST` can be used to disable all tests which\nmight make flatcc compile on platforms that are otherwise problematic.\nThe buld option `FLATCC_CXX_TEST` can be disabled specifically for C++\ntests (a simple C++ file that includes generated C code).\n\n### Platforms reported to work by users\n\n- ESP32 SoC SDK with FreeRTOS and newlib has been reported to compile\n  cleanly with C++ 14 using flatcc generated JSON parsers, as of flatcc\n  0.5.1.\n- FreeRTOS when using custom memory allocation methods.\n- Arduino\n- IBM XLC on AIX big endian Power PC has been tested for release 0.4.0\n  but is not part of regular release tests.\n- IBM s390x big endian via QEMU.\n\n### Portability\n\nThere is no reason why other or older compilers cannot be supported, but\nit may require some work in the build configuration and possibly\nupdates to the portable library. The above is simply what has been\ntested and configured.\n\nThe portability layer has some features that are generally important for\nthings like endian handling, and others to provide compatibility for\noptional and missing C11 features. Together this should support most C\ncompilers around, but relies on community feedback for maturity.\n\nThe necessary size of the runtime include files can be reduced\nsignificantly by using -std=c11 and avoiding JSON (which needs a lot of\nnumeric parsing support), and by removing `include/flatcc/reflection`\nwhich is present to support handling of binary schema files and can be\ngenerated from `reflection/reflection.fbs`, and removing\n`include/flatcc/support` which is only used for tests and samples. The\nexact set of required files may change from release to release, and it\ndoesn't really matter with respect to the compiled code size.\n\n\n## Time / Space / Usability Tradeoff\n\nThe priority has been to design an easy to use C builder interface that\nis reasonably fast, suitable for both servers and embedded devices, but\nwith usability over absolute performance - still the small buffer output\nrate is measured in millons per second and read access 10-100 millon\nbuffers per second from a rough estimate. Reading FlatBuffers is more\nthan an order of magnitude faster than building them.\n\nFor 100MB buffers with 1000 monsters, dynamically extended monster\nnames, monster vector, and inventory vector, the bandwidth reaches about\n2.2GB/s and 45ms/buffer on 2.2GHz Haswell Core i7 CPU. This includes\nreading back and validating all data. Reading only a few key fields\nincreases bandwidth to 2.7GB/s and 37ms/op. For 10MB buffers bandwidth\nmay be higher but eventually smaller buffers will be hit by call\noverhead and thus we get down to 300MB/s at about 150ns/op encoding\nsmall buffers. These numbers are just a rough guideline - they obviously\ndepend on hardware, compiler, and data encoded. Measurements are\nexcluding an initial warmup step.\n\nThe generated JSON parsers are roughly 4 times slower than building a\nFlatBuffer directly in C or C++, or about 2200ns vs 600ns for a 700 byte\nJSON message. JSON parsing is thus roughly two orders of magnitude faster\nthan reading the equivalent Protocol Buffer, as reported on the [Google\nFlatBuffers\nBenchmarks](http://google.github.io/flatbuffers/flatbuffers_benchmarks.html)\npage. LZ4 compression would estimated double the overall processing time\nof JSON parsing. JSON printing is faster than parsing but not very\nsignificantly so. JSON compresses to roughly half the size of compressed\nFlatBuffers on large buffers, but compresses worse on small buffers (not\nto mention when not compressing at all).\n\nIt should be noted that FlatBuffer read performance exclude verification\nwhich JSON parsers and Protocol Buffers inherently include by their\nnature. Verification has not been benchmarked, but would presumably add\nless than 50% read overhead unless only a fraction of a large buffer is to\nbe read.\n\nSee also [Benchmarks].\n\nThe client C code can avoid almost any kind of allocation to build\nbuffers as a builder stack provides an extensible arena before\ncommitting objects - for example appending strings or vectors piecemeal.\nThe stack is mostly bypassed when a complete object can be constructed\ndirectly such as a vector from integer array on little endian platforms.\n\nThe reader interface should be pretty fast as is with less room for\nimprovement performance wise. It is also much simpler than the builder.\n\nUsability has also been prioritized over smallest possible generated\nsource code and compile time. It shouldn't affect the compiled size\nby much.\n\nThe compiled binary output should be reasonably small for everything but\nthe most restrictive microcontrollers. A 33K monster source test file\n(in addition to the generated headers and the builder library) results\nin a less than 50K optimized binary executable file including overhead\nfor printf statements and other support logic, or a 30K object file\nexcluding the builder library.\n\nRead-only binaries are smaller but not necessarily much smaller than\nbuilders considering they do less work: The compatibility test reads a\npre-generated binary `monsterdata_test.golden` monster file and verifies\nthat all content is as expected. This results in a 13K optimized binary\nexecutable or a 6K object file. The source for this check is 5K\nexcluding header files. Readers do not need to link with a library.\n\nJSON parsers bloat the compiled C binary compared to pure Flatbuffer\nusage because they inline the parser decision tree. A JSON parser for\nmonster.fbs may add 100K +/- optimization settings to the executable\nbinary.\n\n\n## Generated Files\n\nThe generated code for building flatbuffers,\nand for parsing and printing flatbuffers, all need access to\n`include/flatcc`. The reader does no rely on any library but all other\ngenerated files rely on the `libflatccrt.a` runtime library. Note that\n`libflatcc.a` is only required if the flatcc compiler itself is required\nas a library.\n\nThe reader and builder rely on generated common reader and builder\nheader files. These common file makes it possible to change the global\nnamespace and redefine basic types (`uoffset_t` etc.). In the future\nthis _might_ move into library code and use macros for these\nabstractions and eventually have a set of predefined files for types\nbeyond the standard 32-bit unsigned offset (`uoffset_t`). The runtime\nlibrary is specific to one set of type definitions.\n\nRefer to [monster_test.c] and the generated files for detailed guidance\non use. The monster schema used in this project is a slight adaptation\nto the original to test some additional edge cases.\n\nFor building flatbuffers a separate builder header file is generated per\nschema. It requires a `flatbuffers_common_builder.h` file also generated\nby the compiler and a small runtime library `libflatccrt.a`. It is\nbecause of this requirement that the reader and builder generated code\nis kept separate. Typical uses can be seen in the [monster_test.c] file.\nThe builder allows for repeated pushing of content to a vector or a\nstring while a containing table is being updated which simplifies\nparsing of external formats. It is also possible to build nested buffers\nin-line - at first this may sound excessive but it is useful when\nwrapping a union of buffers in a network interface and it ensures proper\nalignment of all buffer levels.\n\nFor verifying flatbuffers, a `myschema_verifier.h` is generated. It\ndepends on the runtime library and the reader header.\n\nJson parsers and printers generate one file per schema file and included\nschema will have their own parsers and printers which including parsers\nand printers will depend upon, rather similar to how builders work.\n\nLow level note: the builder generates all vtables at the end of the\nbuffer instead of ad-hoc in front of each table but otherwise does the\nsame deduplication of vtables. This makes it possible to cluster vtables\nin hot cache or to make sure all vtables are available when partially\ntransmitting a buffer. This behavior can be disabled by a runtime flag.\n\nBecause some use cases may include very constrained embedded devices,\nthe builder library can be customized with an allocator object and a\nbuffer emitter object. The separate emitter ensures a buffer can be\nconstructed without requiring a full buffer to be present in memory at\nonce, if so desired.\n\nThe typeless builder library is documented in [flatcc_builder.h] and\n[flatcc_emitter.h] while the generated typed builder api for C is\ndocumented in [Builder Interface Reference].\n\n\n### Use of Macros in Generated Code\n\nOccasionally a concern is raised about the dense nature of the macros\nused in the generated code. These macros make it difficult to understand\nwhich functions are actually available. The [Builder Interface Reference]\nattempts to document the operations in general fashion. To get more\ndetailed information, generated function prototypes can be extracted\nwith the `scripts/flatcc-doc.sh` script.\n\nSome are also concerned with macros being \"unsafe\". Macros are not\nunsafe when used with FlatCC because they generate static or static\ninline functions. These will trigger compile time errors if used\nincorrectly to the same extend that they would in direct C code.\n\nThe expansion compresses the generated output by more than a factor 10\nensuring that code under source control does not explode and making it\npossible to compare versions of generated code in a meaningful manner\nand see if it matches the intended schema. The macros are also important\nfor dealing with platform abstractions via the portable headers.\n\nStill, it is possible to see the generated output although not supported\ndirectly by the build system. As an example,\n`include/flatcc/reflection` contains pre-generated header files for the\nreflection schema. To see the expanded output using the `clang` compiler\ntool chain, run:\n\n\tclang -E -DNDEBUG -I include \\\n\t\t\tinclude/flatcc/reflection/reflection_reader.h | \\\n\tclang-format\n\nOther similar commands are likely available on platforms not supporting\nclang.\n\nNote that the compiler will optimize out nearly all of the generated\ncode and only use the logic actually referenced by end-user code because\nthe functions are static or static inline. The remaining parts generally\ninline efficiently into the application code resulting in a reasonably\nsmall binary code size.\n\nMore details can be found in\n[#88](https://github.com/dvidelabs/flatcc/issues/88)\n\n\n### Extracting Documentation\n\nThe expansion of generated code can be used to get documentation for\na specific object type.\n\nThe following script automates this process:\n\n    scripts/flatcc-doc.sh \u003cschema-file\u003e \u003cname-prefix\u003e [\u003coutdir\u003e]\n\nwriting function prototypes to `\u003coutdir\u003e/\u003cname-prefix\u003e.doc`.\n\nNote that the script requires the clang compiler and the clang-format\ntool, but the script could likely be adapted for other tool chains as well.\n\nThe principle behind the script can be illustrated using the reflection\nschema as an example, where documentation for the Object table is\nextracted:\n\n    bin/flatcc reflection/reflection.fbs -a --json --stdout | \\\n        clang - -E -DNDEBUG -I include | \\\n        clang-format -style=\"WebKit\" | \\\n    \tgrep \"^static.* reflection_Object_\\w*(\" | \\\n        cut -f 1 -d '{' | \\\n        grep -v deprecated | \\\n        grep -v \");\" | \\\n        sed 's/__tmp//g' | \\\n        sed 's/)/);/g'\n\nThe WebKit style of clang-format ensures that parameters and the return\ntype are all placed on the same line. Grep extracts the function headers\nand cut strips function bodies starting on the same line. Sed strips\n`__tmp` suffix from parameter names used to avoid macro name conflicts.\nGrep strips `);` to remove redundant forward declarations and sed then\nadds ; to make each line a valid C prototype.\n\nThe above is not guaranteed to always work as output may change, but it\nshould go a long way.\n\nA small extract of the output, as of flatcc-v0.5.2\n\n\tstatic inline size_t reflection_Object_vec_len(reflection_Object_vec_t vec);\n\tstatic inline reflection_Object_table_t reflection_Object_vec_at(reflection_Object_vec_t vec, size_t i);\n\tstatic inline reflection_Object_table_t reflection_Object_as_root_with_identifier(const void* buffer, const char* fid);\n\tstatic inline reflection_Object_table_t reflection_Object_as_root_with_type_hash(const void* buffer, flatbuffers_thash_t thash);\n\tstatic inline reflection_Object_table_t reflection_Object_as_root(const void* buffer);\n\tstatic inline reflection_Object_table_t reflection_Object_as_typed_root(const void* buffer);\n\tstatic inline flatbuffers_string_t reflection_Object_name_get(reflection_Object_table_t t);\n\tstatic inline flatbuffers_string_t reflection_Object_name(reflection_Object_table_t t);\n\tstatic inline int reflection_Object_name_is_present(reflection_Object_table_t t);\n\tstatic inline size_t reflection_Object_vec_scan_by_name(reflection_Object_vec_t vec, const char* s);\n\tstatic inline size_t reflection_Object_vec_scan_n_by_name(reflection_Object_vec_t vec, const char* s, int n);\n\t...\n\n\nExamples are provided in following script using the reflection and monster schema:\n\n    scripts/reflection-doc-example.sh\n    scripts/monster-doc-example.sh\n\nThe monster doc example essentially calls:\n\n\tscripts/flatcc-doc.sh samples/monster/monster.fbs MyGame_Sample_Monster_\n\nresulting in the file `MyGame_Sample_Monster_.doc`:\n\n\tstatic inline size_t MyGame_Sample_Monster_vec_len(MyGame_Sample_Monster_vec_t vec);\n\tstatic inline MyGame_Sample_Monster_table_t MyGame_Sample_Monster_vec_at(MyGame_Sample_Monster_vec_t vec, size_t i);\n\tstatic inline MyGame_Sample_Monster_table_t MyGame_Sample_Monster_as_root_with_identifier(const void* buffer, const char* fid);\n\tstatic inline MyGame_Sample_Monster_table_t MyGame_Sample_Monster_as_root_with_type_hash(const void* buffer, flatbuffers_thash_t thash);\n\tstatic inline MyGame_Sample_Monster_table_t MyGame_Sample_Monster_as_root(const void* buffer);\n\tstatic inline MyGame_Sample_Monster_table_t MyGame_Sample_Monster_as_typed_root(const void* buffer);\n\tstatic inline MyGame_Sample_Vec3_struct_t MyGame_Sample_Monster_pos_get(MyGame_Sample_Monster_table_t t);\n\tstatic inline MyGame_Sample_Vec3_struct_t MyGame_Sample_Monster_pos(MyGame_Sample_Monster_table_t t);\n\tstatic inline int MyGame_Sample_Monster_pos_is_present(MyGame_Sample_Monster_table_t t);\n\tstatic inline int16_t MyGame_Sample_Monster_mana_get(MyGame_Sample_Monster_table_t t);\n\tstatic inline int16_t MyGame_Sample_Monster_mana(MyGame_Sample_Monster_table_t t);\n\tstatic inline const int16_t* MyGame_Sample_Monster_mana_get_ptr(MyGame_Sample_Monster_table_t t);\n\tstatic inline int MyGame_Sample_Monster_mana_is_present(MyGame_Sample_Monster_table_t t);\n\tstatic inline size_t MyGame_Sample_Monster_vec_scan_by_mana(MyGame_Sample_Monster_vec_t vec, int16_t key);\n\tstatic inline size_t MyGame_Sample_Monster_vec_scan_ex_by_mana(MyGame_Sample_Monster_vec_t vec, size_t begin, size_t end, int16_t key);\n\t...\n\n\nFlatBuffer native types can also be extracted, for example string operations:\n\n\tscripts/flatcc-doc.sh samples/monster/monster.fbs flatbuffers_string_\n\nresulting in `flatbuffers_string_.doc`:\n\n\tstatic inline size_t flatbuffers_string_len(flatbuffers_string_t s);\n\tstatic inline size_t flatbuffers_string_vec_len(flatbuffers_string_vec_t vec);\n\tstatic inline flatbuffers_string_t flatbuffers_string_vec_at(flatbuffers_string_vec_t vec, size_t i);\n\tstatic inline flatbuffers_string_t flatbuffers_string_cast_from_generic(const flatbuffers_generic_t p);\n\tstatic inline flatbuffers_string_t flatbuffers_string_cast_from_union(const flatbuffers_union_t u);\n\tstatic inline size_t flatbuffers_string_vec_find(flatbuffers_string_vec_t vec, const char* s);\n\tstatic inline size_t flatbuffers_string_vec_find_n(flatbuffers_string_vec_t vec, const char* s, size_t n);\n\tstatic inline size_t flatbuffers_string_vec_scan(flatbuffers_string_vec_t vec, const char* s);\n\tstatic inline size_t flatbuffers_string_vec_scan_n(flatbuffers_string_vec_t vec, const char* s, size_t n);\n\tstatic inline size_t flatbuffers_string_vec_scan_ex(flatbuffers_string_vec_t vec, size_t begin, size_t end, const char* s);\n\t...\n\n## Using flatcc\n\nRefer to `flatcc -h` for details.\n\nAn online version listed here: [flatcc-help.md] but please use `flatcc\n-h` for an up to date reference.\n\n\nThe compiler can either generate a single header file or headers for all\nincluded schema and a common file and with or without support for both\nreading (default) and writing (-w) flatbuffers. The simplest option is\nto use (-a) for all and include the `myschema_builder.h` file.\n\nThe (-a) or (-v) also generates a verifier file.\n\nMake sure `flatcc` under the `include` folder is visible in the C\ncompilers include path when compiling flatbuffer builders.\n\nThe `flatcc` (-I) include path will assume all schema files with same\nbase name (case insentive) are identical and will only include the\nfirst. All generated files use the input basename and will land in\nworking directory or the path set by (-o).\n\nFiles can be generated to stdout using (--stdout). C headers will be\nordered and concatenated, but are otherwise identical to the separate\nfile output. Each include statement is guarded so this will not lead to\nmissing include files.\n\nThe generated code, especially with all combined with --stdout, may\nappear large, but only the parts actually used will take space up the\nthe final executable or object file. Modern compilers inline and include\nonly necessary parts of the statically linked builder library.\n\nJSON printer and parser can be generated using the --json flag or\n--json-printer or json-parser if only one of them is required. There are\nsome certain runtime library compile time flags that can optimize out\nprinting symbolic enums, but these can also be disabled at runtime.\n\n## Trouble Shooting\n\nMake sure to link with `libflatccrt` (rt for runtime) and not `libflatcc` (the schema compiler), otherwise the builder will not be available. Also make sure to have the 'include' of the flatcc project root in the include path.\n\nFlatcc will by default expect a `file_identifier` in the buffer when reading or\nverifying a buffer.\n\nA buffer can have an unexpected 4-byte identifier at offset 4, or the identifier\nmight be absent.\n\nNot all language interfaces support file identifiers in buffers, and if they do, they might not do so in an older version. Users have reported problems with both Python and Lua interfaces but this is easily resolved.\n\nCheck the return value of the verifier:\n\n    int ret;\n    char *s;\n\n    ret = MyTable_verify_as_root(buf, size);\n    if (ret) {\n        s = flatcc_verify_error_string(ret);\n        printf(\"buffer failed: %s\\n\", s);\n    }\n\nTo verify a buffer with no identifier, or to ignore a different identifier,\nuse the `_with_identifier` version of the verifier with a null identifier:\n\n    char *identifier = 0;\n\n    MyTable_verify_as_root_with_identifier(buf, size, identifier);\n\nTo read a buffer use:\n\n    MyTable_as_root_with_identifier(buf, 0);\n\nAnd to build a buffer without an identifier use:\n\n    MyTable_start_as_root_with_identifier(builder, 0);\n    ...\n    MyTable_end_as_root_with_identifier(builder, 0);\n\nSeveral other `as_root` calls have an `as_root_with_identifier` version,\nincluding JSON printing.\n\n## Quickstart\n\nAfter [building](https://github.com/dvidelabs/flatcc#building) the `flatcc tool`,\nbinaries are located in the `bin` and `lib` directories under the\n`flatcc` source tree.\n\nYou can either jump directly to the [monster\nexample](https://github.com/dvidelabs/flatcc/tree/master/samples/monster)\nthat follows\n[Googles FlatBuffers Tutorial](https://google.github.io/flatbuffers/flatbuffers_guide_tutorial.html), or you can read along the quickstart guide below. If you follow\nthe monster tutorial, you may want to clone and build flatcc and copy\nthe source to a separate project directory as follows:\n\n    git clone https://github.com/dvidelabs/flatcc.git\n    flatcc/scripts/setup.sh -a mymonster\n    cd mymonster\n    scripts/build.sh\n    build/mymonster\n\n`scripts/setup.sh` will as a minimum link the library and tool into a\ncustom directory, here `mymonster`. With (-a) it also adds a simple\nbuild script, copies the example, and updates `.gitignore` - see\n`scripts/setup.sh -h`. Setup can also build flatcc, but you still have\nto ensure the build environment is configured for your system.\n\nTo write your own schema files please follow the main FlatBuffers\nproject documentation on [writing schema\nfiles](https://google.github.io/flatbuffers/flatbuffers_guide_writing_schema.html).\n\nThe [Builder Interface Reference] may be useful after studying the\nmonster sample and quickstart below.\n\nWhen looking for advanced examples such as sorting vectors and finding\nelements by a key, you should find these in the\n[`test/monster_test`](https://github.com/dvidelabs/flatcc/tree/master/test/monster_test) project.\n\nThe following quickstart guide is a broad simplification of the\n`test/monster_test` project - note that the schema is slightly different\nfrom the tutorial. Focus is on the C specific framework rather\nthan general FlatBuffers concepts.\n\nYou can still use the setup tool to create an empty project and\nfollow along, but there are no assumptions about that in the text below.\n\n### Reading a Buffer\n\nHere we provide a quick example of read-only access to Monster flatbuffer -\nit is an adapted extract of the [monster_test.c] file.\n\nFirst we compile the schema read-only with common (-c) support header and we\nadd the recursion because [monster_test.fbs] includes other files.\n\n    flatcc -cr --reader test/monster_test/monster_test.fbs\n\nFor simplicity we assume you build an example project in the project\nroot folder, but in praxis you would want to change some paths, for\nexample:\n\n    mkdir -p build/example\n    flatcc -cr --reader -o build/example test/monster_test/monster_test.fbs\n    cd build/example\n\nWe get:\n\n    flatbuffers_common_reader.h\n    include_test1_reader.h\n    include_test2_reader.h\n    monster_test_reader.h\n\n(There is also the simpler `samples/monster/monster.fbs` but then you won't get\nincluded schema files).\n\nNamespaces can be long so we optionally use a macro to manage this.\n\n    #include \"monster_test_reader.h\"\n\n    #undef ns\n    #define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Example, x)\n\n    int verify_monster(void *buffer)\n    {\n        ns(Monster_table_t) monster;\n        /* This is a read-only reference to a flatbuffer encoded struct. */\n        ns(Vec3_struct_t) vec;\n        flatbuffers_string_t name;\n        size_t offset;\n\n        if (!(monster = ns(Monster_as_root(buffer)))) {\n            printf(\"Monster not available\\n\");\n            return -1;\n        }\n        if (ns(Monster_hp(monster)) != 80) {\n            printf(\"Health points are not as expected\\n\");\n            return -1;\n        }\n        if (!(vec = ns(Monster_pos(monster)))) {\n            printf(\"Position is absent\\n\");\n            return -1;\n        }\n\n        /* -3.2f is actually -3.20000005 and not -3.2 due to representation loss. */\n        if (ns(Vec3_z(vec)) != -3.2f) {\n            printf(\"Position failing on z coordinate\\n\");\n            return -1;\n        }\n\n        /* Verify force_align relative to buffer start. */\n        offset = (char *)vec - (char *)buffer;\n        if (offset \u0026 15) {\n            printf(\"Force align of Vec3 struct not correct\\n\");\n            return -1;\n        }\n\n        /*\n         * If we retrieved the buffer using `flatcc_builder_finalize_aligned_buffer` or\n         * `flatcc_builder_get_direct_buffer` the struct should also\n         * be aligned without subtracting the buffer.\n         */\n        if (vec \u0026 15) {\n            printf(\"warning: buffer not aligned in memory\\n\");\n        }\n\n        /* ... */\n        return 0;\n    }\n    /* main() {...} */\n\n\n### Compiling for Read-Only\n\nAssuming our above file is `monster_example.c` the following are a few\nways to compile the project for read-only - compilation with runtime\nlibrary is shown later on.\n\n    cc -I include monster_example.c -o monster_example\n\n    cc -std=c11 -I include monster_example.c -o monster_example\n\n    cc -D FLATCC_PORTABLE -I include monster_example.c -o monster_example\n\nThe include path or source path is likely different. Some files in\n`include/flatcc/portable` are always used, but the `-D FLATCC_PORTABLE`\nflag includes additional files to support compilers lacking c11\nfeatures.\n\nNOTE: on some clang/gcc platforms it may be necessary to use -std=gnu99 or\n-std=gnu11 if the linker is unable find `posix_memalign`, see also comments in\n[paligned_alloc.h].\n\n\n### Building a Buffer\n\nHere we provide a very limited example of how to build a buffer - only a few\nfields are updated. Pleaser refer to [monster_test.c] and the doc directory\nfor more information.\n\nFirst we must generate the files:\n\n    flatcc -a monster_test.fbs\n\nThis produces:\n\n    flatbuffers_common_reader.h\n    flatbuffers_common_builder.h\n    include_test1_reader.h\n    include_test1_builder.h\n    include_test1_verifier.h\n    include_test2_reader.h\n    include_test2_builder.h\n    include_test2_verifier.h\n    monster_test_reader.h\n    monster_test_builder.h\n    monster_test_verifier.h\n\nNote: we wouldn't actually do the readonly generation shown earlier\nunless we only intend to read buffers - the builder generation always\ngenerates read acces too.\n\nBy including `\"monster_test_builder.h\"` all other files are included\nautomatically. The C compiler needs the `-I include` directive to access\n`flatcc/flatcc_builder.h`, `flatcc/flatcc_verifier.h`, and other files\ndepending on specifics, assuming the project root is the current\ndirectory.\n\nThe verifiers are not required and just created because we lazily chose\nthe -a option.\n\nThe builder must be initialized first to set up the runtime environment\nwe need for building buffers efficiently - the builder depends on an\nemitter object to construct the actual buffer - here we implicitly use\nthe default. Once we have that, we can just consider the builder a\nhandle and focus on the FlatBuffers generated API until we finalize the\nbuffer (i.e. access the result).  For non-trivial uses it is recommended\nto provide a custom emitter and for example emit pages over the network\nas soon as they complete rather than merging all pages into a single\nbuffer using `flatcc_builder_finalize_buffer`, or the simplistic\n`flatcc_builder_get_direct_buffer` which returns null if the buffer is\ntoo large. See also documentation comments in [flatcc_builder.h] and\n[flatcc_emitter.h]. See also `flatc_builder_finalize_aligned_buffer` in\n`builder.h` and the [Builder Interface Reference] when malloc aligned\nbuffers are insufficent.\n\n\n    #include \"monster_test_builder.h\"\n\n    /* See [monster_test.c] for more advanced examples. */\n    void build_monster(flatcc_builder_t *B)\n    {\n        ns(Vec3_t *vec);\n\n        /* Here we use a table, but structs can also be roots. */\n        ns(Monster_start_as_root(B));\n\n        ns(Monster_hp_add(B, 80));\n        /* The vec struct is zero-initalized. */\n        vec = ns(Monster_pos_start(B));\n        /* Native endian. */\n        vec-\u003ex = 1, vec-\u003ey = 2, vec-\u003ez = -3.2f;\n        /* _end call converts to protocol endian format - for LE it is a nop. */\n        ns(Monster_pos_end(B));\n\n        /* Name is required, or we get an assertion in debug builds. */\n        ns(Monster_name_create_str(B, \"MyMonster\"));\n\n        ns(Monster_end_as_root(B));\n    }\n\n    #include \"flatcc/support/hexdump.h\"\n\n    int main(int argc, char *argv[])\n    {\n        flatcc_builder_t builder;\n        void *buffer;\n        size_t size;\n\n        flatcc_builder_init(\u0026builder);\n\n        build_monster(\u0026builder);\n        /* We could also use `flatcc_builder_finalize_buffer` and free the buffer later. */\n        buffer = flatcc_builder_get_direct_buffer(\u0026builder, \u0026size);\n        assert(buffer);\n        verify_monster(buffer);\n\n        /* Visualize what we got ... */\n        hexdump(\"monster example\", buffer, size, stdout);\n\n        /*\n         * Here we can call `flatcc_builder_reset(\u0026builder) if\n         * we wish to build more buffers before deallocating\n         * internal memory with `flatcc_builder_clear`.\n         */\n\n        flatcc_builder_clear(\u0026builder);\n        return 0;\n    }\n\nCompile the example project:\n\n    cc -std=c11 -I include monster_example.c lib/libflatccrt.a -o monster_example\n\nNote that the runtime library is required for building buffers, but not\nfor reading them. If it is incovenient to distribute the runtime library\nfor a given target, source files may be used instead. Each feature has\nits own source file, so not all runtime files are needed for building a\nbuffer:\n\n    cc -std=c11 -I include monster_example.c \\\n        src/runtime/emitter.c src/runtime/builder.c \\\n        -o monster_example\n\nOther features such as the verifier and the JSON printer and parser\nwould each need a different file in src/runtime. Which file should be\nobvious from the filenames except that JSON parsing also requires the\nbuilder and emitter source files.\n\n\n### Verifying a Buffer\n\nA buffer can be verified to ensure it does not contain any ranges that\npoint outside the the given buffer size, that all data structures are\naligned according to the flatbuffer principles, that strings are zero\nterminated, and that required fields are present.\n\nIn the builder example above, we can apply a verifier to the output:\n\n    #include \"monster_test_builder.h\"\n    #include \"monster_test_verifier.h\"\n    int ret;\n    ...\n    ... finalize\n    if ((ret = ns(Monster_verify_as_root_with_identifier(buffer, size,\n            \"MONS\")))) {\n        printf(\"Monster buffer is invalid: %s\\n\",\n        flatcc_verify_error_string(ret));\n    }\n\nThe [readfile.h] utility may also be helpful in reading an existing\nbuffer for verification.\n\nFlatbuffers can optionally leave out the identifier, here \"MONS\". Use a\nnull pointer as identifier argument to ignore any existing identifiers\nand allow for missing identifiers.\n\nNested flatbuffers are always verified with a null identifier, but it\nmay be checked later when accessing the buffer.\n\nThe verifier does NOT verify that two datastructures are not\noverlapping. Sometimes this is indeed valid, such as a DAG (directed\nacyclic graph) where for example two string references refer to the same\nstring in the buffer. In other cases an attacker may maliciously\nconstruct overlapping datastructures such that in-place updates may\ncause subsequent invalid buffers. Therefore an untrusted buffer should\nnever be updated in-place without first rewriting it to a new buffer.\n\nThe CMake build system has build option to enable assertions in the\nverifier. This will break debug builds and not usually what is desired,\nbut it can be very useful when debugging why a buffer is invalid. Traces\ncan also be enabled so table offset and field id can be reported.\n\nSee also `include/flatcc/flatcc_verifier.h`.\n\nWhen verifying buffers returned directly from the builder, it may be\nnecessary to use the `flatcc_builder_finalize_aligned_buffer` to ensure\nproper alignment and use `aligned_free` to free the buffer (or as of\nv0.5.0 also `flatcc_builder_aligned_free`), see also the\n[Builder Interface Reference]. Buffers may also be copied into aligned\nmemory via mmap or using the portable layers `paligned_alloc.h` feature\nwhich is available when including generated headers.\n`test/flatc_compat/flatc_compat.c` is an example of how this can be\ndone. For the majority of use cases, standard allocation would be\nsufficient, but for example standard 32-bit Windows only allocates on an\n8-byte boundary and can break the monster schema because it has 16-byte\naligned fields.\n\nNOTE: as of August 2024 it has been discovered that C++ writer code has been\naligning empty vectors to the size field only, even if elements require\ngreater alignment like the double type which requires 8. This would cause the\nFlatCC verifier to (correctly) reject these vectors because it would result\nin an invalid C pointer type on some architectures. However, because this has\nbeen in effect for over 10 years, the consensus is to have verifiers tolerate\nthis behaviour even if C++ will eventually fix this issue. The FlatCC\nverifier has been updated to accept such buffers by default with an optional\ncompile time flag to enforce the strict behaviour as well\n(`FLATCC_ENFORCE_ALIGNED_EMPTY_VECTORS`). In principle the misaligned vectors\ncan potentially lead to undefined behaviour in agressively optimized C\ncompilers. As of now it appears to be safe to read such buffers on common\nplatforms and it is preferable to avoid additional runtime reader overhead to\ndeal with this. For more, see [FlatCC #287], [Google Flatbuffers #8374],\n[FlatCC #289].\n\n\n### Potential Name Conflicts\n\nIf unfortunate, it is possible to have a read accessor method conflict\nwith other generated methods and typenames. Usually a small change in\nthe schema will resolve this issue.\n\nAs of flatcc 0.6.2 conservative warnings will detect most likely\npotential conflicts in enum member names and table field names. The\n`-s` option silences warnings.\n\nAs of flatcc 0.5.2 read accors are generated with and without a `_get`\nsuffix so it is also possible to use `Monster_pos_get(monster)` instead\nof `Monster_pos(monster)`. When calling flatcc with option `-g` the\nread accesors will only be generated with `_get` suffix. This avoids\npotential name conflicts. An example of a conflict is a field name\nlike `pos_add` when there is also a `pos` field because the builder\ninterface generates the `add` suffix. Using the -g option avoids this\nproblem, but it is preferable to choose another name such as `added_pos`\nwhen the schema can be modified.\n\nThe `-g` option only changes the content of the\n`flatbuffers_common_reader.h` file, so it is technically  possible to\nuse different versions of this file if they are not mixed.\n\nIf an external code generator depends on flatcc output, it should use\nthe `_get` suffix because it will work with and without the -g option,\nbut only as of version 0.5.2 or later. For human readable code it is\nprobaly simpler to stick to the orignal naming convention without the\n`_get` suffix.\n\nEven with the above, it is still possible to have a conflict with the\nunion type field. If a union field is named `foo`, an additional field\nis automatically - this field is named `foo_type` and holds,\nunsurprisingly, the type of the union.\n\nNamespaces can also cause conflicts. If a schema has the namespace\nFoo.Bar and table named MyTable with a field name hello, then a\nread accessor will be named: `Foo_Bar_MyTable_hello_get`. It\nis also possible to have a table named `Bar_MyTable` because `_` are\nallowed in FlatBuffers schema names, but in this case we have name\nconflict in the generated the C code. FlatCC does not attempt to avoid\nsuch conflicts so such schema are considered invalid.\n\nNotably several users have experienced conflicts with a table or struct\nfield named 'identifier' because `\u003ctable-name\u003e_identifier` has been\ndefined to be the file identifier to be used when creating a buffer with\nthat table (or struct) as root. As of 0.6.1, the name is\n`\u003ctable-name\u003e_file_identifier` to reduce the risk of conflicts. The old\nform is deprecated but still generated for tables without a field named\n'identifier' for backwards compatibility. Mostly this macro is used for\nhigher level functions such as `mytable_create_as_root` which need to\nknow what identifier to use.\n\n\n### Debugging a Buffer\n\nWhen reading a FlatBuffer does not provide the expected results, the\nfirst line of defense is to ensure that the code being tested is linked\nagainst `flatccrt_d`, the debug build of the runtime library. This will\nraise an assertion if calls to the builder are not properly balanced or\nif required fields are not being set.\n\nTo dig further into a buffer, call the buffer verifier and see if the\nbuffer is actually valid with respect to the expected buffer type.\n\nStrings and tables will be returned as null pointers when their\ncorresponding field is not set in the buffer. User code should test for\nthis but it might also be helpful to temporarily or permanently set the\n`required` attribute in the schema. The builder will then detect missing fields\nwhen cerating buffers and the verifier can will detect their absence in\nan existing buffer.\n\nIf the verifier rejects a buffer, the error can be printed (see\n[Verifying a Buffer](#verifying-a-buffer)), but it will not say exactly\nwhere the problem was found. To go further, the verifier can be made to\nassert where the problem is encountered so the buffer content can be\nanalyzed. This is enabled with:\n\n    -DFLATCC_DEBUG_VERIFY=1\n\nNote that this will break test cases where a buffer is expected to fail\nverification.\n\nTo dump detailed contents of a valid buffer, or the valid contents up to\nthe point of failure, use:\n\n    -DFLATCC_TRACE_VERIFY=1\n\nBoth of these options can be set as CMake options, or in the\n[flatcc_rtconfig.h] file.\n\nWhen reporting bugs, output from the above might also prove helpful.\n\nThe JSON parser and printer can also be used to create and display\nbuffers. The parser will use the builder API correctly or issue a syntax\nerror or an error on required field missing. This can rule out some\nuncertainty about using the api correctly. The [test_json.c] file and\n[test_json_parser.c] have\ntest functions that can be adapted for custom tests.\n\nFor advanced debugging the [hexdump.h] file can be used to dump the buffer\ncontents. It is used in [test_json.c] and also in [monster_test.c].\nSee also [FlatBuffers Binary Format].\n\nAs of April 2022, Googles flatc tool has implemented an `--annotate` feature.\nThis provides an annotated hex dump given a binary buffer and a schema. The\noutput can be used to troubleshoot and rule out or confirm suspected encoding\nbugs in the buffer at hand. The eclectic example in the [FlatBuffers Binary\nFormat] document contains a hand written annotated example which inspired the\n`--annotate` feature, but it is not the exact same output format. Note also that\n`flatc` generated buffers tend to have vtables before the table it is referenced\nby, while flatcc normally packs all vtables at the end of the buffer for\nbetter padding and cache efficiency.\n\nSee also [flatc --annotate].\n\nNote: There is experimental support for text editor that supports\nclangd language server or similar. You can edit `CMakeList.txt`\nto generate `build/Debug/compile_comands.json`, at least when\nusing clang as a compiler, and copy or symlink it from root. Or\ncome with a better suggestion. There are `.gitignore` entries for\n`compile_flags.txt` and `compile_commands.json` in project root.\n\n\n## File and Type Identifiers\n\nThere are two ways to identify the content of a FlatBuffer. The first is\nto use file identifiers which are defined in the schema. The second is\nto use `type identifiers` which are calculated hashes based on each\ntables name prefixed with its namespace, if any. In either case the\nidentifier is stored at offset 4 in binary FlatBuffers, when present.\nType identifiers are not to be confused with union types.\n\n### File Identifiers\n\nThe FlatBuffers schema language has the optional `file_identifier`\ndeclaration which accepts a 4 characer ASCII string. It is intended to be\nhuman readable. When absent, the buffer potentially becomes 4 bytes\nshorter (depending on padding).\n\nThe `file_identifier` is intended to match the `root_type` schema\ndeclaration, but this does not take into account that it is convenient\nto create FlatBuffers for other types as well. `flatcc` makes no special\ndestinction for the `root_type` while Googles `flatc` JSON parser uses\nit to determine the JSON root object type.\n\nAs a consequence, the file identifier is ambigous. Included schema may\nhave separate `file_identifier` declarations. To at least make sure each\ntype is associated with its own schemas `file_identifier`, a symbol is\ndefined for each type. If the schema has such identifier, it will be\ndefined as the null identifier.\n\nThe generated code defines the identifiers for a given table:\n\n    #ifndef MyGame_Example_Monster_file_identifier\n    #define MyGame_Example_Monster_file_identifier \"MONS\"\n    #endif\n\nThe user can now override the identifier for a given type, for example:\n\n    #define MyGame_Example_Vec3_file_identifier \"VEC3\"\n    #include \"monster_test_builder.h\"\n\n    ...\n    MyGame_Example_Vec3_create_as_root(B, ...);\n\nThe `create_as_root` method uses the identifier for the type in question,\nand so does other `_as_root` methods.\n\nThe `file_extension` is handled in a similar manner:\n\n    #ifndef MyGame_Example_Monster_file_extension\n    #define MyGame_Example_Monster_file_extension \"mon\"\n    #endif\n\n### Type Identifiers\n\nTo better deal with the ambigouties of file identifiers, type\nidentifiers have been introduced as an alternative 4 byte buffer\nidentifier. The hash is standardized on FNV-1a for interoperability.\n\nThe type identifier use a type hash which maps a fully qualified type\nname into a 4 byte hash. The type hash is a 32-bit native value and the\ntype identifier is a 4 character little endian encoded string of the\nsame value.\n\nIn this example the type hash is derived from the string\n\"MyGame.Example.Monster\" and is the same for all FlatBuffer code\ngenerators that supports type hashes.\n\nThe value 0 is used to indicate that one does not care about the\nidentifier in the buffer.\n\n    ...\n    MyGame_Example_Monster_create_as_typed_root(B, ...);\n    buffer = flatcc_builder_get_direct_buffer(B);\n    MyGame_Example_Monster_verify_as_typed_root(buffer, size);\n    // read back\n    monster = MyGame_Example_Monster_as_typed_root(buffer);\n\n    switch (flatbuffers_get_type_hash(buffer)) {\n    case MyGame_Example_Monster_type_hash:\n        ...\n\n    }\n    ...\n    if (flatbuffers_get_type_hash(buffer) ==\n        flatbuffers_type_hash_from_name(\"Some.Old.Buffer\")) {\n        printf(\"Buffer is the old version, not supported.\\n\");\n    }\n\nMore API calls are available to naturally extend the existing API. See\n[monster_test.c] for more.\n\nThe type identifiers are defined like:\n\n    #define MyGame_Example_Monster_type_hash ((flatbuffers_thash_t)0x330ef481)\n    #define MyGame_Example_Monster_type_identifier \"\\x81\\xf4\\x0e\\x33\"\n\nThe `type_identifier` can be used anywhere the original 4 character\nfile identifier would be used, but a buffer must choose which system, if any,\nto use. This will not affect the `file_extension`.\n\nNOTE: The generated `_type_identifier` strings should not normally be\nused when an identifier string is expected in the generated API because\nit may contain null bytes which will be zero padded after the first null\nbefore comparison. Use the API calls that take a type hash instead. The\n`type_identifier` can be used in low level [flatcc_builder.h] calls\nbecause it handles identifiers as a fixed byte array and handles type\nhashes and strings the same.\n\nNOTE: it is possible to compile the flatcc runtime to encode buffers in\nbig endian format rather than the standard little endian format\nregardless of the host platforms endianness. If this is done, the\nidentifier field in the buffer is always byte swapped regardless of the\nidentifier method chosen. The API calls make this transparent, so \"MONS\"\nwill be stored as \"SNOM\" but should still be verified as \"MONS\" in API\ncalls. This safeguards against mixing little- and big-endian buffers.\nLikewise, type hashes are always tested in native (host) endian format.\n\n\nThe\n[`flatcc/flatcc_identifier.h`](https://github.com/dvidelabs/flatcc/blob/master/include/flatcc/flatcc_identifier.h)\nfile contains an implementation of the FNV-1a hash used. The hash was\nchosen for simplicity, availability, and collision resistance. For\nbetter distribution, and for internal use only, a dispersion function is\nalso provided, mostly to discourage use of alternative hashes in\ntransmission since the type hash is normally good enough as is.\n\n_Note: there is a potential for collisions in the type hash values\nbecause the hash is only 4 bytes._\n\n\n## JSON Parsing and Printing\n\nJSON support files are generated with `flatcc --json`.\n\nThis section is not a tutorial on JSON printing and parsing, it merely\ncovers some non-obvious aspects. The best source to get started quickly\nis the test file:\n\n    test/json_test/json_test.c\n\nFor detailed usage, please refer to:\n\n    test/json_test/test_json_printer.c\n    test/json_test/test_json_parser.c\n    test/json_test/json_test.c\n    test/benchmark/benchflatccjson\n\nSee also JSON parsing section in the Googles FlatBuffers [schema\ndocumentation](https://google.github.io/flatbuffers/flatbuffers_guide_writing_schema.html).\n\nBy using the flatbuffer schema it is possible to generate schema\nspecific JSON printers and parsers. This differs for better and worse\nfrom Googles `flatc` tool which takes a binary schema as input and\nprocesses JSON input and output. Here that parser and printer only rely\non the `flatcc` runtime library, is faster (probably significantly so),\nbut requires recompilition when new JSON formats are to be supported -\nthis is not as bad as it sounds - it would for example not be difficult\nto create a Docker container to process a specific schema in a web\nserver context.\n\nThe parser always takes a text buffer as input and produces output\naccording to how the builder object is initialized. The printer has\ndifferent init functions: one for printing to a file pointer, including\nstdout, one for printing to a fixed length external buffer, and one for\nprinting to a dynamically growing buffer. The dynamic buffer may be\nreused between prints via the reset function. See `flatcc_json_parser.h`\nfor details.\n\nThe parser will accept unquoted names (not strings) and trailing commas,\ni.e. non-strict JSON and also allows for hex `\\x03` in strings. Strict\nmode must be enabled by a compile time flag. In addition the parser\nschema specific symbolic enum values that can optionally be unquoted\nwhere a numeric value is expected:\n\n    color: Green\n    color: Color.Green\n    color: MyGame.Example.Color.Green\n    color: 2\n\nThe symbolic values do not have to be quoted (unless required by runtime\nor compile time configuration), but can be while numeric values cannot\nbe quoted. If no namespace is provided, like `color: Green`, the symbol\nmust match the receiving enum type. Any scalar value may receive a\nsymbolic value either in a relative namespace like `hp: Color.Green`, or\nan absolute namespace like `hp: MyGame.Example.Color.Green`, but not\n`hp: Green` (since `hp` in the monster example schema) is not an enum\ntype with a `Green` value). A namespace is relative to the namespace of\nthe receiving object.\n\nIt is also possible to have multiple values, but these always have to be\nquoted in order to be compatible with Googles flatc tool for Flatbuffers\n1.1:\n\n    color: \"Green Red\"\n\n_Unquoted multi-valued enums can be enabled at compile time but this is\ndeprecated because it is incompatible with both Googles flatc JSON and\nalso with other possible future extensions: `color: Green Red`_\n\nThese value-valued expressions were originally intended for enums that\nhave the bit flag attribute defined (which Color does have), but this is\ntricky to process, so therefore any symblic value can be listed in a\nsequence with or without namespace as appropriate. Because this further\ncauses problems with signed symbols the exact definition is that all\nsymbols are first coerced to the target type (or fail), then added to\nthe target type if not the first this results in:\n\n    color: \"Green Blue Red Blue\"\n    color: 19\n\nBecause Green is 2, Red is 1, Blue is 8 and repeated.\n\n__NOTE__: Duplicate values should be considered implementation dependent\nas it cannot be guaranteed that all flatbuffer JSON parsers will handle\nthis the same. It may also be that this implementation will change in\nthe future, for example to use bitwise or when all members and target\nare of bit flag type.\n\nIt is not valid to specify an empty set like:\n\n    color: \"\"\n\nbecause it might be understood as 0 or the default value, and it does\nnot unquote very well.\n\nThe printer will by default print valid json without any spaces and\neverything quoted. Use the non-strict formatting option (see headers and\ntest examples) to produce pretty printing. It is possibly to disable\nsymbolic enum values using the `noenum` option.\n\nOnly enums will print symbolic values are there is no history of any\nparsed symbolic values at all. Furthermore, symbolic values are only\nprinted if the stored value maps cleanly to one value, or in the case of\nbit-flags, cleanly to multiple values. For exmaple if parsing `color: Green Red`\nit will print as `\"color\":\"Red Green\"` by default, while `color: Green\nBlue Red Blue` will print as `color:19`.\n\nBoth printer and parser are limited to roughly 100 table nesting levels\nand an additional 100 nested struct depths. This can be changed by\nconfiguration flags but must fit in the runtime stack since the\noperation is recursive descent. Exceedning the limits will result in an\nerror.\n\nNumeric values are coerced to the receiving type. Integer types will\nfail if the assignment does not fit the target while floating point\nvalues may loose precision silently. Integer types never accepts\nfloating point values. Strings only accept strings.\n\nNested flatbuffers may either by arrays of byte sized integers, or a\ntable or a struct of the target type. See test cases for details.\n\nThe parser will by default fail on unknown fields, but these can also be\nskipped silently with a runtime option.\n\nUnions are difficult to parse. A union is two json fields: a table as\nusual, and an enum to indicate the type which has the same name with a\n`_type` suffix and accepts a numeric or symbolic type code:\n\n    {\n      name: \"Container Monster\",\n      test_type: Monster,\n      test: { name: \"Contained Monster\" }\n    }\n\nbased on the schema is defined in [monster_test.fbs].\n\nBecause other json processors may sort fields, it is possible to receive\nthe type field after the test field. The parser does not store temporary\ndatastructures. It constructs a flatbuffer directly. This is not\npossible when the type is late. This is handled by parsing the field as\na skipped field on a first pass, followed by a typed back-tracking\nsecond pass once the type is known (only the table is parsed twice, but\nfor nested unions this can still expand). Needless to say this slows down\nparsing. It is an error to provide only the table field or the type\nfield alone, except if the type is `NONE` or `0` in which case the table\nis not allowed to be present.\n\nUnion vectors are supported as of v0.5.0. A union vector is represented\nas two vectors, one with a vector of tables and one with a vector of\ntypes, similar to ordinary unions. It is more efficient to place the\ntype vector first because it avoids backtracking. Because a union of\ntype NONE cannot be represented by absence of table field when dealing\nwith vectors of unions, a table must have the value `null` if its type\nis NONE in the corresponding type vector. In other cases a table should\nbe absent, and not null.\n\nHere is an example of JSON containing Monster root table with a union\nvector field named `manyany` which is a vector of `Any` unions in the\n[monster_test.fbs] schema:\n\n    {\n        \"name\": \"Monster\",\n        \"manyany_type\": [ \"Monster\", \"NONE\" ],\n        \"manyany\": [{\"name\": \"Joe\"}, null]\n    }\n\n### Base64 Encoding\n\nAs of v0.5.0 it is possible to encode and decode a vector of type\n`[uint8]` (aka `[ubyte]`) as a base64 encoded string or a base64url\nencoded string as documented in RFC 4648. Any other type, notably the\nstring type, do not handle base64 encoding.\n\nLimiting the support to `[uint8]` avoids introducing binary data into\nstrings and also avoids dealing with sign and endian encoding of binary\ndata of other types. Furthermore, array encoding of values larger than 8\nbits are not necessarily less efficient than base64.\n\nBase64 padding is always printed and is optional when parsed. Spaces,\nlinebreaks, JSON string escape character '\\\\', or any other character\nnot in the base64(url) alphabet are rejected as a parse error.\n\nThe schema must add the attribute `(base64)` or `(base64url)` to the\nfield holding the vector, for example:\n\n    table Monster {\n        name: string;\n        sprite: [uint8] (base64);\n        token: [uint8] (base64url);\n    }\n\nIf more complex data needs to be encoded as base64 such as vectors of\nstructs, this can be done via nested FlatBuffers which are also of type\n`[uint8]`.\n\nNote that for some use cases it might be desireable to read binary data as\nbase64 into memory aligned to more than 8 bits. This is not currently\npossible, but it is recognized that a `(force_align: n)` attribute on\n`[ubyte]` vectors could be useful, but it can also be handled via nested\nflatbuffers which also align data.\n\n### Parsing Fixed Length Arrays\n\nFixed length arrays introduced in 0.6.0 allow for structs containing arrays\nof fixed length scalars, structs and chars. Arrays are parsed like vectors\nfor of similar type but are zero padded if shorter than expected and fails\nif longer than expected. The flag `reject_array_underflow` will error if an\narray is shorter than expected instead of zero padding. The flag\n`skip_array_overflow` will allow overlong arrays and simply drop extra elements.\n\nChar arrays are parsed like strings and zero padded if short than expected, but\nthey are not zero terminated. A string like \"hello\" will exactly fit into a\nfield of type `[char:5]`. Trailing zero characters are not printed, but embedded\nzero characters are. This allows for loss-less roundtrips without having to zero\npad strings. Note that other arrays are always printed in full. If the flag\n`skip_array_overflow` is set, a string might be truncated in the middle of a\nmulti-byte character. This is not checked nor enforced by the verifier.\n\n### Runtime Flags\n\nBoth the printer and the parser have the ability to accept runtime flags that\nmodifies their behavior. Please refer to header file comments for documentation\nand test cases for examples. Notably it is possible to print unquoted symbols\nand to ignore unknown fields when parsing instead of generating an error.\n\nNote that deprecated fields are considered unknown fields during parsing so in\norder to process JSON from an old schema version with deprecated fields present,\nunknown symbols must be skipped.\n\n### Generic Parsing and Printing.\n\nAs of v0.5.1 [test_json.c] demonstrates how a single parser driver can be used\nto parse different table types without changes to the driver or to the schema.\n\nFor example, the following layout can be used to configure a generic parser or printer.\n\n\tstruct json_scope {\n\t\tconst char *identifier;\n\t\tflatcc_json_parser_table_f *parser;\n\t\tflatcc_json_printer_table_f *printer;\n\t\tflatcc_table_verifier_f *verifier;\n\t};\n\n\tstatic const struct json_scope Monster = {\n\t\t/* The is the schema global file identifier. */\n\t\tns(Monster_identifier),\n\t\tns(Monster_parse_json_table),\n\t\tns(Monster_print_json_table),\n\t\tns(Monster_verify_table)\n\t};\n\nThe `Monster` scope can now be used by a driver or replaced with a new scope as needed:\n\n\t/* Abbreviated ... */\n\tstruct json_scope = Monster;\n    flatcc_json_parser_table_as_root(B, \u0026parser_ctx, json, strlen(json), parse_flags,\n            scope-\u003eidentifier, scope-\u003eparser);\n\t/* Printing and verifying works roughly the same. */\n\nThe generated table `MyGame_Example_Monster_parse_json_as_root` is a thin\nconvenience wrapper roughly implementing the above.\n\nThe generated `monster_test_parse_json` is a higher level convenience wrapper named\nof the schema file itself, not any specific table. It parses the `root_type` configured\nin the schema. This is how the `test_json.c` test driver operated prior to v0.5.1 but\nit made it hard to test parsing and printing distinct table types.\n\nNote that verification is not really needed for JSON parsing because a\ngenerated JSON parser is supposed to build buffers that always verify (except\nfor binary encoded nested buffers), but it is useful for testing.\n\n\n### Performance Notes\n\nNote that json parsing and printing is very fast reaching 500MB/s for\nprinting and about 300 MB/s for parsing. Floating point parsing can\nsignificantly skew these numbers. The integer and floating point parsing\nand printing are handled via support functions in the portable library.\nIn addition the floating point `include/flatcc/portable/grisu3_*` library\nis used unless explicitly disable by a compile time flag. Disabling\n`grisu3` will revert to `sprintf` and `strtod`. Grisu3 will fall back to\n`strtod` and `grisu3` in some rare special cases. Due to the reliance on\n`strtod` and because `strtod` cannot efficiently handle\nnon-zero-terminated buffers, it is recommended to zero terminate\nbuffers. Alternatively, grisu3 can be compiled with a flag that allows\nerrors in conversion. These errors are very small and still correct, but\nmay break some checksums. Allowing for these errors can significantly\nimprove parsing speed and moves the benchmark from below half a million\nparses to above half a million parses per second on 700 byte json\nstring, on a 2.2 GHz core-i7.\n\nWhile unquoted strings may sound more efficient due to the compact size,\nit is actually slower to process. Furthermore, large flatbuffer\ngenerated JSON files may compress by a factor 8 using gzip or a factor\n4 using LZ4 so this is probably the better place to optimize. For small\nbuffers it may be more efficient to compress flatbuffer binaries, but\nfor large files, json may actually compress significantly better due to\nthe absence of pointers in the format.\n\nSSE 4.2 has been experimentally added, but it the gains are limited\nbecause it works best when parsing space, and the space parsing is\nalready fast without SSE 4.2 and because one might just leave out the\nspaces if in a hurry. For parsing strings, trivial use of SSE 4.2 string\nscanning doesn't work well becasuse all the escape codes below ASCII 32\nmust be detected rather than just searching for `\\` and `\"`. That is not\nto say there are not gains, they just don't seem worthwhile.\n\nThe parser is heavily optimized for 64-bit because it implements an\n8-byte wide trie directly in code. It might work well for 32-bit\ncompilers too, but this hasn't been tested. The large trie does put some\nstrain on compile time. Optimizing beyond -O2 leads to too large\nbinaries which offsets any speed gains.\n\n\n## Global Scope and Included Schema\n\nAttributes included in the schema are viewed in a global namespace and\neach include file adds to this namespace so a schema file can use\nincluded attributes without namespace prefixes.\n\nEach included schema will also add types to a global scope until it sees\na `namespace` declaration. An included schema does not inherit the\nnamespace of an including file or an earlier included file, so all\nschema files starts in the global scope. An included file can, however,\nsee other types previously defined in the global scope. Because include\nstatements always appear first in a schema, this can only be earlier\nincluded files, not types from a containing schema.\n\nThe generated output for any included schema is indendent of how it was\nincluded, but it might not compile without the earlier included files\nbeing present and included first. By including the toplevel `myschema.h`\nor `myschema_builder.h` all these dependencies are handled correctly.\n\nNote: `libflatcc.a` can only parse a single schema when the schema is\ngiven as a memory buffer, but can handle the above when given a\nfilename. It is possible to concatenate schema files, but a `namespace;`\ndeclaration must be inserted as a separator to revert to global\nnamespace at the start of each included file. This can lead to subtle\nerrors because if one parent schema includes two child schema `a.fbs`\nand `b.fbs`, then `b.fbs` should not be able to see anything in `a.fbs`\neven if they share namespaces. This would rarely be a problem in praxis,\nbut it means that schema compilation from memory buffers cannot\nauthoratively validate a schema. The reason the schema must be isolated\nis that otherwise code generation for a given schema could change with\nhow it is being used leading to very strange errors in user code.\n\n\n## Required Fields and Duplicate Fields\n\nIf a field is required such as Monster.name, the table end call will\nassert in debug mode and create incorrect tables in non-debug builds.\nThe assertion may not be easy to decipher as it happens in library code\nand it will not tell which field is missing.\n\nWhen reading the name, debug mode will again assert and non-debug builds\nwill return a default value.\n\nWriting the same field twice will also trigger an assertion in debug\nbuilds.\n\n\n## Fast Buffers\n\nBuffers can be used for high speed communication by using the ability to\ncreate buffers with structs as root. In addition the default emitter\nsupports `flatcc_emitter_direct_buffer` for small buffers so no extra copy\nstep is required to get a linear buffer in memory. Preliminary\nmeasurements suggests there is a limit to how fast this can go (about\n6-7 mill. buffers/sec) because the builder object must be reset between\nbuffers which involves zeroing allocated buffers. Small tables with a\nsimple vector achieve roughly half that speed. For really high speed a\ndedicated builder for structs would be needed. See also\n[monster_test.c].\n\n\n## Types\n\nAll types stored in a buffer has a type suffix such as `Monster_table_t`\nor `Vec3_struct_t` (and namespace prefix which we leave out here). These\ntypes are read-only pointers into endian encoded data. Enum types are\njust constants easily grasped from the generated code. Tables are dense so\nthey are never accessed directly.\n\nEnums support schema evolution meaning that more names can be added to\nthe enumeration in a future schema version. As of v0.5.0 the function\n`_is_known_value` can be used ot check if an enum value is known to the\ncurrent schema version.\n\nStructs have a dual purpose because they are also valid types in native\nformat, yet the native reprsention has a slightly different purpose.\nThus the convention is that a const pointer to a struct encoded in a\nflatbuffer has the type `Vec3_struct_t` where as a writeable pointer to\na native struct has the type `Vec3_t *` or `struct Vec3 *`.\n\nAll types have a `_vec_t` suffix which is a const pointer to the\nunderlying type. For example `Monster_table_t` has the vector type\n`Monster_vec_t`. There is also a non-const variant with suffix\n`_mutable_vec_t` which is rarely used. However, it is possible to sort\nvectors in-place in a buffer, and for this to work, the vector must be\ncast to mutable first. A vector (or string) type points to the element\nwith index 0 in the buffer, just after the length field, and it may be\ncast to a native type for direct access with attention to endian\nencoding. (Note that `table_t` types do point to the header field unlike\nvectors.) These types are all for the reader interface. Corresponding\ntypes with a `_ref_t` suffix such as `_vec_ref_t` are used during\nthe construction of buffers.\n\nNative scalar types are mapped from the FlatBuffers schema type names\nsuch as ubyte to `uint8_t` and so forth. These types also have vector\ntypes provided in the common namespace (default `flatbuffers_`) so\na `[ubyte]` vector has type `flatbuffers_uint8_vec_t` which is defined\nas `const uint8_t *`.\n\nThe FlatBuffers boolean type is strictly 8 bits wide so we cannot use or\nemulate `\u003cstdbool.h\u003e` where `sizeof(bool)` is implementation dependent.\nTherefore `flatbuffers_bool_t` is defined as `uint8_t` and used to\nrepresent FlatBuffers boolean values and the constants of same type:\n`flatbuffers_true = 1` and `flatbuffers_false = 0`. Even so,\n`pstdbool.h` is available in the `include/flatcc/portable` directory if\n`bool`, `true`, and `false` are desired in user code and `\u003cstdbool.h\u003e`\nis unavailable.\n\n`flatbuffers_string_t` is `const char *` but imply the returned pointer\nhas a length prefix just before the pointer. `flatbuffers_string_vec_t`\nis a vector of strings. The `flatbufers_string_t` type guarantees that a\nlength field is present using `flatbuffers_string_len(s)` and that the\nstring is zero terminated. It also suggests that it is in utf-8 format\naccording to the FlatBuffers specification, but not checks are done and\nthe `flatbuffers_create_string(B, s, n)` call explicitly allows for\nstoring embedded null characters and other binary data.\n\nAll vector types have operations defined as the typename with `_vec_t`\nreplaced by `_vec_at` and `_vec_len`. For example\n`flatbuffers_uint8_vec_at(inv, 1)` or `Monster_vec_len(inv)`. The length\nor `_vec_len` will be 0 if the vector is missing whereas `_vec_at` will\nassert in debug or behave undefined in release builds following out of\nbounds access. This also applies to related string operations.\n\nThe FlatBuffers schema uses the following scalar types: `ubyte`, `byte`,\n`ushort`, `short, uint`, `int`, `ulong`, and `long` to represent\nunsigned and signed integer types of length 8, 16, 32, and 64\nrespectively. The schema syntax has been updated to also support the\ntype aliases `uint8`, `int8`, `uint16`, `int16`, `uint32`, `int32`,\n`uint64`, `int64` to represent the same basic types. Likewise, the\nschema uses the types `float` and `double` to represent IEEE-754\nbinary32 and binary64 floating point formats where the updated syntax\nalso supports the type aliases `float32` and `float64`.\n\nThe C interface uses the standard C types such as uint8 and double to\nrepresent scalar types and this is unaffected by the schema type name\nused, so the schema vector type `[float64]` is represented as\n`flatbuffers_double_vec_t` the same as `[double]` would be.\n\nNote that the C standard does not guarantee that the C types `float` and\n`double` are represented by the IEEE-754 binary32 single precision\nformat and the binary64 double precision format respectively, although\nthey usually are. If this is not the case FlatCC cannot work correctly\nwith FlatBuffers floating point values. (If someone really has this\nproblem, it would be possible to fix).\n\nUnions are represented with a two table fields, one with a table field\nand one with a type field. See separate section on Unions. As of flatcc\nv0.5.0 union vectors are also supported.\n\n## Unions\n\nA union represents one of several possible tables. A table with a union\nfield such as `Monster.equipped` in the samples schema will have two\naccessors: `MyGame_Sample_Monster_equipped(t)` of type\n`flatbuffers_generic_t` and `MyGame_Sample_Monster_equipped_type(t)` of\ntype `MyGame_Sample_Equipment_union_type_t`. A generic type is is just a\nconst void pointer that can be assigned to the expected table type,\nstruct type, or string type. The enumeration has a type code for member\nof the union and also `MyGame_Sample_Equipment_NONE` which has the value\n0.\n\nThe union interface were changed in 0.5.0 and 0.5.1 to use a consistent\n{ type, value } naming convention for both unions and union vectors\nin all interfaces and to support unions and union vectors of multiple\ntypes.\n\nA union can be accessed by its field name, like Monster\n`MyGame_Sample_Monster_equipped(t)` and its type is given by\n`MyGame_Sample_Monster_type(t)`, or a `flatbuffers_union_t` struct\ncan be returned with `MyGame_Sample_monster_union(t)` with the fields\n{ type, value }. A union vector is accessed in the same way but {\ntype, value } represents a type vector and a vector of the given type,\ne.g. a vector Monster tables or a vector of strings.\n\nThere is a test in [monster_test.c] covering union vectors and a\nseparate test focusing on mixed type unions that also has union vectors.\n\n\n### Union Scope Resolution\n\nGoogles `monster_test.fbs` schema has the union (details left out):\n\n\tnamespace MyGame.Example2;\n\ttable Monster{}\n\n\tnamespace MyGame.Example;\n\ttable Monster{}\n\n\tunion Any { Monster, MyGame.Example2.Monster }\n\nwhere the two Monster tables are defined in separate namespaces.\n\n`flatcc` rejects this schema due to a name conflict because it uses the\nbasename of a union type, here `Monster` to generate the union member names\nwhich are also used in JSON parsing.  This can be resolved by adding an\nexplicit name such as `Monster2` to resolve the conflict:\n\n\tunion Any { Monster, Monster2: MyGame.Example2.Monster }\n\nThis syntax is accepted by both `flatc` and `flatcc`.\n\nBoth versions will implement the same union with the same type codes in the\nbinary format but generated code will differ in how the types are referred to.\n\nIn JSON the monster type values are now identified by\n`MyGame.Example.Any.Monster`, or just `Monster`, when assigning the first\nmonster type to an Any union field, and `MyGame.Example.Any.Monster2`, or just\n`Monster2` when assigning the second monster type. C uses the usual enum\nnamespace prefixed symbols like `MyGame_Example_Any_Monster2`.\n\n## Fixed Length Arrays\n\nFixed Length Arrays is a late feature to the FlatBuffers format introduced in\nflatc and flatcc mid 2019. Currently only scalars arrays are supported, and only\nas struct fields. To use fixed length arrays as a table field wrap it in a\nstruct first. It would make sense to support struct elements and enum elements,\nbut that has not been implemented. Char arrays are more controversial due to\nverification and zero termination and are also not supported. Arrays are aligned\nto the size of the first field and are equivalent to repeating elements within\nthe struct.\n\nThe schema syntax is:\n\n```\nstruct MyStruct {\n    my_array : [float:10];\n}\n```\n\nSee `test_fixed_array` in [monster_test.c] for an example of how to work with\nthese arrays.\n\nFlatcc opts to allow arbitrary length fixed length arrays but limit the entire\nstruct to 2^16-1 bytes. Tables cannot hold larger structs, and the C language\ndoes not guarantee support for larger structs. Other implementations might have\ndifferent limits on maximum array size. Arrays of 0 length are not permitted.\n\n\n## Optional Fields\n\nOptional scalar table fields were introduced to FlatBuffers mid 2020 in order to\nbetter handle null values also for scalar data types, as is common in SQL\ndatabases. Before describing optional values, first understand how ordinary\nscalar values work in FlatBuffers:\n\nImagine a FlatBuffer table with a `mana` field from the monster sample schema.\nOrdinarily a scalar table field has implicit default value of 0 like `mana :\nuint8;`, or an explicit default value specified in the schema like `mana : uint8\n= 100;`. When a value is absent from a table field, the default value is\nreturned, and when a value is added during buffer construction, it will not\nactually be stored if the value matches the default value, unless the\n`force_add` option is used to write a value even if it matches the default\nvalue. Likewise the `is_present` method can be used to test if a field was\nactually stored in the buffer when reading it.\n\nWhen a table has many fields, most of which just hold default settings,\nsignificant space can be saved using default values, but it also means that an\nabsent value does not indicate null. Field absence is essentially just a data\ncompression technique, not a semantic change to the data. However, it is\npossible to use `force_add` and `is_present` to interpret values as null when\nnot present, except that this is not a standardized technique. Optional fields\nrepresents a standardized way to achieve this.\n\nScalar fields can be marked as optional by assigning `null` as a default\nvalue. For example, some objects might not have a meaningful `mana`\nvalue, so it could be represented as `lifeforce : uint8 = null`. Now the\n`lifeforce` field has become an optional field. In the FlatCC implementation\nthis means that the field is written, it will always be written also if the\nvalue is 0 or any other representable value. It also means that the `force_add`\nmethod is not available for the field because `force_add` is essentially always\nin effect for the field. On the read side, optional scalar fields behave exactly is ordinary scalar fields that have not specified a default value, that is, if the field is absent, 0 will be returned and `is_present` will return false. Instead optional scalar fields get a new accessor method with the suffix `_option()` which returns a struct with two fiels: `{ is_null, value }` where `_option().is_null == !is_present()` and `_option().value` is the same value is the `_get()` method, which will be 0 if `is_null` is true. The option struct is named after the type similar to unions, for example `flatbuffers_uint8_option_t` or `MyGame_Example_Color_option_t`, and the option accessor method also works similar to unions. Note that `_get()` will also return 0 for optional enum values that are null (i.e. absent), even if the enum value does not have an enumerated element with the value 0. Normally enums without a 0 element is not allowed in the schema unless a default value is specified, but in this case it is null, and `_get()` needs some value to return in this case.\n\nBy keeping the original accessors, read logic can be made simpler and faster when it is not important whether a value is null or 0 and at the same time the option value can be returned and stored.\n\nNote that struct fields cannot be optional. Also note that, non-scalar table fields are not declared optional because these types can already represent null via a null pointer or a NONE union type.\n\nJSON parsing and printing change behavior for scalar fields by treating absent\nfields differently according the optional semantics. For example parsing a\nmissing field will not store a default value even if the parser is executed with\na flag to force default values to be stored and the printer will not print\nabsent optional fields even if otherwise flagged to print default values.\nCurrenlty the JSON printers and parsers do not print or parse JSON null and can\nonly represent null be absence of a field.\n\nFor an example of reading and writing, as well as printing and parsing JSON,\noptional scalar fields, please refer to [optional_scalars_test.fbs] and [optional_scalars_test.c].\n\n\n## Endianness\n\nThe [pendian_detect.h]` file detects endianness\nfor popular compilers and provides a runtime fallback detection for\nothers. In most cases even the runtime detection will be optimized out\nat compile time in release builds.\n\nThe `FLATBUFFERS_LITTLEENDIAN` flag is respected for compatibility with\nGoogles `flatc` compiler, but it is recommended to avoid its use and\nwork with the mostly standard flags defined and/or used in\n`pendian_detect.h`, or to provide for additional compiler support.\n\nAs of flatcc 0.4.0 there is support for flatbuffers running natively on\nbig endian hosts. This has been tested on IBM AIX. However, always run\ntests against the system of interest - the release process does not cover\nautomated tests on any BE platform.\n\nAs of flatcc 0.4.0 there is also support for compiling the flatbuffers\nruntime library with flatbuffers encoded in big endian format regardless\nof the host platforms endianness. Longer term this should probably be\nplaced in a separate library with separate name prefixes or suffixes,\nbut it is usable as is. Redefine `FLATBUFFERS_PROTOCOL_IS_LE/BE`\naccordingly in [flatcc_types.h]. This is already done in\nthe `be` branch. This branch is not maintained but the master branch can\nbe merged into it as needed.\n\nNote that standard flatbuffers are always encoded in little endian but\nin situations where all buffer producers and consumers are big endian,\nthe non standard big endian encoding may be faster, depending on\nintrinsic byteswap support. As a curiosity, the `load_test` actually\nruns faster with big endian buffers on a little endian MacOS platform\nfor reasons only the optimizer will know, but read performance of small\nbuffers drop to 40% while writing buffers generally drops to 80-90%\nperformance. For platforms without compiler intrinsics for byteswapping,\nthis can be much worse.\n\nFlatbuffers encoded in big endian will have the optional file identifier\nbyteswapped. The interface should make this transparent, but details\nare still being worked out. For example, a buffer should always verify\nthe monster buffer has the identifier \"MONS\", but internally the buffer\nwill store the identifier as \"SNOM\" on big endian encoded buffers.\n\nBecause buffers can be encode in two ways, `flatcc` uses the term\n`native` endianness and `protocol` endianess. `_pe` is a suffix used in\nvarious low level API calls to convert between native and protocol\nendianness without caring about whether host or buffer is little or big\nendian.\n\nIf it is necessary to write application code that behaves differently if\nthe native encoding differs from protocol encoding, use\n`flatbuffers_is_pe_native()`. This is a function, not a define, but for\nall practical purposes it will have same efficience while also\nsupporting runtime endian detection where necessary.\n\nThe flatbuffer environment only supports reading either big or little\nendian for the time being. To test which is supported, use the define\n`FLATBUFFERS_PROTOCOL_IS_LE` or `FLATBUFFERS_PROTOCOL_IS_BE`. They are\ndefines as 1 and 0 respectively.\n\n\n## Pitfalls in Error Handling\n\nThe builder API often returns a reference or a pointer where null is\nconsidered an error or at least a missing object default. However, some\noperations do not have a meaningful object or value to return. These\nfollow the convention of 0 for success and non-zero for failure.\nAlso, if anything fails, it is not safe to proceed with building a\nbuffer.  However, to avoid overheads, there is no hand holding here. On\nthe upside, failures only happen with incorrect use or allocation\nfailure and since the allocator can be customized, it is possible to\nprovide a central error state there or to guarantee no failure will\nhappen depending on use case, assuming the API is otherwise used\ncorrectly.  By not checking error codes, this logic also optimizes out\nfor better performance.\n\n\n## Searching and Sorting\n\nThe builder API does not support sorting due to the complexity of\ncustomizable emitters, but the reader API does support sorting so a\nbuffer can be sorted at a later stage. This requires casting a vector to\nmutable and calling the sort method available for fields with keys.\n\nThe sort uses heap sort and can sort a vector in-place without using\nexternal memory or recursion. Due to the lack of external memory, the\nsort is not stable. The corresponding find operation returns the lowest\nindex of any matching key, or `flatbuffers_not_found`.\n\nWhen configured in `config.h` (the default), the `flatcc` compiler\nallows multiple keyed fields unlike Googles `flatc` compiler. This works\ntransparently by providing `\u003ctable_name\u003e_vec_sort_by_\u003cfield_name\u003e` and\n`\u003ctable_name\u003e_vec_find_by_\u003cfield_name\u003e` methods for all keyed fields.\nThe first field maps to `\u003ctable_name\u003e_vec_sort` and\n`\u003ctable_name\u003e_vec_find`. Obviously the chosen find method must match\nthe chosen sort method. The find operation is O(logN).\n\nAs of v0.6.0 the default key used for find and and sort without the `by_name`\nsuffix is the field with the smaller id instead of the first listed in the\nschema which is often but not always the same thing.\n\nv0.6.0 also introduces the `primary_key` attribute that can be used instead of\nthe `key` attribute on at most one field. The two attributes are mutually\nexclusive. This can be used if a key field with a higher id should be the\ndefault key. There is no difference when only one field has a `key` or\n`primary_key` attribute, so in that case choose `key` for compatiblity.\nGoogles flatc compiler does not recognize the `primary_key` attribute.\n\nAs of v0.6.0 a 'sorted' attribute has been introduced together with the sort\noperations `\u003ctable_name\u003e_sort` and `\u003cunion_name\u003e_sort`. If a table or a union,\ndirectly or indirectly, contains a vector with the 'sorted' attribute, then the\nsort operation is made available. The sort will recursively visit all children\nwith vectors marked sorted. The sort operatoin will use the default (primary)\nkey. A table or union must first be cast to mutable, for example\n`ns(Monster_sort((ns(Monster_mutable_table_t))monster)`. The actual vector\nsort operations are the same as before, they are just called automatically.\nThe `sorted` attribute can only be set on vectors that are not unions. The\nvector can be of scalar, string, struct, or table type. `sorted` is only valid\nfor a struct or table vector if the struct or table has a field with a `key`\nor `primary_key` attribute. NOTE: A FlatBuffer can reference the same object\nmultiple times. The sort operation will be repeated if this is the case.\nSometimes that is OK, but if it is a concern, remove the `sorted` attribute\nand sort the vector manually. Note that sharing can also happen via a shared\ncontaining object. The sort operations are generated in `_reader.h` files\nand only for objects directly or indirectly affected by the `sorted` attribute.\nUnions have a new mutable case operator for use with sorting unions:\n`ns(Any_sort(ns(Any_mutable_cast)(my_any_union))`. Usually unions will be\nsorted via a containing table which performs this cast automatically. See also\n`test_recursive_sort` in [monster_test.c].\n\nAs of v0.4.1 `\u003ctable_name\u003e_vec_scan_by_\u003cfield_name\u003e` and the default\n`\u003ctable_name\u003e_vec_scan` are also provided, similar to `find`, but as a\nlinear search that does not require the vector to be sorted. This is\nespecially useful for searching by a secondary key (multiple keys is a\nnon-standard flatcc feature). `_scan_ex` searches a sub-range [a, b)\nwhere b is an exclusive index. `b = flatbuffers_end == flatbuffers_not_found\n== (size_t)-1` may be used when searching from a position to the end,\nand `b` can also conveniently be the result of a previous search.\n\n`rscan` searches in the opposite direction starting from the last\nelement. `rscan_ex` accepts the same range arguments as `scan_ex`. If\n`a \u003e= b or a \u003e= len` the range is considered empty and\n`flatbuffers_not_found` is returned. `[r]scan[_ex]_n[_by_name]` is for\nlength terminated string keys. See [monster_test.c] for examples.\n\nNote that `find` requires `key` attribute in the schema. `scan` is also\navailable on keyed fields. By default `flatcc` will also enable scan by\nany other field but this can be disabled by a compile time flag.\n\nBasic types such as `uint8_vec` also have search operations.\n\nSee also [Builder Interface Reference] and [monster_test.c].\n\n\n## Null Values\n\nThe FlatBuffers format does not fully distinguish between default values\nand missing or null values but it is possible to force values to be\nwritten to the buffer. This is discussed further in the\n[Builder Interface Reference]. For SQL data roundtrips this may be more\nimportant that having compact data.\n\nThe `_is_present` suffix on table access methods can be used to detect if\nvalue is present in a vtable, for example `Monster_hp_present`. Unions\nreturn true of the type field is present, even if it holds the value\nNone.\n\nThe `add` methods have corresponding `force_add` methods for scalar and enum\nvalues to force storing the value even if it is default and thus making\nit detectable by `is_present`.\n\n\n## Portability Layer\n\nThe portable library is placed under `include/flatcc/portable` and is\nrequired by flatcc, but isn't strictly part of the `flatcc` project. It\nis intended as an independent light-weight header-only library to deal\nwith compiler and platform variations. It is placed under the flatcc\ninclude path to simplify flatcc runtime distribution and to avoid\nname and versioning conflicts if used by other projects.\n\nThe license of portable is different from `flatcc`. It is mostly MIT or\nApache depending on the original source of the various parts.\n\nA larger set of portable files is included if `FLATCC_PORTABLE` is\ndefined by the user when building.\n\n    cc -D FLATCC_PORTABLE -I include monster_test.c -o monster_test\n\nOtherwise a targeted subset is\nincluded by `flatcc_flatbuffers.h` in order to deal with non-standard\nbehavior of some C11 compilers.\n\n`pwarnings.h` is also always included so compiler specific warnings can\nbe disabled where necessary.\n\nThe portable library includes the essential parts of the grisu3 library\nfound in `external/grisu3`, but excludes the test cases. The JSON\nprinter and parser relies on fast portable numeric print and parse\noperations based mostly on grisu3.\n\nIf a specific platform has been tested, it would be good with feedback\nand possibly patches to the portability layer so these can be made\navailable to other users.\n\n## Building\n\nNote: if a test fails, see [Strict Aliasing](#strict-aliasing)\nfor a possible resolution.\n\n### Unix Build (OS-X, Linux, related)\n\nTo initialize and run the build (see required build tools below):\n\n    scripts/build.sh\n\nThe `bin` and `lib` folders will be created with debug and release\nbuild products.\n\nThe build depends on `CMake`. By default the `Ninja` build tool is also required,\nbut alternatively `make` can be used.\n\nOptionally switch to a different build tool by choosing one of:\n\n    scripts/initbuild.sh make\n    scripts/initbuild.sh make-concurrent\n    scripts/initbuild.sh ninja\n\nwhere `ninja` is the default and `make-concurrent` is `make` with the `-j` flag.\n\nTo enforce a 32-bit build on a 64-bit machine the following configuration\ncan be used:\n\n    scripts/initbuild.sh make-32bit\n\nwhich uses `make` and provides the `-m32` flag to the compiler.\nA custom build configuration `X` can be added by adding a\n`scripts/build.cfg.X` file.\n\n`scripts/initbuild.sh` cleans the build if a specific build\nconfiguration is given as argument. Without arguments it only ensures\nthat CMake is initialized and is therefore fast to run on subsequent\ncalls. This is used by all test scripts.\n\nTo install build tools on OS-X, and build:\n\n    brew update\n    brew install cmake ninja\n    git clone https://github.com/dvidelabs/flatcc.git\n    cd flatcc\n    scripts/build.sh\n\nTo install build tools on Ubuntu, and build:\n\n    sudo apt-get update\n    sudo apt-get install cmake ninja-build\n    git clone https://github.com/dvidelabs/flatcc.git\n    cd flatcc\n    scripts/build.sh\n\nTo install build tools on Centos, and build:\n\n    sudo yum group install \"Development Tools\"\n    sudo yum install cmake\n    git clone https://github.com/dvidelabs/flatcc.git\n    cd flatcc\n    scripts/initbuild.sh make # there is no ninja build tool\n    scripts/build.sh\n\n\nOS-X also has a HomeBrew package:\n\n    brew update\n    brew install flatcc\n\nor for the bleeding edge:\n\n    brew update\n    brew install flatcc --HEAD\n\n\n### Windows Build (MSVC)\n\nInstall CMake, MSVC, and git (tested with MSVC 14 2015).\n\nIn PowerShell:\n\n    git clone https://github.com/dvidelabs/flatcc.git\n    cd flatcc\n    mkdir build\\MSVC\n    cd build\\MSVC\n    cmake -G \"Visual Studio 14 2015\" ..\\..\n\nOptionally also build from the command line (in build\\MSVC):\n\n    cmake --build . --target --config Debug\n    cmake --build . --target --config Release\n\nIn Visual Studio:\n\n    open flatcc\\build\\MSVC\\FlatCC.sln\n    build solution\n    choose Release build configuration menu\n    rebuild solution\n\n*Note that `flatcc\\CMakeList.txt` sets the `-DFLATCC_PORTABLE` flag and\nthat `include\\flatcc\\portable\\pwarnings.h` disable certain warnings for\nwarning level -W3.*\n\n### Docker\n\nDocker image:\n\n- \u003chttps://github.com/neomantra/docker-flatbuffers\u003e\n\n\n### Cross-compilation\n\nUsers have been reporting some degree of success using cross compiles\nfrom Linux x86 host to embedded ARM Linux devices.\n\nFor this to work, `FLATCC_TEST` option should be disabled in part\nbecause cross-compilation cannot run the cross-compiled flatcc tool, and\nin part because there appears to be some issues with CMake custom build\nsteps needed when building test and sample projects.\n\n2024-03-08: WARNING:\n-O2 -mcpu=cortex-m7 targets using the arm-none-eabi 13.2.Rel1 toolchain\ncan result in uninitialized stack access when not compiled with\n`-fno-strict-aliasing`\n-mcpu=cortex-m0 and -mcpu=cortex-m1 appears to be unaffected.\nSee also [issue #274](https://github.com/dvidelabs/flatcc/issues/274).\n2024-10-03: Fix available on flatcc master branch when you read this.\nSee also CHANGELOG comments for release 0.6.2.\n\n\nThe option `FLATCC_RTONLY` will disable tests and only build the runtime\nlibrary.\n\nThe following is not well tested, but may be a starting point:\n\n    mkdir -p build/xbuild\n    cd build/xbuild\n    cmake ../.. -DBUILD_SHARED_LIBS=on -DFLATCC_RTONLY=on \\\n      -DCMAKE_BUILD_TYPE=Release\n\nOverall, it may be simpler to create a separate Makefile and just\ncompile the few `src/runtime/*.c` into a library and distribute the\nheaders as for other platforms, unless `flatcc` is also required for the\ntarget. Or to simply include the runtime source and header files in the user\nproject.\n\nNote that no tests will be built nor run with `FLATCC_RTONLY` enabled.\nIt is highly recommended to at least run the `tests/monster_test`\nproject on a new platform.\n\n\n### Custom Allocation\n\nSome target systems will not work with Posix `malloc`, `realloc`, `free`\nand C11 `aligned_alloc`. Or they might, but more allocation control is\ndesired. The best approach is to use `flatcc_builder_custom_init` to\nprovide a custom allocator and emitter object, but for simpler case or\nwhile piloting a new platform\n[flatcc_alloc.h](include/flatcc/flatcc_alloc.h) can be used to override\nruntime allocation functions. _Carefully_ read the comments in this file\nif doing so. There is a test case implementing a new emitter, and a\ncustom allocator can be copied from the one embedded in the builder\nlibrary source.\n\n\n### Custom Asserts\n\nOn systems where the default POSIX `assert` call is unavailable, or when\na different assert behaviour is desirable, it is possible to override\nthe default behaviour in runtime part of flatcc library via logic defined\nin [flatcc_assert.h](include/flatcc/flatcc_assert.h).\n\nBy default Posix `assert` is beeing used. It can be changed by preprocessor definition:\n\n    -DFLATCC_ASSERT=own_assert\n\nbut it will not override assertions used in the portable library, notably the\nGrisu3 fast numerical conversion library used with JSON parsing.\n\nRuntime assertions can be disabled using:\n\n    -DFLATCC_NO_ASSERT\n\nThis will also disable Grisu3 assertions. See\n[flatcc_assert.h](include/flatcc/flatcc_assert.h) for details.\n\nThe `\u003cassert.h\u003e` file will in all cases remain a dependency for C11 style static\nassertions. Static assertions are needed to ensure the generated structs have\nthe correct physical layout on all compilers. The portable library has a generic\nstatic assert implementation for older compilers.\n\n\n### Shared Libraries\n\nBy default libraries are built statically.\n\nOccasionally there are requests\n[#42](https://github.com/dvidelabs/flatcc/pull/42) for also building shared\nlibraries. It is not clear how to build both static and shared libraries\nat the same time without choosing some unconvential naming scheme that\nmight affect install targets unexpectedly.\n\nCMake supports building shared libraries out of the box using the\nstandard library name using the following option:\n\n    CMAKE ... -DBUILD_SHARED_LIBS=ON ...\n\nSee also [CMake Gold: Static + shared](http://cgold.readthedocs.io/en/latest/tutorials/libraries/static-shared.html).\n\n\n## Strict Aliasing\n\nThe Flatcc build files should take care of strict aliasing issues on\ncommon platforms, but it is not a solved problem, so here is some background\ninformation.\n\nIn most cases this is a non-issue with the current flatcc code\nbase, but that does not help in the cases where it is an issue.\n\nCompilers have become increasingly aggressive with applying, and defaulting\nto, strict aliasing rules.\n\nFlatCC does not guarantee that strict aliasing rules are followed, but\nthe code base is updated as issues are detected. If a test fails or segfaults\nthe first thing to check is `-fno-strict-aliasing`, or the platform equivalent,\nor to disable pointer casts, as discussed below.\n\nStrict aliasing means that a cast like `p2 = *(T *)p1` is not valid because the\ncompiler thinks that p2 does not depend on data pointed to by p1. In most cases\ncompilers are sensible enough to handle this, but not always. It can, and\nwill, lead to reading from uninitialized memory or segfaults. There are two ways\naround this, one is to use unions to convert from integer to float, which is\nvalid in C, but not in C++, and the other is to use `memcpy` for small constant\nsizes, which is guaranteed safe, but can be slow if not optimized, and it is\nnot always optimized. (Not strictly `memcpy` but access via cast to `char *` or\nother \"narrow\" type).\n\nFlatCC manages this in [flatcc_accessors.h] which forwards to platform dependent\ncode in [pmemaccess.h]. Note that is applies to the runtime code base only. For\ncompile time the only issue should be hash tables and these should also be safe.\n\nFlatCC either uses optimized `memcpy` or non-compliant pointer casts depending on\nthe platform. Essentially, buffer memory is first copied, or pointer cast, into\nan unsigned integer of a given size. This integer is then endian converted into\nanother unsigned integer. Then that integer is converted into a final integer\ntype or floating point type using union casts. This generally optimizes out to\nvery few assembly instructions, but when it does not, code size and execution\ntime can grow significantly.\n\nIt has been observed that targets both default to strict aliasing with\n-O2 optimization, and at the same to uses a function call for\n`memcpy(dest, src, sizeof(uint32_t))`, but where `__builtin_memcpy`\ndoes optimize well, hence requiring detection of a fast `memcpy` operation.\n\nThis is a game between being reasonably performant and compliant.\n\n`-DPORTABLE_MEM_PTR_ACCESS=0` will force the runtime code to not use\npointer casts but it can potentially generate suboptimal code and\ncan be set 1 if the compiler and build configuration is known to not\nhave issues with strict aliasing. It is set to 1 for most x86/64 targets\nsince this has been working for a long time in FlatCC builds and tests,\nwhile memcpy might not work efficient.\n\n\n## Distribution\n\nInstall targes may be built with:\n\n    mkdir -p build/install\n    cd build/install\n    cmake ../.. -DBUILD_SHARED_LIBS=on -DFLATCC_RTONLY=on \\\n      -DCMAKE_BUILD_TYPE=Release -DFLATCC_INSTALL=on\n    make install\n\nHowever, this is not well tested and should be seen as a starting point.\nThe normal scripts/build.sh places files in bin and lib of the source tree.\n\nBy default lib files a built into the `lib` subdirectory of the project. This\ncan be changed, for example like `-DFLATCC_INSTALL_LIB=lib64`.\n\n\n### Unix Files\n\nTo distribute the compiled binaries the following files are\nrequired:\n\nCompiler:\n\n    bin/flatcc                 (command line interface to schema compiler)\n    lib/libflatcc.a            (optional, for linking with schema compiler)\n    include/flatcc/flatcc.h    (optional, header and doc for libflatcc.a)\n\nRuntime:\n\n    include/flatcc/**          (runtime header files)\n    include/flatcc/reflection  (optional)\n    include/flatcc/support     (optional, only used for test and samples)\n    lib/libflatccrt.a          (runtime library)\n\nIn addition the runtime library source files may be used instead of\n`libflatccrt.a`. This may be handy when packaging the runtime library\nalong with schema specific generated files for a foreign target that is\nnot binary compatible with the host system:\n\n    src/runtime/*.c\n\n### Windows Files\n\nThe build products from MSVC are placed in the bin and lib subdirectories:\n\n    flatcc\\bin\\Debug\\flatcc.exe\n    flatcc\\lib\\Debug\\flatcc_d.lib\n    flatcc\\lib\\Debug\\flatccrt_d.lib\n    flatcc\\bin\\Release\\flatcc.exe\n    flatcc\\lib\\Release\\flatcc.lib\n    flatcc\\lib\\Release\\flatccrt.lib\n\nRuntime `include\\flatcc` directory is distributed like other platforms.\n\n\n## Running Tests on Unix\n\nRun\n\n    scripts/test.sh [--no-clean]\n\n**NOTE:** The test script will clean everything in the build directy before\ninitializing CMake with the chosen or default build configuration, then\nbuild Debug and Release builds, and run tests for both.\n\nThe script must end with `TEST PASSED`, or it didn't pass.\n\nTo make sure everything works, also run the benchmarks:\n\n    scripts/benchmark.sh\n\n\n## Running Tests on Windows\n\nIn Visual Studio the test can be run as follows: first build the main\nproject, the right click the `RUN_TESTS` target and chose build. See\nthe output window for test results.\n\nIt is also possible to run tests from the command line after the project has\nbeen built:\n\n    cd build\\MSVC\n    ctest\n\nNote that the monster example is disabled for MSVC 2010.\n\nBe aware that tests copy and generate certain files which are not\nautomatically cleaned by Visual Studio. Close the solution and wipe the\n`MSVC` directory, and start over to get a guaranteed clean build.\n\nPlease also observe that the file `.gitattributes` is used to prevent\ncertain files from getting CRLF line endings. Using another source\ncontrol systems might break tests, notably\n`test/flatc_compat/monsterdata_test.golden`.\n\n\n*Note: Benchmarks have not been ported to Windows.*\n\n\n## Configuration\n\nThe configuration\n\n    config/config.h\n\ndrives the permitted syntax and semantics of the schema compiler and\ncode generator. These generally default to be compatible with\nGoogles `flatc` compiler. It also sets things like permitted nesting\ndepth of structs and tables.\n\nThe runtime library has a separate configuration file\n\n    include/flatcc/flatcc_rtconfig.h\n\nThis file can modify certain aspects of JSON parsing and printing such\nas disabling the Grisu3 library or requiring that all names in JSON are\nquoted.\n\nFor most users, it should not be relevant to modify these configuration\nsettings. If changes are required, they can be given in the build\nsystem - it is not necessary to edit the config files, for example\nto disable trailing comma in the JSON parser:\n\n    cc -DFLATCC_JSON_PARSE_ALLOW_TRAILING_COMMA=0 ...\n\n\n## Using the Compiler and Builder library\n\nThe compiler library `libflatcc.a` can compile schemas provided\nin a memory buffer or as a filename. When given as a buffer, the schema\ncannot contain include statements - these will cause a compile error.\n\nWhen given a filename the behavior is similar to the commandline\n`flatcc` interface, but with more options - see `flatcc.h` and\n`config/config.h`.\n\n`libflatcc.a` supports functions named `flatcc_...`. `reflection...` may\nalso be available which are simple the C generated interface for the\nbinary schema. The builder library is also included. These last two\ninterfaces are only present because the library supports binary schema\ngeneration.\n\nThe standalone runtime library `libflatccrt.a` is a collection of the\n`src/runtime/*.c` files. This supports the generated C headers for\nvarious features. It is also possible to distribute and compile with the\nsource files directly.  For debugging, it is useful to use the\n`libflatccrt_d.a` version because it catches a lot of incorrect API use\nin assertions.\n\nThe runtime library may also be used by other languages. See comments\nin [flatcc_builder.h]. JSON parsing is on example of an\nalternative use of the builder library so it may help to inspect the\ngenerated JSON parser source and runtime source.\n\n## FlatBuffers Binary Format\n\nMostly for implementers: [FlatBuffers Binary Format]\n\n\n## Security Considerations\n\nSee [Security Considerations].\n\n\n## Style Guide\n\nFlatCC coding style is largely similar to the [WebKit Style], with the following notable exceptions:\n\n* Syntax requiring C99 or later is avoided, except `\u003cstdint.h\u003e` types are made available.\n* If conditions always use curly brackets, or single line statements without linebreak: `if (err) return -1;`.\n* NULL and nullptr are generally just represented as `0`.\n* Comments are old-school C-style (pre C99). Text is generally cased with punctuation: `/* A comment. */`\n* `true` and `false` keywords are not used (pre C99).\n* In code generation there is essentially no formatting to avoid excessive bloat.\n* Struct names and other types is lower case since this is C, not C++.\n* `snake_case` is used over `camelCase`.\n* Header guards are used over `#pragma once` because it is non-standard and not always reliable in filesystems with ambigious paths.\n* Comma is not placed first in multi-line calls (but maybe that would be a good idea for diff stability).\n* `config.h` inclusion might be handled differently in that `flatbuffers.h` includes the config file.\n* `unsigned` is not used without `int` for historical reasons. Generally a type like `uint32_t` is preferred.\n* Use `TODO:` instead of `FIXME:` in comments for historical reasons.\n\nAll the main source code in compiler and runtime aim to be C11 compatible and\nuses many C11 constructs. This is made possible through the included portable\nlibrary such that older compilers can also function. Therefore any platform specific adaptations will be provided by updating\nthe portable library rather than introducing compile time flags in the main\nsource code.\n\n\n## Benchmarks\n\nSee [Benchmarks]\n\n[Builder Interface Reference]: https://github.com/dvidelabs/flatcc/blob/master/doc/builder.md\n[FlatBuffers Binary Format]: https://github.com/dvidelabs/flatcc/blob/master/doc/binary-format.md\n[Benchmarks]: https://github.com/dvidelabs/flatcc/blob/master/doc/benchmarks.md\n[monster_test.c]: https://github.com/dvidelabs/flatcc/blob/master/test/monster_test/monster_test.c\n[monster_test.fbs]: https://github.com/dvidelabs/flatcc/blob/master/test/monster_test/monster_test.fbs\n[optional_scalars_test.fbs]: https://github.com/dvidelabs/flatcc/blob/optional/test/optional_scalars_test/optional_scalars_test.fbs\n[optional_scalars_test.c]: https://github.com/dvidelabs/flatcc/blob/optional/test/optional_scalars_test/optional_scalars_test.c\n[paligned_alloc.h]: https://github.com/dvidelabs/flatcc/blob/master/include/flatcc/portable/paligned_alloc.h\n[test_json.c]: https://github.com/dvidelabs/flatcc/blob/master/test/json_test/test_json.c\n[test_json_parser.c]: https://github.com/dvidelabs/flatcc/blob/master/test/json_test/test_json_parser.c\n[flatcc_builder.h]: https://github.com/dvidelabs/flatcc/blob/master/include/flatcc/flatcc_builder.h\n[flatcc_emitter.h]: https://github.com/dvidelabs/flatcc/blob/master/include/flatcc/flatcc_emitter.h\n[flatcc-help.md]: https://github.com/dvidelabs/flatcc/blob/master/doc/flatcc-help.md\n[flatcc_rtconfig.h]: https://github.com/dvidelabs/flatcc/blob/master/include/flatcc/flatcc_rtconfig.h\n[hexdump.h]: https://github.com/dvidelabs/flatcc/blob/master/include/flatcc/support/hexdump.h\n[readfile.h]: include/flatcc/support/readfile.h\n[Security Considerations]: https://github.com/dvidelabs/flatcc/blob/master/doc/security.md\n[flatc --annotate]: https://github.com/google/flatbuffers/tree/master/tests/annotated_binary\n[flatcc_accessors.h]: https://github.com/dvidelabs/flatcc/blob/master/include/flatcc/flatcc_accessors.h\n[pmemaccess.h]: https://github.com/dvidelabs/flatcc/blob/master/include/flatcc/portable/pmemaccess.h\n[pendian_detect.h]: include/flatcc/portable/pendian_detect.h`\n[flatcc_types.h]: include/flatcc/flatcc_types.h\n[WebKit Style]: https://webkit.org/code-style-guidelines/\n[FlatCC #287]: https://github.com/dvidelabs/flatcc/issues/287\n[Google Flatbuffers #8374]: https://github.com/google/flatbuffers/issues/8374\n[FlatCC #289]: https://github.com/dvidelabs/flatcc/issues/289\n","funding_links":[],"categories":["Serialization","序列化","C"],"sub_categories":["Advanced books","高级书籍"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdvidelabs%2Fflatcc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdvidelabs%2Fflatcc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdvidelabs%2Fflatcc/lists"}