OLD | NEW |
| (Empty) |
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/StringUtil.h" | |
6 | |
7 #include "src/inspector/protocol/Protocol.h" | |
8 | |
9 namespace v8_inspector { | |
10 | |
11 v8::Local<v8::String> toV8String(v8::Isolate* isolate, const String16& string) { | |
12 if (string.isEmpty()) return v8::String::Empty(isolate); | |
13 return v8::String::NewFromTwoByte( | |
14 isolate, reinterpret_cast<const uint16_t*>(string.characters16()), | |
15 v8::NewStringType::kNormal, string.length()) | |
16 .ToLocalChecked(); | |
17 } | |
18 | |
19 v8::Local<v8::String> toV8StringInternalized(v8::Isolate* isolate, | |
20 const String16& string) { | |
21 if (string.isEmpty()) return v8::String::Empty(isolate); | |
22 return v8::String::NewFromTwoByte( | |
23 isolate, reinterpret_cast<const uint16_t*>(string.characters16()), | |
24 v8::NewStringType::kInternalized, string.length()) | |
25 .ToLocalChecked(); | |
26 } | |
27 | |
28 v8::Local<v8::String> toV8StringInternalized(v8::Isolate* isolate, | |
29 const char* str) { | |
30 return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kInternalized) | |
31 .ToLocalChecked(); | |
32 } | |
33 | |
34 v8::Local<v8::String> toV8String(v8::Isolate* isolate, | |
35 const StringView& string) { | |
36 if (!string.length()) return v8::String::Empty(isolate); | |
37 if (string.is8Bit()) | |
38 return v8::String::NewFromOneByte( | |
39 isolate, reinterpret_cast<const uint8_t*>(string.characters8()), | |
40 v8::NewStringType::kNormal, string.length()) | |
41 .ToLocalChecked(); | |
42 return v8::String::NewFromTwoByte( | |
43 isolate, reinterpret_cast<const uint16_t*>(string.characters16()), | |
44 v8::NewStringType::kNormal, string.length()) | |
45 .ToLocalChecked(); | |
46 } | |
47 | |
48 String16 toProtocolString(v8::Local<v8::String> value) { | |
49 if (value.IsEmpty() || value->IsNull() || value->IsUndefined()) | |
50 return String16(); | |
51 std::unique_ptr<UChar[]> buffer(new UChar[value->Length()]); | |
52 value->Write(reinterpret_cast<uint16_t*>(buffer.get()), 0, value->Length()); | |
53 return String16(buffer.get(), value->Length()); | |
54 } | |
55 | |
56 String16 toProtocolStringWithTypeCheck(v8::Local<v8::Value> value) { | |
57 if (value.IsEmpty() || !value->IsString()) return String16(); | |
58 return toProtocolString(value.As<v8::String>()); | |
59 } | |
60 | |
61 String16 toString16(const StringView& string) { | |
62 if (!string.length()) return String16(); | |
63 if (string.is8Bit()) | |
64 return String16(reinterpret_cast<const char*>(string.characters8()), | |
65 string.length()); | |
66 return String16(reinterpret_cast<const UChar*>(string.characters16()), | |
67 string.length()); | |
68 } | |
69 | |
70 StringView toStringView(const String16& string) { | |
71 if (string.isEmpty()) return StringView(); | |
72 return StringView(reinterpret_cast<const uint16_t*>(string.characters16()), | |
73 string.length()); | |
74 } | |
75 | |
76 bool stringViewStartsWith(const StringView& string, const char* prefix) { | |
77 if (!string.length()) return !(*prefix); | |
78 if (string.is8Bit()) { | |
79 for (size_t i = 0, j = 0; prefix[j] && i < string.length(); ++i, ++j) { | |
80 if (string.characters8()[i] != prefix[j]) return false; | |
81 } | |
82 } else { | |
83 for (size_t i = 0, j = 0; prefix[j] && i < string.length(); ++i, ++j) { | |
84 if (string.characters16()[i] != prefix[j]) return false; | |
85 } | |
86 } | |
87 return true; | |
88 } | |
89 | |
90 namespace protocol { | |
91 | |
92 std::unique_ptr<protocol::Value> parseJSON(const StringView& string) { | |
93 if (!string.length()) return nullptr; | |
94 if (string.is8Bit()) | |
95 return protocol::parseJSON(string.characters8(), string.length()); | |
96 return protocol::parseJSON(string.characters16(), string.length()); | |
97 } | |
98 | |
99 std::unique_ptr<protocol::Value> parseJSON(const String16& string) { | |
100 if (!string.length()) return nullptr; | |
101 return protocol::parseJSON(string.characters16(), string.length()); | |
102 } | |
103 | |
104 } // namespace protocol | |
105 | |
106 std::unique_ptr<protocol::Value> toProtocolValue(v8::Local<v8::Context> context, | |
107 v8::Local<v8::Value> value, | |
108 int maxDepth) { | |
109 if (value.IsEmpty()) { | |
110 UNREACHABLE(); | |
111 return nullptr; | |
112 } | |
113 | |
114 if (!maxDepth) return nullptr; | |
115 maxDepth--; | |
116 | |
117 if (value->IsNull() || value->IsUndefined()) return protocol::Value::null(); | |
118 if (value->IsBoolean()) | |
119 return protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value()); | |
120 if (value->IsNumber()) { | |
121 double doubleValue = value.As<v8::Number>()->Value(); | |
122 int intValue = static_cast<int>(doubleValue); | |
123 if (intValue == doubleValue) | |
124 return protocol::FundamentalValue::create(intValue); | |
125 return protocol::FundamentalValue::create(doubleValue); | |
126 } | |
127 if (value->IsString()) | |
128 return protocol::StringValue::create( | |
129 toProtocolString(value.As<v8::String>())); | |
130 if (value->IsArray()) { | |
131 v8::Local<v8::Array> array = value.As<v8::Array>(); | |
132 std::unique_ptr<protocol::ListValue> inspectorArray = | |
133 protocol::ListValue::create(); | |
134 uint32_t length = array->Length(); | |
135 for (uint32_t i = 0; i < length; i++) { | |
136 v8::Local<v8::Value> value; | |
137 if (!array->Get(context, i).ToLocal(&value)) return nullptr; | |
138 std::unique_ptr<protocol::Value> element = | |
139 toProtocolValue(context, value, maxDepth); | |
140 if (!element) return nullptr; | |
141 inspectorArray->pushValue(std::move(element)); | |
142 } | |
143 return std::move(inspectorArray); | |
144 } | |
145 if (value->IsObject()) { | |
146 std::unique_ptr<protocol::DictionaryValue> jsonObject = | |
147 protocol::DictionaryValue::create(); | |
148 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value); | |
149 v8::Local<v8::Array> propertyNames; | |
150 if (!object->GetPropertyNames(context).ToLocal(&propertyNames)) | |
151 return nullptr; | |
152 uint32_t length = propertyNames->Length(); | |
153 for (uint32_t i = 0; i < length; i++) { | |
154 v8::Local<v8::Value> name; | |
155 if (!propertyNames->Get(context, i).ToLocal(&name)) return nullptr; | |
156 // FIXME(yurys): v8::Object should support GetOwnPropertyNames | |
157 if (name->IsString()) { | |
158 v8::Maybe<bool> hasRealNamedProperty = object->HasRealNamedProperty( | |
159 context, v8::Local<v8::String>::Cast(name)); | |
160 if (!hasRealNamedProperty.IsJust() || !hasRealNamedProperty.FromJust()) | |
161 continue; | |
162 } | |
163 v8::Local<v8::String> propertyName; | |
164 if (!name->ToString(context).ToLocal(&propertyName)) continue; | |
165 v8::Local<v8::Value> property; | |
166 if (!object->Get(context, name).ToLocal(&property)) return nullptr; | |
167 std::unique_ptr<protocol::Value> propertyValue = | |
168 toProtocolValue(context, property, maxDepth); | |
169 if (!propertyValue) return nullptr; | |
170 jsonObject->setValue(toProtocolString(propertyName), | |
171 std::move(propertyValue)); | |
172 } | |
173 return std::move(jsonObject); | |
174 } | |
175 UNREACHABLE(); | |
176 return nullptr; | |
177 } | |
178 | |
179 // static | |
180 std::unique_ptr<StringBuffer> StringBuffer::create(const StringView& string) { | |
181 String16 owner = toString16(string); | |
182 return StringBufferImpl::adopt(owner); | |
183 } | |
184 | |
185 // static | |
186 std::unique_ptr<StringBufferImpl> StringBufferImpl::adopt(String16& string) { | |
187 return wrapUnique(new StringBufferImpl(string)); | |
188 } | |
189 | |
190 StringBufferImpl::StringBufferImpl(String16& string) { | |
191 m_owner.swap(string); | |
192 m_string = toStringView(m_owner); | |
193 } | |
194 | |
195 } // namespace v8_inspector | |
OLD | NEW |