1 /* 2 * 3 * Copyright 2017 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 #ifndef GRPCPP_IMPL_CODEGEN_BYTE_BUFFER_H 20 #define GRPCPP_IMPL_CODEGEN_BYTE_BUFFER_H 21 22 #include <grpc/impl/codegen/byte_buffer.h> 23 24 #include <grpcpp/impl/codegen/config.h> 25 #include <grpcpp/impl/codegen/core_codegen_interface.h> 26 #include <grpcpp/impl/codegen/serialization_traits.h> 27 #include <grpcpp/impl/codegen/slice.h> 28 #include <grpcpp/impl/codegen/status.h> 29 30 #include <vector> 31 32 namespace grpc_impl { 33 namespace internal { 34 35 template <class RequestType, class ResponseType> 36 class CallbackUnaryHandler; 37 template <class RequestType, class ResponseType> 38 class CallbackServerStreamingHandler; 39 template <class ServiceType, class RequestType, class ResponseType> 40 class RpcMethodHandler; 41 template <class ServiceType, class RequestType, class ResponseType> 42 class ServerStreamingHandler; 43 template <::grpc::StatusCode code> 44 class ErrorMethodHandler; 45 46 } // namespace internal 47 } // namespace grpc_impl 48 49 namespace grpc { 50 51 class ServerInterface; 52 class ByteBuffer; 53 class ServerInterface; 54 55 namespace internal { 56 class CallOpSendMessage; 57 template <class R> 58 class CallOpRecvMessage; 59 class CallOpGenericRecvMessage; 60 class ExternalConnectionAcceptorImpl; 61 template <class R> 62 class DeserializeFuncType; 63 class GrpcByteBufferPeer; 64 65 } // namespace internal 66 /// A sequence of bytes. 67 class ByteBuffer final { 68 public: 69 /// Constuct an empty buffer. ByteBuffer()70 ByteBuffer() : buffer_(nullptr) {} 71 72 /// Construct buffer from \a slices, of which there are \a nslices. ByteBuffer(const Slice * slices,size_t nslices)73 ByteBuffer(const Slice* slices, size_t nslices) { 74 // The following assertions check that the representation of a grpc::Slice 75 // is identical to that of a grpc_slice: it has a grpc_slice field, and 76 // nothing else. 77 static_assert(std::is_same<decltype(slices[0].slice_), grpc_slice>::value, 78 "Slice must have same representation as grpc_slice"); 79 static_assert(sizeof(Slice) == sizeof(grpc_slice), 80 "Slice must have same representation as grpc_slice"); 81 // The following assertions check that the representation of a ByteBuffer is 82 // identical to grpc_byte_buffer*: it has a grpc_byte_buffer* field, 83 // and nothing else. 84 static_assert(std::is_same<decltype(buffer_), grpc_byte_buffer*>::value, 85 "ByteBuffer must have same representation as " 86 "grpc_byte_buffer*"); 87 static_assert(sizeof(ByteBuffer) == sizeof(grpc_byte_buffer*), 88 "ByteBuffer must have same representation as " 89 "grpc_byte_buffer*"); 90 // The const_cast is legal if grpc_raw_byte_buffer_create() does no more 91 // than its advertised side effect of increasing the reference count of the 92 // slices it processes, and such an increase does not affect the semantics 93 // seen by the caller of this constructor. 94 buffer_ = g_core_codegen_interface->grpc_raw_byte_buffer_create( 95 reinterpret_cast<grpc_slice*>(const_cast<Slice*>(slices)), nslices); 96 } 97 98 /// Constuct a byte buffer by referencing elements of existing buffer 99 /// \a buf. Wrapper of core function grpc_byte_buffer_copy . This is not 100 /// a deep copy; it is just a referencing. As a result, its performance is 101 /// size-independent. ByteBuffer(const ByteBuffer & buf)102 ByteBuffer(const ByteBuffer& buf) : buffer_(nullptr) { operator=(buf); } 103 ~ByteBuffer()104 ~ByteBuffer() { 105 if (buffer_) { 106 g_core_codegen_interface->grpc_byte_buffer_destroy(buffer_); 107 } 108 } 109 110 /// Wrapper of core function grpc_byte_buffer_copy . This is not 111 /// a deep copy; it is just a referencing. As a result, its performance is 112 /// size-independent. 113 ByteBuffer& operator=(const ByteBuffer& buf) { 114 if (this != &buf) { 115 Clear(); // first remove existing data 116 } 117 if (buf.buffer_) { 118 // then copy 119 buffer_ = g_core_codegen_interface->grpc_byte_buffer_copy(buf.buffer_); 120 } 121 return *this; 122 } 123 124 /// Dump (read) the buffer contents into \a slices. 125 Status Dump(std::vector<Slice>* slices) const; 126 127 /// Remove all data. Clear()128 void Clear() { 129 if (buffer_) { 130 g_core_codegen_interface->grpc_byte_buffer_destroy(buffer_); 131 buffer_ = nullptr; 132 } 133 } 134 135 /// Make a duplicate copy of the internals of this byte 136 /// buffer so that we have our own owned version of it. 137 /// bbuf.Duplicate(); is equivalent to bbuf=bbuf; but is actually readable. 138 /// This is not a deep copy; it is a referencing and its performance 139 /// is size-independent. Duplicate()140 void Duplicate() { 141 buffer_ = g_core_codegen_interface->grpc_byte_buffer_copy(buffer_); 142 } 143 144 /// Forget underlying byte buffer without destroying 145 /// Use this only for un-owned byte buffers Release()146 void Release() { buffer_ = nullptr; } 147 148 /// Buffer size in bytes. Length()149 size_t Length() const { 150 return buffer_ == nullptr 151 ? 0 152 : g_core_codegen_interface->grpc_byte_buffer_length(buffer_); 153 } 154 155 /// Swap the state of *this and *other. Swap(ByteBuffer * other)156 void Swap(ByteBuffer* other) { 157 grpc_byte_buffer* tmp = other->buffer_; 158 other->buffer_ = buffer_; 159 buffer_ = tmp; 160 } 161 162 /// Is this ByteBuffer valid? Valid()163 bool Valid() const { return (buffer_ != nullptr); } 164 165 private: 166 friend class SerializationTraits<ByteBuffer, void>; 167 friend class ServerInterface; 168 friend class internal::CallOpSendMessage; 169 template <class R> 170 friend class internal::CallOpRecvMessage; 171 friend class internal::CallOpGenericRecvMessage; 172 template <class ServiceType, class RequestType, class ResponseType> 173 friend class ::grpc_impl::internal::RpcMethodHandler; 174 template <class ServiceType, class RequestType, class ResponseType> 175 friend class ::grpc_impl::internal::ServerStreamingHandler; 176 template <class RequestType, class ResponseType> 177 friend class ::grpc_impl::internal::CallbackUnaryHandler; 178 template <class RequestType, class ResponseType> 179 friend class ::grpc_impl::internal::CallbackServerStreamingHandler; 180 template <StatusCode code> 181 friend class ::grpc_impl::internal::ErrorMethodHandler; 182 template <class R> 183 friend class internal::DeserializeFuncType; 184 friend class ProtoBufferReader; 185 friend class ProtoBufferWriter; 186 friend class internal::GrpcByteBufferPeer; 187 friend class internal::ExternalConnectionAcceptorImpl; 188 189 grpc_byte_buffer* buffer_; 190 191 // takes ownership set_buffer(grpc_byte_buffer * buf)192 void set_buffer(grpc_byte_buffer* buf) { 193 if (buffer_) { 194 Clear(); 195 } 196 buffer_ = buf; 197 } 198 c_buffer()199 grpc_byte_buffer* c_buffer() { return buffer_; } c_buffer_ptr()200 grpc_byte_buffer** c_buffer_ptr() { return &buffer_; } 201 202 class ByteBufferPointer { 203 public: ByteBufferPointer(const ByteBuffer * b)204 ByteBufferPointer(const ByteBuffer* b) 205 : bbuf_(const_cast<ByteBuffer*>(b)) {} 206 operator ByteBuffer*() { return bbuf_; } 207 operator grpc_byte_buffer*() { return bbuf_->buffer_; } 208 operator grpc_byte_buffer**() { return &bbuf_->buffer_; } 209 210 private: 211 ByteBuffer* bbuf_; 212 }; bbuf_ptr()213 ByteBufferPointer bbuf_ptr() const { return ByteBufferPointer(this); } 214 }; 215 216 template <> 217 class SerializationTraits<ByteBuffer, void> { 218 public: Deserialize(ByteBuffer * byte_buffer,ByteBuffer * dest)219 static Status Deserialize(ByteBuffer* byte_buffer, ByteBuffer* dest) { 220 dest->set_buffer(byte_buffer->buffer_); 221 return Status::OK; 222 } Serialize(const ByteBuffer & source,ByteBuffer * buffer,bool * own_buffer)223 static Status Serialize(const ByteBuffer& source, ByteBuffer* buffer, 224 bool* own_buffer) { 225 *buffer = source; 226 *own_buffer = true; 227 return g_core_codegen_interface->ok(); 228 } 229 }; 230 231 } // namespace grpc 232 233 #endif // GRPCPP_IMPL_CODEGEN_BYTE_BUFFER_H 234