1 /* 2 * Copyright 2014 Google Inc. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef FLATBUFFERS_GRPC_H_ 18 #define FLATBUFFERS_GRPC_H_ 19 20 // Helper functionality to glue FlatBuffers and GRPC. 21 22 #include "grpc++/support/byte_buffer.h" 23 #include "grpc/byte_buffer_reader.h" 24 25 namespace grpc { 26 27 template <class T> 28 class SerializationTraits<T, typename std::enable_if<std::is_base_of< 29 flatbuffers::BufferRefBase, T>::value>::type> { 30 public: 31 // The type we're passing here is a BufferRef, which is already serialized 32 // FlatBuffer data, which then gets passed to GRPC. Serialize(const T & msg,grpc_byte_buffer ** buffer,bool * own_buffer)33 static grpc::Status Serialize(const T& msg, 34 grpc_byte_buffer **buffer, 35 bool *own_buffer) { 36 // TODO(wvo): make this work without copying. 37 auto slice = gpr_slice_from_copied_buffer( 38 reinterpret_cast<const char *>(msg.buf), msg.len); 39 *buffer = grpc_raw_byte_buffer_create(&slice, 1); 40 *own_buffer = true; 41 return grpc::Status(); 42 } 43 44 // There is no de-serialization step in FlatBuffers, so we just receive 45 // the data from GRPC. Deserialize(grpc_byte_buffer * buffer,T * msg)46 static grpc::Status Deserialize(grpc_byte_buffer *buffer, T *msg) { 47 // TODO(wvo): make this more efficient / zero copy when possible. 48 auto len = grpc_byte_buffer_length(buffer); 49 msg->buf = reinterpret_cast<uint8_t *>(malloc(len)); 50 msg->len = static_cast<flatbuffers::uoffset_t>(len); 51 msg->must_free = true; 52 uint8_t *current = msg->buf; 53 grpc_byte_buffer_reader reader; 54 grpc_byte_buffer_reader_init(&reader, buffer); 55 gpr_slice slice; 56 while (grpc_byte_buffer_reader_next(&reader, &slice)) { 57 memcpy(current, GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice)); 58 current += GPR_SLICE_LENGTH(slice); 59 gpr_slice_unref(slice); 60 } 61 GPR_ASSERT(current == msg->buf + msg->len); 62 grpc_byte_buffer_reader_destroy(&reader); 63 grpc_byte_buffer_destroy(buffer); 64 return grpc::Status(); 65 } 66 }; 67 68 } // namespace grpc; 69 70 #endif // FLATBUFFERS_GRPC_H_ 71