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 3 // found in the LICENSE file. 4 5 #include "ppapi/proxy/ppapi_param_traits.h" 6 7 #include <string.h> // For memcpy 8 9 #include "ppapi/c/pp_resource.h" 10 #include "ppapi/proxy/ppapi_messages.h" 11 #include "ppapi/proxy/serialized_var.h" 12 #include "ppapi/proxy/serialized_flash_menu.h" 13 #include "ppapi/shared_impl/host_resource.h" 14 #include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h" 15 16 namespace IPC { 17 18 namespace { 19 20 // Deserializes a vector from IPC. This special version must be used instead 21 // of the default IPC version when the vector contains a SerializedVar, either 22 // directly or indirectly (i.e. a vector of objects that have a SerializedVar 23 // inside them). 24 // 25 // The default vector deserializer does resize and then we deserialize into 26 // those allocated slots. However, the implementation of vector (at least in 27 // GCC's implementation), creates a new empty object using the default 28 // constructor, and then sets the rest of the items to that empty one using the 29 // copy constructor. 30 // 31 // Since we allocate the inner class when you call the default constructor and 32 // transfer the inner class when you do operator=, the entire vector will end 33 // up referring to the same inner class. Deserializing into this will just end 34 // up overwriting the same item over and over, since all the SerializedVars 35 // will refer to the same thing. 36 // 37 // The solution is to make a new object for each deserialized item, and then 38 // add it to the vector one at a time. 39 template<typename T> 40 bool ReadVectorWithoutCopy(const Message* m, 41 PickleIterator* iter, 42 std::vector<T>* output) { 43 // This part is just a copy of the the default ParamTraits vector Read(). 44 int size; 45 // ReadLength() checks for < 0 itself. 46 if (!m->ReadLength(iter, &size)) 47 return false; 48 // Resizing beforehand is not safe, see BUG 1006367 for details. 49 if (INT_MAX / sizeof(T) <= static_cast<size_t>(size)) 50 return false; 51 52 output->reserve(size); 53 for (int i = 0; i < size; i++) { 54 T cur; 55 if (!ReadParam(m, iter, &cur)) 56 return false; 57 output->push_back(cur); 58 } 59 return true; 60 } 61 62 // This serializes the vector of items to the IPC message in exactly the same 63 // way as the "regular" IPC vector serializer does. But having the code here 64 // saves us from having to copy this code into all ParamTraits that use the 65 // ReadVectorWithoutCopy function for deserializing. 66 template<typename T> 67 void WriteVectorWithoutCopy(Message* m, const std::vector<T>& p) { 68 WriteParam(m, static_cast<int>(p.size())); 69 for (size_t i = 0; i < p.size(); i++) 70 WriteParam(m, p[i]); 71 } 72 73 } // namespace 74 75 // PP_Bool --------------------------------------------------------------------- 76 77 // static 78 void ParamTraits<PP_Bool>::Write(Message* m, const param_type& p) { 79 ParamTraits<bool>::Write(m, PP_ToBool(p)); 80 } 81 82 // static 83 bool ParamTraits<PP_Bool>::Read(const Message* m, 84 PickleIterator* iter, 85 param_type* r) { 86 // We specifically want to be strict here about what types of input we accept, 87 // which ParamTraits<bool> does for us. We don't want to deserialize "2" into 88 // a PP_Bool, for example. 89 bool result = false; 90 if (!ParamTraits<bool>::Read(m, iter, &result)) 91 return false; 92 *r = PP_FromBool(result); 93 return true; 94 } 95 96 // static 97 void ParamTraits<PP_Bool>::Log(const param_type& p, std::string* l) { 98 } 99 100 // PP_NetAddress_Private ------------------------------------------------------- 101 102 // static 103 void ParamTraits<PP_NetAddress_Private>::Write(Message* m, 104 const param_type& p) { 105 WriteParam(m, p.size); 106 m->WriteBytes(p.data, static_cast<int>(p.size)); 107 } 108 109 // static 110 bool ParamTraits<PP_NetAddress_Private>::Read(const Message* m, 111 PickleIterator* iter, 112 param_type* p) { 113 uint16 size; 114 if (!ReadParam(m, iter, &size)) 115 return false; 116 if (size > sizeof(p->data)) 117 return false; 118 p->size = size; 119 120 const char* data; 121 if (!m->ReadBytes(iter, &data, size)) 122 return false; 123 memcpy(p->data, data, size); 124 return true; 125 } 126 127 // static 128 void ParamTraits<PP_NetAddress_Private>::Log(const param_type& p, 129 std::string* l) { 130 l->append("<PP_NetAddress_Private ("); 131 LogParam(p.size, l); 132 l->append(" bytes)>"); 133 } 134 135 // HostResource ---------------------------------------------------------------- 136 137 // static 138 void ParamTraits<ppapi::HostResource>::Write(Message* m, 139 const param_type& p) { 140 ParamTraits<PP_Instance>::Write(m, p.instance()); 141 ParamTraits<PP_Resource>::Write(m, p.host_resource()); 142 } 143 144 // static 145 bool ParamTraits<ppapi::HostResource>::Read(const Message* m, 146 PickleIterator* iter, 147 param_type* r) { 148 PP_Instance instance; 149 PP_Resource resource; 150 if (!ParamTraits<PP_Instance>::Read(m, iter, &instance) || 151 !ParamTraits<PP_Resource>::Read(m, iter, &resource)) 152 return false; 153 r->SetHostResource(instance, resource); 154 return true; 155 } 156 157 // static 158 void ParamTraits<ppapi::HostResource>::Log(const param_type& p, 159 std::string* l) { 160 } 161 162 // SerializedVar --------------------------------------------------------------- 163 164 // static 165 void ParamTraits<ppapi::proxy::SerializedVar>::Write(Message* m, 166 const param_type& p) { 167 p.WriteToMessage(m); 168 } 169 170 // static 171 bool ParamTraits<ppapi::proxy::SerializedVar>::Read(const Message* m, 172 PickleIterator* iter, 173 param_type* r) { 174 return r->ReadFromMessage(m, iter); 175 } 176 177 // static 178 void ParamTraits<ppapi::proxy::SerializedVar>::Log(const param_type& p, 179 std::string* l) { 180 } 181 182 // std::vector<SerializedVar> -------------------------------------------------- 183 184 void ParamTraits< std::vector<ppapi::proxy::SerializedVar> >::Write( 185 Message* m, 186 const param_type& p) { 187 WriteVectorWithoutCopy(m, p); 188 } 189 190 // static 191 bool ParamTraits< std::vector<ppapi::proxy::SerializedVar> >::Read( 192 const Message* m, 193 PickleIterator* iter, 194 param_type* r) { 195 return ReadVectorWithoutCopy(m, iter, r); 196 } 197 198 // static 199 void ParamTraits< std::vector<ppapi::proxy::SerializedVar> >::Log( 200 const param_type& p, 201 std::string* l) { 202 } 203 204 // ppapi::PpapiPermissions ----------------------------------------------------- 205 206 void ParamTraits<ppapi::PpapiPermissions>::Write(Message* m, 207 const param_type& p) { 208 ParamTraits<uint32_t>::Write(m, p.GetBits()); 209 } 210 211 // static 212 bool ParamTraits<ppapi::PpapiPermissions>::Read(const Message* m, 213 PickleIterator* iter, 214 param_type* r) { 215 uint32_t bits; 216 if (!ParamTraits<uint32_t>::Read(m, iter, &bits)) 217 return false; 218 *r = ppapi::PpapiPermissions(bits); 219 return true; 220 } 221 222 // static 223 void ParamTraits<ppapi::PpapiPermissions>::Log(const param_type& p, 224 std::string* l) { 225 } 226 227 // SerializedHandle ------------------------------------------------------------ 228 229 // static 230 void ParamTraits<ppapi::proxy::SerializedHandle>::Write(Message* m, 231 const param_type& p) { 232 ppapi::proxy::SerializedHandle::WriteHeader(p.header(), m); 233 switch (p.type()) { 234 case ppapi::proxy::SerializedHandle::SHARED_MEMORY: 235 ParamTraits<base::SharedMemoryHandle>::Write(m, p.shmem()); 236 break; 237 case ppapi::proxy::SerializedHandle::SOCKET: 238 case ppapi::proxy::SerializedHandle::FILE: 239 ParamTraits<IPC::PlatformFileForTransit>::Write(m, p.descriptor()); 240 break; 241 case ppapi::proxy::SerializedHandle::INVALID: 242 break; 243 // No default so the compiler will warn on new types. 244 } 245 } 246 247 // static 248 bool ParamTraits<ppapi::proxy::SerializedHandle>::Read(const Message* m, 249 PickleIterator* iter, 250 param_type* r) { 251 ppapi::proxy::SerializedHandle::Header header; 252 if (!ppapi::proxy::SerializedHandle::ReadHeader(iter, &header)) 253 return false; 254 switch (header.type) { 255 case ppapi::proxy::SerializedHandle::SHARED_MEMORY: { 256 base::SharedMemoryHandle handle; 257 if (ParamTraits<base::SharedMemoryHandle>::Read(m, iter, &handle)) { 258 r->set_shmem(handle, header.size); 259 return true; 260 } 261 break; 262 } 263 case ppapi::proxy::SerializedHandle::SOCKET: { 264 IPC::PlatformFileForTransit socket; 265 if (ParamTraits<IPC::PlatformFileForTransit>::Read(m, iter, &socket)) { 266 r->set_socket(socket); 267 return true; 268 } 269 break; 270 } 271 case ppapi::proxy::SerializedHandle::FILE: { 272 IPC::PlatformFileForTransit desc; 273 if (ParamTraits<IPC::PlatformFileForTransit>::Read(m, iter, &desc)) { 274 r->set_file_handle(desc, header.open_flags, header.file_io); 275 return true; 276 } 277 break; 278 } 279 case ppapi::proxy::SerializedHandle::INVALID: 280 return true; 281 // No default so the compiler will warn us if a new type is added. 282 } 283 return false; 284 } 285 286 // static 287 void ParamTraits<ppapi::proxy::SerializedHandle>::Log(const param_type& p, 288 std::string* l) { 289 } 290 291 // PPBURLLoader_UpdateProgress_Params ------------------------------------------ 292 293 // static 294 void ParamTraits<ppapi::proxy::PPBURLLoader_UpdateProgress_Params>::Write( 295 Message* m, 296 const param_type& p) { 297 ParamTraits<PP_Instance>::Write(m, p.instance); 298 ParamTraits<ppapi::HostResource>::Write(m, p.resource); 299 ParamTraits<int64_t>::Write(m, p.bytes_sent); 300 ParamTraits<int64_t>::Write(m, p.total_bytes_to_be_sent); 301 ParamTraits<int64_t>::Write(m, p.bytes_received); 302 ParamTraits<int64_t>::Write(m, p.total_bytes_to_be_received); 303 } 304 305 // static 306 bool ParamTraits<ppapi::proxy::PPBURLLoader_UpdateProgress_Params>::Read( 307 const Message* m, 308 PickleIterator* iter, 309 param_type* r) { 310 return 311 ParamTraits<PP_Instance>::Read(m, iter, &r->instance) && 312 ParamTraits<ppapi::HostResource>::Read(m, iter, &r->resource) && 313 ParamTraits<int64_t>::Read(m, iter, &r->bytes_sent) && 314 ParamTraits<int64_t>::Read(m, iter, &r->total_bytes_to_be_sent) && 315 ParamTraits<int64_t>::Read(m, iter, &r->bytes_received) && 316 ParamTraits<int64_t>::Read(m, iter, &r->total_bytes_to_be_received); 317 } 318 319 // static 320 void ParamTraits<ppapi::proxy::PPBURLLoader_UpdateProgress_Params>::Log( 321 const param_type& p, 322 std::string* l) { 323 } 324 325 #if !defined(OS_NACL) && !defined(NACL_WIN64) 326 // PPBFlash_DrawGlyphs_Params -------------------------------------------------- 327 // static 328 void ParamTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params>::Write( 329 Message* m, 330 const param_type& p) { 331 ParamTraits<PP_Instance>::Write(m, p.instance); 332 ParamTraits<ppapi::HostResource>::Write(m, p.image_data); 333 ParamTraits<ppapi::proxy::SerializedFontDescription>::Write(m, p.font_desc); 334 ParamTraits<uint32_t>::Write(m, p.color); 335 ParamTraits<PP_Point>::Write(m, p.position); 336 ParamTraits<PP_Rect>::Write(m, p.clip); 337 ParamTraits<float>::Write(m, p.transformation[0][0]); 338 ParamTraits<float>::Write(m, p.transformation[0][1]); 339 ParamTraits<float>::Write(m, p.transformation[0][2]); 340 ParamTraits<float>::Write(m, p.transformation[1][0]); 341 ParamTraits<float>::Write(m, p.transformation[1][1]); 342 ParamTraits<float>::Write(m, p.transformation[1][2]); 343 ParamTraits<float>::Write(m, p.transformation[2][0]); 344 ParamTraits<float>::Write(m, p.transformation[2][1]); 345 ParamTraits<float>::Write(m, p.transformation[2][2]); 346 ParamTraits<PP_Bool>::Write(m, p.allow_subpixel_aa); 347 ParamTraits<std::vector<uint16_t> >::Write(m, p.glyph_indices); 348 ParamTraits<std::vector<PP_Point> >::Write(m, p.glyph_advances); 349 } 350 351 // static 352 bool ParamTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params>::Read( 353 const Message* m, 354 PickleIterator* iter, 355 param_type* r) { 356 return 357 ParamTraits<PP_Instance>::Read(m, iter, &r->instance) && 358 ParamTraits<ppapi::HostResource>::Read(m, iter, &r->image_data) && 359 ParamTraits<ppapi::proxy::SerializedFontDescription>::Read(m, iter, 360 &r->font_desc) && 361 ParamTraits<uint32_t>::Read(m, iter, &r->color) && 362 ParamTraits<PP_Point>::Read(m, iter, &r->position) && 363 ParamTraits<PP_Rect>::Read(m, iter, &r->clip) && 364 ParamTraits<float>::Read(m, iter, &r->transformation[0][0]) && 365 ParamTraits<float>::Read(m, iter, &r->transformation[0][1]) && 366 ParamTraits<float>::Read(m, iter, &r->transformation[0][2]) && 367 ParamTraits<float>::Read(m, iter, &r->transformation[1][0]) && 368 ParamTraits<float>::Read(m, iter, &r->transformation[1][1]) && 369 ParamTraits<float>::Read(m, iter, &r->transformation[1][2]) && 370 ParamTraits<float>::Read(m, iter, &r->transformation[2][0]) && 371 ParamTraits<float>::Read(m, iter, &r->transformation[2][1]) && 372 ParamTraits<float>::Read(m, iter, &r->transformation[2][2]) && 373 ParamTraits<PP_Bool>::Read(m, iter, &r->allow_subpixel_aa) && 374 ParamTraits<std::vector<uint16_t> >::Read(m, iter, &r->glyph_indices) && 375 ParamTraits<std::vector<PP_Point> >::Read(m, iter, &r->glyph_advances) && 376 r->glyph_indices.size() == r->glyph_advances.size(); 377 } 378 379 // static 380 void ParamTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params>::Log( 381 const param_type& p, 382 std::string* l) { 383 } 384 385 // SerializedDirEntry ---------------------------------------------------------- 386 387 // static 388 void ParamTraits<ppapi::proxy::SerializedDirEntry>::Write(Message* m, 389 const param_type& p) { 390 ParamTraits<std::string>::Write(m, p.name); 391 ParamTraits<bool>::Write(m, p.is_dir); 392 } 393 394 // static 395 bool ParamTraits<ppapi::proxy::SerializedDirEntry>::Read(const Message* m, 396 PickleIterator* iter, 397 param_type* r) { 398 return ParamTraits<std::string>::Read(m, iter, &r->name) && 399 ParamTraits<bool>::Read(m, iter, &r->is_dir); 400 } 401 402 // static 403 void ParamTraits<ppapi::proxy::SerializedDirEntry>::Log(const param_type& p, 404 std::string* l) { 405 } 406 407 // ppapi::proxy::SerializedFontDescription ------------------------------------- 408 409 // static 410 void ParamTraits<ppapi::proxy::SerializedFontDescription>::Write( 411 Message* m, 412 const param_type& p) { 413 ParamTraits<std::string>::Write(m, p.face); 414 ParamTraits<int32_t>::Write(m, p.family); 415 ParamTraits<uint32_t>::Write(m, p.size); 416 ParamTraits<int32_t>::Write(m, p.weight); 417 ParamTraits<PP_Bool>::Write(m, p.italic); 418 ParamTraits<PP_Bool>::Write(m, p.small_caps); 419 ParamTraits<int32_t>::Write(m, p.letter_spacing); 420 ParamTraits<int32_t>::Write(m, p.word_spacing); 421 } 422 423 // static 424 bool ParamTraits<ppapi::proxy::SerializedFontDescription>::Read( 425 const Message* m, 426 PickleIterator* iter, 427 param_type* r) { 428 return 429 ParamTraits<std::string>::Read(m, iter, &r->face) && 430 ParamTraits<int32_t>::Read(m, iter, &r->family) && 431 ParamTraits<uint32_t>::Read(m, iter, &r->size) && 432 ParamTraits<int32_t>::Read(m, iter, &r->weight) && 433 ParamTraits<PP_Bool>::Read(m, iter, &r->italic) && 434 ParamTraits<PP_Bool>::Read(m, iter, &r->small_caps) && 435 ParamTraits<int32_t>::Read(m, iter, &r->letter_spacing) && 436 ParamTraits<int32_t>::Read(m, iter, &r->word_spacing); 437 } 438 439 // static 440 void ParamTraits<ppapi::proxy::SerializedFontDescription>::Log( 441 const param_type& p, 442 std::string* l) { 443 } 444 #endif // !defined(OS_NACL) && !defined(NACL_WIN64) 445 446 // ppapi::proxy::SerializedTrueTypeFontDesc ------------------------------------ 447 448 // static 449 void ParamTraits<ppapi::proxy::SerializedTrueTypeFontDesc>::Write( 450 Message* m, 451 const param_type& p) { 452 ParamTraits<std::string>::Write(m, p.family); 453 ParamTraits<PP_TrueTypeFontFamily_Dev>::Write(m, p.generic_family); 454 ParamTraits<PP_TrueTypeFontStyle_Dev>::Write(m, p.style); 455 ParamTraits<PP_TrueTypeFontWeight_Dev>::Write(m, p.weight); 456 ParamTraits<PP_TrueTypeFontWidth_Dev>::Write(m, p.width); 457 ParamTraits<PP_TrueTypeFontCharset_Dev>::Write(m, p.charset); 458 } 459 460 // static 461 bool ParamTraits<ppapi::proxy::SerializedTrueTypeFontDesc>::Read( 462 const Message* m, 463 PickleIterator* iter, 464 param_type* r) { 465 return 466 ParamTraits<std::string>::Read(m, iter, &r->family) && 467 ParamTraits<PP_TrueTypeFontFamily_Dev>::Read(m, iter, 468 &r->generic_family) && 469 ParamTraits<PP_TrueTypeFontStyle_Dev>::Read(m, iter, &r->style) && 470 ParamTraits<PP_TrueTypeFontWeight_Dev>::Read(m, iter, &r->weight) && 471 ParamTraits<PP_TrueTypeFontWidth_Dev>::Read(m, iter, &r->width) && 472 ParamTraits<PP_TrueTypeFontCharset_Dev>::Read(m, iter, &r->charset); 473 } 474 475 // static 476 void ParamTraits<ppapi::proxy::SerializedTrueTypeFontDesc>::Log( 477 const param_type& p, 478 std::string* l) { 479 } 480 481 #if !defined(OS_NACL) && !defined(NACL_WIN64) 482 // ppapi::PepperFilePath ------------------------------------------------------- 483 484 // static 485 void ParamTraits<ppapi::PepperFilePath>::Write(Message* m, 486 const param_type& p) { 487 WriteParam(m, static_cast<unsigned>(p.domain())); 488 WriteParam(m, p.path()); 489 } 490 491 // static 492 bool ParamTraits<ppapi::PepperFilePath>::Read(const Message* m, 493 PickleIterator* iter, 494 param_type* p) { 495 unsigned domain; 496 base::FilePath path; 497 if (!ReadParam(m, iter, &domain) || !ReadParam(m, iter, &path)) 498 return false; 499 if (domain > ppapi::PepperFilePath::DOMAIN_MAX_VALID) 500 return false; 501 502 *p = ppapi::PepperFilePath( 503 static_cast<ppapi::PepperFilePath::Domain>(domain), path); 504 return true; 505 } 506 507 // static 508 void ParamTraits<ppapi::PepperFilePath>::Log(const param_type& p, 509 std::string* l) { 510 l->append("("); 511 LogParam(static_cast<unsigned>(p.domain()), l); 512 l->append(", "); 513 LogParam(p.path(), l); 514 l->append(")"); 515 } 516 517 // SerializedFlashMenu --------------------------------------------------------- 518 519 // static 520 void ParamTraits<ppapi::proxy::SerializedFlashMenu>::Write( 521 Message* m, 522 const param_type& p) { 523 p.WriteToMessage(m); 524 } 525 526 // static 527 bool ParamTraits<ppapi::proxy::SerializedFlashMenu>::Read(const Message* m, 528 PickleIterator* iter, 529 param_type* r) { 530 return r->ReadFromMessage(m, iter); 531 } 532 533 // static 534 void ParamTraits<ppapi::proxy::SerializedFlashMenu>::Log(const param_type& p, 535 std::string* l) { 536 } 537 #endif // !defined(OS_NACL) && !defined(NACL_WIN64) 538 539 // PPB_X509Certificate_Fields -------------------------------------------------- 540 541 // static 542 void ParamTraits<ppapi::PPB_X509Certificate_Fields>::Write( 543 Message* m, 544 const param_type& p) { 545 ParamTraits<base::ListValue>::Write(m, p.values_); 546 } 547 548 // static 549 bool ParamTraits<ppapi::PPB_X509Certificate_Fields>::Read(const Message* m, 550 PickleIterator* iter, 551 param_type* r) { 552 return ParamTraits<base::ListValue>::Read(m, iter, &(r->values_)); 553 } 554 555 // static 556 void ParamTraits<ppapi::PPB_X509Certificate_Fields>::Log(const param_type& p, 557 std::string* l) { 558 } 559 560 // ppapi::SocketOptionData ----------------------------------------------------- 561 562 // static 563 void ParamTraits<ppapi::SocketOptionData>::Write(Message* m, 564 const param_type& p) { 565 ppapi::SocketOptionData::Type type = p.GetType(); 566 ParamTraits<int32_t>::Write(m, static_cast<int32_t>(type)); 567 switch (type) { 568 case ppapi::SocketOptionData::TYPE_INVALID: { 569 break; 570 } 571 case ppapi::SocketOptionData::TYPE_BOOL: { 572 bool out_value = false; 573 bool result = p.GetBool(&out_value); 574 // Suppress unused variable warnings. 575 static_cast<void>(result); 576 DCHECK(result); 577 578 ParamTraits<bool>::Write(m, out_value); 579 break; 580 } 581 case ppapi::SocketOptionData::TYPE_INT32: { 582 int32_t out_value = 0; 583 bool result = p.GetInt32(&out_value); 584 // Suppress unused variable warnings. 585 static_cast<void>(result); 586 DCHECK(result); 587 588 ParamTraits<int32_t>::Write(m, out_value); 589 break; 590 } 591 // No default so the compiler will warn on new types. 592 } 593 } 594 595 // static 596 bool ParamTraits<ppapi::SocketOptionData>::Read(const Message* m, 597 PickleIterator* iter, 598 param_type* r) { 599 *r = ppapi::SocketOptionData(); 600 int32_t type = 0; 601 if (!ParamTraits<int32_t>::Read(m, iter, &type)) 602 return false; 603 if (type != ppapi::SocketOptionData::TYPE_INVALID && 604 type != ppapi::SocketOptionData::TYPE_BOOL && 605 type != ppapi::SocketOptionData::TYPE_INT32) { 606 return false; 607 } 608 switch (static_cast<ppapi::SocketOptionData::Type>(type)) { 609 case ppapi::SocketOptionData::TYPE_INVALID: { 610 return true; 611 } 612 case ppapi::SocketOptionData::TYPE_BOOL: { 613 bool value = false; 614 if (!ParamTraits<bool>::Read(m, iter, &value)) 615 return false; 616 r->SetBool(value); 617 return true; 618 } 619 case ppapi::SocketOptionData::TYPE_INT32: { 620 int32_t value = 0; 621 if (!ParamTraits<int32_t>::Read(m, iter, &value)) 622 return false; 623 r->SetInt32(value); 624 return true; 625 } 626 // No default so the compiler will warn on new types. 627 } 628 return false; 629 } 630 631 // static 632 void ParamTraits<ppapi::SocketOptionData>::Log(const param_type& p, 633 std::string* l) { 634 } 635 636 // ppapi::CompositorLayerData -------------------------------------------------- 637 638 // static 639 void ParamTraits<ppapi::CompositorLayerData::Transform>::Write( 640 Message* m, 641 const param_type& p) { 642 for (size_t i = 0; i < arraysize(p.matrix); i++) 643 ParamTraits<float>::Write(m, p.matrix[i]); 644 } 645 646 // static 647 bool ParamTraits<ppapi::CompositorLayerData::Transform>::Read( 648 const Message* m, 649 PickleIterator* iter, 650 param_type* r) { 651 for (size_t i = 0; i < arraysize(r->matrix);i++) { 652 if (!ParamTraits<float>::Read(m, iter, &r->matrix[i])) 653 return false; 654 } 655 return true; 656 } 657 658 void ParamTraits<ppapi::CompositorLayerData::Transform>::Log( 659 const param_type& p, 660 std::string* l) { 661 } 662 663 } // namespace IPC 664