1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set sw=2 ts=8 et tw=80 : */
3 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is Mozilla IPC.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Ben Turner <bent.mozilla@gmail.com>.
20 : * Portions created by the Initial Developer are Copyright (C) 2009
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #ifndef __IPC_GLUE_IPCMESSAGEUTILS_H__
40 : #define __IPC_GLUE_IPCMESSAGEUTILS_H__
41 :
42 : #include "chrome/common/ipc_message_utils.h"
43 :
44 : #include "mozilla/Util.h"
45 :
46 : #include "prtypes.h"
47 : #include "nsID.h"
48 : #include "nsMemory.h"
49 : #include "nsStringGlue.h"
50 : #include "nsTArray.h"
51 : #include "gfx3DMatrix.h"
52 : #include "gfxColor.h"
53 : #include "gfxMatrix.h"
54 : #include "gfxPattern.h"
55 : #include "nsRect.h"
56 : #include "nsRegion.h"
57 : #include "gfxASurface.h"
58 : #include "Layers.h"
59 :
60 : #ifdef _MSC_VER
61 : #pragma warning( disable : 4800 )
62 : #endif
63 :
64 : #if !defined(OS_POSIX)
65 : // This condition must be kept in sync with the one in
66 : // ipc_message_utils.h, but this dummy definition of
67 : // base::FileDescriptor acts as a static assert that we only get one
68 : // def or the other (or neither, in which case code using
69 : // FileDescriptor fails to build)
70 : namespace base { struct FileDescriptor { }; }
71 : #endif
72 :
73 : using mozilla::layers::LayerManager;
74 :
75 : namespace mozilla {
76 :
77 : typedef gfxPattern::GraphicsFilter GraphicsFilterType;
78 : typedef gfxASurface::gfxSurfaceType gfxSurfaceType;
79 : typedef LayerManager::LayersBackend LayersBackend;
80 : typedef gfxASurface::gfxImageFormat PixelFormat;
81 :
82 : // This is a cross-platform approximation to HANDLE, which we expect
83 : // to be typedef'd to void* or thereabouts.
84 : typedef uintptr_t WindowsHandle;
85 :
86 : // XXX there are out of place and might be generally useful. Could
87 : // move to nscore.h or something.
88 0 : struct void_t {
89 0 : bool operator==(const void_t&) const { return true; }
90 : };
91 0 : struct null_t {
92 0 : bool operator==(const null_t&) const { return true; }
93 : };
94 :
95 : } // namespace mozilla
96 :
97 : namespace IPC {
98 :
99 : /**
100 : * Generic enum serializer.
101 : *
102 : * This is a generic serializer for any enum type used in IPDL.
103 : * Programmers can define ParamTraits<E> for enum type E by deriving
104 : * EnumSerializer<E, smallestLegal, highGuard>.
105 : *
106 : * The serializer would check value againts a range specified by
107 : * smallestLegal and highGuard. Only values from smallestLegal to
108 : * highGuard are valid, include smallestLegal but highGuard.
109 : *
110 : * For example, following is definition of serializer for enum type FOO.
111 : * \code
112 : * enum FOO { FOO_FIRST, FOO_SECOND, FOO_LAST, NUM_FOO };
113 : *
114 : * template <>
115 : * struct ParamTraits<FOO>:
116 : * public EnumSerializer<FOO, FOO_FIRST, NUM_FOO> {};
117 : * \endcode
118 : * FOO_FIRST, FOO_SECOND, and FOO_LAST are valid value.
119 : *
120 : * \sa https://developer.mozilla.org/en/IPDL/Type_Serialization
121 : */
122 : template <typename E, E smallestLegal, E highBound>
123 : struct EnumSerializer {
124 : typedef E paramType;
125 :
126 0 : static bool IsLegalValue(const paramType &aValue) {
127 0 : return smallestLegal <= aValue && aValue < highBound;
128 : }
129 :
130 0 : static void Write(Message* aMsg, const paramType& aValue) {
131 0 : MOZ_ASSERT(IsLegalValue(aValue));
132 0 : WriteParam(aMsg, (int32)aValue);
133 0 : }
134 :
135 0 : static bool Read(const Message* aMsg, void** aIter, paramType* aResult) {
136 : int32 value;
137 0 : if(!ReadParam(aMsg, aIter, &value) ||
138 : !IsLegalValue(paramType(value))) {
139 0 : return false;
140 : }
141 0 : *aResult = paramType(value);
142 0 : return true;
143 : }
144 : };
145 :
146 : template<>
147 : struct ParamTraits<PRInt8>
148 : {
149 : typedef PRInt8 paramType;
150 :
151 : static void Write(Message* aMsg, const paramType& aParam)
152 : {
153 : aMsg->WriteBytes(&aParam, sizeof(aParam));
154 : }
155 :
156 : static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
157 : {
158 : const char* outp;
159 : if (!aMsg->ReadBytes(aIter, &outp, sizeof(*aResult)))
160 : return false;
161 :
162 : *aResult = *reinterpret_cast<const paramType*>(outp);
163 : return true;
164 : }
165 : };
166 :
167 : template<>
168 : struct ParamTraits<PRUint8>
169 : {
170 : typedef PRUint8 paramType;
171 :
172 0 : static void Write(Message* aMsg, const paramType& aParam)
173 : {
174 0 : aMsg->WriteBytes(&aParam, sizeof(aParam));
175 0 : }
176 :
177 0 : static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
178 : {
179 : const char* outp;
180 0 : if (!aMsg->ReadBytes(aIter, &outp, sizeof(*aResult)))
181 0 : return false;
182 :
183 0 : *aResult = *reinterpret_cast<const paramType*>(outp);
184 0 : return true;
185 : }
186 : };
187 :
188 : #if !defined(OS_POSIX)
189 : // See above re: keeping definitions in sync
190 : template<>
191 : struct ParamTraits<base::FileDescriptor>
192 : {
193 : typedef base::FileDescriptor paramType;
194 : static void Write(Message* aMsg, const paramType& aParam) {
195 : NS_RUNTIMEABORT("FileDescriptor isn't meaningful on this platform");
196 : }
197 : static bool Read(const Message* aMsg, void** aIter, paramType* aResult) {
198 : NS_RUNTIMEABORT("FileDescriptor isn't meaningful on this platform");
199 : return false;
200 : }
201 : };
202 : #endif // !defined(OS_POSIX)
203 :
204 : template <>
205 : struct ParamTraits<nsACString>
206 : {
207 : typedef nsACString paramType;
208 :
209 0 : static void Write(Message* aMsg, const paramType& aParam)
210 : {
211 0 : bool isVoid = aParam.IsVoid();
212 0 : aMsg->WriteBool(isVoid);
213 :
214 0 : if (isVoid)
215 : // represents a NULL pointer
216 0 : return;
217 :
218 0 : PRUint32 length = aParam.Length();
219 0 : WriteParam(aMsg, length);
220 0 : aMsg->WriteBytes(aParam.BeginReading(), length);
221 : }
222 :
223 0 : static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
224 : {
225 : bool isVoid;
226 0 : if (!aMsg->ReadBool(aIter, &isVoid))
227 0 : return false;
228 :
229 0 : if (isVoid) {
230 0 : aResult->SetIsVoid(true);
231 0 : return true;
232 : }
233 :
234 : PRUint32 length;
235 0 : if (ReadParam(aMsg, aIter, &length)) {
236 : const char* buf;
237 0 : if (aMsg->ReadBytes(aIter, &buf, length)) {
238 0 : aResult->Assign(buf, length);
239 0 : return true;
240 : }
241 : }
242 0 : return false;
243 : }
244 :
245 : static void Log(const paramType& aParam, std::wstring* aLog)
246 : {
247 : if (aParam.IsVoid())
248 : aLog->append(L"(NULL)");
249 : else
250 : aLog->append(UTF8ToWide(aParam.BeginReading()));
251 : }
252 : };
253 :
254 : template <>
255 : struct ParamTraits<nsAString>
256 : {
257 : typedef nsAString paramType;
258 :
259 0 : static void Write(Message* aMsg, const paramType& aParam)
260 : {
261 0 : bool isVoid = aParam.IsVoid();
262 0 : aMsg->WriteBool(isVoid);
263 :
264 0 : if (isVoid)
265 : // represents a NULL pointer
266 0 : return;
267 :
268 0 : PRUint32 length = aParam.Length();
269 0 : WriteParam(aMsg, length);
270 0 : aMsg->WriteBytes(aParam.BeginReading(), length * sizeof(PRUnichar));
271 : }
272 :
273 0 : static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
274 : {
275 : bool isVoid;
276 0 : if (!aMsg->ReadBool(aIter, &isVoid))
277 0 : return false;
278 :
279 0 : if (isVoid) {
280 0 : aResult->SetIsVoid(true);
281 0 : return true;
282 : }
283 :
284 : PRUint32 length;
285 0 : if (ReadParam(aMsg, aIter, &length)) {
286 : const PRUnichar* buf;
287 0 : if (aMsg->ReadBytes(aIter, reinterpret_cast<const char**>(&buf),
288 0 : length * sizeof(PRUnichar))) {
289 0 : aResult->Assign(buf, length);
290 0 : return true;
291 : }
292 : }
293 0 : return false;
294 : }
295 :
296 : static void Log(const paramType& aParam, std::wstring* aLog)
297 : {
298 : if (aParam.IsVoid())
299 : aLog->append(L"(NULL)");
300 : else {
301 : #ifdef WCHAR_T_IS_UTF16
302 : aLog->append(reinterpret_cast<const wchar_t*>(aParam.BeginReading()));
303 : #else
304 : PRUint32 length = aParam.Length();
305 : for (PRUint32 index = 0; index < length; index++) {
306 : aLog->push_back(std::wstring::value_type(aParam[index]));
307 : }
308 : #endif
309 : }
310 : }
311 : };
312 :
313 : template <>
314 : struct ParamTraits<nsCString> : ParamTraits<nsACString>
315 : {
316 : typedef nsCString paramType;
317 : };
318 :
319 : #ifdef MOZILLA_INTERNAL_API
320 :
321 : template<>
322 : struct ParamTraits<nsCAutoString> : ParamTraits<nsCString>
323 : {
324 : typedef nsCAutoString paramType;
325 : };
326 :
327 : #endif // MOZILLA_INTERNAL_API
328 :
329 : template <>
330 : struct ParamTraits<nsString> : ParamTraits<nsAString>
331 : {
332 : typedef nsString paramType;
333 : };
334 :
335 : template <typename E, class A>
336 : struct ParamTraits<nsTArray<E, A> >
337 : {
338 : typedef nsTArray<E, A> paramType;
339 :
340 0 : static void Write(Message* aMsg, const paramType& aParam)
341 : {
342 0 : PRUint32 length = aParam.Length();
343 0 : WriteParam(aMsg, length);
344 0 : for (PRUint32 index = 0; index < length; index++) {
345 0 : WriteParam(aMsg, aParam[index]);
346 : }
347 0 : }
348 :
349 0 : static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
350 : {
351 : PRUint32 length;
352 0 : if (!ReadParam(aMsg, aIter, &length)) {
353 0 : return false;
354 : }
355 :
356 0 : aResult->SetCapacity(length);
357 0 : for (PRUint32 index = 0; index < length; index++) {
358 0 : E* element = aResult->AppendElement();
359 0 : if (!(element && ReadParam(aMsg, aIter, element))) {
360 0 : return false;
361 : }
362 : }
363 :
364 0 : return true;
365 : }
366 :
367 : static void Log(const paramType& aParam, std::wstring* aLog)
368 : {
369 : for (PRUint32 index = 0; index < aParam.Length(); index++) {
370 : if (index) {
371 : aLog->append(L" ");
372 : }
373 : LogParam(aParam[index], aLog);
374 : }
375 : }
376 : };
377 :
378 : template<typename E>
379 : struct ParamTraits<InfallibleTArray<E> > :
380 : ParamTraits<nsTArray<E, nsTArrayInfallibleAllocator> >
381 : {
382 : typedef InfallibleTArray<E> paramType;
383 :
384 : // use nsTArray Write() method
385 :
386 : // deserialize the array fallibly, but return an InfallibleTArray
387 0 : static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
388 : {
389 0 : nsTArray<E> temp;
390 0 : if (!ReadParam(aMsg, aIter, &temp))
391 0 : return false;
392 :
393 0 : aResult->SwapElements(temp);
394 0 : return true;
395 : }
396 :
397 : // use nsTArray Log() method
398 : };
399 :
400 : template<>
401 : struct ParamTraits<float>
402 : {
403 : typedef float paramType;
404 :
405 0 : static void Write(Message* aMsg, const paramType& aParam)
406 : {
407 0 : aMsg->WriteBytes(&aParam, sizeof(paramType));
408 0 : }
409 :
410 0 : static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
411 : {
412 : const char* outFloat;
413 0 : if (!aMsg->ReadBytes(aIter, &outFloat, sizeof(float)))
414 0 : return false;
415 0 : *aResult = *reinterpret_cast<const float*>(outFloat);
416 0 : return true;
417 : }
418 :
419 : static void Log(const paramType& aParam, std::wstring* aLog)
420 : {
421 : aLog->append(StringPrintf(L"%g", aParam));
422 : }
423 : };
424 :
425 : template<>
426 : struct ParamTraits<gfxMatrix>
427 : {
428 : typedef gfxMatrix paramType;
429 :
430 0 : static void Write(Message* aMsg, const paramType& aParam)
431 : {
432 0 : WriteParam(aMsg, aParam.xx);
433 0 : WriteParam(aMsg, aParam.xy);
434 0 : WriteParam(aMsg, aParam.yx);
435 0 : WriteParam(aMsg, aParam.yy);
436 0 : WriteParam(aMsg, aParam.x0);
437 0 : WriteParam(aMsg, aParam.y0);
438 0 : }
439 :
440 0 : static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
441 : {
442 0 : if (ReadParam(aMsg, aIter, &aResult->xx) &&
443 0 : ReadParam(aMsg, aIter, &aResult->xy) &&
444 0 : ReadParam(aMsg, aIter, &aResult->yx) &&
445 0 : ReadParam(aMsg, aIter, &aResult->yy) &&
446 0 : ReadParam(aMsg, aIter, &aResult->x0) &&
447 0 : ReadParam(aMsg, aIter, &aResult->y0))
448 0 : return true;
449 :
450 0 : return false;
451 : }
452 :
453 : static void Log(const paramType& aParam, std::wstring* aLog)
454 : {
455 : aLog->append(StringPrintf(L"[[%g %g] [%g %g] [%g %g]]", aParam.xx, aParam.xy, aParam.yx, aParam.yy,
456 : aParam.x0, aParam.y0));
457 : }
458 : };
459 :
460 : template<>
461 : struct ParamTraits<gfx3DMatrix>
462 : {
463 : typedef gfx3DMatrix paramType;
464 :
465 0 : static void Write(Message* msg, const paramType& param)
466 : {
467 : #define Wr(_f) WriteParam(msg, param. _f)
468 0 : Wr(_11); Wr(_12); Wr(_13); Wr(_14);
469 0 : Wr(_21); Wr(_22); Wr(_23); Wr(_24);
470 0 : Wr(_31); Wr(_32); Wr(_33); Wr(_34);
471 0 : Wr(_41); Wr(_42); Wr(_43); Wr(_44);
472 : #undef Wr
473 0 : }
474 :
475 0 : static bool Read(const Message* msg, void** iter, paramType* result)
476 : {
477 : #define Rd(_f) ReadParam(msg, iter, &result-> _f)
478 0 : return (Rd(_11) && Rd(_12) && Rd(_13) && Rd(_14) &&
479 0 : Rd(_21) && Rd(_22) && Rd(_23) && Rd(_24) &&
480 0 : Rd(_31) && Rd(_32) && Rd(_33) && Rd(_34) &&
481 0 : Rd(_41) && Rd(_42) && Rd(_43) && Rd(_44));
482 : #undef Rd
483 : }
484 : };
485 :
486 : template<>
487 : struct ParamTraits<mozilla::GraphicsFilterType>
488 : {
489 : typedef mozilla::GraphicsFilterType paramType;
490 :
491 0 : static void Write(Message* msg, const paramType& param)
492 : {
493 0 : switch (param) {
494 : case gfxPattern::FILTER_FAST:
495 : case gfxPattern::FILTER_GOOD:
496 : case gfxPattern::FILTER_BEST:
497 : case gfxPattern::FILTER_NEAREST:
498 : case gfxPattern::FILTER_BILINEAR:
499 : case gfxPattern::FILTER_GAUSSIAN:
500 0 : WriteParam(msg, int32(param));
501 0 : return;
502 :
503 : }
504 0 : NS_RUNTIMEABORT("not reached");
505 : }
506 :
507 0 : static bool Read(const Message* msg, void** iter, paramType* result)
508 : {
509 : int32 filter;
510 0 : if (!ReadParam(msg, iter, &filter))
511 0 : return false;
512 :
513 0 : switch (filter) {
514 : case gfxPattern::FILTER_FAST:
515 : case gfxPattern::FILTER_GOOD:
516 : case gfxPattern::FILTER_BEST:
517 : case gfxPattern::FILTER_NEAREST:
518 : case gfxPattern::FILTER_BILINEAR:
519 : case gfxPattern::FILTER_GAUSSIAN:
520 0 : *result = paramType(filter);
521 0 : return true;
522 :
523 : default:
524 0 : return false;
525 : }
526 : }
527 : };
528 :
529 : template<>
530 : struct ParamTraits<mozilla::gfxSurfaceType>
531 : {
532 : typedef mozilla::gfxSurfaceType paramType;
533 :
534 0 : static void Write(Message* msg, const paramType& param)
535 : {
536 0 : if (gfxASurface::SurfaceTypeImage <= param &&
537 : param < gfxASurface::SurfaceTypeMax) {
538 0 : WriteParam(msg, int32(param));
539 0 : return;
540 : }
541 0 : NS_RUNTIMEABORT("surface type not reached");
542 : }
543 :
544 0 : static bool Read(const Message* msg, void** iter, paramType* result)
545 : {
546 : int32 filter;
547 0 : if (!ReadParam(msg, iter, &filter))
548 0 : return false;
549 :
550 0 : if (gfxASurface::SurfaceTypeImage <= filter &&
551 : filter < gfxASurface::SurfaceTypeMax) {
552 0 : *result = paramType(filter);
553 0 : return true;
554 : }
555 0 : return false;
556 : }
557 : };
558 :
559 : template<>
560 : struct ParamTraits<mozilla::LayersBackend>
561 : {
562 : typedef mozilla::LayersBackend paramType;
563 :
564 0 : static void Write(Message* msg, const paramType& param)
565 : {
566 0 : if (LayerManager::LAYERS_NONE <= param &&
567 : param < LayerManager::LAYERS_LAST) {
568 0 : WriteParam(msg, int32(param));
569 0 : return;
570 : }
571 0 : NS_RUNTIMEABORT("backend type not reached");
572 : }
573 :
574 0 : static bool Read(const Message* msg, void** iter, paramType* result)
575 : {
576 : int32 type;
577 0 : if (!ReadParam(msg, iter, &type))
578 0 : return false;
579 :
580 0 : if (LayerManager::LAYERS_NONE <= type &&
581 : type < LayerManager::LAYERS_LAST) {
582 0 : *result = paramType(type);
583 0 : return true;
584 : }
585 0 : return false;
586 : }
587 : };
588 :
589 : template<>
590 : struct ParamTraits<mozilla::PixelFormat>
591 : {
592 : typedef mozilla::PixelFormat paramType;
593 :
594 : static bool IsLegalPixelFormat(const paramType& format)
595 : {
596 : return (gfxASurface::ImageFormatARGB32 <= format &&
597 : format < gfxASurface::ImageFormatUnknown);
598 : }
599 :
600 : static void Write(Message* msg, const paramType& param)
601 : {
602 : if (!IsLegalPixelFormat(param)) {
603 : NS_RUNTIMEABORT("Unknown pixel format");
604 : }
605 : WriteParam(msg, int32(param));
606 : return;
607 : }
608 :
609 : static bool Read(const Message* msg, void** iter, paramType* result)
610 : {
611 : int32 format;
612 : if (!ReadParam(msg, iter, &format) ||
613 : !IsLegalPixelFormat(paramType(format))) {
614 : return false;
615 : }
616 : *result = paramType(format);
617 : return true;
618 : }
619 : };
620 :
621 : template<>
622 : struct ParamTraits<gfxRGBA>
623 : {
624 : typedef gfxRGBA paramType;
625 :
626 0 : static void Write(Message* msg, const paramType& param)
627 : {
628 0 : WriteParam(msg, param.r);
629 0 : WriteParam(msg, param.g);
630 0 : WriteParam(msg, param.b);
631 0 : WriteParam(msg, param.a);
632 0 : }
633 :
634 0 : static bool Read(const Message* msg, void** iter, paramType* result)
635 : {
636 0 : return (ReadParam(msg, iter, &result->r) &&
637 0 : ReadParam(msg, iter, &result->g) &&
638 0 : ReadParam(msg, iter, &result->b) &&
639 0 : ReadParam(msg, iter, &result->a));
640 : }
641 : };
642 :
643 : template<>
644 : struct ParamTraits<mozilla::void_t>
645 : {
646 : typedef mozilla::void_t paramType;
647 0 : static void Write(Message* aMsg, const paramType& aParam) { }
648 : static bool
649 0 : Read(const Message* aMsg, void** aIter, paramType* aResult)
650 : {
651 0 : *aResult = paramType();
652 0 : return true;
653 : }
654 : };
655 :
656 : template<>
657 : struct ParamTraits<mozilla::null_t>
658 : {
659 : typedef mozilla::null_t paramType;
660 0 : static void Write(Message* aMsg, const paramType& aParam) { }
661 : static bool
662 0 : Read(const Message* aMsg, void** aIter, paramType* aResult)
663 : {
664 0 : *aResult = paramType();
665 0 : return true;
666 : }
667 : };
668 :
669 : template<>
670 : struct ParamTraits<nsIntPoint>
671 : {
672 : typedef nsIntPoint paramType;
673 :
674 0 : static void Write(Message* msg, const paramType& param)
675 : {
676 0 : WriteParam(msg, param.x);
677 0 : WriteParam(msg, param.y);
678 0 : }
679 :
680 0 : static bool Read(const Message* msg, void** iter, paramType* result)
681 : {
682 0 : return (ReadParam(msg, iter, &result->x) &&
683 0 : ReadParam(msg, iter, &result->y));
684 : }
685 : };
686 :
687 : template<>
688 : struct ParamTraits<nsIntRect>
689 : {
690 : typedef nsIntRect paramType;
691 :
692 0 : static void Write(Message* msg, const paramType& param)
693 : {
694 0 : WriteParam(msg, param.x);
695 0 : WriteParam(msg, param.y);
696 0 : WriteParam(msg, param.width);
697 0 : WriteParam(msg, param.height);
698 0 : }
699 :
700 0 : static bool Read(const Message* msg, void** iter, paramType* result)
701 : {
702 0 : return (ReadParam(msg, iter, &result->x) &&
703 0 : ReadParam(msg, iter, &result->y) &&
704 0 : ReadParam(msg, iter, &result->width) &&
705 0 : ReadParam(msg, iter, &result->height));
706 : }
707 : };
708 :
709 : template<>
710 : struct ParamTraits<nsIntRegion>
711 : {
712 : typedef nsIntRegion paramType;
713 :
714 0 : static void Write(Message* msg, const paramType& param)
715 : {
716 0 : nsIntRegionRectIterator it(param);
717 0 : while (const nsIntRect* r = it.Next())
718 0 : WriteParam(msg, *r);
719 : // empty rects are sentinel values because nsRegions will never
720 : // contain them
721 0 : WriteParam(msg, nsIntRect());
722 0 : }
723 :
724 0 : static bool Read(const Message* msg, void** iter, paramType* result)
725 : {
726 0 : nsIntRect rect;
727 0 : while (ReadParam(msg, iter, &rect)) {
728 0 : if (rect.IsEmpty())
729 0 : return true;
730 0 : result->Or(*result, rect);
731 : }
732 0 : return false;
733 : }
734 : };
735 :
736 : template<>
737 : struct ParamTraits<nsIntSize>
738 : {
739 : typedef nsIntSize paramType;
740 :
741 0 : static void Write(Message* msg, const paramType& param)
742 : {
743 0 : WriteParam(msg, param.width);
744 0 : WriteParam(msg, param.height);
745 0 : }
746 :
747 0 : static bool Read(const Message* msg, void** iter, paramType* result)
748 : {
749 0 : return (ReadParam(msg, iter, &result->width) &&
750 0 : ReadParam(msg, iter, &result->height));
751 : }
752 : };
753 :
754 : template<>
755 : struct ParamTraits<nsRect>
756 : {
757 : typedef nsRect paramType;
758 :
759 0 : static void Write(Message* msg, const paramType& param)
760 : {
761 0 : WriteParam(msg, param.x);
762 0 : WriteParam(msg, param.y);
763 0 : WriteParam(msg, param.width);
764 0 : WriteParam(msg, param.height);
765 0 : }
766 :
767 0 : static bool Read(const Message* msg, void** iter, paramType* result)
768 : {
769 0 : return (ReadParam(msg, iter, &result->x) &&
770 0 : ReadParam(msg, iter, &result->y) &&
771 0 : ReadParam(msg, iter, &result->width) &&
772 0 : ReadParam(msg, iter, &result->height));
773 : }
774 : };
775 :
776 : template<>
777 : struct ParamTraits<nsID>
778 : {
779 : typedef nsID paramType;
780 :
781 0 : static void Write(Message* aMsg, const paramType& aParam)
782 : {
783 0 : WriteParam(aMsg, aParam.m0);
784 0 : WriteParam(aMsg, aParam.m1);
785 0 : WriteParam(aMsg, aParam.m2);
786 0 : for (unsigned int i = 0; i < mozilla::ArrayLength(aParam.m3); i++) {
787 0 : WriteParam(aMsg, aParam.m3[i]);
788 : }
789 0 : }
790 :
791 0 : static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
792 : {
793 0 : if(!ReadParam(aMsg, aIter, &(aResult->m0)) ||
794 0 : !ReadParam(aMsg, aIter, &(aResult->m1)) ||
795 0 : !ReadParam(aMsg, aIter, &(aResult->m2)))
796 0 : return false;
797 :
798 0 : for (unsigned int i = 0; i < mozilla::ArrayLength(aResult->m3); i++)
799 0 : if (!ReadParam(aMsg, aIter, &(aResult->m3[i])))
800 0 : return false;
801 :
802 0 : return true;
803 : }
804 :
805 : static void Log(const paramType& aParam, std::wstring* aLog)
806 : {
807 : aLog->append(L"{");
808 : aLog->append(StringPrintf(L"%8.8X-%4.4X-%4.4X-",
809 : aParam.m0,
810 : aParam.m1,
811 : aParam.m2));
812 : for (unsigned int i = 0; i < mozilla::ArrayLength(aParam.m3); i++)
813 : aLog->append(StringPrintf(L"%2.2X", aParam.m3[i]));
814 : aLog->append(L"}");
815 : }
816 : };
817 :
818 : } /* namespace IPC */
819 :
820 : #endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */
|