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