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