3 * Copyright 2019 gRPC authors.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #ifndef GRPC_CORE_LIB_GPRPP_STRING_VIEW_H
19 #define GRPC_CORE_LIB_GPRPP_STRING_VIEW_H
21 #include <grpc/support/port_platform.h>
23 #include <grpc/impl/codegen/slice.h>
24 #include <grpc/support/alloc.h>
25 #include <grpc/support/log.h>
32 #include "src/core/lib/gpr/string.h"
33 #include "src/core/lib/gpr/useful.h"
34 #include "src/core/lib/gprpp/memory.h"
38 // Provides a light-weight view over a char array or a slice, similar but not
39 // identical to absl::string_view.
41 // Any method that has the same name as absl::string_view MUST HAVE identical
42 // semantics to what absl::string_view provides.
44 // Methods that are not part of absl::string_view API, must be clearly
47 // StringView does not own the buffers that back the view. Callers must ensure
48 // the buffer stays around while the StringView is accessible.
50 // Pass StringView by value in functions, since it is exactly two pointers in
53 // The interface used here is not identical to absl::string_view. Notably, we
54 // need to support slices while we cannot support std::string, and gpr string
55 // style functions such as strdup() and cmp(). Once we switch to
56 // absl::string_view this class will inherit from absl::string_view and add the
57 // gRPC-specific APIs.
58 class StringView final {
60 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 // Not part of absl::string_view API.
66 StringView(const grpc_slice& slice)
67 : StringView(reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(slice)),
68 GRPC_SLICE_LENGTH(slice)) {}
69 constexpr StringView() : StringView(nullptr, 0) {}
71 constexpr const char* data() const { return ptr_; }
72 constexpr size_t size() const { return size_; }
73 constexpr bool empty() const { return size_ == 0; }
75 StringView substr(size_t start, size_t size = npos) {
76 GPR_DEBUG_ASSERT(start + size <= size_);
77 return StringView(ptr_ + start, std::min(size, size_ - start));
80 constexpr const char& operator[](size_t i) const { return ptr_[i]; }
82 const char& front() const { return ptr_[0]; }
83 const char& back() const { return ptr_[size_ - 1]; }
85 void remove_prefix(size_t n) {
86 GPR_DEBUG_ASSERT(n <= size_);
91 void remove_suffix(size_t n) {
92 GPR_DEBUG_ASSERT(n <= size_);
96 size_t find(char c, size_t pos = 0) const {
97 if (empty() || pos >= size_) return npos;
99 static_cast<const char*>(memchr(ptr_ + pos, c, size_ - pos));
100 return result != nullptr ? result - ptr_ : npos;
108 // Creates a dup of the string viewed by this class.
109 // Return value is null-terminated and never nullptr.
111 // Not part of absl::string_view API.
112 grpc_core::UniquePtr<char> dup() const {
113 char* str = static_cast<char*>(gpr_malloc(size_ + 1));
114 if (size_ > 0) memcpy(str, ptr_, size_);
116 return grpc_core::UniquePtr<char>(str);
119 // Not part of absl::string_view API.
120 int cmp(StringView other) const {
121 const size_t len = GPR_MIN(size(), other.size());
122 const int ret = strncmp(data(), other.data(), len);
123 if (ret != 0) return ret;
124 if (size() == other.size()) return 0;
125 if (size() < other.size()) return -1;
134 inline bool operator==(StringView lhs, StringView rhs) {
135 return lhs.size() == rhs.size() &&
136 strncmp(lhs.data(), rhs.data(), lhs.size()) == 0;
139 inline bool operator!=(StringView lhs, StringView rhs) { return !(lhs == rhs); }
141 } // namespace grpc_core
143 #endif /* GRPC_CORE_LIB_GPRPP_STRING_VIEW_H */