Home | History | Annotate | Download | only in proxy
      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