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