11cb0ef41Sopenharmony_ci#include "node_string.h"
21cb0ef41Sopenharmony_ci#include "node/inspector/protocol/Protocol.h"
31cb0ef41Sopenharmony_ci#include "node_util.h"
41cb0ef41Sopenharmony_ci#include "simdutf.h"
51cb0ef41Sopenharmony_ci#include "util-inl.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_cinamespace node {
81cb0ef41Sopenharmony_cinamespace inspector {
91cb0ef41Sopenharmony_cinamespace protocol {
101cb0ef41Sopenharmony_cinamespace StringUtil {
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cisize_t kNotFound = std::string::npos;
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci// NOLINTNEXTLINE(runtime/references) V8 API requirement
151cb0ef41Sopenharmony_civoid builderAppendQuotedString(StringBuilder& builder,
161cb0ef41Sopenharmony_ci                               const std::string_view string) {
171cb0ef41Sopenharmony_ci  builder.put('"');
181cb0ef41Sopenharmony_ci  if (!string.empty()) {
191cb0ef41Sopenharmony_ci    size_t expected_utf16_length =
201cb0ef41Sopenharmony_ci        simdutf::utf16_length_from_utf8(string.data(), string.length());
211cb0ef41Sopenharmony_ci    MaybeStackBuffer<char16_t> buffer(expected_utf16_length);
221cb0ef41Sopenharmony_ci    // simdutf::convert_utf8_to_utf16 returns zero in case of error.
231cb0ef41Sopenharmony_ci    size_t utf16_length = simdutf::convert_utf8_to_utf16(
241cb0ef41Sopenharmony_ci        string.data(), string.length(), buffer.out());
251cb0ef41Sopenharmony_ci    // We have that utf16_length == expected_utf16_length if and only
261cb0ef41Sopenharmony_ci    // if the input was a valid UTF-8 string.
271cb0ef41Sopenharmony_ci    if (utf16_length != 0) {
281cb0ef41Sopenharmony_ci      CHECK_EQ(expected_utf16_length, utf16_length);
291cb0ef41Sopenharmony_ci      escapeWideStringForJSON(reinterpret_cast<const uint16_t*>(buffer.out()),
301cb0ef41Sopenharmony_ci                              utf16_length,
311cb0ef41Sopenharmony_ci                              &builder);
321cb0ef41Sopenharmony_ci    }  // Otherwise, we had an invalid UTF-8 input.
331cb0ef41Sopenharmony_ci  }
341cb0ef41Sopenharmony_ci  builder.put('"');
351cb0ef41Sopenharmony_ci}
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_cistd::unique_ptr<Value> parseJSON(const std::string_view string) {
381cb0ef41Sopenharmony_ci  if (string.empty())
391cb0ef41Sopenharmony_ci    return nullptr;
401cb0ef41Sopenharmony_ci  size_t expected_utf16_length =
411cb0ef41Sopenharmony_ci      simdutf::utf16_length_from_utf8(string.data(), string.length());
421cb0ef41Sopenharmony_ci  MaybeStackBuffer<char16_t> buffer(expected_utf16_length);
431cb0ef41Sopenharmony_ci  // simdutf::convert_utf8_to_utf16 returns zero in case of error.
441cb0ef41Sopenharmony_ci  size_t utf16_length = simdutf::convert_utf8_to_utf16(
451cb0ef41Sopenharmony_ci      string.data(), string.length(), buffer.out());
461cb0ef41Sopenharmony_ci  // We have that utf16_length == expected_utf16_length if and only
471cb0ef41Sopenharmony_ci  // if the input was a valid UTF-8 string.
481cb0ef41Sopenharmony_ci  if (utf16_length == 0) return nullptr;  // We had an invalid UTF-8 input.
491cb0ef41Sopenharmony_ci  CHECK_EQ(expected_utf16_length, utf16_length);
501cb0ef41Sopenharmony_ci  return parseJSONCharacters(reinterpret_cast<const uint16_t*>(buffer.out()),
511cb0ef41Sopenharmony_ci                             utf16_length);
521cb0ef41Sopenharmony_ci}
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_cistd::unique_ptr<Value> parseJSON(v8_inspector::StringView string) {
551cb0ef41Sopenharmony_ci  if (string.length() == 0)
561cb0ef41Sopenharmony_ci    return nullptr;
571cb0ef41Sopenharmony_ci  if (string.is8Bit())
581cb0ef41Sopenharmony_ci    return parseJSONCharacters(string.characters8(), string.length());
591cb0ef41Sopenharmony_ci  return parseJSONCharacters(string.characters16(), string.length());
601cb0ef41Sopenharmony_ci}
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ciString StringViewToUtf8(v8_inspector::StringView view) {
631cb0ef41Sopenharmony_ci  if (view.length() == 0)
641cb0ef41Sopenharmony_ci    return "";
651cb0ef41Sopenharmony_ci  if (view.is8Bit()) {
661cb0ef41Sopenharmony_ci    return std::string(reinterpret_cast<const char*>(view.characters8()),
671cb0ef41Sopenharmony_ci                       view.length());
681cb0ef41Sopenharmony_ci  }
691cb0ef41Sopenharmony_ci  const char16_t* source =
701cb0ef41Sopenharmony_ci      reinterpret_cast<const char16_t*>(view.characters16());
711cb0ef41Sopenharmony_ci  size_t expected_utf8_length =
721cb0ef41Sopenharmony_ci      simdutf::utf8_length_from_utf16(source, view.length());
731cb0ef41Sopenharmony_ci  MaybeStackBuffer<char> buffer(expected_utf8_length);
741cb0ef41Sopenharmony_ci  // convert_utf16_to_utf8 returns zero in case of error.
751cb0ef41Sopenharmony_ci  size_t utf8_length =
761cb0ef41Sopenharmony_ci      simdutf::convert_utf16_to_utf8(source, view.length(), buffer.out());
771cb0ef41Sopenharmony_ci  // We have that utf8_length == expected_utf8_length if and only
781cb0ef41Sopenharmony_ci  // if the input was a valid UTF-16 string. Otherwise, utf8_length
791cb0ef41Sopenharmony_ci  // must be zero.
801cb0ef41Sopenharmony_ci  CHECK(utf8_length == 0 || utf8_length == expected_utf8_length);
811cb0ef41Sopenharmony_ci  // An invalid UTF-16 input will generate the empty string:
821cb0ef41Sopenharmony_ci  return String(buffer.out(), utf8_length);
831cb0ef41Sopenharmony_ci}
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ciString fromDouble(double d) {
861cb0ef41Sopenharmony_ci  std::ostringstream stream;
871cb0ef41Sopenharmony_ci  stream.imbue(std::locale::classic());  // Ignore current locale
881cb0ef41Sopenharmony_ci  stream << d;
891cb0ef41Sopenharmony_ci  return stream.str();
901cb0ef41Sopenharmony_ci}
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_cidouble toDouble(const char* buffer, size_t length, bool* ok) {
931cb0ef41Sopenharmony_ci  std::istringstream stream(std::string(buffer, length));
941cb0ef41Sopenharmony_ci  stream.imbue(std::locale::classic());  // Ignore current locale
951cb0ef41Sopenharmony_ci  double d;
961cb0ef41Sopenharmony_ci  stream >> d;
971cb0ef41Sopenharmony_ci  *ok = !stream.fail();
981cb0ef41Sopenharmony_ci  return d;
991cb0ef41Sopenharmony_ci}
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_cistd::unique_ptr<Value> parseMessage(const std::string_view message,
1021cb0ef41Sopenharmony_ci                                    bool binary) {
1031cb0ef41Sopenharmony_ci  if (binary) {
1041cb0ef41Sopenharmony_ci    return Value::parseBinary(
1051cb0ef41Sopenharmony_ci        reinterpret_cast<const uint8_t*>(message.data()),
1061cb0ef41Sopenharmony_ci        message.length());
1071cb0ef41Sopenharmony_ci  }
1081cb0ef41Sopenharmony_ci  return parseJSON(message);
1091cb0ef41Sopenharmony_ci}
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ciProtocolMessage jsonToMessage(String message) {
1121cb0ef41Sopenharmony_ci  return message;
1131cb0ef41Sopenharmony_ci}
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ciProtocolMessage binaryToMessage(std::vector<uint8_t> message) {
1161cb0ef41Sopenharmony_ci  return std::string(reinterpret_cast<const char*>(message.data()),
1171cb0ef41Sopenharmony_ci                     message.size());
1181cb0ef41Sopenharmony_ci}
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ciString fromUTF8(const uint8_t* data, size_t length) {
1211cb0ef41Sopenharmony_ci  return std::string(reinterpret_cast<const char*>(data), length);
1221cb0ef41Sopenharmony_ci}
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ciString fromUTF16(const uint16_t* data, size_t length) {
1251cb0ef41Sopenharmony_ci  auto casted_data = reinterpret_cast<const char16_t*>(data);
1261cb0ef41Sopenharmony_ci  size_t expected_utf8_length =
1271cb0ef41Sopenharmony_ci      simdutf::utf8_length_from_utf16(casted_data, length);
1281cb0ef41Sopenharmony_ci  MaybeStackBuffer<char> buffer(expected_utf8_length);
1291cb0ef41Sopenharmony_ci  // simdutf::convert_utf16_to_utf8 returns zero in case of error.
1301cb0ef41Sopenharmony_ci  size_t utf8_length =
1311cb0ef41Sopenharmony_ci      simdutf::convert_utf16_to_utf8(casted_data, length, buffer.out());
1321cb0ef41Sopenharmony_ci  // We have that utf8_length == expected_utf8_length if and only
1331cb0ef41Sopenharmony_ci  // if the input was a valid UTF-16 string. Otherwise, utf8_length
1341cb0ef41Sopenharmony_ci  // must be zero.
1351cb0ef41Sopenharmony_ci  CHECK(utf8_length == 0 || utf8_length == expected_utf8_length);
1361cb0ef41Sopenharmony_ci  // An invalid UTF-16 input will generate the empty string:
1371cb0ef41Sopenharmony_ci  return String(buffer.out(), utf8_length);
1381cb0ef41Sopenharmony_ci}
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ciconst uint8_t* CharactersUTF8(const std::string_view s) {
1411cb0ef41Sopenharmony_ci  return reinterpret_cast<const uint8_t*>(s.data());
1421cb0ef41Sopenharmony_ci}
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_cisize_t CharacterCount(const std::string_view s) {
1451cb0ef41Sopenharmony_ci  // The utf32_length_from_utf8 function calls count_utf8.
1461cb0ef41Sopenharmony_ci  // The count_utf8 function counts the number of code points
1471cb0ef41Sopenharmony_ci  // (characters) in the string, assuming that the string is valid Unicode.
1481cb0ef41Sopenharmony_ci  // TODO(@anonrig): Test to make sure CharacterCount returns correctly.
1491cb0ef41Sopenharmony_ci  return simdutf::utf32_length_from_utf8(s.data(), s.length());
1501cb0ef41Sopenharmony_ci}
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci}  // namespace StringUtil
1531cb0ef41Sopenharmony_ci}  // namespace protocol
1541cb0ef41Sopenharmony_ci}  // namespace inspector
1551cb0ef41Sopenharmony_ci}  // namespace node
1561cb0ef41Sopenharmony_ci
157