OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "bindings/core/v8/JSONValuesForV8.h" | 5 #include "bindings/core/v8/JSONValuesForV8.h" |
6 | 6 |
7 #include "bindings/core/v8/ExceptionState.h" | 7 #include "bindings/core/v8/ExceptionState.h" |
8 #include "bindings/core/v8/ScriptState.h" | 8 #include "bindings/core/v8/ScriptState.h" |
9 #include "bindings/core/v8/V8Binding.h" | 9 #include "bindings/core/v8/V8Binding.h" |
10 | 10 |
11 namespace blink { | 11 namespace blink { |
12 | 12 |
13 static String coreString(v8::Local<v8::String> v8String) { | |
14 int length = v8String->Length(); | |
15 UChar* buffer; | |
16 String result = String::createUninitialized(length, buffer); | |
17 v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length); | |
18 return result; | |
19 } | |
20 | |
21 std::unique_ptr<JSONValue> toJSONValue(v8::Local<v8::Context> context, | |
22 v8::Local<v8::Value> value, | |
23 int maxDepth) { | |
24 if (value.IsEmpty()) { | |
25 ASSERT_NOT_REACHED(); | |
26 return nullptr; | |
27 } | |
28 | |
29 if (!maxDepth) | |
30 return nullptr; | |
31 maxDepth--; | |
32 | |
33 if (value->IsNull() || value->IsUndefined()) | |
34 return JSONValue::null(); | |
35 if (value->IsBoolean()) | |
36 return JSONBasicValue::create(value.As<v8::Boolean>()->Value()); | |
37 if (value->IsNumber()) | |
38 return JSONBasicValue::create(value.As<v8::Number>()->Value()); | |
39 if (value->IsString()) | |
40 return JSONString::create(coreString(value.As<v8::String>())); | |
41 if (value->IsArray()) { | |
42 v8::Local<v8::Array> array = value.As<v8::Array>(); | |
43 std::unique_ptr<JSONArray> inspectorArray = JSONArray::create(); | |
44 uint32_t length = array->Length(); | |
45 for (uint32_t i = 0; i < length; i++) { | |
46 v8::Local<v8::Value> value; | |
47 if (!array->Get(context, i).ToLocal(&value)) | |
48 return nullptr; | |
49 std::unique_ptr<JSONValue> element = | |
50 toJSONValue(context, value, maxDepth); | |
51 if (!element) | |
52 return nullptr; | |
53 inspectorArray->pushValue(std::move(element)); | |
54 } | |
55 return std::move(inspectorArray); | |
56 } | |
57 if (value->IsObject()) { | |
58 std::unique_ptr<JSONObject> jsonObject = JSONObject::create(); | |
59 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value); | |
60 v8::Local<v8::Array> propertyNames; | |
61 if (!object->GetPropertyNames(context).ToLocal(&propertyNames)) | |
62 return nullptr; | |
63 uint32_t length = propertyNames->Length(); | |
64 for (uint32_t i = 0; i < length; i++) { | |
65 v8::Local<v8::Value> name; | |
66 if (!propertyNames->Get(context, i).ToLocal(&name)) | |
67 return nullptr; | |
68 // FIXME(yurys): v8::Object should support GetOwnPropertyNames | |
69 if (name->IsString()) { | |
70 v8::Maybe<bool> hasRealNamedProperty = object->HasRealNamedProperty( | |
71 context, v8::Local<v8::String>::Cast(name)); | |
72 if (!hasRealNamedProperty.IsJust() || !hasRealNamedProperty.FromJust()) | |
73 continue; | |
74 } | |
75 v8::Local<v8::String> propertyName; | |
76 if (!name->ToString(context).ToLocal(&propertyName)) | |
77 continue; | |
78 v8::Local<v8::Value> property; | |
79 if (!object->Get(context, name).ToLocal(&property)) | |
80 return nullptr; | |
81 std::unique_ptr<JSONValue> propertyValue = | |
82 toJSONValue(context, property, maxDepth); | |
83 if (!propertyValue) | |
84 return nullptr; | |
85 jsonObject->setValue(coreString(propertyName), std::move(propertyValue)); | |
86 } | |
87 return std::move(jsonObject); | |
88 } | |
89 ASSERT_NOT_REACHED(); | |
90 return nullptr; | |
91 } | |
92 | |
93 v8::Local<v8::Value> fromJSONString(ScriptState* scriptState, | 13 v8::Local<v8::Value> fromJSONString(ScriptState* scriptState, |
94 const String& stringifiedJSON, | 14 const String& stringifiedJSON, |
95 ExceptionState& exceptionState) { | 15 ExceptionState& exceptionState) { |
96 v8::Isolate* isolate = scriptState->isolate(); | 16 v8::Isolate* isolate = scriptState->isolate(); |
97 v8::Local<v8::Value> parsed; | 17 v8::Local<v8::Value> parsed; |
98 v8::TryCatch tryCatch(isolate); | 18 v8::TryCatch tryCatch(isolate); |
99 if (!v8Call(v8::JSON::Parse(isolate, v8String(isolate, stringifiedJSON)), | 19 if (!v8Call(v8::JSON::Parse(isolate, v8String(isolate, stringifiedJSON)), |
100 parsed, tryCatch)) { | 20 parsed, tryCatch)) { |
101 if (tryCatch.HasCaught()) | 21 if (tryCatch.HasCaught()) |
102 exceptionState.rethrowV8Exception(tryCatch.Exception()); | 22 exceptionState.rethrowV8Exception(tryCatch.Exception()); |
103 } | 23 } |
104 | 24 |
105 return parsed; | 25 return parsed; |
106 } | 26 } |
107 | 27 |
108 } // namespace blink | 28 } // namespace blink |
OLD | NEW |