snowflake-connector-python 3.16.0__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. snowflake/connector/__init__.py +96 -0
  2. snowflake/connector/_query_context_cache.py +276 -0
  3. snowflake/connector/_sql_util.py +48 -0
  4. snowflake/connector/_utils.py +70 -0
  5. snowflake/connector/arrow_context.py +203 -0
  6. snowflake/connector/auth/__init__.py +53 -0
  7. snowflake/connector/auth/_auth.py +586 -0
  8. snowflake/connector/auth/_http_server.py +220 -0
  9. snowflake/connector/auth/_oauth_base.py +400 -0
  10. snowflake/connector/auth/by_plugin.py +219 -0
  11. snowflake/connector/auth/default.py +36 -0
  12. snowflake/connector/auth/idtoken.py +72 -0
  13. snowflake/connector/auth/keypair.py +222 -0
  14. snowflake/connector/auth/no_auth.py +39 -0
  15. snowflake/connector/auth/oauth.py +49 -0
  16. snowflake/connector/auth/oauth_code.py +479 -0
  17. snowflake/connector/auth/oauth_credentials.py +66 -0
  18. snowflake/connector/auth/okta.py +335 -0
  19. snowflake/connector/auth/pat.py +39 -0
  20. snowflake/connector/auth/usrpwdmfa.py +69 -0
  21. snowflake/connector/auth/webbrowser.py +502 -0
  22. snowflake/connector/auth/workload_identity.py +94 -0
  23. snowflake/connector/azure_storage_client.py +276 -0
  24. snowflake/connector/backoff_policies.py +141 -0
  25. snowflake/connector/bind_upload_agent.py +89 -0
  26. snowflake/connector/cache.py +696 -0
  27. snowflake/connector/compat.py +127 -0
  28. snowflake/connector/config_manager.py +496 -0
  29. snowflake/connector/connection.py +2273 -0
  30. snowflake/connector/connection_diagnostic.py +776 -0
  31. snowflake/connector/constants.py +442 -0
  32. snowflake/connector/converter.py +785 -0
  33. snowflake/connector/converter_issue23517.py +87 -0
  34. snowflake/connector/converter_null.py +14 -0
  35. snowflake/connector/converter_snowsql.py +205 -0
  36. snowflake/connector/cursor.py +1951 -0
  37. snowflake/connector/dbapi.py +53 -0
  38. snowflake/connector/description.py +19 -0
  39. snowflake/connector/direct_file_operation_utils.py +88 -0
  40. snowflake/connector/encryption_util.py +220 -0
  41. snowflake/connector/errorcode.py +91 -0
  42. snowflake/connector/errors.py +615 -0
  43. snowflake/connector/externals_utils/__init__.py +0 -0
  44. snowflake/connector/externals_utils/externals_setup.py +27 -0
  45. snowflake/connector/feature.py +4 -0
  46. snowflake/connector/file_compression_type.py +118 -0
  47. snowflake/connector/file_lock.py +72 -0
  48. snowflake/connector/file_transfer_agent.py +1215 -0
  49. snowflake/connector/file_util.py +153 -0
  50. snowflake/connector/gcs_storage_client.py +474 -0
  51. snowflake/connector/gzip_decoder.py +85 -0
  52. snowflake/connector/local_storage_client.py +90 -0
  53. snowflake/connector/log_configuration.py +60 -0
  54. snowflake/connector/logging_utils/__init__.py +0 -0
  55. snowflake/connector/logging_utils/filters.py +72 -0
  56. snowflake/connector/nanoarrow_arrow_iterator.cp313-win_amd64.pyd +0 -0
  57. snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +60 -0
  58. snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +29 -0
  59. snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +19 -0
  60. snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +26 -0
  61. snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +21 -0
  62. snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +23 -0
  63. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.cpp +557 -0
  64. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.hpp +98 -0
  65. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +125 -0
  66. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +115 -0
  67. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.cpp +1005 -0
  68. snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.hpp +127 -0
  69. snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +47 -0
  70. snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +46 -0
  71. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +83 -0
  72. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +35 -0
  73. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +97 -0
  74. snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +72 -0
  75. snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +73 -0
  76. snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +28 -0
  77. snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +30 -0
  78. snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +35 -0
  79. snowflake/connector/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +17 -0
  80. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +23 -0
  81. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +45 -0
  82. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +71 -0
  83. snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +56 -0
  84. snowflake/connector/nanoarrow_cpp/ArrowIterator/LICENSE.txt +209 -0
  85. snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +75 -0
  86. snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +30 -0
  87. snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +46 -0
  88. snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +29 -0
  89. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +8 -0
  90. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +95 -0
  91. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +57 -0
  92. snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +36 -0
  93. snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +34 -0
  94. snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +48 -0
  95. snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +19 -0
  96. snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +26 -0
  97. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +36 -0
  98. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +31 -0
  99. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +346 -0
  100. snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +145 -0
  101. snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +14 -0
  102. snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.cpp +65 -0
  103. snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.hpp +68 -0
  104. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +101 -0
  105. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +127 -0
  106. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +45 -0
  107. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +1908 -0
  108. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +215 -0
  109. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +125 -0
  110. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +7 -0
  111. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +55 -0
  112. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +148 -0
  113. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +31 -0
  114. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +8 -0
  115. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +144 -0
  116. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +162 -0
  117. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +97 -0
  118. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +239 -0
  119. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +14 -0
  120. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +210 -0
  121. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +84 -0
  122. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +84 -0
  123. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +20 -0
  124. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +51 -0
  125. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +206 -0
  126. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +118 -0
  127. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +19 -0
  128. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +52 -0
  129. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +2 -0
  130. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +25 -0
  131. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +67 -0
  132. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +162 -0
  133. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +898 -0
  134. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +190 -0
  135. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +6 -0
  136. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +52 -0
  137. snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc.c +3204 -0
  138. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.c +3217 -0
  139. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.h +3618 -0
  140. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +379 -0
  141. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_arrow_iterator.pyx +256 -0
  142. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.c +512 -0
  143. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.h +350 -0
  144. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +33273 -0
  145. snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +397 -0
  146. snowflake/connector/nanoarrow_cpp/Logging/logging.cpp +100 -0
  147. snowflake/connector/nanoarrow_cpp/Logging/logging.hpp +49 -0
  148. snowflake/connector/network.py +1297 -0
  149. snowflake/connector/ocsp_asn1crypto.py +447 -0
  150. snowflake/connector/ocsp_snowflake.py +1883 -0
  151. snowflake/connector/options.py +131 -0
  152. snowflake/connector/pandas_tools.py +732 -0
  153. snowflake/connector/proxy.py +43 -0
  154. snowflake/connector/py.typed +0 -0
  155. snowflake/connector/result_batch.py +786 -0
  156. snowflake/connector/result_set.py +319 -0
  157. snowflake/connector/s3_storage_client.py +605 -0
  158. snowflake/connector/secret_detector.py +181 -0
  159. snowflake/connector/sf_dirs.py +64 -0
  160. snowflake/connector/sfbinaryformat.py +35 -0
  161. snowflake/connector/sfdatetime.py +345 -0
  162. snowflake/connector/snow_logging.py +144 -0
  163. snowflake/connector/sqlstate.py +9 -0
  164. snowflake/connector/ssd_internal_keys.py +30 -0
  165. snowflake/connector/ssl_wrap_socket.py +134 -0
  166. snowflake/connector/storage_client.py +478 -0
  167. snowflake/connector/telemetry.py +249 -0
  168. snowflake/connector/telemetry_oob.py +543 -0
  169. snowflake/connector/test_util.py +30 -0
  170. snowflake/connector/time_util.py +159 -0
  171. snowflake/connector/token_cache.py +402 -0
  172. snowflake/connector/tool/__init__.py +0 -0
  173. snowflake/connector/tool/dump_certs.py +57 -0
  174. snowflake/connector/tool/dump_ocsp_response.py +139 -0
  175. snowflake/connector/tool/dump_ocsp_response_cache.py +194 -0
  176. snowflake/connector/tool/probe_connection.py +69 -0
  177. snowflake/connector/url_util.py +49 -0
  178. snowflake/connector/util_text.py +301 -0
  179. snowflake/connector/vendored/__init__.py +3 -0
  180. snowflake/connector/vendored/requests/LICENSE +175 -0
  181. snowflake/connector/vendored/requests/__init__.py +169 -0
  182. snowflake/connector/vendored/requests/__version__.py +14 -0
  183. snowflake/connector/vendored/requests/_internal_utils.py +50 -0
  184. snowflake/connector/vendored/requests/adapters.py +537 -0
  185. snowflake/connector/vendored/requests/api.py +157 -0
  186. snowflake/connector/vendored/requests/auth.py +315 -0
  187. snowflake/connector/vendored/requests/certs.py +17 -0
  188. snowflake/connector/vendored/requests/compat.py +79 -0
  189. snowflake/connector/vendored/requests/cookies.py +561 -0
  190. snowflake/connector/vendored/requests/exceptions.py +140 -0
  191. snowflake/connector/vendored/requests/help.py +134 -0
  192. snowflake/connector/vendored/requests/hooks.py +33 -0
  193. snowflake/connector/vendored/requests/models.py +1033 -0
  194. snowflake/connector/vendored/requests/sessions.py +833 -0
  195. snowflake/connector/vendored/requests/status_codes.py +128 -0
  196. snowflake/connector/vendored/requests/structures.py +99 -0
  197. snowflake/connector/vendored/requests/utils.py +1093 -0
  198. snowflake/connector/vendored/urllib3/LICENSE.txt +21 -0
  199. snowflake/connector/vendored/urllib3/__init__.py +85 -0
  200. snowflake/connector/vendored/urllib3/_collections.py +355 -0
  201. snowflake/connector/vendored/urllib3/_version.py +2 -0
  202. snowflake/connector/vendored/urllib3/connection.py +572 -0
  203. snowflake/connector/vendored/urllib3/connectionpool.py +1137 -0
  204. snowflake/connector/vendored/urllib3/contrib/__init__.py +0 -0
  205. snowflake/connector/vendored/urllib3/contrib/_appengine_environ.py +36 -0
  206. snowflake/connector/vendored/urllib3/contrib/_securetransport/__init__.py +0 -0
  207. snowflake/connector/vendored/urllib3/contrib/_securetransport/bindings.py +519 -0
  208. snowflake/connector/vendored/urllib3/contrib/_securetransport/low_level.py +397 -0
  209. snowflake/connector/vendored/urllib3/contrib/appengine.py +314 -0
  210. snowflake/connector/vendored/urllib3/contrib/ntlmpool.py +130 -0
  211. snowflake/connector/vendored/urllib3/contrib/pyopenssl.py +509 -0
  212. snowflake/connector/vendored/urllib3/contrib/securetransport.py +920 -0
  213. snowflake/connector/vendored/urllib3/contrib/socks.py +216 -0
  214. snowflake/connector/vendored/urllib3/exceptions.py +323 -0
  215. snowflake/connector/vendored/urllib3/fields.py +274 -0
  216. snowflake/connector/vendored/urllib3/filepost.py +98 -0
  217. snowflake/connector/vendored/urllib3/packages/__init__.py +0 -0
  218. snowflake/connector/vendored/urllib3/packages/backports/__init__.py +0 -0
  219. snowflake/connector/vendored/urllib3/packages/backports/makefile.py +51 -0
  220. snowflake/connector/vendored/urllib3/packages/backports/weakref_finalize.py +155 -0
  221. snowflake/connector/vendored/urllib3/packages/six.py +1076 -0
  222. snowflake/connector/vendored/urllib3/poolmanager.py +540 -0
  223. snowflake/connector/vendored/urllib3/request.py +191 -0
  224. snowflake/connector/vendored/urllib3/response.py +885 -0
  225. snowflake/connector/vendored/urllib3/util/__init__.py +49 -0
  226. snowflake/connector/vendored/urllib3/util/connection.py +156 -0
  227. snowflake/connector/vendored/urllib3/util/proxy.py +57 -0
  228. snowflake/connector/vendored/urllib3/util/queue.py +22 -0
  229. snowflake/connector/vendored/urllib3/util/request.py +146 -0
  230. snowflake/connector/vendored/urllib3/util/response.py +107 -0
  231. snowflake/connector/vendored/urllib3/util/retry.py +620 -0
  232. snowflake/connector/vendored/urllib3/util/ssl_.py +495 -0
  233. snowflake/connector/vendored/urllib3/util/ssl_match_hostname.py +159 -0
  234. snowflake/connector/vendored/urllib3/util/ssltransport.py +221 -0
  235. snowflake/connector/vendored/urllib3/util/timeout.py +271 -0
  236. snowflake/connector/vendored/urllib3/util/url.py +435 -0
  237. snowflake/connector/vendored/urllib3/util/wait.py +152 -0
  238. snowflake/connector/version.py +3 -0
  239. snowflake/connector/wif_util.py +407 -0
  240. snowflake_connector_python-3.16.0.dist-info/METADATA +1475 -0
  241. snowflake_connector_python-3.16.0.dist-info/RECORD +246 -0
  242. snowflake_connector_python-3.16.0.dist-info/WHEEL +5 -0
  243. snowflake_connector_python-3.16.0.dist-info/entry_points.txt +4 -0
  244. snowflake_connector_python-3.16.0.dist-info/licenses/LICENSE.txt +202 -0
  245. snowflake_connector_python-3.16.0.dist-info/licenses/NOTICE +8 -0
  246. snowflake_connector_python-3.16.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1908 @@
