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.
5 #include "ppapi/proxy/ppapi_param_traits.h"
7 #include <string.h> // For memcpy
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"
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
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
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.
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.
41 bool ReadVectorWithoutCopy(const Message
* m
,
43 std::vector
<T
>* output
) {
44 // This part is just a copy of the the default ParamTraits vector Read().
46 // ReadLength() checks for < 0 itself.
47 if (!m
->ReadLength(iter
, &size
))
49 // Resizing beforehand is not safe, see BUG 1006367 for details.
50 if (INT_MAX
/ sizeof(T
) <= static_cast<size_t>(size
))
53 output
->reserve(size
);
54 for (int i
= 0; i
< size
; i
++) {
56 if (!ReadParam(m
, iter
, &cur
))
58 output
->push_back(cur
);
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.
68 void 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
++)
76 // PP_Bool ---------------------------------------------------------------------
79 void ParamTraits
<PP_Bool
>::Write(Message
* m
, const param_type
& p
) {
80 ParamTraits
<bool>::Write(m
, PP_ToBool(p
));
84 bool ParamTraits
<PP_Bool
>::Read(const Message
* m
,
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.
91 if (!ParamTraits
<bool>::Read(m
, iter
, &result
))
93 *r
= PP_FromBool(result
);
98 void ParamTraits
<PP_Bool
>::Log(const param_type
& p
, std::string
* l
) {
101 // PP_FileInfo -------------------------------------------------------------
104 void 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
);
114 bool ParamTraits
<PP_FileInfo
>::Read(const Message
* m
, PickleIterator
* iter
,
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
))
124 if (type
!= PP_FILETYPE_REGULAR
&&
125 type
!= PP_FILETYPE_DIRECTORY
&&
126 type
!= PP_FILETYPE_OTHER
)
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
)
135 r
->system_type
= static_cast<PP_FileSystemType
>(system_type
);
140 void ParamTraits
<PP_FileInfo
>::Log(const param_type
& p
, std::string
* l
) {
143 // PP_NetAddress_Private -------------------------------------------------------
146 void 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
));
153 bool ParamTraits
<PP_NetAddress_Private
>::Read(const Message
* m
,
154 PickleIterator
* iter
,
157 if (!ReadParam(m
, iter
, &size
))
159 if (size
> sizeof(p
->data
))
164 if (!m
->ReadBytes(iter
, &data
, size
))
166 memcpy(p
->data
, data
, size
);
171 void ParamTraits
<PP_NetAddress_Private
>::Log(const param_type
& p
,
173 l
->append("<PP_NetAddress_Private (");
175 l
->append(" bytes)>");
178 // TODO(teravest): Remove this when FileRef is moved to the "new" proxy.
179 // PPB_FileRef_CreateInfo ------------------------------------------------------
182 void 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
);
192 bool ParamTraits
<ppapi::PPB_FileRef_CreateInfo
>::Read(const Message
* m
,
193 PickleIterator
* iter
,
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
);
204 void ParamTraits
<ppapi::PPB_FileRef_CreateInfo
>::Log(const param_type
& p
,
208 // HostResource ----------------------------------------------------------------
211 void 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());
218 bool ParamTraits
<ppapi::HostResource
>::Read(const Message
* m
,
219 PickleIterator
* iter
,
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
))
226 r
->SetHostResource(instance
, resource
);
231 void ParamTraits
<ppapi::HostResource
>::Log(const param_type
& p
,
235 // SerializedVar ---------------------------------------------------------------
238 void ParamTraits
<ppapi::proxy::SerializedVar
>::Write(Message
* m
,
239 const param_type
& p
) {
244 bool ParamTraits
<ppapi::proxy::SerializedVar
>::Read(const Message
* m
,
245 PickleIterator
* iter
,
247 return r
->ReadFromMessage(m
, iter
);
251 void ParamTraits
<ppapi::proxy::SerializedVar
>::Log(const param_type
& p
,
255 // std::vector<SerializedVar> --------------------------------------------------
257 void ParamTraits
< std::vector
<ppapi::proxy::SerializedVar
> >::Write(
259 const param_type
& p
) {
260 WriteVectorWithoutCopy(m
, p
);
264 bool ParamTraits
< std::vector
<ppapi::proxy::SerializedVar
> >::Read(
266 PickleIterator
* iter
,
268 return ReadVectorWithoutCopy(m
, iter
, r
);
272 void ParamTraits
< std::vector
<ppapi::proxy::SerializedVar
> >::Log(
277 // std::vector<PPB_FileRef_CreateInfo> -----------------------------------------
279 void ParamTraits
< std::vector
<ppapi::PPB_FileRef_CreateInfo
> >::Write(
281 const param_type
& p
) {
282 WriteVectorWithoutCopy(m
, p
);
286 bool ParamTraits
< std::vector
<ppapi::PPB_FileRef_CreateInfo
> >::Read(
288 PickleIterator
* iter
,
290 return ReadVectorWithoutCopy(m
, iter
, r
);
294 void ParamTraits
< std::vector
<ppapi::PPB_FileRef_CreateInfo
> >::Log(
299 // ppapi::PpapiPermissions -----------------------------------------------------
301 void ParamTraits
<ppapi::PpapiPermissions
>::Write(Message
* m
,
302 const param_type
& p
) {
303 ParamTraits
<uint32_t>::Write(m
, p
.GetBits());
307 bool ParamTraits
<ppapi::PpapiPermissions
>::Read(const Message
* m
,
308 PickleIterator
* iter
,
311 if (!ParamTraits
<uint32_t>::Read(m
, iter
, &bits
))
313 *r
= ppapi::PpapiPermissions(bits
);
318 void ParamTraits
<ppapi::PpapiPermissions
>::Log(const param_type
& p
,
322 // SerializedHandle ------------------------------------------------------------
325 void ParamTraits
<ppapi::proxy::SerializedHandle
>::Write(Message
* m
,
326 const param_type
& p
) {
327 ppapi::proxy::SerializedHandle::WriteHeader(p
.header(), m
);
329 case ppapi::proxy::SerializedHandle::SHARED_MEMORY
:
330 ParamTraits
<base::SharedMemoryHandle
>::Write(m
, p
.shmem());
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());
337 case ppapi::proxy::SerializedHandle::INVALID
:
339 // No default so the compiler will warn on new types.
344 bool ParamTraits
<ppapi::proxy::SerializedHandle
>::Read(const Message
* m
,
345 PickleIterator
* iter
,
347 ppapi::proxy::SerializedHandle::Header header
;
348 if (!ppapi::proxy::SerializedHandle::ReadHeader(iter
, &header
))
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
);
359 case ppapi::proxy::SerializedHandle::SOCKET
: {
360 IPC::PlatformFileForTransit socket
;
361 if (ParamTraits
<IPC::PlatformFileForTransit
>::Read(m
, iter
, &socket
)) {
362 r
->set_socket(socket
);
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
);
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
);
383 case ppapi::proxy::SerializedHandle::INVALID
:
385 // No default so the compiler will warn us if a new type is added.
391 void ParamTraits
<ppapi::proxy::SerializedHandle
>::Log(const param_type
& p
,
395 // PPBURLLoader_UpdateProgress_Params ------------------------------------------
398 void ParamTraits
<ppapi::proxy::PPBURLLoader_UpdateProgress_Params
>::Write(
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
);
410 bool ParamTraits
<ppapi::proxy::PPBURLLoader_UpdateProgress_Params
>::Read(
412 PickleIterator
* iter
,
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
);
424 void ParamTraits
<ppapi::proxy::PPBURLLoader_UpdateProgress_Params
>::Log(
429 #if !defined(OS_NACL) && !defined(NACL_WIN64)
430 // PPBFlash_DrawGlyphs_Params --------------------------------------------------
432 void ParamTraits
<ppapi::proxy::PPBFlash_DrawGlyphs_Params
>::Write(
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
);
456 bool ParamTraits
<ppapi::proxy::PPBFlash_DrawGlyphs_Params
>::Read(
458 PickleIterator
* iter
,
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
,
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();
484 void ParamTraits
<ppapi::proxy::PPBFlash_DrawGlyphs_Params
>::Log(
489 // SerializedDirEntry ----------------------------------------------------------
492 void 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
);
499 bool ParamTraits
<ppapi::proxy::SerializedDirEntry
>::Read(const Message
* m
,
500 PickleIterator
* iter
,
502 return ParamTraits
<std::string
>::Read(m
, iter
, &r
->name
) &&
503 ParamTraits
<bool>::Read(m
, iter
, &r
->is_dir
);
507 void ParamTraits
<ppapi::proxy::SerializedDirEntry
>::Log(const param_type
& p
,
511 // ppapi::proxy::SerializedFontDescription -------------------------------------
514 void ParamTraits
<ppapi::proxy::SerializedFontDescription
>::Write(
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
);
528 bool ParamTraits
<ppapi::proxy::SerializedFontDescription
>::Read(
530 PickleIterator
* iter
,
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
);
544 void ParamTraits
<ppapi::proxy::SerializedFontDescription
>::Log(
548 #endif // !defined(OS_NACL) && !defined(NACL_WIN64)
550 // ppapi::proxy::SerializedTrueTypeFontDesc ------------------------------------
553 void ParamTraits
<ppapi::proxy::SerializedTrueTypeFontDesc
>::Write(
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
);
565 bool ParamTraits
<ppapi::proxy::SerializedTrueTypeFontDesc
>::Read(
567 PickleIterator
* iter
,
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
);
580 void ParamTraits
<ppapi::proxy::SerializedTrueTypeFontDesc
>::Log(
585 #if !defined(OS_NACL) && !defined(NACL_WIN64)
586 // ppapi::PepperFilePath -------------------------------------------------------
589 void ParamTraits
<ppapi::PepperFilePath
>::Write(Message
* m
,
590 const param_type
& p
) {
591 WriteParam(m
, static_cast<unsigned>(p
.domain()));
592 WriteParam(m
, p
.path());
596 bool ParamTraits
<ppapi::PepperFilePath
>::Read(const Message
* m
,
597 PickleIterator
* iter
,
601 if (!ReadParam(m
, iter
, &domain
) || !ReadParam(m
, iter
, &path
))
603 if (domain
> ppapi::PepperFilePath::DOMAIN_MAX_VALID
)
606 *p
= ppapi::PepperFilePath(
607 static_cast<ppapi::PepperFilePath::Domain
>(domain
), path
);
612 void ParamTraits
<ppapi::PepperFilePath
>::Log(const param_type
& p
,
615 LogParam(static_cast<unsigned>(p
.domain()), l
);
617 LogParam(p
.path(), l
);
621 // SerializedFlashMenu ---------------------------------------------------------
624 void ParamTraits
<ppapi::proxy::SerializedFlashMenu
>::Write(
626 const param_type
& p
) {
631 bool ParamTraits
<ppapi::proxy::SerializedFlashMenu
>::Read(const Message
* m
,
632 PickleIterator
* iter
,
634 return r
->ReadFromMessage(m
, iter
);
638 void ParamTraits
<ppapi::proxy::SerializedFlashMenu
>::Log(const param_type
& p
,
641 #endif // !defined(OS_NACL) && !defined(NACL_WIN64)
643 // PPB_X509Certificate_Fields --------------------------------------------------
646 void ParamTraits
<ppapi::PPB_X509Certificate_Fields
>::Write(
648 const param_type
& p
) {
649 ParamTraits
<ListValue
>::Write(m
, p
.values_
);
653 bool ParamTraits
<ppapi::PPB_X509Certificate_Fields
>::Read(const Message
* m
,
654 PickleIterator
* iter
,
656 return ParamTraits
<ListValue
>::Read(m
, iter
, &(r
->values_
));
660 void ParamTraits
<ppapi::PPB_X509Certificate_Fields
>::Log(const param_type
& p
,