OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "chrome/common/ipc_message_utils.h" | 5 #include "chrome/common/ipc_message_utils.h" |
6 | 6 |
7 #include "base/gfx/rect.h" | 7 #include "base/gfx/rect.h" |
| 8 #include "base/json_writer.h" |
| 9 #include "base/scoped_ptr.h" |
| 10 #include "base/values.h" |
8 #include "googleurl/src/gurl.h" | 11 #include "googleurl/src/gurl.h" |
9 #ifndef EXCLUDE_SKIA_DEPENDENCIES | 12 #ifndef EXCLUDE_SKIA_DEPENDENCIES |
10 #include "third_party/skia/include/core/SkBitmap.h" | 13 #include "third_party/skia/include/core/SkBitmap.h" |
11 #endif | 14 #endif |
12 #include "webkit/glue/dom_operations.h" | 15 #include "webkit/glue/dom_operations.h" |
13 | 16 |
14 namespace IPC { | 17 namespace IPC { |
15 | 18 |
16 #ifndef EXCLUDE_SKIA_DEPENDENCIES | 19 #ifndef EXCLUDE_SKIA_DEPENDENCIES |
17 | 20 |
(...skipping 27 matching lines...) Expand all Loading... |
45 if (!bitmap->allocPixels()) | 48 if (!bitmap->allocPixels()) |
46 return false; | 49 return false; |
47 if (total_pixels > bitmap->getSize()) | 50 if (total_pixels > bitmap->getSize()) |
48 return false; | 51 return false; |
49 memcpy(bitmap->getPixels(), pixels, total_pixels); | 52 memcpy(bitmap->getPixels(), pixels, total_pixels); |
50 } | 53 } |
51 return true; | 54 return true; |
52 } | 55 } |
53 }; | 56 }; |
54 | 57 |
| 58 const int kMaxRecursionDepth = 100; |
| 59 |
55 } // namespace | 60 } // namespace |
56 | 61 |
57 | 62 |
58 void ParamTraits<SkBitmap>::Write(Message* m, const SkBitmap& p) { | 63 void ParamTraits<SkBitmap>::Write(Message* m, const SkBitmap& p) { |
59 size_t fixed_size = sizeof(SkBitmap_Data); | 64 size_t fixed_size = sizeof(SkBitmap_Data); |
60 SkBitmap_Data bmp_data; | 65 SkBitmap_Data bmp_data; |
61 bmp_data.InitSkBitmapDataForTransfer(p); | 66 bmp_data.InitSkBitmapDataForTransfer(p); |
62 m->WriteData(reinterpret_cast<const char*>(&bmp_data), | 67 m->WriteData(reinterpret_cast<const char*>(&bmp_data), |
63 static_cast<int>(fixed_size)); | 68 static_cast<int>(fixed_size)); |
64 size_t pixel_size = p.getSize(); | 69 size_t pixel_size = p.getSize(); |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 r->icons.push_back(icon_info); | 219 r->icons.push_back(icon_info); |
215 } | 220 } |
216 return result; | 221 return result; |
217 } | 222 } |
218 | 223 |
219 void ParamTraits<webkit_glue::WebApplicationInfo>::Log( | 224 void ParamTraits<webkit_glue::WebApplicationInfo>::Log( |
220 const webkit_glue::WebApplicationInfo& p, std::wstring* l) { | 225 const webkit_glue::WebApplicationInfo& p, std::wstring* l) { |
221 l->append(L"<WebApplicationInfo>"); | 226 l->append(L"<WebApplicationInfo>"); |
222 } | 227 } |
223 | 228 |
| 229 // Value serialization |
| 230 |
| 231 static bool ReadValue(const Message* m, void** iter, Value** value, |
| 232 int recursion); |
| 233 |
| 234 static void WriteValue(Message* m, const Value* value, int recursion) { |
| 235 if (recursion > kMaxRecursionDepth) { |
| 236 LOG(WARNING) << "Max recursion depth hit in WriteValue."; |
| 237 return; |
| 238 } |
| 239 |
| 240 m->WriteInt(value->GetType()); |
| 241 |
| 242 switch (value->GetType()) { |
| 243 case Value::TYPE_NULL: |
| 244 break; |
| 245 case Value::TYPE_BOOLEAN: { |
| 246 bool val; |
| 247 value->GetAsBoolean(&val); |
| 248 WriteParam(m, val); |
| 249 break; |
| 250 } |
| 251 case Value::TYPE_INTEGER: { |
| 252 int val; |
| 253 value->GetAsInteger(&val); |
| 254 WriteParam(m, val); |
| 255 break; |
| 256 } |
| 257 case Value::TYPE_REAL: { |
| 258 double val; |
| 259 value->GetAsReal(&val); |
| 260 WriteParam(m, val); |
| 261 break; |
| 262 } |
| 263 case Value::TYPE_STRING: { |
| 264 std::string val; |
| 265 value->GetAsString(&val); |
| 266 WriteParam(m, val); |
| 267 break; |
| 268 } |
| 269 case Value::TYPE_BINARY: { |
| 270 NOTREACHED() << "Don't send BinaryValues over IPC."; |
| 271 } |
| 272 case Value::TYPE_DICTIONARY: { |
| 273 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value); |
| 274 |
| 275 WriteParam(m, static_cast<int>(dict->GetSize())); |
| 276 |
| 277 for (DictionaryValue::key_iterator it = dict->begin_keys(); |
| 278 it != dict->end_keys(); ++it) { |
| 279 Value* subval; |
| 280 if (dict->Get(*it, &subval)) { |
| 281 WriteParam(m, *it); |
| 282 WriteValue(m, subval, recursion + 1); |
| 283 } else { |
| 284 NOTREACHED() << "DictionaryValue iterators are filthy liars."; |
| 285 } |
| 286 } |
| 287 break; |
| 288 } |
| 289 case Value::TYPE_LIST: { |
| 290 const ListValue* list = static_cast<const ListValue*>(value); |
| 291 WriteParam(m, static_cast<int>(list->GetSize())); |
| 292 for (size_t i = 0; i < list->GetSize(); ++i) { |
| 293 Value* subval; |
| 294 if (list->Get(i, &subval)) { |
| 295 WriteValue(m, subval, recursion + 1); |
| 296 } else { |
| 297 NOTREACHED() << "ListValue::GetSize is a filthy liar."; |
| 298 } |
| 299 } |
| 300 break; |
| 301 } |
| 302 } |
| 303 } |
| 304 |
| 305 // Helper for ReadValue that reads a DictionaryValue into a pre-allocated |
| 306 // object. |
| 307 static bool ReadDictionaryValue(const Message* m, void** iter, |
| 308 DictionaryValue* value, int recursion) { |
| 309 int size; |
| 310 if (!ReadParam(m, iter, &size)) |
| 311 return false; |
| 312 |
| 313 for (int i = 0; i < size; ++i) { |
| 314 std::wstring key; |
| 315 Value* subval; |
| 316 if (!ReadParam(m, iter, &key) || |
| 317 !ReadValue(m, iter, &subval, recursion + 1)) |
| 318 return false; |
| 319 value->Set(key, subval); |
| 320 } |
| 321 |
| 322 return true; |
| 323 } |
| 324 |
| 325 // Helper for ReadValue that reads a ReadListValue into a pre-allocated |
| 326 // object. |
| 327 static bool ReadListValue(const Message* m, void** iter, |
| 328 ListValue* value, int recursion) { |
| 329 int size; |
| 330 if (!ReadParam(m, iter, &size)) |
| 331 return false; |
| 332 |
| 333 for (int i = 0; i < size; ++i) { |
| 334 Value* subval; |
| 335 if (!ReadValue(m, iter, &subval, recursion + 1)) |
| 336 return false; |
| 337 value->Set(i, subval); |
| 338 } |
| 339 |
| 340 return true; |
| 341 } |
| 342 |
| 343 static bool ReadValue(const Message* m, void** iter, Value** value, |
| 344 int recursion) { |
| 345 if (recursion > kMaxRecursionDepth) { |
| 346 LOG(WARNING) << "Max recursion depth hit in ReadValue."; |
| 347 return false; |
| 348 } |
| 349 |
| 350 int type; |
| 351 if (!ReadParam(m, iter, &type)) |
| 352 return false; |
| 353 |
| 354 switch (type) { |
| 355 case Value::TYPE_NULL: |
| 356 *value = Value::CreateNullValue(); |
| 357 break; |
| 358 case Value::TYPE_BOOLEAN: { |
| 359 bool val; |
| 360 if (!ReadParam(m, iter, &val)) |
| 361 return false; |
| 362 *value = Value::CreateBooleanValue(val); |
| 363 break; |
| 364 } |
| 365 case Value::TYPE_INTEGER: { |
| 366 int val; |
| 367 if (!ReadParam(m, iter, &val)) |
| 368 return false; |
| 369 *value = Value::CreateIntegerValue(val); |
| 370 break; |
| 371 } |
| 372 case Value::TYPE_REAL: { |
| 373 double val; |
| 374 if (!ReadParam(m, iter, &val)) |
| 375 return false; |
| 376 *value = Value::CreateRealValue(val); |
| 377 break; |
| 378 } |
| 379 case Value::TYPE_STRING: { |
| 380 std::string val; |
| 381 if (!ReadParam(m, iter, &val)) |
| 382 return false; |
| 383 *value = Value::CreateStringValue(val); |
| 384 break; |
| 385 } |
| 386 case Value::TYPE_BINARY: { |
| 387 NOTREACHED() << "Don't send BinaryValues over IPC."; |
| 388 break; |
| 389 } |
| 390 case Value::TYPE_DICTIONARY: { |
| 391 scoped_ptr<DictionaryValue> val(new DictionaryValue()); |
| 392 if (!ReadDictionaryValue(m, iter, val.get(), recursion)) |
| 393 return false; |
| 394 *value = val.release(); |
| 395 break; |
| 396 } |
| 397 case Value::TYPE_LIST: { |
| 398 scoped_ptr<ListValue> val(new ListValue()); |
| 399 if (!ReadListValue(m, iter, val.get(), recursion)) |
| 400 return false; |
| 401 *value = val.release(); |
| 402 break; |
| 403 } |
| 404 default: |
| 405 return false; |
| 406 } |
| 407 |
| 408 return true; |
| 409 } |
| 410 |
| 411 void ParamTraits<DictionaryValue>::Write(Message* m, const param_type& p) { |
| 412 WriteValue(m, &p, 0); |
| 413 } |
| 414 |
| 415 bool ParamTraits<DictionaryValue>::Read( |
| 416 const Message* m, void** iter, param_type* r) { |
| 417 int type; |
| 418 if (!ReadParam(m, iter, &type) || type != Value::TYPE_DICTIONARY) |
| 419 return false; |
| 420 |
| 421 return ReadDictionaryValue(m, iter, r, 0); |
| 422 } |
| 423 |
| 424 void ParamTraits<DictionaryValue>::Log(const param_type& p, std::wstring* l) { |
| 425 std::string json; |
| 426 JSONWriter::Write(&p, false, &json); |
| 427 l->append(UTF8ToWide(json)); |
| 428 } |
| 429 |
| 430 void ParamTraits<ListValue>::Write(Message* m, const param_type& p) { |
| 431 WriteValue(m, &p, 0); |
| 432 } |
| 433 |
| 434 bool ParamTraits<ListValue>::Read( |
| 435 const Message* m, void** iter, param_type* r) { |
| 436 int type; |
| 437 if (!ReadParam(m, iter, &type) || type != Value::TYPE_LIST) |
| 438 return false; |
| 439 |
| 440 return ReadListValue(m, iter, r, 0); |
| 441 } |
| 442 |
| 443 void ParamTraits<ListValue>::Log(const param_type& p, std::wstring* l) { |
| 444 std::string json; |
| 445 JSONWriter::Write(&p, false, &json); |
| 446 l->append(UTF8ToWide(json)); |
| 447 } |
224 } // namespace IPC | 448 } // namespace IPC |
OLD | NEW |