Serenity Operating System
at hosted 153 lines 5.7 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#pragma once 28 29#include <AK/Forward.h> 30#include <AK/StdLibExtras.h> 31#include <AK/StringUtils.h> 32 33namespace AK { 34 35class StringView { 36public: 37 using ConstIterator = const char*; 38 39 StringView() {} 40 StringView(const char* characters, size_t length) 41 : m_characters(characters) 42 , m_length(length) 43 { 44 } 45 StringView(const unsigned char* characters, size_t length) 46 : m_characters((const char*)characters) 47 , m_length(length) 48 { 49 } 50 [[gnu::always_inline]] inline StringView(const char* cstring) 51 : m_characters(cstring) 52 , m_length(cstring ? __builtin_strlen(cstring) : 0) 53 { 54 } 55 56 StringView(const ByteBuffer&); 57 StringView(const String&); 58 StringView(const FlyString&); 59 60 bool is_null() const { return !m_characters; } 61 bool is_empty() const { return m_length == 0; } 62 const char* characters_without_null_termination() const { return m_characters; } 63 size_t length() const { return m_length; } 64 const char& operator[](size_t index) const { return m_characters[index]; } 65 66 ConstIterator begin() const { return characters_without_null_termination(); } 67 ConstIterator end() const { return begin() + length(); } 68 69 unsigned hash() const; 70 71 bool starts_with(const StringView&) const; 72 bool ends_with(const StringView&) const; 73 bool starts_with(char) const; 74 bool ends_with(char) const; 75 bool matches(const StringView& mask, CaseSensitivity = CaseSensitivity::CaseInsensitive) const; 76 77 StringView substring_view(size_t start, size_t length) const; 78 Vector<StringView> split_view(char, bool keep_empty = false) const; 79 80 // Create a Vector of StringViews split by line endings. As of CommonMark 81 // 0.29, the spec defines a line ending as "a newline (U+000A), a carriage 82 // return (U+000D) not followed by a newline, or a carriage return and a 83 // following newline.". 84 Vector<StringView> lines(bool consider_cr = true) const; 85 86 int to_int(bool& ok) const; 87 unsigned to_uint(bool& ok) const; 88 89 // Create a new substring view of this string view, starting either at the beginning of 90 // the given substring view, or after its end, and continuing until the end of this string 91 // view (that is, for the remaining part of its length). For example, 92 // 93 // StringView str { "foobar" }; 94 // StringView substr = str.substring_view(1, 2); // "oo" 95 // StringView substr_from = str.substring_view_starting_from_substring(subst); // "oobar" 96 // StringView substr_after = str.substring_view_starting_after_substring(subst); // "bar" 97 // 98 // Note that this only works if the string view passed as an argument is indeed a substring 99 // view of this string view, such as one created by substring_view() and split_view(). It 100 // does not work for arbitrary strings; for example declaring substr in the example above as 101 // 102 // StringView substr { "oo" }; 103 // 104 // would not work. 105 StringView substring_view_starting_from_substring(const StringView& substring) const; 106 StringView substring_view_starting_after_substring(const StringView& substring) const; 107 108 bool operator==(const char* cstring) const 109 { 110 if (is_null()) 111 return !cstring; 112 if (!cstring) 113 return false; 114 size_t other_length = __builtin_strlen(cstring); 115 if (m_length != other_length) 116 return false; 117 return !__builtin_memcmp(m_characters, cstring, m_length); 118 } 119 bool operator!=(const char* cstring) const 120 { 121 return !(*this == cstring); 122 } 123 124 bool operator==(const String&) const; 125 126 bool operator==(const StringView& other) const 127 { 128 if (is_null()) 129 return other.is_null(); 130 if (other.is_null()) 131 return false; 132 if (length() != other.length()) 133 return false; 134 return !__builtin_memcmp(m_characters, other.m_characters, m_length); 135 } 136 137 bool operator!=(const StringView& other) const 138 { 139 return !(*this == other); 140 } 141 142 const StringImpl* impl() const { return m_impl; } 143 144private: 145 friend class String; 146 const StringImpl* m_impl { nullptr }; 147 const char* m_characters { nullptr }; 148 size_t m_length { 0 }; 149}; 150 151} 152 153using AK::StringView;