xref: /aosp_15_r20/external/grpc-grpc/include/grpcpp/support/slice.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker //
2*cc02d7e2SAndroid Build Coastguard Worker //
3*cc02d7e2SAndroid Build Coastguard Worker // Copyright 2015 gRPC authors.
4*cc02d7e2SAndroid Build Coastguard Worker //
5*cc02d7e2SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
6*cc02d7e2SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
7*cc02d7e2SAndroid Build Coastguard Worker // You may obtain a copy of the License at
8*cc02d7e2SAndroid Build Coastguard Worker //
9*cc02d7e2SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
10*cc02d7e2SAndroid Build Coastguard Worker //
11*cc02d7e2SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
12*cc02d7e2SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
13*cc02d7e2SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*cc02d7e2SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
15*cc02d7e2SAndroid Build Coastguard Worker // limitations under the License.
16*cc02d7e2SAndroid Build Coastguard Worker //
17*cc02d7e2SAndroid Build Coastguard Worker //
18*cc02d7e2SAndroid Build Coastguard Worker 
19*cc02d7e2SAndroid Build Coastguard Worker #ifndef GRPCPP_SUPPORT_SLICE_H
20*cc02d7e2SAndroid Build Coastguard Worker #define GRPCPP_SUPPORT_SLICE_H
21*cc02d7e2SAndroid Build Coastguard Worker 
22*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/slice.h>
23*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/support/config.h>
24*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/support/string_ref.h>
25*cc02d7e2SAndroid Build Coastguard Worker 
26*cc02d7e2SAndroid Build Coastguard Worker namespace grpc {
27*cc02d7e2SAndroid Build Coastguard Worker 
28*cc02d7e2SAndroid Build Coastguard Worker /// A wrapper around \a grpc_slice.
29*cc02d7e2SAndroid Build Coastguard Worker ///
30*cc02d7e2SAndroid Build Coastguard Worker /// A slice represents a contiguous reference counted array of bytes.
31*cc02d7e2SAndroid Build Coastguard Worker /// It is cheap to take references to a slice, and it is cheap to create a
32*cc02d7e2SAndroid Build Coastguard Worker /// slice pointing to a subset of another slice.
33*cc02d7e2SAndroid Build Coastguard Worker class Slice final {
34*cc02d7e2SAndroid Build Coastguard Worker  public:
35*cc02d7e2SAndroid Build Coastguard Worker   /// Construct an empty slice.
Slice()36*cc02d7e2SAndroid Build Coastguard Worker   Slice() : slice_(grpc_empty_slice()) {}
37*cc02d7e2SAndroid Build Coastguard Worker   /// Destructor - drops one reference.
~Slice()38*cc02d7e2SAndroid Build Coastguard Worker   ~Slice() { grpc_slice_unref(slice_); }
39*cc02d7e2SAndroid Build Coastguard Worker 
40*cc02d7e2SAndroid Build Coastguard Worker   enum AddRef { ADD_REF };
41*cc02d7e2SAndroid Build Coastguard Worker   /// Construct a slice from \a slice, adding a reference.
Slice(grpc_slice slice,AddRef)42*cc02d7e2SAndroid Build Coastguard Worker   Slice(grpc_slice slice, AddRef) : slice_(grpc_slice_ref(slice)) {}
43*cc02d7e2SAndroid Build Coastguard Worker 
44*cc02d7e2SAndroid Build Coastguard Worker   enum StealRef { STEAL_REF };
45*cc02d7e2SAndroid Build Coastguard Worker   /// Construct a slice from \a slice, stealing a reference.
Slice(grpc_slice slice,StealRef)46*cc02d7e2SAndroid Build Coastguard Worker   Slice(grpc_slice slice, StealRef) : slice_(slice) {}
47*cc02d7e2SAndroid Build Coastguard Worker 
48*cc02d7e2SAndroid Build Coastguard Worker   /// Allocate a slice of specified size
Slice(size_t len)49*cc02d7e2SAndroid Build Coastguard Worker   explicit Slice(size_t len) : slice_(grpc_slice_malloc(len)) {}
50*cc02d7e2SAndroid Build Coastguard Worker 
51*cc02d7e2SAndroid Build Coastguard Worker   /// Construct a slice from a copied buffer
Slice(const void * buf,size_t len)52*cc02d7e2SAndroid Build Coastguard Worker   Slice(const void* buf, size_t len)
53*cc02d7e2SAndroid Build Coastguard Worker       : slice_(grpc_slice_from_copied_buffer(reinterpret_cast<const char*>(buf),
54*cc02d7e2SAndroid Build Coastguard Worker                                              len)) {}
55*cc02d7e2SAndroid Build Coastguard Worker 
56*cc02d7e2SAndroid Build Coastguard Worker   /// Construct a slice from a copied string
57*cc02d7e2SAndroid Build Coastguard Worker   // NOLINTNEXTLINE(google-explicit-constructor)
Slice(const std::string & str)58*cc02d7e2SAndroid Build Coastguard Worker   Slice(const std::string& str)
59*cc02d7e2SAndroid Build Coastguard Worker       : slice_(grpc_slice_from_copied_buffer(str.c_str(), str.length())) {}
60*cc02d7e2SAndroid Build Coastguard Worker 
61*cc02d7e2SAndroid Build Coastguard Worker   enum StaticSlice { STATIC_SLICE };
62*cc02d7e2SAndroid Build Coastguard Worker 
63*cc02d7e2SAndroid Build Coastguard Worker   /// Construct a slice from a static buffer
Slice(const void * buf,size_t len,StaticSlice)64*cc02d7e2SAndroid Build Coastguard Worker   Slice(const void* buf, size_t len, StaticSlice)
65*cc02d7e2SAndroid Build Coastguard Worker       : slice_(grpc_slice_from_static_buffer(reinterpret_cast<const char*>(buf),
66*cc02d7e2SAndroid Build Coastguard Worker                                              len)) {}
67*cc02d7e2SAndroid Build Coastguard Worker 
68*cc02d7e2SAndroid Build Coastguard Worker   /// Copy constructor, adds a reference.
Slice(const Slice & other)69*cc02d7e2SAndroid Build Coastguard Worker   Slice(const Slice& other) : slice_(grpc_slice_ref(other.slice_)) {}
70*cc02d7e2SAndroid Build Coastguard Worker 
71*cc02d7e2SAndroid Build Coastguard Worker   /// Move constructor, steals a reference.
Slice(Slice && other)72*cc02d7e2SAndroid Build Coastguard Worker   Slice(Slice&& other) noexcept : slice_(other.slice_) {
73*cc02d7e2SAndroid Build Coastguard Worker     other.slice_ = grpc_empty_slice();
74*cc02d7e2SAndroid Build Coastguard Worker   }
75*cc02d7e2SAndroid Build Coastguard Worker 
76*cc02d7e2SAndroid Build Coastguard Worker   /// Assignment, reference count is unchanged.
77*cc02d7e2SAndroid Build Coastguard Worker   Slice& operator=(Slice other) {
78*cc02d7e2SAndroid Build Coastguard Worker     std::swap(slice_, other.slice_);
79*cc02d7e2SAndroid Build Coastguard Worker     return *this;
80*cc02d7e2SAndroid Build Coastguard Worker   }
81*cc02d7e2SAndroid Build Coastguard Worker 
82*cc02d7e2SAndroid Build Coastguard Worker   /// Create a slice pointing at some data. Calls malloc to allocate a refcount
83*cc02d7e2SAndroid Build Coastguard Worker   /// for the object, and arranges that destroy will be called with the
84*cc02d7e2SAndroid Build Coastguard Worker   /// user data pointer passed in at destruction. Can be the same as buf or
85*cc02d7e2SAndroid Build Coastguard Worker   /// different (e.g., if data is part of a larger structure that must be
86*cc02d7e2SAndroid Build Coastguard Worker   /// destroyed when the data is no longer needed)
Slice(void * buf,size_t len,void (* destroy)(void *),void * user_data)87*cc02d7e2SAndroid Build Coastguard Worker   Slice(void* buf, size_t len, void (*destroy)(void*), void* user_data)
88*cc02d7e2SAndroid Build Coastguard Worker       : slice_(grpc_slice_new_with_user_data(buf, len, destroy, user_data)) {}
89*cc02d7e2SAndroid Build Coastguard Worker 
90*cc02d7e2SAndroid Build Coastguard Worker   /// Specialization of above for common case where buf == user_data
Slice(void * buf,size_t len,void (* destroy)(void *))91*cc02d7e2SAndroid Build Coastguard Worker   Slice(void* buf, size_t len, void (*destroy)(void*))
92*cc02d7e2SAndroid Build Coastguard Worker       : Slice(buf, len, destroy, buf) {}
93*cc02d7e2SAndroid Build Coastguard Worker 
94*cc02d7e2SAndroid Build Coastguard Worker   /// Similar to the above but has a destroy that also takes slice length
Slice(void * buf,size_t len,void (* destroy)(void *,size_t))95*cc02d7e2SAndroid Build Coastguard Worker   Slice(void* buf, size_t len, void (*destroy)(void*, size_t))
96*cc02d7e2SAndroid Build Coastguard Worker       : slice_(grpc_slice_new_with_len(buf, len, destroy)) {}
97*cc02d7e2SAndroid Build Coastguard Worker 
98*cc02d7e2SAndroid Build Coastguard Worker   /// Byte size.
size()99*cc02d7e2SAndroid Build Coastguard Worker   size_t size() const { return GRPC_SLICE_LENGTH(slice_); }
100*cc02d7e2SAndroid Build Coastguard Worker 
101*cc02d7e2SAndroid Build Coastguard Worker   /// Raw pointer to the beginning (first element) of the slice.
begin()102*cc02d7e2SAndroid Build Coastguard Worker   const uint8_t* begin() const { return GRPC_SLICE_START_PTR(slice_); }
103*cc02d7e2SAndroid Build Coastguard Worker 
104*cc02d7e2SAndroid Build Coastguard Worker   /// Raw pointer to the end (one byte \em past the last element) of the slice.
end()105*cc02d7e2SAndroid Build Coastguard Worker   const uint8_t* end() const { return GRPC_SLICE_END_PTR(slice_); }
106*cc02d7e2SAndroid Build Coastguard Worker 
107*cc02d7e2SAndroid Build Coastguard Worker   /// Returns a substring of the `slice` as another slice.
sub(size_t begin,size_t end)108*cc02d7e2SAndroid Build Coastguard Worker   Slice sub(size_t begin, size_t end) const {
109*cc02d7e2SAndroid Build Coastguard Worker     return Slice(grpc_slice_sub(slice_, begin, end), STEAL_REF);
110*cc02d7e2SAndroid Build Coastguard Worker   }
111*cc02d7e2SAndroid Build Coastguard Worker 
112*cc02d7e2SAndroid Build Coastguard Worker   /// Raw C slice. Caller needs to call grpc_slice_unref when done.
c_slice()113*cc02d7e2SAndroid Build Coastguard Worker   grpc_slice c_slice() const { return grpc_slice_ref(slice_); }
114*cc02d7e2SAndroid Build Coastguard Worker 
115*cc02d7e2SAndroid Build Coastguard Worker  private:
116*cc02d7e2SAndroid Build Coastguard Worker   friend class ByteBuffer;
117*cc02d7e2SAndroid Build Coastguard Worker 
118*cc02d7e2SAndroid Build Coastguard Worker   grpc_slice slice_;
119*cc02d7e2SAndroid Build Coastguard Worker };
120*cc02d7e2SAndroid Build Coastguard Worker 
StringRefFromSlice(const grpc_slice * slice)121*cc02d7e2SAndroid Build Coastguard Worker inline grpc::string_ref StringRefFromSlice(const grpc_slice* slice) {
122*cc02d7e2SAndroid Build Coastguard Worker   return grpc::string_ref(
123*cc02d7e2SAndroid Build Coastguard Worker       reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(*slice)),
124*cc02d7e2SAndroid Build Coastguard Worker       GRPC_SLICE_LENGTH(*slice));
125*cc02d7e2SAndroid Build Coastguard Worker }
126*cc02d7e2SAndroid Build Coastguard Worker 
StringFromCopiedSlice(grpc_slice slice)127*cc02d7e2SAndroid Build Coastguard Worker inline std::string StringFromCopiedSlice(grpc_slice slice) {
128*cc02d7e2SAndroid Build Coastguard Worker   return std::string(reinterpret_cast<char*>(GRPC_SLICE_START_PTR(slice)),
129*cc02d7e2SAndroid Build Coastguard Worker                      GRPC_SLICE_LENGTH(slice));
130*cc02d7e2SAndroid Build Coastguard Worker }
131*cc02d7e2SAndroid Build Coastguard Worker 
SliceReferencingString(const std::string & str)132*cc02d7e2SAndroid Build Coastguard Worker inline grpc_slice SliceReferencingString(const std::string& str) {
133*cc02d7e2SAndroid Build Coastguard Worker   return grpc_slice_from_static_buffer(str.data(), str.length());
134*cc02d7e2SAndroid Build Coastguard Worker }
135*cc02d7e2SAndroid Build Coastguard Worker 
SliceFromCopiedString(const std::string & str)136*cc02d7e2SAndroid Build Coastguard Worker inline grpc_slice SliceFromCopiedString(const std::string& str) {
137*cc02d7e2SAndroid Build Coastguard Worker   return grpc_slice_from_copied_buffer(str.data(), str.length());
138*cc02d7e2SAndroid Build Coastguard Worker }
139*cc02d7e2SAndroid Build Coastguard Worker 
140*cc02d7e2SAndroid Build Coastguard Worker }  // namespace grpc
141*cc02d7e2SAndroid Build Coastguard Worker 
142*cc02d7e2SAndroid Build Coastguard Worker #endif  // GRPCPP_SUPPORT_SLICE_H
143