1
+ #ifndef FLATCC_BUILDER_H
2
+ #define FLATCC_BUILDER_H
3
+
4
+ #ifdef __cplusplus
5
+ extern "C" {
6
+ #endif
7
+
8
+ /**
9
+ * Library for building untyped FlatBuffers. Intended as a support
10
+ * library for generated C code to produce typed builders, but might
11
+ * also be useful in runtime environments and as support for scripting
12
+ * languages.
13
+ *
14
+ * The builder has two API layers: a stack based `start/end` approach,
15
+ * and a direct `create`, and they may be mixed freely. The direct
16
+ * approach may be used as part of more specialized optimizations such
17
+ * as rewriting buffers while the stack approach is convenient for state
18
+ * machine driven parsers without a stack, or with a very simple stack
19
+ * without extra allocations.
20
+ *
21
+ * The builder emits partial buffer sequences to a user provided emitter
22
+ * function and does not require a full buffer reprensenation in memory.
23
+ * For this reason it also does not support sorting or other operations
24
+ * that requires representing the buffer, but post-processors can easily
25
+ * do this, and the generated schema specific code and provide functions
26
+ * to handle this.
27
+ *
28
+ * A custom allocator with a default realloc implementation can place
29
+ * restraints on resource consumption and provide initial allocation
30
+ * sizes for various buffers and stacks in use.
31
+ *
32
+ * A buffer under construction uses a virtual address space for the
33
+ * completed part of the buffer, starting at 0 and growing in both
34
+ * directions, or just down depending on whether vtables should be
35
+ * clustered at the end or not. Clustering may help caching and
36
+ * preshipping that part of the buffer.
37
+ *
38
+ * Because an offset cannot be known before its reference location is
39
+ * defined, every completed table, vector, etc. returns a reference into
40
+ * the virtual address range. If the final buffer keeps the 0 offset,
41
+ * these references remain stable an may be used for external references
42
+ * into the buffer.
43
+ *
44
+ * The maximum buffer that can be constructed is in praxis limited to
45
+ * half the UOFFSET_MAX size, typically 2^31 bytes, not counting
46
+ * clustered vtables that may consume and additional 2^31 bytes
47
+ * (positive address range), but in praxis cannot because vtable
48
+ * references are signed and thus limited to 2^31 bytes (or equivalent
49
+ * depending on the flatbuffer types chosen).
50
+ *
51
+ * CORRECTION: in various places rules are mentioned about nesting and using
52
+ * a reference at most once. In fact, DAG's are also valid flatbuffers.
53
+ * This means a reference may be reused as long as each individual use
54
+ * obeys the rules and, for example, circular references are not
55
+ * constructed (circular types are ok, but objects graphs with cycles
56
+ * are not permitted). Be especially aware of the offset vector create
57
+ * call which translates the references into offsets - this can be
58
+ * reverted by noting the reference in vector and calculate the base
59
+ * used for the offset to restore the original references after the
60
+ * vector has been emitted.
61
+ */
62
+
63
+ #include <stdlib.h>
64
+ #ifndef UINT8_MAX
65
+ #include <stdint.h>
66
+ #endif
67
+
68
+ #include "flatcc_flatbuffers.h"
69
+ #include "flatcc_emitter.h"
70
+ #include "flatcc_refmap.h"
71
+
72
+ /* It is possible to enable logging here. */
73
+ #ifndef FLATCC_BUILDER_ASSERT
74
+ #define FLATCC_BUILDER_ASSERT(cond, reason) FLATCC_ASSERT(cond)
75
+ #endif
76
+
77
+ /*
78
+ * Eror handling is not convenient and correct use should not cause
79
+ * errors beyond possibly memory allocation, but assertions are a
80
+ * good way to trace problems.
81
+ *
82
+ * Note: some internal assertion will remain if disabled.
83
+ */
84
+ #ifndef FLATCC_BUILDER_ASSERT_ON_ERROR
85
+ #define FLATCC_BUILDER_ASSERT_ON_ERROR 1
86
+ #endif
87
+
88
+ /*
89
+ * If set, checks user input agains state and returns error,
90
+ * otherwise errors are ignored (assuming they won't happen).
91
+ * Errors will be asserted if enabled and checks are not skipped.
92
+ */
93
+ #ifndef FLATCC_BUILDER_SKIP_CHECKS
94
+ #define FLATCC_BUILDER_SKIP_CHECKS 0
95
+ #endif
96
+
97
+
98
+ /*
99
+ * When adding the same field to a table twice this is either an error
100
+ * or the existing field is returned, potentially introducing garbage
101
+ * if the type is a vector, table, or string. When implementing parsers
102
+ * it may be convenient to not treat this as an error.
103
+ */
104
+ #ifndef FLATCC_BUILDER_ALLOW_REPEAT_TABLE_ADD
105
+ #define FLATCC_BUILDER_ALLOW_REPEAT_TABLE_ADD 0
106
+ #endif
107
+
108
+ /**
109
+ * This type must have same size as `flatbuffers_uoffset_t`
110
+ * and must be a signed type.
111
+ */
112
+ typedef flatbuffers_soffset_t flatcc_builder_ref_t;
113
+ typedef flatbuffers_utype_t flatcc_builder_utype_t;
114
+
115
+ /**
116
+ * This type must be compatible with code generation that
117
+ * creates union specific ref types.
118
+ */
119
+ typedef struct flatcc_builder_union_ref {
120
+ flatcc_builder_utype_t type;
121
+ flatcc_builder_ref_t value;
122
+ } flatcc_builder_union_ref_t;
123
+
124
+ typedef struct flatcc_builder_union_vec_ref {
125
+ flatcc_builder_ref_t type;
126
+ flatcc_builder_ref_t value;
127
+ } flatcc_builder_union_vec_ref_t;
128
+
129
+ /**
130
+ * Virtual tables are off by one to avoid being mistaken for error at
131
+ * position 0, and it makes them detectable as such because no other
132
+ * reference is uneven. Vtables are emitted at their actual location
133
+ * which is one less than the reference value.
134
+ */
135
+ typedef flatbuffers_soffset_t flatcc_builder_vt_ref_t;
136
+
137
+ typedef flatbuffers_uoffset_t flatcc_builder_identifier_t;
138
+
139
+ /**
140
+ * Hints to custom allocators so they can provide initial alloc sizes
141
+ * etc. There will be at most one buffer for each allocation type per
142
+ * flatcc_builder instance. Buffers containing only structs may avoid
143
+ * allocation altogether using a `create` call. The vs stack must hold
144
+ * vtable entries for all open tables up to their requested max id, but
145
+ * unused max id overlap on the stack. The final vtables only store the
146
+ * largest id actually added. The fs stack must hold stack frames for
147
+ * the nesting levels expected in the buffer, each about 50-100 bytes.
148
+ * The ds stack holds open vectors, table data, and nested buffer state.
149
+ * `create` calls bypass the `ds` and `fs` stack and are thus faster.
150
+ * The vb buffer holds a copy of all vtables seen and emitted since last
151
+ * vtable flush. The patch log holds a uoffset for every table field
152
+ * added to currently open tables. The hash table holds a uoffset entry
153
+ * for each hash slot where the allocator decides how many to provide
154
+ * above a certain minimum. The vd buffer allocates vtable descriptors
155
+ * which is a reference to an emitted vtable, an offset to a cached
156
+ * vtable, and a link to next descriptor with same hash. Calling `reset`
157
+ * after build can either keep the allocation levels for the next
158
+ * buffer, or reduce the buffers already allocated by requesting 1 byte
159
+ * allocations (meaning provide a default).
160
+ *
161
+ * The user stack is not automatically allocated, but when entered
162
+ * explicitly, the boundary is rembered in the current live
163
+ * frame.
164
+ */
165
+ enum flatcc_builder_alloc_type {
166
+ /* The stack where vtables are build. */
167
+ flatcc_builder_alloc_vs,
168
+ /* The stack where data structures are build. */
169
+ flatcc_builder_alloc_ds,
170
+ /* The virtual table buffer cache, holds a copy of each vt seen. */
171
+ flatcc_builder_alloc_vb,
172
+ /* The patch log, remembers table fields with outstanding offset refs. */
173
+ flatcc_builder_alloc_pl,
174
+ /* The stack of frames for nested types. */
175
+ flatcc_builder_alloc_fs,
176
+ /* The hash table part of the virtual table cache. */
177
+ flatcc_builder_alloc_ht,
178
+ /* The vtable descriptor buffer, i.e. list elements for emitted vtables. */
179
+ flatcc_builder_alloc_vd,
180
+ /* User stack frame for custom data. */
181
+ flatcc_builder_alloc_us,
182
+
183
+ /* Number of allocation buffers. */
184
+ flatcc_builder_alloc_buffer_count
185
+ };
186
+
187
+ /** Must reflect the `flatcc_builder_alloc_type` enum. */
188
+ #define FLATCC_BUILDER_ALLOC_BUFFER_COUNT flatcc_builder_alloc_buffer_count
189
+
190
+ #ifndef FLATCC_BUILDER_ALLOC
191
+ #define FLATCC_BUILDER_ALLOC(n) FLATCC_ALLOC(n)
192
+ #endif
193
+
194
+ #ifndef FLATCC_BUILDER_FREE
195
+ #define FLATCC_BUILDER_FREE(p) FLATCC_FREE(p)
196
+ #endif
197
+
198
+ #ifndef FLATCC_BUILDER_REALLOC
199
+ #define FLATCC_BUILDER_REALLOC(p, n) FLATCC_REALLOC(p, n)
200
+ #endif
201
+
202
+ #ifndef FLATCC_BUILDER_ALIGNED_ALLOC
203
+ #define FLATCC_BUILDER_ALIGNED_ALLOC(a, n) FLATCC_ALIGNED_ALLOC(a, n)
204
+ #endif
205
+
206
+ #ifndef FLATCC_BUILDER_ALIGNED_FREE
207
+ #define FLATCC_BUILDER_ALIGNED_FREE(p) FLATCC_ALIGNED_FREE(p)
208
+ #endif
209
+
210
+ /**
211
+ * Emits data to a conceptual deque by appending to either front or
212
+ * back, starting from offset 0.
213
+ *
214
+ * Each emit call appends a strictly later or earlier sequence than the
215
+ * last emit with same offset sign. Thus a buffer is gradually grown at
216
+ * both ends. `len` is the combined length of all iov entries such that
217
+ * `offset + len` yields the former offset for negative offsets and
218
+ * `offset + len` yields the next offset for non-negative offsets.
219
+ * The bulk of the data will be in the negative range, possibly all of
220
+ * it. The first emitted emitted range will either start or end at
221
+ * offset 0. If offset 0 is emitted, it indicates the start of clustered
222
+ * vtables. The last positive (non-zero) offset may be zero padding to
223
+ * place the buffer in a full multiple of `block_align`, if set.
224
+ *
225
+ * No iov entry is empty, 0 < iov_count <= FLATCC_IOV_COUNT_MAX.
226
+ *
227
+ * The source data are in general ephemeral and should be consumed
228
+ * immediately, as opposed to caching iov.
229
+ *
230
+ * For high performance applications:
231
+ *
232
+ * The `create` calls may reference longer living data, but header
233
+ * fields etc. will still be short lived. If an emitter wants to
234
+ * reference data in another buffer rather than copying, it should
235
+ * inspect the memory range. The length of an iov entry may also be used
236
+ * since headers are never very long (anything starting at 16 bytes can
237
+ * safely be assumed to be user provided, or static zero padding). It is
238
+ * guaranteed that data pointers in `create` calls receive a unique slot
239
+ * separate from temporary headers, in the iov table which may be used
240
+ * for range checking or hashing (`create_table` is the only call that
241
+ * mutates the data buffer). It is also guaranteed (with the exception
242
+ * of `create_table` and `create_cached_vtable`) that data provided to
243
+ * create calls are not referenced at all by the builder, and these data
244
+ * may therefore de-facto be handles rather than direct pointers when
245
+ * the emitter and data provider can agree on such a protocol. This does
246
+ * NOT apply to any start/end/add/etc. calls which do copy to stack.
247
+ * `flatcc_builder_padding_base` may be used to test if an iov entry is
248
+ * zero padding which always begins at that address.
249
+ *
250
+ * Future: the emit interface could be extended with a type code
251
+ * and return an existing object insted of the emitted if, for
252
+ * example, they are identical. Outside this api level, generated
253
+ * code could provide a table comparison function to help such
254
+ * deduplication. It would be optional because two equal objects
255
+ * are not necessarily identical. The emitter already receives
256
+ * one object at time.
257
+ *
258
+ * Returns 0 on success and otherwise causes the flatcc_builder
259
+ * to fail.
260
+ */
261
+ typedef int flatcc_builder_emit_fun(void *emit_context,
262
+ const flatcc_iovec_t *iov, int iov_count, flatbuffers_soffset_t offset, size_t len);
263
+
264
+ /*
265
+ * Returns a pointer to static padding used in emitter calls. May
266
+ * sometimes also be used for empty defaults such as identifier.
267
+ */
268
+ extern const uint8_t flatcc_builder_padding_base[];
269
+
270
+ /**
271
+ * `request` is a minimum size to be returned, but allocation is
272
+ * expected to grow exponentially or in reasonable chunks. Notably,
273
+ * `alloc_type = flatcc_builder_alloc_ht` will only use highest available
274
+ * power of 2. The allocator may shrink if `request` is well below
275
+ * current size but should avoid repeated resizing on small changes in
276
+ * request sizes. If `zero_fill` is non-zero, allocated data beyond
277
+ * the current size must be zeroed. The buffer `b` may be null with 0
278
+ * length initially. `alloc_context` is completely implementation
279
+ * dependendent, and not needed when just relying on realloc. The
280
+ * resulting buffer may be the same or different with moved data, like
281
+ * realloc. Returns -1 with unmodified buffer on failure or 0 on
282
+ * success. The `alloc_type` identifies the buffer type. This may be
283
+ * used to cache buffers between instances of builders, or to decide a
284
+ * default allocation size larger than requested. If `need` is zero the
285
+ * buffer should be deallocate if non-zero, and return success (0)
286
+ * regardless.
287
+ */
288
+ typedef int flatcc_builder_alloc_fun(void *alloc_context,
289
+ flatcc_iovec_t *b, size_t request, int zero_fill, int alloc_type);
290
+
291
+ /*
292
+ * The number of hash slots there will be allocated space for. The
293
+ * allocator may provide more. The size returned should be
294
+ * `sizeof(flatbuffers_uoffset_t) * count`, where the size is a power of
295
+ * 2 (or the rest is wasted). The hash table can store many more entries
296
+ * than slots using linear search. The table does not resize.
297
+ */
298
+ #ifndef FLATCC_BUILDER_MIN_HASH_COUNT
299
+ #define FLATCC_BUILDER_MIN_HASH_COUNT 64
300
+ #endif
301
+
302
+ typedef struct __flatcc_builder_buffer_frame __flatcc_builder_buffer_frame_t;
303
+ struct __flatcc_builder_buffer_frame {
304
+ flatcc_builder_identifier_t identifier;
305
+ flatcc_builder_ref_t mark;
306
+ flatbuffers_uoffset_t vs_end;
307
+ flatbuffers_uoffset_t nest_id;
308
+ uint16_t flags;
309
+ uint16_t block_align;
310
+ };
311
+
312
+ typedef struct __flatcc_builder_vector_frame __flatcc_builder_vector_frame_t;
313
+ struct __flatcc_builder_vector_frame {
314
+ flatbuffers_uoffset_t elem_size;
315
+ flatbuffers_uoffset_t count;
316
+ flatbuffers_uoffset_t max_count;
317
+ };
318
+
319
+ typedef struct __flatcc_builder_table_frame __flatcc_builder_table_frame_t;
320
+ struct __flatcc_builder_table_frame {
321
+ flatbuffers_uoffset_t vs_end;
322
+ flatbuffers_uoffset_t pl_end;
323
+ uint32_t vt_hash;
324
+ flatbuffers_voffset_t id_end;
325
+ };
326
+
327
+ /*
328
+ * Store state for nested structures such as buffers, tables and vectors.
329
+ *
330
+ * For less busy data and data where access to a previous state is
331
+ * irrelevant, the frame may store the current state directly. Otherwise
332
+ * the current state is maintained in the flatcc_builder_t structure in a
333
+ * possibly derived form (e.g. ds pointer instead of ds_end offset) and
334
+ * the frame is used to store the previous state when the frame is
335
+ * entered.
336
+ *
337
+ * Most operations have a start/update/end cycle the decides the
338
+ * liftetime of a frame, but these generally also have a direct form
339
+ * (create) that does not use a frame at all. These still do some
340
+ * state updates notably passing min_align to parent which may also be
341
+ * an operation without a frame following the child level operation
342
+ * (e.g. create struct, create buffer). Ending a frame results in the
343
+ * same kind of updates.
344
+ */
345
+ typedef struct __flatcc_builder_frame __flatcc_builder_frame_t;
346
+ struct __flatcc_builder_frame {
347
+ flatbuffers_uoffset_t ds_first;
348
+ flatbuffers_uoffset_t type_limit;
349
+ flatbuffers_uoffset_t ds_offset;
350
+ uint16_t align;
351
+ uint16_t type;
352
+ union {
353
+ __flatcc_builder_table_frame_t table;
354
+ __flatcc_builder_vector_frame_t vector;
355
+ __flatcc_builder_buffer_frame_t buffer;
356
+ } container;
357
+ };
358
+
359
+ /**
360
+ * The main flatcc_builder structure. Can be stack allocated and must
361
+ * be initialized with `flatcc_builder_init` and cleared with
362
+ * `flatcc_builder_clear` to reclaim memory. Between buffer builds,
363
+ * `flatcc_builder_reset` may be used.
364
+ */
365
+ typedef struct flatcc_builder flatcc_builder_t;
366
+
367
+ struct flatcc_builder {
368
+ /* Next entry on reserved stack in `alloc_pl` buffer. */
369
+ flatbuffers_voffset_t *pl;
370
+ /* Next entry on reserved stack in `alloc_vs` buffer. */
371
+ flatbuffers_voffset_t *vs;
372
+ /* One above the highest entry in vs, used to track vt_size. */
373
+ flatbuffers_voffset_t id_end;
374
+ /* The evolving vtable hash updated with every new field. */
375
+ uint32_t vt_hash;
376
+
377
+ /* Pointer to ds_first. */
378
+ uint8_t *ds;
379
+ /* Offset from `ds` on current frame. */
380
+ flatbuffers_uoffset_t ds_offset;
381
+ /* ds buffer size relative to ds_first, clamped to max size of current type. */
382
+ flatbuffers_uoffset_t ds_limit;
383
+
384
+ /* ds_first, ds_first + ds_offset is current ds stack range. */
385
+ flatbuffers_uoffset_t ds_first;
386
+ /* Points to currently open frame in `alloc_fs` buffer. */
387
+ __flatcc_builder_frame_t *frame;
388
+
389
+ /* Only significant to emitter function, if at all. */
390
+ void *emit_context;
391
+ /* Only significant to allocator function, if at all. */
392
+ void *alloc_context;
393
+ /* Customizable write function that both appends and prepends data. */
394
+ flatcc_builder_emit_fun *emit;
395
+ /* Customizable allocator that also deallocates. */
396
+ flatcc_builder_alloc_fun *alloc;
397
+ /* Buffers indexed by `alloc_type` */
398
+ flatcc_iovec_t buffers[FLATCC_BUILDER_ALLOC_BUFFER_COUNT];
399
+ /* Number of slots in ht given as 1 << ht_width. */
400
+ size_t ht_width;
401
+
402
+ /* The location in vb to add next cached vtable. */
403
+ flatbuffers_uoffset_t vb_end;
404
+ /* Where to allocate next vtable descriptor for hash table. */
405
+ flatbuffers_uoffset_t vd_end;
406
+ /* Ensure final buffer is aligned to at least this. Nested buffers get their own `min_align`. */
407
+ uint16_t min_align;
408
+ /* The current active objects alignment isolated from nested activity. */
409
+ uint16_t align;
410
+ /* The current buffers block alignment used when emitting buffer. */
411
+ uint16_t block_align;
412
+ /* Signed virtual address range used for `flatcc_builder_ref_t` and emitter. */
413
+ flatcc_builder_ref_t emit_start;
414
+ flatcc_builder_ref_t emit_end;
415
+ /* 0 for top level, and end of buffer ref for nested buffers (can also be 0). */
416
+ flatcc_builder_ref_t buffer_mark;
417
+ /* Next nest_id. */
418
+ flatbuffers_uoffset_t nest_count;
419
+ /* Unique id to prevent sharing of vtables across buffers. */
420
+ flatbuffers_uoffset_t nest_id;
421
+ /* Current nesting level. Helpful to state-machines with explicit stack and to check `max_level`. */
422
+ int level;
423
+ /* Aggregate check for allocated frame and max_level. */
424
+ int limit_level;
425
+ /* Track size prefixed buffer. */
426
+ uint16_t buffer_flags;
427
+
428
+ /* Settings that may happen with no frame allocated. */
429
+
430
+ flatcc_builder_identifier_t identifier;
431
+
432
+ /* Settings that survive reset (emitter, alloc, and contexts also survive): */
433
+
434
+ /* If non-zero, vtable cache gets flushed periodically. */
435
+ size_t vb_flush_limit;
436
+ /* If non-zero, fails on deep nesting to help drivers with a stack, such as recursive parsers etc. */
437
+ int max_level;
438
+ /* If non-zero, do not cluster vtables at end, only emit negative offsets (0 by default). */
439
+ int disable_vt_clustering;
440
+
441
+ /* Set if the default emitter is being used. */
442
+ int is_default_emitter;
443
+ /* Only used with default emitter. */
444
+ flatcc_emitter_t default_emit_context;
445
+
446
+ /* Offset to the last entered user frame on the user frame stack, after frame header, or 0. */
447
+ size_t user_frame_offset;
448
+
449
+ /* The offset to the end of the most recent user frame. */
450
+ size_t user_frame_end;
451
+
452
+ /* The optional user supplied refmap for cloning DAG's - not shared with nested buffers. */
453
+ flatcc_refmap_t *refmap;
454
+ };
455
+
456
+ /**
457
+ * Call this before any other API call.
458
+ *
459
+ * The emitter handles the completed chunks of the buffer that will no
460
+ * longer be required by the builder. It is largely a `write` function
461
+ * that can append to both positive and negative offsets.
462
+ *
463
+ * No memory is allocated during init. Buffers will be allocated as
464
+ * needed. The `emit_context` is only used by the emitter, if at all.
465
+ *
466
+ * `flatcc_builder_reset/clear` calls are automtically forwarded to the
467
+ * default emitter.
468
+ *
469
+ * Returns -1 on failure, 0 on success.
470
+ */
471
+ int flatcc_builder_init(flatcc_builder_t *B);
472
+
473
+ /**
474
+ * Use instead of `flatcc_builder_init` when providing a custom allocator
475
+ * or emitter. Leave emitter or allocator null to use default.
476
+ * Cleanup of emit and alloc context must be handled manually after
477
+ * the builder is cleared or reset, except if emitter is null the
478
+ * default will be automatically cleared and reset.
479
+ *
480
+ * Returns -1 on failure, 0 on success.
481
+ */
482
+ int flatcc_builder_custom_init(flatcc_builder_t *B,
483
+ flatcc_builder_emit_fun *emit, void *emit_context,
484
+ flatcc_builder_alloc_fun *alloc, void *alloc_context);
485
+
486
+ /*
487
+ * Returns (flatcc_emitter_t *) if the default context is used.
488
+ * Other emitter might have null contexts.
489
+ */
490
+ void *flatcc_builder_get_emit_context(flatcc_builder_t *B);
491
+
492
+ /**
493
+ * Prepares builder for a new build. The emitter is not told when a
494
+ * buffer is finished or when a new begins, and must be told so
495
+ * separately. Allocated buffers will be zeroed, but may optionally be
496
+ * reduced to their defaults (signalled by reallocating each non-empty
497
+ * buffer to a single byte). General settings are cleared optionally,
498
+ * such as cache flushing. Buffer specific settings such as buffer
499
+ * identifier are always cleared.
500
+ *
501
+ * Returns -1 if allocator complains during buffer reduction, 0 on
502
+ * success.
503
+ */
504
+ int flatcc_builder_custom_reset(flatcc_builder_t *B,
505
+ int reduce_buffers, int set_defaults);
506
+
507
+ /*
508
+ * Same as `flatcc_builder_custom_reset` with default arguments
509
+ * where buffers are not reduced and default settings are not reset.
510
+ */
511
+ int flatcc_builder_reset(flatcc_builder_t *B);
512
+
513
+ /**
514
+ * Deallocates all memory by calling allocate with a zero size request
515
+ * on each buffer, then zeroing the builder structure itself.
516
+ */
517
+ void flatcc_builder_clear(flatcc_builder_t *B);
518
+
519
+ /**
520
+ * Allocates to next higher power of 2 using system realloc and ignores
521
+ * `alloc_context`. Only reduces size if a small subsequent increase in
522
+ * size would not trigger a reallocation. `alloc_type` is used to
523
+ * set minimum sizes. Hash tables are allocated to the exact requested
524
+ * size. See also `alloc_fun`.
525
+ */
526
+ int flatcc_builder_default_alloc(void *alloc_context,
527
+ flatcc_iovec_t *b, size_t request, int zero_fill, int alloc_type);
528
+
529
+ /**
530
+ * If non-zero, the vtable cache will get flushed whenever it reaches
531
+ * the given limit at a point in time where more space is needed. The
532
+ * limit is not exact as it is only tested when reallocation is
533
+ * required.
534
+ */
535
+ void flatcc_builder_set_vtable_cache_limit(flatcc_builder_t *B, size_t size);
536
+
537
+ /**
538
+ * Manual flushing of vtable for long running tasks. Mostly used
539
+ * internally to deal with nested buffers.
540
+ */
541
+ void flatcc_builder_flush_vtable_cache(flatcc_builder_t *B);
542
+
543
+ /**
544
+ * Low-level support function to aid in constructing nested buffers without
545
+ * allocation. Not for regular use.
546
+ *
547
+ * Call where `start_buffer` would have been placed when using
548
+ * `create_buffer` in a nested context. Save the return value on a stack
549
+ * as argument to `pop_buffer_alignment`.
550
+ *
551
+ * The call resets the current derived buffer alignment so the nested
552
+ * buffer will not be aligned to more than required.
553
+ *
554
+ * Often it will not be necessary to be so careful with alignment since
555
+ * the alignment cannot be invalid by failing to use push and pop, but
556
+ * for code generation it will ensure the correct result every time.
557
+ */
558
+ uint16_t flatcc_builder_push_buffer_alignment(flatcc_builder_t *B);
559
+
560
+ /**
561
+ * Low-level call.
562
+ *
563
+ * Call with the return value from push_buffer_alignment after a nested
564
+ * `create_buffer_call`. The alignments merge back up in the buffer
565
+ * hierarchy so the top level buffer gets the largest of all aligments.
566
+ */
567
+ void flatcc_builder_pop_buffer_alignment(flatcc_builder_t *B, uint16_t buffer_align);
568
+
569
+ /**
570
+ * This value may be of interest when the buffer has been ended, for
571
+ * example when subsequently allocating memory for the buffer to ensure
572
+ * that memory is properly aligned.
573
+ */
574
+ uint16_t flatcc_builder_get_buffer_alignment(flatcc_builder_t *B);
575
+
576
+ /**
577
+ * Level 0 means no buffer is started, otherwise it increments with
578
+ * start calls and decrements with end calls (approximately for
579
+ * optimized operations such as table vectors).
580
+ *
581
+ * If `max_level` has been set, `get_level` always returns a value <=
582
+ * `max_level` provided no start call has failed.
583
+ *
584
+ * Level continues to increment inside nested buffers.
585
+ */
586
+ int flatcc_builder_get_level(flatcc_builder_t *B);
587
+
588
+ /**
589
+ * Setting the max level triggers a failure on start of new nestings
590
+ * when the level is reached. May be used to protect recursive descend
591
+ * parsers etc. or later buffer readers.
592
+ *
593
+ * The builder itself is not sensitive to depth, and the allocator is a
594
+ * better way to protect resource abuse.
595
+ *
596
+ * `max_level` is not reset inside nested buffers.
597
+ */
598
+ void flatcc_builder_set_max_level(flatcc_builder_t *B, int level);
599
+
600
+ /**
601
+ * By default ordinary data such as tables are placed in front of
602
+ * earlier produced content and vtables are placed at the very end thus
603
+ * clustering vtables together. This can be disabled so all content is
604
+ * placed in front. Nested buffers ignores this setting because they can
605
+ * only place content in front because they cannot blend with the
606
+ * containing buffers content. Clustering could be more cache friendly
607
+ * and also enables pre-shipping of the vtables during transmission.
608
+ */
609
+ void flatcc_builder_set_vtable_clustering(flatcc_builder_t *B, int enable);
610
+
611
+ /**
612
+ * Sets a new user supplied refmap which maps source pointers to
613
+ * references and returns the old refmap, or null. It is also
614
+ * possible to disable an existing refmap by setting a null
615
+ * refmap.
616
+ *
617
+ * A clone or pick operation may use this map when present,
618
+ * depending on the data type. If a hit is found, the stored
619
+ * reference will be used instead of performing a new clone or
620
+ * pick operation. It is also possible to manually populate the
621
+ * refmap. Note that the builder does not have a concept of
622
+ * clone or pick - these are higher level recursive operations
623
+ * to add data from one buffer to another - but such code may
624
+ * rely on the builder to provide the current refmap during
625
+ * recursive operations. For this reason, the builder makes no
626
+ * calls to the refmap interface on its own - it just stores the
627
+ * current refmap such that recursive operations can find it.
628
+ *
629
+ * Refmaps MUST be reset, replaced or disabled if a source
630
+ * pointer may be reused for different purposes - for example if
631
+ * repeatedly reading FlatBuffers into the same memory buffer
632
+ * and performing a clone into a buffer under construction.
633
+ * Refmaps may also be replaced if the same object is to be
634
+ * cloned several times keeping the internal DAG structure
635
+ * intact with every new clone being an independent object.
636
+ *
637
+ * Refmaps must also be replaced or disabled prior to starting a
638
+ * nested buffer and after stopping it, or when cloning a object
639
+ * as a nested root. THIS IS VERY EASY TO GET WRONG! The
640
+ * builder does a lot of bookkeeping for nested buffers but not
641
+ * in this case. Shared references may happen and they WILL fail
642
+ * verification and they WILL break when copying out a nested
643
+ * buffer to somewhere else. The user_frame stack may be used
644
+ * for pushing refmaps, but often user codes recursive stack
645
+ * will work just as well.
646
+ *
647
+ * It is entirely optional to use refmaps when cloning - they
648
+ * preserve DAG structure and may speed up operations or slow
649
+ * them down, depending on the source material.
650
+ *
651
+ * Refmaps may consume a lot of space when large offset vectors
652
+ * are cloned when these do not have significant shared
653
+ * references. They may also be very cheap to use without any
654
+ * dynamic allocation when objects are small and have at most a
655
+ * few references.
656
+ *
657
+ * Refmaps only support init, insert, find, reset, clear but not
658
+ * delete. There is a standard implementation in the runtime
659
+ * source tree but it can easily be replaced compile time and it
660
+ * may also be left out if unused. The builder wraps reset, insert,
661
+ * and find so the user does not have to check if a refmap is
662
+ * present but other operations must be done direcly on the
663
+ * refmap.
664
+ *
665
+ * The builder wrapped refmap operations are valid on a null
666
+ * refmap which will find nothing and insert nothing.
667
+ *
668
+ * The builder will reset the refmap during a builder reset and
669
+ * clear the refmap during a builder clear operation. If the
670
+ * refmap goes out of scope before that happens it is important
671
+ * to call set_refmap with null and manually clear the refmap.
672
+ */
673
+ static inline flatcc_refmap_t *flatcc_builder_set_refmap(flatcc_builder_t *B, flatcc_refmap_t *refmap)
674
+ {
675
+ flatcc_refmap_t *refmap_old;
676
+
677
+ refmap_old = B->refmap;
678
+ B->refmap = refmap;
679
+ return refmap_old;
680
+ }
681
+
682
+ /* Retrieves the current refmap, or null. */
683
+ static inline flatcc_refmap_t *flatcc_builder_get_refmap(flatcc_builder_t *B)
684
+ {
685
+ return B->refmap;
686
+ }
687
+
688
+ /* Finds a reference, or a null reference if no refmap is active. * */
689
+ static inline flatcc_builder_ref_t flatcc_builder_refmap_find(flatcc_builder_t *B, const void *src)
690
+ {
691
+ return B->refmap ? flatcc_refmap_find(B->refmap, src) : flatcc_refmap_not_found;
692
+ }
693
+
694
+ /*
695
+ * Inserts into the current refmap with the inseted ref upon
696
+ * upon success, or not_found on failure (default 0), or just
697
+ * returns ref if refmap is absent.
698
+ *
699
+ * Note that if an existing item exists, the ref is replaced
700
+ * and the new, not the old, ref is returned.
701
+ */
702
+ static inline flatcc_builder_ref_t flatcc_builder_refmap_insert(flatcc_builder_t *B, const void *src, flatcc_builder_ref_t ref)
703
+ {
704
+ return B->refmap ? flatcc_refmap_insert(B->refmap, src, ref) : ref;
705
+ }
706
+
707
+ static inline void flatcc_builder_refmap_reset(flatcc_builder_t *B)
708
+ {
709
+ if (B->refmap) flatcc_refmap_reset(B->refmap);
710
+ }
711
+
712
+
713
+ enum flatcc_builder_buffer_flags {
714
+ flatcc_builder_is_nested = 1,
715
+ flatcc_builder_with_size = 2,
716
+ };
717
+
718
+ /**
719
+ * An alternative to start buffer, start struct/table ... end buffer.
720
+ *
721
+ * This call is mostly of interest as a means to quicly create a zero
722
+ * allocation top-level buffer header following a call to create_struct,
723
+ * or to create_vtable/create_table. For that, it is quite simple to
724
+ * use. For general buffer construction without allocation, more care is
725
+ * needed, as discussed below.
726
+ *
727
+ * If the content is created with `start/end_table` calls, or similar,
728
+ * it is better to use `start/end_buffer` since stack allocation is used
729
+ * anyway.
730
+ *
731
+ * The buffer alignment must be provided manually as it is not derived
732
+ * from constructed content, unlike `start/end_buffer`. Typically
733
+ * `align` would be same argument as provided to `create_struct`.
734
+ * `get_buffer_alignment` may also used (note: `get_buffer_alignment`
735
+ * may return different after the call because it will be updated with
736
+ * the `block_align` argument to `create_buffer` but that is ok).
737
+ *
738
+ * The buffer may be constructed as a nested buffer with the `is_nested
739
+ * = 1` flag. As a nested buffer a ubyte vector header is placed before
740
+ * the aligned buffer header. A top-level buffer will normally have
741
+ * flags set to 0.
742
+ *
743
+ * A top-level buffer may also be constructed with the `with_size = 2`
744
+ * flag for top level buffers. It adds a size prefix similar to
745
+ * `is_nested` but the size is part of the aligned buffer. A size
746
+ * prefixed top level buffer must be accessed with a size prefix aware
747
+ * reader, or the buffer given to a standard reader must point to after
748
+ * the size field while keeping the buffer aligned to the size field
749
+ * (this will depend on the readers API which may be an arbitrary other
750
+ * language).
751
+ *
752
+ * If the `with_size` is used with the `is_nested` flag, the size is
753
+ * added as usual and all fields remain aligned as before, but padding
754
+ * is adjusted to ensure the buffer is aligned to the size field so
755
+ * that, for example, the nested buffer with size can safely be copied
756
+ * to a new memory buffer for consumption.
757
+ *
758
+ * Generally, references may only be used within the same buffer
759
+ * context. With `create_buffer` this becomes less precise. The rule
760
+ * here is that anything that would be valid with start/end_buffer
761
+ * nestings is also valid when removing the `start_buffer` call and
762
+ * replacing `end_buffer` with `create_buffer`.
763
+ *
764
+ * Note the additional burden of tracking buffer alignment manually -
765
+ * To help with this use `push_buffer_alignment` where `start_buffer`
766
+ * would have been placed, and `pop_buffer_alignment after the
767
+ * `create_buffer` call, and use `get_buffer_alignemnt` as described
768
+ * above.
769
+ *
770
+ * `create_buffer` is not suitable as a container for buffers created
771
+ * with `start/end_buffer` as these make assumptions about context that
772
+ * create buffer does not provide. Also, there is no point in doing so,
773
+ * since the idea of `create_buffer` is to avoid allocation in the first
774
+ * place.
775
+ */
776
+ flatcc_builder_ref_t flatcc_builder_create_buffer(flatcc_builder_t *B,
777
+ const char identifier[FLATBUFFERS_IDENTIFIER_SIZE],
778
+ uint16_t block_align,
779
+ flatcc_builder_ref_t ref, uint16_t align, int flags);
780
+
781
+ /**
782
+ * Creates a struct within the current buffer without using any
783
+ * allocation.
784
+ *
785
+ * The struct should be used as a root in the `end_buffer` call or as a
786
+ * union value as there are no other ways to use struct while conforming
787
+ * to the FlatBuffer format - noting that tables embed structs in their
788
+ * own data area except in union fields.
789
+ *
790
+ * The struct should be in little endian format and follow the usual
791
+ * FlatBuffers alignment rules, although this API won't care about what
792
+ * is being stored.
793
+ *
794
+ * May also be used to simply emit a struct through the emitter
795
+ * interface without being in a buffer and without being a valid
796
+ * FlatBuffer.
797
+ */
798
+ flatcc_builder_ref_t flatcc_builder_create_struct(flatcc_builder_t *B,
799
+ const void *data, size_t size, uint16_t align);
800
+
801
+ /**
802
+ * Starts a struct and returns a pointer that should be used immediately
803
+ * to fill in the struct in protocol endian format, and when done,
804
+ * `end_struct` should be called. The returned reference should be used
805
+ * as argument to `end_buffer` or as a union value. See also
806
+ * `create_struct`.
807
+ */
808
+ void *flatcc_builder_start_struct(flatcc_builder_t *B,
809
+ size_t size, uint16_t align);
810
+
811
+ /**
812
+ * Return a pointer also returned at start struct, e.g. for endian
813
+ * conversion.
814
+ */
815
+ void *flatcc_builder_struct_edit(flatcc_builder_t *B);
816
+
817
+ /**
818
+ * Emits the struct started by `start_struct` and returns a reference to
819
+ * be used as root in an enclosing `end_buffer` call or as a union
820
+ * value. As mentioned in `create_struct`, these can also be used more
821
+ * freely, but not while being conformant FlatBuffers.
822
+ */
823
+ flatcc_builder_ref_t flatcc_builder_end_struct(flatcc_builder_t *B);
824
+
825
+ /**
826
+ * The buffer always aligns to at least the offset size (typically 4)
827
+ * and the internal alignment requirements of the buffer content which
828
+ * is derived as content is added.
829
+ *
830
+ * In addition, block_align can be specified. This ensures the resulting
831
+ * buffer is at least aligned to the block size and that the total size
832
+ * is zero padded to fill a block multiple if necessary. Because the
833
+ * emitter operates on a virtual address range before the full buffer is
834
+ * aligned, it may have to make assumptions based on that: For example,
835
+ * it may be processing encryption blocks in the fly, and the resulting
836
+ * buffer should be aligned to the encryption block size, even if the
837
+ * content is just a byte aligned struct. Block align helps ensure this.
838
+ * If the block align as 1 there will be no attempt to zero pad at the
839
+ * end, but the content may still warrant padding after the header. End
840
+ * padding is only needed with clustered vtables (which is the default).
841
+ *
842
+ * `block_align` is allowed to be 0 meaning it will inherit from parent if
843
+ * present, and otherwise it defaults to 1.
844
+ *
845
+ * The identifier may be null, and it may optionally be set later with
846
+ * `set_identifier` before the `end_buffer` call.
847
+ *
848
+ * General note:
849
+ *
850
+ * Only references returned with this buffer as current (i.e. last
851
+ * unended buffer) can be stored in other objects (tables, offset
852
+ * vectors) also belonging to this buffer, or used as the root argument
853
+ * to `end_buffer`. A reference may be stored at most once, and unused
854
+ * references will result in buffer garbage. All calls must be balanced
855
+ * around the respective start / end operations, but may otherwise nest
856
+ * freely, including nested buffers. Nested buffers are supposed to be
857
+ * stored in a table offset field to comply with FlatBuffers, but the
858
+ * API does not place any restrictions on where references are stored,
859
+ * as long as they are indicated as offset fields.
860
+ *
861
+ * All alignment in all API calls must be between 1 and 256 and must be a
862
+ * power of 2. This is not checked. Only if explicitly documented can it
863
+ * also be 0 for a default value.
864
+ *
865
+ * `flags` can be `with_size` but `is_nested` is derived from context
866
+ * see also `create_buffer`.
867
+ */
868
+ int flatcc_builder_start_buffer(flatcc_builder_t *B,
869
+ const char identifier[FLATBUFFERS_IDENTIFIER_SIZE],
870
+ uint16_t block_align, int flags);
871
+
872
+ /**
873
+ * The root object should be a struct or a table to conform to the
874
+ * FlatBuffers format, but technically it can also be a vector or a
875
+ * string, or even a child buffer (which is also vector as seen by the
876
+ * buffer). The object must be created within the current buffer
877
+ * context, that is, while the current buffer is the deepest nested
878
+ * buffer on the stack.
879
+ */
880
+ flatcc_builder_ref_t flatcc_builder_end_buffer(flatcc_builder_t *B, flatcc_builder_ref_t root);
881
+
882
+ /**
883
+ * The embed buffer is mostly intended to add an existing buffer as a
884
+ * nested buffer. The buffer will be wrapped in a ubyte vector such that
885
+ * the buffer is aligned at vector start, after the size field.
886
+ *
887
+ * If `align` is 0 it will default to 8 so that all FlatBuffer numeric
888
+ * types will be readable. NOTE: generally do not count on align 0 being
889
+ * valid or even checked by the API, but in this case it may be
890
+ * difficult to know the internal buffer alignment, and 1 would be the wrong
891
+ * choice.
892
+ *
893
+ * If `block_align` is set (non-zero), the buffer is placed in an isolated
894
+ * block multiple. This may cost up to almost 2 block sizes in padding.
895
+ * If the `block_align` argument is 0, it inherits from the parent
896
+ * buffer block_size, or defaults to 1.
897
+ *
898
+ * The `align` argument must be set to respect the buffers internal
899
+ * alignment requirements, but if the buffer is smaller it will not be
900
+ * padded to isolate the buffer. For example a buffer of with
901
+ * `align = 64` and `size = 65` may share its last 64 byte block with
902
+ * other content, but not if `block_align = 64`.
903
+ *
904
+ * Because the ubyte size field is not, by default, part of the aligned
905
+ * buffer, significant space can be wasted if multiple blocks are added
906
+ * in sequence with a large block size.
907
+ *
908
+ * In most cases the distinction between the two alignments is not
909
+ * important, but it allows separate configuration of block internal
910
+ * alignment and block size, which can be important for auto-generated
911
+ * code that may know the alignment of the buffer, but not the users
912
+ * operational requirements.
913
+ *
914
+ * If the buffer is embedded without a parent buffer, it will simply
915
+ * emit the buffer through the emit interface, but may also add padding
916
+ * up to block alignment. At top-level there will be no size field
917
+ * header.
918
+ *
919
+ * If `with_size` flag is set, the buffer is aligned to size field and
920
+ * the above note about padding space no longer applies. The size field
921
+ * is added regardless. The `is_nested` flag has no effect since it is
922
+ * impplied.
923
+ */
924
+ flatcc_builder_ref_t flatcc_builder_embed_buffer(flatcc_builder_t *B,
925
+ uint16_t block_align,
926
+ const void *data, size_t size, uint16_t align, int flags);
927
+
928
+ /**
929
+ * Applies to the innermost open buffer. The identifier may be null or
930
+ * contain all zero. Overrides any identifier given to the start buffer
931
+ * call.
932
+ */
933
+ void flatcc_builder_set_identifier(flatcc_builder_t *B,
934
+ const char identifier[FLATBUFFERS_IDENTIFIER_SIZE]);
935
+
936
+ enum flatcc_builder_type {
937
+ flatcc_builder_empty = 0,
938
+ flatcc_builder_buffer,
939
+ flatcc_builder_struct,
940
+ flatcc_builder_table,
941
+ flatcc_builder_vector,
942
+ flatcc_builder_offset_vector,
943
+ flatcc_builder_string,
944
+ flatcc_builder_union_vector
945
+ };
946
+
947
+ /**
948
+ * Returns the object type currently on the stack, for example if
949
+ * needing to decide how to close a buffer. Because a table is
950
+ * automatically added when starting a table buffer,
951
+ * `flatcc_builder_table_buffer` should not normally be seen and the level
952
+ * should be 2 before when closing a top-level table buffer, and 0
953
+ * after. A `flatcc_builder_struct_buffer` will be visible at level 1.
954
+ *
955
+ */
956
+ enum flatcc_builder_type flatcc_builder_get_type(flatcc_builder_t *B);
957
+
958
+ /**
959
+ * Similar to `get_type` but for a specific level. `get_type_at(B, 1)`
960
+ * will return `flatcc_builder_table_buffer` if this is the root buffer
961
+ * type. get_type_at(B, 0) is always `flatcc_builder_empty` and so are any
962
+ * level above `get_level`.
963
+ */
964
+ enum flatcc_builder_type flatcc_builder_get_type_at(flatcc_builder_t *B, int level);
965
+
966
+ /**
967
+ * The user stack is available for custom data. It may be used as
968
+ * a simple stack by extending or reducing the inner-most frame.
969
+ *
970
+ * A frame has a size and a location on the user stack. Entering
971
+ * a frame ensures the start is aligned to sizeof(size_t) and
972
+ * ensures the requested space is available without reallocation.
973
+ * When exiting a frame, the previous frame is restored.
974
+ *
975
+ * A user frame works completely independently of the builders
976
+ * frame stack for tracking tables vectors etc. and does not have
977
+ * to be completely at exit, but obviously it is not valid to
978
+ * exit more often the entered.
979
+ *
980
+ * The frame is zeroed when entered.
981
+ *
982
+ * Returns a non-zero handle to the user frame upon success or
983
+ * 0 on allocation failure.
984
+ */
985
+ size_t flatcc_builder_enter_user_frame(flatcc_builder_t *B, size_t size);
986
+
987
+ /**
988
+ * Makes the parent user frame current, if any. It is not valid to call
989
+ * if there isn't any current frame. Returns handle to parent frame if
990
+ * any, or 0.
991
+ */
992
+ size_t flatcc_builder_exit_user_frame(flatcc_builder_t *B);
993
+
994
+ /**
995
+ * Exits the frame represented by the given handle. All more
996
+ * recently entered frames will also be exited. Returns the parent
997
+ * frame handle if any, or 0.
998
+ */
999
+ size_t flatcc_builder_exit_user_frame_at(flatcc_builder_t *B, size_t handle);
1000
+
1001
+ /**
1002
+ * Returns a non-zero handle to the current inner-most user frame if
1003
+ * any, or 0.
1004
+ */
1005
+ size_t flatcc_builder_get_current_user_frame(flatcc_builder_t *B);
1006
+
1007
+ /*
1008
+ * Returns a pointer to the user frame at the given handle. Any active
1009
+ * frame can be accessed in this manner but the pointer is invalidated
1010
+ * by user frame enter and exit operations.
1011
+ */
1012
+ void *flatcc_builder_get_user_frame_ptr(flatcc_builder_t *B, size_t handle);
1013
+
1014
+ /**
1015
+ * Returns the size of the buffer and the logical start and end address
1016
+ * of with respect to the emitters address range. `end` - `start` also
1017
+ * yields the size. During construction `size` is the emitted number of
1018
+ * bytes and after buffer close it is the actual buffer size - by then
1019
+ * the start is also the return value of close buffer. End marks the end
1020
+ * of the virtual table cluster block.
1021
+ *
1022
+ * NOTE: there is no guarantee that all vtables end up in the cluster
1023
+ * block if there is placed a limit on the vtable size, or if nested
1024
+ * buffers are being used. On the other hand, if these conditions are
1025
+ * met, it is guaranteed that all vtables are present if the vtable
1026
+ * block is available (this depends on external transmission - the
1027
+ * vtables are always emitted before tables using them). In all cases
1028
+ * the vtables will behave as valid vtables in a flatbuffer.
1029
+ */
1030
+ size_t flatcc_builder_get_buffer_size(flatcc_builder_t *B);
1031
+
1032
+ /**
1033
+ * Returns the reference to the start of the emitter buffer so far, or
1034
+ * in total after buffer end, in the virtual address range used
1035
+ * by the emitter. Start is also returned by buffer end.
1036
+ */
1037
+ flatcc_builder_ref_t flatcc_builder_get_buffer_start(flatcc_builder_t *B);
1038
+
1039
+ /**
1040
+ * Returns the reference to the end of buffer emitted so far. When
1041
+ * clustering vtables, this is the end of tables, or after buffer end,
1042
+ * also zero padding if block aligned. If clustering is disabled, this
1043
+ * method will return 0 as the buffer only grows down then.
1044
+ */
1045
+ flatcc_builder_ref_t flatcc_builder_get_buffer_mark(flatcc_builder_t *B);
1046
+
1047
+ /**
1048
+ * Creates the vtable in the current buffer context, somewhat similar to
1049
+ * how create_vector operates. Each call results in a new table even if
1050
+ * an identical has already been emitted.
1051
+ *
1052
+ * Also consider `create_cached_vtable` which will reuse existing
1053
+ * vtables.
1054
+ *
1055
+ * This is low-low-level function intended to support
1056
+ * `create_cached_vtable` or equivalent, and `create_table`, both of
1057
+ * which are normally used indirectly via `start_table`, `table_add`,
1058
+ * `table_add_offset`..., `table_end`.
1059
+ *
1060
+ * Creates a vtable as a verbatim copy. This means the vtable must
1061
+ * include the header fields containing the vtable size and the table
1062
+ * size in little endian voffset_t encoding followed by the vtable
1063
+ * entries in same encoding.
1064
+ *
1065
+ * The function may be used to copy vtables from other other buffers
1066
+ * since they are directly transferable.
1067
+ *
1068
+ * The returned reference is actually the emitted location + 1. This
1069
+ * ensures the vtable is not mistaken for error because 0 is a valid
1070
+ * vtable reference. `create_table` is aware of this and substracts one
1071
+ * before computing the final offset relative to the table. This also
1072
+ * means vtable references are uniquely identifiable by having the
1073
+ * lowest bit set.
1074
+ *
1075
+ * vtable references may be reused within the same buffer, not any
1076
+ * parent or other related buffer (technically this is possible though,
1077
+ * as long as it is within same builder context, but it will not construct
1078
+ * valid FlatBuffers because the buffer cannot be extracted in isolation).
1079
+ */
1080
+ flatcc_builder_vt_ref_t flatcc_builder_create_vtable(flatcc_builder_t *B,
1081
+ const flatbuffers_voffset_t *vt,
1082
+ flatbuffers_voffset_t vt_size);
1083
+
1084
+ /**
1085
+ * Support function to `create_vtable`. See also the uncached version
1086
+ * `create_vtable`.
1087
+ *
1088
+ * Looks up the constructed vtable on the vs stack too see if it matches
1089
+ * a cached entry. If not, it emits a new vtable either at the end if
1090
+ * top-level and clustering is enabled, or at the front (always for
1091
+ * nested buffers).
1092
+ *
1093
+ * If the same vtable was already emitted in a different buffer, but not
1094
+ * in the current buffer, the cache entry will be reused, but a new
1095
+ * table will be emitted the first it happens in the same table.
1096
+ *
1097
+ * The returned reference is + 1 relative to the emitted address range
1098
+ * to identify it as a vtable and to avoid mistaking the valid 0
1099
+ * reference for an error (clustered vtables tend to start at the end at
1100
+ * the virtual address 0, and up).
1101
+ *
1102
+ * The hash function can be chosen arbitrarily but may result in
1103
+ * duplicate emitted vtables if different hash functions are being used
1104
+ * concurrently, such as mixing the default used by `start/end table`
1105
+ * with a custom function (this is not incorrect, it only increases the
1106
+ * buffer size and cache pressure).
1107
+ *
1108
+ * If a vtable has a unique ID by other means than hashing the content,
1109
+ * such as an integer id, and offset into another buffer, or a pointer,
1110
+ * a good hash may be multiplication by a 32-bit prime number. The hash
1111
+ * table is not very sensitive to collissions as it uses externally
1112
+ * chained hashing with move to front semantics.
1113
+ */
1114
+ flatcc_builder_vt_ref_t flatcc_builder_create_cached_vtable(flatcc_builder_t *B,
1115
+ const flatbuffers_voffset_t *vt,
1116
+ flatbuffers_voffset_t vt_size, uint32_t vt_hash);
1117
+
1118
+ /*
1119
+ * Based on Knuth's prime multiplier.
1120
+ *
1121
+ * This is an incremental hash that is called with id and size of each
1122
+ * non-empty field, and finally with the two vtable header fields
1123
+ * when vtables are constructed via `table_add/table_add_offset`.
1124
+ *
1125
+ */
1126
+ #ifndef FLATCC_SLOW_MUL
1127
+ #ifndef FLATCC_BUILDER_INIT_VT_HASH
1128
+ #define FLATCC_BUILDER_INIT_VT_HASH(hash) { (hash) = (uint32_t)0x2f693b52UL; }
1129
+ #endif
1130
+ #ifndef FLATCC_BUILDER_UPDATE_VT_HASH
1131
+ #define FLATCC_BUILDER_UPDATE_VT_HASH(hash, id, offset) \
1132
+ { (hash) = (((((uint32_t)id ^ (hash)) * (uint32_t)2654435761UL)\
1133
+ ^ (uint32_t)(offset)) * (uint32_t)2654435761UL); }
1134
+ #endif
1135
+ #ifndef FLATCC_BUILDER_BUCKET_VT_HASH
1136
+ #define FLATCC_BUILDER_BUCKET_VT_HASH(hash, width) (((uint32_t)(hash)) >> (32 - (width)))
1137
+ #endif
1138
+ #endif
1139
+
1140
+ /*
1141
+ * By default we use Bernsteins hash as fallback if multiplication is slow.
1142
+ *
1143
+ * This just have to be simple, fast, and work on devices without fast
1144
+ * multiplication. We are not too sensitive to collisions. Feel free to
1145
+ * experiment and replace.
1146
+ */
1147
+ #ifndef FLATCC_BUILDER_INIT_VT_HASH
1148
+ #define FLATCC_BUILDER_INIT_VT_HASH(hash) { (hash) = 5381; }
1149
+ #endif
1150
+ #ifndef FLATCC_BUILDER_UPDATE_VT_HASH
1151
+ #define FLATCC_BUILDER_UPDATE_VT_HASH(hash, id, offset) \
1152
+ { (hash) = ((((hash) << 5) ^ (id)) << 5) ^ (offset); }
1153
+ #endif
1154
+ #ifndef FLATCC_BUILDER_BUCKET_VT_HASH
1155
+ #define FLATCC_BUILDER_BUCKET_VT_HASH(hash, width) (((1 << (width)) - 1) & (hash))
1156
+ #endif
1157
+
1158
+
1159
+
1160
+ /**
1161
+ * Normally use `start_table` instead of this call.
1162
+ *
1163
+ * This is a low-level call only intended for high-performance
1164
+ * applications that repeatedly churn about similar tables of known
1165
+ * layout, or as a support layer for other builders that maintain their
1166
+ * own allocation rather than using the stack of this builder.
1167
+ *
1168
+ * Creates a table from an already emitted vtable, actual data that is
1169
+ * properly aligned relative to data start and in little endian
1170
+ * encoding. Unlike structs, tables can have offset fields. These must
1171
+ * be stored as flatcc_builder_ref_t types (which have uoffset_t size) as
1172
+ * returned by the api in native encoding. The `offsets` table contain
1173
+ * voffsets relative to `data` start (this is different from how vtables
1174
+ * store offsets because they are relative to a table header). The
1175
+ * `offsets` table is only used temporarily to translate the stored
1176
+ * references and is not part of final buffer content. `offsets` may be
1177
+ * null if `offset_count` is 0. `align` should be the highest aligned
1178
+ * field in the table, but `size` need not be a multiple of `align`.
1179
+ * Aside from endian encoding, the vtable must record a table size equal
1180
+ * to `size + sizeof(flatbuffers_uoffset_t)` because it includes the
1181
+ * table header field size. The vtable is not accessed by this call (nor
1182
+ * is it available). Unlike other references, the vtable reference may
1183
+ * be shared between tables in the same buffer (not with any related
1184
+ * buffer such as a parent buffer).
1185
+ *
1186
+ * The operation will not use any allocation, but will update the
1187
+ * alignment of the containing buffer if any.
1188
+ *
1189
+ * Note: unlike other create calls, except `create_offset_vector`,
1190
+ * the source data is modified in order to translate references intok
1191
+ * offsets before emitting the table.
1192
+ */
1193
+ flatcc_builder_ref_t flatcc_builder_create_table(flatcc_builder_t *B,
1194
+ const void *data, size_t size, uint16_t align,
1195
+ flatbuffers_voffset_t *offsets, int offset_count,
1196
+ flatcc_builder_vt_ref_t vt_ref);
1197
+
1198
+ /**
1199
+ * Starts a table, typically following a start_buffer call as an
1200
+ * alternative to starting a struct, or to create table fields to be
1201
+ * stored in a parent table, or in an offset vector.
1202
+ * A number of `table_add` and table_add_offset` call may be placed
1203
+ * before the `end_table` call. Struct fields should NOT use `struct`
1204
+ * related call (because table structs are in-place), rather they should
1205
+ * use the `table_add` call with the appropriate size and alignment.
1206
+ *
1207
+ * A table, like other reference returning calls, may also be started
1208
+ * outside a buffer if the buffer header and alignment is of no
1209
+ * interest to the application, for example as part of an externally
1210
+ * built buffer.
1211
+ *
1212
+ * `count` must be larger than the largest id used for this table
1213
+ * instance. Normally it is set to the number of fields defined in the
1214
+ * schema, but it may be less if memory is constrained and only few
1215
+ * fields with low valued id's are in use. The count can extended later
1216
+ * with `reserve_table` if necessary. `count` may be also be set to a
1217
+ * large enough value such as FLATBUFFERS_ID_MAX + 1 if memory is not a
1218
+ * concern (reserves about twice the maximum vtable size to track the
1219
+ * current vtable and voffsets where references must be translated to
1220
+ * offsets at table end). `count` may be zero if for example
1221
+ * `reserve_table` is being used.
1222
+ *
1223
+ * Returns -1 on error, 0 on success.
1224
+ */
1225
+ int flatcc_builder_start_table(flatcc_builder_t *B, int count);
1226
+
1227
+ /**
1228
+ * Call before adding a field with an id that is not below the count set
1229
+ * at table start. Not needed in most cases. For performance reasons
1230
+ * the builder does not check all bounds all the the time, but the user
1231
+ * can do so if memory constraints prevent start_table from using a
1232
+ * conservative value. See also `table_start`.
1233
+ *
1234
+ * Note: this call has absolutely no effect on the table layout, it just
1235
+ * prevents internal buffer overruns.
1236
+ *
1237
+ * Returns -1 on error, 0 on success.
1238
+ */
1239
+ int flatcc_builder_reserve_table(flatcc_builder_t *B, int count);
1240
+
1241
+ /**
1242
+ * Completes the table constructed on the internal stack including
1243
+ * emitting a vtable, or finding a matching vtable that has already been
1244
+ * emitted to the same buffer. (Vtables cannot be shared between
1245
+ * buffers, but they can between tables of the same buffer).
1246
+ *
1247
+ * Note: there is a considerable, but necessary, amount of bookkeeping
1248
+ * involved in constructing tables. The `create_table` call is much
1249
+ * faster, but it also expects a lot of work to be done already.
1250
+ *
1251
+ * Tables can be created with no fields added. This will result in an
1252
+ * empty vtable and a table with just a vtable reference. If a table is
1253
+ * used as a sub-table, such a table might also not be stored at all,
1254
+ * but we do not return a special reference for that, nor do we provide
1255
+ * and option to not create the table in this case. This may be
1256
+ * interpreted as the difference between a null table (not stored in
1257
+ * parent), and an empty table with a unique offset (and thus identity)
1258
+ * different from other empty tables.
1259
+ */
1260
+ flatcc_builder_ref_t flatcc_builder_end_table(flatcc_builder_t *B);
1261
+
1262
+ /**
1263
+ * Optionally this method can be called just before `flatcc_builder_end_table`
1264
+ * to verify that all required fields have been set.
1265
+ * Each entry is a table field id.
1266
+ *
1267
+ * Union fields should use the type field when checking for presence and
1268
+ * may also want to check the soundness of the union field overall using
1269
+ * `check_union_field` with the id one higher than the type field id.
1270
+ *
1271
+ * This funcion is typically called by an assertion in generated builder
1272
+ * interfaces while release builds may want to avoid this performance
1273
+ * overhead.
1274
+ *
1275
+ * Returns 1 if all fields are matched, 0 otherwise.
1276
+ */
1277
+ int flatcc_builder_check_required(flatcc_builder_t *B, const flatbuffers_voffset_t *required, int count);
1278
+
1279
+ /**
1280
+ * Same as `check_required` when called with a single element.
1281
+ *
1282
+ * Typically used when direct calls are more convenient than building an
1283
+ * array first. Useful when dealing with untrusted intput such as parsed
1284
+ * text from an external source.
1285
+ */
1286
+ int flatcc_builder_check_required_field(flatcc_builder_t *B, flatbuffers_voffset_t id);
1287
+
1288
+ /**
1289
+ * Checks that a union field is valid.
1290
+ *
1291
+ * The criteria is:
1292
+ *
1293
+ * If the type field is not present (at id - 1), or it holds a zero value,
1294
+ * then the table field (at id) must be present.
1295
+ *
1296
+ * Generated builder code may be able to enforce valid unions without
1297
+ * this check by setting both type and table together, but e.g. parsers
1298
+ * may receive the type and the table independently and then it makes
1299
+ * sense to validate the union fields before table completion.
1300
+ *
1301
+ * Note that an absent union field is perfectly valid. If a union is
1302
+ * required, the type field (id - 1), should be checked separately
1303
+ * while the table field should only be checked here because it can
1304
+ * (and must) be absent when the type is NONE (= 0).
1305
+ */
1306
+ int flatcc_builder_check_union_field(flatcc_builder_t *B, flatbuffers_voffset_t id);
1307
+
1308
+ /**
1309
+ * A struct, enum or scalar added should be stored in little endian in
1310
+ * the return pointer location. The pointer is short lived and will
1311
+ * not necessarily survive other builder calls.
1312
+ *
1313
+ * A union type field can also be set using this call. In fact, this is
1314
+ * the only way to deal with unions via this API. Consequently, it is
1315
+ * the users repsonsibility to ensure the appropriate type is added
1316
+ * at the next higher id.
1317
+ *
1318
+ * Null and default values:
1319
+ *
1320
+ * FlatBuffers does not officially provide an option for null values
1321
+ * because it does not distinguish between default values and values
1322
+ * that are not present. At this api level, we do not deal with defaults
1323
+ * at all. Callee should test the stored value against the default value
1324
+ * and only add the field if it does not match the default. This only
1325
+ * applies to scalar and enum values. Structs cannot have defaults so
1326
+ * their absence means null, and strings, vectors and subtables do have
1327
+ * natural null values different from the empty object and empty objects
1328
+ * with different identity is also possible.
1329
+ *
1330
+ * To handle Null for scalars, the following approach is recommended:
1331
+ *
1332
+ * Provide a schema-specific `add` operation that only calls this
1333
+ * low-level add method if the default does not match, and also provide
1334
+ * another `set` operation that always stores the value, regardless of
1335
+ * default. For most readers this will be transparent, except for extra
1336
+ * space used, but for Null aware readers, these can support operations
1337
+ * to test for Null/default/other value while still supporting the
1338
+ * normal read operation that returns default when a value is absent
1339
+ * (i.e. Null).
1340
+ *
1341
+ * It is valid to call with a size of 0 - the effect being adding the
1342
+ * vtable entry. The call may also be dropped in this case to reduce
1343
+ * the vtable size - the difference will be in null detection.
1344
+ */
1345
+ void *flatcc_builder_table_add(flatcc_builder_t *B, int id, size_t size, uint16_t align);
1346
+
1347
+ /**
1348
+ * Returns a pointer to the buffer holding the last field added. The
1349
+ * size argument must match the field size added. May, for example, be
1350
+ * used to perform endian conversion after initially updating field
1351
+ * as a native struct. Must be called before the table is ended.
1352
+ */
1353
+ void *flatcc_builder_table_edit(flatcc_builder_t *B, size_t size);
1354
+
1355
+ /**
1356
+ * Similar to `table_add` but copies source data into the buffer before
1357
+ * it is returned. Useful when adding a larger struct already encoded in
1358
+ * little endian.
1359
+ */
1360
+ void *flatcc_builder_table_add_copy(flatcc_builder_t *B, int id, const void *data, size_t size, uint16_t align);
1361
+
1362
+ /**
1363
+ * Add a string, vector, or sub-table depending on the type if the
1364
+ * field identifier. The offset ref obtained when the field object was
1365
+ * closed should be stored as is in the given pointer. The pointer
1366
+ * is only valid short term, so create the object before calling
1367
+ * add to table, but the owner table can be started earlier. Never mix
1368
+ * refs from nested buffers with parent buffers.
1369
+ *
1370
+ * Also uses this method to add nested buffers. A nested buffer is
1371
+ * simple a buffer created while another buffer is open. The buffer
1372
+ * close operation provides the necessary reference.
1373
+ *
1374
+ * When the table closes, all references get converted into offsets.
1375
+ * Before that point, it is not required that the offset is written
1376
+ * to.
1377
+ */
1378
+ flatcc_builder_ref_t *flatcc_builder_table_add_offset(flatcc_builder_t *B, int id);
1379
+
1380
+ /*
1381
+ * Adds a union type and reference in a single operation and returns 0
1382
+ * on success. Stores the type field at `id - 1` and the value at
1383
+ * `id`. The `value` is a reference to a table, to a string, or to a
1384
+ * standalone `struct` outside the table.
1385
+ *
1386
+ * If the type is 0, the value field must also be 0.
1387
+ *
1388
+ * Unions can also be added as separate calls to the type and the offset
1389
+ * separately which can lead to better packing when the type is placed
1390
+ * together will other small fields.
1391
+ */
1392
+ int flatcc_builder_table_add_union(flatcc_builder_t *B, int id,
1393
+ flatcc_builder_union_ref_t uref);
1394
+
1395
+ /*
1396
+ * Adds a union type vector and value vector in a single operations
1397
+ * and returns 0 on success.
1398
+ *
1399
+ * If both the type and value vector is null, nothing is added.
1400
+ * Otherwise both must be present and have the same length.
1401
+ *
1402
+ * Any 0 entry in the type vector must also have a 0 entry in
1403
+ * the value vector.
1404
+ */
1405
+ int flatcc_builder_table_add_union_vector(flatcc_builder_t *B, int id,
1406
+ flatcc_builder_union_vec_ref_t uvref);
1407
+ /**
1408
+ * Creates a vector in a single operation using an externally supplied
1409
+ * buffer. This completely bypasses the stack, but the size must be
1410
+ * known and the content must be little endian. Do not use for strings
1411
+ * and offset vectors. Other flatbuffer vectors could be used as a
1412
+ * source, but the length prefix is not required.
1413
+ *
1414
+ * Set `max_count` to `FLATBUFFERS_COUNT_MAX(elem_size)` before a call
1415
+ * to any string or vector operation to the get maximum safe vector
1416
+ * size, or use (size_t)-1 if overflow is not a concern.
1417
+ *
1418
+ * The max count property is a global property that remains until
1419
+ * explicitly changed.
1420
+ *
1421
+ * `max_count` is to prevent malicous or accidental overflow which is
1422
+ * difficult to detect by multiplication alone, depending on the type
1423
+ * sizes being used and having `max_count` thus avoids a division for
1424
+ * every vector created. `max_count` does not guarantee a vector will
1425
+ * fit in an empty buffer, it just ensures the internal size checks do
1426
+ * not overflow. A safe, sane limit woud be max_count / 4 because that
1427
+ * is half the maximum buffer size that can realistically be
1428
+ * constructed, corresponding to a vector size of `UOFFSET_MAX / 4`
1429
+ * which can always hold the vector in 1GB excluding the size field when
1430
+ * sizeof(uoffset_t) = 4.
1431
+ */
1432
+ flatcc_builder_ref_t flatcc_builder_create_vector(flatcc_builder_t *B,
1433
+ const void *data, size_t count, size_t elem_size, uint16_t align, size_t max_count);
1434
+
1435
+ /**
1436
+ * Starts a vector on the stack.
1437
+ *
1438
+ * Do not use these calls for string or offset vectors, but do store
1439
+ * scalars, enums and structs, always in little endian encoding.
1440
+ *
1441
+ * Use `extend_vector` subsequently to add zero, one or more elements
1442
+ * at time.
1443
+ *
1444
+ * See `create_vector` for `max_count` argument (strings and offset
1445
+ * vectors have a fixed element size and does not need this argument).
1446
+ *
1447
+ * Returns 0 on success.
1448
+ */
1449
+ int flatcc_builder_start_vector(flatcc_builder_t *B, size_t elem_size,
1450
+ uint16_t align, size_t max_count);
1451
+
1452
+ /**
1453
+ * Emits the vector constructed on the stack by start_vector.
1454
+ *
1455
+ * The vector may be accessed in the emitted stream using the returned
1456
+ * reference, even if the containing buffer is still under construction.
1457
+ * This may be useful for sorting. This api does not support sorting
1458
+ * because offset vectors cannot read their references after emission,
1459
+ * and while plain vectors could be sorted, it has been chosen that this
1460
+ * task is better left as a separate processing step. Generated code can
1461
+ * provide sorting functions that work on final in-memory buffers.
1462
+ */
1463
+ flatcc_builder_ref_t flatcc_builder_end_vector(flatcc_builder_t *B);
1464
+
1465
+ /** Returns the number of elements currently on the stack. */
1466
+ size_t flatcc_builder_vector_count(flatcc_builder_t *B);
1467
+
1468
+ /**
1469
+ * Returns a pointer ot the first vector element on stack,
1470
+ * accessible up to the number of elements currently on stack.
1471
+ */
1472
+ void *flatcc_builder_vector_edit(flatcc_builder_t *B);
1473
+
1474
+ /**
1475
+ * Returns a zero initialized buffer to a new region of the vector which
1476
+ * is extended at the end. The buffer must be consumed before other api
1477
+ * calls that may affect the stack, including `extend_vector`.
1478
+ *
1479
+ * Do not use for strings, offset or union vectors. May be used for nested
1480
+ * buffers, but these have dedicated calls to provide better alignment.
1481
+ */
1482
+ void *flatcc_builder_extend_vector(flatcc_builder_t *B, size_t count);
1483
+
1484
+ /**
1485
+ * A specialized `vector_extend` that pushes a single element.
1486
+ *
1487
+ * Returns the buffer holding a modifiable copy of the added content,
1488
+ * or null on error. Note: for structs, care must be taken to ensure
1489
+ * the source has been zero padded. For this reason it may be better to
1490
+ * use extend(B, 1) and assign specific fields instead.
1491
+ */
1492
+ void *flatcc_builder_vector_push(flatcc_builder_t *B, const void *data);
1493
+
1494
+ /**
1495
+ * Pushes multiple elements at a time.
1496
+ *
1497
+ * Returns the buffer holding a modifiable copy of the added content,
1498
+ * or null on error.
1499
+ */
1500
+ void *flatcc_builder_append_vector(flatcc_builder_t *B, const void *data, size_t count);
1501
+
1502
+ /**
1503
+ * Removes elements already added to vector that has not been ended.
1504
+ * For example, a vector of parsed list may remove the trailing comma,
1505
+ * or the vector may simply overallocate to get some temporary working
1506
+ * space. The total vector size must never become negative.
1507
+ *
1508
+ * Returns -1 if the count as larger than current count, or 0 on success.
1509
+ */
1510
+ int flatcc_builder_truncate_vector(flatcc_builder_t *B, size_t count);
1511
+
1512
+ /*
1513
+ * Similar to `create_vector` but with references that get translated
1514
+ * into offsets. The references must, as usual, belong to the current
1515
+ * buffer. Strings, scalar and struct vectors can emit directly without
1516
+ * stack allocation, but offset vectors must translate the offsets
1517
+ * and therefore need the temporary space. Thus, this function is
1518
+ * roughly equivalent to to start, append, end offset vector.
1519
+ *
1520
+ * See also `flatcc_builder_create_offset_vector_direct`.
1521
+ */
1522
+ flatcc_builder_ref_t flatcc_builder_create_offset_vector(flatcc_builder_t *B,
1523
+ const flatcc_builder_ref_t *data, size_t count);
1524
+
1525
+ /*
1526
+ * NOTE: this call takes non-const source array of references
1527
+ * and destroys the content.
1528
+ *
1529
+ * This is a faster version of `create_offset_vector` where the
1530
+ * source references are destroyed. In return the vector can be
1531
+ * emitted directly without passing over the stack.
1532
+ */
1533
+ flatcc_builder_ref_t flatcc_builder_create_offset_vector_direct(flatcc_builder_t *B,
1534
+ flatcc_builder_ref_t *data, size_t count);
1535
+
1536
+
1537
+ /**
1538
+ * Starts a vector holding offsets to tables or strings. Before
1539
+ * completion it will hold `flatcc_builder_ref_t` references because the
1540
+ * offset is not known until the vector start location is known, which
1541
+ * depends to the final size, which for parsers is generally unknown.
1542
+ */
1543
+ int flatcc_builder_start_offset_vector(flatcc_builder_t *B);
1544
+
1545
+ /**
1546
+ * Similar to `end_vector` but updates all stored references so they
1547
+ * become offsets to the vector start.
1548
+ */
1549
+ flatcc_builder_ref_t flatcc_builder_end_offset_vector(flatcc_builder_t *B);
1550
+
1551
+ /**
1552
+ * Same as `flatcc_builder_end_offset_vector` except null references are
1553
+ * permitted when the corresponding `type` entry is 0 (the 'NONE' type).
1554
+ * This makes it possible to build union vectors with less overhead when
1555
+ * the `type` vector is already known. Use standand offset vector calls
1556
+ * prior to this call.
1557
+ */
1558
+ flatcc_builder_ref_t flatcc_builder_end_offset_vector_for_unions(flatcc_builder_t *B,
1559
+ const flatcc_builder_utype_t *type);
1560
+
1561
+ /** Returns the number of elements currently on the stack. */
1562
+ size_t flatcc_builder_offset_vector_count(flatcc_builder_t *B);
1563
+
1564
+ /**
1565
+ * Returns a pointer ot the first vector element on stack,
1566
+ * accessible up to the number of elements currently on stack.
1567
+ */
1568
+ void *flatcc_builder_offset_vector_edit(flatcc_builder_t *B);
1569
+
1570
+ /**
1571
+ * Similar to `extend_vector` but returns a buffer indexable as
1572
+ * `flatcc_builder_ref_t` array. All elements must be set to a valid
1573
+ * unique non-null reference, but truncate and extend may be used to
1574
+ * perform edits. Unused references will leave garbage in the buffer.
1575
+ * References should not originate from any other buffer than the
1576
+ * current, including parents and nested buffers. It is valid to reuse
1577
+ * references in DAG form when contained in the sammer, excluding any
1578
+ * nested, sibling or parent buffers.
1579
+ */
1580
+ flatcc_builder_ref_t *flatcc_builder_extend_offset_vector(flatcc_builder_t *B, size_t count);
1581
+
1582
+ /** Similar to truncate_vector. */
1583
+ int flatcc_builder_truncate_offset_vector(flatcc_builder_t *B, size_t count);
1584
+
1585
+ /**
1586
+ * A specialized extend that pushes a single element.
1587
+ *
1588
+ * Returns the buffer holding a modifiable copy of the added content,
1589
+ * or null on error.
1590
+ */
1591
+ flatcc_builder_ref_t *flatcc_builder_offset_vector_push(flatcc_builder_t *B,
1592
+ flatcc_builder_ref_t ref);
1593
+
1594
+ /**
1595
+ * Takes an array of refs as argument to do a multi push operation.
1596
+ *
1597
+ * Returns the buffer holding a modifiable copy of the added content,
1598
+ * or null on error.
1599
+ */
1600
+ flatcc_builder_ref_t *flatcc_builder_append_offset_vector(flatcc_builder_t *B,
1601
+ const flatcc_builder_ref_t *refs, size_t count);
1602
+
1603
+ /**
1604
+ * All union vector operations are like offset vector operations,
1605
+ * except they take a struct with a type and a reference rather than
1606
+ * just a reference. The finished union vector is returned as a struct
1607
+ * of two references, one for the type vector and one for the table offset
1608
+ * vector. Each reference goes to a separate table field where the type
1609
+ * offset vector id must be one larger than the type vector.
1610
+ */
1611
+
1612
+ /**
1613
+ * Creates a union vector which is in reality two vectors, a type vector
1614
+ * and an offset vector. Both vectors references are returned.
1615
+ */
1616
+ flatcc_builder_union_vec_ref_t flatcc_builder_create_union_vector(flatcc_builder_t *B,
1617
+ const flatcc_builder_union_ref_t *urefs, size_t count);
1618
+
1619
+ /*
1620
+ * NOTE: this call takes non-const source array of references
1621
+ * and destroys the content. The type array remains intact.
1622
+ *
1623
+ * This is a faster version of `create_union_vector` where the source
1624
+ * references are destroyed and where the types are given in a separate
1625
+ * array. In return the vector can be emitted directly without passing
1626
+ * over the stack.
1627
+ *
1628
+ * Unlike `create_offset_vector` we do allow null references but only if
1629
+ * the union type is NONE (0).
1630
+ */
1631
+ flatcc_builder_union_vec_ref_t flatcc_builder_create_union_vector_direct(flatcc_builder_t *B,
1632
+ const flatcc_builder_utype_t *types, flatcc_builder_ref_t *data, size_t count);
1633
+
1634
+ /*
1635
+ * Creates just the type vector part of a union vector. This is
1636
+ * similar to a normal `create_vector` call except that the size
1637
+ * and alignment are given implicitly. Can be used during
1638
+ * cloning or similar operations where the types are all given
1639
+ * but the values must be handled one by one as prescribed by
1640
+ * the type. The values can be added separately as an offset vector.
1641
+ */
1642
+ flatcc_builder_ref_t flatcc_builder_create_type_vector(flatcc_builder_t *B,
1643
+ const flatcc_builder_utype_t *types, size_t count);
1644
+
1645
+ /**
1646
+ * Starts a vector holding types and offsets to tables or strings. Before
1647
+ * completion it will hold `flatcc_builder_union_ref_t` references because the
1648
+ * offset is not known until the vector start location is known, which
1649
+ * depends to the final size, which for parsers is generally unknown,
1650
+ * and also because the union type must be separated out into a separate
1651
+ * vector. It would not be practicaly to push on two different vectors
1652
+ * during construction.
1653
+ */
1654
+ int flatcc_builder_start_union_vector(flatcc_builder_t *B);
1655
+
1656
+ /**
1657
+ * Similar to `end_vector` but updates all stored references so they
1658
+ * become offsets to the vector start and splits the union references
1659
+ * into a type vector and an offset vector.
1660
+ */
1661
+ flatcc_builder_union_vec_ref_t flatcc_builder_end_union_vector(flatcc_builder_t *B);
1662
+
1663
+ /** Returns the number of elements currently on the stack. */
1664
+ size_t flatcc_builder_union_vector_count(flatcc_builder_t *B);
1665
+
1666
+ /**
1667
+ * Returns a pointer ot the first vector element on stack,
1668
+ * accessible up to the number of elements currently on stack.
1669
+ */
1670
+ void *flatcc_builder_union_vector_edit(flatcc_builder_t *B);
1671
+
1672
+ /**
1673
+ * Similar to `extend_offset_vector` but returns a buffer indexable as a
1674
+ * `flatcc_builder_union_ref_t` array. All elements must be set to a valid
1675
+ * unique non-null reference with a valid union type to match, or it
1676
+ * must be null with a zero union type.
1677
+ */
1678
+ flatcc_builder_union_ref_t *flatcc_builder_extend_union_vector(flatcc_builder_t *B, size_t count);
1679
+
1680
+ /** Similar to truncate_vector. */
1681
+ int flatcc_builder_truncate_union_vector(flatcc_builder_t *B, size_t count);
1682
+
1683
+ /**
1684
+ * A specialized extend that pushes a single element.
1685
+ *
1686
+ * Returns the buffer holding a modifiable copy of the added content,
1687
+ * or null on error.
1688
+ */
1689
+ flatcc_builder_union_ref_t *flatcc_builder_union_vector_push(flatcc_builder_t *B,
1690
+ flatcc_builder_union_ref_t uref);
1691
+
1692
+ /**
1693
+ * Takes an array of union_refs as argument to do a multi push operation.
1694
+ *
1695
+ * Returns the buffer holding a modifiable copy of the added content,
1696
+ * or null on error.
1697
+ */
1698
+ flatcc_builder_union_ref_t *flatcc_builder_append_union_vector(flatcc_builder_t *B,
1699
+ const flatcc_builder_union_ref_t *urefs, size_t count);
1700
+
1701
+ /**
1702
+ * Faster string operation that avoids temporary stack storage. The
1703
+ * string is not required to be zero-terminated, but is expected
1704
+ * (unchecked) to be utf-8. Embedded zeroes would be allowed but
1705
+ * ubyte vectors should be used for that. The resulting string will
1706
+ * have a zero termination added, not included in length.
1707
+ */
1708
+ flatcc_builder_ref_t flatcc_builder_create_string(flatcc_builder_t *B,
1709
+ const char *s, size_t len);
1710
+
1711
+ /** `create_string` up to zero termination of source. */
1712
+ flatcc_builder_ref_t flatcc_builder_create_string_str(flatcc_builder_t *B,
1713
+ const char *s);
1714
+
1715
+ /**
1716
+ * `create_string` up to zero termination or at most max_len of source.
1717
+ *
1718
+ * Note that like `strncpy` it will include `max_len` characters if
1719
+ * the source is longer than `max_len`, but unlike `strncpy` it will
1720
+ * always add zero termination.
1721
+ */
1722
+ flatcc_builder_ref_t flatcc_builder_create_string_strn(flatcc_builder_t *B, const char *s, size_t max_len);
1723
+
1724
+ /**
1725
+ * Starts an empty string that can be extended subsequently.
1726
+ *
1727
+ * While the string is being created, it is guaranteed that there is
1728
+ * always a null character after the end of the current string length.
1729
+ * This also holds after `extend` and `append` operations. It is not
1730
+ * allowed to modify the null character.
1731
+ *
1732
+ * Returns 0 on success.
1733
+ */
1734
+ int flatcc_builder_start_string(flatcc_builder_t *B);
1735
+
1736
+ /**
1737
+ * Similar to `extend_vector` except for the buffer return type and a
1738
+ * slight speed advantage. Strings are expected to contain utf-8 content
1739
+ * but this isn't verified, and null characters would be accepted. The
1740
+ * length is given in bytes.
1741
+ *
1742
+ * Appending too much, then truncating can be used to trim string
1743
+ * escapes during parsing, or convert between unicode formats etc.
1744
+ */
1745
+ char *flatcc_builder_extend_string(flatcc_builder_t *B, size_t len);
1746
+
1747
+ /**
1748
+ * Concatenes a length of string. If the string contains zeroes (which
1749
+ * it formally shouldn't), they will be copied in.
1750
+ *
1751
+ * Returns the buffer holding a modifiable copy of the added content,
1752
+ * or null on error.
1753
+ */
1754
+ char *flatcc_builder_append_string(flatcc_builder_t *B, const char *s, size_t len);
1755
+
1756
+ /** `append_string` up to zero termination of source. */
1757
+ char *flatcc_builder_append_string_str(flatcc_builder_t *B, const char *s);
1758
+
1759
+ /** `append_string` up zero termination or at most max_len of source. */
1760
+ char *flatcc_builder_append_string_strn(flatcc_builder_t *B, const char *s, size_t max_len);
1761
+
1762
+ /**
1763
+ * Similar to `truncate_vector` available for consistency and a slight
1764
+ * speed advantage. Reduces string by `len` bytes - it does not set
1765
+ * the length. The resulting length must not become negative. Zero
1766
+ * termination is not counted.
1767
+ *
1768
+ * Returns -1 of the length becomes negative, 0 on success.
1769
+ */
1770
+ int flatcc_builder_truncate_string(flatcc_builder_t *B, size_t len);
1771
+
1772
+ /**
1773
+ * Similar to `end_vector` but adds a trailing zero not included
1774
+ * in the length. The trailing zero is added regardless of whatever
1775
+ * zero content may exist in the provided string (although it
1776
+ * formally should not contain any).
1777
+ */
1778
+ flatcc_builder_ref_t flatcc_builder_end_string(flatcc_builder_t *B);
1779
+
1780
+ /** Returns the length of string currently on the stack. */
1781
+ size_t flatcc_builder_string_len(flatcc_builder_t *B);
1782
+
1783
+ /**
1784
+ * Returns a ponter to the start of the string
1785
+ * accessible up the length of string currently on the stack.
1786
+ */
1787
+ char *flatcc_builder_string_edit(flatcc_builder_t *B);
1788
+
1789
+
1790
+ /*
1791
+ * Only for use with the default emitter.
1792
+ *
1793
+ * Fast acces to small buffers from default emitter.
1794
+ *
1795
+ * Only valid for default emitters before `flatcc_builder_clear`. The
1796
+ * return buffer is not valid after a call to `flatcc_builder_reset` or
1797
+ * `flatcc_builder_clear`.
1798
+ *
1799
+ * Returns null if the buffer size is too large to a have a linear
1800
+ * memory representation or if the emitter is not the default. A valid
1801
+ * size is between half and a full emitter page size depending on vtable
1802
+ * content.
1803
+ *
1804
+ * Non-default emitters must be accessed by means specific to the
1805
+ * particular emitter.
1806
+ *
1807
+ * If `size_out` is not null, it is set to the buffer size, or 0 if
1808
+ * operation failed.
1809
+ *
1810
+ * The returned buffer should NOT be deallocated explicitly.
1811
+ *
1812
+ * The buffer size is the size reported by `flatcc_builder_get_buffer_size`.
1813
+ */
1814
+ void *flatcc_builder_get_direct_buffer(flatcc_builder_t *B, size_t *size_out);
1815
+
1816
+ /*
1817
+ * Only for use with the default emitter.
1818
+ *
1819
+ * Default finalizer that allocates a buffer from the default emitter.
1820
+ *
1821
+ * Returns null if memory could not be allocated or if the emitter is
1822
+ * not the default. This is just a convenience method - there are many
1823
+ * other possible ways to extract the result of the emitter depending on
1824
+ * use case.
1825
+ *
1826
+ * If `size_out` is not null, it is set to the buffer size, or 0 if
1827
+ * operation failed.
1828
+ *
1829
+ * The allocated buffer is aligned according to malloc which may not be
1830
+ * sufficient in advanced cases - for that purpose
1831
+ * `flatcc_builder_finalize_aligned_buffer` may be used.
1832
+ *
1833
+ * It may be worth calling `flatcc_builder_get_direct_buffer` first to see
1834
+ * if the buffer is small enough to avoid copying.
1835
+ *
1836
+ * The returned buffer must be deallocated using `free`.
1837
+ */
1838
+ void *flatcc_builder_finalize_buffer(flatcc_builder_t *B, size_t *size_out);
1839
+
1840
+ /*
1841
+ * Only for use with the default emitter.
1842
+ *
1843
+ * Similar to `flatcc_builder_finalize_buffer` but ensures the returned
1844
+ * memory is aligned to the overall alignment required for the buffer.
1845
+ * Often it is not necessary unless special operations rely on larger
1846
+ * alignments than the stored scalars.
1847
+ *
1848
+ * If `size_out` is not null, it is set to the buffer size, or 0 if
1849
+ * operation failed.
1850
+ *
1851
+ * The returned buffer must be deallocated using `aligned_free` which is
1852
+ * implemented via `flatcc_flatbuffers.h`. `free` will usually work but
1853
+ * is not portable to platforms without posix_memalign or C11
1854
+ * aligned_alloc support.
1855
+ *
1856
+ * NOTE: if a library might be compiled with a version of aligned_free
1857
+ * that differs from the application using it, use
1858
+ * `flatcc_builder_aligned_free` to make sure the correct deallocation
1859
+ * function is used.
1860
+ */
1861
+ void *flatcc_builder_finalize_aligned_buffer(flatcc_builder_t *B, size_t *size_out);
1862
+
1863
+ /*
1864
+ * A stable implementation of `aligned_alloc` that is not sensitive
1865
+ * to the applications compile time flags.
1866
+ */
1867
+ void *flatcc_builder_aligned_alloc(size_t alignment, size_t size);
1868
+
1869
+ /*
1870
+ * A stable implementation of `aligned_free` that is not sensitive
1871
+ * to the applications compile time flags.
1872
+ */
1873
+ void flatcc_builder_aligned_free(void *p);
1874
+
1875
+ /*
1876
+ * Same allocation as `flatcc_builder_finalize_buffer` returnes. Usually
1877
+ * same as `malloc` but can redefined via macros.
1878
+ */
1879
+ void *flatcc_builder_alloc(size_t size);
1880
+
1881
+ /*
1882
+ * A stable implementation of `free` when the default allocation
1883
+ * methods have been redefined.
1884
+ *
1885
+ * Deallocates memory returned from `flatcc_builder_finalize_buffer`.
1886
+ */
1887
+ void flatcc_builder_free(void *p);
1888
+
1889
+ /*
1890
+ * Only for use with the default emitter.
1891
+ *
1892
+ * Convenience method to copy buffer from default emitter. Forwards
1893
+ * call to default emitter and returns input pointer, or null if
1894
+ * the emitter is not default or of the given size is smaller than
1895
+ * the buffer size.
1896
+ *
1897
+ * Note: the `size` argument is the target buffers capacity, not the
1898
+ * flatcc_builders buffer size.
1899
+ *
1900
+ * Other emitters have custom interfaces for reaching their content.
1901
+ */
1902
+ void *flatcc_builder_copy_buffer(flatcc_builder_t *B, void *buffer, size_t size);
1903
+
1904
+ #ifdef __cplusplus
1905
+ }
1906
+ #endif
1907
+
1908
+ #endif /* FLATCC_BUILDER_H */