xref: /aosp_15_r20/external/grpc-grpc/include/grpcpp/support/byte_buffer.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 //
3 // Copyright 2015 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_SUPPORT_BYTE_BUFFER_H
20 #define GRPCPP_SUPPORT_BYTE_BUFFER_H
21 
22 #include <vector>
23 
24 #include <grpc/byte_buffer.h>
25 #include <grpc/grpc.h>
26 #include <grpc/support/log.h>
27 #include <grpcpp/impl/serialization_traits.h>
28 #include <grpcpp/support/config.h>
29 #include <grpcpp/support/slice.h>
30 #include <grpcpp/support/status.h>
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_ = grpc_raw_byte_buffer_create(
88         reinterpret_cast<grpc_slice*>(const_cast<Slice*>(slices)), nslices);
89   }
90 
91   /// Construct 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       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_ = grpc_byte_buffer_copy(buf.buffer_);
113     }
114     return *this;
115   }
116 
117   // If this ByteBuffer's representation is a single flat slice, returns a
118   // slice referencing that array.
119   Status TrySingleSlice(Slice* slice) const;
120 
121   /// Dump (read) the buffer contents into \a slics.
122   Status DumpToSingleSlice(Slice* slice) const;
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       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() { buffer_ = grpc_byte_buffer_copy(buffer_); }
141 
142   /// Forget underlying byte buffer without destroying
143   /// Use this only for un-owned byte buffers
Release()144   void Release() { buffer_ = nullptr; }
145 
146   /// Buffer size in bytes.
Length()147   size_t Length() const {
148     return buffer_ == nullptr ? 0 : grpc_byte_buffer_length(buffer_);
149   }
150 
151   /// Swap the state of *this and *other.
Swap(ByteBuffer * other)152   void Swap(ByteBuffer* other) {
153     grpc_byte_buffer* tmp = other->buffer_;
154     other->buffer_ = buffer_;
155     buffer_ = tmp;
156   }
157 
158   /// Is this ByteBuffer valid?
Valid()159   bool Valid() const { return (buffer_ != nullptr); }
160 
161  private:
162   friend class SerializationTraits<ByteBuffer, void>;
163   friend class ServerInterface;
164   friend class internal::CallOpSendMessage;
165   template <class R>
166   friend class internal::CallOpRecvMessage;
167   friend class internal::CallOpGenericRecvMessage;
168   template <class RequestType>
169   friend void* internal::UnaryDeserializeHelper(grpc_byte_buffer*,
170                                                 grpc::Status*, RequestType*);
171   template <class ServiceType, class RequestType, class ResponseType>
172   friend class internal::ServerStreamingHandler;
173   template <class RequestType, class ResponseType>
174   friend class internal::CallbackUnaryHandler;
175   template <class RequestType, class ResponseType>
176   friend class internal::CallbackServerStreamingHandler;
177   template <StatusCode code>
178   friend class internal::ErrorMethodHandler;
179   template <class R>
180   friend class internal::DeserializeFuncType;
181   friend class ProtoBufferReader;
182   friend class ProtoBufferWriter;
183   friend class internal::GrpcByteBufferPeer;
184   friend class internal::ExternalConnectionAcceptorImpl;
185 
186   grpc_byte_buffer* buffer_;
187 
188   // takes ownership
set_buffer(grpc_byte_buffer * buf)189   void set_buffer(grpc_byte_buffer* buf) {
190     if (buffer_) {
191       Clear();
192     }
193     buffer_ = buf;
194   }
195 
c_buffer()196   grpc_byte_buffer* c_buffer() { return buffer_; }
c_buffer_ptr()197   grpc_byte_buffer** c_buffer_ptr() { return &buffer_; }
198 
199   class ByteBufferPointer {
200    public:
201     // NOLINTNEXTLINE(google-explicit-constructor)
ByteBufferPointer(const ByteBuffer * b)202     ByteBufferPointer(const ByteBuffer* b)
203         : bbuf_(const_cast<ByteBuffer*>(b)) {}
204     // NOLINTNEXTLINE(google-explicit-constructor)
205     operator ByteBuffer*() { return bbuf_; }
206     // NOLINTNEXTLINE(google-explicit-constructor)
207     operator grpc_byte_buffer*() { return bbuf_->buffer_; }
208     // NOLINTNEXTLINE(google-explicit-constructor)
209     operator grpc_byte_buffer**() { return &bbuf_->buffer_; }
210 
211    private:
212     ByteBuffer* bbuf_;
213   };
bbuf_ptr()214   ByteBufferPointer bbuf_ptr() const { return ByteBufferPointer(this); }
215 };
216 
217 template <>
218 class SerializationTraits<ByteBuffer, void> {
219  public:
Deserialize(ByteBuffer * byte_buffer,ByteBuffer * dest)220   static Status Deserialize(ByteBuffer* byte_buffer, ByteBuffer* dest) {
221     dest->set_buffer(byte_buffer->buffer_);
222     return Status::OK;
223   }
Serialize(const ByteBuffer & source,ByteBuffer * buffer,bool * own_buffer)224   static Status Serialize(const ByteBuffer& source, ByteBuffer* buffer,
225                           bool* own_buffer) {
226     *buffer = source;
227     *own_buffer = true;
228     return grpc::Status::OK;
229   }
230 };
231 
232 }  // namespace grpc
233 
234 #endif  // GRPCPP_SUPPORT_BYTE_BUFFER_H
235