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