2009-09-22 02:02:15 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2016-05-27 21:54:31 +00:00
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 11:12:37 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2009-06-29 18:38:29 +00:00
|
|
|
|
|
|
|
#ifndef __IPC_GLUE_IPCMESSAGEUTILS_H__
|
|
|
|
#define __IPC_GLUE_IPCMESSAGEUTILS_H__
|
|
|
|
|
2020-12-10 11:09:21 +00:00
|
|
|
#include <cstdint>
|
|
|
|
#include <string>
|
|
|
|
#include <type_traits>
|
|
|
|
#include "chrome/common/ipc_message.h"
|
2009-06-29 18:38:29 +00:00
|
|
|
#include "chrome/common/ipc_message_utils.h"
|
2020-11-23 16:05:20 +00:00
|
|
|
#include "mozilla/ipc/IPCCore.h"
|
2023-03-15 07:30:36 +00:00
|
|
|
#include "mozilla/MacroForEach.h"
|
2013-07-30 14:25:31 +00:00
|
|
|
|
2020-12-10 11:09:21 +00:00
|
|
|
class PickleIterator;
|
2011-10-11 05:50:08 +00:00
|
|
|
|
2020-12-10 11:09:21 +00:00
|
|
|
// XXX Things that are not necessary if moving implementations to the cpp file
|
|
|
|
#include "base/string_util.h"
|
2009-06-29 18:38:29 +00:00
|
|
|
|
2010-01-22 15:06:13 +00:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
# pragma warning(disable : 4800)
|
|
|
|
#endif
|
|
|
|
|
2023-06-06 21:05:31 +00:00
|
|
|
#if !defined(XP_UNIX)
|
2010-11-09 02:48:59 +00:00
|
|
|
// This condition must be kept in sync with the one in
|
|
|
|
// ipc_message_utils.h, but this dummy definition of
|
|
|
|
// base::FileDescriptor acts as a static assert that we only get one
|
|
|
|
// def or the other (or neither, in which case code using
|
|
|
|
// FileDescriptor fails to build)
|
2012-01-18 02:01:51 +00:00
|
|
|
namespace base {
|
|
|
|
struct FileDescriptor {};
|
|
|
|
} // namespace base
|
2010-11-09 02:48:59 +00:00
|
|
|
#endif
|
2010-05-22 19:35:40 +00:00
|
|
|
|
2020-11-23 16:21:38 +00:00
|
|
|
namespace mozilla {
|
|
|
|
template <typename...>
|
|
|
|
class Variant;
|
|
|
|
|
|
|
|
namespace detail {
|
|
|
|
template <typename...>
|
|
|
|
struct VariantTag;
|
|
|
|
}
|
|
|
|
} // namespace mozilla
|
2010-05-22 19:35:40 +00:00
|
|
|
|
2009-06-29 18:38:29 +00:00
|
|
|
namespace IPC {
|
|
|
|
|
2017-05-04 00:21:11 +00:00
|
|
|
/**
|
|
|
|
* A helper class for serializing plain-old data (POD) structures.
|
|
|
|
* The memory representation of the structure is written to and read from
|
|
|
|
* the serialized stream directly, without individual processing of the
|
|
|
|
* structure's members.
|
|
|
|
*
|
|
|
|
* Derive ParamTraits<T> from PlainOldDataSerializer<T> if T is POD.
|
2017-10-19 00:13:19 +00:00
|
|
|
*
|
|
|
|
* Note: For POD structures with enumeration fields, this will not do
|
|
|
|
* validation of the enum values the way serializing the fields
|
|
|
|
* individually would. Prefer serializing the fields individually
|
|
|
|
* in such cases.
|
2017-05-04 00:21:11 +00:00
|
|
|
*/
|
|
|
|
template <typename T>
|
|
|
|
struct PlainOldDataSerializer {
|
2020-03-14 04:12:50 +00:00
|
|
|
static_assert(
|
|
|
|
std::is_trivially_copyable<T>::value,
|
|
|
|
"PlainOldDataSerializer can only be used with trivially copyable types!");
|
|
|
|
|
2017-05-04 00:21:11 +00:00
|
|
|
typedef T paramType;
|
|
|
|
|
2022-03-04 15:39:41 +00:00
|
|
|
static void Write(MessageWriter* aWriter, const paramType& aParam) {
|
|
|
|
aWriter->WriteBytes(&aParam, sizeof(aParam));
|
2017-05-04 00:21:11 +00:00
|
|
|
}
|
|
|
|
|
2022-03-04 15:39:41 +00:00
|
|
|
static bool Read(MessageReader* aReader, paramType* aResult) {
|
|
|
|
return aReader->ReadBytesInto(aResult, sizeof(paramType));
|
2017-05-04 00:21:11 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-09-02 19:10:40 +00:00
|
|
|
/**
|
|
|
|
* A helper class for serializing empty structs. Since the struct is empty there
|
|
|
|
* is nothing to write, and a priori we know the result of the read.
|
|
|
|
*/
|
|
|
|
template <typename T>
|
|
|
|
struct EmptyStructSerializer {
|
|
|
|
typedef T paramType;
|
|
|
|
|
2022-03-04 15:39:41 +00:00
|
|
|
static void Write(MessageWriter* aWriter, const paramType& aParam) {}
|
2017-09-02 19:10:40 +00:00
|
|
|
|
2022-03-04 15:39:41 +00:00
|
|
|
static bool Read(MessageReader* aReader, paramType* aResult) {
|
2017-09-02 19:10:40 +00:00
|
|
|
*aResult = {};
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2010-01-25 22:47:39 +00:00
|
|
|
template <>
|
2012-08-22 15:56:38 +00:00
|
|
|
struct ParamTraits<int8_t> {
|
|
|
|
typedef int8_t paramType;
|
2010-01-25 22:47:39 +00:00
|
|
|
|
2022-03-04 15:39:41 +00:00
|
|
|
static void Write(MessageWriter* aWriter, const paramType& aParam) {
|
|
|
|
aWriter->WriteBytes(&aParam, sizeof(aParam));
|
2010-01-25 22:47:39 +00:00
|
|
|
}
|
|
|
|
|
2022-03-04 15:39:41 +00:00
|
|
|
static bool Read(MessageReader* aReader, paramType* aResult) {
|
|
|
|
return aReader->ReadBytesInto(aResult, sizeof(*aResult));
|
2010-01-25 22:47:39 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
2012-08-22 15:56:38 +00:00
|
|
|
struct ParamTraits<uint8_t> {
|
|
|
|
typedef uint8_t paramType;
|
2010-01-25 22:47:39 +00:00
|
|
|
|
2022-03-04 15:39:41 +00:00
|
|
|
static void Write(MessageWriter* aWriter, const paramType& aParam) {
|
|
|
|
aWriter->WriteBytes(&aParam, sizeof(aParam));
|
2010-01-25 22:47:39 +00:00
|
|
|
}
|
|
|
|
|
2022-03-04 15:39:41 +00:00
|
|
|
static bool Read(MessageReader* aReader, paramType* aResult) {
|
|
|
|
return aReader->ReadBytesInto(aResult, sizeof(*aResult));
|
2010-01-25 22:47:39 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-06-06 21:05:31 +00:00
|
|
|
#if !defined(XP_UNIX)
|
2010-11-09 02:48:59 +00:00
|
|
|
// See above re: keeping definitions in sync
|
|
|
|
template <>
|
|
|
|
struct ParamTraits<base::FileDescriptor> {
|
|
|
|
typedef base::FileDescriptor paramType;
|
2022-03-04 15:39:41 +00:00
|
|
|
static void Write(MessageWriter* aWriter, const paramType& aParam) {
|
2016-12-02 21:46:53 +00:00
|
|
|
MOZ_CRASH("FileDescriptor isn't meaningful on this platform");
|
2010-11-09 02:48:59 +00:00
|
|
|
}
|
2022-03-04 15:39:41 +00:00
|
|
|
static bool Read(MessageReader* aReader, paramType* aResult) {
|
2016-12-02 21:46:53 +00:00
|
|
|
MOZ_CRASH("FileDescriptor isn't meaningful on this platform");
|
2010-11-09 02:48:59 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
2023-06-06 21:05:31 +00:00
|
|
|
#endif // !defined(XP_UNIX)
|
2010-11-09 02:48:59 +00:00
|
|
|
|
2010-05-22 19:35:40 +00:00
|
|
|
template <>
|
|
|
|
struct ParamTraits<mozilla::void_t> {
|
|
|
|
typedef mozilla::void_t paramType;
|
2022-03-04 15:39:41 +00:00
|
|
|
static void Write(MessageWriter* aWriter, const paramType& aParam) {}
|
|
|
|
static bool Read(MessageReader* aReader, paramType* aResult) {
|
2010-05-22 19:35:40 +00:00
|
|
|
*aResult = paramType();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct ParamTraits<mozilla::null_t> {
|
|
|
|
typedef mozilla::null_t paramType;
|
2022-03-04 15:39:41 +00:00
|
|
|
static void Write(MessageWriter* aWriter, const paramType& aParam) {}
|
|
|
|
static bool Read(MessageReader* aReader, paramType* aResult) {
|
2010-05-22 19:35:40 +00:00
|
|
|
*aResult = paramType();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-06-20 20:18:45 +00:00
|
|
|
// Helper class for reading bitfields.
|
|
|
|
// If T has bitfields members, derive ParamTraits<T> from BitfieldHelper<T>.
|
|
|
|
template <typename ParamType>
|
|
|
|
struct BitfieldHelper {
|
|
|
|
// We need this helper because we can't get the address of a bitfield to
|
|
|
|
// pass directly to ReadParam. So instead we read it into a temporary bool
|
|
|
|
// and set the bitfield using a setter function
|
2022-03-04 15:39:41 +00:00
|
|
|
static bool ReadBoolForBitfield(MessageReader* aReader, ParamType* aResult,
|
2019-06-20 20:18:45 +00:00
|
|
|
void (ParamType::*aSetter)(bool)) {
|
|
|
|
bool value;
|
2022-03-04 15:39:41 +00:00
|
|
|
if (ReadParam(aReader, &value)) {
|
2019-06-20 20:18:45 +00:00
|
|
|
(aResult->*aSetter)(value);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-11-04 15:00:04 +00:00
|
|
|
// A couple of recursive helper functions, allows syntax like:
|
|
|
|
// WriteParams(aMsg, aParam.foo, aParam.bar, aParam.baz)
|
|
|
|
// ReadParams(aMsg, aIter, aParam.foo, aParam.bar, aParam.baz)
|
|
|
|
|
2020-05-14 16:31:17 +00:00
|
|
|
template <typename... Ts>
|
2022-03-04 15:39:41 +00:00
|
|
|
static void WriteParams(MessageWriter* aWriter, const Ts&... aArgs) {
|
|
|
|
(WriteParam(aWriter, aArgs), ...);
|
2019-11-04 15:00:04 +00:00
|
|
|
}
|
|
|
|
|
2020-05-14 16:31:17 +00:00
|
|
|
template <typename... Ts>
|
2022-03-04 15:39:41 +00:00
|
|
|
static bool ReadParams(MessageReader* aReader, Ts&... aArgs) {
|
|
|
|
return (ReadParam(aReader, &aArgs) && ...);
|
2019-11-04 15:00:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Macros that allow syntax like:
|
|
|
|
// DEFINE_IPC_SERIALIZER_WITH_FIELDS(SomeType, member1, member2, member3)
|
|
|
|
// Makes sure that serialize/deserialize code do the same members in the same
|
|
|
|
// order.
|
|
|
|
#define ACCESS_PARAM_FIELD(Field) aParam.Field
|
|
|
|
|
|
|
|
#define DEFINE_IPC_SERIALIZER_WITH_FIELDS(Type, ...) \
|
|
|
|
template <> \
|
|
|
|
struct ParamTraits<Type> { \
|
|
|
|
typedef Type paramType; \
|
2022-03-04 15:39:41 +00:00
|
|
|
static void Write(MessageWriter* aWriter, const paramType& aParam) { \
|
|
|
|
WriteParams(aWriter, MOZ_FOR_EACH_SEPARATED(ACCESS_PARAM_FIELD, (, ), \
|
|
|
|
(), (__VA_ARGS__))); \
|
2019-11-04 15:00:04 +00:00
|
|
|
} \
|
|
|
|
\
|
2022-03-04 15:39:41 +00:00
|
|
|
static bool Read(MessageReader* aReader, paramType* aResult) { \
|
2019-11-04 15:00:04 +00:00
|
|
|
paramType& aParam = *aResult; \
|
2022-03-04 15:39:41 +00:00
|
|
|
return ReadParams(aReader, \
|
2019-11-04 15:00:04 +00:00
|
|
|
MOZ_FOR_EACH_SEPARATED(ACCESS_PARAM_FIELD, (, ), (), \
|
|
|
|
(__VA_ARGS__))); \
|
|
|
|
} \
|
|
|
|
};
|
|
|
|
|
2020-01-22 07:31:51 +00:00
|
|
|
#define DEFINE_IPC_SERIALIZER_WITHOUT_FIELDS(Type) \
|
|
|
|
template <> \
|
|
|
|
struct ParamTraits<Type> : public EmptyStructSerializer<Type> {};
|
|
|
|
|
2009-06-29 18:38:29 +00:00
|
|
|
} /* namespace IPC */
|
|
|
|
|
2020-06-10 16:34:25 +00:00
|
|
|
#define DEFINE_IPC_SERIALIZER_WITH_SUPER_CLASS_AND_FIELDS(Type, Super, ...) \
|
|
|
|
template <> \
|
|
|
|
struct ParamTraits<Type> { \
|
|
|
|
typedef Type paramType; \
|
2022-03-04 15:39:41 +00:00
|
|
|
static void Write(MessageWriter* aWriter, const paramType& aParam) { \
|
|
|
|
WriteParam(aWriter, static_cast<const Super&>(aParam)); \
|
|
|
|
WriteParams(aWriter, MOZ_FOR_EACH_SEPARATED(ACCESS_PARAM_FIELD, (, ), \
|
|
|
|
(), (__VA_ARGS__))); \
|
2020-06-10 16:34:25 +00:00
|
|
|
} \
|
|
|
|
\
|
2022-03-04 15:39:41 +00:00
|
|
|
static bool Read(MessageReader* aReader, paramType* aResult) { \
|
2020-06-10 16:34:25 +00:00
|
|
|
paramType& aParam = *aResult; \
|
2022-03-04 15:39:41 +00:00
|
|
|
return ReadParam(aReader, static_cast<Super*>(aResult)) && \
|
|
|
|
ReadParams(aReader, \
|
2020-06-10 16:34:25 +00:00
|
|
|
MOZ_FOR_EACH_SEPARATED(ACCESS_PARAM_FIELD, (, ), (), \
|
|
|
|
(__VA_ARGS__))); \
|
|
|
|
} \
|
|
|
|
};
|
|
|
|
|
2009-06-29 18:38:29 +00:00
|
|
|
#endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */
|