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_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"
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
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
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.
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.
40 bool ReadVectorWithoutCopy(const Message
* m
,
42 std::vector
<T
>* output
) {
43 // This part is just a copy of the the default ParamTraits vector Read().
45 // ReadLength() checks for < 0 itself.
46 if (!m
->ReadLength(iter
, &size
))
48 // Resizing beforehand is not safe, see BUG 1006367 for details.
49 if (INT_MAX
/ sizeof(T
) <= static_cast<size_t>(size
))
52 output
->reserve(size
);
53 for (int i
= 0; i
< size
; i
++) {
55 if (!ReadParam(m
, iter
, &cur
))
57 output
->push_back(cur
);
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.
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
++)
75 // PP_Bool ---------------------------------------------------------------------
78 void ParamTraits
<PP_Bool
>::Write(Message
* m
, const param_type
& p
) {
79 ParamTraits
<bool>::Write(m
, PP_ToBool(p
));
83 bool ParamTraits
<PP_Bool
>::Read(const Message
* m
,
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.
90 if (!ParamTraits
<bool>::Read(m
, iter
, &result
))
92 *r
= PP_FromBool(result
);
97 void ParamTraits
<PP_Bool
>::Log(const param_type
& p
, std::string
* l
) {
100 // PP_NetAddress_Private -------------------------------------------------------
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
));
110 bool ParamTraits
<PP_NetAddress_Private
>::Read(const Message
* m
,
111 PickleIterator
* iter
,
114 if (!ReadParam(m
, iter
, &size
))
116 if (size
> sizeof(p
->data
))
121 if (!m
->ReadBytes(iter
, &data
, size
))
123 memcpy(p
->data
, data
, size
);
128 void ParamTraits
<PP_NetAddress_Private
>::Log(const param_type
& p
,
130 l
->append("<PP_NetAddress_Private (");
132 l
->append(" bytes)>");
135 // HostResource ----------------------------------------------------------------
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());
145 bool ParamTraits
<ppapi::HostResource
>::Read(const Message
* m
,
146 PickleIterator
* iter
,
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
))
153 r
->SetHostResource(instance
, resource
);
158 void ParamTraits
<ppapi::HostResource
>::Log(const param_type
& p
,
162 // SerializedVar ---------------------------------------------------------------
165 void ParamTraits
<ppapi::proxy::SerializedVar
>::Write(Message
* m
,
166 const param_type
& p
) {
171 bool ParamTraits
<ppapi::proxy::SerializedVar
>::Read(const Message
* m
,
172 PickleIterator
* iter
,
174 return r
->ReadFromMessage(m
, iter
);
178 void ParamTraits
<ppapi::proxy::SerializedVar
>::Log(const param_type
& p
,
182 // std::vector<SerializedVar> --------------------------------------------------
184 void ParamTraits
< std::vector
<ppapi::proxy::SerializedVar
> >::Write(
186 const param_type
& p
) {
187 WriteVectorWithoutCopy(m
, p
);
191 bool ParamTraits
< std::vector
<ppapi::proxy::SerializedVar
> >::Read(
193 PickleIterator
* iter
,
195 return ReadVectorWithoutCopy(m
, iter
, r
);
199 void ParamTraits
< std::vector
<ppapi::proxy::SerializedVar
> >::Log(
204 // ppapi::PpapiPermissions -----------------------------------------------------
206 void ParamTraits
<ppapi::PpapiPermissions
>::Write(Message
* m
,
207 const param_type
& p
) {
208 ParamTraits
<uint32_t>::Write(m
, p
.GetBits());
212 bool ParamTraits
<ppapi::PpapiPermissions
>::Read(const Message
* m
,
213 PickleIterator
* iter
,
216 if (!ParamTraits
<uint32_t>::Read(m
, iter
, &bits
))
218 *r
= ppapi::PpapiPermissions(bits
);
223 void ParamTraits
<ppapi::PpapiPermissions
>::Log(const param_type
& p
,
227 // SerializedHandle ------------------------------------------------------------
230 void ParamTraits
<ppapi::proxy::SerializedHandle
>::Write(Message
* m
,
231 const param_type
& p
) {
232 ppapi::proxy::SerializedHandle::WriteHeader(p
.header(), m
);
234 case ppapi::proxy::SerializedHandle::SHARED_MEMORY
:
235 ParamTraits
<base::SharedMemoryHandle
>::Write(m
, p
.shmem());
237 case ppapi::proxy::SerializedHandle::SOCKET
:
238 case ppapi::proxy::SerializedHandle::FILE:
239 ParamTraits
<IPC::PlatformFileForTransit
>::Write(m
, p
.descriptor());
241 case ppapi::proxy::SerializedHandle::INVALID
:
243 // No default so the compiler will warn on new types.
248 bool ParamTraits
<ppapi::proxy::SerializedHandle
>::Read(const Message
* m
,
249 PickleIterator
* iter
,
251 ppapi::proxy::SerializedHandle::Header header
;
252 if (!ppapi::proxy::SerializedHandle::ReadHeader(iter
, &header
))
254 switch (header
.type
) {
255 case ppapi::proxy::SerializedHandle::SHARED_MEMORY
: {
256 base::SharedMemoryHandle handle
;
257 if (ParamTraits
<base::SharedMemoryHandle
>::Read(m
, iter
, &handle
)) {
258 r
->set_shmem(handle
, header
.size
);
263 case ppapi::proxy::SerializedHandle::SOCKET
: {
264 IPC::PlatformFileForTransit socket
;
265 if (ParamTraits
<IPC::PlatformFileForTransit
>::Read(m
, iter
, &socket
)) {
266 r
->set_socket(socket
);
271 case ppapi::proxy::SerializedHandle::FILE: {
272 IPC::PlatformFileForTransit desc
;
273 if (ParamTraits
<IPC::PlatformFileForTransit
>::Read(m
, iter
, &desc
)) {
274 r
->set_file_handle(desc
, header
.open_flags
, header
.file_io
);
279 case ppapi::proxy::SerializedHandle::INVALID
:
281 // No default so the compiler will warn us if a new type is added.
287 void ParamTraits
<ppapi::proxy::SerializedHandle
>::Log(const param_type
& p
,
291 // PPBURLLoader_UpdateProgress_Params ------------------------------------------
294 void ParamTraits
<ppapi::proxy::PPBURLLoader_UpdateProgress_Params
>::Write(
296 const param_type
& p
) {
297 ParamTraits
<PP_Instance
>::Write(m
, p
.instance
);
298 ParamTraits
<ppapi::HostResource
>::Write(m
, p
.resource
);
299 ParamTraits
<int64_t>::Write(m
, p
.bytes_sent
);
300 ParamTraits
<int64_t>::Write(m
, p
.total_bytes_to_be_sent
);
301 ParamTraits
<int64_t>::Write(m
, p
.bytes_received
);
302 ParamTraits
<int64_t>::Write(m
, p
.total_bytes_to_be_received
);
306 bool ParamTraits
<ppapi::proxy::PPBURLLoader_UpdateProgress_Params
>::Read(
308 PickleIterator
* iter
,
311 ParamTraits
<PP_Instance
>::Read(m
, iter
, &r
->instance
) &&
312 ParamTraits
<ppapi::HostResource
>::Read(m
, iter
, &r
->resource
) &&
313 ParamTraits
<int64_t>::Read(m
, iter
, &r
->bytes_sent
) &&
314 ParamTraits
<int64_t>::Read(m
, iter
, &r
->total_bytes_to_be_sent
) &&
315 ParamTraits
<int64_t>::Read(m
, iter
, &r
->bytes_received
) &&
316 ParamTraits
<int64_t>::Read(m
, iter
, &r
->total_bytes_to_be_received
);
320 void ParamTraits
<ppapi::proxy::PPBURLLoader_UpdateProgress_Params
>::Log(
325 #if !defined(OS_NACL) && !defined(NACL_WIN64)
326 // PPBFlash_DrawGlyphs_Params --------------------------------------------------
328 void ParamTraits
<ppapi::proxy::PPBFlash_DrawGlyphs_Params
>::Write(
330 const param_type
& p
) {
331 ParamTraits
<PP_Instance
>::Write(m
, p
.instance
);
332 ParamTraits
<ppapi::HostResource
>::Write(m
, p
.image_data
);
333 ParamTraits
<ppapi::proxy::SerializedFontDescription
>::Write(m
, p
.font_desc
);
334 ParamTraits
<uint32_t>::Write(m
, p
.color
);
335 ParamTraits
<PP_Point
>::Write(m
, p
.position
);
336 ParamTraits
<PP_Rect
>::Write(m
, p
.clip
);
337 ParamTraits
<float>::Write(m
, p
.transformation
[0][0]);
338 ParamTraits
<float>::Write(m
, p
.transformation
[0][1]);
339 ParamTraits
<float>::Write(m
, p
.transformation
[0][2]);
340 ParamTraits
<float>::Write(m
, p
.transformation
[1][0]);
341 ParamTraits
<float>::Write(m
, p
.transformation
[1][1]);
342 ParamTraits
<float>::Write(m
, p
.transformation
[1][2]);
343 ParamTraits
<float>::Write(m
, p
.transformation
[2][0]);
344 ParamTraits
<float>::Write(m
, p
.transformation
[2][1]);
345 ParamTraits
<float>::Write(m
, p
.transformation
[2][2]);
346 ParamTraits
<PP_Bool
>::Write(m
, p
.allow_subpixel_aa
);
347 ParamTraits
<std::vector
<uint16_t> >::Write(m
, p
.glyph_indices
);
348 ParamTraits
<std::vector
<PP_Point
> >::Write(m
, p
.glyph_advances
);
352 bool ParamTraits
<ppapi::proxy::PPBFlash_DrawGlyphs_Params
>::Read(
354 PickleIterator
* iter
,
357 ParamTraits
<PP_Instance
>::Read(m
, iter
, &r
->instance
) &&
358 ParamTraits
<ppapi::HostResource
>::Read(m
, iter
, &r
->image_data
) &&
359 ParamTraits
<ppapi::proxy::SerializedFontDescription
>::Read(m
, iter
,
361 ParamTraits
<uint32_t>::Read(m
, iter
, &r
->color
) &&
362 ParamTraits
<PP_Point
>::Read(m
, iter
, &r
->position
) &&
363 ParamTraits
<PP_Rect
>::Read(m
, iter
, &r
->clip
) &&
364 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[0][0]) &&
365 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[0][1]) &&
366 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[0][2]) &&
367 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[1][0]) &&
368 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[1][1]) &&
369 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[1][2]) &&
370 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[2][0]) &&
371 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[2][1]) &&
372 ParamTraits
<float>::Read(m
, iter
, &r
->transformation
[2][2]) &&
373 ParamTraits
<PP_Bool
>::Read(m
, iter
, &r
->allow_subpixel_aa
) &&
374 ParamTraits
<std::vector
<uint16_t> >::Read(m
, iter
, &r
->glyph_indices
) &&
375 ParamTraits
<std::vector
<PP_Point
> >::Read(m
, iter
, &r
->glyph_advances
) &&
376 r
->glyph_indices
.size() == r
->glyph_advances
.size();
380 void ParamTraits
<ppapi::proxy::PPBFlash_DrawGlyphs_Params
>::Log(
385 // SerializedDirEntry ----------------------------------------------------------
388 void ParamTraits
<ppapi::proxy::SerializedDirEntry
>::Write(Message
* m
,
389 const param_type
& p
) {
390 ParamTraits
<std::string
>::Write(m
, p
.name
);
391 ParamTraits
<bool>::Write(m
, p
.is_dir
);
395 bool ParamTraits
<ppapi::proxy::SerializedDirEntry
>::Read(const Message
* m
,
396 PickleIterator
* iter
,
398 return ParamTraits
<std::string
>::Read(m
, iter
, &r
->name
) &&
399 ParamTraits
<bool>::Read(m
, iter
, &r
->is_dir
);
403 void ParamTraits
<ppapi::proxy::SerializedDirEntry
>::Log(const param_type
& p
,
407 // ppapi::proxy::SerializedFontDescription -------------------------------------
410 void ParamTraits
<ppapi::proxy::SerializedFontDescription
>::Write(
412 const param_type
& p
) {
413 ParamTraits
<std::string
>::Write(m
, p
.face
);
414 ParamTraits
<int32_t>::Write(m
, p
.family
);
415 ParamTraits
<uint32_t>::Write(m
, p
.size
);
416 ParamTraits
<int32_t>::Write(m
, p
.weight
);
417 ParamTraits
<PP_Bool
>::Write(m
, p
.italic
);
418 ParamTraits
<PP_Bool
>::Write(m
, p
.small_caps
);
419 ParamTraits
<int32_t>::Write(m
, p
.letter_spacing
);
420 ParamTraits
<int32_t>::Write(m
, p
.word_spacing
);
424 bool ParamTraits
<ppapi::proxy::SerializedFontDescription
>::Read(
426 PickleIterator
* iter
,
429 ParamTraits
<std::string
>::Read(m
, iter
, &r
->face
) &&
430 ParamTraits
<int32_t>::Read(m
, iter
, &r
->family
) &&
431 ParamTraits
<uint32_t>::Read(m
, iter
, &r
->size
) &&
432 ParamTraits
<int32_t>::Read(m
, iter
, &r
->weight
) &&
433 ParamTraits
<PP_Bool
>::Read(m
, iter
, &r
->italic
) &&
434 ParamTraits
<PP_Bool
>::Read(m
, iter
, &r
->small_caps
) &&
435 ParamTraits
<int32_t>::Read(m
, iter
, &r
->letter_spacing
) &&
436 ParamTraits
<int32_t>::Read(m
, iter
, &r
->word_spacing
);
440 void ParamTraits
<ppapi::proxy::SerializedFontDescription
>::Log(
444 #endif // !defined(OS_NACL) && !defined(NACL_WIN64)
446 // ppapi::proxy::SerializedTrueTypeFontDesc ------------------------------------
449 void ParamTraits
<ppapi::proxy::SerializedTrueTypeFontDesc
>::Write(
451 const param_type
& p
) {
452 ParamTraits
<std::string
>::Write(m
, p
.family
);
453 ParamTraits
<PP_TrueTypeFontFamily_Dev
>::Write(m
, p
.generic_family
);
454 ParamTraits
<PP_TrueTypeFontStyle_Dev
>::Write(m
, p
.style
);
455 ParamTraits
<PP_TrueTypeFontWeight_Dev
>::Write(m
, p
.weight
);
456 ParamTraits
<PP_TrueTypeFontWidth_Dev
>::Write(m
, p
.width
);
457 ParamTraits
<PP_TrueTypeFontCharset_Dev
>::Write(m
, p
.charset
);
461 bool ParamTraits
<ppapi::proxy::SerializedTrueTypeFontDesc
>::Read(
463 PickleIterator
* iter
,
466 ParamTraits
<std::string
>::Read(m
, iter
, &r
->family
) &&
467 ParamTraits
<PP_TrueTypeFontFamily_Dev
>::Read(m
, iter
,
468 &r
->generic_family
) &&
469 ParamTraits
<PP_TrueTypeFontStyle_Dev
>::Read(m
, iter
, &r
->style
) &&
470 ParamTraits
<PP_TrueTypeFontWeight_Dev
>::Read(m
, iter
, &r
->weight
) &&
471 ParamTraits
<PP_TrueTypeFontWidth_Dev
>::Read(m
, iter
, &r
->width
) &&
472 ParamTraits
<PP_TrueTypeFontCharset_Dev
>::Read(m
, iter
, &r
->charset
);
476 void ParamTraits
<ppapi::proxy::SerializedTrueTypeFontDesc
>::Log(
481 #if !defined(OS_NACL) && !defined(NACL_WIN64)
482 // ppapi::PepperFilePath -------------------------------------------------------
485 void ParamTraits
<ppapi::PepperFilePath
>::Write(Message
* m
,
486 const param_type
& p
) {
487 WriteParam(m
, static_cast<unsigned>(p
.domain()));
488 WriteParam(m
, p
.path());
492 bool ParamTraits
<ppapi::PepperFilePath
>::Read(const Message
* m
,
493 PickleIterator
* iter
,
497 if (!ReadParam(m
, iter
, &domain
) || !ReadParam(m
, iter
, &path
))
499 if (domain
> ppapi::PepperFilePath::DOMAIN_MAX_VALID
)
502 *p
= ppapi::PepperFilePath(
503 static_cast<ppapi::PepperFilePath::Domain
>(domain
), path
);
508 void ParamTraits
<ppapi::PepperFilePath
>::Log(const param_type
& p
,
511 LogParam(static_cast<unsigned>(p
.domain()), l
);
513 LogParam(p
.path(), l
);
517 // SerializedFlashMenu ---------------------------------------------------------
520 void ParamTraits
<ppapi::proxy::SerializedFlashMenu
>::Write(
522 const param_type
& p
) {
527 bool ParamTraits
<ppapi::proxy::SerializedFlashMenu
>::Read(const Message
* m
,
528 PickleIterator
* iter
,
530 return r
->ReadFromMessage(m
, iter
);
534 void ParamTraits
<ppapi::proxy::SerializedFlashMenu
>::Log(const param_type
& p
,
537 #endif // !defined(OS_NACL) && !defined(NACL_WIN64)
539 // PPB_X509Certificate_Fields --------------------------------------------------
542 void ParamTraits
<ppapi::PPB_X509Certificate_Fields
>::Write(
544 const param_type
& p
) {
545 ParamTraits
<base::ListValue
>::Write(m
, p
.values_
);
549 bool ParamTraits
<ppapi::PPB_X509Certificate_Fields
>::Read(const Message
* m
,
550 PickleIterator
* iter
,
552 return ParamTraits
<base::ListValue
>::Read(m
, iter
, &(r
->values_
));
556 void ParamTraits
<ppapi::PPB_X509Certificate_Fields
>::Log(const param_type
& p
,
560 // ppapi::SocketOptionData -----------------------------------------------------
563 void ParamTraits
<ppapi::SocketOptionData
>::Write(Message
* m
,
564 const param_type
& p
) {
565 ppapi::SocketOptionData::Type type
= p
.GetType();
566 ParamTraits
<int32_t>::Write(m
, static_cast<int32_t>(type
));
568 case ppapi::SocketOptionData::TYPE_INVALID
: {
571 case ppapi::SocketOptionData::TYPE_BOOL
: {
572 bool out_value
= false;
573 bool result
= p
.GetBool(&out_value
);
574 // Suppress unused variable warnings.
575 static_cast<void>(result
);
578 ParamTraits
<bool>::Write(m
, out_value
);
581 case ppapi::SocketOptionData::TYPE_INT32
: {
582 int32_t out_value
= 0;
583 bool result
= p
.GetInt32(&out_value
);
584 // Suppress unused variable warnings.
585 static_cast<void>(result
);
588 ParamTraits
<int32_t>::Write(m
, out_value
);
591 // No default so the compiler will warn on new types.
596 bool ParamTraits
<ppapi::SocketOptionData
>::Read(const Message
* m
,
597 PickleIterator
* iter
,
599 *r
= ppapi::SocketOptionData();
601 if (!ParamTraits
<int32_t>::Read(m
, iter
, &type
))
603 if (type
!= ppapi::SocketOptionData::TYPE_INVALID
&&
604 type
!= ppapi::SocketOptionData::TYPE_BOOL
&&
605 type
!= ppapi::SocketOptionData::TYPE_INT32
) {
608 switch (static_cast<ppapi::SocketOptionData::Type
>(type
)) {
609 case ppapi::SocketOptionData::TYPE_INVALID
: {
612 case ppapi::SocketOptionData::TYPE_BOOL
: {
614 if (!ParamTraits
<bool>::Read(m
, iter
, &value
))
619 case ppapi::SocketOptionData::TYPE_INT32
: {
621 if (!ParamTraits
<int32_t>::Read(m
, iter
, &value
))
626 // No default so the compiler will warn on new types.
632 void ParamTraits
<ppapi::SocketOptionData
>::Log(const param_type
& p
,
636 // ppapi::CompositorLayerData --------------------------------------------------
639 void ParamTraits
<ppapi::CompositorLayerData::Transform
>::Write(
641 const param_type
& p
) {
642 for (size_t i
= 0; i
< arraysize(p
.matrix
); i
++)
643 ParamTraits
<float>::Write(m
, p
.matrix
[i
]);
647 bool ParamTraits
<ppapi::CompositorLayerData::Transform
>::Read(
649 PickleIterator
* iter
,
651 for (size_t i
= 0; i
< arraysize(r
->matrix
);i
++) {
652 if (!ParamTraits
<float>::Read(m
, iter
, &r
->matrix
[i
]))
658 void ParamTraits
<ppapi::CompositorLayerData::Transform
>::Log(