ONE - On-device Neural Engine
Loading...
Searching...
No Matches
flatbuffers.h
Go to the documentation of this file.
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#include <algorithm>
21
22// TODO: These includes are for mitigating the pains of users editing their
23// source because they relied on flatbuffers.h to include everything for them.
24#include "flatbuffers/array.h"
25#include "flatbuffers/base.h"
26#include "flatbuffers/buffer.h"
31#include "flatbuffers/string.h"
32#include "flatbuffers/struct.h"
33#include "flatbuffers/table.h"
34#include "flatbuffers/vector.h"
37
38namespace flatbuffers {
39
44inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
45 auto table = reinterpret_cast<const Table *>(root);
46 auto vtable = table->GetVTable();
47 // Either the vtable is before the root or after the root.
48 auto start = (std::min)(vtable, reinterpret_cast<const uint8_t *>(root));
49 // Align to at least sizeof(uoffset_t).
50 start = reinterpret_cast<const uint8_t *>(reinterpret_cast<uintptr_t>(start) &
51 ~(sizeof(uoffset_t) - 1));
52 // Additionally, there may be a file_identifier in the buffer, and the root
53 // offset. The buffer may have been aligned to any size between
54 // sizeof(uoffset_t) and FLATBUFFERS_MAX_ALIGNMENT (see "force_align").
55 // Sadly, the exact alignment is only known when constructing the buffer,
56 // since it depends on the presence of values with said alignment properties.
57 // So instead, we simply look at the next uoffset_t values (root,
58 // file_identifier, and alignment padding) to see which points to the root.
59 // None of the other values can "impersonate" the root since they will either
60 // be 0 or four ASCII characters.
61 static_assert(flatbuffers::kFileIdentifierLength == sizeof(uoffset_t),
62 "file_identifier is assumed to be the same size as uoffset_t");
63 for (auto possible_roots = FLATBUFFERS_MAX_ALIGNMENT / sizeof(uoffset_t) + 1;
64 possible_roots; possible_roots--) {
65 start -= sizeof(uoffset_t);
66 if (ReadScalar<uoffset_t>(start) + start ==
67 reinterpret_cast<const uint8_t *>(root))
68 return start;
69 }
70 // We didn't find the root, either the "root" passed isn't really a root,
71 // or the buffer is corrupt.
72 // Assert, because calling this function with bad data may cause reads
73 // outside of buffer boundaries.
74 FLATBUFFERS_ASSERT(false);
75 return nullptr;
76}
77
79template<typename SizeT = uoffset_t>
80inline SizeT GetPrefixedSize(const uint8_t *buf) {
81 return ReadScalar<SizeT>(buf);
82}
83
84// Gets the total length of the buffer given a sized prefixed FlatBuffer.
85//
86// This includes the size of the prefix as well as the buffer:
87//
88// [size prefix][flatbuffer]
89// |---------length--------|
90template<typename SizeT = uoffset_t>
91inline SizeT GetSizePrefixedBufferLength(const uint8_t *const buf) {
92 return ReadScalar<SizeT>(buf) + sizeof(SizeT);
93}
94
95// Base class for native objects (FlatBuffer data de-serialized into native
96// C++ data structures).
97// Contains no functionality, purely documentative.
98struct NativeTable {};
99
108typedef uint64_t hash_value_t;
109typedef std::function<void(void **pointer_adr, hash_value_t hash)>
111typedef std::function<hash_value_t(void *pointer)> rehasher_function_t;
112
113// Helper function to test if a field is present, using any of the field
114// enums in the generated code.
115// `table` must be a generated table type. Since this is a template parameter,
116// this is not typechecked to be a subclass of Table, so beware!
117// Note: this function will return false for fields equal to the default
118// value, since they're not stored in the buffer (unless force_defaults was
119// used).
120template<typename T>
121bool IsFieldPresent(const T *table, typename T::FlatBuffersVTableOffset field) {
122 // Cast, since Table is a private baseclass of any table types.
123 return reinterpret_cast<const Table *>(table)->CheckField(
124 static_cast<voffset_t>(field));
125}
126
127// Utility function for reverse lookups on the EnumNames*() functions
128// (in the generated C++ code)
129// names must be NULL terminated.
130inline int LookupEnum(const char **names, const char *name) {
131 for (const char **p = names; *p; p++)
132 if (!strcmp(*p, name)) return static_cast<int>(p - names);
133 return -1;
134}
135
136// These macros allow us to layout a struct with a guarantee that they'll end
137// up looking the same on different compilers and platforms.
138// It does this by disallowing the compiler to do any padding, and then
139// does padding itself by inserting extra padding fields that make every
140// element aligned to its own size.
141// Additionally, it manually sets the alignment of the struct as a whole,
142// which is typically its largest element, or a custom size set in the schema
143// by the force_align attribute.
144// These are used in the generated code only.
145
146// clang-format off
147#if defined(_MSC_VER)
148 #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
149 __pragma(pack(1)) \
150 struct __declspec(align(alignment))
151 #define FLATBUFFERS_STRUCT_END(name, size) \
152 __pragma(pack()) \
153 static_assert(sizeof(name) == size, "compiler breaks packing rules")
154#elif defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
155 #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
156 _Pragma("pack(1)") \
157 struct __attribute__((aligned(alignment)))
158 #define FLATBUFFERS_STRUCT_END(name, size) \
159 _Pragma("pack()") \
160 static_assert(sizeof(name) == size, "compiler breaks packing rules")
161#else
162 #error Unknown compiler, please define structure alignment macros
163#endif
164// clang-format on
165
166// Minimal reflection via code generation.
167// Besides full-fat reflection (see reflection.h) and parsing/printing by
168// loading schemas (see idl.h), we can also have code generation for minimal
169// reflection data which allows pretty-printing and other uses without needing
170// a schema or a parser.
171// Generate code with --reflect-types (types only) or --reflect-names (names
172// also) to enable.
173// See minireflect.h for utilities using this functionality.
174
175// These types are organized slightly differently as the ones in idl.h.
177
178// Scalars have the same order as in idl.h
179// clang-format off
180#define FLATBUFFERS_GEN_ELEMENTARY_TYPES(ET) \
181 ET(ET_UTYPE) \
182 ET(ET_BOOL) \
183 ET(ET_CHAR) \
184 ET(ET_UCHAR) \
185 ET(ET_SHORT) \
186 ET(ET_USHORT) \
187 ET(ET_INT) \
188 ET(ET_UINT) \
189 ET(ET_LONG) \
190 ET(ET_ULONG) \
191 ET(ET_FLOAT) \
192 ET(ET_DOUBLE) \
193 ET(ET_STRING) \
194 ET(ET_SEQUENCE) // See SequenceType.
195
197 #define FLATBUFFERS_ET(E) E,
199 #undef FLATBUFFERS_ET
200};
201
202inline const char * const *ElementaryTypeNames() {
203 static const char * const names[] = {
204 #define FLATBUFFERS_ET(E) #E,
206 #undef FLATBUFFERS_ET
207 };
208 return names;
209}
210// clang-format on
211
212// Basic type info cost just 16bits per field!
213// We're explicitly defining the signedness since the signedness of integer
214// bitfields is otherwise implementation-defined and causes warnings on older
215// GCC compilers.
216struct TypeCode {
217 // ElementaryType
218 unsigned short base_type : 4;
219 // Either vector (in table) or array (in struct)
220 unsigned short is_repeating : 1;
221 // Index into type_refs below, or -1 for none.
222 signed short sequence_ref : 11;
223};
224
225static_assert(sizeof(TypeCode) == 2, "TypeCode");
226
227struct TypeTable;
228
229// Signature of the static method present in each type.
230typedef const TypeTable *(*TypeFunction)();
231
232struct TypeTable {
234 size_t num_elems; // of type_codes, values, names (but not type_refs).
235 const TypeCode *type_codes; // num_elems count
236 const TypeFunction *type_refs; // less than num_elems entries (see TypeCode).
237 const int16_t *array_sizes; // less than num_elems entries (see TypeCode).
238 const int64_t *values; // Only set for non-consecutive enum/union or structs.
239 const char *const *names; // Only set if compiled with --reflect-names.
240};
241
242// String which identifies the current version of FlatBuffers.
243inline const char *flatbuffers_version_string() {
244 return "FlatBuffers " FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "."
245 FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "."
246 FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
247}
248
249// clang-format off
250#define FLATBUFFERS_DEFINE_BITMASK_OPERATORS(E, T)\
251 inline E operator | (E lhs, E rhs){\
252 return E(T(lhs) | T(rhs));\
253 }\
254 inline E operator & (E lhs, E rhs){\
255 return E(T(lhs) & T(rhs));\
256 }\
257 inline E operator ^ (E lhs, E rhs){\
258 return E(T(lhs) ^ T(rhs));\
259 }\
260 inline E operator ~ (E lhs){\
261 return E(~T(lhs));\
262 }\
263 inline E operator |= (E &lhs, E rhs){\
264 lhs = lhs | rhs;\
265 return lhs;\
266 }\
267 inline E operator &= (E &lhs, E rhs){\
268 lhs = lhs & rhs;\
269 return lhs;\
270 }\
271 inline E operator ^= (E &lhs, E rhs){\
272 lhs = lhs ^ rhs;\
273 return lhs;\
274 }\
275 inline bool operator !(E rhs) \
276 {\
277 return !bool(T(rhs)); \
278 }
280} // namespace flatbuffers
281
282// clang-format on
283
284#endif // FLATBUFFERS_H_
#define FLATBUFFERS_ASSERT
Definition base.h:21
const uint8_t * GetVTable() const
Definition table.h:29
#define FLATBUFFERS_GEN_ELEMENTARY_TYPES(ET)
#define FLATBUFFERS_ET(E)
std::function< hash_value_t(void *pointer)> rehasher_function_t
const char *const * ElementaryTypeNames()
uint64_t hash_value_t
Function types to be used with resolving hashes into objects and back again. The resolver gets a poin...
const TypeTable *(* TypeFunction)()
bool IsFieldPresent(const T *table, typename T::FlatBuffersVTableOffset field)
SizeT GetPrefixedSize(const uint8_t *buf)
This return the prefixed size of a FlatBuffer.
Definition flatbuffers.h:80
int LookupEnum(const char **names, const char *name)
const uint8_t * GetBufferStartFromRootPointer(const void *root)
This can compute the start of a FlatBuffer from a root pointer, i.e. it is the opposite transformatio...
Definition flatbuffers.h:44
const char * flatbuffers_version_string()
std::function< void(void **pointer_adr, hash_value_t hash)> resolver_function_t
SizeT GetSizePrefixedBufferLength(const uint8_t *const buf)
Definition flatbuffers.h:91
Configuration p
signed short sequence_ref
unsigned short is_repeating
unsigned short base_type
const char *const * names
const int16_t * array_sizes
const int64_t * values
const TypeFunction * type_refs
const TypeCode * type_codes