/* * Copyright 2014 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef FLATBUFFERS_GRPC_H_ #define FLATBUFFERS_GRPC_H_ // Helper functionality to glue FlatBuffers and GRPC. #include "grpc++/support/byte_buffer.h" #include "grpc/byte_buffer_reader.h" namespace grpc { template class SerializationTraits::value>::type> { public: // The type we're passing here is a BufferRef, which is already serialized // FlatBuffer data, which then gets passed to GRPC. static grpc::Status Serialize(const T& msg, grpc_byte_buffer **buffer, bool *own_buffer) { // TODO(wvo): make this work without copying. auto slice = gpr_slice_from_copied_buffer( reinterpret_cast(msg.buf), msg.len); *buffer = grpc_raw_byte_buffer_create(&slice, 1); *own_buffer = true; return grpc::Status(); } // There is no de-serialization step in FlatBuffers, so we just receive // the data from GRPC. static grpc::Status Deserialize(grpc_byte_buffer *buffer, T *msg, int max_message_size) { // TODO(wvo): make this more efficient / zero copy when possible. auto len = grpc_byte_buffer_length(buffer); msg->buf = reinterpret_cast(malloc(len)); msg->len = static_cast(len); msg->must_free = true; uint8_t *current = msg->buf; grpc_byte_buffer_reader reader; grpc_byte_buffer_reader_init(&reader, buffer); gpr_slice slice; while (grpc_byte_buffer_reader_next(&reader, &slice)) { memcpy(current, GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice)); current += GPR_SLICE_LENGTH(slice); gpr_slice_unref(slice); } GPR_ASSERT(current == msg->buf + msg->len); grpc_byte_buffer_reader_destroy(&reader); grpc_byte_buffer_destroy(buffer); return grpc::Status(); } }; } // namespace grpc; #endif // FLATBUFFERS_GRPC_H_