1 // Copyright 2016 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_INSPECTOR_STRING16_H_ 6 #define V8_INSPECTOR_STRING16_H_ 7 8 #include <stdint.h> 9 #include <cctype> 10 #include <climits> 11 #include <cstring> 12 #include <string> 13 #include <vector> 14 15 namespace v8_inspector { 16 17 using UChar = uint16_t; 18 19 class String16 { 20 public: 21 static const size_t kNotFound = static_cast<size_t>(-1); 22 23 String16() {} 24 String16(const String16& other) 25 : m_impl(other.m_impl), hash_code(other.hash_code) {} 26 String16(const String16&& other) 27 : m_impl(std::move(other.m_impl)), hash_code(other.hash_code) {} 28 String16(const UChar* characters, size_t size) : m_impl(characters, size) {} 29 String16(const UChar* characters) // NOLINT(runtime/explicit) 30 : m_impl(characters) {} 31 String16(const char* characters) // NOLINT(runtime/explicit) 32 : String16(characters, std::strlen(characters)) {} 33 String16(const char* characters, size_t size) { 34 m_impl.resize(size); 35 for (size_t i = 0; i < size; ++i) m_impl[i] = characters[i]; 36 } 37 explicit String16(const std::basic_string<UChar>& impl) : m_impl(impl) {} 38 39 String16& operator=(const String16& other) { 40 m_impl = other.m_impl; 41 hash_code = other.hash_code; 42 return *this; 43 } 44 String16& operator=(String16&& other) { 45 m_impl = std::move(other.m_impl); 46 hash_code = other.hash_code; 47 return *this; 48 } 49 50 static String16 fromInteger(int); 51 static String16 fromInteger(size_t); 52 static String16 fromDouble(double); 53 static String16 fromDouble(double, int precision); 54 55 int toInteger(bool* ok = nullptr) const; 56 String16 stripWhiteSpace() const; 57 const UChar* characters16() const { return m_impl.c_str(); } 58 size_t length() const { return m_impl.length(); } 59 bool isEmpty() const { return !m_impl.length(); } 60 UChar operator[](size_t index) const { return m_impl[index]; } 61 String16 substring(size_t pos, size_t len = UINT_MAX) const { 62 return String16(m_impl.substr(pos, len)); 63 } 64 size_t find(const String16& str, size_t start = 0) const { 65 return m_impl.find(str.m_impl, start); 66 } 67 size_t reverseFind(const String16& str, size_t start = UINT_MAX) const { 68 return m_impl.rfind(str.m_impl, start); 69 } 70 size_t find(UChar c, size_t start = 0) const { return m_impl.find(c, start); } 71 size_t reverseFind(UChar c, size_t start = UINT_MAX) const { 72 return m_impl.rfind(c, start); 73 } 74 void swap(String16& other) { 75 m_impl.swap(other.m_impl); 76 std::swap(hash_code, other.hash_code); 77 } 78 79 // Convenience methods. 80 std::string utf8() const; 81 static String16 fromUTF8(const char* stringStart, size_t length); 82 83 std::size_t hash() const { 84 if (!hash_code) { 85 for (char c : m_impl) hash_code = 31 * hash_code + c; 86 // Map hash code 0 to 1. This double the number of hash collisions for 1, 87 // but avoids recomputing the hash code. 88 if (!hash_code) ++hash_code; 89 } 90 return hash_code; 91 } 92 93 inline bool operator==(const String16& other) const { 94 return m_impl == other.m_impl; 95 } 96 inline bool operator<(const String16& other) const { 97 return m_impl < other.m_impl; 98 } 99 inline bool operator!=(const String16& other) const { 100 return m_impl != other.m_impl; 101 } 102 inline String16 operator+(const String16& other) const { 103 return String16(m_impl + other.m_impl); 104 } 105 106 // Defined later, since it uses the String16Builder. 107 template <typename... T> 108 static String16 concat(T... args); 109 110 private: 111 std::basic_string<UChar> m_impl; 112 mutable std::size_t hash_code = 0; 113 }; 114 115 inline String16 operator+(const char* a, const String16& b) { 116 return String16(a) + b; 117 } 118 119 class String16Builder { 120 public: 121 String16Builder(); 122 void append(const String16&); 123 void append(UChar); 124 void append(char); 125 void append(const UChar*, size_t); 126 void append(const char*, size_t); 127 void appendNumber(int); 128 void appendNumber(size_t); 129 String16 toString(); 130 void reserveCapacity(size_t); 131 132 template <typename T, typename... R> 133 void appendAll(T first, R... rest) { 134 append(first); 135 appendAll(rest...); 136 } 137 void appendAll() {} 138 139 private: 140 std::vector<UChar> m_buffer; 141 }; 142 143 template <typename... T> 144 String16 String16::concat(T... args) { 145 String16Builder builder; 146 builder.appendAll(args...); 147 return builder.toString(); 148 } 149 150 } // namespace v8_inspector 151 152 #if !defined(__APPLE__) || defined(_LIBCPP_VERSION) 153 154 namespace std { 155 template <> 156 struct hash<v8_inspector::String16> { 157 std::size_t operator()(const v8_inspector::String16& string) const { 158 return string.hash(); 159 } 160 }; 161 162 } // namespace std 163 164 #endif // !defined(__APPLE__) || defined(_LIBCPP_VERSION) 165 166 #endif // V8_INSPECTOR_STRING16_H_ 167