/src/gdal/ogr/ogrsf_frmts/flatgeobuf/flatbuffers/table.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2021 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_TABLE_H_ |
18 | | #define FLATBUFFERS_TABLE_H_ |
19 | | |
20 | | #include "flatbuffers/base.h" |
21 | | #include "flatbuffers/verifier.h" |
22 | | |
23 | | namespace flatbuffers { |
24 | | |
25 | | // "tables" use an offset table (possibly shared) that allows fields to be |
26 | | // omitted and added at will, but uses an extra indirection to read. |
27 | | class Table { |
28 | | public: |
29 | 1.00M | const uint8_t *GetVTable() const { |
30 | 1.00M | return data_ - ReadScalar<soffset_t>(data_); |
31 | 1.00M | } |
32 | | |
33 | | // This gets the field offset for any of the functions below it, or 0 |
34 | | // if the field was not present. |
35 | 1.00M | voffset_t GetOptionalFieldOffset(voffset_t field) const { |
36 | | // The vtable offset is always at the start. |
37 | 1.00M | auto vtable = GetVTable(); |
38 | | // The first element is the size of the vtable (fields + type id + itself). |
39 | 1.00M | auto vtsize = ReadScalar<voffset_t>(vtable); |
40 | | // If the field we're accessing is outside the vtable, we're reading older |
41 | | // data, so it's the same as if the offset was 0 (not present). |
42 | 1.00M | return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0; |
43 | 1.00M | } |
44 | | |
45 | 172k | template<typename T> T GetField(voffset_t field, T defaultval) const { |
46 | 172k | auto field_offset = GetOptionalFieldOffset(field); |
47 | 172k | return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval; |
48 | 172k | } unsigned char gdal_flatbuffers::Table::GetField<unsigned char>(unsigned short, unsigned char) const Line | Count | Source | 45 | 85.7k | template<typename T> T GetField(voffset_t field, T defaultval) const { | 46 | 85.7k | auto field_offset = GetOptionalFieldOffset(field); | 47 | 85.7k | return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval; | 48 | 85.7k | } |
int gdal_flatbuffers::Table::GetField<int>(unsigned short, int) const Line | Count | Source | 45 | 34.6k | template<typename T> T GetField(voffset_t field, T defaultval) const { | 46 | 34.6k | auto field_offset = GetOptionalFieldOffset(field); | 47 | 34.6k | return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval; | 48 | 34.6k | } |
unsigned long gdal_flatbuffers::Table::GetField<unsigned long>(unsigned short, unsigned long) const Line | Count | Source | 45 | 26.2k | template<typename T> T GetField(voffset_t field, T defaultval) const { | 46 | 26.2k | auto field_offset = GetOptionalFieldOffset(field); | 47 | 26.2k | return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval; | 48 | 26.2k | } |
unsigned short gdal_flatbuffers::Table::GetField<unsigned short>(unsigned short, unsigned short) const Line | Count | Source | 45 | 26.2k | template<typename T> T GetField(voffset_t field, T defaultval) const { | 46 | 26.2k | auto field_offset = GetOptionalFieldOffset(field); | 47 | 26.2k | return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval; | 48 | 26.2k | } |
|
49 | | |
50 | 428k | template<typename P> P GetPointer(voffset_t field) { |
51 | 428k | auto field_offset = GetOptionalFieldOffset(field); |
52 | 428k | auto p = data_ + field_offset; |
53 | 428k | return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p)) |
54 | 428k | : nullptr; |
55 | 428k | } gdal_flatbuffers::String const* gdal_flatbuffers::Table::GetPointer<gdal_flatbuffers::String const*>(unsigned short) Line | Count | Source | 50 | 253k | template<typename P> P GetPointer(voffset_t field) { | 51 | 253k | auto field_offset = GetOptionalFieldOffset(field); | 52 | 253k | auto p = data_ + field_offset; | 53 | 253k | return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p)) | 54 | 253k | : nullptr; | 55 | 253k | } |
gdal_flatbuffers::Vector<double> const* gdal_flatbuffers::Table::GetPointer<gdal_flatbuffers::Vector<double> const*>(unsigned short) Line | Count | Source | 50 | 62.2k | template<typename P> P GetPointer(voffset_t field) { | 51 | 62.2k | auto field_offset = GetOptionalFieldOffset(field); | 52 | 62.2k | auto p = data_ + field_offset; | 53 | 62.2k | return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p)) | 54 | 62.2k | : nullptr; | 55 | 62.2k | } |
gdal_flatbuffers::Vector<gdal_flatbuffers::Offset<FlatGeobuf::Column> > const* gdal_flatbuffers::Table::GetPointer<gdal_flatbuffers::Vector<gdal_flatbuffers::Offset<FlatGeobuf::Column> > const*>(unsigned short) Line | Count | Source | 50 | 47.1k | template<typename P> P GetPointer(voffset_t field) { | 51 | 47.1k | auto field_offset = GetOptionalFieldOffset(field); | 52 | 47.1k | auto p = data_ + field_offset; | 53 | 47.1k | return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p)) | 54 | 47.1k | : nullptr; | 55 | 47.1k | } |
FlatGeobuf::Crs const* gdal_flatbuffers::Table::GetPointer<FlatGeobuf::Crs const*>(unsigned short) Line | Count | Source | 50 | 26.4k | template<typename P> P GetPointer(voffset_t field) { | 51 | 26.4k | auto field_offset = GetOptionalFieldOffset(field); | 52 | 26.4k | auto p = data_ + field_offset; | 53 | 26.4k | return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p)) | 54 | 26.4k | : nullptr; | 55 | 26.4k | } |
gdal_flatbuffers::Vector<unsigned int> const* gdal_flatbuffers::Table::GetPointer<gdal_flatbuffers::Vector<unsigned int> const*>(unsigned short) Line | Count | Source | 50 | 7.96k | template<typename P> P GetPointer(voffset_t field) { | 51 | 7.96k | auto field_offset = GetOptionalFieldOffset(field); | 52 | 7.96k | auto p = data_ + field_offset; | 53 | 7.96k | return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p)) | 54 | 7.96k | : nullptr; | 55 | 7.96k | } |
gdal_flatbuffers::Vector<unsigned long> const* gdal_flatbuffers::Table::GetPointer<gdal_flatbuffers::Vector<unsigned long> const*>(unsigned short) Line | Count | Source | 50 | 6.04k | template<typename P> P GetPointer(voffset_t field) { | 51 | 6.04k | auto field_offset = GetOptionalFieldOffset(field); | 52 | 6.04k | auto p = data_ + field_offset; | 53 | 6.04k | return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p)) | 54 | 6.04k | : nullptr; | 55 | 6.04k | } |
gdal_flatbuffers::Vector<gdal_flatbuffers::Offset<FlatGeobuf::Geometry> > const* gdal_flatbuffers::Table::GetPointer<gdal_flatbuffers::Vector<gdal_flatbuffers::Offset<FlatGeobuf::Geometry> > const*>(unsigned short) Line | Count | Source | 50 | 13.8k | template<typename P> P GetPointer(voffset_t field) { | 51 | 13.8k | auto field_offset = GetOptionalFieldOffset(field); | 52 | 13.8k | auto p = data_ + field_offset; | 53 | 13.8k | return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p)) | 54 | 13.8k | : nullptr; | 55 | 13.8k | } |
FlatGeobuf::Geometry const* gdal_flatbuffers::Table::GetPointer<FlatGeobuf::Geometry const*>(unsigned short) Line | Count | Source | 50 | 5.91k | template<typename P> P GetPointer(voffset_t field) { | 51 | 5.91k | auto field_offset = GetOptionalFieldOffset(field); | 52 | 5.91k | auto p = data_ + field_offset; | 53 | 5.91k | return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p)) | 54 | 5.91k | : nullptr; | 55 | 5.91k | } |
gdal_flatbuffers::Vector<unsigned char> const* gdal_flatbuffers::Table::GetPointer<gdal_flatbuffers::Vector<unsigned char> const*>(unsigned short) Line | Count | Source | 50 | 5.48k | template<typename P> P GetPointer(voffset_t field) { | 51 | 5.48k | auto field_offset = GetOptionalFieldOffset(field); | 52 | 5.48k | auto p = data_ + field_offset; | 53 | 5.48k | return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p)) | 54 | 5.48k | : nullptr; | 55 | 5.48k | } |
|
56 | 428k | template<typename P> P GetPointer(voffset_t field) const { |
57 | 428k | return const_cast<Table *>(this)->GetPointer<P>(field); |
58 | 428k | } gdal_flatbuffers::String const* gdal_flatbuffers::Table::GetPointer<gdal_flatbuffers::String const*>(unsigned short) const Line | Count | Source | 56 | 253k | template<typename P> P GetPointer(voffset_t field) const { | 57 | 253k | return const_cast<Table *>(this)->GetPointer<P>(field); | 58 | 253k | } |
gdal_flatbuffers::Vector<double> const* gdal_flatbuffers::Table::GetPointer<gdal_flatbuffers::Vector<double> const*>(unsigned short) const Line | Count | Source | 56 | 62.2k | template<typename P> P GetPointer(voffset_t field) const { | 57 | 62.2k | return const_cast<Table *>(this)->GetPointer<P>(field); | 58 | 62.2k | } |
gdal_flatbuffers::Vector<gdal_flatbuffers::Offset<FlatGeobuf::Column> > const* gdal_flatbuffers::Table::GetPointer<gdal_flatbuffers::Vector<gdal_flatbuffers::Offset<FlatGeobuf::Column> > const*>(unsigned short) const Line | Count | Source | 56 | 47.1k | template<typename P> P GetPointer(voffset_t field) const { | 57 | 47.1k | return const_cast<Table *>(this)->GetPointer<P>(field); | 58 | 47.1k | } |
FlatGeobuf::Crs const* gdal_flatbuffers::Table::GetPointer<FlatGeobuf::Crs const*>(unsigned short) const Line | Count | Source | 56 | 26.4k | template<typename P> P GetPointer(voffset_t field) const { | 57 | 26.4k | return const_cast<Table *>(this)->GetPointer<P>(field); | 58 | 26.4k | } |
gdal_flatbuffers::Vector<unsigned int> const* gdal_flatbuffers::Table::GetPointer<gdal_flatbuffers::Vector<unsigned int> const*>(unsigned short) const Line | Count | Source | 56 | 7.96k | template<typename P> P GetPointer(voffset_t field) const { | 57 | 7.96k | return const_cast<Table *>(this)->GetPointer<P>(field); | 58 | 7.96k | } |
gdal_flatbuffers::Vector<unsigned long> const* gdal_flatbuffers::Table::GetPointer<gdal_flatbuffers::Vector<unsigned long> const*>(unsigned short) const Line | Count | Source | 56 | 6.04k | template<typename P> P GetPointer(voffset_t field) const { | 57 | 6.04k | return const_cast<Table *>(this)->GetPointer<P>(field); | 58 | 6.04k | } |
gdal_flatbuffers::Vector<gdal_flatbuffers::Offset<FlatGeobuf::Geometry> > const* gdal_flatbuffers::Table::GetPointer<gdal_flatbuffers::Vector<gdal_flatbuffers::Offset<FlatGeobuf::Geometry> > const*>(unsigned short) const Line | Count | Source | 56 | 13.8k | template<typename P> P GetPointer(voffset_t field) const { | 57 | 13.8k | return const_cast<Table *>(this)->GetPointer<P>(field); | 58 | 13.8k | } |
FlatGeobuf::Geometry const* gdal_flatbuffers::Table::GetPointer<FlatGeobuf::Geometry const*>(unsigned short) const Line | Count | Source | 56 | 5.91k | template<typename P> P GetPointer(voffset_t field) const { | 57 | 5.91k | return const_cast<Table *>(this)->GetPointer<P>(field); | 58 | 5.91k | } |
gdal_flatbuffers::Vector<unsigned char> const* gdal_flatbuffers::Table::GetPointer<gdal_flatbuffers::Vector<unsigned char> const*>(unsigned short) const Line | Count | Source | 56 | 5.48k | template<typename P> P GetPointer(voffset_t field) const { | 57 | 5.48k | return const_cast<Table *>(this)->GetPointer<P>(field); | 58 | 5.48k | } |
|
59 | | |
60 | | template<typename P> P GetStruct(voffset_t field) const { |
61 | | auto field_offset = GetOptionalFieldOffset(field); |
62 | | auto p = const_cast<uint8_t *>(data_ + field_offset); |
63 | | return field_offset ? reinterpret_cast<P>(p) : nullptr; |
64 | | } |
65 | | |
66 | | template<typename Raw, typename Face> |
67 | | flatbuffers::Optional<Face> GetOptional(voffset_t field) const { |
68 | | auto field_offset = GetOptionalFieldOffset(field); |
69 | | auto p = data_ + field_offset; |
70 | | return field_offset ? Optional<Face>(static_cast<Face>(ReadScalar<Raw>(p))) |
71 | | : Optional<Face>(); |
72 | | } |
73 | | |
74 | | template<typename T> bool SetField(voffset_t field, T val, T def) { |
75 | | auto field_offset = GetOptionalFieldOffset(field); |
76 | | if (!field_offset) return IsTheSameAs(val, def); |
77 | | WriteScalar(data_ + field_offset, val); |
78 | | return true; |
79 | | } |
80 | | template<typename T> bool SetField(voffset_t field, T val) { |
81 | | auto field_offset = GetOptionalFieldOffset(field); |
82 | | if (!field_offset) return false; |
83 | | WriteScalar(data_ + field_offset, val); |
84 | | return true; |
85 | | } |
86 | | |
87 | 0 | bool SetPointer(voffset_t field, const uint8_t *val) { |
88 | 0 | auto field_offset = GetOptionalFieldOffset(field); |
89 | 0 | if (!field_offset) return false; |
90 | 0 | WriteScalar(data_ + field_offset, |
91 | 0 | static_cast<uoffset_t>(val - (data_ + field_offset))); |
92 | 0 | return true; |
93 | 0 | } |
94 | | |
95 | 0 | uint8_t *GetAddressOf(voffset_t field) { |
96 | 0 | auto field_offset = GetOptionalFieldOffset(field); |
97 | 0 | return field_offset ? data_ + field_offset : nullptr; |
98 | 0 | } |
99 | 0 | const uint8_t *GetAddressOf(voffset_t field) const { |
100 | 0 | return const_cast<Table *>(this)->GetAddressOf(field); |
101 | 0 | } |
102 | | |
103 | 0 | bool CheckField(voffset_t field) const { |
104 | 0 | return GetOptionalFieldOffset(field) != 0; |
105 | 0 | } |
106 | | |
107 | | // Verify the vtable of this table. |
108 | | // Call this once per table, followed by VerifyField once per field. |
109 | 43.1k | bool VerifyTableStart(Verifier &verifier) const { |
110 | 43.1k | return verifier.VerifyTableStart(data_); |
111 | 43.1k | } |
112 | | |
113 | | // Verify a particular field. |
114 | | template<typename T> |
115 | | bool VerifyField(const Verifier &verifier, voffset_t field, |
116 | 166k | size_t align) const { |
117 | | // Calling GetOptionalFieldOffset should be safe now thanks to |
118 | | // VerifyTable(). |
119 | 166k | auto field_offset = GetOptionalFieldOffset(field); |
120 | | // Check the actual field. |
121 | 166k | return !field_offset || verifier.VerifyField<T>(data_, field_offset, align); |
122 | 166k | } bool gdal_flatbuffers::Table::VerifyField<unsigned char>(gdal_flatbuffers::Verifier const&, unsigned short, unsigned long) const Line | Count | Source | 116 | 104k | size_t align) const { | 117 | | // Calling GetOptionalFieldOffset should be safe now thanks to | 118 | | // VerifyTable(). | 119 | 104k | auto field_offset = GetOptionalFieldOffset(field); | 120 | | // Check the actual field. | 121 | 104k | return !field_offset || verifier.VerifyField<T>(data_, field_offset, align); | 122 | 104k | } |
bool gdal_flatbuffers::Table::VerifyField<int>(gdal_flatbuffers::Verifier const&, unsigned short, unsigned long) const Line | Count | Source | 116 | 35.0k | size_t align) const { | 117 | | // Calling GetOptionalFieldOffset should be safe now thanks to | 118 | | // VerifyTable(). | 119 | 35.0k | auto field_offset = GetOptionalFieldOffset(field); | 120 | | // Check the actual field. | 121 | 35.0k | return !field_offset || verifier.VerifyField<T>(data_, field_offset, align); | 122 | 35.0k | } |
bool gdal_flatbuffers::Table::VerifyField<unsigned long>(gdal_flatbuffers::Verifier const&, unsigned short, unsigned long) const Line | Count | Source | 116 | 13.3k | size_t align) const { | 117 | | // Calling GetOptionalFieldOffset should be safe now thanks to | 118 | | // VerifyTable(). | 119 | 13.3k | auto field_offset = GetOptionalFieldOffset(field); | 120 | | // Check the actual field. | 121 | 13.3k | return !field_offset || verifier.VerifyField<T>(data_, field_offset, align); | 122 | 13.3k | } |
bool gdal_flatbuffers::Table::VerifyField<unsigned short>(gdal_flatbuffers::Verifier const&, unsigned short, unsigned long) const Line | Count | Source | 116 | 13.3k | size_t align) const { | 117 | | // Calling GetOptionalFieldOffset should be safe now thanks to | 118 | | // VerifyTable(). | 119 | 13.3k | auto field_offset = GetOptionalFieldOffset(field); | 120 | | // Check the actual field. | 121 | 13.3k | return !field_offset || verifier.VerifyField<T>(data_, field_offset, align); | 122 | 13.3k | } |
|
123 | | |
124 | | // VerifyField for required fields. |
125 | | template<typename T> |
126 | | bool VerifyFieldRequired(const Verifier &verifier, voffset_t field, |
127 | | size_t align) const { |
128 | | auto field_offset = GetOptionalFieldOffset(field); |
129 | | return verifier.Check(field_offset != 0) && |
130 | | verifier.VerifyField<T>(data_, field_offset, align); |
131 | | } |
132 | | |
133 | | // Versions for offsets. |
134 | 229k | bool VerifyOffset(const Verifier &verifier, voffset_t field) const { |
135 | 229k | auto field_offset = GetOptionalFieldOffset(field); |
136 | 229k | return !field_offset || verifier.VerifyOffset(data_, field_offset); |
137 | 229k | } |
138 | | |
139 | 7.69k | bool VerifyOffsetRequired(const Verifier &verifier, voffset_t field) const { |
140 | 7.69k | auto field_offset = GetOptionalFieldOffset(field); |
141 | 7.69k | return verifier.Check(field_offset != 0) && |
142 | 7.69k | verifier.VerifyOffset(data_, field_offset); |
143 | 7.69k | } |
144 | | |
145 | | private: |
146 | | // private constructor & copy constructor: you obtain instances of this |
147 | | // class by pointing to existing data only |
148 | | Table(); |
149 | | Table(const Table &other); |
150 | | Table &operator=(const Table &); |
151 | | |
152 | | uint8_t data_[1]; |
153 | | }; |
154 | | |
155 | | // This specialization allows avoiding warnings like: |
156 | | // MSVC C4800: type: forcing value to bool 'true' or 'false'. |
157 | | template<> |
158 | | inline flatbuffers::Optional<bool> Table::GetOptional<uint8_t, bool>( |
159 | 0 | voffset_t field) const { |
160 | 0 | auto field_offset = GetOptionalFieldOffset(field); |
161 | 0 | auto p = data_ + field_offset; |
162 | 0 | return field_offset ? Optional<bool>(ReadScalar<uint8_t>(p) != 0) |
163 | 0 | : Optional<bool>(); |
164 | 0 | } |
165 | | |
166 | | } // namespace flatbuffers |
167 | | |
168 | | #endif // FLATBUFFERS_TABLE_H_ |