ipc/glue/IPCMessageUtils.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set sw=2 ts=8 et tw=80 : */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #ifndef __IPC_GLUE_IPCMESSAGEUTILS_H__
michael@0 8 #define __IPC_GLUE_IPCMESSAGEUTILS_H__
michael@0 9
michael@0 10 #include "base/process_util.h"
michael@0 11 #include "chrome/common/ipc_message_utils.h"
michael@0 12
michael@0 13 #include "mozilla/ArrayUtils.h"
michael@0 14 #include "mozilla/TimeStamp.h"
michael@0 15 #ifdef XP_WIN
michael@0 16 #include "mozilla/TimeStamp_windows.h"
michael@0 17 #endif
michael@0 18 #include "mozilla/TypedEnum.h"
michael@0 19 #include "mozilla/IntegerTypeTraits.h"
michael@0 20
michael@0 21 #include <stdint.h>
michael@0 22
michael@0 23 #include "nsID.h"
michael@0 24 #include "nsMemory.h"
michael@0 25 #include "nsString.h"
michael@0 26 #include "nsTArray.h"
michael@0 27 #include "js/StructuredClone.h"
michael@0 28 #include "nsCSSProperty.h"
michael@0 29
michael@0 30 #ifdef _MSC_VER
michael@0 31 #pragma warning( disable : 4800 )
michael@0 32 #endif
michael@0 33
michael@0 34 #if !defined(OS_POSIX)
michael@0 35 // This condition must be kept in sync with the one in
michael@0 36 // ipc_message_utils.h, but this dummy definition of
michael@0 37 // base::FileDescriptor acts as a static assert that we only get one
michael@0 38 // def or the other (or neither, in which case code using
michael@0 39 // FileDescriptor fails to build)
michael@0 40 namespace base { struct FileDescriptor { }; }
michael@0 41 #endif
michael@0 42
michael@0 43 namespace mozilla {
michael@0 44
michael@0 45 // This is a cross-platform approximation to HANDLE, which we expect
michael@0 46 // to be typedef'd to void* or thereabouts.
michael@0 47 typedef uintptr_t WindowsHandle;
michael@0 48
michael@0 49 // XXX there are out of place and might be generally useful. Could
michael@0 50 // move to nscore.h or something.
michael@0 51 struct void_t {
michael@0 52 bool operator==(const void_t&) const { return true; }
michael@0 53 };
michael@0 54 struct null_t {
michael@0 55 bool operator==(const null_t&) const { return true; }
michael@0 56 };
michael@0 57
michael@0 58 struct SerializedStructuredCloneBuffer
michael@0 59 {
michael@0 60 SerializedStructuredCloneBuffer()
michael@0 61 : data(nullptr), dataLength(0)
michael@0 62 { }
michael@0 63
michael@0 64 SerializedStructuredCloneBuffer(const JSAutoStructuredCloneBuffer& aOther)
michael@0 65 {
michael@0 66 *this = aOther;
michael@0 67 }
michael@0 68
michael@0 69 bool
michael@0 70 operator==(const SerializedStructuredCloneBuffer& aOther) const
michael@0 71 {
michael@0 72 return this->data == aOther.data &&
michael@0 73 this->dataLength == aOther.dataLength;
michael@0 74 }
michael@0 75
michael@0 76 SerializedStructuredCloneBuffer&
michael@0 77 operator=(const JSAutoStructuredCloneBuffer& aOther)
michael@0 78 {
michael@0 79 data = aOther.data();
michael@0 80 dataLength = aOther.nbytes();
michael@0 81 return *this;
michael@0 82 }
michael@0 83
michael@0 84 uint64_t* data;
michael@0 85 size_t dataLength;
michael@0 86 };
michael@0 87
michael@0 88 } // namespace mozilla
michael@0 89
michael@0 90 namespace IPC {
michael@0 91
michael@0 92 /**
michael@0 93 * Generic enum serializer.
michael@0 94 *
michael@0 95 * Consider using the specializations below, such as ContiguousEnumSerializer.
michael@0 96 *
michael@0 97 * This is a generic serializer for any enum type used in IPDL.
michael@0 98 * Programmers can define ParamTraits<E> for enum type E by deriving
michael@0 99 * EnumSerializer<E, MyEnumValidator> where MyEnumValidator is a struct
michael@0 100 * that has to define a static IsLegalValue function returning whether
michael@0 101 * a given value is a legal value of the enum type at hand.
michael@0 102 *
michael@0 103 * \sa https://developer.mozilla.org/en/IPDL/Type_Serialization
michael@0 104 */
michael@0 105 template <typename E, typename EnumValidator>
michael@0 106 struct EnumSerializer {
michael@0 107 typedef E paramType;
michael@0 108 typedef typename mozilla::UnsignedStdintTypeForSize<sizeof(paramType)>::Type
michael@0 109 uintParamType;
michael@0 110
michael@0 111 static void Write(Message* aMsg, const paramType& aValue) {
michael@0 112 MOZ_ASSERT(EnumValidator::IsLegalValue(aValue));
michael@0 113 WriteParam(aMsg, uintParamType(aValue));
michael@0 114 }
michael@0 115
michael@0 116 static bool Read(const Message* aMsg, void** aIter, paramType* aResult) {
michael@0 117 uintParamType value;
michael@0 118 if(!ReadParam(aMsg, aIter, &value) ||
michael@0 119 !EnumValidator::IsLegalValue(paramType(value))) {
michael@0 120 return false;
michael@0 121 }
michael@0 122 *aResult = paramType(value);
michael@0 123 return true;
michael@0 124 }
michael@0 125 };
michael@0 126
michael@0 127 template <typename E,
michael@0 128 E MinLegal,
michael@0 129 E HighBound>
michael@0 130 struct ContiguousEnumValidator
michael@0 131 {
michael@0 132 static bool IsLegalValue(E e)
michael@0 133 {
michael@0 134 return MinLegal <= e && e < HighBound;
michael@0 135 }
michael@0 136 };
michael@0 137
michael@0 138 template <typename E,
michael@0 139 MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) MinLegal,
michael@0 140 MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) HighBound>
michael@0 141 class ContiguousTypedEnumValidator
michael@0 142 {
michael@0 143 // Silence overzealous -Wtype-limits bug in GCC fixed in GCC 4.8:
michael@0 144 // "comparison of unsigned expression >= 0 is always true"
michael@0 145 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11856
michael@0 146 template <typename T>
michael@0 147 static bool IsLessThanOrEqual(T a, T b) { return a <= b; }
michael@0 148
michael@0 149 public:
michael@0 150 static bool IsLegalValue(E e)
michael@0 151 {
michael@0 152 typedef MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) ActualEnumType;
michael@0 153 return IsLessThanOrEqual(MinLegal, ActualEnumType(e)) &&
michael@0 154 ActualEnumType(e) < HighBound;
michael@0 155 }
michael@0 156 };
michael@0 157
michael@0 158 template <typename E,
michael@0 159 E AllBits>
michael@0 160 struct BitFlagsEnumValidator
michael@0 161 {
michael@0 162 static bool IsLegalValue(E e)
michael@0 163 {
michael@0 164 return (e & AllBits) == e;
michael@0 165 }
michael@0 166 };
michael@0 167
michael@0 168 template <typename E,
michael@0 169 MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) AllBits>
michael@0 170 struct BitFlagsTypedEnumValidator
michael@0 171 {
michael@0 172 static bool IsLegalValue(E e)
michael@0 173 {
michael@0 174 return (e & AllBits) == e;
michael@0 175 }
michael@0 176 };
michael@0 177
michael@0 178 /**
michael@0 179 * Specialization of EnumSerializer for enums with contiguous enum values.
michael@0 180 *
michael@0 181 * Provide two values: MinLegal, HighBound. An enum value x will be
michael@0 182 * considered legal if MinLegal <= x < HighBound.
michael@0 183 *
michael@0 184 * For example, following is definition of serializer for enum type FOO.
michael@0 185 * \code
michael@0 186 * enum FOO { FOO_FIRST, FOO_SECOND, FOO_LAST, NUM_FOO };
michael@0 187 *
michael@0 188 * template <>
michael@0 189 * struct ParamTraits<FOO>:
michael@0 190 * public ContiguousEnumSerializer<FOO, FOO_FIRST, NUM_FOO> {};
michael@0 191 * \endcode
michael@0 192 * FOO_FIRST, FOO_SECOND, and FOO_LAST are valid value.
michael@0 193 */
michael@0 194 template <typename E,
michael@0 195 E MinLegal,
michael@0 196 E HighBound>
michael@0 197 struct ContiguousEnumSerializer
michael@0 198 : EnumSerializer<E,
michael@0 199 ContiguousEnumValidator<E, MinLegal, HighBound>>
michael@0 200 {};
michael@0 201
michael@0 202 /**
michael@0 203 * Similar to ContiguousEnumSerializer, but for MFBT typed enums
michael@0 204 * as constructed by MOZ_BEGIN_ENUM_CLASS. This can go away when
michael@0 205 * we drop MOZ_BEGIN_ENUM_CLASS and use C++11 enum classes directly.
michael@0 206 */
michael@0 207 template <typename E,
michael@0 208 MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) MinLegal,
michael@0 209 MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) HighBound>
michael@0 210 struct ContiguousTypedEnumSerializer
michael@0 211 : EnumSerializer<E,
michael@0 212 ContiguousTypedEnumValidator<E, MinLegal, HighBound>>
michael@0 213 {};
michael@0 214
michael@0 215 /**
michael@0 216 * Specialization of EnumSerializer for enums representing bit flags.
michael@0 217 *
michael@0 218 * Provide one value: AllBits. An enum value x will be
michael@0 219 * considered legal if (x & AllBits) == x;
michael@0 220 *
michael@0 221 * Example:
michael@0 222 * \code
michael@0 223 * enum FOO {
michael@0 224 * FOO_FIRST = 1 << 0,
michael@0 225 * FOO_SECOND = 1 << 1,
michael@0 226 * FOO_LAST = 1 << 2,
michael@0 227 * ALL_BITS = (1 << 3) - 1
michael@0 228 * };
michael@0 229 *
michael@0 230 * template <>
michael@0 231 * struct ParamTraits<FOO>:
michael@0 232 * public BitFlagsEnumSerializer<FOO, FOO::ALL_BITS> {};
michael@0 233 * \endcode
michael@0 234 */
michael@0 235 template <typename E,
michael@0 236 E AllBits>
michael@0 237 struct BitFlagsEnumSerializer
michael@0 238 : EnumSerializer<E,
michael@0 239 BitFlagsEnumValidator<E, AllBits>>
michael@0 240 {};
michael@0 241
michael@0 242 /**
michael@0 243 * Similar to BitFlagsEnumSerializer, but for MFBT typed enums
michael@0 244 * as constructed by MOZ_BEGIN_ENUM_CLASS. This can go away when
michael@0 245 * we drop MOZ_BEGIN_ENUM_CLASS and use C++11 enum classes directly.
michael@0 246 */
michael@0 247 template <typename E,
michael@0 248 MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) AllBits>
michael@0 249 struct BitFlagsTypedEnumSerializer
michael@0 250 : EnumSerializer<E,
michael@0 251 BitFlagsTypedEnumValidator<E, AllBits>>
michael@0 252 {};
michael@0 253
michael@0 254 template <>
michael@0 255 struct ParamTraits<base::ChildPrivileges>
michael@0 256 : public ContiguousEnumSerializer<base::ChildPrivileges,
michael@0 257 base::PRIVILEGES_DEFAULT,
michael@0 258 base::PRIVILEGES_LAST>
michael@0 259 { };
michael@0 260
michael@0 261 template<>
michael@0 262 struct ParamTraits<int8_t>
michael@0 263 {
michael@0 264 typedef int8_t paramType;
michael@0 265
michael@0 266 static void Write(Message* aMsg, const paramType& aParam)
michael@0 267 {
michael@0 268 aMsg->WriteBytes(&aParam, sizeof(aParam));
michael@0 269 }
michael@0 270
michael@0 271 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 272 {
michael@0 273 const char* outp;
michael@0 274 if (!aMsg->ReadBytes(aIter, &outp, sizeof(*aResult)))
michael@0 275 return false;
michael@0 276
michael@0 277 *aResult = *reinterpret_cast<const paramType*>(outp);
michael@0 278 return true;
michael@0 279 }
michael@0 280 };
michael@0 281
michael@0 282 template<>
michael@0 283 struct ParamTraits<uint8_t>
michael@0 284 {
michael@0 285 typedef uint8_t paramType;
michael@0 286
michael@0 287 static void Write(Message* aMsg, const paramType& aParam)
michael@0 288 {
michael@0 289 aMsg->WriteBytes(&aParam, sizeof(aParam));
michael@0 290 }
michael@0 291
michael@0 292 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 293 {
michael@0 294 const char* outp;
michael@0 295 if (!aMsg->ReadBytes(aIter, &outp, sizeof(*aResult)))
michael@0 296 return false;
michael@0 297
michael@0 298 *aResult = *reinterpret_cast<const paramType*>(outp);
michael@0 299 return true;
michael@0 300 }
michael@0 301 };
michael@0 302
michael@0 303 #if !defined(OS_POSIX)
michael@0 304 // See above re: keeping definitions in sync
michael@0 305 template<>
michael@0 306 struct ParamTraits<base::FileDescriptor>
michael@0 307 {
michael@0 308 typedef base::FileDescriptor paramType;
michael@0 309 static void Write(Message* aMsg, const paramType& aParam) {
michael@0 310 NS_RUNTIMEABORT("FileDescriptor isn't meaningful on this platform");
michael@0 311 }
michael@0 312 static bool Read(const Message* aMsg, void** aIter, paramType* aResult) {
michael@0 313 NS_RUNTIMEABORT("FileDescriptor isn't meaningful on this platform");
michael@0 314 return false;
michael@0 315 }
michael@0 316 };
michael@0 317 #endif // !defined(OS_POSIX)
michael@0 318
michael@0 319 template <>
michael@0 320 struct ParamTraits<nsACString>
michael@0 321 {
michael@0 322 typedef nsACString paramType;
michael@0 323
michael@0 324 static void Write(Message* aMsg, const paramType& aParam)
michael@0 325 {
michael@0 326 bool isVoid = aParam.IsVoid();
michael@0 327 aMsg->WriteBool(isVoid);
michael@0 328
michael@0 329 if (isVoid)
michael@0 330 // represents a nullptr pointer
michael@0 331 return;
michael@0 332
michael@0 333 uint32_t length = aParam.Length();
michael@0 334 WriteParam(aMsg, length);
michael@0 335 aMsg->WriteBytes(aParam.BeginReading(), length);
michael@0 336 }
michael@0 337
michael@0 338 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 339 {
michael@0 340 bool isVoid;
michael@0 341 if (!aMsg->ReadBool(aIter, &isVoid))
michael@0 342 return false;
michael@0 343
michael@0 344 if (isVoid) {
michael@0 345 aResult->SetIsVoid(true);
michael@0 346 return true;
michael@0 347 }
michael@0 348
michael@0 349 uint32_t length;
michael@0 350 if (ReadParam(aMsg, aIter, &length)) {
michael@0 351 const char* buf;
michael@0 352 if (aMsg->ReadBytes(aIter, &buf, length)) {
michael@0 353 aResult->Assign(buf, length);
michael@0 354 return true;
michael@0 355 }
michael@0 356 }
michael@0 357 return false;
michael@0 358 }
michael@0 359
michael@0 360 static void Log(const paramType& aParam, std::wstring* aLog)
michael@0 361 {
michael@0 362 if (aParam.IsVoid())
michael@0 363 aLog->append(L"(NULL)");
michael@0 364 else
michael@0 365 aLog->append(UTF8ToWide(aParam.BeginReading()));
michael@0 366 }
michael@0 367 };
michael@0 368
michael@0 369 template <>
michael@0 370 struct ParamTraits<nsAString>
michael@0 371 {
michael@0 372 typedef nsAString paramType;
michael@0 373
michael@0 374 static void Write(Message* aMsg, const paramType& aParam)
michael@0 375 {
michael@0 376 bool isVoid = aParam.IsVoid();
michael@0 377 aMsg->WriteBool(isVoid);
michael@0 378
michael@0 379 if (isVoid)
michael@0 380 // represents a nullptr pointer
michael@0 381 return;
michael@0 382
michael@0 383 uint32_t length = aParam.Length();
michael@0 384 WriteParam(aMsg, length);
michael@0 385 aMsg->WriteBytes(aParam.BeginReading(), length * sizeof(char16_t));
michael@0 386 }
michael@0 387
michael@0 388 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 389 {
michael@0 390 bool isVoid;
michael@0 391 if (!aMsg->ReadBool(aIter, &isVoid))
michael@0 392 return false;
michael@0 393
michael@0 394 if (isVoid) {
michael@0 395 aResult->SetIsVoid(true);
michael@0 396 return true;
michael@0 397 }
michael@0 398
michael@0 399 uint32_t length;
michael@0 400 if (ReadParam(aMsg, aIter, &length)) {
michael@0 401 const char16_t* buf;
michael@0 402 if (aMsg->ReadBytes(aIter, reinterpret_cast<const char**>(&buf),
michael@0 403 length * sizeof(char16_t))) {
michael@0 404 aResult->Assign(buf, length);
michael@0 405 return true;
michael@0 406 }
michael@0 407 }
michael@0 408 return false;
michael@0 409 }
michael@0 410
michael@0 411 static void Log(const paramType& aParam, std::wstring* aLog)
michael@0 412 {
michael@0 413 if (aParam.IsVoid())
michael@0 414 aLog->append(L"(NULL)");
michael@0 415 else {
michael@0 416 #ifdef WCHAR_T_IS_UTF16
michael@0 417 aLog->append(reinterpret_cast<const wchar_t*>(aParam.BeginReading()));
michael@0 418 #else
michael@0 419 uint32_t length = aParam.Length();
michael@0 420 for (uint32_t index = 0; index < length; index++) {
michael@0 421 aLog->push_back(std::wstring::value_type(aParam[index]));
michael@0 422 }
michael@0 423 #endif
michael@0 424 }
michael@0 425 }
michael@0 426 };
michael@0 427
michael@0 428 template <>
michael@0 429 struct ParamTraits<nsCString> : ParamTraits<nsACString>
michael@0 430 {
michael@0 431 typedef nsCString paramType;
michael@0 432 };
michael@0 433
michael@0 434 template <>
michael@0 435 struct ParamTraits<nsLiteralCString> : ParamTraits<nsACString>
michael@0 436 {
michael@0 437 typedef nsLiteralCString paramType;
michael@0 438 };
michael@0 439
michael@0 440 #ifdef MOZILLA_INTERNAL_API
michael@0 441
michael@0 442 template<>
michael@0 443 struct ParamTraits<nsAutoCString> : ParamTraits<nsCString>
michael@0 444 {
michael@0 445 typedef nsAutoCString paramType;
michael@0 446 };
michael@0 447
michael@0 448 #endif // MOZILLA_INTERNAL_API
michael@0 449
michael@0 450 template <>
michael@0 451 struct ParamTraits<nsString> : ParamTraits<nsAString>
michael@0 452 {
michael@0 453 typedef nsString paramType;
michael@0 454 };
michael@0 455
michael@0 456 template <>
michael@0 457 struct ParamTraits<nsLiteralString> : ParamTraits<nsAString>
michael@0 458 {
michael@0 459 typedef nsLiteralString paramType;
michael@0 460 };
michael@0 461
michael@0 462 template <typename E>
michael@0 463 struct ParamTraits<FallibleTArray<E> >
michael@0 464 {
michael@0 465 typedef FallibleTArray<E> paramType;
michael@0 466
michael@0 467 static void Write(Message* aMsg, const paramType& aParam)
michael@0 468 {
michael@0 469 uint32_t length = aParam.Length();
michael@0 470 WriteParam(aMsg, length);
michael@0 471 for (uint32_t index = 0; index < length; index++) {
michael@0 472 WriteParam(aMsg, aParam[index]);
michael@0 473 }
michael@0 474 }
michael@0 475
michael@0 476 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 477 {
michael@0 478 uint32_t length;
michael@0 479 if (!ReadParam(aMsg, aIter, &length)) {
michael@0 480 return false;
michael@0 481 }
michael@0 482
michael@0 483 aResult->SetCapacity(length);
michael@0 484 for (uint32_t index = 0; index < length; index++) {
michael@0 485 E* element = aResult->AppendElement();
michael@0 486 if (!(element && ReadParam(aMsg, aIter, element))) {
michael@0 487 return false;
michael@0 488 }
michael@0 489 }
michael@0 490
michael@0 491 return true;
michael@0 492 }
michael@0 493
michael@0 494 static void Log(const paramType& aParam, std::wstring* aLog)
michael@0 495 {
michael@0 496 for (uint32_t index = 0; index < aParam.Length(); index++) {
michael@0 497 if (index) {
michael@0 498 aLog->append(L" ");
michael@0 499 }
michael@0 500 LogParam(aParam[index], aLog);
michael@0 501 }
michael@0 502 }
michael@0 503 };
michael@0 504
michael@0 505 template<typename E>
michael@0 506 struct ParamTraits<InfallibleTArray<E> >
michael@0 507 {
michael@0 508 typedef InfallibleTArray<E> paramType;
michael@0 509
michael@0 510 static void Write(Message* aMsg, const paramType& aParam)
michael@0 511 {
michael@0 512 WriteParam(aMsg, static_cast<const FallibleTArray<E>&>(aParam));
michael@0 513 }
michael@0 514
michael@0 515 // deserialize the array fallibly, but return an InfallibleTArray
michael@0 516 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 517 {
michael@0 518 FallibleTArray<E> temp;
michael@0 519 if (!ReadParam(aMsg, aIter, &temp))
michael@0 520 return false;
michael@0 521
michael@0 522 aResult->SwapElements(temp);
michael@0 523 return true;
michael@0 524 }
michael@0 525
michael@0 526 static void Log(const paramType& aParam, std::wstring* aLog)
michael@0 527 {
michael@0 528 LogParam(static_cast<const FallibleTArray<E>&>(aParam), aLog);
michael@0 529 }
michael@0 530 };
michael@0 531
michael@0 532 template<>
michael@0 533 struct ParamTraits<float>
michael@0 534 {
michael@0 535 typedef float paramType;
michael@0 536
michael@0 537 static void Write(Message* aMsg, const paramType& aParam)
michael@0 538 {
michael@0 539 aMsg->WriteBytes(&aParam, sizeof(paramType));
michael@0 540 }
michael@0 541
michael@0 542 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 543 {
michael@0 544 const char* outFloat;
michael@0 545 if (!aMsg->ReadBytes(aIter, &outFloat, sizeof(float)))
michael@0 546 return false;
michael@0 547 *aResult = *reinterpret_cast<const float*>(outFloat);
michael@0 548 return true;
michael@0 549 }
michael@0 550
michael@0 551 static void Log(const paramType& aParam, std::wstring* aLog)
michael@0 552 {
michael@0 553 aLog->append(StringPrintf(L"%g", aParam));
michael@0 554 }
michael@0 555 };
michael@0 556
michael@0 557 template <>
michael@0 558 struct ParamTraits<nsCSSProperty>
michael@0 559 : public ContiguousEnumSerializer<nsCSSProperty,
michael@0 560 eCSSProperty_UNKNOWN,
michael@0 561 eCSSProperty_COUNT>
michael@0 562 {};
michael@0 563
michael@0 564 template<>
michael@0 565 struct ParamTraits<mozilla::void_t>
michael@0 566 {
michael@0 567 typedef mozilla::void_t paramType;
michael@0 568 static void Write(Message* aMsg, const paramType& aParam) { }
michael@0 569 static bool
michael@0 570 Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 571 {
michael@0 572 *aResult = paramType();
michael@0 573 return true;
michael@0 574 }
michael@0 575 };
michael@0 576
michael@0 577 template<>
michael@0 578 struct ParamTraits<mozilla::null_t>
michael@0 579 {
michael@0 580 typedef mozilla::null_t paramType;
michael@0 581 static void Write(Message* aMsg, const paramType& aParam) { }
michael@0 582 static bool
michael@0 583 Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 584 {
michael@0 585 *aResult = paramType();
michael@0 586 return true;
michael@0 587 }
michael@0 588 };
michael@0 589
michael@0 590 template<>
michael@0 591 struct ParamTraits<nsID>
michael@0 592 {
michael@0 593 typedef nsID paramType;
michael@0 594
michael@0 595 static void Write(Message* aMsg, const paramType& aParam)
michael@0 596 {
michael@0 597 WriteParam(aMsg, aParam.m0);
michael@0 598 WriteParam(aMsg, aParam.m1);
michael@0 599 WriteParam(aMsg, aParam.m2);
michael@0 600 for (unsigned int i = 0; i < mozilla::ArrayLength(aParam.m3); i++) {
michael@0 601 WriteParam(aMsg, aParam.m3[i]);
michael@0 602 }
michael@0 603 }
michael@0 604
michael@0 605 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 606 {
michael@0 607 if(!ReadParam(aMsg, aIter, &(aResult->m0)) ||
michael@0 608 !ReadParam(aMsg, aIter, &(aResult->m1)) ||
michael@0 609 !ReadParam(aMsg, aIter, &(aResult->m2)))
michael@0 610 return false;
michael@0 611
michael@0 612 for (unsigned int i = 0; i < mozilla::ArrayLength(aResult->m3); i++)
michael@0 613 if (!ReadParam(aMsg, aIter, &(aResult->m3[i])))
michael@0 614 return false;
michael@0 615
michael@0 616 return true;
michael@0 617 }
michael@0 618
michael@0 619 static void Log(const paramType& aParam, std::wstring* aLog)
michael@0 620 {
michael@0 621 aLog->append(L"{");
michael@0 622 aLog->append(StringPrintf(L"%8.8X-%4.4X-%4.4X-",
michael@0 623 aParam.m0,
michael@0 624 aParam.m1,
michael@0 625 aParam.m2));
michael@0 626 for (unsigned int i = 0; i < mozilla::ArrayLength(aParam.m3); i++)
michael@0 627 aLog->append(StringPrintf(L"%2.2X", aParam.m3[i]));
michael@0 628 aLog->append(L"}");
michael@0 629 }
michael@0 630 };
michael@0 631
michael@0 632 template<>
michael@0 633 struct ParamTraits<mozilla::TimeDuration>
michael@0 634 {
michael@0 635 typedef mozilla::TimeDuration paramType;
michael@0 636 static void Write(Message* aMsg, const paramType& aParam)
michael@0 637 {
michael@0 638 WriteParam(aMsg, aParam.mValue);
michael@0 639 }
michael@0 640 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 641 {
michael@0 642 return ReadParam(aMsg, aIter, &aResult->mValue);
michael@0 643 };
michael@0 644 };
michael@0 645
michael@0 646 template<>
michael@0 647 struct ParamTraits<mozilla::TimeStamp>
michael@0 648 {
michael@0 649 typedef mozilla::TimeStamp paramType;
michael@0 650 static void Write(Message* aMsg, const paramType& aParam)
michael@0 651 {
michael@0 652 WriteParam(aMsg, aParam.mValue);
michael@0 653 }
michael@0 654 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 655 {
michael@0 656 return ReadParam(aMsg, aIter, &aResult->mValue);
michael@0 657 };
michael@0 658 };
michael@0 659
michael@0 660 #ifdef XP_WIN
michael@0 661
michael@0 662 template<>
michael@0 663 struct ParamTraits<mozilla::TimeStampValue>
michael@0 664 {
michael@0 665 typedef mozilla::TimeStampValue paramType;
michael@0 666 static void Write(Message* aMsg, const paramType& aParam)
michael@0 667 {
michael@0 668 WriteParam(aMsg, aParam.mGTC);
michael@0 669 WriteParam(aMsg, aParam.mQPC);
michael@0 670 WriteParam(aMsg, aParam.mHasQPC);
michael@0 671 WriteParam(aMsg, aParam.mIsNull);
michael@0 672 }
michael@0 673 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 674 {
michael@0 675 return (ReadParam(aMsg, aIter, &aResult->mGTC) &&
michael@0 676 ReadParam(aMsg, aIter, &aResult->mQPC) &&
michael@0 677 ReadParam(aMsg, aIter, &aResult->mHasQPC) &&
michael@0 678 ReadParam(aMsg, aIter, &aResult->mIsNull));
michael@0 679 }
michael@0 680 };
michael@0 681
michael@0 682 #endif
michael@0 683
michael@0 684 template <>
michael@0 685 struct ParamTraits<mozilla::SerializedStructuredCloneBuffer>
michael@0 686 {
michael@0 687 typedef mozilla::SerializedStructuredCloneBuffer paramType;
michael@0 688
michael@0 689 static void Write(Message* aMsg, const paramType& aParam)
michael@0 690 {
michael@0 691 WriteParam(aMsg, aParam.dataLength);
michael@0 692 if (aParam.dataLength) {
michael@0 693 // Structured clone data must be 64-bit aligned.
michael@0 694 aMsg->WriteBytes(aParam.data, aParam.dataLength, sizeof(uint64_t));
michael@0 695 }
michael@0 696 }
michael@0 697
michael@0 698 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 699 {
michael@0 700 if (!ReadParam(aMsg, aIter, &aResult->dataLength)) {
michael@0 701 return false;
michael@0 702 }
michael@0 703
michael@0 704 if (aResult->dataLength) {
michael@0 705 const char** buffer =
michael@0 706 const_cast<const char**>(reinterpret_cast<char**>(&aResult->data));
michael@0 707 // Structured clone data must be 64-bit aligned.
michael@0 708 if (!aMsg->ReadBytes(aIter, buffer, aResult->dataLength,
michael@0 709 sizeof(uint64_t))) {
michael@0 710 return false;
michael@0 711 }
michael@0 712 } else {
michael@0 713 aResult->data = nullptr;
michael@0 714 }
michael@0 715
michael@0 716 return true;
michael@0 717 }
michael@0 718
michael@0 719 static void Log(const paramType& aParam, std::wstring* aLog)
michael@0 720 {
michael@0 721 LogParam(aParam.dataLength, aLog);
michael@0 722 }
michael@0 723 };
michael@0 724
michael@0 725 } /* namespace IPC */
michael@0 726
michael@0 727 #endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */

mercurial