| /* | |
| * | |
| * Copyright 2017 gRPC authors. | |
| * | |
| * 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 GRPCPP_IMPL_CODEGEN_BYTE_BUFFER_H | |
| #define GRPCPP_IMPL_CODEGEN_BYTE_BUFFER_H | |
| #include <grpc/impl/codegen/byte_buffer.h> | |
| #include <grpcpp/impl/codegen/config.h> | |
| #include <grpcpp/impl/codegen/core_codegen_interface.h> | |
| #include <grpcpp/impl/codegen/serialization_traits.h> | |
| #include <grpcpp/impl/codegen/slice.h> | |
| #include <grpcpp/impl/codegen/status.h> | |
| #include <vector> | |
| namespace grpc { | |
| class ServerInterface; | |
| class ByteBuffer; | |
| class ServerInterface; | |
| namespace internal { | |
| class CallOpSendMessage; | |
| template <class R> | |
| class CallOpRecvMessage; | |
| class CallOpGenericRecvMessage; | |
| class MethodHandler; | |
| template <class ServiceType, class RequestType, class ResponseType> | |
| class RpcMethodHandler; | |
| template <class ServiceType, class RequestType, class ResponseType> | |
| class ServerStreamingHandler; | |
| template <class RequestType, class ResponseType> | |
| class CallbackUnaryHandler; | |
| template <class RequestType, class ResponseType> | |
| class CallbackServerStreamingHandler; | |
| template <StatusCode code> | |
| class ErrorMethodHandler; | |
| template <class R> | |
| class DeserializeFuncType; | |
| class GrpcByteBufferPeer; | |
| template <class ServiceType, class RequestType, class ResponseType> | |
| class RpcMethodHandler; | |
| template <class ServiceType, class RequestType, class ResponseType> | |
| class ServerStreamingHandler; | |
| } // namespace internal | |
| /// A sequence of bytes. | |
| class ByteBuffer final { | |
| public: | |
| /// Constuct an empty buffer. | |
| ByteBuffer() : buffer_(nullptr) {} | |
| /// Construct buffer from \a slices, of which there are \a nslices. | |
| ByteBuffer(const Slice* slices, size_t nslices) { | |
| // The following assertions check that the representation of a grpc::Slice | |
| // is identical to that of a grpc_slice: it has a grpc_slice field, and | |
| // nothing else. | |
| static_assert(std::is_same<decltype(slices[0].slice_), grpc_slice>::value, | |
| "Slice must have same representation as grpc_slice"); | |
| static_assert(sizeof(Slice) == sizeof(grpc_slice), | |
| "Slice must have same representation as grpc_slice"); | |
| // The following assertions check that the representation of a ByteBuffer is | |
| // identical to grpc_byte_buffer*: it has a grpc_byte_buffer* field, | |
| // and nothing else. | |
| static_assert(std::is_same<decltype(buffer_), grpc_byte_buffer*>::value, | |
| "ByteBuffer must have same representation as " | |
| "grpc_byte_buffer*"); | |
| static_assert(sizeof(ByteBuffer) == sizeof(grpc_byte_buffer*), | |
| "ByteBuffer must have same representation as " | |
| "grpc_byte_buffer*"); | |
| // The const_cast is legal if grpc_raw_byte_buffer_create() does no more | |
| // than its advertised side effect of increasing the reference count of the | |
| // slices it processes, and such an increase does not affect the semantics | |
| // seen by the caller of this constructor. | |
| buffer_ = g_core_codegen_interface->grpc_raw_byte_buffer_create( | |
| reinterpret_cast<grpc_slice*>(const_cast<Slice*>(slices)), nslices); | |
| } | |
| /// Constuct a byte buffer by referencing elements of existing buffer | |
| /// \a buf. Wrapper of core function grpc_byte_buffer_copy . This is not | |
| /// a deep copy; it is just a referencing. As a result, its performance is | |
| /// size-independent. | |
| ByteBuffer(const ByteBuffer& buf); | |
| ~ByteBuffer() { | |
| if (buffer_) { | |
| g_core_codegen_interface->grpc_byte_buffer_destroy(buffer_); | |
| } | |
| } | |
| /// Wrapper of core function grpc_byte_buffer_copy . This is not | |
| /// a deep copy; it is just a referencing. As a result, its performance is | |
| /// size-independent. | |
| ByteBuffer& operator=(const ByteBuffer&); | |
| /// Dump (read) the buffer contents into \a slices. | |
| Status Dump(std::vector<Slice>* slices) const; | |
| /// Remove all data. | |
| void Clear() { | |
| if (buffer_) { | |
| g_core_codegen_interface->grpc_byte_buffer_destroy(buffer_); | |
| buffer_ = nullptr; | |
| } | |
| } | |
| /// Make a duplicate copy of the internals of this byte | |
| /// buffer so that we have our own owned version of it. | |
| /// bbuf.Duplicate(); is equivalent to bbuf=bbuf; but is actually readable. | |
| /// This is not a deep copy; it is a referencing and its performance | |
| /// is size-independent. | |
| void Duplicate() { | |
| buffer_ = g_core_codegen_interface->grpc_byte_buffer_copy(buffer_); | |
| } | |
| /// Forget underlying byte buffer without destroying | |
| /// Use this only for un-owned byte buffers | |
| void Release() { buffer_ = nullptr; } | |
| /// Buffer size in bytes. | |
| size_t Length() const { | |
| return buffer_ == nullptr | |
| ? 0 | |
| : g_core_codegen_interface->grpc_byte_buffer_length(buffer_); | |
| } | |
| /// Swap the state of *this and *other. | |
| void Swap(ByteBuffer* other) { | |
| grpc_byte_buffer* tmp = other->buffer_; | |
| other->buffer_ = buffer_; | |
| buffer_ = tmp; | |
| } | |
| /// Is this ByteBuffer valid? | |
| bool Valid() const { return (buffer_ != nullptr); } | |
| private: | |
| friend class SerializationTraits<ByteBuffer, void>; | |
| friend class ServerInterface; | |
| friend class internal::CallOpSendMessage; | |
| template <class R> | |
| friend class internal::CallOpRecvMessage; | |
| friend class internal::CallOpGenericRecvMessage; | |
| template <class ServiceType, class RequestType, class ResponseType> | |
| friend class RpcMethodHandler; | |
| template <class ServiceType, class RequestType, class ResponseType> | |
| friend class ServerStreamingHandler; | |
| template <class ServiceType, class RequestType, class ResponseType> | |
| friend class internal::RpcMethodHandler; | |
| template <class ServiceType, class RequestType, class ResponseType> | |
| friend class internal::ServerStreamingHandler; | |
| template <class RequestType, class ResponseType> | |
| friend class internal::CallbackUnaryHandler; | |
| template <class RequestType, class ResponseType> | |
| friend class ::grpc::internal::CallbackServerStreamingHandler; | |
| template <StatusCode code> | |
| friend class internal::ErrorMethodHandler; | |
| template <class R> | |
| friend class internal::DeserializeFuncType; | |
| friend class ProtoBufferReader; | |
| friend class ProtoBufferWriter; | |
| friend class internal::GrpcByteBufferPeer; | |
| grpc_byte_buffer* buffer_; | |
| // takes ownership | |
| void set_buffer(grpc_byte_buffer* buf) { | |
| if (buffer_) { | |
| Clear(); | |
| } | |
| buffer_ = buf; | |
| } | |
| grpc_byte_buffer* c_buffer() { return buffer_; } | |
| grpc_byte_buffer** c_buffer_ptr() { return &buffer_; } | |
| class ByteBufferPointer { | |
| public: | |
| ByteBufferPointer(const ByteBuffer* b) | |
| : bbuf_(const_cast<ByteBuffer*>(b)) {} | |
| operator ByteBuffer*() { return bbuf_; } | |
| operator grpc_byte_buffer*() { return bbuf_->buffer_; } | |
| operator grpc_byte_buffer**() { return &bbuf_->buffer_; } | |
| private: | |
| ByteBuffer* bbuf_; | |
| }; | |
| ByteBufferPointer bbuf_ptr() const { return ByteBufferPointer(this); } | |
| }; | |
| template <> | |
| class SerializationTraits<ByteBuffer, void> { | |
| public: | |
| static Status Deserialize(ByteBuffer* byte_buffer, ByteBuffer* dest) { | |
| dest->set_buffer(byte_buffer->buffer_); | |
| return Status::OK; | |
| } | |
| static Status Serialize(const ByteBuffer& source, ByteBuffer* buffer, | |
| bool* own_buffer) { | |
| *buffer = source; | |
| *own_buffer = true; | |
| return Status::OK; | |
| } | |
| }; | |
| } // namespace grpc | |
| #endif // GRPCPP_IMPL_CODEGEN_BYTE_BUFFER_H |