OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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/common/common_param_traits.h" | |
6 | |
7 #include "content/common/content_constants.h" | |
8 #include "net/base/host_port_pair.h" | |
9 #include "net/base/upload_data.h" | |
10 #include "net/http/http_response_headers.h" | |
11 #include "third_party/skia/include/core/SkBitmap.h" | |
12 #include "ui/base/range/range.h" | |
13 #include "ui/gfx/rect.h" | |
14 | |
15 namespace { | |
16 | |
17 struct 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 | |
50 namespace IPC { | |
51 | |
52 void ParamTraits<GURL>::Write(Message* m, const GURL& p) { | |
53 m->WriteString(p.possibly_invalid_spec()); | |
54 // TODO(brettw) bug 684583: Add encoding for query params. | |
55 } | |
56 | |
57 bool ParamTraits<GURL>::Read(const Message* m, void** iter, GURL* p) { | |
58 std::string s; | |
59 if (!m->ReadString(iter, &s) || s.length() > content::kMaxURLChars) { | |
60 *p = GURL(); | |
61 return false; | |
62 } | |
63 *p = GURL(s); | |
64 return true; | |
65 } | |
66 | |
67 void ParamTraits<GURL>::Log(const GURL& p, std::string* l) { | |
68 l->append(p.spec()); | |
69 } | |
70 | |
71 void ParamTraits<ResourceType::Type>::Write(Message* m, const param_type& p) { | |
72 m->WriteInt(p); | |
73 } | |
74 | |
75 bool ParamTraits<ResourceType::Type>::Read(const Message* m, | |
76 void** iter, | |
77 param_type* p) { | |
78 int type; | |
79 if (!m->ReadInt(iter, &type) || !ResourceType::ValidType(type)) | |
80 return false; | |
81 *p = ResourceType::FromInt(type); | |
82 return true; | |
83 } | |
84 | |
85 void ParamTraits<ResourceType::Type>::Log(const param_type& p, std::string* l) { | |
86 std::string type; | |
87 switch (p) { | |
88 case ResourceType::MAIN_FRAME: | |
89 type = "MAIN_FRAME"; | |
90 break; | |
91 case ResourceType::SUB_FRAME: | |
92 type = "SUB_FRAME"; | |
93 break; | |
94 case ResourceType::STYLESHEET: | |
95 type = "STYLESHEET"; | |
96 break; | |
97 case ResourceType::SCRIPT: | |
98 type = "SCRIPT"; | |
99 break; | |
100 case ResourceType::IMAGE: | |
101 type = "IMAGE"; | |
102 break; | |
103 case ResourceType::FONT_RESOURCE: | |
104 type = "FONT_RESOURCE"; | |
105 break; | |
106 case ResourceType::SUB_RESOURCE: | |
107 type = "SUB_RESOURCE"; | |
108 break; | |
109 case ResourceType::OBJECT: | |
110 type = "OBJECT"; | |
111 break; | |
112 case ResourceType::MEDIA: | |
113 type = "MEDIA"; | |
114 break; | |
115 case ResourceType::WORKER: | |
116 type = "WORKER"; | |
117 break; | |
118 case ResourceType::SHARED_WORKER: | |
119 type = "SHARED_WORKER"; | |
120 break; | |
121 case ResourceType::PREFETCH: | |
122 type = "PREFETCH"; | |
123 break; | |
124 case ResourceType::PRERENDER: | |
125 type = "PRERENDER"; | |
126 break; | |
127 case ResourceType::FAVICON: | |
128 type = "FAVICON"; | |
129 break; | |
130 case ResourceType::XHR: | |
131 type = "XHR"; | |
132 break; | |
133 default: | |
134 type = "UNKNOWN"; | |
135 break; | |
136 } | |
137 | |
138 LogParam(type, l); | |
139 } | |
140 | |
141 void ParamTraits<net::URLRequestStatus>::Write(Message* m, | |
142 const param_type& p) { | |
143 WriteParam(m, static_cast<int>(p.status())); | |
144 WriteParam(m, p.error()); | |
145 } | |
146 | |
147 bool ParamTraits<net::URLRequestStatus>::Read(const Message* m, void** iter, | |
148 param_type* r) { | |
149 int status, error; | |
150 if (!ReadParam(m, iter, &status) || !ReadParam(m, iter, &error)) | |
151 return false; | |
152 r->set_status(static_cast<net::URLRequestStatus::Status>(status)); | |
153 r->set_error(error); | |
154 return true; | |
155 } | |
156 | |
157 void ParamTraits<net::URLRequestStatus>::Log(const param_type& p, | |
158 std::string* l) { | |
159 std::string status; | |
160 switch (p.status()) { | |
161 case net::URLRequestStatus::SUCCESS: | |
162 status = "SUCCESS"; | |
163 break; | |
164 case net::URLRequestStatus::IO_PENDING: | |
165 status = "IO_PENDING "; | |
166 break; | |
167 case net::URLRequestStatus::HANDLED_EXTERNALLY: | |
168 status = "HANDLED_EXTERNALLY"; | |
169 break; | |
170 case net::URLRequestStatus::CANCELED: | |
171 status = "CANCELED"; | |
172 break; | |
173 case net::URLRequestStatus::FAILED: | |
174 status = "FAILED"; | |
175 break; | |
176 default: | |
177 status = "UNKNOWN"; | |
178 break; | |
179 } | |
180 if (p.status() == net::URLRequestStatus::FAILED) | |
181 l->append("("); | |
182 | |
183 LogParam(status, l); | |
184 | |
185 if (p.status() == net::URLRequestStatus::FAILED) { | |
186 l->append(", "); | |
187 LogParam(p.error(), l); | |
188 l->append(")"); | |
189 } | |
190 } | |
191 | |
192 // Only the net::UploadData ParamTraits<> definition needs this definition, so | |
193 // keep this in the implementation file so we can forward declare UploadData in | |
194 // the header. | |
195 template <> | |
196 struct ParamTraits<net::UploadData::Element> { | |
197 typedef net::UploadData::Element param_type; | |
198 static void Write(Message* m, const param_type& p) { | |
199 WriteParam(m, static_cast<int>(p.type())); | |
200 switch (p.type()) { | |
201 case net::UploadData::TYPE_BYTES: { | |
202 m->WriteData(&p.bytes()[0], static_cast<int>(p.bytes().size())); | |
203 break; | |
204 } | |
205 case net::UploadData::TYPE_CHUNK: { | |
206 std::string chunk_length = StringPrintf( | |
207 "%X\r\n", static_cast<unsigned int>(p.bytes().size())); | |
208 std::vector<char> bytes; | |
209 bytes.insert(bytes.end(), chunk_length.data(), | |
210 chunk_length.data() + chunk_length.length()); | |
211 const char* data = &p.bytes()[0]; | |
212 bytes.insert(bytes.end(), data, data + p.bytes().size()); | |
213 const char* crlf = "\r\n"; | |
214 bytes.insert(bytes.end(), crlf, crlf + strlen(crlf)); | |
215 if (p.is_last_chunk()) { | |
216 const char* end_of_data = "0\r\n\r\n"; | |
217 bytes.insert(bytes.end(), end_of_data, | |
218 end_of_data + strlen(end_of_data)); | |
219 } | |
220 m->WriteData(&bytes[0], static_cast<int>(bytes.size())); | |
221 // If this element is part of a chunk upload then send over information | |
222 // indicating if this is the last chunk. | |
223 WriteParam(m, p.is_last_chunk()); | |
224 break; | |
225 } | |
226 case net::UploadData::TYPE_FILE: { | |
227 WriteParam(m, p.file_path()); | |
228 WriteParam(m, p.file_range_offset()); | |
229 WriteParam(m, p.file_range_length()); | |
230 WriteParam(m, p.expected_file_modification_time()); | |
231 break; | |
232 } | |
233 default: { | |
234 WriteParam(m, p.blob_url()); | |
235 break; | |
236 } | |
237 } | |
238 } | |
239 static bool Read(const Message* m, void** iter, param_type* r) { | |
240 int type; | |
241 if (!ReadParam(m, iter, &type)) | |
242 return false; | |
243 switch (type) { | |
244 case net::UploadData::TYPE_BYTES: { | |
245 const char* data; | |
246 int len; | |
247 if (!m->ReadData(iter, &data, &len)) | |
248 return false; | |
249 r->SetToBytes(data, len); | |
250 break; | |
251 } | |
252 case net::UploadData::TYPE_CHUNK: { | |
253 const char* data; | |
254 int len; | |
255 if (!m->ReadData(iter, &data, &len)) | |
256 return false; | |
257 r->SetToBytes(data, len); | |
258 // If this element is part of a chunk upload then we need to explicitly | |
259 // set the type of the element and whether it is the last chunk. | |
260 bool is_last_chunk = false; | |
261 if (!ReadParam(m, iter, &is_last_chunk)) | |
262 return false; | |
263 r->set_type(net::UploadData::TYPE_CHUNK); | |
264 r->set_is_last_chunk(is_last_chunk); | |
265 break; | |
266 } | |
267 case net::UploadData::TYPE_FILE: { | |
268 FilePath file_path; | |
269 uint64 offset, length; | |
270 base::Time expected_modification_time; | |
271 if (!ReadParam(m, iter, &file_path)) | |
272 return false; | |
273 if (!ReadParam(m, iter, &offset)) | |
274 return false; | |
275 if (!ReadParam(m, iter, &length)) | |
276 return false; | |
277 if (!ReadParam(m, iter, &expected_modification_time)) | |
278 return false; | |
279 r->SetToFilePathRange(file_path, offset, length, | |
280 expected_modification_time); | |
281 break; | |
282 } | |
283 default: { | |
284 DCHECK(type == net::UploadData::TYPE_BLOB); | |
285 GURL blob_url; | |
286 if (!ReadParam(m, iter, &blob_url)) | |
287 return false; | |
288 r->SetToBlobUrl(blob_url); | |
289 break; | |
290 } | |
291 } | |
292 return true; | |
293 } | |
294 static void Log(const param_type& p, std::string* l) { | |
295 l->append("<net::UploadData::Element>"); | |
296 } | |
297 }; | |
298 | |
299 void ParamTraits<scoped_refptr<net::UploadData> >::Write(Message* m, | |
300 const param_type& p) { | |
301 WriteParam(m, p.get() != NULL); | |
302 if (p) { | |
303 WriteParam(m, *p->elements()); | |
304 WriteParam(m, p->identifier()); | |
305 WriteParam(m, p->is_chunked()); | |
306 } | |
307 } | |
308 | |
309 bool ParamTraits<scoped_refptr<net::UploadData> >::Read(const Message* m, | |
310 void** iter, | |
311 param_type* r) { | |
312 bool has_object; | |
313 if (!ReadParam(m, iter, &has_object)) | |
314 return false; | |
315 if (!has_object) | |
316 return true; | |
317 std::vector<net::UploadData::Element> elements; | |
318 if (!ReadParam(m, iter, &elements)) | |
319 return false; | |
320 int64 identifier; | |
321 if (!ReadParam(m, iter, &identifier)) | |
322 return false; | |
323 bool is_chunked = false; | |
324 if (!ReadParam(m, iter, &is_chunked)) | |
325 return false; | |
326 *r = new net::UploadData; | |
327 (*r)->swap_elements(&elements); | |
328 (*r)->set_identifier(identifier); | |
329 (*r)->set_is_chunked(is_chunked); | |
330 return true; | |
331 } | |
332 | |
333 void ParamTraits<scoped_refptr<net::UploadData> >::Log(const param_type& p, | |
334 std::string* l) { | |
335 l->append("<net::UploadData>"); | |
336 } | |
337 | |
338 void ParamTraits<net::HostPortPair>::Write(Message* m, const param_type& p) { | |
339 WriteParam(m, p.host()); | |
340 WriteParam(m, p.port()); | |
341 } | |
342 | |
343 bool ParamTraits<net::HostPortPair>::Read(const Message* m, void** iter, | |
344 param_type* r) { | |
345 std::string host; | |
346 uint16 port; | |
347 if (!ReadParam(m, iter, &host) || !ReadParam(m, iter, &port)) | |
348 return false; | |
349 | |
350 r->set_host(host); | |
351 r->set_port(port); | |
352 return true; | |
353 } | |
354 | |
355 void ParamTraits<net::HostPortPair>::Log(const param_type& p, std::string* l) { | |
356 l->append(p.ToString()); | |
357 } | |
358 | |
359 void ParamTraits<scoped_refptr<net::HttpResponseHeaders> >::Write( | |
360 Message* m, const param_type& p) { | |
361 WriteParam(m, p.get() != NULL); | |
362 if (p) { | |
363 // Do not disclose Set-Cookie headers over IPC. | |
364 p->Persist(m, net::HttpResponseHeaders::PERSIST_SANS_COOKIES); | |
365 } | |
366 } | |
367 | |
368 bool ParamTraits<scoped_refptr<net::HttpResponseHeaders> >::Read( | |
369 const Message* m, void** iter, param_type* r) { | |
370 bool has_object; | |
371 if (!ReadParam(m, iter, &has_object)) | |
372 return false; | |
373 if (has_object) | |
374 *r = new net::HttpResponseHeaders(*m, iter); | |
375 return true; | |
376 } | |
377 | |
378 void ParamTraits<scoped_refptr<net::HttpResponseHeaders> >::Log( | |
379 const param_type& p, std::string* l) { | |
380 l->append("<HttpResponseHeaders>"); | |
381 } | |
382 | |
383 void ParamTraits<net::IPEndPoint>::Write(Message* m, const param_type& p) { | |
384 WriteParam(m, p.address()); | |
385 WriteParam(m, p.port()); | |
386 } | |
387 | |
388 bool ParamTraits<net::IPEndPoint>::Read(const Message* m, void** iter, | |
389 param_type* p) { | |
390 net::IPAddressNumber address; | |
391 int port; | |
392 if (!ReadParam(m, iter, &address) || !ReadParam(m, iter, &port)) | |
393 return false; | |
394 *p = net::IPEndPoint(address, port); | |
395 return true; | |
396 } | |
397 | |
398 void ParamTraits<net::IPEndPoint>::Log(const param_type& p, std::string* l) { | |
399 LogParam("IPEndPoint:" + p.ToString(), l); | |
400 } | |
401 | |
402 void ParamTraits<base::PlatformFileInfo>::Write( | |
403 Message* m, const param_type& p) { | |
404 WriteParam(m, p.size); | |
405 WriteParam(m, p.is_directory); | |
406 WriteParam(m, p.last_modified.ToDoubleT()); | |
407 WriteParam(m, p.last_accessed.ToDoubleT()); | |
408 WriteParam(m, p.creation_time.ToDoubleT()); | |
409 } | |
410 | |
411 bool ParamTraits<base::PlatformFileInfo>::Read( | |
412 const Message* m, void** iter, param_type* p) { | |
413 double last_modified; | |
414 double last_accessed; | |
415 double creation_time; | |
416 bool result = | |
417 ReadParam(m, iter, &p->size) && | |
418 ReadParam(m, iter, &p->is_directory) && | |
419 ReadParam(m, iter, &last_modified) && | |
420 ReadParam(m, iter, &last_accessed) && | |
421 ReadParam(m, iter, &creation_time); | |
422 if (result) { | |
423 p->last_modified = base::Time::FromDoubleT(last_modified); | |
424 p->last_accessed = base::Time::FromDoubleT(last_accessed); | |
425 p->creation_time = base::Time::FromDoubleT(creation_time); | |
426 } | |
427 return result; | |
428 } | |
429 | |
430 void ParamTraits<base::PlatformFileInfo>::Log( | |
431 const param_type& p, std::string* l) { | |
432 l->append("("); | |
433 LogParam(p.size, l); | |
434 l->append(","); | |
435 LogParam(p.is_directory, l); | |
436 l->append(","); | |
437 LogParam(p.last_modified.ToDoubleT(), l); | |
438 l->append(","); | |
439 LogParam(p.last_accessed.ToDoubleT(), l); | |
440 l->append(","); | |
441 LogParam(p.creation_time.ToDoubleT(), l); | |
442 l->append(")"); | |
443 } | |
444 | |
445 void ParamTraits<gfx::Point>::Write(Message* m, const gfx::Point& p) { | |
446 m->WriteInt(p.x()); | |
447 m->WriteInt(p.y()); | |
448 } | |
449 | |
450 bool ParamTraits<gfx::Point>::Read(const Message* m, void** iter, | |
451 gfx::Point* r) { | |
452 int x, y; | |
453 if (!m->ReadInt(iter, &x) || | |
454 !m->ReadInt(iter, &y)) | |
455 return false; | |
456 r->set_x(x); | |
457 r->set_y(y); | |
458 return true; | |
459 } | |
460 | |
461 void ParamTraits<gfx::Point>::Log(const gfx::Point& p, std::string* l) { | |
462 l->append(base::StringPrintf("(%d, %d)", p.x(), p.y())); | |
463 } | |
464 | |
465 void ParamTraits<gfx::Size>::Write(Message* m, const gfx::Size& p) { | |
466 m->WriteInt(p.width()); | |
467 m->WriteInt(p.height()); | |
468 } | |
469 | |
470 bool ParamTraits<gfx::Size>::Read(const Message* m, void** iter, gfx::Size* r) { | |
471 int w, h; | |
472 if (!m->ReadInt(iter, &w) || | |
473 !m->ReadInt(iter, &h)) | |
474 return false; | |
475 r->set_width(w); | |
476 r->set_height(h); | |
477 return true; | |
478 } | |
479 | |
480 void ParamTraits<gfx::Size>::Log(const gfx::Size& p, std::string* l) { | |
481 l->append(base::StringPrintf("(%d, %d)", p.width(), p.height())); | |
482 } | |
483 | |
484 void ParamTraits<gfx::Rect>::Write(Message* m, const gfx::Rect& p) { | |
485 m->WriteInt(p.x()); | |
486 m->WriteInt(p.y()); | |
487 m->WriteInt(p.width()); | |
488 m->WriteInt(p.height()); | |
489 } | |
490 | |
491 bool ParamTraits<gfx::Rect>::Read(const Message* m, void** iter, gfx::Rect* r) { | |
492 int x, y, w, h; | |
493 if (!m->ReadInt(iter, &x) || | |
494 !m->ReadInt(iter, &y) || | |
495 !m->ReadInt(iter, &w) || | |
496 !m->ReadInt(iter, &h)) | |
497 return false; | |
498 r->set_x(x); | |
499 r->set_y(y); | |
500 r->set_width(w); | |
501 r->set_height(h); | |
502 return true; | |
503 } | |
504 | |
505 void ParamTraits<gfx::Rect>::Log(const gfx::Rect& p, std::string* l) { | |
506 l->append(base::StringPrintf("(%d, %d, %d, %d)", p.x(), p.y(), | |
507 p.width(), p.height())); | |
508 } | |
509 | |
510 void ParamTraits<ui::Range>::Write(Message* m, const ui::Range& r) { | |
511 m->WriteSize(r.start()); | |
512 m->WriteSize(r.end()); | |
513 } | |
514 | |
515 bool ParamTraits<ui::Range>::Read(const Message* m, void** iter, ui::Range* r) { | |
516 size_t start, end; | |
517 if (!m->ReadSize(iter, &start) || !m->ReadSize(iter, &end)) | |
518 return false; | |
519 r->set_start(start); | |
520 r->set_end(end); | |
521 return true; | |
522 } | |
523 | |
524 void ParamTraits<ui::Range>::Log(const ui::Range& r, std::string* l) { | |
525 l->append(base::StringPrintf("(%"PRIuS", %"PRIuS")", r.start(), r.end())); | |
526 } | |
527 | |
528 void ParamTraits<SkBitmap>::Write(Message* m, const SkBitmap& p) { | |
529 size_t fixed_size = sizeof(SkBitmap_Data); | |
530 SkBitmap_Data bmp_data; | |
531 bmp_data.InitSkBitmapDataForTransfer(p); | |
532 m->WriteData(reinterpret_cast<const char*>(&bmp_data), | |
533 static_cast<int>(fixed_size)); | |
534 size_t pixel_size = p.getSize(); | |
535 SkAutoLockPixels p_lock(p); | |
536 m->WriteData(reinterpret_cast<const char*>(p.getPixels()), | |
537 static_cast<int>(pixel_size)); | |
538 } | |
539 | |
540 bool ParamTraits<SkBitmap>::Read(const Message* m, void** iter, SkBitmap* r) { | |
541 const char* fixed_data; | |
542 int fixed_data_size = 0; | |
543 if (!m->ReadData(iter, &fixed_data, &fixed_data_size) || | |
544 (fixed_data_size <= 0)) { | |
545 NOTREACHED(); | |
546 return false; | |
547 } | |
548 if (fixed_data_size != sizeof(SkBitmap_Data)) | |
549 return false; // Message is malformed. | |
550 | |
551 const char* variable_data; | |
552 int variable_data_size = 0; | |
553 if (!m->ReadData(iter, &variable_data, &variable_data_size) || | |
554 (variable_data_size < 0)) { | |
555 NOTREACHED(); | |
556 return false; | |
557 } | |
558 const SkBitmap_Data* bmp_data = | |
559 reinterpret_cast<const SkBitmap_Data*>(fixed_data); | |
560 return bmp_data->InitSkBitmapFromData(r, variable_data, variable_data_size); | |
561 } | |
562 | |
563 void ParamTraits<SkBitmap>::Log(const SkBitmap& p, std::string* l) { | |
564 l->append("<SkBitmap>"); | |
565 } | |
566 | |
567 } // namespace IPC | |
OLD | NEW |