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 "content/public/common/common_param_traits.h"
7 #include "content/public/common/content_constants.h"
8 #include "content/public/common/referrer.h"
9 #include "net/base/host_port_pair.h"
10 #include "net/base/upload_data.h"
11 #include "net/http/http_response_headers.h"
12 #include "third_party/skia/include/core/SkBitmap.h"
13 #include "ui/base/range/range.h"
14 #include "ui/gfx/rect.h"
15 #include "ui/gfx/rect_f.h"
16 #include "webkit/glue/resource_request_body.h"
20 struct SkBitmap_Data
{
21 // The configuration for the bitmap (bits per pixel, etc).
22 SkBitmap::Config fConfig
;
24 // The width of the bitmap in pixels.
27 // The height of the bitmap in pixels.
30 void InitSkBitmapDataForTransfer(const SkBitmap
& bitmap
) {
31 fConfig
= bitmap
.config();
32 fWidth
= bitmap
.width();
33 fHeight
= bitmap
.height();
36 // Returns whether |bitmap| successfully initialized.
37 bool InitSkBitmapFromData(SkBitmap
* bitmap
, const char* pixels
,
38 size_t total_pixels
) const {
40 bitmap
->setConfig(fConfig
, fWidth
, fHeight
, 0);
41 if (!bitmap
->allocPixels())
43 if (total_pixels
!= bitmap
->getSize())
45 memcpy(bitmap
->getPixels(), pixels
, total_pixels
);
55 void ParamTraits
<GURL
>::Write(Message
* m
, const GURL
& p
) {
56 DCHECK(p
.possibly_invalid_spec().length() <= content::kMaxURLChars
);
57 m
->WriteString(p
.possibly_invalid_spec());
58 // TODO(brettw) bug 684583: Add encoding for query params.
61 bool ParamTraits
<GURL
>::Read(const Message
* m
, PickleIterator
* iter
, GURL
* p
) {
63 if (!m
->ReadString(iter
, &s
) || s
.length() > content::kMaxURLChars
) {
71 void ParamTraits
<GURL
>::Log(const GURL
& p
, std::string
* l
) {
75 void ParamTraits
<net::URLRequestStatus
>::Write(Message
* m
,
76 const param_type
& p
) {
77 WriteParam(m
, static_cast<int>(p
.status()));
78 WriteParam(m
, p
.error());
81 bool ParamTraits
<net::URLRequestStatus
>::Read(const Message
* m
,
85 if (!ReadParam(m
, iter
, &status
) || !ReadParam(m
, iter
, &error
))
87 r
->set_status(static_cast<net::URLRequestStatus::Status
>(status
));
92 void ParamTraits
<net::URLRequestStatus
>::Log(const param_type
& p
,
96 case net::URLRequestStatus::SUCCESS
:
99 case net::URLRequestStatus::IO_PENDING
:
100 status
= "IO_PENDING ";
102 case net::URLRequestStatus::CANCELED
:
105 case net::URLRequestStatus::FAILED
:
112 if (p
.status() == net::URLRequestStatus::FAILED
)
117 if (p
.status() == net::URLRequestStatus::FAILED
) {
119 LogParam(p
.error(), l
);
124 // Only the net::UploadData ParamTraits<> definition needs this definition, so
125 // keep this in the implementation file so we can forward declare UploadData in
128 struct ParamTraits
<net::UploadElement
> {
129 typedef net::UploadElement param_type
;
130 static void Write(Message
* m
, const param_type
& p
) {
131 WriteParam(m
, static_cast<int>(p
.type()));
133 case net::UploadElement::TYPE_BYTES
: {
134 m
->WriteData(p
.bytes(), static_cast<int>(p
.bytes_length()));
138 DCHECK(p
.type() == net::UploadElement::TYPE_FILE
);
139 WriteParam(m
, p
.file_path());
140 WriteParam(m
, p
.file_range_offset());
141 WriteParam(m
, p
.file_range_length());
142 WriteParam(m
, p
.expected_file_modification_time());
147 static bool Read(const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
149 if (!ReadParam(m
, iter
, &type
))
152 case net::UploadElement::TYPE_BYTES
: {
155 if (!m
->ReadData(iter
, &data
, &len
))
157 r
->SetToBytes(data
, len
);
161 DCHECK(type
== net::UploadElement::TYPE_FILE
);
163 uint64 offset
, length
;
164 base::Time expected_modification_time
;
165 if (!ReadParam(m
, iter
, &file_path
))
167 if (!ReadParam(m
, iter
, &offset
))
169 if (!ReadParam(m
, iter
, &length
))
171 if (!ReadParam(m
, iter
, &expected_modification_time
))
173 r
->SetToFilePathRange(file_path
, offset
, length
,
174 expected_modification_time
);
180 static void Log(const param_type
& p
, std::string
* l
) {
181 l
->append("<net::UploadElement>");
185 void ParamTraits
<scoped_refptr
<net::UploadData
> >::Write(Message
* m
,
186 const param_type
& p
) {
187 WriteParam(m
, p
.get() != NULL
);
189 WriteParam(m
, *p
->elements());
190 WriteParam(m
, p
->identifier());
191 WriteParam(m
, p
->is_chunked());
192 WriteParam(m
, p
->last_chunk_appended());
196 bool ParamTraits
<scoped_refptr
<net::UploadData
> >::Read(const Message
* m
,
197 PickleIterator
* iter
,
200 if (!ReadParam(m
, iter
, &has_object
))
204 std::vector
<net::UploadElement
> elements
;
205 if (!ReadParam(m
, iter
, &elements
))
208 if (!ReadParam(m
, iter
, &identifier
))
210 bool is_chunked
= false;
211 if (!ReadParam(m
, iter
, &is_chunked
))
213 bool last_chunk_appended
= false;
214 if (!ReadParam(m
, iter
, &last_chunk_appended
))
216 *r
= new net::UploadData
;
217 (*r
)->swap_elements(&elements
);
218 (*r
)->set_identifier(identifier
);
219 (*r
)->set_is_chunked(is_chunked
);
220 (*r
)->set_last_chunk_appended(last_chunk_appended
);
224 void ParamTraits
<scoped_refptr
<net::UploadData
> >::Log(const param_type
& p
,
226 l
->append("<net::UploadData>");
229 void ParamTraits
<webkit_base::DataElement
>::Write(
230 Message
* m
, const param_type
& p
) {
231 WriteParam(m
, static_cast<int>(p
.type()));
233 case webkit_base::DataElement::TYPE_BYTES
: {
234 m
->WriteData(p
.bytes(), static_cast<int>(p
.length()));
237 case webkit_base::DataElement::TYPE_FILE
: {
238 WriteParam(m
, p
.path());
239 WriteParam(m
, p
.offset());
240 WriteParam(m
, p
.length());
241 WriteParam(m
, p
.expected_modification_time());
244 case webkit_base::DataElement::TYPE_FILE_FILESYSTEM
: {
245 WriteParam(m
, p
.url());
246 WriteParam(m
, p
.offset());
247 WriteParam(m
, p
.length());
248 WriteParam(m
, p
.expected_modification_time());
252 DCHECK(p
.type() == webkit_base::DataElement::TYPE_BLOB
);
253 WriteParam(m
, p
.url());
254 WriteParam(m
, p
.offset());
255 WriteParam(m
, p
.length());
261 bool ParamTraits
<webkit_base::DataElement
>::Read(
262 const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
264 if (!ReadParam(m
, iter
, &type
))
267 case webkit_base::DataElement::TYPE_BYTES
: {
270 if (!m
->ReadData(iter
, &data
, &len
))
272 r
->SetToBytes(data
, len
);
275 case webkit_base::DataElement::TYPE_FILE
: {
277 uint64 offset
, length
;
278 base::Time expected_modification_time
;
279 if (!ReadParam(m
, iter
, &file_path
))
281 if (!ReadParam(m
, iter
, &offset
))
283 if (!ReadParam(m
, iter
, &length
))
285 if (!ReadParam(m
, iter
, &expected_modification_time
))
287 r
->SetToFilePathRange(file_path
, offset
, length
,
288 expected_modification_time
);
291 case webkit_base::DataElement::TYPE_FILE_FILESYSTEM
: {
292 GURL file_system_url
;
293 uint64 offset
, length
;
294 base::Time expected_modification_time
;
295 if (!ReadParam(m
, iter
, &file_system_url
))
297 if (!ReadParam(m
, iter
, &offset
))
299 if (!ReadParam(m
, iter
, &length
))
301 if (!ReadParam(m
, iter
, &expected_modification_time
))
303 r
->SetToFileSystemUrlRange(file_system_url
, offset
, length
,
304 expected_modification_time
);
308 DCHECK(type
== webkit_base::DataElement::TYPE_BLOB
);
310 uint64 offset
, length
;
311 if (!ReadParam(m
, iter
, &blob_url
))
313 if (!ReadParam(m
, iter
, &offset
))
315 if (!ReadParam(m
, iter
, &length
))
317 r
->SetToBlobUrlRange(blob_url
, offset
, length
);
324 void ParamTraits
<webkit_base::DataElement
>::Log(
325 const param_type
& p
, std::string
* l
) {
326 l
->append("<webkit_base::DataElement>");
329 void ParamTraits
<scoped_refptr
<webkit_glue::ResourceRequestBody
> >::Write(
331 const param_type
& p
) {
332 WriteParam(m
, p
.get() != NULL
);
334 WriteParam(m
, *p
->elements());
335 WriteParam(m
, p
->identifier());
339 bool ParamTraits
<scoped_refptr
<webkit_glue::ResourceRequestBody
> >::Read(
341 PickleIterator
* iter
,
344 if (!ReadParam(m
, iter
, &has_object
))
348 std::vector
<webkit_base::DataElement
> elements
;
349 if (!ReadParam(m
, iter
, &elements
))
352 if (!ReadParam(m
, iter
, &identifier
))
354 *r
= new webkit_glue::ResourceRequestBody
;
355 (*r
)->swap_elements(&elements
);
356 (*r
)->set_identifier(identifier
);
360 void ParamTraits
<scoped_refptr
<webkit_glue::ResourceRequestBody
> >::Log(
361 const param_type
& p
, std::string
* l
) {
362 l
->append("<webkit_glue::ResourceRequestBody>");
365 void ParamTraits
<net::HostPortPair
>::Write(Message
* m
, const param_type
& p
) {
366 WriteParam(m
, p
.host());
367 WriteParam(m
, p
.port());
370 bool ParamTraits
<net::HostPortPair
>::Read(const Message
* m
,
371 PickleIterator
* iter
,
375 if (!ReadParam(m
, iter
, &host
) || !ReadParam(m
, iter
, &port
))
383 void ParamTraits
<net::HostPortPair
>::Log(const param_type
& p
, std::string
* l
) {
384 l
->append(p
.ToString());
387 void ParamTraits
<scoped_refptr
<net::HttpResponseHeaders
> >::Write(
388 Message
* m
, const param_type
& p
) {
389 WriteParam(m
, p
.get() != NULL
);
391 // Do not disclose Set-Cookie headers over IPC.
392 p
->Persist(m
, net::HttpResponseHeaders::PERSIST_SANS_COOKIES
);
396 bool ParamTraits
<scoped_refptr
<net::HttpResponseHeaders
> >::Read(
397 const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
399 if (!ReadParam(m
, iter
, &has_object
))
402 *r
= new net::HttpResponseHeaders(*m
, iter
);
406 void ParamTraits
<scoped_refptr
<net::HttpResponseHeaders
> >::Log(
407 const param_type
& p
, std::string
* l
) {
408 l
->append("<HttpResponseHeaders>");
411 void ParamTraits
<net::IPEndPoint
>::Write(Message
* m
, const param_type
& p
) {
412 WriteParam(m
, p
.address());
413 WriteParam(m
, p
.port());
416 bool ParamTraits
<net::IPEndPoint
>::Read(const Message
* m
, PickleIterator
* iter
,
418 net::IPAddressNumber address
;
420 if (!ReadParam(m
, iter
, &address
) || !ReadParam(m
, iter
, &port
))
422 *p
= net::IPEndPoint(address
, port
);
426 void ParamTraits
<net::IPEndPoint
>::Log(const param_type
& p
, std::string
* l
) {
427 LogParam("IPEndPoint:" + p
.ToString(), l
);
430 void ParamTraits
<content::Referrer
>::Write(
431 Message
* m
, const param_type
& p
) {
432 WriteParam(m
, p
.url
);
433 WriteParam(m
, p
.policy
);
436 bool ParamTraits
<content::Referrer
>::Read(
437 const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
438 return ReadParam(m
, iter
, &r
->url
) && ReadParam(m
, iter
, &r
->policy
);
441 void ParamTraits
<content::Referrer
>::Log(
442 const param_type
& p
, std::string
* l
) {
446 LogParam(p
.policy
, l
);
450 void ParamTraits
<gfx::Point
>::Write(Message
* m
, const gfx::Point
& p
) {
455 bool ParamTraits
<gfx::Point
>::Read(const Message
* m
, PickleIterator
* iter
,
458 if (!m
->ReadInt(iter
, &x
) ||
459 !m
->ReadInt(iter
, &y
))
466 void ParamTraits
<gfx::Point
>::Log(const gfx::Point
& p
, std::string
* l
) {
467 l
->append(base::StringPrintf("(%d, %d)", p
.x(), p
.y()));
470 void ParamTraits
<gfx::Size
>::Write(Message
* m
, const gfx::Size
& p
) {
471 m
->WriteInt(p
.width());
472 m
->WriteInt(p
.height());
475 bool ParamTraits
<gfx::Size
>::Read(const Message
* m
,
476 PickleIterator
* iter
,
479 if (!m
->ReadInt(iter
, &w
) ||
480 !m
->ReadInt(iter
, &h
))
487 void ParamTraits
<gfx::Size
>::Log(const gfx::Size
& p
, std::string
* l
) {
488 l
->append(base::StringPrintf("(%d, %d)", p
.width(), p
.height()));
491 void ParamTraits
<gfx::Rect
>::Write(Message
* m
, const gfx::Rect
& p
) {
494 m
->WriteInt(p
.width());
495 m
->WriteInt(p
.height());
498 bool ParamTraits
<gfx::Rect
>::Read(const Message
* m
,
499 PickleIterator
* iter
,
502 if (!m
->ReadInt(iter
, &x
) ||
503 !m
->ReadInt(iter
, &y
) ||
504 !m
->ReadInt(iter
, &w
) ||
505 !m
->ReadInt(iter
, &h
))
514 void ParamTraits
<gfx::Rect
>::Log(const gfx::Rect
& p
, std::string
* l
) {
515 l
->append(base::StringPrintf("(%d, %d, %d, %d)", p
.x(), p
.y(),
516 p
.width(), p
.height()));
519 void ParamTraits
<gfx::RectF
>::Write(Message
* m
, const gfx::RectF
& p
) {
520 ParamTraits
<float>::Write(m
, p
.x());
521 ParamTraits
<float>::Write(m
, p
.y());
522 ParamTraits
<float>::Write(m
, p
.width());
523 ParamTraits
<float>::Write(m
, p
.height());
526 bool ParamTraits
<gfx::RectF
>::Read(const Message
* m
,
527 PickleIterator
* iter
,
530 if (!ParamTraits
<float>::Read(m
, iter
, &x
) ||
531 !ParamTraits
<float>::Read(m
, iter
, &y
) ||
532 !ParamTraits
<float>::Read(m
, iter
, &w
) ||
533 !ParamTraits
<float>::Read(m
, iter
, &h
))
542 void ParamTraits
<gfx::RectF
>::Log(const gfx::RectF
& p
, std::string
* l
) {
543 l
->append(base::StringPrintf("(%f, %f, %f, %f)", p
.x(), p
.y(),
544 p
.width(), p
.height()));
547 void ParamTraits
<ui::Range
>::Write(Message
* m
, const ui::Range
& r
) {
548 m
->WriteUInt64(r
.start());
549 m
->WriteUInt64(r
.end());
552 bool ParamTraits
<ui::Range
>::Read(const Message
* m
,
553 PickleIterator
* iter
,
556 if (!m
->ReadUInt64(iter
, &start
) || !m
->ReadUInt64(iter
, &end
))
563 void ParamTraits
<ui::Range
>::Log(const ui::Range
& r
, std::string
* l
) {
564 l
->append(base::StringPrintf("(%"PRIuS
", %"PRIuS
")", r
.start(), r
.end()));
567 void ParamTraits
<SkBitmap
>::Write(Message
* m
, const SkBitmap
& p
) {
568 size_t fixed_size
= sizeof(SkBitmap_Data
);
569 SkBitmap_Data bmp_data
;
570 bmp_data
.InitSkBitmapDataForTransfer(p
);
571 m
->WriteData(reinterpret_cast<const char*>(&bmp_data
),
572 static_cast<int>(fixed_size
));
573 size_t pixel_size
= p
.getSize();
574 SkAutoLockPixels
p_lock(p
);
575 m
->WriteData(reinterpret_cast<const char*>(p
.getPixels()),
576 static_cast<int>(pixel_size
));
579 bool ParamTraits
<SkBitmap
>::Read(const Message
* m
,
580 PickleIterator
* iter
,
582 const char* fixed_data
;
583 int fixed_data_size
= 0;
584 if (!m
->ReadData(iter
, &fixed_data
, &fixed_data_size
) ||
585 (fixed_data_size
<= 0)) {
589 if (fixed_data_size
!= sizeof(SkBitmap_Data
))
590 return false; // Message is malformed.
592 const char* variable_data
;
593 int variable_data_size
= 0;
594 if (!m
->ReadData(iter
, &variable_data
, &variable_data_size
) ||
595 (variable_data_size
< 0)) {
599 const SkBitmap_Data
* bmp_data
=
600 reinterpret_cast<const SkBitmap_Data
*>(fixed_data
);
601 return bmp_data
->InitSkBitmapFromData(r
, variable_data
, variable_data_size
);
604 void ParamTraits
<SkBitmap
>::Log(const SkBitmap
& p
, std::string
* l
) {
605 l
->append("<SkBitmap>");
610 // Generate param traits write methods.
611 #include "ipc/param_traits_write_macros.h"
613 #undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
614 #include "content/public/common/common_param_traits_macros.h"
617 // Generate param traits read methods.
618 #include "ipc/param_traits_read_macros.h"
620 #undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
621 #include "content/public/common/common_param_traits_macros.h"
624 // Generate param traits log methods.
625 #include "ipc/param_traits_log_macros.h"
627 #undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
628 #include "content/public/common/common_param_traits_macros.h"