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::CHANNEL_HANDLE: 239 case ppapi::proxy::SerializedHandle::FILE: 240 ParamTraits<IPC::PlatformFileForTransit>::Write(m, p.descriptor()); 241 break; 242 case ppapi::proxy::SerializedHandle::INVALID: 243 break; 244 // No default so the compiler will warn on new types. 245 } 246 } 247 248 // static 249 bool ParamTraits<ppapi::proxy::SerializedHandle>::Read(const Message* m, 250 PickleIterator* iter, 251 param_type* r) { 252 ppapi::proxy::SerializedHandle::Header header; 253 if (!ppapi::proxy::SerializedHandle::ReadHeader(iter, &header)) 254 return false; 255 switch (header.type) { 256 case ppapi::proxy::SerializedHandle::SHARED_MEMORY: { 257 base::SharedMemoryHandle handle; 258 if (ParamTraits<base::SharedMemoryHandle>::Read(m, iter, &handle)) { 259 r->set_shmem(handle, header.size); 260 return true; 261 } 262 break; 263 } 264 case ppapi::proxy::SerializedHandle::SOCKET: { 265 IPC::PlatformFileForTransit socket; 266 if (ParamTraits<IPC::PlatformFileForTransit>::Read(m, iter, &socket)) { 267 r->set_socket(socket); 268 return true; 269 } 270 break; 271 } 272 case ppapi::proxy::SerializedHandle::CHANNEL_HANDLE: { 273 IPC::PlatformFileForTransit desc; 274 if (ParamTraits<IPC::PlatformFileForTransit>::Read(m, iter, &desc)) { 275 r->set_channel_handle(desc); 276 return true; 277 } 278 break; 279 } 280 case ppapi::proxy::SerializedHandle::FILE: { 281 IPC::PlatformFileForTransit desc; 282 if (ParamTraits<IPC::PlatformFileForTransit>::Read(m, iter, &desc)) { 283 r->set_file_handle(desc, header.open_flag); 284 return true; 285 } 286 break; 287 } 288 case ppapi::proxy::SerializedHandle::INVALID: 289 return true; 290 // No default so the compiler will warn us if a new type is added. 291 } 292 return false; 293 } 294 295 // static 296 void ParamTraits<ppapi::proxy::SerializedHandle>::Log(const param_type& p, 297 std::string* l) { 298 } 299 300 // PPBURLLoader_UpdateProgress_Params ------------------------------------------ 301 302 // static 303 void ParamTraits<ppapi::proxy::PPBURLLoader_UpdateProgress_Params>::Write( 304 Message* m, 305 const param_type& p) { 306 ParamTraits<PP_Instance>::Write(m, p.instance); 307 ParamTraits<ppapi::HostResource>::Write(m, p.resource); 308 ParamTraits<int64_t>::Write(m, p.bytes_sent); 309 ParamTraits<int64_t>::Write(m, p.total_bytes_to_be_sent); 310 ParamTraits<int64_t>::Write(m, p.bytes_received); 311 ParamTraits<int64_t>::Write(m, p.total_bytes_to_be_received); 312 } 313 314 // static 315 bool ParamTraits<ppapi::proxy::PPBURLLoader_UpdateProgress_Params>::Read( 316 const Message* m, 317 PickleIterator* iter, 318 param_type* r) { 319 return 320 ParamTraits<PP_Instance>::Read(m, iter, &r->instance) && 321 ParamTraits<ppapi::HostResource>::Read(m, iter, &r->resource) && 322 ParamTraits<int64_t>::Read(m, iter, &r->bytes_sent) && 323 ParamTraits<int64_t>::Read(m, iter, &r->total_bytes_to_be_sent) && 324 ParamTraits<int64_t>::Read(m, iter, &r->bytes_received) && 325 ParamTraits<int64_t>::Read(m, iter, &r->total_bytes_to_be_received); 326 } 327 328 // static 329 void ParamTraits<ppapi::proxy::PPBURLLoader_UpdateProgress_Params>::Log( 330 const param_type& p, 331 std::string* l) { 332 } 333 334 #if !defined(OS_NACL) && !defined(NACL_WIN64) 335 // PPBFlash_DrawGlyphs_Params -------------------------------------------------- 336 // static 337 void ParamTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params>::Write( 338 Message* m, 339 const param_type& p) { 340 ParamTraits<PP_Instance>::Write(m, p.instance); 341 ParamTraits<ppapi::HostResource>::Write(m, p.image_data); 342 ParamTraits<ppapi::proxy::SerializedFontDescription>::Write(m, p.font_desc); 343 ParamTraits<uint32_t>::Write(m, p.color); 344 ParamTraits<PP_Point>::Write(m, p.position); 345 ParamTraits<PP_Rect>::Write(m, p.clip); 346 ParamTraits<float>::Write(m, p.transformation[0][0]); 347 ParamTraits<float>::Write(m, p.transformation[0][1]); 348 ParamTraits<float>::Write(m, p.transformation[0][2]); 349 ParamTraits<float>::Write(m, p.transformation[1][0]); 350 ParamTraits<float>::Write(m, p.transformation[1][1]); 351 ParamTraits<float>::Write(m, p.transformation[1][2]); 352 ParamTraits<float>::Write(m, p.transformation[2][0]); 353 ParamTraits<float>::Write(m, p.transformation[2][1]); 354 ParamTraits<float>::Write(m, p.transformation[2][2]); 355 ParamTraits<PP_Bool>::Write(m, p.allow_subpixel_aa); 356 ParamTraits<std::vector<uint16_t> >::Write(m, p.glyph_indices); 357 ParamTraits<std::vector<PP_Point> >::Write(m, p.glyph_advances); 358 } 359 360 // static 361 bool ParamTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params>::Read( 362 const Message* m, 363 PickleIterator* iter, 364 param_type* r) { 365 return 366 ParamTraits<PP_Instance>::Read(m, iter, &r->instance) && 367 ParamTraits<ppapi::HostResource>::Read(m, iter, &r->image_data) && 368 ParamTraits<ppapi::proxy::SerializedFontDescription>::Read(m, iter, 369 &r->font_desc) && 370 ParamTraits<uint32_t>::Read(m, iter, &r->color) && 371 ParamTraits<PP_Point>::Read(m, iter, &r->position) && 372 ParamTraits<PP_Rect>::Read(m, iter, &r->clip) && 373 ParamTraits<float>::Read(m, iter, &r->transformation[0][0]) && 374 ParamTraits<float>::Read(m, iter, &r->transformation[0][1]) && 375 ParamTraits<float>::Read(m, iter, &r->transformation[0][2]) && 376 ParamTraits<float>::Read(m, iter, &r->transformation[1][0]) && 377 ParamTraits<float>::Read(m, iter, &r->transformation[1][1]) && 378 ParamTraits<float>::Read(m, iter, &r->transformation[1][2]) && 379 ParamTraits<float>::Read(m, iter, &r->transformation[2][0]) && 380 ParamTraits<float>::Read(m, iter, &r->transformation[2][1]) && 381 ParamTraits<float>::Read(m, iter, &r->transformation[2][2]) && 382 ParamTraits<PP_Bool>::Read(m, iter, &r->allow_subpixel_aa) && 383 ParamTraits<std::vector<uint16_t> >::Read(m, iter, &r->glyph_indices) && 384 ParamTraits<std::vector<PP_Point> >::Read(m, iter, &r->glyph_advances) && 385 r->glyph_indices.size() == r->glyph_advances.size(); 386 } 387 388 // static 389 void ParamTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params>::Log( 390 const param_type& p, 391 std::string* l) { 392 } 393 394 // SerializedDirEntry ---------------------------------------------------------- 395 396 // static 397 void ParamTraits<ppapi::proxy::SerializedDirEntry>::Write(Message* m, 398 const param_type& p) { 399 ParamTraits<std::string>::Write(m, p.name); 400 ParamTraits<bool>::Write(m, p.is_dir); 401 } 402 403 // static 404 bool ParamTraits<ppapi::proxy::SerializedDirEntry>::Read(const Message* m, 405 PickleIterator* iter, 406 param_type* r) { 407 return ParamTraits<std::string>::Read(m, iter, &r->name) && 408 ParamTraits<bool>::Read(m, iter, &r->is_dir); 409 } 410 411 // static 412 void ParamTraits<ppapi::proxy::SerializedDirEntry>::Log(const param_type& p, 413 std::string* l) { 414 } 415 416 // ppapi::proxy::SerializedFontDescription ------------------------------------- 417 418 // static 419 void ParamTraits<ppapi::proxy::SerializedFontDescription>::Write( 420 Message* m, 421 const param_type& p) { 422 ParamTraits<std::string>::Write(m, p.face); 423 ParamTraits<int32_t>::Write(m, p.family); 424 ParamTraits<uint32_t>::Write(m, p.size); 425 ParamTraits<int32_t>::Write(m, p.weight); 426 ParamTraits<PP_Bool>::Write(m, p.italic); 427 ParamTraits<PP_Bool>::Write(m, p.small_caps); 428 ParamTraits<int32_t>::Write(m, p.letter_spacing); 429 ParamTraits<int32_t>::Write(m, p.word_spacing); 430 } 431 432 // static 433 bool ParamTraits<ppapi::proxy::SerializedFontDescription>::Read( 434 const Message* m, 435 PickleIterator* iter, 436 param_type* r) { 437 return 438 ParamTraits<std::string>::Read(m, iter, &r->face) && 439 ParamTraits<int32_t>::Read(m, iter, &r->family) && 440 ParamTraits<uint32_t>::Read(m, iter, &r->size) && 441 ParamTraits<int32_t>::Read(m, iter, &r->weight) && 442 ParamTraits<PP_Bool>::Read(m, iter, &r->italic) && 443 ParamTraits<PP_Bool>::Read(m, iter, &r->small_caps) && 444 ParamTraits<int32_t>::Read(m, iter, &r->letter_spacing) && 445 ParamTraits<int32_t>::Read(m, iter, &r->word_spacing); 446 } 447 448 // static 449 void ParamTraits<ppapi::proxy::SerializedFontDescription>::Log( 450 const param_type& p, 451 std::string* l) { 452 } 453 #endif // !defined(OS_NACL) && !defined(NACL_WIN64) 454 455 // ppapi::proxy::SerializedTrueTypeFontDesc ------------------------------------ 456 457 // static 458 void ParamTraits<ppapi::proxy::SerializedTrueTypeFontDesc>::Write( 459 Message* m, 460 const param_type& p) { 461 ParamTraits<std::string>::Write(m, p.family); 462 ParamTraits<PP_TrueTypeFontFamily_Dev>::Write(m, p.generic_family); 463 ParamTraits<PP_TrueTypeFontStyle_Dev>::Write(m, p.style); 464 ParamTraits<PP_TrueTypeFontWeight_Dev>::Write(m, p.weight); 465 ParamTraits<PP_TrueTypeFontWidth_Dev>::Write(m, p.width); 466 ParamTraits<PP_TrueTypeFontCharset_Dev>::Write(m, p.charset); 467 } 468 469 // static 470 bool ParamTraits<ppapi::proxy::SerializedTrueTypeFontDesc>::Read( 471 const Message* m, 472 PickleIterator* iter, 473 param_type* r) { 474 return 475 ParamTraits<std::string>::Read(m, iter, &r->family) && 476 ParamTraits<PP_TrueTypeFontFamily_Dev>::Read(m, iter, 477 &r->generic_family) && 478 ParamTraits<PP_TrueTypeFontStyle_Dev>::Read(m, iter, &r->style) && 479 ParamTraits<PP_TrueTypeFontWeight_Dev>::Read(m, iter, &r->weight) && 480 ParamTraits<PP_TrueTypeFontWidth_Dev>::Read(m, iter, &r->width) && 481 ParamTraits<PP_TrueTypeFontCharset_Dev>::Read(m, iter, &r->charset); 482 } 483 484 // static 485 void ParamTraits<ppapi::proxy::SerializedTrueTypeFontDesc>::Log( 486 const param_type& p, 487 std::string* l) { 488 } 489 490 #if !defined(OS_NACL) && !defined(NACL_WIN64) 491 // ppapi::PepperFilePath ------------------------------------------------------- 492 493 // static 494 void ParamTraits<ppapi::PepperFilePath>::Write(Message* m, 495 const param_type& p) { 496 WriteParam(m, static_cast<unsigned>(p.domain())); 497 WriteParam(m, p.path()); 498 } 499 500 // static 501 bool ParamTraits<ppapi::PepperFilePath>::Read(const Message* m, 502 PickleIterator* iter, 503 param_type* p) { 504 unsigned domain; 505 base::FilePath path; 506 if (!ReadParam(m, iter, &domain) || !ReadParam(m, iter, &path)) 507 return false; 508 if (domain > ppapi::PepperFilePath::DOMAIN_MAX_VALID) 509 return false; 510 511 *p = ppapi::PepperFilePath( 512 static_cast<ppapi::PepperFilePath::Domain>(domain), path); 513 return true; 514 } 515 516 // static 517 void ParamTraits<ppapi::PepperFilePath>::Log(const param_type& p, 518 std::string* l) { 519 l->append("("); 520 LogParam(static_cast<unsigned>(p.domain()), l); 521 l->append(", "); 522 LogParam(p.path(), l); 523 l->append(")"); 524 } 525 526 // SerializedFlashMenu --------------------------------------------------------- 527 528 // static 529 void ParamTraits<ppapi::proxy::SerializedFlashMenu>::Write( 530 Message* m, 531 const param_type& p) { 532 p.WriteToMessage(m); 533 } 534 535 // static 536 bool ParamTraits<ppapi::proxy::SerializedFlashMenu>::Read(const Message* m, 537 PickleIterator* iter, 538 param_type* r) { 539 return r->ReadFromMessage(m, iter); 540 } 541 542 // static 543 void ParamTraits<ppapi::proxy::SerializedFlashMenu>::Log(const param_type& p, 544 std::string* l) { 545 } 546 #endif // !defined(OS_NACL) && !defined(NACL_WIN64) 547 548 // PPB_X509Certificate_Fields -------------------------------------------------- 549 550 // static 551 void ParamTraits<ppapi::PPB_X509Certificate_Fields>::Write( 552 Message* m, 553 const param_type& p) { 554 ParamTraits<base::ListValue>::Write(m, p.values_); 555 } 556 557 // static 558 bool ParamTraits<ppapi::PPB_X509Certificate_Fields>::Read(const Message* m, 559 PickleIterator* iter, 560 param_type* r) { 561 return ParamTraits<base::ListValue>::Read(m, iter, &(r->values_)); 562 } 563 564 // static 565 void ParamTraits<ppapi::PPB_X509Certificate_Fields>::Log(const param_type& p, 566 std::string* l) { 567 } 568 569 // ppapi::SocketOptionData ----------------------------------------------------- 570 571 // static 572 void ParamTraits<ppapi::SocketOptionData>::Write(Message* m, 573 const param_type& p) { 574 ppapi::SocketOptionData::Type type = p.GetType(); 575 ParamTraits<int32_t>::Write(m, static_cast<int32_t>(type)); 576 switch (type) { 577 case ppapi::SocketOptionData::TYPE_INVALID: { 578 break; 579 } 580 case ppapi::SocketOptionData::TYPE_BOOL: { 581 bool out_value = false; 582 bool result = p.GetBool(&out_value); 583 // Suppress unused variable warnings. 584 static_cast<void>(result); 585 DCHECK(result); 586 587 ParamTraits<bool>::Write(m, out_value); 588 break; 589 } 590 case ppapi::SocketOptionData::TYPE_INT32: { 591 int32_t out_value = 0; 592 bool result = p.GetInt32(&out_value); 593 // Suppress unused variable warnings. 594 static_cast<void>(result); 595 DCHECK(result); 596 597 ParamTraits<int32_t>::Write(m, out_value); 598 break; 599 } 600 // No default so the compiler will warn on new types. 601 } 602 } 603 604 // static 605 bool ParamTraits<ppapi::SocketOptionData>::Read(const Message* m, 606 PickleIterator* iter, 607 param_type* r) { 608 *r = ppapi::SocketOptionData(); 609 int32_t type = 0; 610 if (!ParamTraits<int32_t>::Read(m, iter, &type)) 611 return false; 612 if (type != ppapi::SocketOptionData::TYPE_INVALID && 613 type != ppapi::SocketOptionData::TYPE_BOOL && 614 type != ppapi::SocketOptionData::TYPE_INT32) { 615 return false; 616 } 617 switch (static_cast<ppapi::SocketOptionData::Type>(type)) { 618 case ppapi::SocketOptionData::TYPE_INVALID: { 619 return true; 620 } 621 case ppapi::SocketOptionData::TYPE_BOOL: { 622 bool value = false; 623 if (!ParamTraits<bool>::Read(m, iter, &value)) 624 return false; 625 r->SetBool(value); 626 return true; 627 } 628 case ppapi::SocketOptionData::TYPE_INT32: { 629 int32_t value = 0; 630 if (!ParamTraits<int32_t>::Read(m, iter, &value)) 631 return false; 632 r->SetInt32(value); 633 return true; 634 } 635 // No default so the compiler will warn on new types. 636 } 637 return false; 638 } 639 640 // static 641 void ParamTraits<ppapi::SocketOptionData>::Log(const param_type& p, 642 std::string* l) { 643 } 644 645 } // namespace IPC 646