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"
9 #include "content/public/common/content_constants.h"
10 #include "content/public/common/page_state.h"
11 #include "content/public/common/referrer.h"
12 #include "content/public/common/url_utils.h"
13 #include "net/base/host_port_pair.h"
14 #include "net/base/ip_endpoint.h"
15 #include "third_party/skia/include/core/SkBitmap.h"
16 #include "ui/gfx/rect.h"
17 #include "ui/gfx/rect_f.h"
21 struct SkBitmap_Data
{
22 // The configuration for the bitmap (bits per pixel, etc).
23 SkBitmap::Config fConfig
;
25 // The width of the bitmap in pixels.
28 // The height of the bitmap in pixels.
31 void InitSkBitmapDataForTransfer(const SkBitmap
& bitmap
) {
32 fConfig
= bitmap
.config();
33 fWidth
= bitmap
.width();
34 fHeight
= bitmap
.height();
37 // Returns whether |bitmap| successfully initialized.
38 bool InitSkBitmapFromData(SkBitmap
* bitmap
, const char* pixels
,
39 size_t total_pixels
) const {
41 bitmap
->setConfig(fConfig
, fWidth
, fHeight
, 0);
42 if (!bitmap
->allocPixels())
44 if (total_pixels
!= bitmap
->getSize())
46 memcpy(bitmap
->getPixels(), pixels
, total_pixels
);
56 void ParamTraits
<GURL
>::Write(Message
* m
, const GURL
& p
) {
57 DCHECK(p
.possibly_invalid_spec().length() <= content::GetMaxURLChars());
59 // Beware of print-parse inconsistency which would change an invalid
60 // URL into a valid one. Ideally, the message would contain this flag
61 // so that the read side could make the check, but performing it here
62 // avoids changing the on-the-wire representation of such a fundamental
63 // type as GURL. See https://crbug.com/166486 for additional work in
66 m
->WriteString(std::string());
70 m
->WriteString(p
.possibly_invalid_spec());
71 // TODO(brettw) bug 684583: Add encoding for query params.
74 bool ParamTraits
<GURL
>::Read(const Message
* m
, PickleIterator
* iter
, GURL
* p
) {
76 if (!m
->ReadString(iter
, &s
) || s
.length() > content::GetMaxURLChars()) {
81 if (!s
.empty() && !p
->is_valid()) {
88 void ParamTraits
<GURL
>::Log(const GURL
& p
, std::string
* l
) {
92 void ParamTraits
<url::Origin
>::Write(Message
* m
,
93 const url::Origin
& p
) {
94 m
->WriteString(p
.string());
97 bool ParamTraits
<url::Origin
>::Read(const Message
* m
,
101 if (!m
->ReadString(iter
, &s
)) {
109 void ParamTraits
<url::Origin
>::Log(const url::Origin
& p
, std::string
* l
) {
110 l
->append(p
.string());
113 void ParamTraits
<net::HostPortPair
>::Write(Message
* m
, const param_type
& p
) {
114 WriteParam(m
, p
.host());
115 WriteParam(m
, p
.port());
118 bool ParamTraits
<net::HostPortPair
>::Read(const Message
* m
,
119 PickleIterator
* iter
,
123 if (!ReadParam(m
, iter
, &host
) || !ReadParam(m
, iter
, &port
))
131 void ParamTraits
<net::HostPortPair
>::Log(const param_type
& p
, std::string
* l
) {
132 l
->append(p
.ToString());
135 void ParamTraits
<net::IPEndPoint
>::Write(Message
* m
, const param_type
& p
) {
136 WriteParam(m
, p
.address());
137 WriteParam(m
, p
.port());
140 bool ParamTraits
<net::IPEndPoint
>::Read(const Message
* m
, PickleIterator
* iter
,
142 net::IPAddressNumber address
;
144 if (!ReadParam(m
, iter
, &address
) || !ReadParam(m
, iter
, &port
))
146 if (address
.size() &&
147 address
.size() != net::kIPv4AddressSize
&&
148 address
.size() != net::kIPv6AddressSize
) {
151 *p
= net::IPEndPoint(address
, port
);
155 void ParamTraits
<net::IPEndPoint
>::Log(const param_type
& p
, std::string
* l
) {
156 LogParam("IPEndPoint:" + p
.ToString(), l
);
159 void ParamTraits
<content::PageState
>::Write(
160 Message
* m
, const param_type
& p
) {
161 WriteParam(m
, p
.ToEncodedData());
164 bool ParamTraits
<content::PageState
>::Read(
165 const Message
* m
, PickleIterator
* iter
, param_type
* r
) {
167 if (!ReadParam(m
, iter
, &data
))
169 *r
= content::PageState::CreateFromEncodedData(data
);
173 void ParamTraits
<content::PageState
>::Log(
174 const param_type
& p
, std::string
* l
) {
176 LogParam(p
.ToEncodedData(), l
);
180 void ParamTraits
<gfx::Point
>::Write(Message
* m
, const gfx::Point
& p
) {
185 bool ParamTraits
<gfx::Point
>::Read(const Message
* m
, PickleIterator
* iter
,
188 if (!m
->ReadInt(iter
, &x
) ||
189 !m
->ReadInt(iter
, &y
))
196 void ParamTraits
<gfx::Point
>::Log(const gfx::Point
& p
, std::string
* l
) {
197 l
->append(base::StringPrintf("(%d, %d)", p
.x(), p
.y()));
200 void ParamTraits
<gfx::PointF
>::Write(Message
* m
, const gfx::PointF
& v
) {
201 ParamTraits
<float>::Write(m
, v
.x());
202 ParamTraits
<float>::Write(m
, v
.y());
205 bool ParamTraits
<gfx::PointF
>::Read(const Message
* m
,
206 PickleIterator
* iter
,
209 if (!ParamTraits
<float>::Read(m
, iter
, &x
) ||
210 !ParamTraits
<float>::Read(m
, iter
, &y
))
217 void ParamTraits
<gfx::PointF
>::Log(const gfx::PointF
& v
, std::string
* l
) {
218 l
->append(base::StringPrintf("(%f, %f)", v
.x(), v
.y()));
221 void ParamTraits
<gfx::Size
>::Write(Message
* m
, const gfx::Size
& p
) {
222 DCHECK_GE(p
.width(), 0);
223 DCHECK_GE(p
.height(), 0);
224 int values
[2] = { p
.width(), p
.height() };
225 m
->WriteBytes(&values
, sizeof(int) * 2);
228 bool ParamTraits
<gfx::Size
>::Read(const Message
* m
,
229 PickleIterator
* iter
,
231 const char* char_values
;
232 if (!m
->ReadBytes(iter
, &char_values
, sizeof(int) * 2))
234 const int* values
= reinterpret_cast<const int*>(char_values
);
235 if (values
[0] < 0 || values
[1] < 0)
237 r
->set_width(values
[0]);
238 r
->set_height(values
[1]);
242 void ParamTraits
<gfx::Size
>::Log(const gfx::Size
& p
, std::string
* l
) {
243 l
->append(base::StringPrintf("(%d, %d)", p
.width(), p
.height()));
246 void ParamTraits
<gfx::SizeF
>::Write(Message
* m
, const gfx::SizeF
& p
) {
247 float values
[2] = { p
.width(), p
.height() };
248 m
->WriteBytes(&values
, sizeof(float) * 2);
251 bool ParamTraits
<gfx::SizeF
>::Read(const Message
* m
,
252 PickleIterator
* iter
,
254 const char* char_values
;
255 if (!m
->ReadBytes(iter
, &char_values
, sizeof(float) * 2))
257 const float* values
= reinterpret_cast<const float*>(char_values
);
258 r
->set_width(values
[0]);
259 r
->set_height(values
[1]);
263 void ParamTraits
<gfx::SizeF
>::Log(const gfx::SizeF
& p
, std::string
* l
) {
264 l
->append(base::StringPrintf("(%f, %f)", p
.width(), p
.height()));
267 void ParamTraits
<gfx::Vector2d
>::Write(Message
* m
, const gfx::Vector2d
& p
) {
268 int values
[2] = { p
.x(), p
.y() };
269 m
->WriteBytes(&values
, sizeof(int) * 2);
272 bool ParamTraits
<gfx::Vector2d
>::Read(const Message
* m
,
273 PickleIterator
* iter
,
275 const char* char_values
;
276 if (!m
->ReadBytes(iter
, &char_values
, sizeof(int) * 2))
278 const int* values
= reinterpret_cast<const int*>(char_values
);
284 void ParamTraits
<gfx::Vector2d
>::Log(const gfx::Vector2d
& v
, std::string
* l
) {
285 l
->append(base::StringPrintf("(%d, %d)", v
.x(), v
.y()));
288 void ParamTraits
<gfx::Vector2dF
>::Write(Message
* m
, const gfx::Vector2dF
& p
) {
289 float values
[2] = { p
.x(), p
.y() };
290 m
->WriteBytes(&values
, sizeof(float) * 2);
293 bool ParamTraits
<gfx::Vector2dF
>::Read(const Message
* m
,
294 PickleIterator
* iter
,
296 const char* char_values
;
297 if (!m
->ReadBytes(iter
, &char_values
, sizeof(float) * 2))
299 const float* values
= reinterpret_cast<const float*>(char_values
);
305 void ParamTraits
<gfx::Vector2dF
>::Log(const gfx::Vector2dF
& v
, std::string
* l
) {
306 l
->append(base::StringPrintf("(%f, %f)", v
.x(), v
.y()));
309 void ParamTraits
<gfx::Rect
>::Write(Message
* m
, const gfx::Rect
& p
) {
310 int values
[4] = { p
.x(), p
.y(), p
.width(), p
.height() };
311 m
->WriteBytes(&values
, sizeof(int) * 4);
314 bool ParamTraits
<gfx::Rect
>::Read(const Message
* m
,
315 PickleIterator
* iter
,
317 const char* char_values
;
318 if (!m
->ReadBytes(iter
, &char_values
, sizeof(int) * 4))
320 const int* values
= reinterpret_cast<const int*>(char_values
);
321 if (values
[2] < 0 || values
[3] < 0)
323 r
->SetRect(values
[0], values
[1], values
[2], values
[3]);
327 void ParamTraits
<gfx::Rect
>::Log(const gfx::Rect
& p
, std::string
* l
) {
328 l
->append(base::StringPrintf("(%d, %d, %d, %d)", p
.x(), p
.y(),
329 p
.width(), p
.height()));
332 void ParamTraits
<gfx::RectF
>::Write(Message
* m
, const gfx::RectF
& p
) {
333 float values
[4] = { p
.x(), p
.y(), p
.width(), p
.height() };
334 m
->WriteBytes(&values
, sizeof(float) * 4);
337 bool ParamTraits
<gfx::RectF
>::Read(const Message
* m
,
338 PickleIterator
* iter
,
340 const char* char_values
;
341 if (!m
->ReadBytes(iter
, &char_values
, sizeof(float) * 4))
343 const float* values
= reinterpret_cast<const float*>(char_values
);
344 r
->SetRect(values
[0], values
[1], values
[2], values
[3]);
348 void ParamTraits
<gfx::RectF
>::Log(const gfx::RectF
& p
, std::string
* l
) {
349 l
->append(base::StringPrintf("(%f, %f, %f, %f)", p
.x(), p
.y(),
350 p
.width(), p
.height()));
353 void ParamTraits
<SkBitmap
>::Write(Message
* m
, const SkBitmap
& p
) {
354 size_t fixed_size
= sizeof(SkBitmap_Data
);
355 SkBitmap_Data bmp_data
;
356 bmp_data
.InitSkBitmapDataForTransfer(p
);
357 m
->WriteData(reinterpret_cast<const char*>(&bmp_data
),
358 static_cast<int>(fixed_size
));
359 size_t pixel_size
= p
.getSize();
360 SkAutoLockPixels
p_lock(p
);
361 m
->WriteData(reinterpret_cast<const char*>(p
.getPixels()),
362 static_cast<int>(pixel_size
));
365 bool ParamTraits
<SkBitmap
>::Read(const Message
* m
,
366 PickleIterator
* iter
,
368 const char* fixed_data
;
369 int fixed_data_size
= 0;
370 if (!m
->ReadData(iter
, &fixed_data
, &fixed_data_size
) ||
371 (fixed_data_size
<= 0)) {
375 if (fixed_data_size
!= sizeof(SkBitmap_Data
))
376 return false; // Message is malformed.
378 const char* variable_data
;
379 int variable_data_size
= 0;
380 if (!m
->ReadData(iter
, &variable_data
, &variable_data_size
) ||
381 (variable_data_size
< 0)) {
385 const SkBitmap_Data
* bmp_data
=
386 reinterpret_cast<const SkBitmap_Data
*>(fixed_data
);
387 return bmp_data
->InitSkBitmapFromData(r
, variable_data
, variable_data_size
);
390 void ParamTraits
<SkBitmap
>::Log(const SkBitmap
& p
, std::string
* l
) {
391 l
->append("<SkBitmap>");
396 // Generate param traits write methods.
397 #include "ipc/param_traits_write_macros.h"
399 #undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
400 #include "content/public/common/common_param_traits_macros.h"
403 // Generate param traits read methods.
404 #include "ipc/param_traits_read_macros.h"
406 #undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
407 #include "content/public/common/common_param_traits_macros.h"
410 // Generate param traits log methods.
411 #include "ipc/param_traits_log_macros.h"
413 #undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
414 #include "content/public/common/common_param_traits_macros.h"