Rename Location to Channel and add extra Flatbuffer helpers
This now follows the convention in the design doc and is more closely
aligned to classic pubsub terminology.
Also add a Flatbuffer<T> base type, along with both an array backed
version. Rename the DetachedBuffer variant.
Change-Id: I257b5dbb5838120c479c4b98139657fc08e73150
diff --git a/aos/flatbuffers.h b/aos/flatbuffers.h
index 6f6fc11..448f34b 100644
--- a/aos/flatbuffers.h
+++ b/aos/flatbuffers.h
@@ -5,8 +5,99 @@
namespace aos {
-// TODO(austin): FlatbufferBase ? We can associate the type table with it, and
-// make it generic.
+// This class is a base class for all sizes of array backed allocators.
+class FixedAllocatorBase : public flatbuffers::Allocator {
+ public:
+ // TODO(austin): Read the contract for these.
+ uint8_t *allocate(size_t) override;
+
+ void deallocate(uint8_t *, size_t) override { is_allocated_ = false; }
+
+ uint8_t *reallocate_downward(uint8_t *, size_t, size_t, size_t,
+ size_t) override;
+
+ virtual const uint8_t *data() const = 0;
+ virtual uint8_t *data() = 0;
+ virtual size_t size() const = 0;
+
+ private:
+ bool is_allocated_ = false;
+};
+
+// This class is a fixed memory allocator which holds the data for a flatbuffer
+// in an array.
+template <size_t S>
+class FixedAllocator : public FixedAllocatorBase {
+ public:
+ uint8_t *data() override { return &buffer_[0]; }
+ const uint8_t *data() const override { return &buffer_[0]; }
+ size_t size() const override { return buffer_.size(); }
+
+ private:
+ std::array<uint8_t, S> buffer_;
+};
+
+// Base class representing an object which holds the memory representing a root
+// flatbuffer.
+template <typename T>
+class Flatbuffer {
+ public:
+ // Returns the MiniReflectTypeTable for T.
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return T::MiniReflectTypeTable();
+ }
+
+ // Returns a message from the buffer.
+ const T &message() const {
+ return *flatbuffers::GetRoot<T>(reinterpret_cast<const void *>(data()));
+ }
+ // Returns a mutable message. It can be mutated via the flatbuffer rules.
+ T *mutable_message() {
+ return flatbuffers::GetMutableRoot<T>(reinterpret_cast<void *>(data()));
+ }
+
+ virtual const uint8_t *data() const = 0;
+ virtual uint8_t *data() = 0;
+ virtual size_t size() const = 0;
+};
+
+// Array backed flatbuffer.
+template <typename T>
+class FlatbufferArray : public Flatbuffer<T> {
+ public:
+ // Builds a Flatbuffer by copying the data from the other flatbuffer.
+ FlatbufferArray(const Flatbuffer<T> &other) {
+ CHECK_LE(other.size(), data_.size());
+
+ memcpy(data_.data(), other.data(), other.size());
+ size_ = other.size();
+ }
+
+ // Coppies the data from the other flatbuffer.
+ FlatbufferArray &operator=(const Flatbuffer<T> &other) {
+ CHECK_LE(other.size(), data_.size());
+
+ memcpy(data_.data(), other.data(), other.size());
+ size_ = other.size();
+ return *this;
+ }
+
+ // Creates a builder wrapping the underlying data.
+ flatbuffers::FlatBufferBuilder FlatBufferBuilder() {
+ data_.deallocate(data_.data(), data_.size());
+ flatbuffers::FlatBufferBuilder fbb(data_.size(), &data_);
+ fbb.ForceDefaults(1);
+ return fbb;
+ }
+
+ const uint8_t *data() const override { return data_.data(); }
+ uint8_t *data() override { return data_.data(); }
+ size_t size() const override { return size_; }
+
+ private:
+ FixedAllocator<8 * 1024> data_;
+ size_t size_ = data_.size();
+};
// This object associates the message type with the memory storing the
// flatbuffer. This only stores root tables.
@@ -14,50 +105,40 @@
// From a usage point of view, pointers to the data are very different than
// pointers to the tables.
template <typename T>
-class Flatbuffer {
+class FlatbufferDetachedBuffer : public Flatbuffer<T> {
public:
// Builds a Flatbuffer by taking ownership of the buffer.
- Flatbuffer(flatbuffers::DetachedBuffer &&buffer)
+ FlatbufferDetachedBuffer(flatbuffers::DetachedBuffer &&buffer)
: buffer_(::std::move(buffer)) {}
// Builds a flatbuffer by taking ownership of the buffer from the other
// flatbuffer.
- Flatbuffer(Flatbuffer &&fb) : buffer_(::std::move(fb.buffer_)) {}
- Flatbuffer &operator=(Flatbuffer &&fb) {
+ FlatbufferDetachedBuffer(FlatbufferDetachedBuffer &&fb)
+ : buffer_(::std::move(fb.buffer_)) {}
+ FlatbufferDetachedBuffer &operator=(FlatbufferDetachedBuffer &&fb) {
::std::swap(buffer_, fb.buffer_);
return *this;
}
// Constructs an empty flatbuffer of type T.
- static Flatbuffer<T> Empty() {
+ static FlatbufferDetachedBuffer<T> Empty() {
flatbuffers::FlatBufferBuilder fbb;
fbb.ForceDefaults(1);
const auto end = fbb.EndTable(fbb.StartTable());
fbb.Finish(flatbuffers::Offset<flatbuffers::Table>(end));
- return Flatbuffer<T>(fbb.Release());
- }
-
- // Returns the MiniReflectTypeTable for T.
- static const flatbuffers::TypeTable *MiniReflectTypeTable() {
- return T::MiniReflectTypeTable();
- }
-
- // Returns a message from the buffer.
- const T &message() const { return *flatbuffers::GetRoot<T>(buffer_.data()); }
- // Returns a mutable message. It can be mutated via the flatbuffer rules.
- T *mutable_message() {
- return flatbuffers::GetMutableRoot<T>(buffer_.data());
+ return FlatbufferDetachedBuffer<T>(fbb.Release());
}
// Returns references to the buffer, and the data.
const flatbuffers::DetachedBuffer &buffer() const { return buffer_; }
- const uint8_t *data() const { return buffer_.data(); }
+ const uint8_t *data() const override { return buffer_.data(); }
+ uint8_t *data() override { return buffer_.data(); }
+ size_t size() const override { return buffer_.size(); }
private:
flatbuffers::DetachedBuffer buffer_;
};
-// TODO(austin): Need a fixed buffer version of Flatbuffer.
// TODO(austin): Need a way to get our hands on the max size. Can start with
// "large" for now.