string_view.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. *
  3. * Copyright 2019 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 GRPC_CORE_LIB_GPRPP_STRING_VIEW_H
  19. #define GRPC_CORE_LIB_GPRPP_STRING_VIEW_H
  20. #include <grpc/support/port_platform.h>
  21. #include <grpc/impl/codegen/slice.h>
  22. #include <grpc/support/alloc.h>
  23. #include <grpc/support/log.h>
  24. #include <algorithm>
  25. #include <cstdint>
  26. #include <cstring>
  27. #include <limits>
  28. #include <string>
  29. #include "src/core/lib/gpr/string.h"
  30. #include "src/core/lib/gpr/useful.h"
  31. #include "src/core/lib/gprpp/memory.h"
  32. #if GRPC_USE_ABSL
  33. #include "absl/strings/string_view.h"
  34. #endif
  35. namespace grpc_core {
  36. #if GRPC_USE_ABSL
  37. using StringView = absl::string_view;
  38. #else
  39. // Provides a light-weight view over a char array or a slice, similar but not
  40. // identical to absl::string_view.
  41. //
  42. // Any method that has the same name as absl::string_view MUST HAVE identical
  43. // semantics to what absl::string_view provides.
  44. //
  45. // Methods that are not part of absl::string_view API, must be clearly
  46. // annotated.
  47. //
  48. // StringView does not own the buffers that back the view. Callers must ensure
  49. // the buffer stays around while the StringView is accessible.
  50. //
  51. // Pass StringView by value in functions, since it is exactly two pointers in
  52. // size.
  53. //
  54. // The interface used here is not identical to absl::string_view. Notably, we
  55. // need to support slices while we cannot support std::string, and gpr string
  56. // style functions such as strdup() and cmp(). Once we switch to
  57. // absl::string_view this class will inherit from absl::string_view and add the
  58. // gRPC-specific APIs.
  59. class StringView final {
  60. public:
  61. static constexpr size_t npos = std::numeric_limits<size_t>::max();
  62. constexpr StringView(const char* ptr, size_t size) : ptr_(ptr), size_(size) {}
  63. constexpr StringView(const char* ptr)
  64. : StringView(ptr, ptr == nullptr ? 0 : strlen(ptr)) {}
  65. constexpr StringView() : StringView(nullptr, 0) {}
  66. constexpr const char* data() const { return ptr_; }
  67. constexpr size_t size() const { return size_; }
  68. constexpr bool empty() const { return size_ == 0; }
  69. StringView substr(size_t start, size_t size = npos) {
  70. GPR_DEBUG_ASSERT(start + size <= size_);
  71. return StringView(ptr_ + start, std::min(size, size_ - start));
  72. }
  73. constexpr const char& operator[](size_t i) const { return ptr_[i]; }
  74. const char& front() const { return ptr_[0]; }
  75. const char& back() const { return ptr_[size_ - 1]; }
  76. void remove_prefix(size_t n) {
  77. GPR_DEBUG_ASSERT(n <= size_);
  78. ptr_ += n;
  79. size_ -= n;
  80. }
  81. void remove_suffix(size_t n) {
  82. GPR_DEBUG_ASSERT(n <= size_);
  83. size_ -= n;
  84. }
  85. size_t find(char c, size_t pos = 0) const {
  86. if (empty() || pos >= size_) return npos;
  87. const char* result =
  88. static_cast<const char*>(memchr(ptr_ + pos, c, size_ - pos));
  89. return result != nullptr ? result - ptr_ : npos;
  90. }
  91. void clear() {
  92. ptr_ = nullptr;
  93. size_ = 0;
  94. }
  95. // Converts to `std::basic_string`.
  96. template <typename Allocator>
  97. explicit operator std::basic_string<char, std::char_traits<char>, Allocator>()
  98. const {
  99. if (data() == nullptr) return {};
  100. return std::basic_string<char, std::char_traits<char>, Allocator>(data(),
  101. size());
  102. }
  103. private:
  104. const char* ptr_;
  105. size_t size_;
  106. };
  107. inline bool operator==(StringView lhs, StringView rhs) {
  108. return lhs.size() == rhs.size() &&
  109. strncmp(lhs.data(), rhs.data(), lhs.size()) == 0;
  110. }
  111. inline bool operator!=(StringView lhs, StringView rhs) { return !(lhs == rhs); }
  112. #endif // GRPC_USE_ABSL
  113. // Converts grpc_slice to StringView.
  114. inline StringView StringViewFromSlice(const grpc_slice& slice) {
  115. return StringView(reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(slice)),
  116. GRPC_SLICE_LENGTH(slice));
  117. }
  118. // Creates a dup of the string viewed by this class.
  119. // Return value is null-terminated and never nullptr.
  120. inline grpc_core::UniquePtr<char> StringViewToCString(const StringView sv) {
  121. char* str = static_cast<char*>(gpr_malloc(sv.size() + 1));
  122. if (sv.size() > 0) memcpy(str, sv.data(), sv.size());
  123. str[sv.size()] = '\0';
  124. return grpc_core::UniquePtr<char>(str);
  125. }
  126. // Compares lhs and rhs.
  127. inline int StringViewCmp(const StringView lhs, const StringView rhs) {
  128. const size_t len = GPR_MIN(lhs.size(), rhs.size());
  129. const int ret = strncmp(lhs.data(), rhs.data(), len);
  130. if (ret != 0) return ret;
  131. if (lhs.size() == rhs.size()) return 0;
  132. if (lhs.size() < rhs.size()) return -1;
  133. return 1;
  134. }
  135. } // namespace grpc_core
  136. #endif /* GRPC_CORE_LIB_GPRPP_STRING_VIEW_H */