1// Copyright (c) 2021 Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30#ifndef COMMON_STRING_VIEW_H__
31#define COMMON_STRING_VIEW_H__
32
33#include <cassert>
34#include <cstring>
35#include <ostream>
36#include "common/using_std_string.h"
37
38namespace google_breakpad {
39
40// A StringView is a string reference to a string object, but not own the
41// string object. It's a compatibile layer until we can use std::string_view in
42// C++17.
43class StringView {
44 private:
45 // The start of the string, in an external buffer. It doesn't have to be
46 // null-terminated.
47 const char* data_ = "";
48
49 size_t length_ = 0;
50
51 public:
52 // Construct an empty StringView.
53 StringView() = default;
54
55 // Disallow construct StringView from nullptr.
56 StringView(std::nullptr_t) = delete;
57
58 // Construct a StringView from a cstring.
59 StringView(const char* str) : data_(str) {
60 assert(str);
61 length_ = strlen(str);
62 }
63
64 // Construct a StringView from a cstring with fixed length.
65 StringView(const char* str, size_t length) : data_(str), length_(length) {
66 assert(str);
67 }
68
69 // Construct a StringView from an std::string.
70 StringView(const string& str) : data_(str.data()), length_(str.length()) {}
71
72 string str() const { return string(data_, length_); }
73
74 const char* data() const { return data_; }
75
76 bool empty() const { return length_ == 0; }
77
78 size_t size() const { return length_; }
79
80 int compare(StringView rhs) const {
81 size_t min_len = std::min(size(), rhs.size());
82 int res = memcmp(data_, rhs.data(), min_len);
83 if (res != 0)
84 return res;
85 if (size() == rhs.size())
86 return 0;
87 return size() < rhs.size() ? -1 : 1;
88 }
89};
90
91inline bool operator==(StringView lhs, StringView rhs) {
92 return lhs.compare(rhs) == 0;
93}
94
95inline bool operator!=(StringView lhs, StringView rhs) {
96 return lhs.compare(rhs) != 0;
97}
98
99inline bool operator<(StringView lhs, StringView rhs) {
100 return lhs.compare(rhs) < 0;
101}
102
103inline bool operator>(StringView lhs, StringView rhs) {
104 return lhs.compare(rhs) > 0;
105}
106
107inline std::ostream& operator<<(std::ostream& os, StringView s) {
108 os << s.str();
109 return os;
110}
111
112} // namespace google_breakpad
113
114#endif // COMMON_STRING_VIEW_H__
115