LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/flatgeobuf/flatbuffers - table.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 28 28 100.0 %
Date: 2024-05-14 23:54:21 Functions: 31 31 100.0 %

          Line data    Source code
       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     1934410 :   const uint8_t *GetVTable() const {
      30     1934410 :     return data_ - ReadScalar<soffset_t>(data_);
      31             :   }
      32             : 
      33             :   // This gets the field offset for any of the functions below it, or 0
      34             :   // if the field was not present.
      35     1934410 :   voffset_t GetOptionalFieldOffset(voffset_t field) const {
      36             :     // The vtable offset is always at the start.
      37     1934410 :     auto vtable = GetVTable();
      38             :     // The first element is the size of the vtable (fields + type id + itself).
      39     1934410 :     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     1934410 :     return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0;
      43             :   }
      44             : 
      45      528520 :   template<typename T> T GetField(voffset_t field, T defaultval) const {
      46      528520 :     auto field_offset = GetOptionalFieldOffset(field);
      47      528520 :     return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval;
      48             :   }
      49             : 
      50      541489 :   template<typename P> P GetPointer(voffset_t field) {
      51      541489 :     auto field_offset = GetOptionalFieldOffset(field);
      52      541489 :     auto p = data_ + field_offset;
      53      541489 :     return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p))
      54      541489 :                         : nullptr;
      55             :   }
      56      541489 :   template<typename P> P GetPointer(voffset_t field) const {
      57      541489 :     return const_cast<Table *>(this)->GetPointer<P>(field);
      58             :   }
      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             :   bool SetPointer(voffset_t field, const uint8_t *val) {
      88             :     auto field_offset = GetOptionalFieldOffset(field);
      89             :     if (!field_offset) return false;
      90             :     WriteScalar(data_ + field_offset,
      91             :                 static_cast<uoffset_t>(val - (data_ + field_offset)));
      92             :     return true;
      93             :   }
      94             : 
      95             :   uint8_t *GetAddressOf(voffset_t field) {
      96             :     auto field_offset = GetOptionalFieldOffset(field);
      97             :     return field_offset ? data_ + field_offset : nullptr;
      98             :   }
      99             :   const uint8_t *GetAddressOf(voffset_t field) const {
     100             :     return const_cast<Table *>(this)->GetAddressOf(field);
     101             :   }
     102             : 
     103             :   bool CheckField(voffset_t field) const {
     104             :     return GetOptionalFieldOffset(field) != 0;
     105             :   }
     106             : 
     107             :   // Verify the vtable of this table.
     108             :   // Call this once per table, followed by VerifyField once per field.
     109       67334 :   bool VerifyTableStart(Verifier &verifier) const {
     110       67334 :     return verifier.VerifyTableStart(data_);
     111             :   }
     112             : 
     113             :   // Verify a particular field.
     114             :   template<typename T>
     115      461473 :   bool VerifyField(const Verifier &verifier, voffset_t field,
     116             :                    size_t align) const {
     117             :     // Calling GetOptionalFieldOffset should be safe now thanks to
     118             :     // VerifyTable().
     119      461473 :     auto field_offset = GetOptionalFieldOffset(field);
     120             :     // Check the actual field.
     121      461473 :     return !field_offset || verifier.VerifyField<T>(data_, field_offset, align);
     122             :   }
     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      205872 :   bool VerifyOffset(const Verifier &verifier, voffset_t field) const {
     135      205872 :     auto field_offset = GetOptionalFieldOffset(field);
     136      205872 :     return !field_offset || verifier.VerifyOffset(data_, field_offset);
     137             :   }
     138             : 
     139       65662 :   bool VerifyOffsetRequired(const Verifier &verifier, voffset_t field) const {
     140       65662 :     auto field_offset = GetOptionalFieldOffset(field);
     141      131324 :     return verifier.Check(field_offset != 0) &&
     142      131324 :            verifier.VerifyOffset(data_, field_offset);
     143             :   }
     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             :     voffset_t field) const {
     160             :   auto field_offset = GetOptionalFieldOffset(field);
     161             :   auto p = data_ + field_offset;
     162             :   return field_offset ? Optional<bool>(ReadScalar<uint8_t>(p) != 0)
     163             :                       : Optional<bool>();
     164             : }
     165             : 
     166             : }  // namespace flatbuffers
     167             : 
     168             : #endif  // FLATBUFFERS_TABLE_H_

Generated by: LCOV version 1.14