no bug - Import translations from android-l10n r=release a=l10n CLOSED TREE
[gecko.git] / ipc / glue / EnumSerializer.h
blob989e1127f51777125e4c62179124f8b99d89b385
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_ENUMSERIALIZER_H__
8 #define __IPC_GLUE_ENUMSERIALIZER_H__
10 #include "CrashAnnotations.h"
11 #include "chrome/common/ipc_message_utils.h"
12 #include "mozilla/Assertions.h"
13 #include "mozilla/IntegerTypeTraits.h"
14 #include "nsExceptionHandler.h"
15 #include "nsLiteralString.h"
16 #include "nsString.h"
17 #include "nsTLiteralString.h"
19 class PickleIterator;
21 namespace IPC {
22 class Message;
23 class MessageReader;
24 class MessageWriter;
25 } // namespace IPC
27 #ifdef _MSC_VER
28 # pragma warning(disable : 4800)
29 #endif
31 namespace IPC {
33 /**
34 * Generic enum serializer.
36 * Consider using the specializations below, such as ContiguousEnumSerializer.
38 * This is a generic serializer for any enum type used in IPDL.
39 * Programmers can define ParamTraits<E> for enum type E by deriving
40 * EnumSerializer<E, MyEnumValidator> where MyEnumValidator is a struct
41 * that has to define a static IsLegalValue function returning whether
42 * a given value is a legal value of the enum type at hand.
44 * \sa https://developer.mozilla.org/en/IPDL/Type_Serialization
46 template <typename E, typename EnumValidator>
47 struct EnumSerializer {
48 typedef E paramType;
50 // XXX(Bug 1690343) Should this be changed to
51 // std::make_unsigned_t<std::underlying_type_t<paramType>>, to make this more
52 // consistent with the type used for validating values?
53 typedef typename mozilla::UnsignedStdintTypeForSize<sizeof(paramType)>::Type
54 uintParamType;
56 static void Write(MessageWriter* aWriter, const paramType& aValue) {
57 // XXX This assertion is somewhat meaningless at least for E that don't have
58 // a fixed underlying type: if aValue weren't a legal value, we would
59 // already have UB where this function is called.
60 MOZ_RELEASE_ASSERT(EnumValidator::IsLegalValue(
61 static_cast<std::underlying_type_t<paramType>>(aValue)));
62 WriteParam(aWriter, uintParamType(aValue));
65 static bool Read(MessageReader* aReader, paramType* aResult) {
66 uintParamType value;
67 if (!ReadParam(aReader, &value)) {
68 CrashReporter::RecordAnnotationCString(
69 CrashReporter::Annotation::IPCReadErrorReason, "Bad iter");
70 return false;
71 } else if (!EnumValidator::IsLegalValue(value)) {
72 CrashReporter::RecordAnnotationCString(
73 CrashReporter::Annotation::IPCReadErrorReason, "Illegal value");
74 return false;
76 *aResult = paramType(value);
77 return true;
81 template <typename E, E MinLegal, E HighBound>
82 class ContiguousEnumValidator {
83 // Silence overzealous -Wtype-limits bug in GCC fixed in GCC 4.8:
84 // "comparison of unsigned expression >= 0 is always true"
85 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11856
86 template <typename T>
87 static bool IsLessThanOrEqual(T a, T b) {
88 return a <= b;
91 public:
92 using IntegralType = std::underlying_type_t<E>;
93 static constexpr auto kMinLegalIntegral = static_cast<IntegralType>(MinLegal);
94 static constexpr auto kHighBoundIntegral =
95 static_cast<IntegralType>(HighBound);
97 static bool IsLegalValue(const IntegralType e) {
98 return IsLessThanOrEqual(kMinLegalIntegral, e) && e < kHighBoundIntegral;
102 template <typename E, E MinLegal, E MaxLegal>
103 class ContiguousEnumValidatorInclusive {
104 // Silence overzealous -Wtype-limits bug in GCC fixed in GCC 4.8:
105 // "comparison of unsigned expression >= 0 is always true"
106 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11856
107 template <typename T>
108 static bool IsLessThanOrEqual(T a, T b) {
109 return a <= b;
112 public:
113 using IntegralType = std::underlying_type_t<E>;
114 static constexpr auto kMinLegalIntegral = static_cast<IntegralType>(MinLegal);
115 static constexpr auto kMaxLegalIntegral = static_cast<IntegralType>(MaxLegal);
117 static bool IsLegalValue(const IntegralType e) {
118 return IsLessThanOrEqual(kMinLegalIntegral, e) && e <= kMaxLegalIntegral;
122 template <typename E, E AllBits>
123 struct BitFlagsEnumValidator {
124 static bool IsLegalValue(const std::underlying_type_t<E> e) {
125 return (e & static_cast<std::underlying_type_t<E>>(AllBits)) == e;
130 * Specialization of EnumSerializer for enums with contiguous enum values.
132 * Provide two values: MinLegal, HighBound. An enum value x will be
133 * considered legal if MinLegal <= x < HighBound.
135 * For example, following is definition of serializer for enum type FOO.
136 * \code
137 * enum FOO { FOO_FIRST, FOO_SECOND, FOO_LAST, NUM_FOO };
139 * template <>
140 * struct ParamTraits<FOO>:
141 * public ContiguousEnumSerializer<FOO, FOO_FIRST, NUM_FOO> {};
142 * \endcode
143 * FOO_FIRST, FOO_SECOND, and FOO_LAST are valid value.
145 template <typename E, E MinLegal, E HighBound>
146 struct ContiguousEnumSerializer
147 : EnumSerializer<E, ContiguousEnumValidator<E, MinLegal, HighBound>> {};
150 * This is similar to ContiguousEnumSerializer, but the last template
151 * parameter is expected to be the highest legal value, rather than a
152 * sentinel value. This is intended to support enumerations that don't
153 * have sentinel values.
155 template <typename E, E MinLegal, E MaxLegal>
156 struct ContiguousEnumSerializerInclusive
157 : EnumSerializer<E,
158 ContiguousEnumValidatorInclusive<E, MinLegal, MaxLegal>> {
162 * Specialization of EnumSerializer for enums representing bit flags.
164 * Provide one value: AllBits. An enum value x will be
165 * considered legal if (x & AllBits) == x;
167 * Example:
168 * \code
169 * enum FOO {
170 * FOO_FIRST = 1 << 0,
171 * FOO_SECOND = 1 << 1,
172 * FOO_LAST = 1 << 2,
173 * ALL_BITS = (1 << 3) - 1
174 * };
176 * template <>
177 * struct ParamTraits<FOO>:
178 * public BitFlagsEnumSerializer<FOO, FOO::ALL_BITS> {};
179 * \endcode
181 template <typename E, E AllBits>
182 struct BitFlagsEnumSerializer
183 : EnumSerializer<E, BitFlagsEnumValidator<E, AllBits>> {};
185 } /* namespace IPC */
187 #endif /* __IPC_GLUE_ENUMSERIALIZER_H__ */