• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "node_string.h"
2 #include "node/inspector/protocol/Protocol.h"
3 #include "node_util.h"
4 #include "simdutf.h"
5 #include "util-inl.h"
6 
7 namespace node {
8 namespace inspector {
9 namespace protocol {
10 namespace StringUtil {
11 
12 size_t kNotFound = std::string::npos;
13 
14 // NOLINTNEXTLINE(runtime/references) V8 API requirement
builderAppendQuotedString(StringBuilder & builder,const std::string_view string)15 void builderAppendQuotedString(StringBuilder& builder,
16                                const std::string_view string) {
17   builder.put('"');
18   if (!string.empty()) {
19     size_t expected_utf16_length =
20         simdutf::utf16_length_from_utf8(string.data(), string.length());
21     MaybeStackBuffer<char16_t> buffer(expected_utf16_length);
22     // simdutf::convert_utf8_to_utf16 returns zero in case of error.
23     size_t utf16_length = simdutf::convert_utf8_to_utf16(
24         string.data(), string.length(), buffer.out());
25     // We have that utf16_length == expected_utf16_length if and only
26     // if the input was a valid UTF-8 string.
27     if (utf16_length != 0) {
28       CHECK_EQ(expected_utf16_length, utf16_length);
29       escapeWideStringForJSON(reinterpret_cast<const uint16_t*>(buffer.out()),
30                               utf16_length,
31                               &builder);
32     }  // Otherwise, we had an invalid UTF-8 input.
33   }
34   builder.put('"');
35 }
36 
parseJSON(const std::string_view string)37 std::unique_ptr<Value> parseJSON(const std::string_view string) {
38   if (string.empty())
39     return nullptr;
40   size_t expected_utf16_length =
41       simdutf::utf16_length_from_utf8(string.data(), string.length());
42   MaybeStackBuffer<char16_t> buffer(expected_utf16_length);
43   // simdutf::convert_utf8_to_utf16 returns zero in case of error.
44   size_t utf16_length = simdutf::convert_utf8_to_utf16(
45       string.data(), string.length(), buffer.out());
46   // We have that utf16_length == expected_utf16_length if and only
47   // if the input was a valid UTF-8 string.
48   if (utf16_length == 0) return nullptr;  // We had an invalid UTF-8 input.
49   CHECK_EQ(expected_utf16_length, utf16_length);
50   return parseJSONCharacters(reinterpret_cast<const uint16_t*>(buffer.out()),
51                              utf16_length);
52 }
53 
parseJSON(v8_inspector::StringView string)54 std::unique_ptr<Value> parseJSON(v8_inspector::StringView string) {
55   if (string.length() == 0)
56     return nullptr;
57   if (string.is8Bit())
58     return parseJSONCharacters(string.characters8(), string.length());
59   return parseJSONCharacters(string.characters16(), string.length());
60 }
61 
StringViewToUtf8(v8_inspector::StringView view)62 String StringViewToUtf8(v8_inspector::StringView view) {
63   if (view.length() == 0)
64     return "";
65   if (view.is8Bit()) {
66     return std::string(reinterpret_cast<const char*>(view.characters8()),
67                        view.length());
68   }
69   const char16_t* source =
70       reinterpret_cast<const char16_t*>(view.characters16());
71   size_t expected_utf8_length =
72       simdutf::utf8_length_from_utf16(source, view.length());
73   MaybeStackBuffer<char> buffer(expected_utf8_length);
74   // convert_utf16_to_utf8 returns zero in case of error.
75   size_t utf8_length =
76       simdutf::convert_utf16_to_utf8(source, view.length(), buffer.out());
77   // We have that utf8_length == expected_utf8_length if and only
78   // if the input was a valid UTF-16 string. Otherwise, utf8_length
79   // must be zero.
80   CHECK(utf8_length == 0 || utf8_length == expected_utf8_length);
81   // An invalid UTF-16 input will generate the empty string:
82   return String(buffer.out(), utf8_length);
83 }
84 
fromDouble(double d)85 String fromDouble(double d) {
86   std::ostringstream stream;
87   stream.imbue(std::locale::classic());  // Ignore current locale
88   stream << d;
89   return stream.str();
90 }
91 
toDouble(const char * buffer,size_t length,bool * ok)92 double toDouble(const char* buffer, size_t length, bool* ok) {
93   std::istringstream stream(std::string(buffer, length));
94   stream.imbue(std::locale::classic());  // Ignore current locale
95   double d;
96   stream >> d;
97   *ok = !stream.fail();
98   return d;
99 }
100 
parseMessage(const std::string_view message,bool binary)101 std::unique_ptr<Value> parseMessage(const std::string_view message,
102                                     bool binary) {
103   if (binary) {
104     return Value::parseBinary(
105         reinterpret_cast<const uint8_t*>(message.data()),
106         message.length());
107   }
108   return parseJSON(message);
109 }
110 
jsonToMessage(String message)111 ProtocolMessage jsonToMessage(String message) {
112   return message;
113 }
114 
binaryToMessage(std::vector<uint8_t> message)115 ProtocolMessage binaryToMessage(std::vector<uint8_t> message) {
116   return std::string(reinterpret_cast<const char*>(message.data()),
117                      message.size());
118 }
119 
fromUTF8(const uint8_t * data,size_t length)120 String fromUTF8(const uint8_t* data, size_t length) {
121   return std::string(reinterpret_cast<const char*>(data), length);
122 }
123 
fromUTF16(const uint16_t * data,size_t length)124 String fromUTF16(const uint16_t* data, size_t length) {
125   auto casted_data = reinterpret_cast<const char16_t*>(data);
126   size_t expected_utf8_length =
127       simdutf::utf8_length_from_utf16(casted_data, length);
128   MaybeStackBuffer<char> buffer(expected_utf8_length);
129   // simdutf::convert_utf16_to_utf8 returns zero in case of error.
130   size_t utf8_length =
131       simdutf::convert_utf16_to_utf8(casted_data, length, buffer.out());
132   // We have that utf8_length == expected_utf8_length if and only
133   // if the input was a valid UTF-16 string. Otherwise, utf8_length
134   // must be zero.
135   CHECK(utf8_length == 0 || utf8_length == expected_utf8_length);
136   // An invalid UTF-16 input will generate the empty string:
137   return String(buffer.out(), utf8_length);
138 }
139 
CharactersUTF8(const std::string_view s)140 const uint8_t* CharactersUTF8(const std::string_view s) {
141   return reinterpret_cast<const uint8_t*>(s.data());
142 }
143 
CharacterCount(const std::string_view s)144 size_t CharacterCount(const std::string_view s) {
145   // The utf32_length_from_utf8 function calls count_utf8.
146   // The count_utf8 function counts the number of code points
147   // (characters) in the string, assuming that the string is valid Unicode.
148   // TODO(@anonrig): Test to make sure CharacterCount returns correctly.
149   return simdutf::utf32_length_from_utf8(s.data(), s.length());
150 }
151 
152 }  // namespace StringUtil
153 }  // namespace protocol
154 }  // namespace inspector
155 }  // namespace node
156 
157