Bug 1920241 - Update Persisted Search preferences text - r=daleharvey,fluent-reviewer...
[gecko.git] / ipc / glue / IPCMessageUtils.h
blob22faac9cf95ea3b524a56926a30df58adf37708f
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_IPCMESSAGEUTILS_H__
8 #define __IPC_GLUE_IPCMESSAGEUTILS_H__
10 #include <cstdint>
11 #include <string>
12 #include <type_traits>
13 #include "chrome/common/ipc_message.h"
14 #include "chrome/common/ipc_message_utils.h"
15 #include "mozilla/ipc/IPCCore.h"
16 #include "mozilla/MacroForEach.h"
18 class PickleIterator;
20 // XXX Things that are not necessary if moving implementations to the cpp file
21 #include "base/string_util.h"
23 #ifdef _MSC_VER
24 # pragma warning(disable : 4800)
25 #endif
27 #if !defined(XP_UNIX)
28 // This condition must be kept in sync with the one in
29 // ipc_message_utils.h, but this dummy definition of
30 // base::FileDescriptor acts as a static assert that we only get one
31 // def or the other (or neither, in which case code using
32 // FileDescriptor fails to build)
33 namespace base {
34 struct FileDescriptor {};
35 } // namespace base
36 #endif
38 namespace mozilla {
39 template <typename...>
40 class Variant;
42 namespace detail {
43 template <typename...>
44 struct VariantTag;
46 } // namespace mozilla
48 namespace IPC {
50 /**
51 * A helper class for serializing empty structs. Since the struct is empty there
52 * is nothing to write, and a priori we know the result of the read.
54 template <typename T>
55 struct EmptyStructSerializer {
56 typedef T paramType;
58 static void Write(MessageWriter* aWriter, const paramType& aParam) {}
60 static bool Read(MessageReader* aReader, paramType* aResult) {
61 *aResult = {};
62 return true;
66 template <>
67 struct ParamTraits<int8_t> {
68 typedef int8_t paramType;
70 static void Write(MessageWriter* aWriter, const paramType& aParam) {
71 aWriter->WriteBytes(&aParam, sizeof(aParam));
74 static bool Read(MessageReader* aReader, paramType* aResult) {
75 return aReader->ReadBytesInto(aResult, sizeof(*aResult));
79 template <>
80 struct ParamTraits<uint8_t> {
81 typedef uint8_t paramType;
83 static void Write(MessageWriter* aWriter, const paramType& aParam) {
84 aWriter->WriteBytes(&aParam, sizeof(aParam));
87 static bool Read(MessageReader* aReader, paramType* aResult) {
88 return aReader->ReadBytesInto(aResult, sizeof(*aResult));
92 #if !defined(XP_UNIX)
93 // See above re: keeping definitions in sync
94 template <>
95 struct ParamTraits<base::FileDescriptor> {
96 typedef base::FileDescriptor paramType;
97 static void Write(MessageWriter* aWriter, const paramType& aParam) {
98 MOZ_CRASH("FileDescriptor isn't meaningful on this platform");
100 static bool Read(MessageReader* aReader, paramType* aResult) {
101 MOZ_CRASH("FileDescriptor isn't meaningful on this platform");
102 return false;
105 #endif // !defined(XP_UNIX)
107 template <>
108 struct ParamTraits<mozilla::void_t> {
109 typedef mozilla::void_t paramType;
110 static void Write(MessageWriter* aWriter, const paramType& aParam) {}
111 static bool Read(MessageReader* aReader, paramType* aResult) {
112 *aResult = paramType();
113 return true;
117 template <>
118 struct ParamTraits<mozilla::null_t> {
119 typedef mozilla::null_t paramType;
120 static void Write(MessageWriter* aWriter, const paramType& aParam) {}
121 static bool Read(MessageReader* aReader, paramType* aResult) {
122 *aResult = paramType();
123 return true;
127 // Helper class for reading bitfields.
128 // If T has bitfields members, derive ParamTraits<T> from BitfieldHelper<T>.
129 template <typename ParamType>
130 struct BitfieldHelper {
131 // We need this helper because we can't get the address of a bitfield to
132 // pass directly to ReadParam. So instead we read it into a temporary bool
133 // and set the bitfield using a setter function
134 static bool ReadBoolForBitfield(MessageReader* aReader, ParamType* aResult,
135 void (ParamType::*aSetter)(bool)) {
136 bool value;
137 if (ReadParam(aReader, &value)) {
138 (aResult->*aSetter)(value);
139 return true;
141 return false;
145 // A couple of recursive helper functions, allows syntax like:
146 // WriteParams(aMsg, aParam.foo, aParam.bar, aParam.baz)
147 // ReadParams(aMsg, aIter, aParam.foo, aParam.bar, aParam.baz)
149 template <typename... Ts>
150 static void WriteParams(MessageWriter* aWriter, const Ts&... aArgs) {
151 (WriteParam(aWriter, aArgs), ...);
154 template <typename... Ts>
155 static bool ReadParams(MessageReader* aReader, Ts&... aArgs) {
156 return (ReadParam(aReader, &aArgs) && ...);
159 // Macros that allow syntax like:
160 // DEFINE_IPC_SERIALIZER_WITH_FIELDS(SomeType, member1, member2, member3)
161 // Makes sure that serialize/deserialize code do the same members in the same
162 // order.
163 #define ACCESS_PARAM_FIELD(Field) aParam.Field
165 #define DEFINE_IPC_SERIALIZER_WITH_FIELDS(Type, ...) \
166 template <> \
167 struct ParamTraits<Type> { \
168 typedef Type paramType; \
169 static void Write(MessageWriter* aWriter, const paramType& aParam) { \
170 WriteParams(aWriter, MOZ_FOR_EACH_SEPARATED(ACCESS_PARAM_FIELD, (, ), \
171 (), (__VA_ARGS__))); \
174 static bool Read(MessageReader* aReader, paramType* aResult) { \
175 paramType& aParam = *aResult; \
176 return ReadParams(aReader, \
177 MOZ_FOR_EACH_SEPARATED(ACCESS_PARAM_FIELD, (, ), (), \
178 (__VA_ARGS__))); \
182 #define DEFINE_IPC_SERIALIZER_WITHOUT_FIELDS(Type) \
183 template <> \
184 struct ParamTraits<Type> : public EmptyStructSerializer<Type> {};
186 } /* namespace IPC */
188 #define DEFINE_IPC_SERIALIZER_WITH_SUPER_CLASS_AND_FIELDS(Type, Super, ...) \
189 template <> \
190 struct ParamTraits<Type> { \
191 typedef Type paramType; \
192 static void Write(MessageWriter* aWriter, const paramType& aParam) { \
193 WriteParam(aWriter, static_cast<const Super&>(aParam)); \
194 WriteParams(aWriter, MOZ_FOR_EACH_SEPARATED(ACCESS_PARAM_FIELD, (, ), \
195 (), (__VA_ARGS__))); \
198 static bool Read(MessageReader* aReader, paramType* aResult) { \
199 paramType& aParam = *aResult; \
200 return ReadParam(aReader, static_cast<Super*>(aResult)) && \
201 ReadParams(aReader, \
202 MOZ_FOR_EACH_SEPARATED(ACCESS_PARAM_FIELD, (, ), (), \
203 (__VA_ARGS__))); \
207 #endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */