Save errno for logging before potentially overwriting it.
[chromium-blink-merge.git] / content / public / common / common_param_traits.cc
blobf2a5c8a0e9d66798f1030cc6047a4ba0ad1872ee
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 "net/base/host_port_pair.h"
11 #include "third_party/skia/include/core/SkBitmap.h"
12 #include "ui/gfx/rect.h"
13 #include "ui/gfx/rect_f.h"
15 namespace {
17 struct SkBitmap_Data {
18 // The configuration for the bitmap (bits per pixel, etc).
19 SkBitmap::Config fConfig;
21 // The width of the bitmap in pixels.
22 uint32 fWidth;
24 // The height of the bitmap in pixels.
25 uint32 fHeight;
27 void InitSkBitmapDataForTransfer(const SkBitmap& bitmap) {
28 fConfig = bitmap.config();
29 fWidth = bitmap.width();
30 fHeight = bitmap.height();
33 // Returns whether |bitmap| successfully initialized.
34 bool InitSkBitmapFromData(SkBitmap* bitmap, const char* pixels,
35 size_t total_pixels) const {
36 if (total_pixels) {
37 bitmap->setConfig(fConfig, fWidth, fHeight, 0);
38 if (!bitmap->allocPixels())
39 return false;
40 if (total_pixels != bitmap->getSize())
41 return false;
42 memcpy(bitmap->getPixels(), pixels, total_pixels);
44 return true;
48 } // namespace
50 namespace IPC {
52 void ParamTraits<GURL>::Write(Message* m, const GURL& p) {
53 DCHECK(p.possibly_invalid_spec().length() <= content::kMaxURLChars);
55 // Beware of print-parse inconsistency which would change an invalid
56 // URL into a valid one. Ideally, the message would contain this flag
57 // so that the read side could make the check, but performing it here
58 // avoids changing the on-the-wire representation of such a fundamental
59 // type as GURL. See https://crbug.com/166486 for additional work in
60 // this area.
61 if (!p.is_valid()) {
62 m->WriteString(std::string());
63 return;
66 m->WriteString(p.possibly_invalid_spec());
67 // TODO(brettw) bug 684583: Add encoding for query params.
70 bool ParamTraits<GURL>::Read(const Message* m, PickleIterator* iter, GURL* p) {
71 std::string s;
72 if (!m->ReadString(iter, &s) || s.length() > content::kMaxURLChars) {
73 *p = GURL();
74 return false;
76 *p = GURL(s);
77 if (!s.empty() && !p->is_valid()) {
78 *p = GURL();
79 return false;
81 return true;
84 void ParamTraits<GURL>::Log(const GURL& p, std::string* l) {
85 l->append(p.spec());
88 void ParamTraits<net::HostPortPair>::Write(Message* m, const param_type& p) {
89 WriteParam(m, p.host());
90 WriteParam(m, p.port());
93 bool ParamTraits<net::HostPortPair>::Read(const Message* m,
94 PickleIterator* iter,
95 param_type* r) {
96 std::string host;
97 uint16 port;
98 if (!ReadParam(m, iter, &host) || !ReadParam(m, iter, &port))
99 return false;
101 r->set_host(host);
102 r->set_port(port);
103 return true;
106 void ParamTraits<net::HostPortPair>::Log(const param_type& p, std::string* l) {
107 l->append(p.ToString());
110 void ParamTraits<content::PageState>::Write(
111 Message* m, const param_type& p) {
112 WriteParam(m, p.ToEncodedData());
115 bool ParamTraits<content::PageState>::Read(
116 const Message* m, PickleIterator* iter, param_type* r) {
117 std::string data;
118 if (!ReadParam(m, iter, &data))
119 return false;
120 *r = content::PageState::CreateFromEncodedData(data);
121 return true;
124 void ParamTraits<content::PageState>::Log(
125 const param_type& p, std::string* l) {
126 l->append("(");
127 LogParam(p.ToEncodedData(), l);
128 l->append(")");
131 void ParamTraits<content::Referrer>::Write(
132 Message* m, const param_type& p) {
133 WriteParam(m, p.url);
134 WriteParam(m, p.policy);
137 bool ParamTraits<content::Referrer>::Read(
138 const Message* m, PickleIterator* iter, param_type* r) {
139 return ReadParam(m, iter, &r->url) && ReadParam(m, iter, &r->policy);
142 void ParamTraits<content::Referrer>::Log(
143 const param_type& p, std::string* l) {
144 l->append("(");
145 LogParam(p.url, l);
146 l->append(",");
147 LogParam(p.policy, l);
148 l->append(")");
151 void ParamTraits<gfx::Point>::Write(Message* m, const gfx::Point& p) {
152 m->WriteInt(p.x());
153 m->WriteInt(p.y());
156 bool ParamTraits<gfx::Point>::Read(const Message* m, PickleIterator* iter,
157 gfx::Point* r) {
158 int x, y;
159 if (!m->ReadInt(iter, &x) ||
160 !m->ReadInt(iter, &y))
161 return false;
162 r->set_x(x);
163 r->set_y(y);
164 return true;
167 void ParamTraits<gfx::Point>::Log(const gfx::Point& p, std::string* l) {
168 l->append(base::StringPrintf("(%d, %d)", p.x(), p.y()));
171 void ParamTraits<gfx::PointF>::Write(Message* m, const gfx::PointF& v) {
172 ParamTraits<float>::Write(m, v.x());
173 ParamTraits<float>::Write(m, v.y());
176 bool ParamTraits<gfx::PointF>::Read(const Message* m,
177 PickleIterator* iter,
178 gfx::PointF* r) {
179 float x, y;
180 if (!ParamTraits<float>::Read(m, iter, &x) ||
181 !ParamTraits<float>::Read(m, iter, &y))
182 return false;
183 r->set_x(x);
184 r->set_y(y);
185 return true;
188 void ParamTraits<gfx::PointF>::Log(const gfx::PointF& v, std::string* l) {
189 l->append(base::StringPrintf("(%f, %f)", v.x(), v.y()));
192 void ParamTraits<gfx::Size>::Write(Message* m, const gfx::Size& p) {
193 DCHECK_GE(p.width(), 0);
194 DCHECK_GE(p.height(), 0);
195 m->WriteInt(p.width());
196 m->WriteInt(p.height());
199 bool ParamTraits<gfx::Size>::Read(const Message* m,
200 PickleIterator* iter,
201 gfx::Size* r) {
202 int w, h;
203 if (!m->ReadInt(iter, &w) || w < 0 ||
204 !m->ReadInt(iter, &h) || h < 0)
205 return false;
206 r->set_width(w);
207 r->set_height(h);
208 return true;
211 void ParamTraits<gfx::Size>::Log(const gfx::Size& p, std::string* l) {
212 l->append(base::StringPrintf("(%d, %d)", p.width(), p.height()));
215 void ParamTraits<gfx::SizeF>::Write(Message* m, const gfx::SizeF& p) {
216 ParamTraits<float>::Write(m, p.width());
217 ParamTraits<float>::Write(m, p.height());
220 bool ParamTraits<gfx::SizeF>::Read(const Message* m,
221 PickleIterator* iter,
222 gfx::SizeF* p) {
223 float w, h;
224 if (!ParamTraits<float>::Read(m, iter, &w) ||
225 !ParamTraits<float>::Read(m, iter, &h))
226 return false;
227 p->set_width(w);
228 p->set_height(h);
229 return true;
232 void ParamTraits<gfx::SizeF>::Log(const gfx::SizeF& p, std::string* l) {
233 l->append(base::StringPrintf("(%f, %f)", p.width(), p.height()));
236 void ParamTraits<gfx::Vector2d>::Write(Message* m, const gfx::Vector2d& v) {
237 m->WriteInt(v.x());
238 m->WriteInt(v.y());
241 bool ParamTraits<gfx::Vector2d>::Read(const Message* m,
242 PickleIterator* iter,
243 gfx::Vector2d* r) {
244 int x, y;
245 if (!m->ReadInt(iter, &x) ||
246 !m->ReadInt(iter, &y))
247 return false;
248 r->set_x(x);
249 r->set_y(y);
250 return true;
253 void ParamTraits<gfx::Vector2d>::Log(const gfx::Vector2d& v, std::string* l) {
254 l->append(base::StringPrintf("(%d, %d)", v.x(), v.y()));
257 void ParamTraits<gfx::Vector2dF>::Write(Message* m, const gfx::Vector2dF& v) {
258 ParamTraits<float>::Write(m, v.x());
259 ParamTraits<float>::Write(m, v.y());
262 bool ParamTraits<gfx::Vector2dF>::Read(const Message* m,
263 PickleIterator* iter,
264 gfx::Vector2dF* r) {
265 float x, y;
266 if (!ParamTraits<float>::Read(m, iter, &x) ||
267 !ParamTraits<float>::Read(m, iter, &y))
268 return false;
269 r->set_x(x);
270 r->set_y(y);
271 return true;
274 void ParamTraits<gfx::Vector2dF>::Log(const gfx::Vector2dF& v, std::string* l) {
275 l->append(base::StringPrintf("(%f, %f)", v.x(), v.y()));
278 void ParamTraits<gfx::Rect>::Write(Message* m, const gfx::Rect& p) {
279 WriteParam(m, p.origin());
280 WriteParam(m, p.size());
283 bool ParamTraits<gfx::Rect>::Read(const Message* m,
284 PickleIterator* iter,
285 gfx::Rect* r) {
286 gfx::Point origin;
287 gfx::Size size;
288 if (!ReadParam(m, iter, &origin) ||
289 !ReadParam(m, iter, &size))
290 return false;
291 r->set_origin(origin);
292 r->set_size(size);
293 return true;
296 void ParamTraits<gfx::Rect>::Log(const gfx::Rect& p, std::string* l) {
297 l->append(base::StringPrintf("(%d, %d, %d, %d)", p.x(), p.y(),
298 p.width(), p.height()));
301 void ParamTraits<gfx::RectF>::Write(Message* m, const gfx::RectF& p) {
302 ParamTraits<float>::Write(m, p.x());
303 ParamTraits<float>::Write(m, p.y());
304 ParamTraits<float>::Write(m, p.width());
305 ParamTraits<float>::Write(m, p.height());
308 bool ParamTraits<gfx::RectF>::Read(const Message* m,
309 PickleIterator* iter,
310 gfx::RectF* r) {
311 float x, y, w, h;
312 if (!ParamTraits<float>::Read(m, iter, &x) ||
313 !ParamTraits<float>::Read(m, iter, &y) ||
314 !ParamTraits<float>::Read(m, iter, &w) ||
315 !ParamTraits<float>::Read(m, iter, &h))
316 return false;
317 r->set_x(x);
318 r->set_y(y);
319 r->set_width(w);
320 r->set_height(h);
321 return true;
324 void ParamTraits<gfx::RectF>::Log(const gfx::RectF& p, std::string* l) {
325 l->append(base::StringPrintf("(%f, %f, %f, %f)", p.x(), p.y(),
326 p.width(), p.height()));
329 void ParamTraits<SkBitmap>::Write(Message* m, const SkBitmap& p) {
330 size_t fixed_size = sizeof(SkBitmap_Data);
331 SkBitmap_Data bmp_data;
332 bmp_data.InitSkBitmapDataForTransfer(p);
333 m->WriteData(reinterpret_cast<const char*>(&bmp_data),
334 static_cast<int>(fixed_size));
335 size_t pixel_size = p.getSize();
336 SkAutoLockPixels p_lock(p);
337 m->WriteData(reinterpret_cast<const char*>(p.getPixels()),
338 static_cast<int>(pixel_size));
341 bool ParamTraits<SkBitmap>::Read(const Message* m,
342 PickleIterator* iter,
343 SkBitmap* r) {
344 const char* fixed_data;
345 int fixed_data_size = 0;
346 if (!m->ReadData(iter, &fixed_data, &fixed_data_size) ||
347 (fixed_data_size <= 0)) {
348 NOTREACHED();
349 return false;
351 if (fixed_data_size != sizeof(SkBitmap_Data))
352 return false; // Message is malformed.
354 const char* variable_data;
355 int variable_data_size = 0;
356 if (!m->ReadData(iter, &variable_data, &variable_data_size) ||
357 (variable_data_size < 0)) {
358 NOTREACHED();
359 return false;
361 const SkBitmap_Data* bmp_data =
362 reinterpret_cast<const SkBitmap_Data*>(fixed_data);
363 return bmp_data->InitSkBitmapFromData(r, variable_data, variable_data_size);
366 void ParamTraits<SkBitmap>::Log(const SkBitmap& p, std::string* l) {
367 l->append("<SkBitmap>");
370 } // namespace IPC
372 // Generate param traits write methods.
373 #include "ipc/param_traits_write_macros.h"
374 namespace IPC {
375 #undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
376 #include "content/public/common/common_param_traits_macros.h"
377 } // namespace IPC
379 // Generate param traits read methods.
380 #include "ipc/param_traits_read_macros.h"
381 namespace IPC {
382 #undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
383 #include "content/public/common/common_param_traits_macros.h"
384 } // namespace IPC
386 // Generate param traits log methods.
387 #include "ipc/param_traits_log_macros.h"
388 namespace IPC {
389 #undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
390 #include "content/public/common/common_param_traits_macros.h"
391 } // namespace IPC