Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-27 09:30:28

0001 /*
0002  * Copyright 2021 Google Inc. All rights reserved.
0003  *
0004  * Licensed under the Apache License, Version 2.0 (the "License");
0005  * you may not use this file except in compliance with the License.
0006  * You may obtain a copy of the License at
0007  *
0008  *     http://www.apache.org/licenses/LICENSE-2.0
0009  *
0010  * Unless required by applicable law or agreed to in writing, software
0011  * distributed under the License is distributed on an "AS IS" BASIS,
0012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013  * See the License for the specific language governing permissions and
0014  * limitations under the License.
0015  */
0016 
0017 #ifndef FLATBUFFERS_TABLE_H_
0018 #define FLATBUFFERS_TABLE_H_
0019 
0020 #include "flatbuffers/base.h"
0021 #include "flatbuffers/verifier.h"
0022 
0023 namespace flatbuffers {
0024 
0025 // "tables" use an offset table (possibly shared) that allows fields to be
0026 // omitted and added at will, but uses an extra indirection to read.
0027 class Table {
0028  public:
0029   const uint8_t *GetVTable() const {
0030     return data_ - ReadScalar<soffset_t>(data_);
0031   }
0032 
0033   // This gets the field offset for any of the functions below it, or 0
0034   // if the field was not present.
0035   voffset_t GetOptionalFieldOffset(voffset_t field) const {
0036     // The vtable offset is always at the start.
0037     auto vtable = GetVTable();
0038     // The first element is the size of the vtable (fields + type id + itself).
0039     auto vtsize = ReadScalar<voffset_t>(vtable);
0040     // If the field we're accessing is outside the vtable, we're reading older
0041     // data, so it's the same as if the offset was 0 (not present).
0042     return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0;
0043   }
0044 
0045   template<typename T> T GetField(voffset_t field, T defaultval) const {
0046     auto field_offset = GetOptionalFieldOffset(field);
0047     return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval;
0048   }
0049 
0050   template<typename P, typename OffsetSize = uoffset_t>
0051   P GetPointer(voffset_t field) {
0052     auto field_offset = GetOptionalFieldOffset(field);
0053     auto p = data_ + field_offset;
0054     return field_offset ? reinterpret_cast<P>(p + ReadScalar<OffsetSize>(p))
0055                         : nullptr;
0056   }
0057   template<typename P, typename OffsetSize = uoffset_t>
0058   P GetPointer(voffset_t field) const {
0059     return const_cast<Table *>(this)->GetPointer<P, OffsetSize>(field);
0060   }
0061 
0062   template<typename P> P GetPointer64(voffset_t field) {
0063     return GetPointer<P, uoffset64_t>(field);
0064   }
0065 
0066   template<typename P> P GetPointer64(voffset_t field) const {
0067     return GetPointer<P, uoffset64_t>(field);
0068   }
0069 
0070   template<typename P> P GetStruct(voffset_t field) const {
0071     auto field_offset = GetOptionalFieldOffset(field);
0072     auto p = const_cast<uint8_t *>(data_ + field_offset);
0073     return field_offset ? reinterpret_cast<P>(p) : nullptr;
0074   }
0075 
0076   template<typename Raw, typename Face>
0077   flatbuffers::Optional<Face> GetOptional(voffset_t field) const {
0078     auto field_offset = GetOptionalFieldOffset(field);
0079     auto p = data_ + field_offset;
0080     return field_offset ? Optional<Face>(static_cast<Face>(ReadScalar<Raw>(p)))
0081                         : Optional<Face>();
0082   }
0083 
0084   template<typename T> bool SetField(voffset_t field, T val, T def) {
0085     auto field_offset = GetOptionalFieldOffset(field);
0086     if (!field_offset) return IsTheSameAs(val, def);
0087     WriteScalar(data_ + field_offset, val);
0088     return true;
0089   }
0090   template<typename T> bool SetField(voffset_t field, T val) {
0091     auto field_offset = GetOptionalFieldOffset(field);
0092     if (!field_offset) return false;
0093     WriteScalar(data_ + field_offset, val);
0094     return true;
0095   }
0096 
0097   bool SetPointer(voffset_t field, const uint8_t *val) {
0098     auto field_offset = GetOptionalFieldOffset(field);
0099     if (!field_offset) return false;
0100     WriteScalar(data_ + field_offset,
0101                 static_cast<uoffset_t>(val - (data_ + field_offset)));
0102     return true;
0103   }
0104 
0105   uint8_t *GetAddressOf(voffset_t field) {
0106     auto field_offset = GetOptionalFieldOffset(field);
0107     return field_offset ? data_ + field_offset : nullptr;
0108   }
0109   const uint8_t *GetAddressOf(voffset_t field) const {
0110     return const_cast<Table *>(this)->GetAddressOf(field);
0111   }
0112 
0113   bool CheckField(voffset_t field) const {
0114     return GetOptionalFieldOffset(field) != 0;
0115   }
0116 
0117   // Verify the vtable of this table.
0118   // Call this once per table, followed by VerifyField once per field.
0119   bool VerifyTableStart(Verifier &verifier) const {
0120     return verifier.VerifyTableStart(data_);
0121   }
0122 
0123   // Verify a particular field.
0124   template<typename T>
0125   bool VerifyField(const Verifier &verifier, voffset_t field,
0126                    size_t align) const {
0127     // Calling GetOptionalFieldOffset should be safe now thanks to
0128     // VerifyTable().
0129     auto field_offset = GetOptionalFieldOffset(field);
0130     // Check the actual field.
0131     return !field_offset || verifier.VerifyField<T>(data_, field_offset, align);
0132   }
0133 
0134   // VerifyField for required fields.
0135   template<typename T>
0136   bool VerifyFieldRequired(const Verifier &verifier, voffset_t field,
0137                            size_t align) const {
0138     auto field_offset = GetOptionalFieldOffset(field);
0139     return verifier.Check(field_offset != 0) &&
0140            verifier.VerifyField<T>(data_, field_offset, align);
0141   }
0142 
0143   // Versions for offsets.
0144   template<typename OffsetT = uoffset_t>
0145   bool VerifyOffset(const Verifier &verifier, voffset_t field) const {
0146     auto field_offset = GetOptionalFieldOffset(field);
0147     return !field_offset || verifier.VerifyOffset<OffsetT>(data_, field_offset);
0148   }
0149 
0150   template<typename OffsetT = uoffset_t>
0151   bool VerifyOffsetRequired(const Verifier &verifier, voffset_t field) const {
0152     auto field_offset = GetOptionalFieldOffset(field);
0153     return verifier.Check(field_offset != 0) &&
0154            verifier.VerifyOffset<OffsetT>(data_, field_offset);
0155   }
0156 
0157   bool VerifyOffset64(const Verifier &verifier, voffset_t field) const {
0158     return VerifyOffset<uoffset64_t>(verifier, field);
0159   }
0160 
0161   bool VerifyOffset64Required(const Verifier &verifier, voffset_t field) const {
0162     return VerifyOffsetRequired<uoffset64_t>(verifier, field);
0163   }
0164 
0165  private:
0166   // private constructor & copy constructor: you obtain instances of this
0167   // class by pointing to existing data only
0168   Table();
0169   Table(const Table &other);
0170   Table &operator=(const Table &);
0171 
0172   uint8_t data_[1];
0173 };
0174 
0175 // This specialization allows avoiding warnings like:
0176 // MSVC C4800: type: forcing value to bool 'true' or 'false'.
0177 template<>
0178 inline flatbuffers::Optional<bool> Table::GetOptional<uint8_t, bool>(
0179     voffset_t field) const {
0180   auto field_offset = GetOptionalFieldOffset(field);
0181   auto p = data_ + field_offset;
0182   return field_offset ? Optional<bool>(ReadScalar<uint8_t>(p) != 0)
0183                       : Optional<bool>();
0184 }
0185 
0186 }  // namespace flatbuffers
0187 
0188 #endif  // FLATBUFFERS_TABLE_H_