ppapi_param_traits.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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    return false;
134  r->system_type = static_cast<PP_FileSystemType>(system_type);
135  return true;
136}
137
138// static
139void ParamTraits<PP_FileInfo>::Log(const param_type& p, std::string* l) {
140}
141
142// PP_NetAddress_Private -------------------------------------------------------
143
144// static
145void ParamTraits<PP_NetAddress_Private>::Write(Message* m,
146                                               const param_type& p) {
147  WriteParam(m, p.size);
148  m->WriteBytes(p.data, static_cast<int>(p.size));
149}
150
151// static
152bool ParamTraits<PP_NetAddress_Private>::Read(const Message* m,
153                                              PickleIterator* iter,
154                                              param_type* p) {
155  uint16 size;
156  if (!ReadParam(m, iter, &size))
157    return false;
158  if (size > sizeof(p->data))
159    return false;
160  p->size = size;
161
162  const char* data;
163  if (!m->ReadBytes(iter, &data, size))
164    return false;
165  memcpy(p->data, data, size);
166  return true;
167}
168
169// static
170void ParamTraits<PP_NetAddress_Private>::Log(const param_type& p,
171                                             std::string* l) {
172  l->append("<PP_NetAddress_Private (");
173  LogParam(p.size, l);
174  l->append(" bytes)>");
175}
176
177// PPB_FileRef_CreateInfo ------------------------------------------------------
178
179// static
180void ParamTraits<ppapi::PPB_FileRef_CreateInfo>::Write(Message* m,
181                                                       const param_type& p) {
182  ParamTraits<ppapi::HostResource>::Write(m, p.resource);
183  ParamTraits<int>::Write(m, p.file_system_type);
184  ParamTraits<std::string>::Write(m, p.path);
185  ParamTraits<std::string>::Write(m, p.name);
186  ParamTraits<PP_Resource>::Write(m, p.file_system_plugin_resource);
187}
188
189// static
190bool ParamTraits<ppapi::PPB_FileRef_CreateInfo>::Read(const Message* m,
191                                                      PickleIterator* iter,
192                                                      param_type* r) {
193  return
194      ParamTraits<ppapi::HostResource>::Read(m, iter, &r->resource) &&
195      ParamTraits<int>::Read(m, iter, &r->file_system_type) &&
196      ParamTraits<std::string>::Read(m, iter, &r->path) &&
197      ParamTraits<std::string>::Read(m, iter, &r->name) &&
198      ParamTraits<PP_Resource>::Read(m, iter, &r->file_system_plugin_resource);
199}
200
201// static
202void ParamTraits<ppapi::PPB_FileRef_CreateInfo>::Log(const param_type& p,
203                                                     std::string* l) {
204}
205
206// HostResource ----------------------------------------------------------------
207
208// static
209void ParamTraits<ppapi::HostResource>::Write(Message* m,
210                                             const param_type& p) {
211  ParamTraits<PP_Instance>::Write(m, p.instance());
212  ParamTraits<PP_Resource>::Write(m, p.host_resource());
213}
214
215// static
216bool ParamTraits<ppapi::HostResource>::Read(const Message* m,
217                                            PickleIterator* iter,
218                                            param_type* r) {
219  PP_Instance instance;
220  PP_Resource resource;
221  if (!ParamTraits<PP_Instance>::Read(m, iter, &instance) ||
222      !ParamTraits<PP_Resource>::Read(m, iter, &resource))
223    return false;
224  r->SetHostResource(instance, resource);
225  return true;
226}
227
228// static
229void ParamTraits<ppapi::HostResource>::Log(const param_type& p,
230                                           std::string* l) {
231}
232
233// SerializedVar ---------------------------------------------------------------
234
235// static
236void ParamTraits<ppapi::proxy::SerializedVar>::Write(Message* m,
237                                                     const param_type& p) {
238  p.WriteToMessage(m);
239}
240
241// static
242bool ParamTraits<ppapi::proxy::SerializedVar>::Read(const Message* m,
243                                                    PickleIterator* iter,
244                                                    param_type* r) {
245  return r->ReadFromMessage(m, iter);
246}
247
248// static
249void ParamTraits<ppapi::proxy::SerializedVar>::Log(const param_type& p,
250                                                   std::string* l) {
251}
252
253// std::vector<SerializedVar> --------------------------------------------------
254
255void ParamTraits< std::vector<ppapi::proxy::SerializedVar> >::Write(
256    Message* m,
257    const param_type& p) {
258  WriteVectorWithoutCopy(m, p);
259}
260
261// static
262bool ParamTraits< std::vector<ppapi::proxy::SerializedVar> >::Read(
263    const Message* m,
264    PickleIterator* iter,
265    param_type* r) {
266  return ReadVectorWithoutCopy(m, iter, r);
267}
268
269// static
270void ParamTraits< std::vector<ppapi::proxy::SerializedVar> >::Log(
271    const param_type& p,
272    std::string* l) {
273}
274
275// std::vector<PPB_FileRef_CreateInfo> -----------------------------------------
276
277void ParamTraits< std::vector<ppapi::PPB_FileRef_CreateInfo> >::Write(
278    Message* m,
279    const param_type& p) {
280  WriteVectorWithoutCopy(m, p);
281}
282
283// static
284bool ParamTraits< std::vector<ppapi::PPB_FileRef_CreateInfo> >::Read(
285    const Message* m,
286    PickleIterator* iter,
287    param_type* r) {
288  return ReadVectorWithoutCopy(m, iter, r);
289}
290
291// static
292void ParamTraits< std::vector<ppapi::PPB_FileRef_CreateInfo> >::Log(
293    const param_type& p,
294    std::string* l) {
295}
296
297// ppapi::PpapiPermissions -----------------------------------------------------
298
299void ParamTraits<ppapi::PpapiPermissions>::Write(Message* m,
300                                                 const param_type& p) {
301  ParamTraits<uint32_t>::Write(m, p.GetBits());
302}
303
304// static
305bool ParamTraits<ppapi::PpapiPermissions>::Read(const Message* m,
306                                                PickleIterator* iter,
307                                                param_type* r) {
308  uint32_t bits;
309  if (!ParamTraits<uint32_t>::Read(m, iter, &bits))
310    return false;
311  *r = ppapi::PpapiPermissions(bits);
312  return true;
313}
314
315// static
316void ParamTraits<ppapi::PpapiPermissions>::Log(const param_type& p,
317                                               std::string* l) {
318}
319
320// SerializedHandle ------------------------------------------------------------
321
322// static
323void ParamTraits<ppapi::proxy::SerializedHandle>::Write(Message* m,
324                                                        const param_type& p) {
325  ppapi::proxy::SerializedHandle::WriteHeader(p.header(), m);
326  switch (p.type()) {
327    case ppapi::proxy::SerializedHandle::SHARED_MEMORY:
328      ParamTraits<base::SharedMemoryHandle>::Write(m, p.shmem());
329      break;
330    case ppapi::proxy::SerializedHandle::SOCKET:
331    case ppapi::proxy::SerializedHandle::CHANNEL_HANDLE:
332    case ppapi::proxy::SerializedHandle::FILE:
333      ParamTraits<IPC::PlatformFileForTransit>::Write(m, p.descriptor());
334      break;
335    case ppapi::proxy::SerializedHandle::INVALID:
336      break;
337    // No default so the compiler will warn on new types.
338  }
339}
340
341// static
342bool ParamTraits<ppapi::proxy::SerializedHandle>::Read(const Message* m,
343                                                       PickleIterator* iter,
344                                                       param_type* r) {
345  ppapi::proxy::SerializedHandle::Header header;
346  if (!ppapi::proxy::SerializedHandle::ReadHeader(iter, &header))
347    return false;
348  switch (header.type) {
349    case ppapi::proxy::SerializedHandle::SHARED_MEMORY: {
350      base::SharedMemoryHandle handle;
351      if (ParamTraits<base::SharedMemoryHandle>::Read(m, iter, &handle)) {
352        r->set_shmem(handle, header.size);
353        return true;
354      }
355      break;
356    }
357    case ppapi::proxy::SerializedHandle::SOCKET: {
358      IPC::PlatformFileForTransit socket;
359      if (ParamTraits<IPC::PlatformFileForTransit>::Read(m, iter, &socket)) {
360        r->set_socket(socket);
361        return true;
362      }
363      break;
364    }
365    case ppapi::proxy::SerializedHandle::CHANNEL_HANDLE: {
366      IPC::PlatformFileForTransit desc;
367      if (ParamTraits<IPC::PlatformFileForTransit>::Read(m, iter, &desc)) {
368        r->set_channel_handle(desc);
369        return true;
370      }
371      break;
372    }
373    case ppapi::proxy::SerializedHandle::FILE: {
374      IPC::PlatformFileForTransit desc;
375      if (ParamTraits<IPC::PlatformFileForTransit>::Read(m, iter, &desc)) {
376        r->set_file_handle(desc);
377        return true;
378      }
379      break;
380    }
381    case ppapi::proxy::SerializedHandle::INVALID:
382      return true;
383    // No default so the compiler will warn us if a new type is added.
384  }
385  return false;
386}
387
388// static
389void ParamTraits<ppapi::proxy::SerializedHandle>::Log(const param_type& p,
390                                                      std::string* l) {
391}
392
393// PPBURLLoader_UpdateProgress_Params ------------------------------------------
394
395// static
396void ParamTraits<ppapi::proxy::PPBURLLoader_UpdateProgress_Params>::Write(
397    Message* m,
398    const param_type& p) {
399  ParamTraits<PP_Instance>::Write(m, p.instance);
400  ParamTraits<ppapi::HostResource>::Write(m, p.resource);
401  ParamTraits<int64_t>::Write(m, p.bytes_sent);
402  ParamTraits<int64_t>::Write(m, p.total_bytes_to_be_sent);
403  ParamTraits<int64_t>::Write(m, p.bytes_received);
404  ParamTraits<int64_t>::Write(m, p.total_bytes_to_be_received);
405}
406
407// static
408bool ParamTraits<ppapi::proxy::PPBURLLoader_UpdateProgress_Params>::Read(
409    const Message* m,
410    PickleIterator* iter,
411    param_type* r) {
412  return
413      ParamTraits<PP_Instance>::Read(m, iter, &r->instance) &&
414      ParamTraits<ppapi::HostResource>::Read(m, iter, &r->resource) &&
415      ParamTraits<int64_t>::Read(m, iter, &r->bytes_sent) &&
416      ParamTraits<int64_t>::Read(m, iter, &r->total_bytes_to_be_sent) &&
417      ParamTraits<int64_t>::Read(m, iter, &r->bytes_received) &&
418      ParamTraits<int64_t>::Read(m, iter, &r->total_bytes_to_be_received);
419}
420
421// static
422void ParamTraits<ppapi::proxy::PPBURLLoader_UpdateProgress_Params>::Log(
423    const param_type& p,
424    std::string* l) {
425}
426
427#if !defined(OS_NACL) && !defined(NACL_WIN64)
428// PPBFlash_DrawGlyphs_Params --------------------------------------------------
429// static
430void ParamTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params>::Write(
431    Message* m,
432    const param_type& p) {
433  ParamTraits<PP_Instance>::Write(m, p.instance);
434  ParamTraits<ppapi::HostResource>::Write(m, p.image_data);
435  ParamTraits<ppapi::proxy::SerializedFontDescription>::Write(m, p.font_desc);
436  ParamTraits<uint32_t>::Write(m, p.color);
437  ParamTraits<PP_Point>::Write(m, p.position);
438  ParamTraits<PP_Rect>::Write(m, p.clip);
439  ParamTraits<float>::Write(m, p.transformation[0][0]);
440  ParamTraits<float>::Write(m, p.transformation[0][1]);
441  ParamTraits<float>::Write(m, p.transformation[0][2]);
442  ParamTraits<float>::Write(m, p.transformation[1][0]);
443  ParamTraits<float>::Write(m, p.transformation[1][1]);
444  ParamTraits<float>::Write(m, p.transformation[1][2]);
445  ParamTraits<float>::Write(m, p.transformation[2][0]);
446  ParamTraits<float>::Write(m, p.transformation[2][1]);
447  ParamTraits<float>::Write(m, p.transformation[2][2]);
448  ParamTraits<PP_Bool>::Write(m, p.allow_subpixel_aa);
449  ParamTraits<std::vector<uint16_t> >::Write(m, p.glyph_indices);
450  ParamTraits<std::vector<PP_Point> >::Write(m, p.glyph_advances);
451}
452
453// static
454bool ParamTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params>::Read(
455    const Message* m,
456    PickleIterator* iter,
457    param_type* r) {
458  return
459      ParamTraits<PP_Instance>::Read(m, iter, &r->instance) &&
460      ParamTraits<ppapi::HostResource>::Read(m, iter, &r->image_data) &&
461      ParamTraits<ppapi::proxy::SerializedFontDescription>::Read(m, iter,
462                                                              &r->font_desc) &&
463      ParamTraits<uint32_t>::Read(m, iter, &r->color) &&
464      ParamTraits<PP_Point>::Read(m, iter, &r->position) &&
465      ParamTraits<PP_Rect>::Read(m, iter, &r->clip) &&
466      ParamTraits<float>::Read(m, iter, &r->transformation[0][0]) &&
467      ParamTraits<float>::Read(m, iter, &r->transformation[0][1]) &&
468      ParamTraits<float>::Read(m, iter, &r->transformation[0][2]) &&
469      ParamTraits<float>::Read(m, iter, &r->transformation[1][0]) &&
470      ParamTraits<float>::Read(m, iter, &r->transformation[1][1]) &&
471      ParamTraits<float>::Read(m, iter, &r->transformation[1][2]) &&
472      ParamTraits<float>::Read(m, iter, &r->transformation[2][0]) &&
473      ParamTraits<float>::Read(m, iter, &r->transformation[2][1]) &&
474      ParamTraits<float>::Read(m, iter, &r->transformation[2][2]) &&
475      ParamTraits<PP_Bool>::Read(m, iter, &r->allow_subpixel_aa) &&
476      ParamTraits<std::vector<uint16_t> >::Read(m, iter, &r->glyph_indices) &&
477      ParamTraits<std::vector<PP_Point> >::Read(m, iter, &r->glyph_advances) &&
478      r->glyph_indices.size() == r->glyph_advances.size();
479}
480
481// static
482void ParamTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params>::Log(
483    const param_type& p,
484    std::string* l) {
485}
486
487// SerializedDirEntry ----------------------------------------------------------
488
489// static
490void ParamTraits<ppapi::proxy::SerializedDirEntry>::Write(Message* m,
491                                                          const param_type& p) {
492  ParamTraits<std::string>::Write(m, p.name);
493  ParamTraits<bool>::Write(m, p.is_dir);
494}
495
496// static
497bool ParamTraits<ppapi::proxy::SerializedDirEntry>::Read(const Message* m,
498                                                         PickleIterator* iter,
499                                                         param_type* r) {
500  return ParamTraits<std::string>::Read(m, iter, &r->name) &&
501         ParamTraits<bool>::Read(m, iter, &r->is_dir);
502}
503
504// static
505void ParamTraits<ppapi::proxy::SerializedDirEntry>::Log(const param_type& p,
506                                                        std::string* l) {
507}
508
509// ppapi::proxy::SerializedFontDescription -------------------------------------
510
511// static
512void ParamTraits<ppapi::proxy::SerializedFontDescription>::Write(
513    Message* m,
514    const param_type& p) {
515  ParamTraits<std::string>::Write(m, p.face);
516  ParamTraits<int32_t>::Write(m, p.family);
517  ParamTraits<uint32_t>::Write(m, p.size);
518  ParamTraits<int32_t>::Write(m, p.weight);
519  ParamTraits<PP_Bool>::Write(m, p.italic);
520  ParamTraits<PP_Bool>::Write(m, p.small_caps);
521  ParamTraits<int32_t>::Write(m, p.letter_spacing);
522  ParamTraits<int32_t>::Write(m, p.word_spacing);
523}
524
525// static
526bool ParamTraits<ppapi::proxy::SerializedFontDescription>::Read(
527    const Message* m,
528    PickleIterator* iter,
529    param_type* r) {
530  return
531      ParamTraits<std::string>::Read(m, iter, &r->face) &&
532      ParamTraits<int32_t>::Read(m, iter, &r->family) &&
533      ParamTraits<uint32_t>::Read(m, iter, &r->size) &&
534      ParamTraits<int32_t>::Read(m, iter, &r->weight) &&
535      ParamTraits<PP_Bool>::Read(m, iter, &r->italic) &&
536      ParamTraits<PP_Bool>::Read(m, iter, &r->small_caps) &&
537      ParamTraits<int32_t>::Read(m, iter, &r->letter_spacing) &&
538      ParamTraits<int32_t>::Read(m, iter, &r->word_spacing);
539}
540
541// static
542void ParamTraits<ppapi::proxy::SerializedFontDescription>::Log(
543    const param_type& p,
544    std::string* l) {
545}
546#endif  // !defined(OS_NACL) && !defined(NACL_WIN64)
547
548// ppapi::proxy::SerializedTrueTypeFontDesc ------------------------------------
549
550// static
551void ParamTraits<ppapi::proxy::SerializedTrueTypeFontDesc>::Write(
552    Message* m,
553    const param_type& p) {
554  ParamTraits<std::string>::Write(m, p.family);
555  ParamTraits<PP_TrueTypeFontFamily_Dev>::Write(m, p.generic_family);
556  ParamTraits<PP_TrueTypeFontStyle_Dev>::Write(m, p.style);
557  ParamTraits<PP_TrueTypeFontWeight_Dev>::Write(m, p.weight);
558  ParamTraits<PP_TrueTypeFontWidth_Dev>::Write(m, p.width);
559  ParamTraits<PP_TrueTypeFontCharset_Dev>::Write(m, p.charset);
560}
561
562// static
563bool ParamTraits<ppapi::proxy::SerializedTrueTypeFontDesc>::Read(
564    const Message* m,
565    PickleIterator* iter,
566    param_type* r) {
567  return
568      ParamTraits<std::string>::Read(m, iter, &r->family) &&
569      ParamTraits<PP_TrueTypeFontFamily_Dev>::Read(m, iter,
570                                                   &r->generic_family) &&
571      ParamTraits<PP_TrueTypeFontStyle_Dev>::Read(m, iter, &r->style) &&
572      ParamTraits<PP_TrueTypeFontWeight_Dev>::Read(m, iter, &r->weight) &&
573      ParamTraits<PP_TrueTypeFontWidth_Dev>::Read(m, iter, &r->width) &&
574      ParamTraits<PP_TrueTypeFontCharset_Dev>::Read(m, iter, &r->charset);
575}
576
577// static
578void ParamTraits<ppapi::proxy::SerializedTrueTypeFontDesc>::Log(
579    const param_type& p,
580    std::string* l) {
581}
582
583#if !defined(OS_NACL) && !defined(NACL_WIN64)
584// ppapi::PepperFilePath -------------------------------------------------------
585
586// static
587void ParamTraits<ppapi::PepperFilePath>::Write(Message* m,
588                                               const param_type& p) {
589  WriteParam(m, static_cast<unsigned>(p.domain()));
590  WriteParam(m, p.path());
591}
592
593// static
594bool ParamTraits<ppapi::PepperFilePath>::Read(const Message* m,
595                                              PickleIterator* iter,
596                                              param_type* p) {
597  unsigned domain;
598  base::FilePath path;
599  if (!ReadParam(m, iter, &domain) || !ReadParam(m, iter, &path))
600    return false;
601  if (domain > ppapi::PepperFilePath::DOMAIN_MAX_VALID)
602    return false;
603
604  *p = ppapi::PepperFilePath(
605      static_cast<ppapi::PepperFilePath::Domain>(domain), path);
606  return true;
607}
608
609// static
610void ParamTraits<ppapi::PepperFilePath>::Log(const param_type& p,
611                                             std::string* l) {
612  l->append("(");
613  LogParam(static_cast<unsigned>(p.domain()), l);
614  l->append(", ");
615  LogParam(p.path(), l);
616  l->append(")");
617}
618
619// SerializedFlashMenu ---------------------------------------------------------
620
621// static
622void ParamTraits<ppapi::proxy::SerializedFlashMenu>::Write(
623    Message* m,
624    const param_type& p) {
625  p.WriteToMessage(m);
626}
627
628// static
629bool ParamTraits<ppapi::proxy::SerializedFlashMenu>::Read(const Message* m,
630                                                          PickleIterator* iter,
631                                                          param_type* r) {
632  return r->ReadFromMessage(m, iter);
633}
634
635// static
636void ParamTraits<ppapi::proxy::SerializedFlashMenu>::Log(const param_type& p,
637                                                         std::string* l) {
638}
639#endif  // !defined(OS_NACL) && !defined(NACL_WIN64)
640
641// PPB_X509Certificate_Fields --------------------------------------------------
642
643// static
644void ParamTraits<ppapi::PPB_X509Certificate_Fields>::Write(
645    Message* m,
646    const param_type& p) {
647  ParamTraits<ListValue>::Write(m, p.values_);
648}
649
650// static
651bool ParamTraits<ppapi::PPB_X509Certificate_Fields>::Read(const Message* m,
652                                                          PickleIterator* iter,
653                                                          param_type* r) {
654  return ParamTraits<ListValue>::Read(m, iter, &(r->values_));
655}
656
657// static
658void ParamTraits<ppapi::PPB_X509Certificate_Fields>::Log(const param_type& p,
659                                                         std::string* l) {
660}
661
662}  // namespace IPC
663