• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
ReadVectorWithoutCopy(const Message * m,PickleIterator * iter,std::vector<T> * output)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>
WriteVectorWithoutCopy(Message * m,const std::vector<T> & p)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
Write(Message * m,const param_type & p)78 void ParamTraits<PP_Bool>::Write(Message* m, const param_type& p) {
79   ParamTraits<bool>::Write(m, PP_ToBool(p));
80 }
81 
82 // static
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)97 void ParamTraits<PP_Bool>::Log(const param_type& p, std::string* l) {
98 }
99 
100 // PP_NetAddress_Private -------------------------------------------------------
101 
102 // static
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * p)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
Log(const param_type & p,std::string * l)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
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)158 void ParamTraits<ppapi::HostResource>::Log(const param_type& p,
159                                            std::string* l) {
160 }
161 
162 // SerializedVar ---------------------------------------------------------------
163 
164 // static
Write(Message * m,const param_type & p)165 void ParamTraits<ppapi::proxy::SerializedVar>::Write(Message* m,
166                                                      const param_type& p) {
167   p.WriteToMessage(m);
168 }
169 
170 // static
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)178 void ParamTraits<ppapi::proxy::SerializedVar>::Log(const param_type& p,
179                                                    std::string* l) {
180 }
181 
182 // std::vector<SerializedVar> --------------------------------------------------
183 
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)199 void ParamTraits< std::vector<ppapi::proxy::SerializedVar> >::Log(
200     const param_type& p,
201     std::string* l) {
202 }
203 
204 // ppapi::PpapiPermissions -----------------------------------------------------
205 
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)223 void ParamTraits<ppapi::PpapiPermissions>::Log(const param_type& p,
224                                                std::string* l) {
225 }
226 
227 // SerializedHandle ------------------------------------------------------------
228 
229 // static
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)287 void ParamTraits<ppapi::proxy::SerializedHandle>::Log(const param_type& p,
288                                                       std::string* l) {
289 }
290 
291 // PPBURLLoader_UpdateProgress_Params ------------------------------------------
292 
293 // static
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)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
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)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
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)403 void ParamTraits<ppapi::proxy::SerializedDirEntry>::Log(const param_type& p,
404                                                         std::string* l) {
405 }
406 
407 // ppapi::proxy::SerializedFontDescription -------------------------------------
408 
409 // static
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)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
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)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
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * p)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
Log(const param_type & p,std::string * l)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
Write(Message * m,const param_type & p)520 void ParamTraits<ppapi::proxy::SerializedFlashMenu>::Write(
521     Message* m,
522     const param_type& p) {
523   p.WriteToMessage(m);
524 }
525 
526 // static
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)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
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)556 void ParamTraits<ppapi::PPB_X509Certificate_Fields>::Log(const param_type& p,
557                                                          std::string* l) {
558 }
559 
560 // ppapi::SocketOptionData -----------------------------------------------------
561 
562 // static
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)632 void ParamTraits<ppapi::SocketOptionData>::Log(const param_type& p,
633                                                std::string* l) {
634 }
635 
636 // ppapi::CompositorLayerData --------------------------------------------------
637 
638 // static
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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 
Log(const param_type & p,std::string * l)658 void ParamTraits<ppapi::CompositorLayerData::Transform>::Log(
659     const param_type& p,
660     std::string* l) {
661 }
662 
663 }  // namespace IPC
664