Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/renderer/v8_value_converter_impl.h" | 5 #include "content/renderer/v8_value_converter_impl.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/values.h" | 11 #include "base/values.h" |
| 12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebArrayBuffer.h" | |
| 13 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebArrayBuff erView.h" | |
| 12 #include "v8/include/v8.h" | 14 #include "v8/include/v8.h" |
| 13 | 15 |
| 16 using base::BinaryValue; | |
| 17 using base::DictionaryValue; | |
| 18 using base::ListValue; | |
| 19 using base::StringValue; | |
| 20 using base::Value; | |
| 21 | |
| 22 | |
| 14 namespace content { | 23 namespace content { |
| 15 | 24 |
| 16 V8ValueConverter* V8ValueConverter::create() { | 25 V8ValueConverter* V8ValueConverter::create() { |
| 17 return new V8ValueConverterImpl(); | 26 return new V8ValueConverterImpl(); |
| 18 } | 27 } |
| 19 | 28 |
| 20 } | 29 } |
| 21 | 30 |
| 22 V8ValueConverterImpl::V8ValueConverterImpl() | 31 V8ValueConverterImpl::V8ValueConverterImpl() |
| 23 : allow_undefined_(false), | 32 : allow_undefined_(false), |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 70 CHECK(value->GetAsString(&val)); | 79 CHECK(value->GetAsString(&val)); |
| 71 return v8::String::New(val.c_str(), val.length()); | 80 return v8::String::New(val.c_str(), val.length()); |
| 72 } | 81 } |
| 73 | 82 |
| 74 case Value::TYPE_LIST: | 83 case Value::TYPE_LIST: |
| 75 return ToV8Array(static_cast<const ListValue*>(value)); | 84 return ToV8Array(static_cast<const ListValue*>(value)); |
| 76 | 85 |
| 77 case Value::TYPE_DICTIONARY: | 86 case Value::TYPE_DICTIONARY: |
| 78 return ToV8Object(static_cast<const DictionaryValue*>(value)); | 87 return ToV8Object(static_cast<const DictionaryValue*>(value)); |
| 79 | 88 |
| 89 case Value::TYPE_BINARY: | |
| 90 return ToArrayBuffer(static_cast<const BinaryValue*>(value)); | |
| 91 | |
| 80 default: | 92 default: |
| 81 LOG(ERROR) << "Unexpected value type: " << value->GetType(); | 93 LOG(ERROR) << "Unexpected value type: " << value->GetType(); |
| 82 return v8::Null(); | 94 return v8::Null(); |
| 83 } | 95 } |
| 84 } | 96 } |
| 85 | 97 |
| 86 v8::Handle<v8::Value> V8ValueConverterImpl::ToV8Array( | 98 v8::Handle<v8::Value> V8ValueConverterImpl::ToV8Array( |
| 87 const ListValue* val) const { | 99 const ListValue* val) const { |
| 88 v8::Handle<v8::Array> result(v8::Array::New(val->GetSize())); | 100 v8::Handle<v8::Array> result(v8::Array::New(val->GetSize())); |
| 89 | 101 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 120 result->Set(v8::String::New(key.c_str(), key.length()), child_v8); | 132 result->Set(v8::String::New(key.c_str(), key.length()), child_v8); |
| 121 if (try_catch.HasCaught()) { | 133 if (try_catch.HasCaught()) { |
| 122 LOG(ERROR) << "Setter for property " << key.c_str() << " threw an " | 134 LOG(ERROR) << "Setter for property " << key.c_str() << " threw an " |
| 123 << "exception."; | 135 << "exception."; |
| 124 } | 136 } |
| 125 } | 137 } |
| 126 | 138 |
| 127 return result; | 139 return result; |
| 128 } | 140 } |
| 129 | 141 |
| 142 v8::Handle<v8::Value> V8ValueConverterImpl::ToArrayBuffer( | |
| 143 const BinaryValue* value) const { | |
| 144 WebKit::WebArrayBuffer buffer = | |
| 145 WebKit::WebArrayBuffer::create(value->GetSize(), 1); | |
|
Matt Perry
2012/05/04 19:22:21
indent += 2
asargent_no_longer_on_chrome
2012/05/04 22:42:22
Done.
| |
| 146 memcpy(buffer.data(), value->GetBuffer(), value->GetSize()); | |
|
asargent_no_longer_on_chrome
2012/05/04 18:10:08
Note that I'm looking into ways to avoid the need
Matt Perry
2012/05/04 19:22:21
BinaryValues are serialized in ipc_message_utils.c
asargent_no_longer_on_chrome
2012/05/04 22:42:22
Yep, but I'd also probably have to do something ab
| |
| 147 return buffer.toV8Value(); | |
| 148 } | |
| 149 | |
| 130 Value* V8ValueConverterImpl::FromV8ValueImpl(v8::Handle<v8::Value> val) const { | 150 Value* V8ValueConverterImpl::FromV8ValueImpl(v8::Handle<v8::Value> val) const { |
| 131 CHECK(!val.IsEmpty()); | 151 CHECK(!val.IsEmpty()); |
| 132 | 152 |
| 133 if (val->IsNull()) | 153 if (val->IsNull()) |
| 134 return Value::CreateNullValue(); | 154 return Value::CreateNullValue(); |
| 135 | 155 |
| 136 if (val->IsBoolean()) | 156 if (val->IsBoolean()) |
| 137 return Value::CreateBooleanValue(val->ToBoolean()->Value()); | 157 return Value::CreateBooleanValue(val->ToBoolean()->Value()); |
| 138 | 158 |
| 139 if (val->IsInt32()) | 159 if (val->IsInt32()) |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 157 | 177 |
| 158 if (allow_regexp_ && val->IsRegExp()) { | 178 if (allow_regexp_ && val->IsRegExp()) { |
| 159 return Value::CreateStringValue( | 179 return Value::CreateStringValue( |
| 160 *v8::String::Utf8Value(val->ToString())); | 180 *v8::String::Utf8Value(val->ToString())); |
| 161 } | 181 } |
| 162 | 182 |
| 163 // v8::Value doesn't have a ToArray() method for some reason. | 183 // v8::Value doesn't have a ToArray() method for some reason. |
| 164 if (val->IsArray()) | 184 if (val->IsArray()) |
| 165 return FromV8Array(val.As<v8::Array>()); | 185 return FromV8Array(val.As<v8::Array>()); |
| 166 | 186 |
| 167 if (val->IsObject()) | 187 if (val->IsObject()) { |
| 168 return FromV8Object(val->ToObject()); | 188 BinaryValue* binary_value = FromV8Buffer(val); |
| 169 | 189 if (binary_value) |
|
Matt Perry
2012/05/04 19:22:21
nit: use braces in compound if/else statements.
asargent_no_longer_on_chrome
2012/05/04 22:42:22
Done.
| |
| 190 return binary_value; | |
| 191 else | |
| 192 return FromV8Object(val->ToObject()); | |
| 193 } | |
| 170 LOG(ERROR) << "Unexpected v8 value type encountered."; | 194 LOG(ERROR) << "Unexpected v8 value type encountered."; |
| 171 return Value::CreateNullValue(); | 195 return Value::CreateNullValue(); |
| 172 } | 196 } |
| 173 | 197 |
| 174 ListValue* V8ValueConverterImpl::FromV8Array(v8::Handle<v8::Array> val) const { | 198 ListValue* V8ValueConverterImpl::FromV8Array(v8::Handle<v8::Array> val) const { |
| 175 ListValue* result = new ListValue(); | 199 ListValue* result = new ListValue(); |
| 176 for (uint32 i = 0; i < val->Length(); ++i) { | 200 for (uint32 i = 0; i < val->Length(); ++i) { |
| 177 v8::TryCatch try_catch; | 201 v8::TryCatch try_catch; |
| 178 v8::Handle<v8::Value> child_v8 = val->Get(i); | 202 v8::Handle<v8::Value> child_v8 = val->Get(i); |
| 179 if (try_catch.HasCaught()) { | 203 if (try_catch.HasCaught()) { |
| 180 LOG(ERROR) << "Getter for index " << i << " threw an exception."; | 204 LOG(ERROR) << "Getter for index " << i << " threw an exception."; |
| 181 child_v8 = v8::Null(); | 205 child_v8 = v8::Null(); |
| 182 } | 206 } |
| 183 | 207 |
| 184 // TODO(aa): It would be nice to support getters, but we need | 208 // TODO(aa): It would be nice to support getters, but we need |
| 185 // http://code.google.com/p/v8/issues/detail?id=1342 to do it properly. | 209 // http://code.google.com/p/v8/issues/detail?id=1342 to do it properly. |
| 186 if (!val->HasRealIndexedProperty(i)) | 210 if (!val->HasRealIndexedProperty(i)) |
| 187 continue; | 211 continue; |
| 188 | 212 |
| 189 Value* child = FromV8ValueImpl(child_v8); | 213 Value* child = FromV8ValueImpl(child_v8); |
| 190 CHECK(child); | 214 CHECK(child); |
| 191 | 215 |
| 192 result->Append(child); | 216 result->Append(child); |
| 193 } | 217 } |
| 194 return result; | 218 return result; |
| 195 } | 219 } |
| 196 | 220 |
| 221 base::BinaryValue* V8ValueConverterImpl::FromV8Buffer( | |
| 222 v8::Handle<v8::Value> val) const { | |
| 223 char* data = NULL; | |
| 224 size_t length = 0; | |
| 225 | |
| 226 WebKit::WebArrayBuffer* array_buffer = | |
| 227 WebKit::WebArrayBuffer::createFromV8Value(val); | |
| 228 if (array_buffer) { | |
| 229 data = reinterpret_cast<char*>(array_buffer->data()); | |
| 230 length = array_buffer->byteLength(); | |
| 231 } else { | |
| 232 WebKit::WebArrayBufferView* view = | |
| 233 WebKit::WebArrayBufferView::createFromV8Value(val); | |
| 234 if (view) { | |
| 235 data = reinterpret_cast<char*>(view->baseAddress()) + view->byteOffset(); | |
| 236 length = view->byteLength(); | |
| 237 } | |
| 238 } | |
| 239 | |
| 240 if (data) | |
| 241 return base::BinaryValue::CreateWithCopiedBuffer(data, length); | |
|
asargent_no_longer_on_chrome
2012/05/04 18:10:08
Similarly here, it would be nice to avoid needing
Matt Perry
2012/05/04 19:22:21
Hmm... maybe introduce a WeakBinaryValue that has
| |
| 242 else | |
| 243 return NULL; | |
| 244 } | |
| 245 | |
| 197 DictionaryValue* V8ValueConverterImpl::FromV8Object( | 246 DictionaryValue* V8ValueConverterImpl::FromV8Object( |
| 198 v8::Handle<v8::Object> val) const { | 247 v8::Handle<v8::Object> val) const { |
| 199 DictionaryValue* result = new DictionaryValue(); | 248 DictionaryValue* result = new DictionaryValue(); |
| 200 v8::Handle<v8::Array> property_names(val->GetPropertyNames()); | 249 v8::Handle<v8::Array> property_names(val->GetPropertyNames()); |
| 201 for (uint32 i = 0; i < property_names->Length(); ++i) { | 250 for (uint32 i = 0; i < property_names->Length(); ++i) { |
| 202 v8::Handle<v8::String> name(property_names->Get(i).As<v8::String>()); | 251 v8::Handle<v8::String> name(property_names->Get(i).As<v8::String>()); |
| 203 | 252 |
| 204 // TODO(aa): It would be nice to support getters, but we need | 253 // TODO(aa): It would be nice to support getters, but we need |
| 205 // http://code.google.com/p/v8/issues/detail?id=1342 to do it properly. | 254 // http://code.google.com/p/v8/issues/detail?id=1342 to do it properly. |
| 206 if (!val->HasRealNamedProperty(name)) | 255 if (!val->HasRealNamedProperty(name)) |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 217 } | 266 } |
| 218 | 267 |
| 219 Value* child = FromV8ValueImpl(child_v8); | 268 Value* child = FromV8ValueImpl(child_v8); |
| 220 CHECK(child); | 269 CHECK(child); |
| 221 | 270 |
| 222 result->SetWithoutPathExpansion(std::string(*name_utf8, name_utf8.length()), | 271 result->SetWithoutPathExpansion(std::string(*name_utf8, name_utf8.length()), |
| 223 child); | 272 child); |
| 224 } | 273 } |
| 225 return result; | 274 return result; |
| 226 } | 275 } |
| OLD | NEW |