1*cc02d7e2SAndroid Build Coastguard Worker // Copyright 2022 gRPC authors.
2*cc02d7e2SAndroid Build Coastguard Worker //
3*cc02d7e2SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*cc02d7e2SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*cc02d7e2SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*cc02d7e2SAndroid Build Coastguard Worker //
7*cc02d7e2SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*cc02d7e2SAndroid Build Coastguard Worker //
9*cc02d7e2SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*cc02d7e2SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*cc02d7e2SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*cc02d7e2SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*cc02d7e2SAndroid Build Coastguard Worker // limitations under the License.
14*cc02d7e2SAndroid Build Coastguard Worker
15*cc02d7e2SAndroid Build Coastguard Worker #ifndef GRPC_EVENT_ENGINE_SLICE_H
16*cc02d7e2SAndroid Build Coastguard Worker #define GRPC_EVENT_ENGINE_SLICE_H
17*cc02d7e2SAndroid Build Coastguard Worker
18*cc02d7e2SAndroid Build Coastguard Worker #include <string.h>
19*cc02d7e2SAndroid Build Coastguard Worker
20*cc02d7e2SAndroid Build Coastguard Worker #include <cstdint>
21*cc02d7e2SAndroid Build Coastguard Worker #include <string>
22*cc02d7e2SAndroid Build Coastguard Worker #include <utility>
23*cc02d7e2SAndroid Build Coastguard Worker
24*cc02d7e2SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
25*cc02d7e2SAndroid Build Coastguard Worker
26*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/event_engine/internal/slice_cast.h>
27*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/slice.h>
28*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/log.h>
29*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/port_platform.h>
30*cc02d7e2SAndroid Build Coastguard Worker
31*cc02d7e2SAndroid Build Coastguard Worker // This public slice definition largely based of the internal grpc_core::Slice
32*cc02d7e2SAndroid Build Coastguard Worker // implementation. Changes to this implementation might warrant changes to the
33*cc02d7e2SAndroid Build Coastguard Worker // internal grpc_core::Slice type as well.
34*cc02d7e2SAndroid Build Coastguard Worker
35*cc02d7e2SAndroid Build Coastguard Worker namespace grpc_event_engine {
36*cc02d7e2SAndroid Build Coastguard Worker namespace experimental {
37*cc02d7e2SAndroid Build Coastguard Worker
38*cc02d7e2SAndroid Build Coastguard Worker // Forward declarations
39*cc02d7e2SAndroid Build Coastguard Worker class Slice;
40*cc02d7e2SAndroid Build Coastguard Worker class MutableSlice;
41*cc02d7e2SAndroid Build Coastguard Worker
42*cc02d7e2SAndroid Build Coastguard Worker namespace slice_detail {
43*cc02d7e2SAndroid Build Coastguard Worker
44*cc02d7e2SAndroid Build Coastguard Worker // Returns an empty slice.
EmptySlice()45*cc02d7e2SAndroid Build Coastguard Worker static constexpr grpc_slice EmptySlice() { return {nullptr, {}}; }
46*cc02d7e2SAndroid Build Coastguard Worker
47*cc02d7e2SAndroid Build Coastguard Worker // BaseSlice holds the grpc_slice object, but does not apply refcounting policy.
48*cc02d7e2SAndroid Build Coastguard Worker // It does export immutable access into the slice, such that this can be shared
49*cc02d7e2SAndroid Build Coastguard Worker // by all storage policies.
50*cc02d7e2SAndroid Build Coastguard Worker class BaseSlice {
51*cc02d7e2SAndroid Build Coastguard Worker public:
52*cc02d7e2SAndroid Build Coastguard Worker BaseSlice(const BaseSlice&) = delete;
53*cc02d7e2SAndroid Build Coastguard Worker BaseSlice& operator=(const BaseSlice&) = delete;
54*cc02d7e2SAndroid Build Coastguard Worker BaseSlice(BaseSlice&& other) = delete;
55*cc02d7e2SAndroid Build Coastguard Worker BaseSlice& operator=(BaseSlice&& other) = delete;
56*cc02d7e2SAndroid Build Coastguard Worker
57*cc02d7e2SAndroid Build Coastguard Worker // Iterator access to the underlying bytes
begin()58*cc02d7e2SAndroid Build Coastguard Worker const uint8_t* begin() const { return GRPC_SLICE_START_PTR(c_slice()); }
end()59*cc02d7e2SAndroid Build Coastguard Worker const uint8_t* end() const { return GRPC_SLICE_END_PTR(c_slice()); }
cbegin()60*cc02d7e2SAndroid Build Coastguard Worker const uint8_t* cbegin() const { return GRPC_SLICE_START_PTR(c_slice()); }
cend()61*cc02d7e2SAndroid Build Coastguard Worker const uint8_t* cend() const { return GRPC_SLICE_END_PTR(c_slice()); }
62*cc02d7e2SAndroid Build Coastguard Worker
63*cc02d7e2SAndroid Build Coastguard Worker // Retrieve a borrowed reference to the underlying grpc_slice.
c_slice()64*cc02d7e2SAndroid Build Coastguard Worker const grpc_slice& c_slice() const { return slice_; }
65*cc02d7e2SAndroid Build Coastguard Worker
66*cc02d7e2SAndroid Build Coastguard Worker // Retrieve the underlying grpc_slice, and replace the one in this object with
67*cc02d7e2SAndroid Build Coastguard Worker // EmptySlice().
TakeCSlice()68*cc02d7e2SAndroid Build Coastguard Worker grpc_slice TakeCSlice() {
69*cc02d7e2SAndroid Build Coastguard Worker grpc_slice out = slice_;
70*cc02d7e2SAndroid Build Coastguard Worker slice_ = EmptySlice();
71*cc02d7e2SAndroid Build Coastguard Worker return out;
72*cc02d7e2SAndroid Build Coastguard Worker }
73*cc02d7e2SAndroid Build Coastguard Worker
74*cc02d7e2SAndroid Build Coastguard Worker // As other things... borrowed references.
as_string_view()75*cc02d7e2SAndroid Build Coastguard Worker absl::string_view as_string_view() const {
76*cc02d7e2SAndroid Build Coastguard Worker return absl::string_view(reinterpret_cast<const char*>(data()), size());
77*cc02d7e2SAndroid Build Coastguard Worker }
78*cc02d7e2SAndroid Build Coastguard Worker
79*cc02d7e2SAndroid Build Coastguard Worker // Array access
80*cc02d7e2SAndroid Build Coastguard Worker uint8_t operator[](size_t i) const {
81*cc02d7e2SAndroid Build Coastguard Worker return GRPC_SLICE_START_PTR(c_slice())[i];
82*cc02d7e2SAndroid Build Coastguard Worker }
83*cc02d7e2SAndroid Build Coastguard Worker
84*cc02d7e2SAndroid Build Coastguard Worker // Access underlying data
data()85*cc02d7e2SAndroid Build Coastguard Worker const uint8_t* data() const { return GRPC_SLICE_START_PTR(c_slice()); }
86*cc02d7e2SAndroid Build Coastguard Worker
87*cc02d7e2SAndroid Build Coastguard Worker // Size of the slice
size()88*cc02d7e2SAndroid Build Coastguard Worker size_t size() const { return GRPC_SLICE_LENGTH(c_slice()); }
length()89*cc02d7e2SAndroid Build Coastguard Worker size_t length() const { return size(); }
empty()90*cc02d7e2SAndroid Build Coastguard Worker bool empty() const { return size() == 0; }
91*cc02d7e2SAndroid Build Coastguard Worker
92*cc02d7e2SAndroid Build Coastguard Worker // For inlined slices - are these two slices equal?
93*cc02d7e2SAndroid Build Coastguard Worker // For non-inlined slices - do these two slices refer to the same block of
94*cc02d7e2SAndroid Build Coastguard Worker // memory?
is_equivalent(const BaseSlice & other)95*cc02d7e2SAndroid Build Coastguard Worker bool is_equivalent(const BaseSlice& other) const {
96*cc02d7e2SAndroid Build Coastguard Worker return grpc_slice_is_equivalent(slice_, other.slice_);
97*cc02d7e2SAndroid Build Coastguard Worker }
98*cc02d7e2SAndroid Build Coastguard Worker
99*cc02d7e2SAndroid Build Coastguard Worker uint32_t Hash() const;
100*cc02d7e2SAndroid Build Coastguard Worker
101*cc02d7e2SAndroid Build Coastguard Worker protected:
BaseSlice()102*cc02d7e2SAndroid Build Coastguard Worker BaseSlice() : slice_(EmptySlice()) {}
BaseSlice(const grpc_slice & slice)103*cc02d7e2SAndroid Build Coastguard Worker explicit BaseSlice(const grpc_slice& slice) : slice_(slice) {}
104*cc02d7e2SAndroid Build Coastguard Worker ~BaseSlice() = default;
105*cc02d7e2SAndroid Build Coastguard Worker
Swap(BaseSlice * other)106*cc02d7e2SAndroid Build Coastguard Worker void Swap(BaseSlice* other) { std::swap(slice_, other->slice_); }
SetCSlice(const grpc_slice & slice)107*cc02d7e2SAndroid Build Coastguard Worker void SetCSlice(const grpc_slice& slice) { slice_ = slice; }
108*cc02d7e2SAndroid Build Coastguard Worker
mutable_data()109*cc02d7e2SAndroid Build Coastguard Worker uint8_t* mutable_data() { return GRPC_SLICE_START_PTR(slice_); }
110*cc02d7e2SAndroid Build Coastguard Worker
c_slice_ptr()111*cc02d7e2SAndroid Build Coastguard Worker grpc_slice* c_slice_ptr() { return &slice_; }
112*cc02d7e2SAndroid Build Coastguard Worker
113*cc02d7e2SAndroid Build Coastguard Worker private:
114*cc02d7e2SAndroid Build Coastguard Worker grpc_slice slice_;
115*cc02d7e2SAndroid Build Coastguard Worker };
116*cc02d7e2SAndroid Build Coastguard Worker
117*cc02d7e2SAndroid Build Coastguard Worker inline bool operator==(const BaseSlice& a, const BaseSlice& b) {
118*cc02d7e2SAndroid Build Coastguard Worker return grpc_slice_eq(a.c_slice(), b.c_slice()) != 0;
119*cc02d7e2SAndroid Build Coastguard Worker }
120*cc02d7e2SAndroid Build Coastguard Worker
121*cc02d7e2SAndroid Build Coastguard Worker inline bool operator!=(const BaseSlice& a, const BaseSlice& b) {
122*cc02d7e2SAndroid Build Coastguard Worker return grpc_slice_eq(a.c_slice(), b.c_slice()) == 0;
123*cc02d7e2SAndroid Build Coastguard Worker }
124*cc02d7e2SAndroid Build Coastguard Worker
125*cc02d7e2SAndroid Build Coastguard Worker inline bool operator==(const BaseSlice& a, absl::string_view b) {
126*cc02d7e2SAndroid Build Coastguard Worker return a.as_string_view() == b;
127*cc02d7e2SAndroid Build Coastguard Worker }
128*cc02d7e2SAndroid Build Coastguard Worker
129*cc02d7e2SAndroid Build Coastguard Worker inline bool operator!=(const BaseSlice& a, absl::string_view b) {
130*cc02d7e2SAndroid Build Coastguard Worker return a.as_string_view() != b;
131*cc02d7e2SAndroid Build Coastguard Worker }
132*cc02d7e2SAndroid Build Coastguard Worker
133*cc02d7e2SAndroid Build Coastguard Worker inline bool operator==(absl::string_view a, const BaseSlice& b) {
134*cc02d7e2SAndroid Build Coastguard Worker return a == b.as_string_view();
135*cc02d7e2SAndroid Build Coastguard Worker }
136*cc02d7e2SAndroid Build Coastguard Worker
137*cc02d7e2SAndroid Build Coastguard Worker inline bool operator!=(absl::string_view a, const BaseSlice& b) {
138*cc02d7e2SAndroid Build Coastguard Worker return a != b.as_string_view();
139*cc02d7e2SAndroid Build Coastguard Worker }
140*cc02d7e2SAndroid Build Coastguard Worker
141*cc02d7e2SAndroid Build Coastguard Worker inline bool operator==(const BaseSlice& a, const grpc_slice& b) {
142*cc02d7e2SAndroid Build Coastguard Worker return grpc_slice_eq(a.c_slice(), b) != 0;
143*cc02d7e2SAndroid Build Coastguard Worker }
144*cc02d7e2SAndroid Build Coastguard Worker
145*cc02d7e2SAndroid Build Coastguard Worker inline bool operator!=(const BaseSlice& a, const grpc_slice& b) {
146*cc02d7e2SAndroid Build Coastguard Worker return grpc_slice_eq(a.c_slice(), b) == 0;
147*cc02d7e2SAndroid Build Coastguard Worker }
148*cc02d7e2SAndroid Build Coastguard Worker
149*cc02d7e2SAndroid Build Coastguard Worker inline bool operator==(const grpc_slice& a, const BaseSlice& b) {
150*cc02d7e2SAndroid Build Coastguard Worker return grpc_slice_eq(a, b.c_slice()) != 0;
151*cc02d7e2SAndroid Build Coastguard Worker }
152*cc02d7e2SAndroid Build Coastguard Worker
153*cc02d7e2SAndroid Build Coastguard Worker inline bool operator!=(const grpc_slice& a, const BaseSlice& b) {
154*cc02d7e2SAndroid Build Coastguard Worker return grpc_slice_eq(a, b.c_slice()) == 0;
155*cc02d7e2SAndroid Build Coastguard Worker }
156*cc02d7e2SAndroid Build Coastguard Worker
157*cc02d7e2SAndroid Build Coastguard Worker template <typename Out>
158*cc02d7e2SAndroid Build Coastguard Worker struct CopyConstructors {
FromCopiedStringCopyConstructors159*cc02d7e2SAndroid Build Coastguard Worker static Out FromCopiedString(const char* s) {
160*cc02d7e2SAndroid Build Coastguard Worker return FromCopiedBuffer(s, strlen(s));
161*cc02d7e2SAndroid Build Coastguard Worker }
FromCopiedStringCopyConstructors162*cc02d7e2SAndroid Build Coastguard Worker static Out FromCopiedString(absl::string_view s) {
163*cc02d7e2SAndroid Build Coastguard Worker return FromCopiedBuffer(s.data(), s.size());
164*cc02d7e2SAndroid Build Coastguard Worker }
165*cc02d7e2SAndroid Build Coastguard Worker static Out FromCopiedString(std::string s);
166*cc02d7e2SAndroid Build Coastguard Worker
FromCopiedBufferCopyConstructors167*cc02d7e2SAndroid Build Coastguard Worker static Out FromCopiedBuffer(const char* p, size_t len) {
168*cc02d7e2SAndroid Build Coastguard Worker return Out(grpc_slice_from_copied_buffer(p, len));
169*cc02d7e2SAndroid Build Coastguard Worker }
170*cc02d7e2SAndroid Build Coastguard Worker
FromCopiedBufferCopyConstructors171*cc02d7e2SAndroid Build Coastguard Worker static Out FromCopiedBuffer(const uint8_t* p, size_t len) {
172*cc02d7e2SAndroid Build Coastguard Worker return Out(
173*cc02d7e2SAndroid Build Coastguard Worker grpc_slice_from_copied_buffer(reinterpret_cast<const char*>(p), len));
174*cc02d7e2SAndroid Build Coastguard Worker }
175*cc02d7e2SAndroid Build Coastguard Worker
176*cc02d7e2SAndroid Build Coastguard Worker template <typename Buffer>
FromCopiedBufferCopyConstructors177*cc02d7e2SAndroid Build Coastguard Worker static Out FromCopiedBuffer(const Buffer& buffer) {
178*cc02d7e2SAndroid Build Coastguard Worker return FromCopiedBuffer(reinterpret_cast<const char*>(buffer.data()),
179*cc02d7e2SAndroid Build Coastguard Worker buffer.size());
180*cc02d7e2SAndroid Build Coastguard Worker }
181*cc02d7e2SAndroid Build Coastguard Worker };
182*cc02d7e2SAndroid Build Coastguard Worker
183*cc02d7e2SAndroid Build Coastguard Worker } // namespace slice_detail
184*cc02d7e2SAndroid Build Coastguard Worker
185*cc02d7e2SAndroid Build Coastguard Worker class GPR_MSVC_EMPTY_BASE_CLASS_WORKAROUND MutableSlice
186*cc02d7e2SAndroid Build Coastguard Worker : public slice_detail::BaseSlice,
187*cc02d7e2SAndroid Build Coastguard Worker public slice_detail::CopyConstructors<MutableSlice> {
188*cc02d7e2SAndroid Build Coastguard Worker public:
189*cc02d7e2SAndroid Build Coastguard Worker MutableSlice() = default;
190*cc02d7e2SAndroid Build Coastguard Worker explicit MutableSlice(const grpc_slice& slice);
191*cc02d7e2SAndroid Build Coastguard Worker ~MutableSlice();
192*cc02d7e2SAndroid Build Coastguard Worker
193*cc02d7e2SAndroid Build Coastguard Worker MutableSlice(const MutableSlice&) = delete;
194*cc02d7e2SAndroid Build Coastguard Worker MutableSlice& operator=(const MutableSlice&) = delete;
MutableSlice(MutableSlice && other)195*cc02d7e2SAndroid Build Coastguard Worker MutableSlice(MutableSlice&& other) noexcept
196*cc02d7e2SAndroid Build Coastguard Worker : slice_detail::BaseSlice(other.TakeCSlice()) {}
197*cc02d7e2SAndroid Build Coastguard Worker MutableSlice& operator=(MutableSlice&& other) noexcept {
198*cc02d7e2SAndroid Build Coastguard Worker Swap(&other);
199*cc02d7e2SAndroid Build Coastguard Worker return *this;
200*cc02d7e2SAndroid Build Coastguard Worker }
201*cc02d7e2SAndroid Build Coastguard Worker
CreateUninitialized(size_t length)202*cc02d7e2SAndroid Build Coastguard Worker static MutableSlice CreateUninitialized(size_t length) {
203*cc02d7e2SAndroid Build Coastguard Worker return MutableSlice(grpc_slice_malloc(length));
204*cc02d7e2SAndroid Build Coastguard Worker }
205*cc02d7e2SAndroid Build Coastguard Worker
206*cc02d7e2SAndroid Build Coastguard Worker // Return a sub slice of this one. Leaves this slice in an indeterminate but
207*cc02d7e2SAndroid Build Coastguard Worker // valid state.
TakeSubSlice(size_t pos,size_t n)208*cc02d7e2SAndroid Build Coastguard Worker MutableSlice TakeSubSlice(size_t pos, size_t n) {
209*cc02d7e2SAndroid Build Coastguard Worker return MutableSlice(grpc_slice_sub_no_ref(TakeCSlice(), pos, pos + n));
210*cc02d7e2SAndroid Build Coastguard Worker }
211*cc02d7e2SAndroid Build Coastguard Worker
212*cc02d7e2SAndroid Build Coastguard Worker // Iterator access to the underlying bytes
begin()213*cc02d7e2SAndroid Build Coastguard Worker uint8_t* begin() { return mutable_data(); }
end()214*cc02d7e2SAndroid Build Coastguard Worker uint8_t* end() { return mutable_data() + size(); }
data()215*cc02d7e2SAndroid Build Coastguard Worker uint8_t* data() { return mutable_data(); }
216*cc02d7e2SAndroid Build Coastguard Worker
217*cc02d7e2SAndroid Build Coastguard Worker // Array access
218*cc02d7e2SAndroid Build Coastguard Worker uint8_t& operator[](size_t i) { return mutable_data()[i]; }
219*cc02d7e2SAndroid Build Coastguard Worker };
220*cc02d7e2SAndroid Build Coastguard Worker
221*cc02d7e2SAndroid Build Coastguard Worker class GPR_MSVC_EMPTY_BASE_CLASS_WORKAROUND Slice
222*cc02d7e2SAndroid Build Coastguard Worker : public slice_detail::BaseSlice,
223*cc02d7e2SAndroid Build Coastguard Worker public slice_detail::CopyConstructors<Slice> {
224*cc02d7e2SAndroid Build Coastguard Worker public:
225*cc02d7e2SAndroid Build Coastguard Worker Slice() = default;
226*cc02d7e2SAndroid Build Coastguard Worker ~Slice();
Slice(const grpc_slice & slice)227*cc02d7e2SAndroid Build Coastguard Worker explicit Slice(const grpc_slice& slice) : slice_detail::BaseSlice(slice) {}
Slice(slice_detail::BaseSlice && other)228*cc02d7e2SAndroid Build Coastguard Worker explicit Slice(slice_detail::BaseSlice&& other)
229*cc02d7e2SAndroid Build Coastguard Worker : slice_detail::BaseSlice(other.TakeCSlice()) {}
230*cc02d7e2SAndroid Build Coastguard Worker
231*cc02d7e2SAndroid Build Coastguard Worker Slice(const Slice&) = delete;
232*cc02d7e2SAndroid Build Coastguard Worker Slice& operator=(const Slice&) = delete;
Slice(Slice && other)233*cc02d7e2SAndroid Build Coastguard Worker Slice(Slice&& other) noexcept : slice_detail::BaseSlice(other.TakeCSlice()) {}
234*cc02d7e2SAndroid Build Coastguard Worker Slice& operator=(Slice&& other) noexcept {
235*cc02d7e2SAndroid Build Coastguard Worker Swap(&other);
236*cc02d7e2SAndroid Build Coastguard Worker return *this;
237*cc02d7e2SAndroid Build Coastguard Worker }
238*cc02d7e2SAndroid Build Coastguard Worker
239*cc02d7e2SAndroid Build Coastguard Worker // A slice might refer to some memory that we keep a refcount to (this is
240*cc02d7e2SAndroid Build Coastguard Worker // owned), or some memory that's inlined into the slice (also owned), or some
241*cc02d7e2SAndroid Build Coastguard Worker // other block of memory that we know will be available for the lifetime of
242*cc02d7e2SAndroid Build Coastguard Worker // some operation in the common case (not owned). In the *less common* case
243*cc02d7e2SAndroid Build Coastguard Worker // that we need to keep that slice text for longer than our API's guarantee us
244*cc02d7e2SAndroid Build Coastguard Worker // access, we need to take a copy and turn this into something that we do own.
245*cc02d7e2SAndroid Build Coastguard Worker
246*cc02d7e2SAndroid Build Coastguard Worker // TakeOwned returns an owned slice regardless of current ownership, and
247*cc02d7e2SAndroid Build Coastguard Worker // leaves the current slice in a valid but externally unpredictable state - in
248*cc02d7e2SAndroid Build Coastguard Worker // doing so it can avoid adding a ref to the underlying slice.
249*cc02d7e2SAndroid Build Coastguard Worker Slice TakeOwned();
250*cc02d7e2SAndroid Build Coastguard Worker
251*cc02d7e2SAndroid Build Coastguard Worker // AsOwned returns an owned slice but does not mutate the current slice,
252*cc02d7e2SAndroid Build Coastguard Worker // meaning that it may add a reference to the underlying slice.
253*cc02d7e2SAndroid Build Coastguard Worker Slice AsOwned() const;
254*cc02d7e2SAndroid Build Coastguard Worker
255*cc02d7e2SAndroid Build Coastguard Worker // TakeMutable returns a MutableSlice, and leaves the current slice in an
256*cc02d7e2SAndroid Build Coastguard Worker // indeterminate but valid state.
257*cc02d7e2SAndroid Build Coastguard Worker // A mutable slice requires only one reference to the bytes of the slice -
258*cc02d7e2SAndroid Build Coastguard Worker // this can be achieved either with inlined storage or with a single
259*cc02d7e2SAndroid Build Coastguard Worker // reference.
260*cc02d7e2SAndroid Build Coastguard Worker // If the current slice is refcounted and there are more than one references
261*cc02d7e2SAndroid Build Coastguard Worker // to that slice, then the slice is copied in order to achieve a mutable
262*cc02d7e2SAndroid Build Coastguard Worker // version.
263*cc02d7e2SAndroid Build Coastguard Worker MutableSlice TakeMutable();
264*cc02d7e2SAndroid Build Coastguard Worker
265*cc02d7e2SAndroid Build Coastguard Worker // Return a sub slice of this one. Leaves this slice in an indeterminate but
266*cc02d7e2SAndroid Build Coastguard Worker // valid state.
TakeSubSlice(size_t pos,size_t n)267*cc02d7e2SAndroid Build Coastguard Worker Slice TakeSubSlice(size_t pos, size_t n) {
268*cc02d7e2SAndroid Build Coastguard Worker return Slice(grpc_slice_sub_no_ref(TakeCSlice(), pos, pos + n));
269*cc02d7e2SAndroid Build Coastguard Worker }
270*cc02d7e2SAndroid Build Coastguard Worker
271*cc02d7e2SAndroid Build Coastguard Worker // Return a sub slice of this one. Adds a reference to the underlying slice.
RefSubSlice(size_t pos,size_t n)272*cc02d7e2SAndroid Build Coastguard Worker Slice RefSubSlice(size_t pos, size_t n) const {
273*cc02d7e2SAndroid Build Coastguard Worker return Slice(grpc_slice_sub(c_slice(), pos, pos + n));
274*cc02d7e2SAndroid Build Coastguard Worker }
275*cc02d7e2SAndroid Build Coastguard Worker
276*cc02d7e2SAndroid Build Coastguard Worker // Split this slice, returning a new slice containing (split:end] and
277*cc02d7e2SAndroid Build Coastguard Worker // leaving this slice with [begin:split).
Split(size_t split)278*cc02d7e2SAndroid Build Coastguard Worker Slice Split(size_t split) {
279*cc02d7e2SAndroid Build Coastguard Worker return Slice(grpc_slice_split_tail(c_slice_ptr(), split));
280*cc02d7e2SAndroid Build Coastguard Worker }
281*cc02d7e2SAndroid Build Coastguard Worker
282*cc02d7e2SAndroid Build Coastguard Worker Slice Ref() const;
283*cc02d7e2SAndroid Build Coastguard Worker
Copy()284*cc02d7e2SAndroid Build Coastguard Worker Slice Copy() const { return Slice(grpc_slice_copy(c_slice())); }
285*cc02d7e2SAndroid Build Coastguard Worker
286*cc02d7e2SAndroid Build Coastguard Worker static Slice FromRefcountAndBytes(grpc_slice_refcount* r,
287*cc02d7e2SAndroid Build Coastguard Worker const uint8_t* begin, const uint8_t* end);
288*cc02d7e2SAndroid Build Coastguard Worker };
289*cc02d7e2SAndroid Build Coastguard Worker
290*cc02d7e2SAndroid Build Coastguard Worker namespace internal {
291*cc02d7e2SAndroid Build Coastguard Worker template <>
292*cc02d7e2SAndroid Build Coastguard Worker struct SliceCastable<Slice, grpc_slice> {};
293*cc02d7e2SAndroid Build Coastguard Worker template <>
294*cc02d7e2SAndroid Build Coastguard Worker struct SliceCastable<grpc_slice, Slice> {};
295*cc02d7e2SAndroid Build Coastguard Worker
296*cc02d7e2SAndroid Build Coastguard Worker template <>
297*cc02d7e2SAndroid Build Coastguard Worker struct SliceCastable<MutableSlice, grpc_slice> {};
298*cc02d7e2SAndroid Build Coastguard Worker template <>
299*cc02d7e2SAndroid Build Coastguard Worker struct SliceCastable<grpc_slice, MutableSlice> {};
300*cc02d7e2SAndroid Build Coastguard Worker
301*cc02d7e2SAndroid Build Coastguard Worker template <>
302*cc02d7e2SAndroid Build Coastguard Worker struct SliceCastable<MutableSlice, Slice> {};
303*cc02d7e2SAndroid Build Coastguard Worker template <>
304*cc02d7e2SAndroid Build Coastguard Worker struct SliceCastable<Slice, MutableSlice> {};
305*cc02d7e2SAndroid Build Coastguard Worker } // namespace internal
306*cc02d7e2SAndroid Build Coastguard Worker
307*cc02d7e2SAndroid Build Coastguard Worker } // namespace experimental
308*cc02d7e2SAndroid Build Coastguard Worker } // namespace grpc_event_engine
309*cc02d7e2SAndroid Build Coastguard Worker
310*cc02d7e2SAndroid Build Coastguard Worker #endif // GRPC_EVENT_ENGINE_SLICE_H
311