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_file_info.h"
10#include "ppapi/c/pp_resource.h"
11#include "ppapi/proxy/ppapi_messages.h"
12#include "ppapi/proxy/serialized_var.h"
13#include "ppapi/proxy/serialized_flash_menu.h"
14#include "ppapi/shared_impl/host_resource.h"
15#include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h"
16
17namespace IPC {
18
19namespace {
20
21// Deserializes a vector from IPC. This special version must be used instead
22// of the default IPC version when the vector contains a SerializedVar, either
23// directly or indirectly (i.e. a vector of objects that have a SerializedVar
24// inside them).
25//
26// The default vector deserializer does resize and then we deserialize into
27// those allocated slots. However, the implementation of vector (at least in
28// GCC's implementation), creates a new empty object using the default
29// constructor, and then sets the rest of the items to that empty one using the
30// copy constructor.
31//
32// Since we allocate the inner class when you call the default constructor and
33// transfer the inner class when you do operator=, the entire vector will end
34// up referring to the same inner class. Deserializing into this will just end
35// up overwriting the same item over and over, since all the SerializedVars
36// will refer to the same thing.
37//
38// The solution is to make a new object for each deserialized item, and then
39// add it to the vector one at a time.
40template<typename T>
41bool ReadVectorWithoutCopy(const Message* m,
42                           PickleIterator* iter,
43                           std::vector<T>* output) {
44  // This part is just a copy of the the default ParamTraits vector Read().
45  int size;
46  // ReadLength() checks for < 0 itself.
47  if (!m->ReadLength(iter, &size))
48    return false;
49  // Resizing beforehand is not safe, see BUG 1006367 for details.
50  if (INT_MAX / sizeof(T) <= static_cast<size_t>(size))
51    return false;
52
53  output->reserve(size);
54  for (int i = 0; i < size; i++) {
55    T cur;
56    if (!ReadParam(m, iter, &cur))
57      return false;
58    output->push_back(cur);
59  }
60  return true;
61}
62
63// This serializes the vector of items to the IPC message in exactly the same
64// way as the "regular" IPC vector serializer does. But having the code here
65// saves us from having to copy this code into all ParamTraits that use the
66// ReadVectorWithoutCopy function for deserializing.
67template<typename T>
68void WriteVectorWithoutCopy(Message* m, const std::vector<T>& p) {
69  WriteParam(m, static_cast<int>(p.size()));
70  for (size_t i = 0; i < p.size(); i++)
71    WriteParam(m, p[i]);
72}
73
74}  // namespace
75
76// PP_Bool ---------------------------------------------------------------------
77
78// static
79void ParamTraits<PP_Bool>::Write(Message* m, const param_type& p) {
80  ParamTraits<bool>::Write(m, PP_ToBool(p));
81}
82
83// static
84bool ParamTraits<PP_Bool>::Read(const Message* m,
85                                PickleIterator* iter,
86                                param_type* r) {
87  // We specifically want to be strict here about what types of input we accept,
88  // which ParamTraits<bool> does for us. We don't want to deserialize "2" into
89  // a PP_Bool, for example.
90  bool result = false;
91  if (!ParamTraits<bool>::Read(m, iter, &result))
92    return false;
93  *r = PP_FromBool(result);
94  return true;
95}
96
97// static
98void ParamTraits<PP_Bool>::Log(const param_type& p, std::string* l) {
99}
100
101// PP_FileInfo -------------------------------------------------------------
102
103// static
104void ParamTraits<PP_FileInfo>::Write(Message* m, const param_type& p) {
105  ParamTraits<int64_t>::Write(m, p.size);
106  ParamTraits<int>::Write(m, static_cast<int>(p.type));
107  ParamTraits<int>::Write(m, static_cast<int>(p.system_type));
108  ParamTraits<double>::Write(m, p.creation_time);
109  ParamTraits<double>::Write(m, p.last_access_time);
110  ParamTraits<double>::Write(m, p.last_modified_time);
111}
112
113// static
114bool ParamTraits<PP_FileInfo>::Read(const Message* m, PickleIterator* iter,
115                                        param_type* r) {
116  int type, system_type;
117  if (!ParamTraits<int64_t>::Read(m, iter, &r->size) ||
118      !ParamTraits<int>::Read(m, iter, &type) ||
119      !ParamTraits<int>::Read(m, iter, &system_type) ||
120      !ParamTraits<double>::Read(m, iter, &r->creation_time) ||
121      !ParamTraits<double>::Read(m, iter, &r->last_access_time) ||
122      !ParamTraits<double>::Read(m, iter, &r->last_modified_time))
123    return false;
124  if (type != PP_FILETYPE_REGULAR &&
125      type != PP_FILETYPE_DIRECTORY &&
126      type != PP_FILETYPE_OTHER)
127    return false;
128  r->type = static_cast<PP_FileType>(type);
129  if (system_type != PP_FILESYSTEMTYPE_INVALID &&
130      system_type != PP_FILESYSTEMTYPE_EXTERNAL &&
131      system_type != PP_FILESYSTEMTYPE_LOCALPERSISTENT &&
132      system_type != PP_FILESYSTEMTYPE_LOCALTEMPORARY &&
133      system_type != PP_FILESYSTEMTYPE_ISOLATED)
134    return false;
135  r->system_type = static_cast<PP_FileSystemType>(system_type);
136  return true;
137}
138
139// static
140void ParamTraits<PP_FileInfo>::Log(const param_type& p, std::string* l) {
141}
142
143// PP_NetAddress_Private -------------------------------------------------------
144
145// static
146void ParamTraits<PP_NetAddress_Private>::Write(Message* m,
147                                               const param_type& p) {
148  WriteParam(m, p.size);
149  m->WriteBytes(p.data, static_cast<int>(p.size));
150}
151
152// static
153bool ParamTraits<PP_NetAddress_Private>::Read(const Message* m,
154                                              PickleIterator* iter,
155                                              param_type* p) {
156  uint16 size;
157  if (!ReadParam(m, iter, &size))
158    return false;
159  if (size > sizeof(p->data))
160    return false;
161  p->size = size;
162
163  const char* data;
164  if (!m->ReadBytes(iter, &data, size))
165    return false;
166  memcpy(p->data, data, size);
167  return true;
168}
169
170// static
171void ParamTraits<PP_NetAddress_Private>::Log(const param_type& p,
172                                             std::string* l) {
173  l->append("<PP_NetAddress_Private (");
174  LogParam(p.size, l);
175  l->append(" bytes)>");
176}
177
178// TODO(teravest): Remove this when FileRef is moved to the "new" proxy.
179// PPB_FileRef_CreateInfo ------------------------------------------------------
180
181// static
182void ParamTraits<ppapi::PPB_FileRef_CreateInfo>::Write(Message* m,
183                                                       const param_type& p) {
184  ParamTraits<ppapi::HostResource>::Write(m, p.resource);
185  ParamTraits<int>::Write(m, p.file_system_type);
186  ParamTraits<std::string>::Write(m, p.path);
187  ParamTraits<std::string>::Write(m, p.name);
188  ParamTraits<PP_Resource>::Write(m, p.file_system_plugin_resource);
189}
190
191// static
192bool ParamTraits<ppapi::PPB_FileRef_CreateInfo>::Read(const Message* m,
193                                                      PickleIterator* iter,
194                                                      param_type* r) {
195  return
196      ParamTraits<ppapi::HostResource>::Read(m, iter, &r->resource) &&
197      ParamTraits<int>::Read(m, iter, &r->file_system_type) &&
198      ParamTraits<std::string>::Read(m, iter, &r->path) &&
199      ParamTraits<std::string>::Read(m, iter, &r->name) &&
200      ParamTraits<PP_Resource>::Read(m, iter, &r->file_system_plugin_resource);
201}
202
203// static
204void ParamTraits<ppapi::PPB_FileRef_CreateInfo>::Log(const param_type& p,
205                                                     std::string* l) {
206}
207
208// HostResource ----------------------------------------------------------------
209
210// static
211void ParamTraits<ppapi::HostResource>::Write(Message* m,
212                                             const param_type& p) {
213  ParamTraits<PP_Instance>::Write(m, p.instance());
214  ParamTraits<PP_Resource>::Write(m, p.host_resource());
215}
216
217// static
218bool ParamTraits<ppapi::HostResource>::Read(const Message* m,
219                                            PickleIterator* iter,
220                                            param_type* r) {
221  PP_Instance instance;
222  PP_Resource resource;
223  if (!ParamTraits<PP_Instance>::Read(m, iter, &instance) ||
224      !ParamTraits<PP_Resource>::Read(m, iter, &resource))
225    return false;
226  r->SetHostResource(instance, resource);
227  return true;
228}
229
230// static
231void ParamTraits<ppapi::HostResource>::Log(const param_type& p,
232                                           std::string* l) {
233}
234
235// SerializedVar ---------------------------------------------------------------
236
237// static
238void ParamTraits<ppapi::proxy::SerializedVar>::Write(Message* m,
239                                                     const param_type& p) {
240  p.WriteToMessage(m);
241}
242
243// static
244bool ParamTraits<ppapi::proxy::SerializedVar>::Read(const Message* m,
245                                                    PickleIterator* iter,
246                                                    param_type* r) {
247  return r->ReadFromMessage(m, iter);
248}
249
250// static
251void ParamTraits<ppapi::proxy::SerializedVar>::Log(const param_type& p,
252                                                   std::string* l) {
253}
254
255// std::vector<SerializedVar> --------------------------------------------------
256
257void ParamTraits< std::vector<ppapi::proxy::SerializedVar> >::Write(
258    Message* m,
259    const param_type& p) {
260  WriteVectorWithoutCopy(m, p);
261}
262
263// static
264bool ParamTraits< std::vector<ppapi::proxy::SerializedVar> >::Read(
265    const Message* m,
266    PickleIterator* iter,
267    param_type* r) {
268  return ReadVectorWithoutCopy(m, iter, r);
269}
270
271// static
272void ParamTraits< std::vector<ppapi::proxy::SerializedVar> >::Log(
273    const param_type& p,
274    std::string* l) {
275}
276
277// std::vector<PPB_FileRef_CreateInfo> -----------------------------------------
278
279void ParamTraits< std::vector<ppapi::PPB_FileRef_CreateInfo> >::Write(
280    Message* m,
281    const param_type& p) {
282  WriteVectorWithoutCopy(m, p);
283}
284
285// static
286bool ParamTraits< std::vector<ppapi::PPB_FileRef_CreateInfo> >::Read(
287    const Message* m,
288    PickleIterator* iter,
289    param_type* r) {
290  return ReadVectorWithoutCopy(m, iter, r);
291}
292
293// static
294void ParamTraits< std::vector<ppapi::PPB_FileRef_CreateInfo> >::Log(
295    const param_type& p,
296    std::string* l) {
297}
298
299// ppapi::PpapiPermissions -----------------------------------------------------
300
301void ParamTraits<ppapi::PpapiPermissions>::Write(Message* m,
302                                                 const param_type& p) {
303  ParamTraits<uint32_t>::Write(m, p.GetBits());
304}
305
306// static
307bool ParamTraits<ppapi::PpapiPermissions>::Read(const Message* m,
308                                                PickleIterator* iter,
309                                                param_type* r) {
310  uint32_t bits;
311  if (!ParamTraits<uint32_t>::Read(m, iter, &bits))
312    return false;
313  *r = ppapi::PpapiPermissions(bits);
314  return true;
315}
316
317// static
318void ParamTraits<ppapi::PpapiPermissions>::Log(const param_type& p,
319                                               std::string* l) {
320}
321
322// SerializedHandle ------------------------------------------------------------
323
324// static
325void ParamTraits<ppapi::proxy::SerializedHandle>::Write(Message* m,
326                                                        const param_type& p) {
327  ppapi::proxy::SerializedHandle::WriteHeader(p.header(), m);
328  switch (p.type()) {
329    case ppapi::proxy::SerializedHandle::SHARED_MEMORY:
330      ParamTraits<base::SharedMemoryHandle>::Write(m, p.shmem());
331      break;
332    case ppapi::proxy::SerializedHandle::SOCKET:
333    case ppapi::proxy::SerializedHandle::CHANNEL_HANDLE:
334    case ppapi::proxy::SerializedHandle::FILE:
335      ParamTraits<IPC::PlatformFileForTransit>::Write(m, p.descriptor());
336      break;
337    case ppapi::proxy::SerializedHandle::INVALID:
338      break;
339    // No default so the compiler will warn on new types.
340  }
341}
342
343// static
344bool ParamTraits<ppapi::proxy::SerializedHandle>::Read(const Message* m,
345                                                       PickleIterator* iter,
346                                                       param_type* r) {
347  ppapi::proxy::SerializedHandle::Header header;
348  if (!ppapi::proxy::SerializedHandle::ReadHeader(iter, &header))
349    return false;
350  switch (header.type) {
351    case ppapi::proxy::SerializedHandle::SHARED_MEMORY: {
352      base::SharedMemoryHandle handle;
353      if (ParamTraits<base::SharedMemoryHandle>::Read(m, iter, &handle)) {
354        r->set_shmem(handle, header.size);
355        return true;
356      }
357      break;
358    }
359    case ppapi::proxy::SerializedHandle::SOCKET: {
360      IPC::PlatformFileForTransit socket;
361      if (ParamTraits<IPC::PlatformFileForTransit>::Read(m, iter, &socket)) {
362        r->set_socket(socket);
363        return true;
364      }
365      break;
366    }
367    case ppapi::proxy::SerializedHandle::CHANNEL_HANDLE: {
368      IPC::PlatformFileForTransit desc;
369      if (ParamTraits<IPC::PlatformFileForTransit>::Read(m, iter, &desc)) {
370        r->set_channel_handle(desc);
371        return true;
372      }
373      break;
374    }
375    case ppapi::proxy::SerializedHandle::FILE: {
376      IPC::PlatformFileForTransit desc;
377      if (ParamTraits<IPC::PlatformFileForTransit>::Read(m, iter, &desc)) {
378        r->set_file_handle(desc, header.open_flag);
379        return true;
380      }
381      break;
382    }
383    case ppapi::proxy::SerializedHandle::INVALID:
384      return true;
385    // No default so the compiler will warn us if a new type is added.
386  }
387  return false;
388}
389
390// static
391void ParamTraits<ppapi::proxy::SerializedHandle>::Log(const param_type& p,
392                                                      std::string* l) {
393}
394
395// PPBURLLoader_UpdateProgress_Params ------------------------------------------
396
397// static
398void ParamTraits<ppapi::proxy::PPBURLLoader_UpdateProgress_Params>::Write(
399    Message* m,
400    const param_type& p) {
401  ParamTraits<PP_Instance>::Write(m, p.instance);
402  ParamTraits<ppapi::HostResource>::Write(m, p.resource);
403  ParamTraits<int64_t>::Write(m, p.bytes_sent);
404  ParamTraits<int64_t>::Write(m, p.total_bytes_to_be_sent);
405  ParamTraits<int64_t>::Write(m, p.bytes_received);
406  ParamTraits<int64_t>::Write(m, p.total_bytes_to_be_received);
407}
408
409// static
410bool ParamTraits<ppapi::proxy::PPBURLLoader_UpdateProgress_Params>::Read(
411    const Message* m,
412    PickleIterator* iter,
413    param_type* r) {
414  return
415      ParamTraits<PP_Instance>::Read(m, iter, &r->instance) &&
416      ParamTraits<ppapi::HostResource>::Read(m, iter, &r->resource) &&
417      ParamTraits<int64_t>::Read(m, iter, &r->bytes_sent) &&
418      ParamTraits<int64_t>::Read(m, iter, &r->total_bytes_to_be_sent) &&
419      ParamTraits<int64_t>::Read(m, iter, &r->bytes_received) &&
420      ParamTraits<int64_t>::Read(m, iter, &r->total_bytes_to_be_received);
421}
422
423// static
424void ParamTraits<ppapi::proxy::PPBURLLoader_UpdateProgress_Params>::Log(
425    const param_type& p,
426    std::string* l) {
427}
428
429#if !defined(OS_NACL) && !defined(NACL_WIN64)
430// PPBFlash_DrawGlyphs_Params --------------------------------------------------
431// static
432void ParamTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params>::Write(
433    Message* m,
434    const param_type& p) {
435  ParamTraits<PP_Instance>::Write(m, p.instance);
436  ParamTraits<ppapi::HostResource>::Write(m, p.image_data);
437  ParamTraits<ppapi::proxy::SerializedFontDescription>::Write(m, p.font_desc);
438  ParamTraits<uint32_t>::Write(m, p.color);
439  ParamTraits<PP_Point>::Write(m, p.position);
440  ParamTraits<PP_Rect>::Write(m, p.clip);
441  ParamTraits<float>::Write(m, p.transformation[0][0]);
442  ParamTraits<float>::Write(m, p.transformation[0][1]);
443  ParamTraits<float>::Write(m, p.transformation[0][2]);
444  ParamTraits<float>::Write(m, p.transformation[1][0]);
445  ParamTraits<float>::Write(m, p.transformation[1][1]);
446  ParamTraits<float>::Write(m, p.transformation[1][2]);
447  ParamTraits<float>::Write(m, p.transformation[2][0]);
448  ParamTraits<float>::Write(m, p.transformation[2][1]);
449  ParamTraits<float>::Write(m, p.transformation[2][2]);
450  ParamTraits<PP_Bool>::Write(m, p.allow_subpixel_aa);
451  ParamTraits<std::vector<uint16_t> >::Write(m, p.glyph_indices);
452  ParamTraits<std::vector<PP_Point> >::Write(m, p.glyph_advances);
453}
454
455// static
456bool ParamTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params>::Read(
457    const Message* m,
458    PickleIterator* iter,
459    param_type* r) {
460  return
461      ParamTraits<PP_Instance>::Read(m, iter, &r->instance) &&
462      ParamTraits<ppapi::HostResource>::Read(m, iter, &r->image_data) &&
463      ParamTraits<ppapi::proxy::SerializedFontDescription>::Read(m, iter,
464                                                              &r->font_desc) &&
465      ParamTraits<uint32_t>::Read(m, iter, &r->color) &&
466      ParamTraits<PP_Point>::Read(m, iter, &r->position) &&
467      ParamTraits<PP_Rect>::Read(m, iter, &r->clip) &&
468      ParamTraits<float>::Read(m, iter, &r->transformation[0][0]) &&
469      ParamTraits<float>::Read(m, iter, &r->transformation[0][1]) &&
470      ParamTraits<float>::Read(m, iter, &r->transformation[0][2]) &&
471      ParamTraits<float>::Read(m, iter, &r->transformation[1][0]) &&
472      ParamTraits<float>::Read(m, iter, &r->transformation[1][1]) &&
473      ParamTraits<float>::Read(m, iter, &r->transformation[1][2]) &&
474      ParamTraits<float>::Read(m, iter, &r->transformation[2][0]) &&
475      ParamTraits<float>::Read(m, iter, &r->transformation[2][1]) &&
476      ParamTraits<float>::Read(m, iter, &r->transformation[2][2]) &&
477      ParamTraits<PP_Bool>::Read(m, iter, &r->allow_subpixel_aa) &&
478      ParamTraits<std::vector<uint16_t> >::Read(m, iter, &r->glyph_indices) &&
479      ParamTraits<std::vector<PP_Point> >::Read(m, iter, &r->glyph_advances) &&
480      r->glyph_indices.size() == r->glyph_advances.size();
481}
482
483// static
484void ParamTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params>::Log(
485    const param_type& p,
486    std::string* l) {
487}
488
489// SerializedDirEntry ----------------------------------------------------------
490
491// static
492void ParamTraits<ppapi::proxy::SerializedDirEntry>::Write(Message* m,
493                                                          const param_type& p) {
494  ParamTraits<std::string>::Write(m, p.name);
495  ParamTraits<bool>::Write(m, p.is_dir);
496}
497
498// static
499bool ParamTraits<ppapi::proxy::SerializedDirEntry>::Read(const Message* m,
500                                                         PickleIterator* iter,
501                                                         param_type* r) {
502  return ParamTraits<std::string>::Read(m, iter, &r->name) &&
503         ParamTraits<bool>::Read(m, iter, &r->is_dir);
504}
505
506// static
507void ParamTraits<ppapi::proxy::SerializedDirEntry>::Log(const param_type& p,
508                                                        std::string* l) {
509}
510
511// ppapi::proxy::SerializedFontDescription -------------------------------------
512
513// static
514void ParamTraits<ppapi::proxy::SerializedFontDescription>::Write(
515    Message* m,
516    const param_type& p) {
517  ParamTraits<std::string>::Write(m, p.face);
518  ParamTraits<int32_t>::Write(m, p.family);
519  ParamTraits<uint32_t>::Write(m, p.size);
520  ParamTraits<int32_t>::Write(m, p.weight);
521  ParamTraits<PP_Bool>::Write(m, p.italic);
522  ParamTraits<PP_Bool>::Write(m, p.small_caps);
523  ParamTraits<int32_t>::Write(m, p.letter_spacing);
524  ParamTraits<int32_t>::Write(m, p.word_spacing);
525}
526
527// static
528bool ParamTraits<ppapi::proxy::SerializedFontDescription>::Read(
529    const Message* m,
530    PickleIterator* iter,
531    param_type* r) {
532  return
533      ParamTraits<std::string>::Read(m, iter, &r->face) &&
534      ParamTraits<int32_t>::Read(m, iter, &r->family) &&
535      ParamTraits<uint32_t>::Read(m, iter, &r->size) &&
536      ParamTraits<int32_t>::Read(m, iter, &r->weight) &&
537      ParamTraits<PP_Bool>::Read(m, iter, &r->italic) &&
538      ParamTraits<PP_Bool>::Read(m, iter, &r->small_caps) &&
539      ParamTraits<int32_t>::Read(m, iter, &r->letter_spacing) &&
540      ParamTraits<int32_t>::Read(m, iter, &r->word_spacing);
541}
542
543// static
544void ParamTraits<ppapi::proxy::SerializedFontDescription>::Log(
545    const param_type& p,
546    std::string* l) {
547}
548#endif  // !defined(OS_NACL) && !defined(NACL_WIN64)
549
550// ppapi::proxy::SerializedTrueTypeFontDesc ------------------------------------
551
552// static
553void ParamTraits<ppapi::proxy::SerializedTrueTypeFontDesc>::Write(
554    Message* m,
555    const param_type& p) {
556  ParamTraits<std::string>::Write(m, p.family);
557  ParamTraits<PP_TrueTypeFontFamily_Dev>::Write(m, p.generic_family);
558  ParamTraits<PP_TrueTypeFontStyle_Dev>::Write(m, p.style);
559  ParamTraits<PP_TrueTypeFontWeight_Dev>::Write(m, p.weight);
560  ParamTraits<PP_TrueTypeFontWidth_Dev>::Write(m, p.width);
561  ParamTraits<PP_TrueTypeFontCharset_Dev>::Write(m, p.charset);
562}
563
564// static
565bool ParamTraits<ppapi::proxy::SerializedTrueTypeFontDesc>::Read(
566    const Message* m,
567    PickleIterator* iter,
568    param_type* r) {
569  return
570      ParamTraits<std::string>::Read(m, iter, &r->family) &&
571      ParamTraits<PP_TrueTypeFontFamily_Dev>::Read(m, iter,
572                                                   &r->generic_family) &&
573      ParamTraits<PP_TrueTypeFontStyle_Dev>::Read(m, iter, &r->style) &&
574      ParamTraits<PP_TrueTypeFontWeight_Dev>::Read(m, iter, &r->weight) &&
575      ParamTraits<PP_TrueTypeFontWidth_Dev>::Read(m, iter, &r->width) &&
576      ParamTraits<PP_TrueTypeFontCharset_Dev>::Read(m, iter, &r->charset);
577}
578
579// static
580void ParamTraits<ppapi::proxy::SerializedTrueTypeFontDesc>::Log(
581    const param_type& p,
582    std::string* l) {
583}
584
585#if !defined(OS_NACL) && !defined(NACL_WIN64)
586// ppapi::PepperFilePath -------------------------------------------------------
587
588// static
589void ParamTraits<ppapi::PepperFilePath>::Write(Message* m,
590                                               const param_type& p) {
591  WriteParam(m, static_cast<unsigned>(p.domain()));
592  WriteParam(m, p.path());
593}
594
595// static
596bool ParamTraits<ppapi::PepperFilePath>::Read(const Message* m,
597                                              PickleIterator* iter,
598                                              param_type* p) {
599  unsigned domain;
600  base::FilePath path;
601  if (!ReadParam(m, iter, &domain) || !ReadParam(m, iter, &path))
602    return false;
603  if (domain > ppapi::PepperFilePath::DOMAIN_MAX_VALID)
604    return false;
605
606  *p = ppapi::PepperFilePath(
607      static_cast<ppapi::PepperFilePath::Domain>(domain), path);
608  return true;
609}
610
611// static
612void ParamTraits<ppapi::PepperFilePath>::Log(const param_type& p,
613                                             std::string* l) {
614  l->append("(");
615  LogParam(static_cast<unsigned>(p.domain()), l);
616  l->append(", ");
617  LogParam(p.path(), l);
618  l->append(")");
619}
620
621// SerializedFlashMenu ---------------------------------------------------------
622
623// static
624void ParamTraits<ppapi::proxy::SerializedFlashMenu>::Write(
625    Message* m,
626    const param_type& p) {
627  p.WriteToMessage(m);
628}
629
630// static
631bool ParamTraits<ppapi::proxy::SerializedFlashMenu>::Read(const Message* m,
632                                                          PickleIterator* iter,
633                                                          param_type* r) {
634  return r->ReadFromMessage(m, iter);
635}
636
637// static
638void ParamTraits<ppapi::proxy::SerializedFlashMenu>::Log(const param_type& p,
639                                                         std::string* l) {
640}
641#endif  // !defined(OS_NACL) && !defined(NACL_WIN64)
642
643// PPB_X509Certificate_Fields --------------------------------------------------
644
645// static
646void ParamTraits<ppapi::PPB_X509Certificate_Fields>::Write(
647    Message* m,
648    const param_type& p) {
649  ParamTraits<base::ListValue>::Write(m, p.values_);
650}
651
652// static
653bool ParamTraits<ppapi::PPB_X509Certificate_Fields>::Read(const Message* m,
654                                                          PickleIterator* iter,
655                                                          param_type* r) {
656  return ParamTraits<base::ListValue>::Read(m, iter, &(r->values_));
657}
658
659// static
660void ParamTraits<ppapi::PPB_X509Certificate_Fields>::Log(const param_type& p,
661                                                         std::string* l) {
662}
663
664// ppapi::SocketOptionData -----------------------------------------------------
665
666// static
667void ParamTraits<ppapi::SocketOptionData>::Write(Message* m,
668                                                 const param_type& p) {
669  ppapi::SocketOptionData::Type type = p.GetType();
670  ParamTraits<int32_t>::Write(m, static_cast<int32_t>(type));
671  switch (type) {
672    case ppapi::SocketOptionData::TYPE_INVALID: {
673      break;
674    }
675    case ppapi::SocketOptionData::TYPE_BOOL: {
676      bool out_value = false;
677      bool result = p.GetBool(&out_value);
678      // Suppress unused variable warnings.
679      static_cast<void>(result);
680      DCHECK(result);
681
682      ParamTraits<bool>::Write(m, out_value);
683      break;
684    }
685    case ppapi::SocketOptionData::TYPE_INT32: {
686      int32_t out_value = 0;
687      bool result = p.GetInt32(&out_value);
688      // Suppress unused variable warnings.
689      static_cast<void>(result);
690      DCHECK(result);
691
692      ParamTraits<int32_t>::Write(m, out_value);
693      break;
694    }
695    // No default so the compiler will warn on new types.
696  }
697}
698
699// static
700bool ParamTraits<ppapi::SocketOptionData>::Read(const Message* m,
701                                                PickleIterator* iter,
702                                                param_type* r) {
703  *r = ppapi::SocketOptionData();
704  int32_t type = 0;
705  if (!ParamTraits<int32_t>::Read(m, iter, &type))
706    return false;
707  if (type != ppapi::SocketOptionData::TYPE_INVALID &&
708      type != ppapi::SocketOptionData::TYPE_BOOL &&
709      type != ppapi::SocketOptionData::TYPE_INT32) {
710    return false;
711  }
712  switch (static_cast<ppapi::SocketOptionData::Type>(type)) {
713    case ppapi::SocketOptionData::TYPE_INVALID: {
714      return true;
715    }
716    case ppapi::SocketOptionData::TYPE_BOOL: {
717      bool value = false;
718      if (!ParamTraits<bool>::Read(m, iter, &value))
719        return false;
720      r->SetBool(value);
721      return true;
722    }
723    case ppapi::SocketOptionData::TYPE_INT32: {
724      int32_t value = 0;
725      if (!ParamTraits<int32_t>::Read(m, iter, &value))
726        return false;
727      r->SetInt32(value);
728      return true;
729    }
730    // No default so the compiler will warn on new types.
731  }
732  return false;
733}
734
735// static
736void ParamTraits<ppapi::SocketOptionData>::Log(const param_type& p,
737                                               std::string* l) {
738}
739
740}  // namespace IPC
741