Home | History | Annotate | Download | only in codegen
      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