Coverage Report

Created: 2025-06-13 06:18

/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_