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_IMPL_CODEGEN_SLICE_H 20 #define GRPCPP_IMPL_CODEGEN_SLICE_H 21 22 #include <grpcpp/impl/codegen/config.h> 23 #include <grpcpp/impl/codegen/core_codegen_interface.h> 24 #include <grpcpp/impl/codegen/string_ref.h> 25 26 #include <grpc/impl/codegen/slice.h> 27 28 namespace grpc { 29 30 /// A wrapper around \a grpc_slice. 31 /// 32 /// A slice represents a contiguous reference counted array of bytes. 33 /// It is cheap to take references to a slice, and it is cheap to create a 34 /// slice pointing to a subset of another slice. 35 class Slice final { 36 public: 37 /// Construct an empty slice. 38 Slice() : slice_(g_core_codegen_interface->grpc_empty_slice()) {} 39 /// Destructor - drops one reference. 40 ~Slice() { g_core_codegen_interface->grpc_slice_unref(slice_); } 41 42 enum AddRef { ADD_REF }; 43 /// Construct a slice from \a slice, adding a reference. 44 Slice(grpc_slice slice, AddRef) 45 : slice_(g_core_codegen_interface->grpc_slice_ref(slice)) {} 46 47 enum StealRef { STEAL_REF }; 48 /// Construct a slice from \a slice, stealing a reference. 49 Slice(grpc_slice slice, StealRef) : slice_(slice) {} 50 51 /// Allocate a slice of specified size 52 Slice(size_t len) 53 : slice_(g_core_codegen_interface->grpc_slice_malloc(len)) {} 54 55 /// Construct a slice from a copied buffer 56 Slice(const void* buf, size_t len) 57 : slice_(g_core_codegen_interface->grpc_slice_from_copied_buffer( 58 reinterpret_cast<const char*>(buf), len)) {} 59 60 /// Construct a slice from a copied string 61 Slice(const grpc::string& str) 62 : slice_(g_core_codegen_interface->grpc_slice_from_copied_buffer( 63 str.c_str(), str.length())) {} 64 65 enum StaticSlice { STATIC_SLICE }; 66 67 /// Construct a slice from a static buffer 68 Slice(const void* buf, size_t len, StaticSlice) 69 : slice_(g_core_codegen_interface->grpc_slice_from_static_buffer( 70 reinterpret_cast<const char*>(buf), len)) {} 71 72 /// Copy constructor, adds a reference. 73 Slice(const Slice& other) 74 : slice_(g_core_codegen_interface->grpc_slice_ref(other.slice_)) {} 75 76 /// Assignment, reference count is unchanged. 77 Slice& operator=(Slice other) { 78 std::swap(slice_, other.slice_); 79 return *this; 80 } 81 82 /// Create a slice pointing at some data. Calls malloc to allocate a refcount 83 /// for the object, and arranges that destroy will be called with the 84 /// user data pointer passed in at destruction. Can be the same as buf or 85 /// different (e.g., if data is part of a larger structure that must be 86 /// destroyed when the data is no longer needed) 87 Slice(void* buf, size_t len, void (*destroy)(void*), void* user_data) 88 : slice_(g_core_codegen_interface->grpc_slice_new_with_user_data( 89 buf, len, destroy, user_data)) {} 90 91 /// Specialization of above for common case where buf == user_data 92 Slice(void* buf, size_t len, void (*destroy)(void*)) 93 : Slice(buf, len, destroy, buf) {} 94 95 /// Similar to the above but has a destroy that also takes slice length 96 Slice(void* buf, size_t len, void (*destroy)(void*, size_t)) 97 : slice_(g_core_codegen_interface->grpc_slice_new_with_len(buf, len, 98 destroy)) {} 99 100 /// Byte size. 101 size_t size() const { return GRPC_SLICE_LENGTH(slice_); } 102 103 /// Raw pointer to the beginning (first element) of the slice. 104 const uint8_t* begin() const { return GRPC_SLICE_START_PTR(slice_); } 105 106 /// Raw pointer to the end (one byte \em past the last element) of the slice. 107 const uint8_t* end() const { return GRPC_SLICE_END_PTR(slice_); } 108 109 /// Raw C slice. Caller needs to call grpc_slice_unref when done. 110 grpc_slice c_slice() const { 111 return g_core_codegen_interface->grpc_slice_ref(slice_); 112 } 113 114 private: 115 friend class ByteBuffer; 116 117 grpc_slice slice_; 118 }; 119 120 inline grpc::string_ref StringRefFromSlice(const grpc_slice* slice) { 121 return grpc::string_ref( 122 reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(*slice)), 123 GRPC_SLICE_LENGTH(*slice)); 124 } 125 126 inline grpc::string StringFromCopiedSlice(grpc_slice slice) { 127 return grpc::string(reinterpret_cast<char*>(GRPC_SLICE_START_PTR(slice)), 128 GRPC_SLICE_LENGTH(slice)); 129 } 130 131 inline grpc_slice SliceReferencingString(const grpc::string& str) { 132 return g_core_codegen_interface->grpc_slice_from_static_buffer(str.data(), 133 str.length()); 134 } 135 136 inline grpc_slice SliceFromCopiedString(const grpc::string& str) { 137 return g_core_codegen_interface->grpc_slice_from_copied_buffer(str.data(), 138 str.length()); 139 } 140 141 } // namespace grpc 142 143 #endif // GRPCPP_IMPL_CODEGEN_SLICE_H 144