@@ -45,8 +45,9 @@ inline voffset_t FieldIndexToOffset(voffset_t field_id) {
4545 // Should correspond to what EndTable() below builds up.
4646 const voffset_t fixed_fields =
4747 2 * sizeof (voffset_t ); // Vtable size and Object Size.
48- return fixed_fields + field_id * sizeof (voffset_t );
49- }
48+ size_t offset = fixed_fields + field_id * sizeof (voffset_t );
49+ FLATBUFFERS_ASSERT (offset < std::numeric_limits<voffset_t >::max ());
50+ return static_cast <voffset_t >(offset);}
5051
5152template <typename T, typename Alloc = std::allocator<T>>
5253const T *data (const std::vector<T, Alloc> &v) {
@@ -220,21 +221,13 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
220221 // / @return Returns a `uint8_t` pointer to the unfinished buffer.
221222 uint8_t *GetCurrentBufferPointer () const { return buf_.data (); }
222223
223- // / @brief Get the released pointer to the serialized buffer.
224- // / @warning Do NOT attempt to use this FlatBufferBuilder afterwards!
225- // / @return A `FlatBuffer` that owns the buffer and its allocator and
226- // / behaves similar to a `unique_ptr` with a deleter.
227- FLATBUFFERS_ATTRIBUTE ([[deprecated(" use Release() instead" )]])
228- DetachedBuffer ReleaseBufferPointer () {
229- Finished ();
230- return buf_.release ();
231- }
232-
233224 // / @brief Get the released DetachedBuffer.
234225 // / @return A `DetachedBuffer` that owns the buffer and its allocator.
235226 DetachedBuffer Release () {
236227 Finished ();
237- return buf_.release ();
228+ DetachedBuffer buffer = buf_.release ();
229+ Clear ();
230+ return buffer;
238231 }
239232
240233 // / @brief Get the released pointer to the serialized buffer.
@@ -245,10 +238,12 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
245238 // / @return A raw pointer to the start of the memory block containing
246239 // / the serialized `FlatBuffer`.
247240 // / @remark If the allocator is owned, it gets deleted when the destructor is
248- // / called..
241+ // / called.
249242 uint8_t *ReleaseRaw (size_t &size, size_t &offset) {
250243 Finished ();
251- return buf_.release_raw (size, offset);
244+ uint8_t * raw = buf_.release_raw (size, offset);
245+ Clear ();
246+ return raw;
252247 }
253248
254249 // / @brief get the minimum alignment this buffer needs to be accessed
@@ -566,7 +561,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
566561 return CreateString<OffsetT>(str.c_str (), str.length ());
567562 }
568563
569- // clang-format off
564+ // clang-format off
570565 #ifdef FLATBUFFERS_HAS_STRING_VIEW
571566 // / @brief Store a string in the buffer, which can contain any binary data.
572567 // / @param[in] str A const string_view to copy in to the buffer.
@@ -588,14 +583,14 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
588583
589584 // / @brief Store a string in the buffer, which can contain any binary data.
590585 // / @param[in] str A const reference to a std::string like type with support
591- // / of T::c_str () and T::length() to store in the buffer.
586+ // / of T::data () and T::length() to store in the buffer.
592587 // / @return Returns the offset in the buffer where the string starts.
593588 template <template <typename > class OffsetT = Offset,
594589 // No need to explicitly declare the T type, let the compiler deduce
595590 // it.
596591 int &...ExplicitArgumentBarrier, typename T>
597592 OffsetT<String> CreateString (const T &str) {
598- return CreateString<OffsetT>(str.c_str (), str.length ());
593+ return CreateString<OffsetT>(str.data (), str.length ());
599594 }
600595
601596 // / @brief Store a string in the buffer, which can contain any binary data.
@@ -698,12 +693,27 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
698693 // normally dictate.
699694 // This is useful when storing a nested_flatbuffer in a vector of bytes,
700695 // or when storing SIMD floats, etc.
701- void ForceVectorAlignment (size_t len, size_t elemsize, size_t alignment) {
696+ void ForceVectorAlignment (const size_t len, const size_t elemsize,
697+ const size_t alignment) {
702698 if (len == 0 ) return ;
703699 FLATBUFFERS_ASSERT (VerifyAlignmentRequirements (alignment));
704700 PreAlign (len * elemsize, alignment);
705701 }
706702
703+ template <bool is_64 = Is64Aware>
704+ typename std::enable_if<is_64, void >::type ForceVectorAlignment64 (
705+ const size_t len, const size_t elemsize, const size_t alignment) {
706+ // If you hit this assertion, you are trying to force alignment on a
707+ // vector with offset64 after serializing a 32-bit offset.
708+ FLATBUFFERS_ASSERT (GetSize () == length_of_64_bit_region_);
709+
710+ // Call through.
711+ ForceVectorAlignment (len, elemsize, alignment);
712+
713+ // Update the 64 bit region.
714+ length_of_64_bit_region_ = GetSize ();
715+ }
716+
707717 // Similar to ForceVectorAlignment but for String fields.
708718 void ForceStringAlignment (size_t len, size_t alignment) {
709719 if (len == 0 ) return ;
@@ -733,7 +743,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
733743 AssertScalarT<T>();
734744 StartVector<T, OffsetT, LenT>(len);
735745 if (len > 0 ) {
736- // clang-format off
746+ // clang-format off
737747 #if FLATBUFFERS_LITTLEENDIAN
738748 PushBytes (reinterpret_cast <const uint8_t *>(v), len * sizeof (T));
739749 #else
@@ -864,7 +874,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
864874 // / where the vector is stored.
865875 template <class It >
866876 Offset<Vector<Offset<String>>> CreateVectorOfStrings (It begin, It end) {
867- auto size = std::distance (begin, end);
877+ auto distance = std::distance (begin, end);
878+ FLATBUFFERS_ASSERT (distance >= 0 );
879+ auto size = static_cast <size_t >(distance);
868880 auto scratch_buffer_usage = size * sizeof (Offset<String>);
869881 // If there is not enough space to store the offsets, there definitely won't
870882 // be enough space to store all the strings. So ensuring space for the
@@ -874,7 +886,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
874886 buf_.scratch_push_small (CreateString (*it));
875887 }
876888 StartVector<Offset<String>>(size);
877- for (auto i = 1 ; i <= size; i++) {
889+ for (size_t i = 1 ; i <= size; i++) {
878890 // Note we re-evaluate the buf location each iteration to account for any
879891 // underlying buffer resizing that may occur.
880892 PushElement (*reinterpret_cast <Offset<String> *>(
@@ -898,8 +910,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
898910 typedef typename VectorT<T>::size_type LenT;
899911 typedef typename OffsetT<VectorT<const T *>>::offset_type offset_type;
900912
901- StartVector<OffsetT, LenT>(len * sizeof (T) / AlignOf<T>(), sizeof (T),
902- AlignOf<T>());
913+ StartVector<OffsetT, LenT>(len, sizeof (T), AlignOf<T>());
903914 if (len > 0 ) {
904915 PushBytes (reinterpret_cast <const uint8_t *>(v), sizeof (T) * len);
905916 }
@@ -1244,6 +1255,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
12441255 FlatBufferBuilderImpl &operator =(const FlatBufferBuilderImpl &);
12451256
12461257 void Finish (uoffset_t root, const char *file_identifier, bool size_prefix) {
1258+ // A buffer can only be finished once. To reuse a builder use `clear()`.
1259+ FLATBUFFERS_ASSERT (!finished);
1260+
12471261 NotNested ();
12481262 buf_.clear_scratch ();
12491263
@@ -1369,8 +1383,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
13691383 // Must be completed with EndVectorOfStructs().
13701384 template <typename T, template <typename > class OffsetT = Offset>
13711385 T *StartVectorOfStructs (size_t vector_size) {
1372- StartVector<OffsetT>(vector_size * sizeof (T) / AlignOf<T>(), sizeof (T),
1373- AlignOf<T>());
1386+ StartVector<OffsetT>(vector_size, sizeof (T), AlignOf<T>());
13741387 return reinterpret_cast <T *>(buf_.make_space (vector_size * sizeof (T)));
13751388 }
13761389
@@ -1456,7 +1469,7 @@ T *GetMutableTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
14561469}
14571470
14581471template <typename T>
1459- const T *GetTemporaryPointer (FlatBufferBuilder &fbb, Offset<T> offset) {
1472+ const T *GetTemporaryPointer (const FlatBufferBuilder &fbb, Offset<T> offset) {
14601473 return GetMutableTemporaryPointer<T>(fbb, offset);
14611474}
14621475
0 commit comments