OLD | NEW |
1 // Copyright (c) 2012 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/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/float_util.h" | 11 #include "base/float_util.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
14 #include "base/values.h" | 14 #include "base/values.h" |
15 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" | 15 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" |
16 #include "third_party/WebKit/public/web/WebArrayBufferConverter.h" | 16 #include "third_party/WebKit/public/web/WebArrayBufferConverter.h" |
17 #include "third_party/WebKit/public/web/WebArrayBufferView.h" | 17 #include "third_party/WebKit/public/web/WebArrayBufferView.h" |
18 #include "v8/include/v8.h" | 18 #include "v8/include/v8.h" |
19 | 19 |
20 namespace content { | 20 namespace content { |
21 | 21 |
| 22 // Default implementation of V8ValueConverter::Strategy |
| 23 |
| 24 bool V8ValueConverter::Strategy::FromV8Object( |
| 25 v8::Handle<v8::Object> value, |
| 26 base::Value** out, |
| 27 v8::Isolate* isolate, |
| 28 const FromV8ValueCallback& callback) const { |
| 29 return false; |
| 30 } |
| 31 |
| 32 bool V8ValueConverter::Strategy::FromV8Array( |
| 33 v8::Handle<v8::Array> value, |
| 34 base::Value** out, |
| 35 v8::Isolate* isolate, |
| 36 const FromV8ValueCallback& callback) const { |
| 37 return false; |
| 38 } |
| 39 |
| 40 bool V8ValueConverter::Strategy::FromV8ArrayBuffer(v8::Handle<v8::Object> value, |
| 41 base::Value** out) const { |
| 42 return false; |
| 43 } |
| 44 |
| 45 bool V8ValueConverter::Strategy::FromV8Number(v8::Handle<v8::Number> value, |
| 46 base::Value** out) const { |
| 47 return false; |
| 48 } |
| 49 |
| 50 bool V8ValueConverter::Strategy::FromV8Undefined(base::Value** out) const { |
| 51 return false; |
| 52 } |
| 53 |
| 54 |
22 namespace { | 55 namespace { |
23 | 56 |
24 // For the sake of the storage API, make this quite large. | 57 // For the sake of the storage API, make this quite large. |
25 const int kMaxRecursionDepth = 100; | 58 const int kMaxRecursionDepth = 100; |
26 | 59 |
27 } // namespace | 60 } // namespace |
28 | 61 |
29 // The state of a call to FromV8Value. | 62 // The state of a call to FromV8Value. |
30 class V8ValueConverterImpl::FromV8ValueState { | 63 class V8ValueConverterImpl::FromV8ValueState { |
31 public: | 64 public: |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 FromV8ValueState::Level state_level(state); | 276 FromV8ValueState::Level state_level(state); |
244 if (state->HasReachedMaxRecursionDepth()) | 277 if (state->HasReachedMaxRecursionDepth()) |
245 return NULL; | 278 return NULL; |
246 | 279 |
247 if (val->IsNull()) | 280 if (val->IsNull()) |
248 return base::Value::CreateNullValue(); | 281 return base::Value::CreateNullValue(); |
249 | 282 |
250 if (val->IsBoolean()) | 283 if (val->IsBoolean()) |
251 return new base::FundamentalValue(val->ToBoolean()->Value()); | 284 return new base::FundamentalValue(val->ToBoolean()->Value()); |
252 | 285 |
| 286 if (val->IsNumber() && strategy_) { |
| 287 base::Value* out = NULL; |
| 288 if (strategy_->FromV8Number(val->ToNumber(), &out)) |
| 289 return out; |
| 290 } |
| 291 |
253 if (val->IsInt32()) | 292 if (val->IsInt32()) |
254 return new base::FundamentalValue(val->ToInt32()->Value()); | 293 return new base::FundamentalValue(val->ToInt32()->Value()); |
255 | 294 |
256 if (val->IsNumber()) { | 295 if (val->IsNumber()) { |
257 double val_as_double = val->ToNumber()->Value(); | 296 double val_as_double = val->ToNumber()->Value(); |
258 if (!base::IsFinite(val_as_double)) | 297 if (!base::IsFinite(val_as_double)) |
259 return NULL; | 298 return NULL; |
260 return new base::FundamentalValue(val_as_double); | 299 return new base::FundamentalValue(val_as_double); |
261 } | 300 } |
262 | 301 |
263 if (val->IsString()) { | 302 if (val->IsString()) { |
264 v8::String::Utf8Value utf8(val->ToString()); | 303 v8::String::Utf8Value utf8(val->ToString()); |
265 return new base::StringValue(std::string(*utf8, utf8.length())); | 304 return new base::StringValue(std::string(*utf8, utf8.length())); |
266 } | 305 } |
267 | 306 |
268 if (val->IsUndefined()) | 307 if (val->IsUndefined()) { |
| 308 if (strategy_) { |
| 309 base::Value* out = NULL; |
| 310 if (strategy_->FromV8Undefined(&out)) |
| 311 return out; |
| 312 } |
269 // JSON.stringify ignores undefined. | 313 // JSON.stringify ignores undefined. |
270 return NULL; | 314 return NULL; |
| 315 } |
271 | 316 |
272 if (val->IsDate()) { | 317 if (val->IsDate()) { |
273 if (!date_allowed_) | 318 if (!date_allowed_) |
274 // JSON.stringify would convert this to a string, but an object is more | 319 // JSON.stringify would convert this to a string, but an object is more |
275 // consistent within this class. | 320 // consistent within this class. |
276 return FromV8Object(val->ToObject(), state, isolate); | 321 return FromV8Object(val->ToObject(), state, isolate); |
277 v8::Date* date = v8::Date::Cast(*val); | 322 v8::Date* date = v8::Date::Cast(*val); |
278 return new base::FundamentalValue(date->ValueOf() / 1000.0); | 323 return new base::FundamentalValue(date->ValueOf() / 1000.0); |
279 } | 324 } |
280 | 325 |
281 if (val->IsRegExp()) { | 326 if (val->IsRegExp()) { |
282 if (!reg_exp_allowed_) | 327 if (!reg_exp_allowed_) |
283 // JSON.stringify converts to an object. | 328 // JSON.stringify converts to an object. |
284 return FromV8Object(val->ToObject(), state, isolate); | 329 return FromV8Object(val->ToObject(), state, isolate); |
285 return new base::StringValue(*v8::String::Utf8Value(val->ToString())); | 330 return new base::StringValue(*v8::String::Utf8Value(val->ToString())); |
286 } | 331 } |
287 | 332 |
288 // v8::Value doesn't have a ToArray() method for some reason. | 333 // v8::Value doesn't have a ToArray() method for some reason. |
289 if (val->IsArray()) | 334 if (val->IsArray()) |
290 return FromV8Array(val.As<v8::Array>(), state, isolate); | 335 return FromV8Array(val.As<v8::Array>(), state, isolate); |
291 | 336 |
292 if (val->IsFunction()) { | 337 if (val->IsFunction()) { |
293 if (!function_allowed_) | 338 if (!function_allowed_) |
294 // JSON.stringify refuses to convert function(){}. | 339 // JSON.stringify refuses to convert function(){}. |
295 return NULL; | 340 return NULL; |
296 return FromV8Object(val->ToObject(), state, isolate); | 341 return FromV8Object(val->ToObject(), state, isolate); |
297 } | 342 } |
298 | 343 |
299 if (val->IsObject()) { | 344 if (val->IsArrayBuffer() || val->IsArrayBufferView()) |
300 base::BinaryValue* binary_value = FromV8Buffer(val); | 345 return FromV8ArrayBuffer(val->ToObject()); |
301 if (binary_value) { | 346 |
302 return binary_value; | 347 if (val->IsObject()) |
303 } else { | 348 return FromV8Object(val->ToObject(), state, isolate); |
304 return FromV8Object(val->ToObject(), state, isolate); | |
305 } | |
306 } | |
307 | 349 |
308 LOG(ERROR) << "Unexpected v8 value type encountered."; | 350 LOG(ERROR) << "Unexpected v8 value type encountered."; |
309 return NULL; | 351 return NULL; |
310 } | 352 } |
311 | 353 |
312 base::Value* V8ValueConverterImpl::FromV8Array( | 354 base::Value* V8ValueConverterImpl::FromV8Array( |
313 v8::Handle<v8::Array> val, | 355 v8::Handle<v8::Array> val, |
314 FromV8ValueState* state, | 356 FromV8ValueState* state, |
315 v8::Isolate* isolate) const { | 357 v8::Isolate* isolate) const { |
316 if (!state->UpdateAndCheckUniqueness(val)) | 358 if (!state->UpdateAndCheckUniqueness(val)) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 if (child) | 397 if (child) |
356 result->Append(child); | 398 result->Append(child); |
357 else | 399 else |
358 // JSON.stringify puts null in places where values don't serialize, for | 400 // JSON.stringify puts null in places where values don't serialize, for |
359 // example undefined and functions. Emulate that behavior. | 401 // example undefined and functions. Emulate that behavior. |
360 result->Append(base::Value::CreateNullValue()); | 402 result->Append(base::Value::CreateNullValue()); |
361 } | 403 } |
362 return result; | 404 return result; |
363 } | 405 } |
364 | 406 |
365 base::BinaryValue* V8ValueConverterImpl::FromV8Buffer( | 407 base::Value* V8ValueConverterImpl::FromV8ArrayBuffer( |
366 v8::Handle<v8::Value> val) const { | 408 v8::Handle<v8::Object> val) const { |
| 409 if (strategy_) { |
| 410 base::Value* out = NULL; |
| 411 if (strategy_->FromV8ArrayBuffer(val, &out)) |
| 412 return out; |
| 413 } |
| 414 |
367 char* data = NULL; | 415 char* data = NULL; |
368 size_t length = 0; | 416 size_t length = 0; |
369 | 417 |
370 scoped_ptr<blink::WebArrayBuffer> array_buffer( | 418 scoped_ptr<blink::WebArrayBuffer> array_buffer( |
371 blink::WebArrayBufferConverter::createFromV8Value(val)); | 419 blink::WebArrayBufferConverter::createFromV8Value(val)); |
372 scoped_ptr<blink::WebArrayBufferView> view; | 420 scoped_ptr<blink::WebArrayBufferView> view; |
373 if (array_buffer) { | 421 if (array_buffer) { |
374 data = reinterpret_cast<char*>(array_buffer->data()); | 422 data = reinterpret_cast<char*>(array_buffer->data()); |
375 length = array_buffer->byteLength(); | 423 length = array_buffer->byteLength(); |
376 } else { | 424 } else { |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 continue; | 532 continue; |
485 | 533 |
486 result->SetWithoutPathExpansion(std::string(*name_utf8, name_utf8.length()), | 534 result->SetWithoutPathExpansion(std::string(*name_utf8, name_utf8.length()), |
487 child.release()); | 535 child.release()); |
488 } | 536 } |
489 | 537 |
490 return result.release(); | 538 return result.release(); |
491 } | 539 } |
492 | 540 |
493 } // namespace content | 541 } // namespace content |
OLD | NEW |