| 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 |