File indexing completed on 2025-08-27 09:30:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef FLATBUFFERS_GRPC_H_
0018 #define FLATBUFFERS_GRPC_H_
0019
0020
0021
0022 #include "flatbuffers/flatbuffers.h"
0023 #include "grpcpp/support/byte_buffer.h"
0024 #include "grpcpp/support/slice.h"
0025
0026 namespace flatbuffers {
0027 namespace grpc {
0028
0029
0030
0031
0032
0033 template<class T> class Message {
0034 public:
0035 Message() {}
0036
0037 Message(::grpc::Slice slice) : slice_(slice) {}
0038
0039 Message &operator=(const Message &other) = delete;
0040
0041 Message(Message &&other) = default;
0042
0043 Message(const Message &other) = delete;
0044
0045 Message &operator=(Message &&other) = default;
0046
0047 const uint8_t *mutable_data() const { return slice_.begin(); }
0048
0049 const uint8_t *data() const { return slice_.begin(); }
0050
0051 size_t size() const { return slice_.size(); }
0052
0053 bool Verify() const {
0054 Verifier verifier(data(), size());
0055 return verifier.VerifyBuffer<T>(nullptr);
0056 }
0057
0058 T *GetMutableRoot() { return flatbuffers::GetMutableRoot<T>(mutable_data()); }
0059
0060 const T *GetRoot() const { return flatbuffers::GetRoot<T>(data()); }
0061
0062
0063 const ::grpc::Slice &BorrowSlice() const { return slice_; }
0064
0065 private:
0066 ::grpc::Slice slice_;
0067 };
0068
0069 class MessageBuilder;
0070
0071
0072
0073
0074 class SliceAllocator : public Allocator {
0075 public:
0076 SliceAllocator() {}
0077
0078 SliceAllocator(const SliceAllocator &other) = delete;
0079 SliceAllocator &operator=(const SliceAllocator &other) = delete;
0080
0081 SliceAllocator(SliceAllocator &&other) {
0082
0083 swap(other);
0084 }
0085
0086 SliceAllocator &operator=(SliceAllocator &&other) {
0087
0088 SliceAllocator temp(std::move(other));
0089 swap(temp);
0090 return *this;
0091 }
0092
0093 void swap(SliceAllocator &other) {
0094 using std::swap;
0095 swap(slice_, other.slice_);
0096 }
0097
0098 virtual ~SliceAllocator() {}
0099
0100 virtual uint8_t *allocate(size_t size) override {
0101 FLATBUFFERS_ASSERT(slice_.size() == 0);
0102 slice_ = ::grpc::Slice(size);
0103 return const_cast<uint8_t *>(slice_.begin());
0104 }
0105
0106 virtual void deallocate(uint8_t *p, size_t size) override {
0107 FLATBUFFERS_ASSERT(p == slice_.begin());
0108 FLATBUFFERS_ASSERT(size == slice_.size());
0109 slice_ = ::grpc::Slice();
0110 }
0111
0112 virtual uint8_t *reallocate_downward(uint8_t *old_p, size_t old_size,
0113 size_t new_size, size_t in_use_back,
0114 size_t in_use_front) override {
0115 FLATBUFFERS_ASSERT(old_p == slice_.begin());
0116 FLATBUFFERS_ASSERT(old_size == slice_.size());
0117 FLATBUFFERS_ASSERT(new_size > old_size);
0118 ::grpc::Slice old_slice = slice_;
0119 ::grpc::Slice new_slice = ::grpc::Slice(new_size);
0120 uint8_t *new_p = const_cast<uint8_t *>(new_slice.begin());
0121 memcpy_downward(old_p, old_size, new_p, new_size, in_use_back,
0122 in_use_front);
0123 slice_ = new_slice;
0124 return new_p;
0125 }
0126
0127 private:
0128 ::grpc::Slice &get_slice(uint8_t *p, size_t size) {
0129 FLATBUFFERS_ASSERT(p == slice_.begin());
0130 FLATBUFFERS_ASSERT(size == slice_.size());
0131 return slice_;
0132 }
0133
0134 ::grpc::Slice slice_;
0135
0136 friend class MessageBuilder;
0137 };
0138
0139
0140
0141
0142 namespace detail {
0143 struct SliceAllocatorMember {
0144 SliceAllocator slice_allocator_;
0145 };
0146 }
0147
0148
0149
0150 class MessageBuilder : private detail::SliceAllocatorMember,
0151 public FlatBufferBuilder {
0152 public:
0153 explicit MessageBuilder(uoffset_t initial_size = 1024)
0154 : FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
0155
0156 MessageBuilder(const MessageBuilder &other) = delete;
0157 MessageBuilder &operator=(const MessageBuilder &other) = delete;
0158
0159 MessageBuilder(MessageBuilder &&other)
0160 : FlatBufferBuilder(1024, &slice_allocator_, false) {
0161
0162 Swap(other);
0163 }
0164
0165
0166 explicit MessageBuilder(FlatBufferBuilder &&src,
0167 void (*dealloc)(void *,
0168 size_t) = &DefaultAllocator::dealloc)
0169 : FlatBufferBuilder(1024, &slice_allocator_, false) {
0170 src.Swap(*this);
0171 src.SwapBufAllocator(*this);
0172 if (buf_.capacity()) {
0173 uint8_t *buf = buf_.scratch_data();
0174 size_t capacity = buf_.capacity();
0175 slice_allocator_.slice_ = ::grpc::Slice(buf, capacity, dealloc);
0176 } else {
0177 slice_allocator_.slice_ = ::grpc::Slice();
0178 }
0179 }
0180
0181
0182
0183
0184 MessageBuilder &operator=(FlatBufferBuilder &&src) {
0185
0186 MessageBuilder temp(std::move(src));
0187 Swap(temp);
0188 return *this;
0189 }
0190
0191 MessageBuilder &operator=(MessageBuilder &&other) {
0192
0193 MessageBuilder temp(std::move(other));
0194 Swap(temp);
0195 return *this;
0196 }
0197
0198 void Swap(MessageBuilder &other) {
0199 slice_allocator_.swap(other.slice_allocator_);
0200 FlatBufferBuilder::Swap(other);
0201
0202
0203
0204
0205
0206 buf_.swap_allocator(other.buf_);
0207 }
0208
0209
0210
0211
0212 uint8_t *ReleaseRaw(size_t &size, size_t &offset, ::grpc::Slice &slice) {
0213 uint8_t *buf = FlatBufferBuilder::ReleaseRaw(size, offset);
0214 slice = slice_allocator_.slice_;
0215 slice_allocator_.slice_ = ::grpc::Slice();
0216 return buf;
0217 }
0218
0219 ~MessageBuilder() {}
0220
0221
0222
0223
0224 template<class T> Message<T> GetMessage() {
0225 auto buf_data = buf_.scratch_data();
0226 auto buf_size = buf_.capacity();
0227 auto msg_data = buf_.data();
0228 auto msg_size = buf_.size();
0229
0230 FLATBUFFERS_ASSERT(msg_data);
0231 FLATBUFFERS_ASSERT(msg_size);
0232 FLATBUFFERS_ASSERT(msg_data >= buf_data);
0233 FLATBUFFERS_ASSERT(msg_data + msg_size <= buf_data + buf_size);
0234
0235 auto begin = msg_data - buf_data;
0236 auto end = begin + msg_size;
0237
0238 ::grpc::Slice slice = slice_allocator_.get_slice(buf_data, buf_size);
0239
0240 ::grpc::Slice subslice = slice.sub(begin, end);
0241
0242 Message<T> msg(subslice);
0243 return msg;
0244 }
0245
0246 template<class T> Message<T> ReleaseMessage() {
0247 Message<T> msg = GetMessage<T>();
0248 Reset();
0249 return msg;
0250 }
0251
0252 private:
0253
0254 };
0255
0256 }
0257 }
0258
0259 namespace grpc {
0260
0261 template<class T> class SerializationTraits<flatbuffers::grpc::Message<T>> {
0262 public:
0263 static grpc::Status Serialize(const flatbuffers::grpc::Message<T> &msg,
0264 ByteBuffer *buffer, bool *own_buffer) {
0265
0266
0267 *buffer = ByteBuffer(&msg.BorrowSlice(), 1);
0268 *own_buffer = true;
0269 return grpc::Status::OK;
0270 }
0271
0272
0273 static grpc::Status Deserialize(ByteBuffer *buf,
0274 flatbuffers::grpc::Message<T> *msg) {
0275 Slice slice;
0276 if (!buf->TrySingleSlice(&slice).ok()) {
0277 if (!buf->DumpToSingleSlice(&slice).ok()) {
0278 buf->Clear();
0279 return ::grpc::Status(::grpc::StatusCode::INTERNAL, "No payload");
0280 }
0281 }
0282 *msg = flatbuffers::grpc::Message<T>(slice);
0283 buf->Clear();
0284 #if FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION
0285 return ::grpc::Status::OK;
0286 #else
0287 if (msg->Verify()) {
0288 return ::grpc::Status::OK;
0289 } else {
0290 return ::grpc::Status(::grpc::StatusCode::INTERNAL,
0291 "Message verification failed");
0292 }
0293 #endif
0294 }
0295 };
0296
0297 }
0298
0299 #endif