7c47ab53907ae1b3c38154e6392244cdedff7fae
[platform/framework/web/crosswalk.git] / src / content / public / common / common_param_traits.cc
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.
4
5 #include "content/public/common/common_param_traits.h"
6
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"
16
17 namespace {
18
19 struct SkBitmap_Data {
20   // The configuration for the bitmap (bits per pixel, etc).
21   SkBitmap::Config fConfig;
22
23   // The width of the bitmap in pixels.
24   uint32 fWidth;
25
26   // The height of the bitmap in pixels.
27   uint32 fHeight;
28
29   void InitSkBitmapDataForTransfer(const SkBitmap& bitmap) {
30     fConfig = bitmap.config();
31     fWidth = bitmap.width();
32     fHeight = bitmap.height();
33   }
34
35   // Returns whether |bitmap| successfully initialized.
36   bool InitSkBitmapFromData(SkBitmap* bitmap, const char* pixels,
37                             size_t total_pixels) const {
38     if (total_pixels) {
39       bitmap->setConfig(fConfig, fWidth, fHeight, 0);
40       if (!bitmap->allocPixels())
41         return false;
42       if (total_pixels != bitmap->getSize())
43         return false;
44       memcpy(bitmap->getPixels(), pixels, total_pixels);
45     }
46     return true;
47   }
48 };
49
50 }  // namespace
51
52 namespace IPC {
53
54 void ParamTraits<GURL>::Write(Message* m, const GURL& p) {
55   DCHECK(p.possibly_invalid_spec().length() <= content::GetMaxURLChars());
56
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
62   // this area.
63   if (!p.is_valid()) {
64     m->WriteString(std::string());
65     return;
66   }
67
68   m->WriteString(p.possibly_invalid_spec());
69   // TODO(brettw) bug 684583: Add encoding for query params.
70 }
71
72 bool ParamTraits<GURL>::Read(const Message* m, PickleIterator* iter, GURL* p) {
73   std::string s;
74   if (!m->ReadString(iter, &s) || s.length() > content::GetMaxURLChars()) {
75     *p = GURL();
76     return false;
77   }
78   *p = GURL(s);
79   if (!s.empty() && !p->is_valid()) {
80     *p = GURL();
81     return false;
82   }
83   return true;
84 }
85
86 void ParamTraits<GURL>::Log(const GURL& p, std::string* l) {
87   l->append(p.spec());
88 }
89
90 void ParamTraits<net::HostPortPair>::Write(Message* m, const param_type& p) {
91   WriteParam(m, p.host());
92   WriteParam(m, p.port());
93 }
94
95 bool ParamTraits<net::HostPortPair>::Read(const Message* m,
96                                           PickleIterator* iter,
97                                           param_type* r) {
98   std::string host;
99   uint16 port;
100   if (!ReadParam(m, iter, &host) || !ReadParam(m, iter, &port))
101     return false;
102
103   r->set_host(host);
104   r->set_port(port);
105   return true;
106 }
107
108 void ParamTraits<net::HostPortPair>::Log(const param_type& p, std::string* l) {
109   l->append(p.ToString());
110 }
111
112 void ParamTraits<net::IPEndPoint>::Write(Message* m, const param_type& p) {
113   WriteParam(m, p.address());
114   WriteParam(m, p.port());
115 }
116
117 bool ParamTraits<net::IPEndPoint>::Read(const Message* m, PickleIterator* iter,
118                                         param_type* p) {
119   net::IPAddressNumber address;
120   int port;
121   if (!ReadParam(m, iter, &address) || !ReadParam(m, iter, &port))
122     return false;
123   *p = net::IPEndPoint(address, port);
124   return true;
125 }
126
127 void ParamTraits<net::IPEndPoint>::Log(const param_type& p, std::string* l) {
128   LogParam("IPEndPoint:" + p.ToString(), l);
129 }
130
131 void ParamTraits<content::PageState>::Write(
132     Message* m, const param_type& p) {
133   WriteParam(m, p.ToEncodedData());
134 }
135
136 bool ParamTraits<content::PageState>::Read(
137     const Message* m, PickleIterator* iter, param_type* r) {
138   std::string data;
139   if (!ReadParam(m, iter, &data))
140     return false;
141   *r = content::PageState::CreateFromEncodedData(data);
142   return true;
143 }
144
145 void ParamTraits<content::PageState>::Log(
146     const param_type& p, std::string* l) {
147   l->append("(");
148   LogParam(p.ToEncodedData(), l);
149   l->append(")");
150 }
151
152 void ParamTraits<gfx::Point>::Write(Message* m, const gfx::Point& p) {
153   m->WriteInt(p.x());
154   m->WriteInt(p.y());
155 }
156
157 bool ParamTraits<gfx::Point>::Read(const Message* m, PickleIterator* iter,
158                                    gfx::Point* r) {
159   int x, y;
160   if (!m->ReadInt(iter, &x) ||
161       !m->ReadInt(iter, &y))
162     return false;
163   r->set_x(x);
164   r->set_y(y);
165   return true;
166 }
167
168 void ParamTraits<gfx::Point>::Log(const gfx::Point& p, std::string* l) {
169   l->append(base::StringPrintf("(%d, %d)", p.x(), p.y()));
170 }
171
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());
175 }
176
177 bool ParamTraits<gfx::PointF>::Read(const Message* m,
178                                       PickleIterator* iter,
179                                       gfx::PointF* r) {
180   float x, y;
181   if (!ParamTraits<float>::Read(m, iter, &x) ||
182       !ParamTraits<float>::Read(m, iter, &y))
183     return false;
184   r->set_x(x);
185   r->set_y(y);
186   return true;
187 }
188
189 void ParamTraits<gfx::PointF>::Log(const gfx::PointF& v, std::string* l) {
190   l->append(base::StringPrintf("(%f, %f)", v.x(), v.y()));
191 }
192
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);
198 }
199
200 bool ParamTraits<gfx::Size>::Read(const Message* m,
201                                   PickleIterator* iter,
202                                   gfx::Size* r) {
203   const char* char_values;
204   if (!m->ReadBytes(iter, &char_values, sizeof(int) * 2))
205     return false;
206   const int* values = reinterpret_cast<const int*>(char_values);
207   if (values[0] < 0 || values[1] < 0)
208     return false;
209   r->set_width(values[0]);
210   r->set_height(values[1]);
211   return true;
212 }
213
214 void ParamTraits<gfx::Size>::Log(const gfx::Size& p, std::string* l) {
215   l->append(base::StringPrintf("(%d, %d)", p.width(), p.height()));
216 }
217
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);
221 }
222
223 bool ParamTraits<gfx::SizeF>::Read(const Message* m,
224                                    PickleIterator* iter,
225                                    gfx::SizeF* r) {
226   const char* char_values;
227   if (!m->ReadBytes(iter, &char_values, sizeof(float) * 2))
228     return false;
229   const float* values = reinterpret_cast<const float*>(char_values);
230   r->set_width(values[0]);
231   r->set_height(values[1]);
232   return true;
233 }
234
235 void ParamTraits<gfx::SizeF>::Log(const gfx::SizeF& p, std::string* l) {
236   l->append(base::StringPrintf("(%f, %f)", p.width(), p.height()));
237 }
238
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);
242 }
243
244 bool ParamTraits<gfx::Vector2d>::Read(const Message* m,
245                                       PickleIterator* iter,
246                                       gfx::Vector2d* r) {
247   const char* char_values;
248   if (!m->ReadBytes(iter, &char_values, sizeof(int) * 2))
249     return false;
250   const int* values = reinterpret_cast<const int*>(char_values);
251   r->set_x(values[0]);
252   r->set_y(values[1]);
253   return true;
254 }
255
256 void ParamTraits<gfx::Vector2d>::Log(const gfx::Vector2d& v, std::string* l) {
257   l->append(base::StringPrintf("(%d, %d)", v.x(), v.y()));
258 }
259
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);
263 }
264
265 bool ParamTraits<gfx::Vector2dF>::Read(const Message* m,
266                                       PickleIterator* iter,
267                                       gfx::Vector2dF* r) {
268   const char* char_values;
269   if (!m->ReadBytes(iter, &char_values, sizeof(float) * 2))
270     return false;
271   const float* values = reinterpret_cast<const float*>(char_values);
272   r->set_x(values[0]);
273   r->set_y(values[1]);
274   return true;
275 }
276
277 void ParamTraits<gfx::Vector2dF>::Log(const gfx::Vector2dF& v, std::string* l) {
278   l->append(base::StringPrintf("(%f, %f)", v.x(), v.y()));
279 }
280
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);
284 }
285
286 bool ParamTraits<gfx::Rect>::Read(const Message* m,
287                                   PickleIterator* iter,
288                                   gfx::Rect* r) {
289   const char* char_values;
290   if (!m->ReadBytes(iter, &char_values, sizeof(int) * 4))
291     return false;
292   const int* values = reinterpret_cast<const int*>(char_values);
293   if (values[2] < 0 || values[3] < 0)
294     return false;
295   r->SetRect(values[0], values[1], values[2], values[3]);
296   return true;
297 }
298
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()));
302 }
303
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);
307 }
308
309 bool ParamTraits<gfx::RectF>::Read(const Message* m,
310                                    PickleIterator* iter,
311                                    gfx::RectF* r) {
312   const char* char_values;
313   if (!m->ReadBytes(iter, &char_values, sizeof(float) * 4))
314     return false;
315   const float* values = reinterpret_cast<const float*>(char_values);
316   r->SetRect(values[0], values[1], values[2], values[3]);
317   return true;
318 }
319
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()));
323 }
324
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));
335 }
336
337 bool ParamTraits<SkBitmap>::Read(const Message* m,
338                                  PickleIterator* iter,
339                                  SkBitmap* r) {
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)) {
344     NOTREACHED();
345     return false;
346   }
347   if (fixed_data_size != sizeof(SkBitmap_Data))
348     return false;  // Message is malformed.
349
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)) {
354     NOTREACHED();
355     return false;
356   }
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);
360 }
361
362 void ParamTraits<SkBitmap>::Log(const SkBitmap& p, std::string* l) {
363   l->append("<SkBitmap>");
364 }
365
366 }  // namespace IPC
367
368 // Generate param traits write methods.
369 #include "ipc/param_traits_write_macros.h"
370 namespace IPC {
371 #undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
372 #include "content/public/common/common_param_traits_macros.h"
373 }  // namespace IPC
374
375 // Generate param traits read methods.
376 #include "ipc/param_traits_read_macros.h"
377 namespace IPC {
378 #undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
379 #include "content/public/common/common_param_traits_macros.h"
380 }  // namespace IPC
381
382 // Generate param traits log methods.
383 #include "ipc/param_traits_log_macros.h"
384 namespace IPC {
385 #undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
386 #include "content/public/common/common_param_traits_macros.h"
387 }  // namespace IPC