Back to home page

EIC code displayed by LXR

 
 

    


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

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_BUFFER_H_
0018 #define FLATBUFFERS_BUFFER_H_
0019 
0020 #include <algorithm>
0021 
0022 #include "flatbuffers/base.h"
0023 
0024 namespace flatbuffers {
0025 
0026 // Wrapper for uoffset_t to allow safe template specialization.
0027 // Value is allowed to be 0 to indicate a null object (see e.g. AddOffset).
0028 template<typename T = void> struct Offset {
0029   // The type of offset to use.
0030   typedef uoffset_t offset_type;
0031 
0032   offset_type o;
0033   Offset() : o(0) {}
0034   Offset(const offset_type _o) : o(_o) {}
0035   Offset<> Union() const { return o; }
0036   bool IsNull() const { return !o; }
0037 };
0038 
0039 // Wrapper for uoffset64_t Offsets.
0040 template<typename T = void> struct Offset64 {
0041   // The type of offset to use.
0042   typedef uoffset64_t offset_type;
0043 
0044   offset_type o;
0045   Offset64() : o(0) {}
0046   Offset64(const offset_type offset) : o(offset) {}
0047   Offset64<> Union() const { return o; }
0048   bool IsNull() const { return !o; }
0049 };
0050 
0051 // Litmus check for ensuring the Offsets are the expected size.
0052 static_assert(sizeof(Offset<>) == 4, "Offset has wrong size");
0053 static_assert(sizeof(Offset64<>) == 8, "Offset64 has wrong size");
0054 
0055 inline void EndianCheck() {
0056   int endiantest = 1;
0057   // If this fails, see FLATBUFFERS_LITTLEENDIAN above.
0058   FLATBUFFERS_ASSERT(*reinterpret_cast<char *>(&endiantest) ==
0059                      FLATBUFFERS_LITTLEENDIAN);
0060   (void)endiantest;
0061 }
0062 
0063 template<typename T> FLATBUFFERS_CONSTEXPR size_t AlignOf() {
0064   // clang-format off
0065   #ifdef _MSC_VER
0066     return __alignof(T);
0067   #else
0068     #ifndef alignof
0069       return __alignof__(T);
0070     #else
0071       return alignof(T);
0072     #endif
0073   #endif
0074   // clang-format on
0075 }
0076 
0077 // Lexicographically compare two strings (possibly containing nulls), and
0078 // return true if the first is less than the second.
0079 static inline bool StringLessThan(const char *a_data, uoffset_t a_size,
0080                                   const char *b_data, uoffset_t b_size) {
0081   const auto cmp = memcmp(a_data, b_data, (std::min)(a_size, b_size));
0082   return cmp == 0 ? a_size < b_size : cmp < 0;
0083 }
0084 
0085 // When we read serialized data from memory, in the case of most scalars,
0086 // we want to just read T, but in the case of Offset, we want to actually
0087 // perform the indirection and return a pointer.
0088 // The template specialization below does just that.
0089 // It is wrapped in a struct since function templates can't overload on the
0090 // return type like this.
0091 // The typedef is for the convenience of callers of this function
0092 // (avoiding the need for a trailing return decltype)
0093 template<typename T> struct IndirectHelper {
0094   typedef T return_type;
0095   typedef T mutable_return_type;
0096   static const size_t element_stride = sizeof(T);
0097 
0098   static return_type Read(const uint8_t *p, const size_t i) {
0099     return EndianScalar((reinterpret_cast<const T *>(p))[i]);
0100   }
0101   static mutable_return_type Read(uint8_t *p, const size_t i) {
0102     return reinterpret_cast<mutable_return_type>(
0103         Read(const_cast<const uint8_t *>(p), i));
0104   }
0105 };
0106 
0107 // For vector of Offsets.
0108 template<typename T, template<typename> class OffsetT>
0109 struct IndirectHelper<OffsetT<T>> {
0110   typedef const T *return_type;
0111   typedef T *mutable_return_type;
0112   typedef typename OffsetT<T>::offset_type offset_type;
0113   static const offset_type element_stride = sizeof(offset_type);
0114 
0115   static return_type Read(const uint8_t *const p, const offset_type i) {
0116     // Offsets are relative to themselves, so first update the pointer to
0117     // point to the offset location.
0118     const uint8_t *const offset_location = p + i * element_stride;
0119 
0120     // Then read the scalar value of the offset (which may be 32 or 64-bits) and
0121     // then determine the relative location from the offset location.
0122     return reinterpret_cast<return_type>(
0123         offset_location + ReadScalar<offset_type>(offset_location));
0124   }
0125   static mutable_return_type Read(uint8_t *const p, const offset_type i) {
0126     // Offsets are relative to themselves, so first update the pointer to
0127     // point to the offset location.
0128     uint8_t *const offset_location = p + i * element_stride;
0129 
0130     // Then read the scalar value of the offset (which may be 32 or 64-bits) and
0131     // then determine the relative location from the offset location.
0132     return reinterpret_cast<mutable_return_type>(
0133         offset_location + ReadScalar<offset_type>(offset_location));
0134   }
0135 };
0136 
0137 // For vector of structs.
0138 template<typename T> struct IndirectHelper<const T *> {
0139   typedef const T *return_type;
0140   typedef T *mutable_return_type;
0141   static const size_t element_stride = sizeof(T);
0142 
0143   static return_type Read(const uint8_t *const p, const size_t i) {
0144     // Structs are stored inline, relative to the first struct pointer.
0145     return reinterpret_cast<return_type>(p + i * element_stride);
0146   }
0147   static mutable_return_type Read(uint8_t *const p, const size_t i) {
0148     // Structs are stored inline, relative to the first struct pointer.
0149     return reinterpret_cast<mutable_return_type>(p + i * element_stride);
0150   }
0151 };
0152 
0153 /// @brief Get a pointer to the file_identifier section of the buffer.
0154 /// @return Returns a const char pointer to the start of the file_identifier
0155 /// characters in the buffer.  The returned char * has length
0156 /// 'flatbuffers::FlatBufferBuilder::kFileIdentifierLength'.
0157 /// This function is UNDEFINED for FlatBuffers whose schema does not include
0158 /// a file_identifier (likely points at padding or the start of a the root
0159 /// vtable).
0160 inline const char *GetBufferIdentifier(const void *buf,
0161                                        bool size_prefixed = false) {
0162   return reinterpret_cast<const char *>(buf) +
0163          ((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t));
0164 }
0165 
0166 // Helper to see if the identifier in a buffer has the expected value.
0167 inline bool BufferHasIdentifier(const void *buf, const char *identifier,
0168                                 bool size_prefixed = false) {
0169   return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
0170                  flatbuffers::kFileIdentifierLength) == 0;
0171 }
0172 
0173 /// @cond FLATBUFFERS_INTERNAL
0174 // Helpers to get a typed pointer to the root object contained in the buffer.
0175 template<typename T> T *GetMutableRoot(void *buf) {
0176   if (!buf) return nullptr;
0177   EndianCheck();
0178   return reinterpret_cast<T *>(
0179       reinterpret_cast<uint8_t *>(buf) +
0180       EndianScalar(*reinterpret_cast<uoffset_t *>(buf)));
0181 }
0182 
0183 template<typename T, typename SizeT = uoffset_t>
0184 T *GetMutableSizePrefixedRoot(void *buf) {
0185   return GetMutableRoot<T>(reinterpret_cast<uint8_t *>(buf) + sizeof(SizeT));
0186 }
0187 
0188 template<typename T> const T *GetRoot(const void *buf) {
0189   return GetMutableRoot<T>(const_cast<void *>(buf));
0190 }
0191 
0192 template<typename T, typename SizeT = uoffset_t>
0193 const T *GetSizePrefixedRoot(const void *buf) {
0194   return GetRoot<T>(reinterpret_cast<const uint8_t *>(buf) + sizeof(SizeT));
0195 }
0196 
0197 }  // namespace flatbuffers
0198 
0199 #endif  // FLATBUFFERS_BUFFER_H_