/src/MapServer/src/flatgeobuf/include/flatbuffers/flatbuffers.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2014 Google Inc. All rights reserved. |
3 | | * |
4 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | * you may not use this file except in compliance with the License. |
6 | | * You may obtain a copy of the License at |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | |
17 | | #ifndef FLATBUFFERS_H_ |
18 | | #define FLATBUFFERS_H_ |
19 | | |
20 | | // TODO: These includes are for mitigating the pains of users editing their |
21 | | // source because they relied on flatbuffers.h to include everything for them. |
22 | | #include "flatbuffers/array.h" |
23 | | #include "flatbuffers/base.h" |
24 | | #include "flatbuffers/buffer.h" |
25 | | #include "flatbuffers/buffer_ref.h" |
26 | | #include "flatbuffers/detached_buffer.h" |
27 | | #include "flatbuffers/flatbuffer_builder.h" |
28 | | #include "flatbuffers/stl_emulation.h" |
29 | | #include "flatbuffers/string.h" |
30 | | #include "flatbuffers/struct.h" |
31 | | #include "flatbuffers/table.h" |
32 | | #include "flatbuffers/vector.h" |
33 | | #include "flatbuffers/vector_downward.h" |
34 | | #include "flatbuffers/verifier.h" |
35 | | |
36 | | namespace mapserver { |
37 | | namespace flatbuffers { |
38 | | |
39 | | /// @brief This can compute the start of a FlatBuffer from a root pointer, i.e. |
40 | | /// it is the opposite transformation of GetRoot(). |
41 | | /// This may be useful if you want to pass on a root and have the recipient |
42 | | /// delete the buffer afterwards. |
43 | 0 | inline const uint8_t *GetBufferStartFromRootPointer(const void *root) { |
44 | 0 | auto table = reinterpret_cast<const Table *>(root); |
45 | 0 | auto vtable = table->GetVTable(); |
46 | 0 | // Either the vtable is before the root or after the root. |
47 | 0 | auto start = (std::min)(vtable, reinterpret_cast<const uint8_t *>(root)); |
48 | 0 | // Align to at least sizeof(uoffset_t). |
49 | 0 | start = reinterpret_cast<const uint8_t *>(reinterpret_cast<uintptr_t>(start) & |
50 | 0 | ~(sizeof(uoffset_t) - 1)); |
51 | 0 | // Additionally, there may be a file_identifier in the buffer, and the root |
52 | 0 | // offset. The buffer may have been aligned to any size between |
53 | 0 | // sizeof(uoffset_t) and FLATBUFFERS_MAX_ALIGNMENT (see "force_align"). |
54 | 0 | // Sadly, the exact alignment is only known when constructing the buffer, |
55 | 0 | // since it depends on the presence of values with said alignment properties. |
56 | 0 | // So instead, we simply look at the next uoffset_t values (root, |
57 | 0 | // file_identifier, and alignment padding) to see which points to the root. |
58 | 0 | // None of the other values can "impersonate" the root since they will either |
59 | 0 | // be 0 or four ASCII characters. |
60 | 0 | static_assert(flatbuffers::kFileIdentifierLength == sizeof(uoffset_t), |
61 | 0 | "file_identifier is assumed to be the same size as uoffset_t"); |
62 | 0 | for (auto possible_roots = FLATBUFFERS_MAX_ALIGNMENT / sizeof(uoffset_t) + 1; |
63 | 0 | possible_roots; possible_roots--) { |
64 | 0 | start -= sizeof(uoffset_t); |
65 | 0 | if (ReadScalar<uoffset_t>(start) + start == |
66 | 0 | reinterpret_cast<const uint8_t *>(root)) |
67 | 0 | return start; |
68 | 0 | } |
69 | 0 | // We didn't find the root, either the "root" passed isn't really a root, |
70 | 0 | // or the buffer is corrupt. |
71 | 0 | // Assert, because calling this function with bad data may cause reads |
72 | 0 | // outside of buffer boundaries. |
73 | 0 | FLATBUFFERS_ASSERT(false); |
74 | 0 | return nullptr; |
75 | 0 | } |
76 | | |
77 | | /// @brief This return the prefixed size of a FlatBuffer. |
78 | 0 | inline uoffset_t GetPrefixedSize(const uint8_t *buf) { |
79 | 0 | return ReadScalar<uoffset_t>(buf); |
80 | 0 | } |
81 | | |
82 | | // Base class for native objects (FlatBuffer data de-serialized into native |
83 | | // C++ data structures). |
84 | | // Contains no functionality, purely documentative. |
85 | | struct NativeTable {}; |
86 | | |
87 | | /// @brief Function types to be used with resolving hashes into objects and |
88 | | /// back again. The resolver gets a pointer to a field inside an object API |
89 | | /// object that is of the type specified in the schema using the attribute |
90 | | /// `cpp_type` (it is thus important whatever you write to this address |
91 | | /// matches that type). The value of this field is initially null, so you |
92 | | /// may choose to implement a delayed binding lookup using this function |
93 | | /// if you wish. The resolver does the opposite lookup, for when the object |
94 | | /// is being serialized again. |
95 | | typedef uint64_t hash_value_t; |
96 | | typedef std::function<void(void **pointer_adr, hash_value_t hash)> |
97 | | resolver_function_t; |
98 | | typedef std::function<hash_value_t(void *pointer)> rehasher_function_t; |
99 | | |
100 | | // Helper function to test if a field is present, using any of the field |
101 | | // enums in the generated code. |
102 | | // `table` must be a generated table type. Since this is a template parameter, |
103 | | // this is not typechecked to be a subclass of Table, so beware! |
104 | | // Note: this function will return false for fields equal to the default |
105 | | // value, since they're not stored in the buffer (unless force_defaults was |
106 | | // used). |
107 | | template<typename T> |
108 | | bool IsFieldPresent(const T *table, typename T::FlatBuffersVTableOffset field) { |
109 | | // Cast, since Table is a private baseclass of any table types. |
110 | | return reinterpret_cast<const Table *>(table)->CheckField( |
111 | | static_cast<voffset_t>(field)); |
112 | | } |
113 | | |
114 | | // Utility function for reverse lookups on the EnumNames*() functions |
115 | | // (in the generated C++ code) |
116 | | // names must be NULL terminated. |
117 | 0 | inline int LookupEnum(const char **names, const char *name) { |
118 | 0 | for (const char **p = names; *p; p++) |
119 | 0 | if (!strcmp(*p, name)) return static_cast<int>(p - names); |
120 | 0 | return -1; |
121 | 0 | } |
122 | | |
123 | | // These macros allow us to layout a struct with a guarantee that they'll end |
124 | | // up looking the same on different compilers and platforms. |
125 | | // It does this by disallowing the compiler to do any padding, and then |
126 | | // does padding itself by inserting extra padding fields that make every |
127 | | // element aligned to its own size. |
128 | | // Additionally, it manually sets the alignment of the struct as a whole, |
129 | | // which is typically its largest element, or a custom size set in the schema |
130 | | // by the force_align attribute. |
131 | | // These are used in the generated code only. |
132 | | |
133 | | // clang-format off |
134 | | #if defined(_MSC_VER) |
135 | | #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \ |
136 | | __pragma(pack(1)) \ |
137 | | struct __declspec(align(alignment)) |
138 | | #define FLATBUFFERS_STRUCT_END(name, size) \ |
139 | | __pragma(pack()) \ |
140 | | static_assert(sizeof(name) == size, "compiler breaks packing rules") |
141 | | #elif defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__) |
142 | | #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \ |
143 | | _Pragma("pack(1)") \ |
144 | | struct __attribute__((aligned(alignment))) |
145 | | #define FLATBUFFERS_STRUCT_END(name, size) \ |
146 | | _Pragma("pack()") \ |
147 | | static_assert(sizeof(name) == size, "compiler breaks packing rules") |
148 | | #else |
149 | | #error Unknown compiler, please define structure alignment macros |
150 | | #endif |
151 | | // clang-format on |
152 | | |
153 | | // Minimal reflection via code generation. |
154 | | // Besides full-fat reflection (see reflection.h) and parsing/printing by |
155 | | // loading schemas (see idl.h), we can also have code generation for minimal |
156 | | // reflection data which allows pretty-printing and other uses without needing |
157 | | // a schema or a parser. |
158 | | // Generate code with --reflect-types (types only) or --reflect-names (names |
159 | | // also) to enable. |
160 | | // See minireflect.h for utilities using this functionality. |
161 | | |
162 | | // These types are organized slightly differently as the ones in idl.h. |
163 | | enum SequenceType { ST_TABLE, ST_STRUCT, ST_UNION, ST_ENUM }; |
164 | | |
165 | | // Scalars have the same order as in idl.h |
166 | | // clang-format off |
167 | | #define FLATBUFFERS_GEN_ELEMENTARY_TYPES(ET) \ |
168 | | ET(ET_UTYPE) \ |
169 | | ET(ET_BOOL) \ |
170 | | ET(ET_CHAR) \ |
171 | | ET(ET_UCHAR) \ |
172 | | ET(ET_SHORT) \ |
173 | | ET(ET_USHORT) \ |
174 | | ET(ET_INT) \ |
175 | | ET(ET_UINT) \ |
176 | | ET(ET_LONG) \ |
177 | | ET(ET_ULONG) \ |
178 | | ET(ET_FLOAT) \ |
179 | | ET(ET_DOUBLE) \ |
180 | | ET(ET_STRING) \ |
181 | | ET(ET_SEQUENCE) // See SequenceType. |
182 | | |
183 | | enum ElementaryType { |
184 | | #define FLATBUFFERS_ET(E) E, |
185 | | FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET) |
186 | | #undef FLATBUFFERS_ET |
187 | | }; |
188 | | |
189 | 0 | inline const char * const *ElementaryTypeNames() { |
190 | 0 | static const char * const names[] = { |
191 | 0 | #define FLATBUFFERS_ET(E) #E, |
192 | 0 | FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET) |
193 | 0 | #undef FLATBUFFERS_ET |
194 | 0 | }; |
195 | 0 | return names; |
196 | 0 | } |
197 | | // clang-format on |
198 | | |
199 | | // Basic type info cost just 16bits per field! |
200 | | // We're explicitly defining the signedness since the signedness of integer |
201 | | // bitfields is otherwise implementation-defined and causes warnings on older |
202 | | // GCC compilers. |
203 | | struct TypeCode { |
204 | | // ElementaryType |
205 | | unsigned short base_type : 4; |
206 | | // Either vector (in table) or array (in struct) |
207 | | unsigned short is_repeating : 1; |
208 | | // Index into type_refs below, or -1 for none. |
209 | | signed short sequence_ref : 11; |
210 | | }; |
211 | | |
212 | | static_assert(sizeof(TypeCode) == 2, "TypeCode"); |
213 | | |
214 | | struct TypeTable; |
215 | | |
216 | | // Signature of the static method present in each type. |
217 | | typedef const TypeTable *(*TypeFunction)(); |
218 | | |
219 | | struct TypeTable { |
220 | | SequenceType st; |
221 | | size_t num_elems; // of type_codes, values, names (but not type_refs). |
222 | | const TypeCode *type_codes; // num_elems count |
223 | | const TypeFunction *type_refs; // less than num_elems entries (see TypeCode). |
224 | | const int16_t *array_sizes; // less than num_elems entries (see TypeCode). |
225 | | const int64_t *values; // Only set for non-consecutive enum/union or structs. |
226 | | const char *const *names; // Only set if compiled with --reflect-names. |
227 | | }; |
228 | | |
229 | | // String which identifies the current version of FlatBuffers. |
230 | 0 | inline const char *flatbuffers_version_string() { |
231 | 0 | return "FlatBuffers " FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "." |
232 | 0 | FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "." |
233 | 0 | FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION); |
234 | 0 | } |
235 | | |
236 | | // clang-format off |
237 | | #define FLATBUFFERS_DEFINE_BITMASK_OPERATORS(E, T)\ |
238 | | inline E operator | (E lhs, E rhs){\ |
239 | | return E(T(lhs) | T(rhs));\ |
240 | | }\ |
241 | | inline E operator & (E lhs, E rhs){\ |
242 | | return E(T(lhs) & T(rhs));\ |
243 | | }\ |
244 | | inline E operator ^ (E lhs, E rhs){\ |
245 | | return E(T(lhs) ^ T(rhs));\ |
246 | | }\ |
247 | | inline E operator ~ (E lhs){\ |
248 | | return E(~T(lhs));\ |
249 | | }\ |
250 | | inline E operator |= (E &lhs, E rhs){\ |
251 | | lhs = lhs | rhs;\ |
252 | | return lhs;\ |
253 | | }\ |
254 | | inline E operator &= (E &lhs, E rhs){\ |
255 | | lhs = lhs & rhs;\ |
256 | | return lhs;\ |
257 | | }\ |
258 | | inline E operator ^= (E &lhs, E rhs){\ |
259 | | lhs = lhs ^ rhs;\ |
260 | | return lhs;\ |
261 | | }\ |
262 | | inline bool operator !(E rhs) \ |
263 | | {\ |
264 | | return !bool(T(rhs)); \ |
265 | | } |
266 | | /// @endcond |
267 | | } // namespace flatbuffers |
268 | | } // namespace mapserver |
269 | | |
270 | | // clang-format on |
271 | | |
272 | | #endif // FLATBUFFERS_H_ |