aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/grpcpp/impl/codegen/slice.h
blob: 8966559dc853494bf815b23a485dffddf2d98734 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
 *
 * Copyright 2015 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_SLICE_H
#define GRPCPP_IMPL_CODEGEN_SLICE_H

#include <grpcpp/impl/codegen/config.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/string_ref.h>

#include <grpc/impl/codegen/slice.h>

namespace grpc {

/// A wrapper around \a grpc_slice.
///
/// A slice represents a contiguous reference counted array of bytes.
/// It is cheap to take references to a slice, and it is cheap to create a
/// slice pointing to a subset of another slice.
class Slice final {
 public:
  /// Construct an empty slice.
  Slice() : slice_(g_core_codegen_interface->grpc_empty_slice()) {}
  /// Destructor - drops one reference.
  ~Slice() { g_core_codegen_interface->grpc_slice_unref(slice_); }

  enum AddRef { ADD_REF };
  /// Construct a slice from \a slice, adding a reference.
  Slice(grpc_slice slice, AddRef)
      : slice_(g_core_codegen_interface->grpc_slice_ref(slice)) {}

  enum StealRef { STEAL_REF };
  /// Construct a slice from \a slice, stealing a reference.
  Slice(grpc_slice slice, StealRef) : slice_(slice) {}

  /// Allocate a slice of specified size
  Slice(size_t len)
      : slice_(g_core_codegen_interface->grpc_slice_malloc(len)) {}

  /// Construct a slice from a copied buffer
  Slice(const void* buf, size_t len)
      : slice_(g_core_codegen_interface->grpc_slice_from_copied_buffer(
            reinterpret_cast<const char*>(buf), len)) {}

  /// Construct a slice from a copied string
  Slice(const grpc::string& str)
      : slice_(g_core_codegen_interface->grpc_slice_from_copied_buffer(
            str.c_str(), str.length())) {}

  enum StaticSlice { STATIC_SLICE };

  /// Construct a slice from a static buffer
  Slice(const void* buf, size_t len, StaticSlice)
      : slice_(g_core_codegen_interface->grpc_slice_from_static_buffer(
            reinterpret_cast<const char*>(buf), len)) {}

  /// Copy constructor, adds a reference.
  Slice(const Slice& other)
      : slice_(g_core_codegen_interface->grpc_slice_ref(other.slice_)) {}

  /// Assignment, reference count is unchanged.
  Slice& operator=(Slice other) {
    std::swap(slice_, other.slice_);
    return *this;
  }

  /// Create a slice pointing at some data. Calls malloc to allocate a refcount
  /// for the object, and arranges that destroy will be called with the
  /// user data pointer passed in at destruction. Can be the same as buf or
  /// different (e.g., if data is part of a larger structure that must be
  /// destroyed when the data is no longer needed)
  Slice(void* buf, size_t len, void (*destroy)(void*), void* user_data)
      : slice_(g_core_codegen_interface->grpc_slice_new_with_user_data(
            buf, len, destroy, user_data)) {}

  /// Specialization of above for common case where buf == user_data
  Slice(void* buf, size_t len, void (*destroy)(void*))
      : Slice(buf, len, destroy, buf) {}

  /// Similar to the above but has a destroy that also takes slice length
  Slice(void* buf, size_t len, void (*destroy)(void*, size_t))
      : slice_(g_core_codegen_interface->grpc_slice_new_with_len(buf, len,
                                                                 destroy)) {}

  /// Byte size.
  size_t size() const { return GRPC_SLICE_LENGTH(slice_); }

  /// Raw pointer to the beginning (first element) of the slice.
  const uint8_t* begin() const { return GRPC_SLICE_START_PTR(slice_); }

  /// Raw pointer to the end (one byte \em past the last element) of the slice.
  const uint8_t* end() const { return GRPC_SLICE_END_PTR(slice_); }

  /// Raw C slice. Caller needs to call grpc_slice_unref when done.
  grpc_slice c_slice() const {
    return g_core_codegen_interface->grpc_slice_ref(slice_);
  }

 private:
  friend class ByteBuffer;

  grpc_slice slice_;
};

inline grpc::string_ref StringRefFromSlice(const grpc_slice* slice) {
  return grpc::string_ref(
      reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(*slice)),
      GRPC_SLICE_LENGTH(*slice));
}

inline grpc::string StringFromCopiedSlice(grpc_slice slice) {
  return grpc::string(reinterpret_cast<char*>(GRPC_SLICE_START_PTR(slice)),
                      GRPC_SLICE_LENGTH(slice));
}

inline grpc_slice SliceReferencingString(const grpc::string& str) {
  return g_core_codegen_interface->grpc_slice_from_static_buffer(str.data(),
                                                                 str.length());
}

inline grpc_slice SliceFromCopiedString(const grpc::string& str) {
  return g_core_codegen_interface->grpc_slice_from_copied_buffer(str.data(),
                                                                 str.length());
}

}  // namespace grpc

#endif  // GRPCPP_IMPL_CODEGEN_SLICE_H