Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(232)

Side by Side Diff: chrome/common/ipc_message_utils.cc

Issue 155905: Separates ipc code from common (http://crbug.com/16829) (Closed)
Patch Set: Fixes reference to 'common_message_traits' it's actually 'common_param_traits' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/common/ipc_message_utils.h ('k') | chrome/common/ipc_send_fds_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2006-2008 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 "chrome/common/ipc_message_utils.h"
6
7 #include "base/gfx/rect.h"
8 #include "base/json_writer.h"
9 #include "base/scoped_ptr.h"
10 #include "base/values.h"
11 #include "googleurl/src/gurl.h"
12 #ifndef EXCLUDE_SKIA_DEPENDENCIES
13 #include "third_party/skia/include/core/SkBitmap.h"
14 #endif
15 #include "webkit/glue/dom_operations.h"
16
17 namespace IPC {
18
19 const int kMaxRecursionDepth = 100;
20
21 #ifndef EXCLUDE_SKIA_DEPENDENCIES
22
23 namespace {
24
25 struct SkBitmap_Data {
26 // The configuration for the bitmap (bits per pixel, etc).
27 SkBitmap::Config fConfig;
28
29 // The width of the bitmap in pixels.
30 uint32 fWidth;
31
32 // The height of the bitmap in pixels.
33 uint32 fHeight;
34
35 // The number of bytes between subsequent rows of the bitmap.
36 uint32 fRowBytes;
37
38 void InitSkBitmapDataForTransfer(const SkBitmap& bitmap) {
39 fConfig = bitmap.config();
40 fWidth = bitmap.width();
41 fHeight = bitmap.height();
42 fRowBytes = bitmap.rowBytes();
43 }
44
45 // Returns whether |bitmap| successfully initialized.
46 bool InitSkBitmapFromData(SkBitmap* bitmap, const char* pixels,
47 size_t total_pixels) const {
48 if (total_pixels) {
49 bitmap->setConfig(fConfig, fWidth, fHeight, fRowBytes);
50 if (!bitmap->allocPixels())
51 return false;
52 if (total_pixels > bitmap->getSize())
53 return false;
54 memcpy(bitmap->getPixels(), pixels, total_pixels);
55 }
56 return true;
57 }
58 };
59
60 } // namespace
61
62
63 void ParamTraits<SkBitmap>::Write(Message* m, const SkBitmap& p) {
64 size_t fixed_size = sizeof(SkBitmap_Data);
65 SkBitmap_Data bmp_data;
66 bmp_data.InitSkBitmapDataForTransfer(p);
67 m->WriteData(reinterpret_cast<const char*>(&bmp_data),
68 static_cast<int>(fixed_size));
69 size_t pixel_size = p.getSize();
70 SkAutoLockPixels p_lock(p);
71 m->WriteData(reinterpret_cast<const char*>(p.getPixels()),
72 static_cast<int>(pixel_size));
73 }
74
75 bool ParamTraits<SkBitmap>::Read(const Message* m, void** iter, SkBitmap* r) {
76 const char* fixed_data;
77 int fixed_data_size = 0;
78 if (!m->ReadData(iter, &fixed_data, &fixed_data_size) ||
79 (fixed_data_size <= 0)) {
80 NOTREACHED();
81 return false;
82 }
83 if (fixed_data_size != sizeof(SkBitmap_Data))
84 return false; // Message is malformed.
85
86 const char* variable_data;
87 int variable_data_size = 0;
88 if (!m->ReadData(iter, &variable_data, &variable_data_size) ||
89 (variable_data_size < 0)) {
90 NOTREACHED();
91 return false;
92 }
93 const SkBitmap_Data* bmp_data =
94 reinterpret_cast<const SkBitmap_Data*>(fixed_data);
95 return bmp_data->InitSkBitmapFromData(r, variable_data, variable_data_size);
96 }
97
98 void ParamTraits<SkBitmap>::Log(const SkBitmap& p, std::wstring* l) {
99 l->append(StringPrintf(L"<SkBitmap>"));
100 }
101
102 #endif // EXCLUDE_SKIA_DEPENDENCIES
103
104 void ParamTraits<GURL>::Write(Message* m, const GURL& p) {
105 m->WriteString(p.possibly_invalid_spec());
106 // TODO(brettw) bug 684583: Add encoding for query params.
107 }
108
109 bool ParamTraits<GURL>::Read(const Message* m, void** iter, GURL* p) {
110 std::string s;
111 if (!m->ReadString(iter, &s)) {
112 *p = GURL();
113 return false;
114 }
115 *p = GURL(s);
116 return true;
117 }
118
119 void ParamTraits<GURL>::Log(const GURL& p, std::wstring* l) {
120 l->append(UTF8ToWide(p.spec()));
121 }
122
123 void ParamTraits<gfx::Point>::Write(Message* m, const gfx::Point& p) {
124 m->WriteInt(p.x());
125 m->WriteInt(p.y());
126 }
127
128 bool ParamTraits<gfx::Point>::Read(const Message* m, void** iter,
129 gfx::Point* r) {
130 int x, y;
131 if (!m->ReadInt(iter, &x) ||
132 !m->ReadInt(iter, &y))
133 return false;
134 r->set_x(x);
135 r->set_y(y);
136 return true;
137 }
138
139 void ParamTraits<gfx::Point>::Log(const gfx::Point& p, std::wstring* l) {
140 l->append(StringPrintf(L"(%d, %d)", p.x(), p.y()));
141 }
142
143
144 void ParamTraits<gfx::Rect>::Write(Message* m, const gfx::Rect& p) {
145 m->WriteInt(p.x());
146 m->WriteInt(p.y());
147 m->WriteInt(p.width());
148 m->WriteInt(p.height());
149 }
150
151 bool ParamTraits<gfx::Rect>::Read(const Message* m, void** iter, gfx::Rect* r) {
152 int x, y, w, h;
153 if (!m->ReadInt(iter, &x) ||
154 !m->ReadInt(iter, &y) ||
155 !m->ReadInt(iter, &w) ||
156 !m->ReadInt(iter, &h))
157 return false;
158 r->set_x(x);
159 r->set_y(y);
160 r->set_width(w);
161 r->set_height(h);
162 return true;
163 }
164
165 void ParamTraits<gfx::Rect>::Log(const gfx::Rect& p, std::wstring* l) {
166 l->append(StringPrintf(L"(%d, %d, %d, %d)", p.x(), p.y(),
167 p.width(), p.height()));
168 }
169
170
171 void ParamTraits<gfx::Size>::Write(Message* m, const gfx::Size& p) {
172 m->WriteInt(p.width());
173 m->WriteInt(p.height());
174 }
175
176 bool ParamTraits<gfx::Size>::Read(const Message* m, void** iter, gfx::Size* r) {
177 int w, h;
178 if (!m->ReadInt(iter, &w) ||
179 !m->ReadInt(iter, &h))
180 return false;
181 r->set_width(w);
182 r->set_height(h);
183 return true;
184 }
185
186 void ParamTraits<gfx::Size>::Log(const gfx::Size& p, std::wstring* l) {
187 l->append(StringPrintf(L"(%d, %d)", p.width(), p.height()));
188 }
189
190 void ParamTraits<webkit_glue::WebApplicationInfo>::Write(
191 Message* m, const webkit_glue::WebApplicationInfo& p) {
192 WriteParam(m, p.title);
193 WriteParam(m, p.description);
194 WriteParam(m, p.app_url);
195 WriteParam(m, p.icons.size());
196 for (size_t i = 0; i < p.icons.size(); ++i) {
197 WriteParam(m, p.icons[i].url);
198 WriteParam(m, p.icons[i].width);
199 WriteParam(m, p.icons[i].height);
200 }
201 }
202
203 bool ParamTraits<webkit_glue::WebApplicationInfo>::Read(
204 const Message* m, void** iter, webkit_glue::WebApplicationInfo* r) {
205 size_t icon_count;
206 bool result =
207 ReadParam(m, iter, &r->title) &&
208 ReadParam(m, iter, &r->description) &&
209 ReadParam(m, iter, &r->app_url) &&
210 ReadParam(m, iter, &icon_count);
211 if (!result)
212 return false;
213 for (size_t i = 0; i < icon_count && result; ++i) {
214 param_type::IconInfo icon_info;
215 result =
216 ReadParam(m, iter, &icon_info.url) &&
217 ReadParam(m, iter, &icon_info.width) &&
218 ReadParam(m, iter, &icon_info.height);
219 r->icons.push_back(icon_info);
220 }
221 return result;
222 }
223
224 void ParamTraits<webkit_glue::WebApplicationInfo>::Log(
225 const webkit_glue::WebApplicationInfo& p, std::wstring* l) {
226 l->append(L"<WebApplicationInfo>");
227 }
228
229 // Value serialization
230
231 static bool ReadValue(const Message* m, void** iter, Value** value,
232 int recursion);
233
234 static void WriteValue(Message* m, const Value* value, int recursion) {
235 if (recursion > kMaxRecursionDepth) {
236 LOG(WARNING) << "Max recursion depth hit in WriteValue.";
237 return;
238 }
239
240 m->WriteInt(value->GetType());
241
242 switch (value->GetType()) {
243 case Value::TYPE_NULL:
244 break;
245 case Value::TYPE_BOOLEAN: {
246 bool val;
247 value->GetAsBoolean(&val);
248 WriteParam(m, val);
249 break;
250 }
251 case Value::TYPE_INTEGER: {
252 int val;
253 value->GetAsInteger(&val);
254 WriteParam(m, val);
255 break;
256 }
257 case Value::TYPE_REAL: {
258 double val;
259 value->GetAsReal(&val);
260 WriteParam(m, val);
261 break;
262 }
263 case Value::TYPE_STRING: {
264 std::string val;
265 value->GetAsString(&val);
266 WriteParam(m, val);
267 break;
268 }
269 case Value::TYPE_BINARY: {
270 NOTREACHED() << "Don't send BinaryValues over IPC.";
271 }
272 case Value::TYPE_DICTIONARY: {
273 const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
274
275 WriteParam(m, static_cast<int>(dict->GetSize()));
276
277 for (DictionaryValue::key_iterator it = dict->begin_keys();
278 it != dict->end_keys(); ++it) {
279 Value* subval;
280 if (dict->Get(*it, &subval)) {
281 WriteParam(m, *it);
282 WriteValue(m, subval, recursion + 1);
283 } else {
284 NOTREACHED() << "DictionaryValue iterators are filthy liars.";
285 }
286 }
287 break;
288 }
289 case Value::TYPE_LIST: {
290 const ListValue* list = static_cast<const ListValue*>(value);
291 WriteParam(m, static_cast<int>(list->GetSize()));
292 for (size_t i = 0; i < list->GetSize(); ++i) {
293 Value* subval;
294 if (list->Get(i, &subval)) {
295 WriteValue(m, subval, recursion + 1);
296 } else {
297 NOTREACHED() << "ListValue::GetSize is a filthy liar.";
298 }
299 }
300 break;
301 }
302 }
303 }
304
305 // Helper for ReadValue that reads a DictionaryValue into a pre-allocated
306 // object.
307 static bool ReadDictionaryValue(const Message* m, void** iter,
308 DictionaryValue* value, int recursion) {
309 int size;
310 if (!ReadParam(m, iter, &size))
311 return false;
312
313 for (int i = 0; i < size; ++i) {
314 std::wstring key;
315 Value* subval;
316 if (!ReadParam(m, iter, &key) ||
317 !ReadValue(m, iter, &subval, recursion + 1))
318 return false;
319 value->Set(key, subval);
320 }
321
322 return true;
323 }
324
325 // Helper for ReadValue that reads a ReadListValue into a pre-allocated
326 // object.
327 static bool ReadListValue(const Message* m, void** iter,
328 ListValue* value, int recursion) {
329 int size;
330 if (!ReadParam(m, iter, &size))
331 return false;
332
333 for (int i = 0; i < size; ++i) {
334 Value* subval;
335 if (!ReadValue(m, iter, &subval, recursion + 1))
336 return false;
337 value->Set(i, subval);
338 }
339
340 return true;
341 }
342
343 static bool ReadValue(const Message* m, void** iter, Value** value,
344 int recursion) {
345 if (recursion > kMaxRecursionDepth) {
346 LOG(WARNING) << "Max recursion depth hit in ReadValue.";
347 return false;
348 }
349
350 int type;
351 if (!ReadParam(m, iter, &type))
352 return false;
353
354 switch (type) {
355 case Value::TYPE_NULL:
356 *value = Value::CreateNullValue();
357 break;
358 case Value::TYPE_BOOLEAN: {
359 bool val;
360 if (!ReadParam(m, iter, &val))
361 return false;
362 *value = Value::CreateBooleanValue(val);
363 break;
364 }
365 case Value::TYPE_INTEGER: {
366 int val;
367 if (!ReadParam(m, iter, &val))
368 return false;
369 *value = Value::CreateIntegerValue(val);
370 break;
371 }
372 case Value::TYPE_REAL: {
373 double val;
374 if (!ReadParam(m, iter, &val))
375 return false;
376 *value = Value::CreateRealValue(val);
377 break;
378 }
379 case Value::TYPE_STRING: {
380 std::string val;
381 if (!ReadParam(m, iter, &val))
382 return false;
383 *value = Value::CreateStringValue(val);
384 break;
385 }
386 case Value::TYPE_BINARY: {
387 NOTREACHED() << "Don't send BinaryValues over IPC.";
388 break;
389 }
390 case Value::TYPE_DICTIONARY: {
391 scoped_ptr<DictionaryValue> val(new DictionaryValue());
392 if (!ReadDictionaryValue(m, iter, val.get(), recursion))
393 return false;
394 *value = val.release();
395 break;
396 }
397 case Value::TYPE_LIST: {
398 scoped_ptr<ListValue> val(new ListValue());
399 if (!ReadListValue(m, iter, val.get(), recursion))
400 return false;
401 *value = val.release();
402 break;
403 }
404 default:
405 return false;
406 }
407
408 return true;
409 }
410
411 void ParamTraits<DictionaryValue>::Write(Message* m, const param_type& p) {
412 WriteValue(m, &p, 0);
413 }
414
415 bool ParamTraits<DictionaryValue>::Read(
416 const Message* m, void** iter, param_type* r) {
417 int type;
418 if (!ReadParam(m, iter, &type) || type != Value::TYPE_DICTIONARY)
419 return false;
420
421 return ReadDictionaryValue(m, iter, r, 0);
422 }
423
424 void ParamTraits<DictionaryValue>::Log(const param_type& p, std::wstring* l) {
425 std::string json;
426 JSONWriter::Write(&p, false, &json);
427 l->append(UTF8ToWide(json));
428 }
429
430 void ParamTraits<ListValue>::Write(Message* m, const param_type& p) {
431 WriteValue(m, &p, 0);
432 }
433
434 bool ParamTraits<ListValue>::Read(
435 const Message* m, void** iter, param_type* r) {
436 int type;
437 if (!ReadParam(m, iter, &type) || type != Value::TYPE_LIST)
438 return false;
439
440 return ReadListValue(m, iter, r, 0);
441 }
442
443 void ParamTraits<ListValue>::Log(const param_type& p, std::wstring* l) {
444 std::string json;
445 JSONWriter::Write(&p, false, &json);
446 l->append(UTF8ToWide(json));
447 }
448 } // namespace IPC
OLDNEW
« no previous file with comments | « chrome/common/ipc_message_utils.h ('k') | chrome/common/ipc_send_fds_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698