common_param_traits.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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 "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" 14 15namespace { 16 17struct SkBitmap_Data { 18 // The configuration for the bitmap (bits per pixel, etc). 19 SkBitmap::Config fConfig; 20 21 // The width of the bitmap in pixels. 22 uint32 fWidth; 23 24 // The height of the bitmap in pixels. 25 uint32 fHeight; 26 27 void InitSkBitmapDataForTransfer(const SkBitmap& bitmap) { 28 fConfig = bitmap.config(); 29 fWidth = bitmap.width(); 30 fHeight = bitmap.height(); 31 } 32 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); 43 } 44 return true; 45 } 46}; 47 48} // namespace 49 50namespace IPC { 51 52void ParamTraits<GURL>::Write(Message* m, const GURL& p) { 53 DCHECK(p.possibly_invalid_spec().length() <= content::kMaxURLChars); 54 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; 64 } 65 66 m->WriteString(p.possibly_invalid_spec()); 67 // TODO(brettw) bug 684583: Add encoding for query params. 68} 69 70bool 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; 75 } 76 *p = GURL(s); 77 if (!s.empty() && !p->is_valid()) { 78 *p = GURL(); 79 return false; 80 } 81 return true; 82} 83 84void ParamTraits<GURL>::Log(const GURL& p, std::string* l) { 85 l->append(p.spec()); 86} 87 88void ParamTraits<net::HostPortPair>::Write(Message* m, const param_type& p) { 89 WriteParam(m, p.host()); 90 WriteParam(m, p.port()); 91} 92 93bool 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; 100 101 r->set_host(host); 102 r->set_port(port); 103 return true; 104} 105 106void ParamTraits<net::HostPortPair>::Log(const param_type& p, std::string* l) { 107 l->append(p.ToString()); 108} 109 110void ParamTraits<content::PageState>::Write( 111 Message* m, const param_type& p) { 112 WriteParam(m, p.ToEncodedData()); 113} 114 115bool 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; 122} 123 124void ParamTraits<content::PageState>::Log( 125 const param_type& p, std::string* l) { 126 l->append("("); 127 LogParam(p.ToEncodedData(), l); 128 l->append(")"); 129} 130 131void ParamTraits<content::Referrer>::Write( 132 Message* m, const param_type& p) { 133 WriteParam(m, p.url); 134 WriteParam(m, p.policy); 135} 136 137bool 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); 140} 141 142void 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(")"); 149} 150 151void ParamTraits<gfx::Point>::Write(Message* m, const gfx::Point& p) { 152 m->WriteInt(p.x()); 153 m->WriteInt(p.y()); 154} 155 156bool 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; 165} 166 167void ParamTraits<gfx::Point>::Log(const gfx::Point& p, std::string* l) { 168 l->append(base::StringPrintf("(%d, %d)", p.x(), p.y())); 169} 170 171void ParamTraits<gfx::PointF>::Write(Message* m, const gfx::PointF& v) { 172 ParamTraits<float>::Write(m, v.x()); 173 ParamTraits<float>::Write(m, v.y()); 174} 175 176bool 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; 186} 187 188void ParamTraits<gfx::PointF>::Log(const gfx::PointF& v, std::string* l) { 189 l->append(base::StringPrintf("(%f, %f)", v.x(), v.y())); 190} 191 192void ParamTraits<gfx::Size>::Write(Message* m, const gfx::Size& p) { 193 DCHECK_GE(p.width(), 0); 194 DCHECK_GE(p.height(), 0); 195 int values[2] = { p.width(), p.height() }; 196 m->WriteBytes(&values, sizeof(int) * 2); 197} 198 199bool ParamTraits<gfx::Size>::Read(const Message* m, 200 PickleIterator* iter, 201 gfx::Size* r) { 202 const char* char_values; 203 if (!m->ReadBytes(iter, &char_values, sizeof(int) * 2)) 204 return false; 205 const int* values = reinterpret_cast<const int*>(char_values); 206 if (values[0] < 0 || values[1] < 0) 207 return false; 208 r->set_width(values[0]); 209 r->set_height(values[1]); 210 return true; 211} 212 213void ParamTraits<gfx::Size>::Log(const gfx::Size& p, std::string* l) { 214 l->append(base::StringPrintf("(%d, %d)", p.width(), p.height())); 215} 216 217void ParamTraits<gfx::SizeF>::Write(Message* m, const gfx::SizeF& p) { 218 float values[2] = { p.width(), p.height() }; 219 m->WriteBytes(&values, sizeof(float) * 2); 220} 221 222bool ParamTraits<gfx::SizeF>::Read(const Message* m, 223 PickleIterator* iter, 224 gfx::SizeF* r) { 225 const char* char_values; 226 if (!m->ReadBytes(iter, &char_values, sizeof(float) * 2)) 227 return false; 228 const float* values = reinterpret_cast<const float*>(char_values); 229 r->set_width(values[0]); 230 r->set_height(values[1]); 231 return true; 232} 233 234void ParamTraits<gfx::SizeF>::Log(const gfx::SizeF& p, std::string* l) { 235 l->append(base::StringPrintf("(%f, %f)", p.width(), p.height())); 236} 237 238void ParamTraits<gfx::Vector2d>::Write(Message* m, const gfx::Vector2d& p) { 239 int values[2] = { p.x(), p.y() }; 240 m->WriteBytes(&values, sizeof(int) * 2); 241} 242 243bool ParamTraits<gfx::Vector2d>::Read(const Message* m, 244 PickleIterator* iter, 245 gfx::Vector2d* r) { 246 const char* char_values; 247 if (!m->ReadBytes(iter, &char_values, sizeof(int) * 2)) 248 return false; 249 const int* values = reinterpret_cast<const int*>(char_values); 250 r->set_x(values[0]); 251 r->set_y(values[1]); 252 return true; 253} 254 255void ParamTraits<gfx::Vector2d>::Log(const gfx::Vector2d& v, std::string* l) { 256 l->append(base::StringPrintf("(%d, %d)", v.x(), v.y())); 257} 258 259void ParamTraits<gfx::Vector2dF>::Write(Message* m, const gfx::Vector2dF& p) { 260 float values[2] = { p.x(), p.y() }; 261 m->WriteBytes(&values, sizeof(float) * 2); 262} 263 264bool ParamTraits<gfx::Vector2dF>::Read(const Message* m, 265 PickleIterator* iter, 266 gfx::Vector2dF* r) { 267 const char* char_values; 268 if (!m->ReadBytes(iter, &char_values, sizeof(float) * 2)) 269 return false; 270 const float* values = reinterpret_cast<const float*>(char_values); 271 r->set_x(values[0]); 272 r->set_y(values[1]); 273 return true; 274} 275 276void ParamTraits<gfx::Vector2dF>::Log(const gfx::Vector2dF& v, std::string* l) { 277 l->append(base::StringPrintf("(%f, %f)", v.x(), v.y())); 278} 279 280void ParamTraits<gfx::Rect>::Write(Message* m, const gfx::Rect& p) { 281 int values[4] = { p.x(), p.y(), p.width(), p.height() }; 282 m->WriteBytes(&values, sizeof(int) * 4); 283} 284 285bool ParamTraits<gfx::Rect>::Read(const Message* m, 286 PickleIterator* iter, 287 gfx::Rect* r) { 288 const char* char_values; 289 if (!m->ReadBytes(iter, &char_values, sizeof(int) * 4)) 290 return false; 291 const int* values = reinterpret_cast<const int*>(char_values); 292 if (values[2] < 0 || values[3] < 0) 293 return false; 294 r->SetRect(values[0], values[1], values[2], values[3]); 295 return true; 296} 297 298void ParamTraits<gfx::Rect>::Log(const gfx::Rect& p, std::string* l) { 299 l->append(base::StringPrintf("(%d, %d, %d, %d)", p.x(), p.y(), 300 p.width(), p.height())); 301} 302 303void ParamTraits<gfx::RectF>::Write(Message* m, const gfx::RectF& p) { 304 float values[4] = { p.x(), p.y(), p.width(), p.height() }; 305 m->WriteBytes(&values, sizeof(float) * 4); 306} 307 308bool ParamTraits<gfx::RectF>::Read(const Message* m, 309 PickleIterator* iter, 310 gfx::RectF* r) { 311 const char* char_values; 312 if (!m->ReadBytes(iter, &char_values, sizeof(float) * 4)) 313 return false; 314 const float* values = reinterpret_cast<const float*>(char_values); 315 r->SetRect(values[0], values[1], values[2], values[3]); 316 return true; 317} 318 319void ParamTraits<gfx::RectF>::Log(const gfx::RectF& p, std::string* l) { 320 l->append(base::StringPrintf("(%f, %f, %f, %f)", p.x(), p.y(), 321 p.width(), p.height())); 322} 323 324void ParamTraits<SkBitmap>::Write(Message* m, const SkBitmap& p) { 325 size_t fixed_size = sizeof(SkBitmap_Data); 326 SkBitmap_Data bmp_data; 327 bmp_data.InitSkBitmapDataForTransfer(p); 328 m->WriteData(reinterpret_cast<const char*>(&bmp_data), 329 static_cast<int>(fixed_size)); 330 size_t pixel_size = p.getSize(); 331 SkAutoLockPixels p_lock(p); 332 m->WriteData(reinterpret_cast<const char*>(p.getPixels()), 333 static_cast<int>(pixel_size)); 334} 335 336bool ParamTraits<SkBitmap>::Read(const Message* m, 337 PickleIterator* iter, 338 SkBitmap* r) { 339 const char* fixed_data; 340 int fixed_data_size = 0; 341 if (!m->ReadData(iter, &fixed_data, &fixed_data_size) || 342 (fixed_data_size <= 0)) { 343 NOTREACHED(); 344 return false; 345 } 346 if (fixed_data_size != sizeof(SkBitmap_Data)) 347 return false; // Message is malformed. 348 349 const char* variable_data; 350 int variable_data_size = 0; 351 if (!m->ReadData(iter, &variable_data, &variable_data_size) || 352 (variable_data_size < 0)) { 353 NOTREACHED(); 354 return false; 355 } 356 const SkBitmap_Data* bmp_data = 357 reinterpret_cast<const SkBitmap_Data*>(fixed_data); 358 return bmp_data->InitSkBitmapFromData(r, variable_data, variable_data_size); 359} 360 361void ParamTraits<SkBitmap>::Log(const SkBitmap& p, std::string* l) { 362 l->append("<SkBitmap>"); 363} 364 365} // namespace IPC 366 367// Generate param traits write methods. 368#include "ipc/param_traits_write_macros.h" 369namespace IPC { 370#undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_ 371#include "content/public/common/common_param_traits_macros.h" 372} // namespace IPC 373 374// Generate param traits read methods. 375#include "ipc/param_traits_read_macros.h" 376namespace IPC { 377#undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_ 378#include "content/public/common/common_param_traits_macros.h" 379} // namespace IPC 380 381// Generate param traits log methods. 382#include "ipc/param_traits_log_macros.h" 383namespace IPC { 384#undef CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_ 385#include "content/public/common/common_param_traits_macros.h" 386} // namespace IPC 387