common_param_traits.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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 <string> 8 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" 18 19namespace { 20 21struct SkBitmap_Data { 22 // The configuration for the bitmap (bits per pixel, etc). 23 SkBitmap::Config fConfig; 24 25 // The width of the bitmap in pixels. 26 uint32 fWidth; 27 28 // The height of the bitmap in pixels. 29 uint32 fHeight; 30 31 void InitSkBitmapDataForTransfer(const SkBitmap& bitmap) { 32 fConfig = bitmap.config(); 33 fWidth = bitmap.width(); 34 fHeight = bitmap.height(); 35 } 36 37 // Returns whether |bitmap| successfully initialized. 38 bool InitSkBitmapFromData(SkBitmap* bitmap, const char* pixels, 39 size_t total_pixels) const { 40 if (total_pixels) { 41 bitmap->setConfig(fConfig, fWidth, fHeight, 0); 42 if (!bitmap->allocPixels()) 43 return false; 44 if (total_pixels != bitmap->getSize()) 45 return false; 46 memcpy(bitmap->getPixels(), pixels, total_pixels); 47 } 48 return true; 49 } 50}; 51 52} // namespace 53 54namespace IPC { 55 56void ParamTraits<GURL>::Write(Message* m, const GURL& p) { 57 DCHECK(p.possibly_invalid_spec().length() <= content::GetMaxURLChars()); 58 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 64 // this area. 65 if (!p.is_valid()) { 66 m->WriteString(std::string()); 67 return; 68 } 69 70 m->WriteString(p.possibly_invalid_spec()); 71 // TODO(brettw) bug 684583: Add encoding for query params. 72} 73 74bool ParamTraits<GURL>::Read(const Message* m, PickleIterator* iter, GURL* p) { 75 std::string s; 76 if (!m->ReadString(iter, &s) || s.length() > content::GetMaxURLChars()) { 77 *p = GURL(); 78 return false; 79 } 80 *p = GURL(s); 81 if (!s.empty() && !p->is_valid()) { 82 *p = GURL(); 83 return false; 84 } 85 return true; 86} 87 88void ParamTraits<GURL>::Log(const GURL& p, std::string* l) { 89 l->append(p.spec()); 90} 91 92void ParamTraits<url::Origin>::Write(Message* m, 93 const url::Origin& p) { 94 m->WriteString(p.string()); 95} 96 97bool ParamTraits<url::Origin>::Read(const Message* m, 98 PickleIterator* iter, 99 url::Origin* p) { 100 std::string s; 101 if (!m->ReadString(iter, &s)) { 102 *p = url::Origin(); 103 return false; 104 } 105 *p = url::Origin(s); 106 return true; 107} 108 109void ParamTraits<url::Origin>::Log(const url::Origin& p, std::string* l) { 110 l->append(p.string()); 111} 112 113void ParamTraits<net::HostPortPair>::Write(Message* m, const param_type& p) { 114 WriteParam(m, p.host()); 115 WriteParam(m, p.port()); 116} 117 118bool ParamTraits<net::HostPortPair>::Read(const Message* m, 119 PickleIterator* iter, 120 param_type* r) { 121 std::string host; 122 uint16 port; 123 if (!ReadParam(m, iter, &host) || !ReadParam(m, iter, &port)) 124 return false; 125 126 r->set_host(host); 127 r->set_port(port); 128 return true; 129} 130 131void ParamTraits<net::HostPortPair>::Log(const param_type& p, std::string* l) { 132 l->append(p.ToString()); 133} 134 135void ParamTraits<net::IPEndPoint>::Write(Message* m, const param_type& p) { 136 WriteParam(m, p.address()); 137 WriteParam(m, p.port()); 138} 139 140bool ParamTraits<net::IPEndPoint>::Read(const Message* m, PickleIterator* iter, 141 param_type* p) { 142 net::IPAddressNumber address; 143 int port; 144 if (!ReadParam(m, iter, &address) || !ReadParam(m, iter, &port)) 145 return false; 146 if (address.size() && 147 address.size() != net::kIPv4AddressSize && 148 address.size() != net::kIPv6AddressSize) { 149 return false; 150 } 151 *p = net::IPEndPoint(address, port); 152 return true; 153} 154 155void ParamTraits<net::IPEndPoint>::Log(const param_type& p, std::string* l) { 156 LogParam("IPEndPoint:" + p.ToString(), l); 157} 158 159void ParamTraits<content::PageState>::Write( 160 Message* m, const param_type& p) { 161 WriteParam(m, p.ToEncodedData()); 162} 163 164bool ParamTraits<content::PageState>::Read( 165 const Message* m, PickleIterator* iter, param_type* r) { 166 std::string data; 167 if (!ReadParam(m, iter, &data)) 168 return false; 169 *r = content::PageState::CreateFromEncodedData(data); 170 return true; 171} 172 173void ParamTraits<content::PageState>::Log( 174 const param_type& p, std::string* l) { 175 l->append("("); 176 LogParam(p.ToEncodedData(), l); 177 l->append(")"); 178} 179 180void ParamTraits<gfx::Point>::Write(Message* m, const gfx::Point& p) { 181 m->WriteInt(p.x()); 182 m->WriteInt(p.y()); 183} 184 185bool ParamTraits<gfx::Point>::Read(const Message* m, PickleIterator* iter, 186 gfx::Point* r) { 187 int x, y; 188 if (!m->ReadInt(iter, &x) || 189 !m->ReadInt(iter, &y)) 190 return false; 191 r->set_x(x); 192 r->set_y(y); 193 return true; 194} 195 196void ParamTraits<gfx::Point>::Log(const gfx::Point& p, std::string* l) { 197 l->append(base::StringPrintf("(%d, %d)", p.x(), p.y())); 198} 199 200void ParamTraits<gfx::PointF>::Write(Message* m, const gfx::PointF& v) { 201 ParamTraits<float>::Write(m, v.x()); 202 ParamTraits<float>::Write(m, v.y()); 203} 204 205bool ParamTraits<gfx::PointF>::Read(const Message* m, 206 PickleIterator* iter, 207 gfx::PointF* r) { 208 float x, y; 209 if (!ParamTraits<float>::Read(m, iter, &x) || 210 !ParamTraits<float>::Read(m, iter, &y)) 211 return false; 212 r->set_x(x); 213 r->set_y(y); 214 return true; 215} 216 217void ParamTraits<gfx::PointF>::Log(const gfx::PointF& v, std::string* l) { 218 l->append(base::StringPrintf("(%f, %f)", v.x(), v.y())); 219} 220 221void 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); 226} 227 228bool ParamTraits<gfx::Size>::Read(const Message* m, 229 PickleIterator* iter, 230 gfx::Size* r) { 231 const char* char_values; 232 if (!m->ReadBytes(iter, &char_values, sizeof(int) * 2)) 233 return false; 234 const int* values = reinterpret_cast<const int*>(char_values); 235 if (values[0] < 0 || values[1] < 0) 236 return false; 237 r->set_width(values[0]); 238 r->set_height(values[1]); 239 return true; 240} 241 242void ParamTraits<gfx::Size>::Log(const gfx::Size& p, std::string* l) { 243 l->append(base::StringPrintf("(%d, %d)", p.width(), p.height())); 244} 245 246void 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); 249} 250 251bool ParamTraits<gfx::SizeF>::Read(const Message* m, 252 PickleIterator* iter, 253 gfx::SizeF* r) { 254 const char* char_values; 255 if (!m->ReadBytes(iter, &char_values, sizeof(float) * 2)) 256 return false; 257 const float* values = reinterpret_cast<const float*>(char_values); 258 r->set_width(values[0]); 259 r->set_height(values[1]); 260 return true; 261} 262 263void ParamTraits<gfx::SizeF>::Log(const gfx::SizeF& p, std::string* l) { 264 l->append(base::StringPrintf("(%f, %f)", p.width(), p.height())); 265} 266 267void 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); 270} 271 272bool ParamTraits<gfx::Vector2d>::Read(const Message* m, 273 PickleIterator* iter, 274 gfx::Vector2d* r) { 275 const char* char_values; 276 if (!m->ReadBytes(iter, &char_values, sizeof(int) * 2)) 277 return false; 278 const int* values = reinterpret_cast<const int*>(char_values); 279 r->set_x(values[0]); 280 r->set_y(values[1]); 281 return true; 282} 283 284void ParamTraits<gfx::Vector2d>::Log(const gfx::Vector2d& v, std::string* l) { 285 l->append(base::StringPrintf("(%d, %d)", v.x(), v.y())); 286} 287 288void 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); 291} 292 293bool ParamTraits<gfx::Vector2dF>::Read(const Message* m, 294 PickleIterator* iter, 295 gfx::Vector2dF* r) { 296 const char* char_values; 297 if (!m->ReadBytes(iter, &char_values, sizeof(float) * 2)) 298 return false; 299 const float* values = reinterpret_cast<const float*>(char_values); 300 r->set_x(values[0]); 301 r->set_y(values[1]); 302 return true; 303} 304 305void ParamTraits<gfx::Vector2dF>::Log(const gfx::Vector2dF& v, std::string* l) { 306 l->append(base::StringPrintf("(%f, %f)", v.x(), v.y())); 307} 308 309void 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); 312} 313 314bool ParamTraits<gfx::Rect>::Read(const Message* m, 315 PickleIterator* iter, 316 gfx::Rect* r) { 317 const char* char_values; 318 if (!m->ReadBytes(iter, &char_values, sizeof(int) * 4)) 319 return false; 320 const int* values = reinterpret_cast<const int*>(char_values); 321 if (values[2] < 0 || values[3] < 0) 322 return false; 323 r->SetRect(values[0], values[1], values[2], values[3]); 324 return true; 325} 326 327void 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())); 330} 331 332void 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); 335} 336 337bool ParamTraits<gfx::RectF>::Read(const Message* m, 338 PickleIterator* iter, 339 gfx::RectF* r) { 340 const char* char_values; 341 if (!m->ReadBytes(iter, &char_values, sizeof(float) * 4)) 342 return false; 343 const float* values = reinterpret_cast<const float*>(char_values); 344 r->SetRect(values[0], values[1], values[2], values[3]); 345 return true; 346} 347 348void 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())); 351} 352 353void 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)); 363} 364 365bool ParamTraits<SkBitmap>::Read(const Message* m, 366 PickleIterator* iter, 367 SkBitmap* r) { 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)) { 372 NOTREACHED(); 373 return false; 374 } 375 if (fixed_data_size != sizeof(SkBitmap_Data)) 376 return false; // Message is malformed. 377 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)) { 382 NOTREACHED(); 383 return false; 384 } 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); 388} 389 390void ParamTraits<SkBitmap>::Log(const SkBitmap& p, std::string* l) { 391 l->append("<SkBitmap>"); 392} 393 394} // namespace IPC 395 396// Generate param traits write methods. 397#include "ipc/param_traits_write_macros.h" 398namespace IPC { 399#undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_ 400#include "content/public/common/common_param_traits_macros.h" 401} // namespace IPC 402 403// Generate param traits read methods. 404#include "ipc/param_traits_read_macros.h" 405namespace IPC { 406#undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_ 407#include "content/public/common/common_param_traits_macros.h" 408} // namespace IPC 409 410// Generate param traits log methods. 411#include "ipc/param_traits_log_macros.h" 412namespace IPC { 413#undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_ 414#include "content/public/common/common_param_traits_macros.h" 415} // namespace IPC 416