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::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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)296 void ParamTraits<ppapi::proxy::SerializedHandle>::Log(const param_type& p,
297 std::string* l) {
298 }
299
300 // PPBURLLoader_UpdateProgress_Params ------------------------------------------
301
302 // static
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)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
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)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
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)412 void ParamTraits<ppapi::proxy::SerializedDirEntry>::Log(const param_type& p,
413 std::string* l) {
414 }
415
416 // ppapi::proxy::SerializedFontDescription -------------------------------------
417
418 // static
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)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
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)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
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * p)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
Log(const param_type & p,std::string * l)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
Write(Message * m,const param_type & p)529 void ParamTraits<ppapi::proxy::SerializedFlashMenu>::Write(
530 Message* m,
531 const param_type& p) {
532 p.WriteToMessage(m);
533 }
534
535 // static
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)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
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)565 void ParamTraits<ppapi::PPB_X509Certificate_Fields>::Log(const param_type& p,
566 std::string* l) {
567 }
568
569 // ppapi::SocketOptionData -----------------------------------------------------
570
571 // static
Write(Message * m,const param_type & p)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
Read(const Message * m,PickleIterator * iter,param_type * r)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
Log(const param_type & p,std::string * l)641 void ParamTraits<ppapi::SocketOptionData>::Log(const param_type& p,
642 std::string* l) {
643 }
644
645 } // namespace IPC
646