mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-08 06:05:17 +00:00
Efficient Conversion of a FlatBufferBuilder to a MessageBuilder (#4980)
* Efficient conversion of FlatBufferBuilder to grpc::MessageBuilder * Added a variety of tests to validate correctness of the MessageBuilder move operations. Disable MessageBuilder half-n-half tests on MacOS. * Fix failing Android build * Generalized the MessageBuilder move constructor to accept a deallocator
This commit is contained in:
committed by
Wouter van Oortmerssen
parent
ad8b1e5dbd
commit
802639e40d
@@ -425,6 +425,10 @@ class DefaultAllocator : public Allocator {
|
||||
void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE {
|
||||
delete[] p;
|
||||
}
|
||||
|
||||
static void dealloc(void *p, size_t) {
|
||||
delete[] static_cast<uint8_t *>(p);
|
||||
}
|
||||
};
|
||||
|
||||
// These functions allow for a null allocator to mean use the default allocator,
|
||||
@@ -549,7 +553,7 @@ class DetachedBuffer {
|
||||
#endif // !defined(FLATBUFFERS_CPP98_STL)
|
||||
// clang-format on
|
||||
|
||||
protected:
|
||||
protected:
|
||||
Allocator *allocator_;
|
||||
bool own_allocator_;
|
||||
uint8_t *buf_;
|
||||
@@ -986,7 +990,7 @@ class FlatBufferBuilder {
|
||||
/// `FlatBuffer` starts.
|
||||
/// @return A raw pointer to the start of the memory block containing
|
||||
/// the serialized `FlatBuffer`.
|
||||
/// @remark If the allocator is owned, it gets deleted during this call.
|
||||
/// @remark If the allocator is owned, it gets deleted when the destructor is called..
|
||||
uint8_t *ReleaseRaw(size_t &size, size_t &offset) {
|
||||
Finished();
|
||||
return buf_.release_raw(size, offset);
|
||||
@@ -1759,7 +1763,12 @@ class FlatBufferBuilder {
|
||||
Finish(root.o, file_identifier, true);
|
||||
}
|
||||
|
||||
protected:
|
||||
void SwapBufAllocator(FlatBufferBuilder &other) {
|
||||
buf_.swap_allocator(other.buf_);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
// You shouldn't really be copying instances of this class.
|
||||
FlatBufferBuilder(const FlatBufferBuilder &);
|
||||
FlatBufferBuilder &operator=(const FlatBufferBuilder &);
|
||||
|
||||
@@ -164,7 +164,7 @@ class MessageBuilder : private detail::SliceAllocatorMember,
|
||||
public FlatBufferBuilder {
|
||||
public:
|
||||
explicit MessageBuilder(uoffset_t initial_size = 1024)
|
||||
: FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
|
||||
: FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
|
||||
|
||||
MessageBuilder(const MessageBuilder &other) = delete;
|
||||
MessageBuilder &operator=(const MessageBuilder &other) = delete;
|
||||
@@ -175,6 +175,30 @@ class MessageBuilder : private detail::SliceAllocatorMember,
|
||||
Swap(other);
|
||||
}
|
||||
|
||||
/// Create a MessageBuilder from a FlatBufferBuilder.
|
||||
explicit MessageBuilder(FlatBufferBuilder &&src, void (*dealloc)(void*, size_t) = &DefaultAllocator::dealloc)
|
||||
: FlatBufferBuilder(1024, &slice_allocator_, false) {
|
||||
src.Swap(*this);
|
||||
src.SwapBufAllocator(*this);
|
||||
if (buf_.capacity()) {
|
||||
uint8_t *buf = buf_.scratch_data(); // pointer to memory
|
||||
size_t capacity = buf_.capacity(); // size of memory
|
||||
slice_allocator_.slice_ = grpc_slice_new_with_len(buf, capacity, dealloc);
|
||||
}
|
||||
else {
|
||||
slice_allocator_.slice_ = grpc_empty_slice();
|
||||
}
|
||||
}
|
||||
|
||||
/// Move-assign a FlatBufferBuilder to a MessageBuilder.
|
||||
/// Only FlatBufferBuilder with default allocator (basically, nullptr) is supported.
|
||||
MessageBuilder &operator=(FlatBufferBuilder &&src) {
|
||||
// Move construct a temporary and swap
|
||||
MessageBuilder temp(std::move(src));
|
||||
Swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MessageBuilder &operator=(MessageBuilder &&other) {
|
||||
// Move construct a temporary and swap
|
||||
MessageBuilder temp(std::move(other));
|
||||
|
||||
Reference in New Issue
Block a user