blob: 7518bed8fec2cae313a008e856c4e2fd2040dd71 [file] [log] [blame]
Austin Schuh09d7ffa2019-10-03 23:43:34 -07001#ifndef AOS_FLATBUFFER_MERGE_H_
2#define AOS_FLATBUFFER_MERGE_H_
3
4#include <cstddef>
5#include <string>
6
Austin Schuhe93d8642019-10-13 15:27:07 -07007#include "aos/flatbuffers.h"
Austin Schuh09d7ffa2019-10-03 23:43:34 -07008#include "flatbuffers/flatbuffers.h"
9
10namespace aos {
11
Austin Schuhe93d8642019-10-13 15:27:07 -070012flatbuffers::DetachedBuffer MergeFlatBuffers(
13 const flatbuffers::TypeTable *typetable, const uint8_t *data1,
14 const uint8_t *data2);
15
16// Merges 2 flat buffers with the provided type table into the builder. Returns
17// the offset to the flatbuffers.
18// One or both of t1 and t2 must be non-null. If one is null, this method
19// coppies instead of merging.
20flatbuffers::Offset<flatbuffers::Table> MergeFlatBuffers(
21 const flatbuffers::TypeTable *typetable, const flatbuffers::Table *t1,
22 const flatbuffers::Table *t2, flatbuffers::FlatBufferBuilder *fbb);
Austin Schuh09d7ffa2019-10-03 23:43:34 -070023
24template <class T>
Austin Schuhe93d8642019-10-13 15:27:07 -070025inline flatbuffers::Offset<T> MergeFlatBuffers(
26 const flatbuffers::Table *t1,
27 const flatbuffers::Table *t2, flatbuffers::FlatBufferBuilder *fbb) {
28 return MergeFlatBuffers(T::MiniReflectTypeTable(), t1, t2, fbb).o;
29}
30
31template <class T>
32inline flatbuffers::DetachedBuffer MergeFlatBuffers(const uint8_t *data1,
33 const uint8_t *data2) {
Austin Schuh09d7ffa2019-10-03 23:43:34 -070034 return MergeFlatBuffers(T::MiniReflectTypeTable(), data1, data2);
35}
36
Austin Schuhe93d8642019-10-13 15:27:07 -070037template <class T>
38inline flatbuffers::DetachedBuffer MergeFlatBuffers(
39 const flatbuffers::DetachedBuffer &data1,
40 const flatbuffers::DetachedBuffer &data2) {
41 return MergeFlatBuffers(T::MiniReflectTypeTable(), data1.data(),
42 data2.data());
43}
44
45template <class T>
Austin Schuh40485ed2019-10-26 21:51:44 -070046inline aos::FlatbufferDetachedBuffer<T> MergeFlatBuffers(
47 const aos::Flatbuffer<T> &fb1, const aos::Flatbuffer<T> &fb2) {
48const uint8_t *data1 = fb1.data();
49const uint8_t *data2 = fb2.data();
50 return aos::FlatbufferDetachedBuffer<T>(
51 MergeFlatBuffers(T::MiniReflectTypeTable(), data1, data2));
Austin Schuhe93d8642019-10-13 15:27:07 -070052}
53
54template <class T>
Austin Schuh40485ed2019-10-26 21:51:44 -070055inline aos::FlatbufferDetachedBuffer<T> MergeFlatBuffers(const T *fb1,
56 const T *fb2) {
James Kuszmaulf3a3be22020-01-04 12:12:00 -080057 flatbuffers::FlatBufferBuilder fbb;
Austin Schuhd7b15da2020-02-17 15:06:11 -080058 fbb.ForceDefaults(true);
James Kuszmaulf3a3be22020-01-04 12:12:00 -080059 fbb.Finish(MergeFlatBuffers<T>(
60 reinterpret_cast<const flatbuffers::Table *>(fb1),
61 reinterpret_cast<const flatbuffers::Table *>(fb2), &fbb));
62 return aos::FlatbufferDetachedBuffer<T>(fbb.Release());
Austin Schuhe93d8642019-10-13 15:27:07 -070063}
64
65template <class T>
Austin Schuhe6958212020-10-19 11:48:14 -070066inline flatbuffers::Offset<T> MergeFlatBuffers(
67 const T *fb1, const T *fb2, flatbuffers::FlatBufferBuilder *fbb) {
68 return MergeFlatBuffers<T>(reinterpret_cast<const flatbuffers::Table *>(fb1),
69 reinterpret_cast<const flatbuffers::Table *>(fb2),
70 fbb);
71}
72
Austin Schuha4fc60f2020-11-01 23:06:47 -080073// Copies a flatbuffer by walking the tree and copying all the pieces. This
74// converts DAGs to trees.
Austin Schuhe6958212020-10-19 11:48:14 -070075template <class T>
Austin Schuha4fc60f2020-11-01 23:06:47 -080076inline flatbuffers::Offset<T> RecursiveCopyFlatBuffer(
Austin Schuhe93d8642019-10-13 15:27:07 -070077 const T *t1, flatbuffers::FlatBufferBuilder *fbb) {
78 return MergeFlatBuffers<T>(reinterpret_cast<const flatbuffers::Table *>(t1),
79 nullptr, fbb);
80}
81
Austin Schuha4fc60f2020-11-01 23:06:47 -080082// Copies a flatbuffer by finding the extents of the memory using the typetable
83// and copying the containing memory. This doesn't allocate memory, and
84// preserves DAGs.
85flatbuffers::Offset<flatbuffers::Table> CopyFlatBuffer(
86 const flatbuffers::Table *t1, const flatbuffers::TypeTable *typetable,
87 flatbuffers::FlatBufferBuilder *fbb);
88
89template <class T>
90inline flatbuffers::Offset<T> CopyFlatBuffer(
91 const T *t1, flatbuffers::FlatBufferBuilder *fbb) {
92 return flatbuffers::Offset<T>(
93 CopyFlatBuffer(reinterpret_cast<const flatbuffers::Table *>(t1),
94 T::MiniReflectTypeTable(), fbb)
95 .o);
96}
97
98template <class T>
99inline flatbuffers::Offset<T> CopyFlatBuffer(
100 const Flatbuffer<T> &t1, flatbuffers::FlatBufferBuilder *fbb) {
101 return flatbuffers::Offset<T>(
102 CopyFlatBuffer(
103 reinterpret_cast<const flatbuffers::Table *>(&t1.message()),
104 T::MiniReflectTypeTable(), fbb)
105 .o);
106}
107
108// Copies a flatbuffer by copying all the data without looking inside and
109// pointing inside it.
110template <class T>
111inline flatbuffers::Offset<T> BlindCopyFlatBuffer(
112 const Flatbuffer<T> &t, flatbuffers::FlatBufferBuilder *fbb) {
113 // Enforce 8 byte alignment so anything inside the flatbuffer can be read.
114 fbb->Align(sizeof(flatbuffers::largest_scalar_t));
115
116 // We don't know how much of the start of the flatbuffer is padding. The
117 // safest thing to do from an alignment point of view (without looking inside)
118 // is to copy the initial offset and leave it as dead space.
119 fbb->PushBytes(t.data(), t.size());
120 return fbb->GetSize() -
121 flatbuffers::ReadScalar<flatbuffers::uoffset_t>(t.data());
122}
123
Austin Schuhe93d8642019-10-13 15:27:07 -0700124template <class T>
Austin Schuhcbe9d5a2020-11-01 23:25:23 -0800125inline flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<T>>>
126CopyVectorTable(const flatbuffers::Vector<flatbuffers::Offset<T>> *t1,
127 flatbuffers::FlatBufferBuilder *fbb) {
128 if (t1 == nullptr) {
129 return 0;
130 }
131 std::vector<flatbuffers::Offset<T>> v;
132 for (const T *t : *t1) {
133 v.emplace_back(CopyFlatBuffer(t, fbb));
134 }
135 return fbb->CreateVector(v);
136}
137
138inline flatbuffers::Offset<
139 flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>>
140CopyVectorSharedString(
141 const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *t1,
142 flatbuffers::FlatBufferBuilder *fbb) {
143 if (t1 == nullptr) {
144 return 0;
145 }
146 std::vector<flatbuffers::Offset<flatbuffers::String>> v;
147 for (const flatbuffers::String *t : *t1) {
148 v.emplace_back(fbb->CreateSharedString(t));
149 }
150 return fbb->CreateVector(v);
151}
152
153template <class T>
Austin Schuh40485ed2019-10-26 21:51:44 -0700154inline FlatbufferDetachedBuffer<T> CopyFlatBuffer(const T *t) {
Austin Schuhe93d8642019-10-13 15:27:07 -0700155 flatbuffers::FlatBufferBuilder fbb;
Austin Schuhd7b15da2020-02-17 15:06:11 -0800156 fbb.ForceDefaults(true);
Austin Schuhe93d8642019-10-13 15:27:07 -0700157 fbb.Finish(CopyFlatBuffer<T>(t, &fbb));
Austin Schuh40485ed2019-10-26 21:51:44 -0700158 return FlatbufferDetachedBuffer<T>(fbb.Release());
Austin Schuhe93d8642019-10-13 15:27:07 -0700159}
160
Austin Schuha4fc60f2020-11-01 23:06:47 -0800161template <class T>
162inline FlatbufferDetachedBuffer<T> RecursiveCopyFlatBuffer(const T *t) {
163 flatbuffers::FlatBufferBuilder fbb;
164 fbb.ForceDefaults(true);
165 fbb.Finish(RecursiveCopyFlatBuffer<T>(t, &fbb));
166 return FlatbufferDetachedBuffer<T>(fbb.Release());
167}
168
Austin Schuh30d7db92020-01-26 16:45:47 -0800169// Compares 2 flatbuffers. Returns true if they match, false otherwise.
170bool CompareFlatBuffer(const flatbuffers::TypeTable *typetable,
171 const flatbuffers::Table *t1,
172 const flatbuffers::Table *t2);
173
174template <class T>
175inline bool CompareFlatBuffer(const T *t1, const T *t2) {
176 return CompareFlatBuffer(T::MiniReflectTypeTable(),
177 reinterpret_cast<const flatbuffers::Table *>(t1),
178 reinterpret_cast<const flatbuffers::Table *>(t2));
179}
180
Austin Schuh97789fc2020-08-01 14:42:45 -0700181template <class T>
182inline bool CompareFlatBuffer(const aos::Flatbuffer<T> &t1,
183 const aos::Flatbuffer<T> &t2) {
184 return t1.span() == t2.span();
185}
186
Austin Schuh09d7ffa2019-10-03 23:43:34 -0700187} // namespace aos
188
189#endif // AOS_FLATBUFFER_MERGE_H_