slice.h 4.9 KB

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