• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
33 
34 class ServerInterface;
35 class ByteBuffer;
36 class ServerInterface;
37 
38 namespace internal {
39 template <class RequestType, class ResponseType>
40 class CallbackUnaryHandler;
41 template <class RequestType, class ResponseType>
42 class CallbackServerStreamingHandler;
43 template <class RequestType>
44 void* UnaryDeserializeHelper(grpc_byte_buffer*, ::grpc::Status*, RequestType*);
45 template <class ServiceType, class RequestType, class ResponseType>
46 class ServerStreamingHandler;
47 template <::grpc::StatusCode code>
48 class ErrorMethodHandler;
49 class CallOpSendMessage;
50 template <class R>
51 class CallOpRecvMessage;
52 class CallOpGenericRecvMessage;
53 class ExternalConnectionAcceptorImpl;
54 template <class R>
55 class DeserializeFuncType;
56 class GrpcByteBufferPeer;
57 
58 }  // namespace internal
59 /// A sequence of bytes.
60 class ByteBuffer final {
61  public:
62   /// Constuct an empty buffer.
ByteBuffer()63   ByteBuffer() : buffer_(nullptr) {}
64 
65   /// Construct buffer from \a slices, of which there are \a nslices.
ByteBuffer(const Slice * slices,size_t nslices)66   ByteBuffer(const Slice* slices, size_t nslices) {
67     // The following assertions check that the representation of a grpc::Slice
68     // is identical to that of a grpc_slice:  it has a grpc_slice field, and
69     // nothing else.
70     static_assert(std::is_same<decltype(slices[0].slice_), grpc_slice>::value,
71                   "Slice must have same representation as grpc_slice");
72     static_assert(sizeof(Slice) == sizeof(grpc_slice),
73                   "Slice must have same representation as grpc_slice");
74     // The following assertions check that the representation of a ByteBuffer is
75     // identical to grpc_byte_buffer*:  it has a grpc_byte_buffer* field,
76     // and nothing else.
77     static_assert(std::is_same<decltype(buffer_), grpc_byte_buffer*>::value,
78                   "ByteBuffer must have same representation as "
79                   "grpc_byte_buffer*");
80     static_assert(sizeof(ByteBuffer) == sizeof(grpc_byte_buffer*),
81                   "ByteBuffer must have same representation as "
82                   "grpc_byte_buffer*");
83     // The const_cast is legal if grpc_raw_byte_buffer_create() does no more
84     // than its advertised side effect of increasing the reference count of the
85     // slices it processes, and such an increase does not affect the semantics
86     // seen by the caller of this constructor.
87     buffer_ = g_core_codegen_interface->grpc_raw_byte_buffer_create(
88         reinterpret_cast<grpc_slice*>(const_cast<Slice*>(slices)), nslices);
89   }
90 
91   /// Constuct a byte buffer by referencing elements of existing buffer
92   /// \a buf. Wrapper of core function grpc_byte_buffer_copy . This is not
93   /// a deep copy; it is just a referencing. As a result, its performance is
94   /// size-independent.
ByteBuffer(const ByteBuffer & buf)95   ByteBuffer(const ByteBuffer& buf) : buffer_(nullptr) { operator=(buf); }
96 
~ByteBuffer()97   ~ByteBuffer() {
98     if (buffer_) {
99       g_core_codegen_interface->grpc_byte_buffer_destroy(buffer_);
100     }
101   }
102 
103   /// Wrapper of core function grpc_byte_buffer_copy . This is not
104   /// a deep copy; it is just a referencing. As a result, its performance is
105   /// size-independent.
106   ByteBuffer& operator=(const ByteBuffer& buf) {
107     if (this != &buf) {
108       Clear();  // first remove existing data
109     }
110     if (buf.buffer_) {
111       // then copy
112       buffer_ = g_core_codegen_interface->grpc_byte_buffer_copy(buf.buffer_);
113     }
114     return *this;
115   }
116 
117   /// Dump (read) the buffer contents into \a slices.
118   Status Dump(std::vector<Slice>* slices) const;
119 
120   /// Remove all data.
Clear()121   void Clear() {
122     if (buffer_) {
123       g_core_codegen_interface->grpc_byte_buffer_destroy(buffer_);
124       buffer_ = nullptr;
125     }
126   }
127 
128   /// Make a duplicate copy of the internals of this byte
129   /// buffer so that we have our own owned version of it.
130   /// bbuf.Duplicate(); is equivalent to bbuf=bbuf; but is actually readable.
131   /// This is not a deep copy; it is a referencing and its performance
132   /// is size-independent.
Duplicate()133   void Duplicate() {
134     buffer_ = g_core_codegen_interface->grpc_byte_buffer_copy(buffer_);
135   }
136 
137   /// Forget underlying byte buffer without destroying
138   /// Use this only for un-owned byte buffers
Release()139   void Release() { buffer_ = nullptr; }
140 
141   /// Buffer size in bytes.
Length()142   size_t Length() const {
143     return buffer_ == nullptr
144                ? 0
145                : g_core_codegen_interface->grpc_byte_buffer_length(buffer_);
146   }
147 
148   /// Swap the state of *this and *other.
Swap(ByteBuffer * other)149   void Swap(ByteBuffer* other) {
150     grpc_byte_buffer* tmp = other->buffer_;
151     other->buffer_ = buffer_;
152     buffer_ = tmp;
153   }
154 
155   /// Is this ByteBuffer valid?
Valid()156   bool Valid() const { return (buffer_ != nullptr); }
157 
158  private:
159   friend class SerializationTraits<ByteBuffer, void>;
160   friend class ServerInterface;
161   friend class internal::CallOpSendMessage;
162   template <class R>
163   friend class internal::CallOpRecvMessage;
164   friend class internal::CallOpGenericRecvMessage;
165   template <class RequestType>
166   friend void* internal::UnaryDeserializeHelper(grpc_byte_buffer*,
167                                                 ::grpc::Status*, RequestType*);
168   template <class ServiceType, class RequestType, class ResponseType>
169   friend class internal::ServerStreamingHandler;
170   template <class RequestType, class ResponseType>
171   friend class internal::CallbackUnaryHandler;
172   template <class RequestType, class ResponseType>
173   friend class internal::CallbackServerStreamingHandler;
174   template <StatusCode code>
175   friend class internal::ErrorMethodHandler;
176   template <class R>
177   friend class internal::DeserializeFuncType;
178   friend class ProtoBufferReader;
179   friend class ProtoBufferWriter;
180   friend class internal::GrpcByteBufferPeer;
181   friend class internal::ExternalConnectionAcceptorImpl;
182 
183   grpc_byte_buffer* buffer_;
184 
185   // takes ownership
set_buffer(grpc_byte_buffer * buf)186   void set_buffer(grpc_byte_buffer* buf) {
187     if (buffer_) {
188       Clear();
189     }
190     buffer_ = buf;
191   }
192 
c_buffer()193   grpc_byte_buffer* c_buffer() { return buffer_; }
c_buffer_ptr()194   grpc_byte_buffer** c_buffer_ptr() { return &buffer_; }
195 
196   class ByteBufferPointer {
197    public:
198     /* NOLINTNEXTLINE(google-explicit-constructor) */
ByteBufferPointer(const ByteBuffer * b)199     ByteBufferPointer(const ByteBuffer* b)
200         : bbuf_(const_cast<ByteBuffer*>(b)) {}
201     /* NOLINTNEXTLINE(google-explicit-constructor) */
202     operator ByteBuffer*() { return bbuf_; }
203     /* NOLINTNEXTLINE(google-explicit-constructor) */
204     operator grpc_byte_buffer*() { return bbuf_->buffer_; }
205     /* NOLINTNEXTLINE(google-explicit-constructor) */
206     operator grpc_byte_buffer**() { return &bbuf_->buffer_; }
207 
208    private:
209     ByteBuffer* bbuf_;
210   };
bbuf_ptr()211   ByteBufferPointer bbuf_ptr() const { return ByteBufferPointer(this); }
212 };
213 
214 template <>
215 class SerializationTraits<ByteBuffer, void> {
216  public:
Deserialize(ByteBuffer * byte_buffer,ByteBuffer * dest)217   static Status Deserialize(ByteBuffer* byte_buffer, ByteBuffer* dest) {
218     dest->set_buffer(byte_buffer->buffer_);
219     return Status::OK;
220   }
Serialize(const ByteBuffer & source,ByteBuffer * buffer,bool * own_buffer)221   static Status Serialize(const ByteBuffer& source, ByteBuffer* buffer,
222                           bool* own_buffer) {
223     *buffer = source;
224     *own_buffer = true;
225     return g_core_codegen_interface->ok();
226   }
227 };
228 
229 }  // namespace grpc
230 
231 #endif  // GRPCPP_IMPL_CODEGEN_BYTE_BUFFER_H
232