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