1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/glue/IPCMessageUtils.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,727 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set sw=2 ts=8 et tw=80 : */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef __IPC_GLUE_IPCMESSAGEUTILS_H__ 1.11 +#define __IPC_GLUE_IPCMESSAGEUTILS_H__ 1.12 + 1.13 +#include "base/process_util.h" 1.14 +#include "chrome/common/ipc_message_utils.h" 1.15 + 1.16 +#include "mozilla/ArrayUtils.h" 1.17 +#include "mozilla/TimeStamp.h" 1.18 +#ifdef XP_WIN 1.19 +#include "mozilla/TimeStamp_windows.h" 1.20 +#endif 1.21 +#include "mozilla/TypedEnum.h" 1.22 +#include "mozilla/IntegerTypeTraits.h" 1.23 + 1.24 +#include <stdint.h> 1.25 + 1.26 +#include "nsID.h" 1.27 +#include "nsMemory.h" 1.28 +#include "nsString.h" 1.29 +#include "nsTArray.h" 1.30 +#include "js/StructuredClone.h" 1.31 +#include "nsCSSProperty.h" 1.32 + 1.33 +#ifdef _MSC_VER 1.34 +#pragma warning( disable : 4800 ) 1.35 +#endif 1.36 + 1.37 +#if !defined(OS_POSIX) 1.38 +// This condition must be kept in sync with the one in 1.39 +// ipc_message_utils.h, but this dummy definition of 1.40 +// base::FileDescriptor acts as a static assert that we only get one 1.41 +// def or the other (or neither, in which case code using 1.42 +// FileDescriptor fails to build) 1.43 +namespace base { struct FileDescriptor { }; } 1.44 +#endif 1.45 + 1.46 +namespace mozilla { 1.47 + 1.48 +// This is a cross-platform approximation to HANDLE, which we expect 1.49 +// to be typedef'd to void* or thereabouts. 1.50 +typedef uintptr_t WindowsHandle; 1.51 + 1.52 +// XXX there are out of place and might be generally useful. Could 1.53 +// move to nscore.h or something. 1.54 +struct void_t { 1.55 + bool operator==(const void_t&) const { return true; } 1.56 +}; 1.57 +struct null_t { 1.58 + bool operator==(const null_t&) const { return true; } 1.59 +}; 1.60 + 1.61 +struct SerializedStructuredCloneBuffer 1.62 +{ 1.63 + SerializedStructuredCloneBuffer() 1.64 + : data(nullptr), dataLength(0) 1.65 + { } 1.66 + 1.67 + SerializedStructuredCloneBuffer(const JSAutoStructuredCloneBuffer& aOther) 1.68 + { 1.69 + *this = aOther; 1.70 + } 1.71 + 1.72 + bool 1.73 + operator==(const SerializedStructuredCloneBuffer& aOther) const 1.74 + { 1.75 + return this->data == aOther.data && 1.76 + this->dataLength == aOther.dataLength; 1.77 + } 1.78 + 1.79 + SerializedStructuredCloneBuffer& 1.80 + operator=(const JSAutoStructuredCloneBuffer& aOther) 1.81 + { 1.82 + data = aOther.data(); 1.83 + dataLength = aOther.nbytes(); 1.84 + return *this; 1.85 + } 1.86 + 1.87 + uint64_t* data; 1.88 + size_t dataLength; 1.89 +}; 1.90 + 1.91 +} // namespace mozilla 1.92 + 1.93 +namespace IPC { 1.94 + 1.95 +/** 1.96 + * Generic enum serializer. 1.97 + * 1.98 + * Consider using the specializations below, such as ContiguousEnumSerializer. 1.99 + * 1.100 + * This is a generic serializer for any enum type used in IPDL. 1.101 + * Programmers can define ParamTraits<E> for enum type E by deriving 1.102 + * EnumSerializer<E, MyEnumValidator> where MyEnumValidator is a struct 1.103 + * that has to define a static IsLegalValue function returning whether 1.104 + * a given value is a legal value of the enum type at hand. 1.105 + * 1.106 + * \sa https://developer.mozilla.org/en/IPDL/Type_Serialization 1.107 + */ 1.108 +template <typename E, typename EnumValidator> 1.109 +struct EnumSerializer { 1.110 + typedef E paramType; 1.111 + typedef typename mozilla::UnsignedStdintTypeForSize<sizeof(paramType)>::Type 1.112 + uintParamType; 1.113 + 1.114 + static void Write(Message* aMsg, const paramType& aValue) { 1.115 + MOZ_ASSERT(EnumValidator::IsLegalValue(aValue)); 1.116 + WriteParam(aMsg, uintParamType(aValue)); 1.117 + } 1.118 + 1.119 + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) { 1.120 + uintParamType value; 1.121 + if(!ReadParam(aMsg, aIter, &value) || 1.122 + !EnumValidator::IsLegalValue(paramType(value))) { 1.123 + return false; 1.124 + } 1.125 + *aResult = paramType(value); 1.126 + return true; 1.127 + } 1.128 +}; 1.129 + 1.130 +template <typename E, 1.131 + E MinLegal, 1.132 + E HighBound> 1.133 +struct ContiguousEnumValidator 1.134 +{ 1.135 + static bool IsLegalValue(E e) 1.136 + { 1.137 + return MinLegal <= e && e < HighBound; 1.138 + } 1.139 +}; 1.140 + 1.141 +template <typename E, 1.142 + MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) MinLegal, 1.143 + MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) HighBound> 1.144 +class ContiguousTypedEnumValidator 1.145 +{ 1.146 + // Silence overzealous -Wtype-limits bug in GCC fixed in GCC 4.8: 1.147 + // "comparison of unsigned expression >= 0 is always true" 1.148 + // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11856 1.149 + template <typename T> 1.150 + static bool IsLessThanOrEqual(T a, T b) { return a <= b; } 1.151 + 1.152 +public: 1.153 + static bool IsLegalValue(E e) 1.154 + { 1.155 + typedef MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) ActualEnumType; 1.156 + return IsLessThanOrEqual(MinLegal, ActualEnumType(e)) && 1.157 + ActualEnumType(e) < HighBound; 1.158 + } 1.159 +}; 1.160 + 1.161 +template <typename E, 1.162 + E AllBits> 1.163 +struct BitFlagsEnumValidator 1.164 +{ 1.165 + static bool IsLegalValue(E e) 1.166 + { 1.167 + return (e & AllBits) == e; 1.168 + } 1.169 +}; 1.170 + 1.171 +template <typename E, 1.172 + MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) AllBits> 1.173 +struct BitFlagsTypedEnumValidator 1.174 +{ 1.175 + static bool IsLegalValue(E e) 1.176 + { 1.177 + return (e & AllBits) == e; 1.178 + } 1.179 +}; 1.180 + 1.181 +/** 1.182 + * Specialization of EnumSerializer for enums with contiguous enum values. 1.183 + * 1.184 + * Provide two values: MinLegal, HighBound. An enum value x will be 1.185 + * considered legal if MinLegal <= x < HighBound. 1.186 + * 1.187 + * For example, following is definition of serializer for enum type FOO. 1.188 + * \code 1.189 + * enum FOO { FOO_FIRST, FOO_SECOND, FOO_LAST, NUM_FOO }; 1.190 + * 1.191 + * template <> 1.192 + * struct ParamTraits<FOO>: 1.193 + * public ContiguousEnumSerializer<FOO, FOO_FIRST, NUM_FOO> {}; 1.194 + * \endcode 1.195 + * FOO_FIRST, FOO_SECOND, and FOO_LAST are valid value. 1.196 + */ 1.197 +template <typename E, 1.198 + E MinLegal, 1.199 + E HighBound> 1.200 +struct ContiguousEnumSerializer 1.201 + : EnumSerializer<E, 1.202 + ContiguousEnumValidator<E, MinLegal, HighBound>> 1.203 +{}; 1.204 + 1.205 +/** 1.206 + * Similar to ContiguousEnumSerializer, but for MFBT typed enums 1.207 + * as constructed by MOZ_BEGIN_ENUM_CLASS. This can go away when 1.208 + * we drop MOZ_BEGIN_ENUM_CLASS and use C++11 enum classes directly. 1.209 + */ 1.210 +template <typename E, 1.211 + MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) MinLegal, 1.212 + MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) HighBound> 1.213 +struct ContiguousTypedEnumSerializer 1.214 + : EnumSerializer<E, 1.215 + ContiguousTypedEnumValidator<E, MinLegal, HighBound>> 1.216 +{}; 1.217 + 1.218 +/** 1.219 + * Specialization of EnumSerializer for enums representing bit flags. 1.220 + * 1.221 + * Provide one value: AllBits. An enum value x will be 1.222 + * considered legal if (x & AllBits) == x; 1.223 + * 1.224 + * Example: 1.225 + * \code 1.226 + * enum FOO { 1.227 + * FOO_FIRST = 1 << 0, 1.228 + * FOO_SECOND = 1 << 1, 1.229 + * FOO_LAST = 1 << 2, 1.230 + * ALL_BITS = (1 << 3) - 1 1.231 + * }; 1.232 + * 1.233 + * template <> 1.234 + * struct ParamTraits<FOO>: 1.235 + * public BitFlagsEnumSerializer<FOO, FOO::ALL_BITS> {}; 1.236 + * \endcode 1.237 + */ 1.238 +template <typename E, 1.239 + E AllBits> 1.240 +struct BitFlagsEnumSerializer 1.241 + : EnumSerializer<E, 1.242 + BitFlagsEnumValidator<E, AllBits>> 1.243 +{}; 1.244 + 1.245 +/** 1.246 + * Similar to BitFlagsEnumSerializer, but for MFBT typed enums 1.247 + * as constructed by MOZ_BEGIN_ENUM_CLASS. This can go away when 1.248 + * we drop MOZ_BEGIN_ENUM_CLASS and use C++11 enum classes directly. 1.249 + */ 1.250 +template <typename E, 1.251 + MOZ_TEMPLATE_ENUM_CLASS_ENUM_TYPE(E) AllBits> 1.252 +struct BitFlagsTypedEnumSerializer 1.253 + : EnumSerializer<E, 1.254 + BitFlagsTypedEnumValidator<E, AllBits>> 1.255 +{}; 1.256 + 1.257 +template <> 1.258 +struct ParamTraits<base::ChildPrivileges> 1.259 + : public ContiguousEnumSerializer<base::ChildPrivileges, 1.260 + base::PRIVILEGES_DEFAULT, 1.261 + base::PRIVILEGES_LAST> 1.262 +{ }; 1.263 + 1.264 +template<> 1.265 +struct ParamTraits<int8_t> 1.266 +{ 1.267 + typedef int8_t paramType; 1.268 + 1.269 + static void Write(Message* aMsg, const paramType& aParam) 1.270 + { 1.271 + aMsg->WriteBytes(&aParam, sizeof(aParam)); 1.272 + } 1.273 + 1.274 + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) 1.275 + { 1.276 + const char* outp; 1.277 + if (!aMsg->ReadBytes(aIter, &outp, sizeof(*aResult))) 1.278 + return false; 1.279 + 1.280 + *aResult = *reinterpret_cast<const paramType*>(outp); 1.281 + return true; 1.282 + } 1.283 +}; 1.284 + 1.285 +template<> 1.286 +struct ParamTraits<uint8_t> 1.287 +{ 1.288 + typedef uint8_t paramType; 1.289 + 1.290 + static void Write(Message* aMsg, const paramType& aParam) 1.291 + { 1.292 + aMsg->WriteBytes(&aParam, sizeof(aParam)); 1.293 + } 1.294 + 1.295 + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) 1.296 + { 1.297 + const char* outp; 1.298 + if (!aMsg->ReadBytes(aIter, &outp, sizeof(*aResult))) 1.299 + return false; 1.300 + 1.301 + *aResult = *reinterpret_cast<const paramType*>(outp); 1.302 + return true; 1.303 + } 1.304 +}; 1.305 + 1.306 +#if !defined(OS_POSIX) 1.307 +// See above re: keeping definitions in sync 1.308 +template<> 1.309 +struct ParamTraits<base::FileDescriptor> 1.310 +{ 1.311 + typedef base::FileDescriptor paramType; 1.312 + static void Write(Message* aMsg, const paramType& aParam) { 1.313 + NS_RUNTIMEABORT("FileDescriptor isn't meaningful on this platform"); 1.314 + } 1.315 + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) { 1.316 + NS_RUNTIMEABORT("FileDescriptor isn't meaningful on this platform"); 1.317 + return false; 1.318 + } 1.319 +}; 1.320 +#endif // !defined(OS_POSIX) 1.321 + 1.322 +template <> 1.323 +struct ParamTraits<nsACString> 1.324 +{ 1.325 + typedef nsACString paramType; 1.326 + 1.327 + static void Write(Message* aMsg, const paramType& aParam) 1.328 + { 1.329 + bool isVoid = aParam.IsVoid(); 1.330 + aMsg->WriteBool(isVoid); 1.331 + 1.332 + if (isVoid) 1.333 + // represents a nullptr pointer 1.334 + return; 1.335 + 1.336 + uint32_t length = aParam.Length(); 1.337 + WriteParam(aMsg, length); 1.338 + aMsg->WriteBytes(aParam.BeginReading(), length); 1.339 + } 1.340 + 1.341 + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) 1.342 + { 1.343 + bool isVoid; 1.344 + if (!aMsg->ReadBool(aIter, &isVoid)) 1.345 + return false; 1.346 + 1.347 + if (isVoid) { 1.348 + aResult->SetIsVoid(true); 1.349 + return true; 1.350 + } 1.351 + 1.352 + uint32_t length; 1.353 + if (ReadParam(aMsg, aIter, &length)) { 1.354 + const char* buf; 1.355 + if (aMsg->ReadBytes(aIter, &buf, length)) { 1.356 + aResult->Assign(buf, length); 1.357 + return true; 1.358 + } 1.359 + } 1.360 + return false; 1.361 + } 1.362 + 1.363 + static void Log(const paramType& aParam, std::wstring* aLog) 1.364 + { 1.365 + if (aParam.IsVoid()) 1.366 + aLog->append(L"(NULL)"); 1.367 + else 1.368 + aLog->append(UTF8ToWide(aParam.BeginReading())); 1.369 + } 1.370 +}; 1.371 + 1.372 +template <> 1.373 +struct ParamTraits<nsAString> 1.374 +{ 1.375 + typedef nsAString paramType; 1.376 + 1.377 + static void Write(Message* aMsg, const paramType& aParam) 1.378 + { 1.379 + bool isVoid = aParam.IsVoid(); 1.380 + aMsg->WriteBool(isVoid); 1.381 + 1.382 + if (isVoid) 1.383 + // represents a nullptr pointer 1.384 + return; 1.385 + 1.386 + uint32_t length = aParam.Length(); 1.387 + WriteParam(aMsg, length); 1.388 + aMsg->WriteBytes(aParam.BeginReading(), length * sizeof(char16_t)); 1.389 + } 1.390 + 1.391 + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) 1.392 + { 1.393 + bool isVoid; 1.394 + if (!aMsg->ReadBool(aIter, &isVoid)) 1.395 + return false; 1.396 + 1.397 + if (isVoid) { 1.398 + aResult->SetIsVoid(true); 1.399 + return true; 1.400 + } 1.401 + 1.402 + uint32_t length; 1.403 + if (ReadParam(aMsg, aIter, &length)) { 1.404 + const char16_t* buf; 1.405 + if (aMsg->ReadBytes(aIter, reinterpret_cast<const char**>(&buf), 1.406 + length * sizeof(char16_t))) { 1.407 + aResult->Assign(buf, length); 1.408 + return true; 1.409 + } 1.410 + } 1.411 + return false; 1.412 + } 1.413 + 1.414 + static void Log(const paramType& aParam, std::wstring* aLog) 1.415 + { 1.416 + if (aParam.IsVoid()) 1.417 + aLog->append(L"(NULL)"); 1.418 + else { 1.419 +#ifdef WCHAR_T_IS_UTF16 1.420 + aLog->append(reinterpret_cast<const wchar_t*>(aParam.BeginReading())); 1.421 +#else 1.422 + uint32_t length = aParam.Length(); 1.423 + for (uint32_t index = 0; index < length; index++) { 1.424 + aLog->push_back(std::wstring::value_type(aParam[index])); 1.425 + } 1.426 +#endif 1.427 + } 1.428 + } 1.429 +}; 1.430 + 1.431 +template <> 1.432 +struct ParamTraits<nsCString> : ParamTraits<nsACString> 1.433 +{ 1.434 + typedef nsCString paramType; 1.435 +}; 1.436 + 1.437 +template <> 1.438 +struct ParamTraits<nsLiteralCString> : ParamTraits<nsACString> 1.439 +{ 1.440 + typedef nsLiteralCString paramType; 1.441 +}; 1.442 + 1.443 +#ifdef MOZILLA_INTERNAL_API 1.444 + 1.445 +template<> 1.446 +struct ParamTraits<nsAutoCString> : ParamTraits<nsCString> 1.447 +{ 1.448 + typedef nsAutoCString paramType; 1.449 +}; 1.450 + 1.451 +#endif // MOZILLA_INTERNAL_API 1.452 + 1.453 +template <> 1.454 +struct ParamTraits<nsString> : ParamTraits<nsAString> 1.455 +{ 1.456 + typedef nsString paramType; 1.457 +}; 1.458 + 1.459 +template <> 1.460 +struct ParamTraits<nsLiteralString> : ParamTraits<nsAString> 1.461 +{ 1.462 + typedef nsLiteralString paramType; 1.463 +}; 1.464 + 1.465 +template <typename E> 1.466 +struct ParamTraits<FallibleTArray<E> > 1.467 +{ 1.468 + typedef FallibleTArray<E> paramType; 1.469 + 1.470 + static void Write(Message* aMsg, const paramType& aParam) 1.471 + { 1.472 + uint32_t length = aParam.Length(); 1.473 + WriteParam(aMsg, length); 1.474 + for (uint32_t index = 0; index < length; index++) { 1.475 + WriteParam(aMsg, aParam[index]); 1.476 + } 1.477 + } 1.478 + 1.479 + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) 1.480 + { 1.481 + uint32_t length; 1.482 + if (!ReadParam(aMsg, aIter, &length)) { 1.483 + return false; 1.484 + } 1.485 + 1.486 + aResult->SetCapacity(length); 1.487 + for (uint32_t index = 0; index < length; index++) { 1.488 + E* element = aResult->AppendElement(); 1.489 + if (!(element && ReadParam(aMsg, aIter, element))) { 1.490 + return false; 1.491 + } 1.492 + } 1.493 + 1.494 + return true; 1.495 + } 1.496 + 1.497 + static void Log(const paramType& aParam, std::wstring* aLog) 1.498 + { 1.499 + for (uint32_t index = 0; index < aParam.Length(); index++) { 1.500 + if (index) { 1.501 + aLog->append(L" "); 1.502 + } 1.503 + LogParam(aParam[index], aLog); 1.504 + } 1.505 + } 1.506 +}; 1.507 + 1.508 +template<typename E> 1.509 +struct ParamTraits<InfallibleTArray<E> > 1.510 +{ 1.511 + typedef InfallibleTArray<E> paramType; 1.512 + 1.513 + static void Write(Message* aMsg, const paramType& aParam) 1.514 + { 1.515 + WriteParam(aMsg, static_cast<const FallibleTArray<E>&>(aParam)); 1.516 + } 1.517 + 1.518 + // deserialize the array fallibly, but return an InfallibleTArray 1.519 + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) 1.520 + { 1.521 + FallibleTArray<E> temp; 1.522 + if (!ReadParam(aMsg, aIter, &temp)) 1.523 + return false; 1.524 + 1.525 + aResult->SwapElements(temp); 1.526 + return true; 1.527 + } 1.528 + 1.529 + static void Log(const paramType& aParam, std::wstring* aLog) 1.530 + { 1.531 + LogParam(static_cast<const FallibleTArray<E>&>(aParam), aLog); 1.532 + } 1.533 +}; 1.534 + 1.535 +template<> 1.536 +struct ParamTraits<float> 1.537 +{ 1.538 + typedef float paramType; 1.539 + 1.540 + static void Write(Message* aMsg, const paramType& aParam) 1.541 + { 1.542 + aMsg->WriteBytes(&aParam, sizeof(paramType)); 1.543 + } 1.544 + 1.545 + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) 1.546 + { 1.547 + const char* outFloat; 1.548 + if (!aMsg->ReadBytes(aIter, &outFloat, sizeof(float))) 1.549 + return false; 1.550 + *aResult = *reinterpret_cast<const float*>(outFloat); 1.551 + return true; 1.552 + } 1.553 + 1.554 + static void Log(const paramType& aParam, std::wstring* aLog) 1.555 + { 1.556 + aLog->append(StringPrintf(L"%g", aParam)); 1.557 + } 1.558 +}; 1.559 + 1.560 +template <> 1.561 +struct ParamTraits<nsCSSProperty> 1.562 + : public ContiguousEnumSerializer<nsCSSProperty, 1.563 + eCSSProperty_UNKNOWN, 1.564 + eCSSProperty_COUNT> 1.565 +{}; 1.566 + 1.567 +template<> 1.568 +struct ParamTraits<mozilla::void_t> 1.569 +{ 1.570 + typedef mozilla::void_t paramType; 1.571 + static void Write(Message* aMsg, const paramType& aParam) { } 1.572 + static bool 1.573 + Read(const Message* aMsg, void** aIter, paramType* aResult) 1.574 + { 1.575 + *aResult = paramType(); 1.576 + return true; 1.577 + } 1.578 +}; 1.579 + 1.580 +template<> 1.581 +struct ParamTraits<mozilla::null_t> 1.582 +{ 1.583 + typedef mozilla::null_t paramType; 1.584 + static void Write(Message* aMsg, const paramType& aParam) { } 1.585 + static bool 1.586 + Read(const Message* aMsg, void** aIter, paramType* aResult) 1.587 + { 1.588 + *aResult = paramType(); 1.589 + return true; 1.590 + } 1.591 +}; 1.592 + 1.593 +template<> 1.594 +struct ParamTraits<nsID> 1.595 +{ 1.596 + typedef nsID paramType; 1.597 + 1.598 + static void Write(Message* aMsg, const paramType& aParam) 1.599 + { 1.600 + WriteParam(aMsg, aParam.m0); 1.601 + WriteParam(aMsg, aParam.m1); 1.602 + WriteParam(aMsg, aParam.m2); 1.603 + for (unsigned int i = 0; i < mozilla::ArrayLength(aParam.m3); i++) { 1.604 + WriteParam(aMsg, aParam.m3[i]); 1.605 + } 1.606 + } 1.607 + 1.608 + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) 1.609 + { 1.610 + if(!ReadParam(aMsg, aIter, &(aResult->m0)) || 1.611 + !ReadParam(aMsg, aIter, &(aResult->m1)) || 1.612 + !ReadParam(aMsg, aIter, &(aResult->m2))) 1.613 + return false; 1.614 + 1.615 + for (unsigned int i = 0; i < mozilla::ArrayLength(aResult->m3); i++) 1.616 + if (!ReadParam(aMsg, aIter, &(aResult->m3[i]))) 1.617 + return false; 1.618 + 1.619 + return true; 1.620 + } 1.621 + 1.622 + static void Log(const paramType& aParam, std::wstring* aLog) 1.623 + { 1.624 + aLog->append(L"{"); 1.625 + aLog->append(StringPrintf(L"%8.8X-%4.4X-%4.4X-", 1.626 + aParam.m0, 1.627 + aParam.m1, 1.628 + aParam.m2)); 1.629 + for (unsigned int i = 0; i < mozilla::ArrayLength(aParam.m3); i++) 1.630 + aLog->append(StringPrintf(L"%2.2X", aParam.m3[i])); 1.631 + aLog->append(L"}"); 1.632 + } 1.633 +}; 1.634 + 1.635 +template<> 1.636 +struct ParamTraits<mozilla::TimeDuration> 1.637 +{ 1.638 + typedef mozilla::TimeDuration paramType; 1.639 + static void Write(Message* aMsg, const paramType& aParam) 1.640 + { 1.641 + WriteParam(aMsg, aParam.mValue); 1.642 + } 1.643 + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) 1.644 + { 1.645 + return ReadParam(aMsg, aIter, &aResult->mValue); 1.646 + }; 1.647 +}; 1.648 + 1.649 +template<> 1.650 +struct ParamTraits<mozilla::TimeStamp> 1.651 +{ 1.652 + typedef mozilla::TimeStamp paramType; 1.653 + static void Write(Message* aMsg, const paramType& aParam) 1.654 + { 1.655 + WriteParam(aMsg, aParam.mValue); 1.656 + } 1.657 + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) 1.658 + { 1.659 + return ReadParam(aMsg, aIter, &aResult->mValue); 1.660 + }; 1.661 +}; 1.662 + 1.663 +#ifdef XP_WIN 1.664 + 1.665 +template<> 1.666 +struct ParamTraits<mozilla::TimeStampValue> 1.667 +{ 1.668 + typedef mozilla::TimeStampValue paramType; 1.669 + static void Write(Message* aMsg, const paramType& aParam) 1.670 + { 1.671 + WriteParam(aMsg, aParam.mGTC); 1.672 + WriteParam(aMsg, aParam.mQPC); 1.673 + WriteParam(aMsg, aParam.mHasQPC); 1.674 + WriteParam(aMsg, aParam.mIsNull); 1.675 + } 1.676 + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) 1.677 + { 1.678 + return (ReadParam(aMsg, aIter, &aResult->mGTC) && 1.679 + ReadParam(aMsg, aIter, &aResult->mQPC) && 1.680 + ReadParam(aMsg, aIter, &aResult->mHasQPC) && 1.681 + ReadParam(aMsg, aIter, &aResult->mIsNull)); 1.682 + } 1.683 +}; 1.684 + 1.685 +#endif 1.686 + 1.687 +template <> 1.688 +struct ParamTraits<mozilla::SerializedStructuredCloneBuffer> 1.689 +{ 1.690 + typedef mozilla::SerializedStructuredCloneBuffer paramType; 1.691 + 1.692 + static void Write(Message* aMsg, const paramType& aParam) 1.693 + { 1.694 + WriteParam(aMsg, aParam.dataLength); 1.695 + if (aParam.dataLength) { 1.696 + // Structured clone data must be 64-bit aligned. 1.697 + aMsg->WriteBytes(aParam.data, aParam.dataLength, sizeof(uint64_t)); 1.698 + } 1.699 + } 1.700 + 1.701 + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) 1.702 + { 1.703 + if (!ReadParam(aMsg, aIter, &aResult->dataLength)) { 1.704 + return false; 1.705 + } 1.706 + 1.707 + if (aResult->dataLength) { 1.708 + const char** buffer = 1.709 + const_cast<const char**>(reinterpret_cast<char**>(&aResult->data)); 1.710 + // Structured clone data must be 64-bit aligned. 1.711 + if (!aMsg->ReadBytes(aIter, buffer, aResult->dataLength, 1.712 + sizeof(uint64_t))) { 1.713 + return false; 1.714 + } 1.715 + } else { 1.716 + aResult->data = nullptr; 1.717 + } 1.718 + 1.719 + return true; 1.720 + } 1.721 + 1.722 + static void Log(const paramType& aParam, std::wstring* aLog) 1.723 + { 1.724 + LogParam(aParam.dataLength, aLog); 1.725 + } 1.726 +}; 1.727 + 1.728 +} /* namespace IPC */ 1.729 + 1.730 +#endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */