1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef __IPC_GLUE_IPCMESSAGEUTILSSPECIALIZATIONS_H__
8 #define __IPC_GLUE_IPCMESSAGEUTILSSPECIALIZATIONS_H__
14 #include <type_traits>
15 #include <unordered_map>
18 #include "chrome/common/ipc_message.h"
19 #include "chrome/common/ipc_message_utils.h"
20 #include "ipc/EnumSerializer.h"
21 #include "ipc/IPCMessageUtils.h"
22 #include "mozilla/Assertions.h"
23 #include "mozilla/BitSet.h"
24 #include "mozilla/EnumSet.h"
25 #include "mozilla/EnumTypeTraits.h"
26 #include "mozilla/IntegerRange.h"
27 #include "mozilla/Maybe.h"
28 #include "mozilla/TimeStamp.h"
30 # include "mozilla/TimeStamp_windows.h"
33 #include "mozilla/UniquePtr.h"
34 #include "mozilla/Unused.h"
35 #include "mozilla/Vector.h"
36 #include "mozilla/dom/ipc/StructuredCloneData.h"
37 #include "mozilla/dom/UserActivation.h"
38 #include "nsCSSPropertyID.h"
40 #include "nsIContentPolicy.h"
42 #include "nsILoadInfo.h"
43 #include "nsIThread.h"
44 #include "nsLiteralString.h"
45 #include "nsNetUtil.h"
48 #include "nsTHashSet.h"
50 // XXX Includes that are only required by implementations which could be moved
52 #include "base/string_util.h" // for StringPrintf
53 #include "mozilla/ArrayUtils.h" // for ArrayLength
54 #include "mozilla/CheckedInt.h"
57 # pragma warning(disable : 4800)
61 template <typename
... Ts
>
65 template <typename
... Ts
>
68 } // namespace mozilla
70 namespace mozilla::dom
{
80 struct ParamTraits
<nsTSubstring
<T
>> {
81 typedef nsTSubstring
<T
> paramType
;
83 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
84 bool isVoid
= aParam
.IsVoid();
85 aWriter
->WriteBool(isVoid
);
88 // represents a nullptr pointer
92 WriteSequenceParam
<const T
&>(aWriter
, aParam
.BeginReading(),
96 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
98 if (!aReader
->ReadBool(&isVoid
)) {
103 aResult
->SetIsVoid(true);
107 return ReadSequenceParam
<T
>(aReader
, [&](uint32_t aLength
) -> T
* {
109 aResult
->GetMutableData(&data
, aLength
);
116 struct ParamTraits
<nsTString
<T
>> : ParamTraits
<nsTSubstring
<T
>> {};
119 struct ParamTraits
<nsTLiteralString
<T
>> : ParamTraits
<nsTSubstring
<T
>> {};
121 template <class T
, size_t N
>
122 struct ParamTraits
<nsTAutoStringN
<T
, N
>> : ParamTraits
<nsTSubstring
<T
>> {};
125 struct ParamTraits
<nsTDependentString
<T
>> : ParamTraits
<nsTSubstring
<T
>> {};
127 // XXX While this has no special dependencies, it's currently only used in
128 // GfxMessageUtils and could be moved there, or generalized to potentially work
129 // with any nsTHashSet.
131 struct ParamTraits
<nsTHashSet
<uint64_t>> {
132 typedef nsTHashSet
<uint64_t> paramType
;
134 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
135 uint32_t count
= aParam
.Count();
136 WriteParam(aWriter
, count
);
137 for (const auto& key
: aParam
) {
138 WriteParam(aWriter
, key
);
142 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
144 if (!ReadParam(aReader
, &count
)) {
147 paramType
table(count
);
148 for (uint32_t i
= 0; i
< count
; ++i
) {
150 if (!ReadParam(aReader
, &key
)) {
155 *aResult
= std::move(table
);
160 template <typename E
>
161 struct ParamTraits
<nsTArray
<E
>> {
162 typedef nsTArray
<E
> paramType
;
164 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
165 WriteSequenceParam
<const E
&>(aWriter
, aParam
.Elements(), aParam
.Length());
168 static void Write(MessageWriter
* aWriter
, paramType
&& aParam
) {
169 WriteSequenceParam
<E
&&>(aWriter
, aParam
.Elements(), aParam
.Length());
172 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
173 return ReadSequenceParam
<E
>(aReader
, [&](uint32_t aLength
) {
174 if constexpr (std::is_trivially_default_constructible_v
<E
>) {
175 return aResult
->AppendElements(aLength
);
177 aResult
->SetCapacity(aLength
);
178 return mozilla::Some(MakeBackInserter(*aResult
));
184 template <typename E
>
185 struct ParamTraits
<CopyableTArray
<E
>> : ParamTraits
<nsTArray
<E
>> {};
187 template <typename E
>
188 struct ParamTraits
<FallibleTArray
<E
>> {
189 typedef FallibleTArray
<E
> paramType
;
191 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
192 WriteSequenceParam
<const E
&>(aWriter
, aParam
.Elements(), aParam
.Length());
195 static void Write(MessageWriter
* aWriter
, paramType
&& aParam
) {
196 WriteSequenceParam
<E
&&>(aWriter
, aParam
.Elements(), aParam
.Length());
199 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
200 return ReadSequenceParam
<E
>(aReader
, [&](uint32_t aLength
) {
201 if constexpr (std::is_trivially_default_constructible_v
<E
>) {
202 return aResult
->AppendElements(aLength
, mozilla::fallible
);
204 if (!aResult
->SetCapacity(aLength
, mozilla::fallible
)) {
205 return mozilla::Maybe
<BackInserter
>{};
207 return mozilla::Some(BackInserter
{.mArray
= aResult
});
213 struct BackInserter
{
214 using iterator_category
= std::output_iterator_tag
;
215 using value_type
= void;
216 using difference_type
= void;
217 using pointer
= void;
218 using reference
= void;
223 template <typename U
>
224 void operator=(U
&& aValue
) {
225 // This won't fail because we've reserved capacity earlier.
226 MOZ_ALWAYS_TRUE(mArray
.AppendElement(aValue
, mozilla::fallible
));
229 Proxy
operator*() { return Proxy
{.mArray
= *mArray
}; }
231 BackInserter
& operator++() { return *this; }
232 BackInserter
& operator++(int) { return *this; }
234 paramType
* mArray
= nullptr;
238 template <typename E
, size_t N
>
239 struct ParamTraits
<AutoTArray
<E
, N
>> : ParamTraits
<nsTArray
<E
>> {
240 typedef AutoTArray
<E
, N
> paramType
;
243 template <typename E
, size_t N
>
244 struct ParamTraits
<CopyableAutoTArray
<E
, N
>> : ParamTraits
<AutoTArray
<E
, N
>> {};
246 template <typename T
>
247 struct ParamTraits
<mozilla::dom::Sequence
<T
>> : ParamTraits
<FallibleTArray
<T
>> {
250 template <typename E
, size_t N
, typename AP
>
251 struct ParamTraits
<mozilla::Vector
<E
, N
, AP
>> {
252 typedef mozilla::Vector
<E
, N
, AP
> paramType
;
254 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
255 WriteSequenceParam
<const E
&>(aWriter
, aParam
.Elements(), aParam
.Length());
258 static void Write(MessageWriter
* aWriter
, paramType
&& aParam
) {
259 WriteSequenceParam
<E
&&>(aWriter
, aParam
.Elements(), aParam
.Length());
262 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
263 return ReadSequenceParam
<E
>(aReader
, [&](uint32_t aLength
) -> E
* {
264 if (!aResult
->resize(aLength
)) {
265 // So that OOM failure shows up as OOM crash instead of IPC FatalError.
266 NS_ABORT_OOM(aLength
* sizeof(E
));
268 return aResult
->begin();
273 template <typename E
>
274 struct ParamTraits
<std::vector
<E
>> {
275 typedef std::vector
<E
> paramType
;
277 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
278 WriteSequenceParam
<const E
&>(aWriter
, aParam
.data(), aParam
.size());
280 static void Write(MessageWriter
* aWriter
, paramType
&& aParam
) {
281 WriteSequenceParam
<E
&&>(aWriter
, aParam
.data(), aParam
.size());
284 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
285 return ReadSequenceParam
<E
>(aReader
, [&](uint32_t aLength
) {
286 if constexpr (std::is_trivially_default_constructible_v
<E
>) {
287 aResult
->resize(aLength
);
288 return aResult
->data();
290 aResult
->reserve(aLength
);
291 return mozilla::Some(std::back_inserter(*aResult
));
297 template <typename K
, typename V
>
298 struct ParamTraits
<std::unordered_map
<K
, V
>> final
{
299 using T
= std::unordered_map
<K
, V
>;
301 static void Write(MessageWriter
* const writer
, const T
& in
) {
302 WriteParam(writer
, in
.size());
303 for (const auto& pair
: in
) {
304 WriteParam(writer
, pair
.first
);
305 WriteParam(writer
, pair
.second
);
309 static bool Read(MessageReader
* const reader
, T
* const out
) {
311 if (!ReadParam(reader
, &size
)) return false;
314 for (const auto i
: mozilla::IntegerRange(size
)) {
315 std::pair
<K
, V
> pair
;
316 mozilla::Unused
<< i
;
317 if (!ReadParam(reader
, &(pair
.first
)) ||
318 !ReadParam(reader
, &(pair
.second
))) {
321 map
.insert(std::move(pair
));
323 *out
= std::move(map
);
329 struct ParamTraits
<float> {
330 typedef float paramType
;
332 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
333 aWriter
->WriteBytes(&aParam
, sizeof(paramType
));
336 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
337 return aReader
->ReadBytesInto(aResult
, sizeof(*aResult
));
342 struct ParamTraits
<nsCSSPropertyID
>
343 : public ContiguousEnumSerializer
<nsCSSPropertyID
, eCSSProperty_UNKNOWN
,
344 eCSSProperty_COUNT
> {};
347 struct ParamTraits
<nsID
> {
348 typedef nsID paramType
;
350 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
351 WriteParam(aWriter
, aParam
.m0
);
352 WriteParam(aWriter
, aParam
.m1
);
353 WriteParam(aWriter
, aParam
.m2
);
354 for (unsigned int i
= 0; i
< mozilla::ArrayLength(aParam
.m3
); i
++) {
355 WriteParam(aWriter
, aParam
.m3
[i
]);
359 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
360 if (!ReadParam(aReader
, &(aResult
->m0
)) ||
361 !ReadParam(aReader
, &(aResult
->m1
)) ||
362 !ReadParam(aReader
, &(aResult
->m2
)))
365 for (unsigned int i
= 0; i
< mozilla::ArrayLength(aResult
->m3
); i
++)
366 if (!ReadParam(aReader
, &(aResult
->m3
[i
]))) return false;
373 struct ParamTraits
<nsContentPolicyType
>
374 : public ContiguousEnumSerializer
<nsContentPolicyType
,
375 nsIContentPolicy::TYPE_INVALID
,
376 nsIContentPolicy::TYPE_END
> {};
379 struct ParamTraits
<mozilla::TimeDuration
> {
380 typedef mozilla::TimeDuration paramType
;
381 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
382 WriteParam(aWriter
, aParam
.mValue
);
384 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
385 return ReadParam(aReader
, &aResult
->mValue
);
390 struct ParamTraits
<mozilla::TimeStamp
> {
391 typedef mozilla::TimeStamp paramType
;
392 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
393 WriteParam(aWriter
, aParam
.mValue
);
395 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
396 return ReadParam(aReader
, &aResult
->mValue
);
403 struct ParamTraits
<mozilla::TimeStampValue
> {
404 typedef mozilla::TimeStampValue paramType
;
405 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
406 WriteParam(aWriter
, aParam
.mGTC
);
407 WriteParam(aWriter
, aParam
.mQPC
);
408 WriteParam(aWriter
, aParam
.mIsNull
);
409 WriteParam(aWriter
, aParam
.mHasQPC
);
411 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
412 return (ReadParam(aReader
, &aResult
->mGTC
) &&
413 ReadParam(aReader
, &aResult
->mQPC
) &&
414 ReadParam(aReader
, &aResult
->mIsNull
) &&
415 ReadParam(aReader
, &aResult
->mHasQPC
));
422 struct ParamTraits
<mozilla::dom::ipc::StructuredCloneData
> {
423 typedef mozilla::dom::ipc::StructuredCloneData paramType
;
425 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
426 aParam
.WriteIPCParams(aWriter
);
429 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
430 return aResult
->ReadIPCParams(aReader
);
435 struct ParamTraits
<mozilla::Maybe
<T
>> {
436 typedef mozilla::Maybe
<T
> paramType
;
438 static void Write(MessageWriter
* writer
, const paramType
& param
) {
439 if (param
.isSome()) {
440 WriteParam(writer
, true);
441 WriteParam(writer
, param
.ref());
443 WriteParam(writer
, false);
447 static void Write(MessageWriter
* writer
, paramType
&& param
) {
448 if (param
.isSome()) {
449 WriteParam(writer
, true);
450 WriteParam(writer
, std::move(param
.ref()));
452 WriteParam(writer
, false);
456 static bool Read(MessageReader
* reader
, paramType
* result
) {
458 if (!ReadParam(reader
, &isSome
)) {
462 mozilla::Maybe
<T
> tmp
= ReadParam
<T
>(reader
).TakeMaybe();
466 *result
= std::move(tmp
);
468 *result
= mozilla::Nothing();
474 template <typename T
, typename U
>
475 struct ParamTraits
<mozilla::EnumSet
<T
, U
>> {
476 typedef mozilla::EnumSet
<T
, U
> paramType
;
477 typedef U serializedType
;
479 static void Write(MessageWriter
* writer
, const paramType
& param
) {
480 MOZ_RELEASE_ASSERT(IsLegalValue(param
.serialize()));
481 WriteParam(writer
, param
.serialize());
484 static bool Read(MessageReader
* reader
, paramType
* result
) {
487 if (ReadParam(reader
, &tmp
)) {
488 if (IsLegalValue(tmp
)) {
489 result
->deserialize(tmp
);
497 static constexpr serializedType
AllEnumBits() {
498 return ~serializedType(0) >> (std::numeric_limits
<serializedType
>::digits
-
499 (mozilla::MaxEnumValue
<T
>::value
+ 1));
502 static constexpr bool IsLegalValue(const serializedType value
) {
503 static_assert(mozilla::MaxEnumValue
<T
>::value
<
504 std::numeric_limits
<serializedType
>::digits
,
505 "Enum max value is not in the range!");
507 std::is_unsigned
<decltype(mozilla::MaxEnumValue
<T
>::value
)>::value
,
508 "Type of MaxEnumValue<T>::value specialization should be unsigned!");
510 return (value
& AllEnumBits()) == value
;
514 template <class... Ts
>
515 struct ParamTraits
<mozilla::Variant
<Ts
...>> {
516 typedef mozilla::Variant
<Ts
...> paramType
;
517 using Tag
= typename
mozilla::detail::VariantTag
<Ts
...>::Type
;
519 static void Write(MessageWriter
* writer
, const paramType
& param
) {
520 WriteParam(writer
, param
.tag
);
521 param
.match([writer
](const auto& t
) { WriteParam(writer
, t
); });
524 // Because VariantReader is a nested struct, we need the dummy template
525 // parameter to avoid making VariantReader<0> an explicit specialization,
526 // which is not allowed for a nested class template
527 template <size_t N
, typename dummy
= void>
528 struct VariantReader
{
529 using Next
= VariantReader
<N
- 1>;
531 static bool Read(MessageReader
* reader
, Tag tag
, paramType
* result
) {
532 // Since the VariantReader specializations start at N , we need to
533 // subtract one to look at N - 1, the first valid tag. This means our
534 // comparisons are off by 1. If we get to N = 0 then we have failed to
535 // find a match to the tag.
537 // Recall, even though the template parameter is N, we are
538 // actually interested in the N - 1 tag.
539 // Default construct our field within the result outparameter and
540 // directly deserialize into the variant. Note that this means that
541 // every type in Ts needs to be default constructible
542 return ReadParam(reader
, &result
->template emplace
<N
- 1>());
544 return Next::Read(reader
, tag
, result
);
548 }; // VariantReader<N>
550 // Since we are conditioning on tag = N - 1 in the preceding specialization,
551 // if we get to `VariantReader<0, dummy>` we have failed to find
553 template <typename dummy
>
554 struct VariantReader
<0, dummy
> {
555 static bool Read(MessageReader
* reader
, Tag tag
, paramType
* result
) {
560 static bool Read(MessageReader
* reader
, paramType
* result
) {
562 if (ReadParam(reader
, &tag
)) {
563 return VariantReader
<sizeof...(Ts
)>::Read(reader
, tag
, result
);
569 template <typename T
>
570 struct ParamTraits
<mozilla::dom::Optional
<T
>> {
571 typedef mozilla::dom::Optional
<T
> paramType
;
573 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
574 if (aParam
.WasPassed()) {
575 WriteParam(aWriter
, true);
576 WriteParam(aWriter
, aParam
.Value());
580 WriteParam(aWriter
, false);
583 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
584 bool wasPassed
= false;
586 if (!ReadParam(aReader
, &wasPassed
)) {
593 if (!ReadParam(aReader
, &aResult
->Construct())) {
603 struct ParamTraits
<nsAtom
*> {
604 typedef nsAtom paramType
;
606 static void Write(MessageWriter
* aWriter
, const paramType
* aParam
);
607 static bool Read(MessageReader
* aReader
, RefPtr
<paramType
>* aResult
);
610 struct CrossOriginOpenerPolicyValidator
{
612 std::underlying_type_t
<nsILoadInfo::CrossOriginOpenerPolicy
>;
614 static bool IsLegalValue(const IntegralType e
) {
615 return AreIntegralValuesEqual(e
, nsILoadInfo::OPENER_POLICY_UNSAFE_NONE
) ||
616 AreIntegralValuesEqual(e
, nsILoadInfo::OPENER_POLICY_SAME_ORIGIN
) ||
617 AreIntegralValuesEqual(
618 e
, nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_ALLOW_POPUPS
) ||
619 AreIntegralValuesEqual(
621 OPENER_POLICY_SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP
);
625 static bool AreIntegralValuesEqual(
626 const IntegralType aLhs
,
627 const nsILoadInfo::CrossOriginOpenerPolicy aRhs
) {
628 return aLhs
== static_cast<IntegralType
>(aRhs
);
633 struct ParamTraits
<nsILoadInfo::CrossOriginOpenerPolicy
>
634 : EnumSerializer
<nsILoadInfo::CrossOriginOpenerPolicy
,
635 CrossOriginOpenerPolicyValidator
> {};
637 struct CrossOriginEmbedderPolicyValidator
{
639 std::underlying_type_t
<nsILoadInfo::CrossOriginEmbedderPolicy
>;
641 static bool IsLegalValue(const IntegralType e
) {
642 return AreIntegralValuesEqual(e
, nsILoadInfo::EMBEDDER_POLICY_NULL
) ||
643 AreIntegralValuesEqual(e
,
644 nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP
) ||
645 AreIntegralValuesEqual(e
,
646 nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS
);
650 static bool AreIntegralValuesEqual(
651 const IntegralType aLhs
,
652 const nsILoadInfo::CrossOriginEmbedderPolicy aRhs
) {
653 return aLhs
== static_cast<IntegralType
>(aRhs
);
658 struct ParamTraits
<nsILoadInfo::CrossOriginEmbedderPolicy
>
659 : EnumSerializer
<nsILoadInfo::CrossOriginEmbedderPolicy
,
660 CrossOriginEmbedderPolicyValidator
> {};
663 struct ParamTraits
<nsIThread::QoSPriority
>
664 : public ContiguousEnumSerializerInclusive
<nsIThread::QoSPriority
,
665 nsIThread::QOS_PRIORITY_NORMAL
,
666 nsIThread::QOS_PRIORITY_LOW
> {};
668 template <size_t N
, typename Word
>
669 struct ParamTraits
<mozilla::BitSet
<N
, Word
>> {
670 typedef mozilla::BitSet
<N
, Word
> paramType
;
672 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
673 for (Word word
: aParam
.Storage()) {
674 WriteParam(aWriter
, word
);
678 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
679 for (Word
& word
: aResult
->Storage()) {
680 if (!ReadParam(aReader
, &word
)) {
688 template <typename T
>
689 struct ParamTraits
<mozilla::UniquePtr
<T
>> {
690 typedef mozilla::UniquePtr
<T
> paramType
;
692 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
693 bool isNull
= aParam
== nullptr;
694 WriteParam(aWriter
, isNull
);
697 WriteParam(aWriter
, *aParam
.get());
701 static bool Read(IPC::MessageReader
* aReader
, paramType
* aResult
) {
703 if (!ReadParam(aReader
, &isNull
)) {
710 *aResult
= mozilla::MakeUnique
<T
>();
711 if (!ReadParam(aReader
, aResult
->get())) {
719 template <typename
... Ts
>
720 struct ParamTraits
<std::tuple
<Ts
...>> {
721 typedef std::tuple
<Ts
...> paramType
;
723 template <typename U
>
724 static void Write(IPC::MessageWriter
* aWriter
, U
&& aParam
) {
725 WriteInternal(aWriter
, std::forward
<U
>(aParam
),
726 std::index_sequence_for
<Ts
...>{});
729 static bool Read(IPC::MessageReader
* aReader
, std::tuple
<Ts
...>* aResult
) {
730 return ReadInternal(aReader
, *aResult
, std::index_sequence_for
<Ts
...>{});
734 template <size_t... Is
>
735 static void WriteInternal(IPC::MessageWriter
* aWriter
,
736 const std::tuple
<Ts
...>& aParam
,
737 std::index_sequence
<Is
...>) {
738 WriteParams(aWriter
, std::get
<Is
>(aParam
)...);
741 template <size_t... Is
>
742 static void WriteInternal(IPC::MessageWriter
* aWriter
,
743 std::tuple
<Ts
...>&& aParam
,
744 std::index_sequence
<Is
...>) {
745 WriteParams(aWriter
, std::move(std::get
<Is
>(aParam
))...);
748 template <size_t... Is
>
749 static bool ReadInternal(IPC::MessageReader
* aReader
,
750 std::tuple
<Ts
...>& aResult
,
751 std::index_sequence
<Is
...>) {
752 return ReadParams(aReader
, std::get
<Is
>(aResult
)...);
757 struct ParamTraits
<mozilla::net::LinkHeader
> {
758 typedef mozilla::net::LinkHeader paramType
;
759 constexpr static int kNumberOfMembers
= 14;
760 constexpr static int kSizeOfEachMember
= sizeof(nsString
);
761 constexpr static int kExpectedSizeOfParamType
=
762 kNumberOfMembers
* kSizeOfEachMember
;
764 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
765 static_assert(sizeof(paramType
) == kExpectedSizeOfParamType
,
766 "All members of should be written below.");
767 // Bug 1860565: `aParam.mAnchor` is not written.
769 WriteParam(aWriter
, aParam
.mHref
);
770 WriteParam(aWriter
, aParam
.mRel
);
771 WriteParam(aWriter
, aParam
.mTitle
);
772 WriteParam(aWriter
, aParam
.mNonce
);
773 WriteParam(aWriter
, aParam
.mIntegrity
);
774 WriteParam(aWriter
, aParam
.mSrcset
);
775 WriteParam(aWriter
, aParam
.mSizes
);
776 WriteParam(aWriter
, aParam
.mType
);
777 WriteParam(aWriter
, aParam
.mMedia
);
778 WriteParam(aWriter
, aParam
.mCrossOrigin
);
779 WriteParam(aWriter
, aParam
.mReferrerPolicy
);
780 WriteParam(aWriter
, aParam
.mAs
);
781 WriteParam(aWriter
, aParam
.mFetchPriority
);
783 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
784 static_assert(sizeof(paramType
) == kExpectedSizeOfParamType
,
785 "All members of should be handled below.");
786 // Bug 1860565: `aParam.mAnchor` is not handled.
788 if (!ReadParam(aReader
, &aResult
->mHref
)) {
791 if (!ReadParam(aReader
, &aResult
->mRel
)) {
794 if (!ReadParam(aReader
, &aResult
->mTitle
)) {
797 if (!ReadParam(aReader
, &aResult
->mNonce
)) {
800 if (!ReadParam(aReader
, &aResult
->mIntegrity
)) {
803 if (!ReadParam(aReader
, &aResult
->mSrcset
)) {
806 if (!ReadParam(aReader
, &aResult
->mSizes
)) {
809 if (!ReadParam(aReader
, &aResult
->mType
)) {
812 if (!ReadParam(aReader
, &aResult
->mMedia
)) {
815 if (!ReadParam(aReader
, &aResult
->mCrossOrigin
)) {
818 if (!ReadParam(aReader
, &aResult
->mReferrerPolicy
)) {
821 if (!ReadParam(aReader
, &aResult
->mAs
)) {
824 return ReadParam(aReader
, &aResult
->mFetchPriority
);
829 struct ParamTraits
<mozilla::dom::UserActivation::Modifiers
> {
830 typedef mozilla::dom::UserActivation::Modifiers paramType
;
831 static void Write(MessageWriter
* aWriter
, const paramType
& aParam
) {
832 WriteParam(aWriter
, aParam
.mModifiers
);
834 static bool Read(MessageReader
* aReader
, paramType
* aResult
) {
835 return ReadParam(aReader
, &aResult
->mModifiers
);
839 } /* namespace IPC */
841 #endif /* __IPC_GLUE_IPCMESSAGEUTILSSPECIALIZATIONS_H__ */