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/page_state.h"
9 #include "content/public/common/referrer.h"
10 #include "content/public/common/url_utils.h"
11 #include "net/base/host_port_pair.h"
12 #include "net/base/ip_endpoint.h"
13 #include "third_party/skia/include/core/SkBitmap.h"
14 #include "ui/gfx/rect.h"
15 #include "ui/gfx/rect_f.h"
19 struct SkBitmap_Data {
20 // The configuration for the bitmap (bits per pixel, etc).
21 SkBitmap::Config fConfig;
23 // The width of the bitmap in pixels.
26 // The height of the bitmap in pixels.
29 void InitSkBitmapDataForTransfer(const SkBitmap& bitmap) {
30 fConfig = bitmap.config();
31 fWidth = bitmap.width();
32 fHeight = bitmap.height();
35 // Returns whether |bitmap| successfully initialized.
36 bool InitSkBitmapFromData(SkBitmap* bitmap, const char* pixels,
37 size_t total_pixels) const {
39 bitmap->setConfig(fConfig, fWidth, fHeight, 0);
40 if (!bitmap->allocPixels())
42 if (total_pixels != bitmap->getSize())
44 memcpy(bitmap->getPixels(), pixels, total_pixels);
54 void ParamTraits<GURL>::Write(Message* m, const GURL& p) {
55 DCHECK(p.possibly_invalid_spec().length() <= content::GetMaxURLChars());
57 // Beware of print-parse inconsistency which would change an invalid
58 // URL into a valid one. Ideally, the message would contain this flag
59 // so that the read side could make the check, but performing it here
60 // avoids changing the on-the-wire representation of such a fundamental
61 // type as GURL. See https://crbug.com/166486 for additional work in
64 m->WriteString(std::string());
68 m->WriteString(p.possibly_invalid_spec());
69 // TODO(brettw) bug 684583: Add encoding for query params.
72 bool ParamTraits<GURL>::Read(const Message* m, PickleIterator* iter, GURL* p) {
74 if (!m->ReadString(iter, &s) || s.length() > content::GetMaxURLChars()) {
79 if (!s.empty() && !p->is_valid()) {
86 void ParamTraits<GURL>::Log(const GURL& p, std::string* l) {
90 void ParamTraits<net::HostPortPair>::Write(Message* m, const param_type& p) {
91 WriteParam(m, p.host());
92 WriteParam(m, p.port());
95 bool ParamTraits<net::HostPortPair>::Read(const Message* m,
100 if (!ReadParam(m, iter, &host) || !ReadParam(m, iter, &port))
108 void ParamTraits<net::HostPortPair>::Log(const param_type& p, std::string* l) {
109 l->append(p.ToString());
112 void ParamTraits<net::IPEndPoint>::Write(Message* m, const param_type& p) {
113 WriteParam(m, p.address());
114 WriteParam(m, p.port());
117 bool ParamTraits<net::IPEndPoint>::Read(const Message* m, PickleIterator* iter,
119 net::IPAddressNumber address;
121 if (!ReadParam(m, iter, &address) || !ReadParam(m, iter, &port))
123 *p = net::IPEndPoint(address, port);
127 void ParamTraits<net::IPEndPoint>::Log(const param_type& p, std::string* l) {
128 LogParam("IPEndPoint:" + p.ToString(), l);
131 void ParamTraits<content::PageState>::Write(
132 Message* m, const param_type& p) {
133 WriteParam(m, p.ToEncodedData());
136 bool ParamTraits<content::PageState>::Read(
137 const Message* m, PickleIterator* iter, param_type* r) {
139 if (!ReadParam(m, iter, &data))
141 *r = content::PageState::CreateFromEncodedData(data);
145 void ParamTraits<content::PageState>::Log(
146 const param_type& p, std::string* l) {
148 LogParam(p.ToEncodedData(), l);
152 void ParamTraits<gfx::Point>::Write(Message* m, const gfx::Point& p) {
157 bool ParamTraits<gfx::Point>::Read(const Message* m, PickleIterator* iter,
160 if (!m->ReadInt(iter, &x) ||
161 !m->ReadInt(iter, &y))
168 void ParamTraits<gfx::Point>::Log(const gfx::Point& p, std::string* l) {
169 l->append(base::StringPrintf("(%d, %d)", p.x(), p.y()));
172 void ParamTraits<gfx::PointF>::Write(Message* m, const gfx::PointF& v) {
173 ParamTraits<float>::Write(m, v.x());
174 ParamTraits<float>::Write(m, v.y());
177 bool ParamTraits<gfx::PointF>::Read(const Message* m,
178 PickleIterator* iter,
181 if (!ParamTraits<float>::Read(m, iter, &x) ||
182 !ParamTraits<float>::Read(m, iter, &y))
189 void ParamTraits<gfx::PointF>::Log(const gfx::PointF& v, std::string* l) {
190 l->append(base::StringPrintf("(%f, %f)", v.x(), v.y()));
193 void ParamTraits<gfx::Size>::Write(Message* m, const gfx::Size& p) {
194 DCHECK_GE(p.width(), 0);
195 DCHECK_GE(p.height(), 0);
196 int values[2] = { p.width(), p.height() };
197 m->WriteBytes(&values, sizeof(int) * 2);
200 bool ParamTraits<gfx::Size>::Read(const Message* m,
201 PickleIterator* iter,
203 const char* char_values;
204 if (!m->ReadBytes(iter, &char_values, sizeof(int) * 2))
206 const int* values = reinterpret_cast<const int*>(char_values);
207 if (values[0] < 0 || values[1] < 0)
209 r->set_width(values[0]);
210 r->set_height(values[1]);
214 void ParamTraits<gfx::Size>::Log(const gfx::Size& p, std::string* l) {
215 l->append(base::StringPrintf("(%d, %d)", p.width(), p.height()));
218 void ParamTraits<gfx::SizeF>::Write(Message* m, const gfx::SizeF& p) {
219 float values[2] = { p.width(), p.height() };
220 m->WriteBytes(&values, sizeof(float) * 2);
223 bool ParamTraits<gfx::SizeF>::Read(const Message* m,
224 PickleIterator* iter,
226 const char* char_values;
227 if (!m->ReadBytes(iter, &char_values, sizeof(float) * 2))
229 const float* values = reinterpret_cast<const float*>(char_values);
230 r->set_width(values[0]);
231 r->set_height(values[1]);
235 void ParamTraits<gfx::SizeF>::Log(const gfx::SizeF& p, std::string* l) {
236 l->append(base::StringPrintf("(%f, %f)", p.width(), p.height()));
239 void ParamTraits<gfx::Vector2d>::Write(Message* m, const gfx::Vector2d& p) {
240 int values[2] = { p.x(), p.y() };
241 m->WriteBytes(&values, sizeof(int) * 2);
244 bool ParamTraits<gfx::Vector2d>::Read(const Message* m,
245 PickleIterator* iter,
247 const char* char_values;
248 if (!m->ReadBytes(iter, &char_values, sizeof(int) * 2))
250 const int* values = reinterpret_cast<const int*>(char_values);
256 void ParamTraits<gfx::Vector2d>::Log(const gfx::Vector2d& v, std::string* l) {
257 l->append(base::StringPrintf("(%d, %d)", v.x(), v.y()));
260 void ParamTraits<gfx::Vector2dF>::Write(Message* m, const gfx::Vector2dF& p) {
261 float values[2] = { p.x(), p.y() };
262 m->WriteBytes(&values, sizeof(float) * 2);
265 bool ParamTraits<gfx::Vector2dF>::Read(const Message* m,
266 PickleIterator* iter,
268 const char* char_values;
269 if (!m->ReadBytes(iter, &char_values, sizeof(float) * 2))
271 const float* values = reinterpret_cast<const float*>(char_values);
277 void ParamTraits<gfx::Vector2dF>::Log(const gfx::Vector2dF& v, std::string* l) {
278 l->append(base::StringPrintf("(%f, %f)", v.x(), v.y()));
281 void ParamTraits<gfx::Rect>::Write(Message* m, const gfx::Rect& p) {
282 int values[4] = { p.x(), p.y(), p.width(), p.height() };
283 m->WriteBytes(&values, sizeof(int) * 4);
286 bool ParamTraits<gfx::Rect>::Read(const Message* m,
287 PickleIterator* iter,
289 const char* char_values;
290 if (!m->ReadBytes(iter, &char_values, sizeof(int) * 4))
292 const int* values = reinterpret_cast<const int*>(char_values);
293 if (values[2] < 0 || values[3] < 0)
295 r->SetRect(values[0], values[1], values[2], values[3]);
299 void ParamTraits<gfx::Rect>::Log(const gfx::Rect& p, std::string* l) {
300 l->append(base::StringPrintf("(%d, %d, %d, %d)", p.x(), p.y(),
301 p.width(), p.height()));
304 void ParamTraits<gfx::RectF>::Write(Message* m, const gfx::RectF& p) {
305 float values[4] = { p.x(), p.y(), p.width(), p.height() };
306 m->WriteBytes(&values, sizeof(float) * 4);
309 bool ParamTraits<gfx::RectF>::Read(const Message* m,
310 PickleIterator* iter,
312 const char* char_values;
313 if (!m->ReadBytes(iter, &char_values, sizeof(float) * 4))
315 const float* values = reinterpret_cast<const float*>(char_values);
316 r->SetRect(values[0], values[1], values[2], values[3]);
320 void ParamTraits<gfx::RectF>::Log(const gfx::RectF& p, std::string* l) {
321 l->append(base::StringPrintf("(%f, %f, %f, %f)", p.x(), p.y(),
322 p.width(), p.height()));
325 void ParamTraits<SkBitmap>::Write(Message* m, const SkBitmap& p) {
326 size_t fixed_size = sizeof(SkBitmap_Data);
327 SkBitmap_Data bmp_data;
328 bmp_data.InitSkBitmapDataForTransfer(p);
329 m->WriteData(reinterpret_cast<const char*>(&bmp_data),
330 static_cast<int>(fixed_size));
331 size_t pixel_size = p.getSize();
332 SkAutoLockPixels p_lock(p);
333 m->WriteData(reinterpret_cast<const char*>(p.getPixels()),
334 static_cast<int>(pixel_size));
337 bool ParamTraits<SkBitmap>::Read(const Message* m,
338 PickleIterator* iter,
340 const char* fixed_data;
341 int fixed_data_size = 0;
342 if (!m->ReadData(iter, &fixed_data, &fixed_data_size) ||
343 (fixed_data_size <= 0)) {
347 if (fixed_data_size != sizeof(SkBitmap_Data))
348 return false; // Message is malformed.
350 const char* variable_data;
351 int variable_data_size = 0;
352 if (!m->ReadData(iter, &variable_data, &variable_data_size) ||
353 (variable_data_size < 0)) {
357 const SkBitmap_Data* bmp_data =
358 reinterpret_cast<const SkBitmap_Data*>(fixed_data);
359 return bmp_data->InitSkBitmapFromData(r, variable_data, variable_data_size);
362 void ParamTraits<SkBitmap>::Log(const SkBitmap& p, std::string* l) {
363 l->append("<SkBitmap>");
368 // Generate param traits write methods.
369 #include "ipc/param_traits_write_macros.h"
371 #undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
372 #include "content/public/common/common_param_traits_macros.h"
375 // Generate param traits read methods.
376 #include "ipc/param_traits_read_macros.h"
378 #undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
379 #include "content/public/common/common_param_traits_macros.h"
382 // Generate param traits log methods.
383 #include "ipc/param_traits_log_macros.h"
385 #undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
386 #include "content/public/common/common_param_traits_macros.h"