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 #include "src/inspector/string-util.h"
6
7 #include "src/base/platform/platform.h"
8 #include "src/conversions.h"
9 #include "src/inspector/protocol/Protocol.h"
10 #include "src/unicode-cache.h"
11
12 namespace v8_inspector {
13
toV8String(v8::Isolate * isolate,const String16 & string)14 v8::Local<v8::String> toV8String(v8::Isolate* isolate, const String16& string) {
15 if (string.isEmpty()) return v8::String::Empty(isolate);
16 DCHECK_GT(v8::String::kMaxLength, string.length());
17 return v8::String::NewFromTwoByte(
18 isolate, reinterpret_cast<const uint16_t*>(string.characters16()),
19 v8::NewStringType::kNormal, static_cast<int>(string.length()))
20 .ToLocalChecked();
21 }
22
toV8StringInternalized(v8::Isolate * isolate,const String16 & string)23 v8::Local<v8::String> toV8StringInternalized(v8::Isolate* isolate,
24 const String16& string) {
25 if (string.isEmpty()) return v8::String::Empty(isolate);
26 DCHECK_GT(v8::String::kMaxLength, string.length());
27 return v8::String::NewFromTwoByte(
28 isolate, reinterpret_cast<const uint16_t*>(string.characters16()),
29 v8::NewStringType::kInternalized,
30 static_cast<int>(string.length()))
31 .ToLocalChecked();
32 }
33
toV8StringInternalized(v8::Isolate * isolate,const char * str)34 v8::Local<v8::String> toV8StringInternalized(v8::Isolate* isolate,
35 const char* str) {
36 return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kInternalized)
37 .ToLocalChecked();
38 }
39
toV8String(v8::Isolate * isolate,const StringView & string)40 v8::Local<v8::String> toV8String(v8::Isolate* isolate,
41 const StringView& string) {
42 if (!string.length()) return v8::String::Empty(isolate);
43 DCHECK_GT(v8::String::kMaxLength, string.length());
44 if (string.is8Bit())
45 return v8::String::NewFromOneByte(
46 isolate, reinterpret_cast<const uint8_t*>(string.characters8()),
47 v8::NewStringType::kNormal, static_cast<int>(string.length()))
48 .ToLocalChecked();
49 return v8::String::NewFromTwoByte(
50 isolate, reinterpret_cast<const uint16_t*>(string.characters16()),
51 v8::NewStringType::kNormal, static_cast<int>(string.length()))
52 .ToLocalChecked();
53 }
54
toProtocolString(v8::Isolate * isolate,v8::Local<v8::String> value)55 String16 toProtocolString(v8::Isolate* isolate, v8::Local<v8::String> value) {
56 if (value.IsEmpty() || value->IsNullOrUndefined()) return String16();
57 std::unique_ptr<UChar[]> buffer(new UChar[value->Length()]);
58 value->Write(isolate, reinterpret_cast<uint16_t*>(buffer.get()), 0,
59 value->Length());
60 return String16(buffer.get(), value->Length());
61 }
62
toProtocolStringWithTypeCheck(v8::Isolate * isolate,v8::Local<v8::Value> value)63 String16 toProtocolStringWithTypeCheck(v8::Isolate* isolate,
64 v8::Local<v8::Value> value) {
65 if (value.IsEmpty() || !value->IsString()) return String16();
66 return toProtocolString(isolate, value.As<v8::String>());
67 }
68
toString16(const StringView & string)69 String16 toString16(const StringView& string) {
70 if (!string.length()) return String16();
71 if (string.is8Bit())
72 return String16(reinterpret_cast<const char*>(string.characters8()),
73 string.length());
74 return String16(reinterpret_cast<const UChar*>(string.characters16()),
75 string.length());
76 }
77
toStringView(const String16 & string)78 StringView toStringView(const String16& string) {
79 if (string.isEmpty()) return StringView();
80 return StringView(reinterpret_cast<const uint16_t*>(string.characters16()),
81 string.length());
82 }
83
stringViewStartsWith(const StringView & string,const char * prefix)84 bool stringViewStartsWith(const StringView& string, const char* prefix) {
85 if (!string.length()) return !(*prefix);
86 if (string.is8Bit()) {
87 for (size_t i = 0, j = 0; prefix[j] && i < string.length(); ++i, ++j) {
88 if (string.characters8()[i] != prefix[j]) return false;
89 }
90 } else {
91 for (size_t i = 0, j = 0; prefix[j] && i < string.length(); ++i, ++j) {
92 if (string.characters16()[i] != prefix[j]) return false;
93 }
94 }
95 return true;
96 }
97
98 namespace protocol {
99
100 // static
toDouble(const char * s,size_t len,bool * isOk)101 double StringUtil::toDouble(const char* s, size_t len, bool* isOk) {
102 v8::internal::UnicodeCache unicode_cache;
103 int flags = v8::internal::ALLOW_HEX | v8::internal::ALLOW_OCTAL |
104 v8::internal::ALLOW_BINARY;
105 double result = StringToDouble(&unicode_cache, s, flags);
106 *isOk = !std::isnan(result);
107 return result;
108 }
109
parseJSON(const StringView & string)110 std::unique_ptr<protocol::Value> StringUtil::parseJSON(
111 const StringView& string) {
112 if (!string.length()) return nullptr;
113 if (string.is8Bit()) {
114 return parseJSONCharacters(string.characters8(),
115 static_cast<int>(string.length()));
116 }
117 return parseJSONCharacters(string.characters16(),
118 static_cast<int>(string.length()));
119 }
120
parseJSON(const String16 & string)121 std::unique_ptr<protocol::Value> StringUtil::parseJSON(const String16& string) {
122 if (!string.length()) return nullptr;
123 return parseJSONCharacters(string.characters16(),
124 static_cast<int>(string.length()));
125 }
126
127 // static
builderAppendQuotedString(StringBuilder & builder,const String & str)128 void StringUtil::builderAppendQuotedString(StringBuilder& builder,
129 const String& str) {
130 builder.append('"');
131 if (!str.isEmpty()) {
132 escapeWideStringForJSON(
133 reinterpret_cast<const uint16_t*>(str.characters16()),
134 static_cast<int>(str.length()), &builder);
135 }
136 builder.append('"');
137 }
138
139 } // namespace protocol
140
141 // static
create(const StringView & string)142 std::unique_ptr<StringBuffer> StringBuffer::create(const StringView& string) {
143 String16 owner = toString16(string);
144 return StringBufferImpl::adopt(owner);
145 }
146
147 // static
adopt(String16 & string)148 std::unique_ptr<StringBufferImpl> StringBufferImpl::adopt(String16& string) {
149 return std::unique_ptr<StringBufferImpl>(new StringBufferImpl(string));
150 }
151
StringBufferImpl(String16 & string)152 StringBufferImpl::StringBufferImpl(String16& string) {
153 m_owner.swap(string);
154 m_string = toStringView(m_owner);
155 }
156
debuggerIdToString(const std::pair<int64_t,int64_t> & debuggerId)157 String16 debuggerIdToString(const std::pair<int64_t, int64_t>& debuggerId) {
158 const size_t kBufferSize = 35;
159
160 char buffer[kBufferSize];
161 v8::base::OS::SNPrintF(buffer, kBufferSize, "(%08" PRIX64 "%08" PRIX64 ")",
162 debuggerId.first, debuggerId.second);
163 return String16(buffer);
164 }
165
stackTraceIdToString(uintptr_t id)166 String16 stackTraceIdToString(uintptr_t id) {
167 String16Builder builder;
168 builder.appendNumber(static_cast<size_t>(id));
169 return builder.toString();
170 }
171
172 } // namespace v8_inspector
173