forked from frc971/971-Robot-Code
-
Notifications
You must be signed in to change notification settings - Fork 0
/
static_table.h
125 lines (112 loc) · 4.97 KB
/
static_table.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#ifndef AOS_FLATBUFFERS_STATIC_TABLE_H_
#define AOS_FLATBUFFERS_STATIC_TABLE_H_
#include <algorithm>
#include <span>
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "flatbuffers/base.h"
#include "aos/flatbuffers/base.h"
namespace aos::fbs {
// This Table object is used as the parent class to the generated code for every
// flatbuffer table that we generate code for.
// This object primarily serves to provide some useful common methods for
// mutating the flatbuffer memory.
//
// Every table will be aligned to the greatest alignment of all of its members
// and its size will be equal to a multiple of the alignment. Each table shall
// have the following layout: [vtable offset; inline data with padding; vtable;
// table/vector data with padding]
//
// Within the table/vector data with padding section, there will be a chunk of
// memory for the data associated with each sub-table/vector of the table.
// That memory will start with some padding and then the memory actually
// allocated to the table/vector in question will start at said
// sub-table/vector's individual alignment.
class Table : public ResizeableObject {
public:
// Prints out a debug string of the raw flatbuffer memory. Does not currently
// do anything intelligent ot traverse down into the subobjects of the
// flatbuffer (if you want that, then use the flatbuffer binary
// annotator---this code mostly exists for debugging the static flatbuffers
// implementation itself).
std::string SerializationDebugString() const {
std::stringstream str;
str << "Size: " << buffer_.size() << " alignment: " << Alignment() << "\n";
str << "Observed Vtable offset " << Get<soffset_t>(0) << "\n";
str << "Inline Size " << InlineTableSize() << " Inline Bytes:\n";
internal::DebugBytes(internal::GetSubSpan(buffer_, 4, InlineTableSize()),
str);
str << "Vtable offset " << FixedVtableOffset() << " Vtable size "
<< VtableSize() << " Vtable contents:\n";
internal::DebugBytes(
internal::GetSubSpan(buffer_, FixedVtableOffset(), VtableSize()), str);
str << "Offset data offset " << OffsetDataStart() << "\n";
// Actual contents can be big; don't print them out until we run into a
// situation where we need to debug that.
return str.str();
}
protected:
static constexpr size_t kMinAlign = alignof(uoffset_t);
Table(std::span<uint8_t> buffer, ResizeableObject *parent)
: ResizeableObject(buffer, parent) {}
Table(std::span<uint8_t> buffer, Allocator *allocator)
: ResizeableObject(buffer, allocator) {}
Table(std::span<uint8_t> buffer, ::std::unique_ptr<Allocator> allocator)
: ResizeableObject(buffer, ::std::move(allocator)) {}
Table(Table &&) = default;
virtual ~Table() {}
virtual size_t FixedVtableOffset() const = 0;
virtual size_t VtableSize() const = 0;
virtual size_t InlineTableSize() const = 0;
virtual size_t OffsetDataStart() const = 0;
void PopulateVtable() {
// Zero out everything up to the start of the sub-messages/tables, which are
// responsible for doing their own memory initialization.
internal::ClearSpan(internal::GetSubSpan(buffer_, 0, OffsetDataStart()));
// Set the offset to the start of the vtable (points backwards, hence the
// sign inversion).
Set<soffset_t>(0, -FixedVtableOffset());
// First element of the vtable is the size of the table.
Set<voffset_t>(FixedVtableOffset(), VtableSize());
// Second element of the vtable is the size of the inlined data (not really
// used by anything...).
Set<voffset_t>(FixedVtableOffset() + sizeof(voffset_t), InlineTableSize());
}
template <typename T>
void SetField(size_t absolute_offset, size_t vtable_offset, const T &value) {
Set<T>(absolute_offset, value);
CHECK_EQ(0u, (absolute_offset + reinterpret_cast<size_t>(buffer_.data())) %
alignof(T));
Set<voffset_t>(FixedVtableOffset() + vtable_offset, absolute_offset);
}
void ClearField(size_t absolute_offset, size_t inline_size,
size_t vtable_offset) {
// TODO: Remove/account for any excess allocated memory.
internal::ClearSpan(
internal::GetSubSpan(buffer_, absolute_offset, inline_size));
Set<voffset_t>(FixedVtableOffset() + vtable_offset, 0);
}
template <typename T>
const T &Get(size_t absolute_offset) const {
return *reinterpret_cast<const T *>(buffer_.data() + absolute_offset);
}
template <typename T>
T *MutableGet(size_t absolute_offset) {
return reinterpret_cast<T *>(buffer_.data() + absolute_offset);
}
template <typename T>
T *GetMutableFlatbuffer() {
return reinterpret_cast<T *>(buffer_.data());
}
template <typename T>
const T *GetFlatbuffer() const {
return reinterpret_cast<const T *>(buffer_.data());
}
private:
template <typename T>
void Set(size_t absolute_offset, const T &value) {
*reinterpret_cast<T *>(buffer_.data() + absolute_offset) = value;
}
};
} // namespace aos::fbs
#endif // AOS_FLATBUFFERS_STATIC_TABLE_H_