/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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/. */ #ifndef __IPC_GLUE_ENUMSERIALIZER_H__ #define __IPC_GLUE_ENUMSERIALIZER_H__ #include "CrashAnnotations.h" #include "chrome/common/ipc_message_utils.h" #include "mozilla/Assertions.h" #include "mozilla/IntegerTypeTraits.h" #include "nsExceptionHandler.h" #include "nsLiteralString.h" #include "nsString.h" #include "nsTLiteralString.h" class PickleIterator; namespace IPC { class Message; } #ifdef _MSC_VER # pragma warning(disable : 4800) #endif namespace IPC { /** * Generic enum serializer. * * Consider using the specializations below, such as ContiguousEnumSerializer. * * This is a generic serializer for any enum type used in IPDL. * Programmers can define ParamTraits for enum type E by deriving * EnumSerializer where MyEnumValidator is a struct * that has to define a static IsLegalValue function returning whether * a given value is a legal value of the enum type at hand. * * \sa https://developer.mozilla.org/en/IPDL/Type_Serialization */ template struct EnumSerializer { typedef E paramType; typedef typename mozilla::UnsignedStdintTypeForSize::Type uintParamType; static void Write(Message* aMsg, const paramType& aValue) { MOZ_RELEASE_ASSERT(EnumValidator::IsLegalValue(aValue)); WriteParam(aMsg, uintParamType(aValue)); } static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) { uintParamType value; if (!ReadParam(aMsg, aIter, &value)) { CrashReporter::AnnotateCrashReport( CrashReporter::Annotation::IPCReadErrorReason, "Bad iter"_ns); return false; } else if (!EnumValidator::IsLegalValue(paramType(value))) { CrashReporter::AnnotateCrashReport( CrashReporter::Annotation::IPCReadErrorReason, "Illegal value"_ns); return false; } *aResult = paramType(value); return true; } }; template class ContiguousEnumValidator { // Silence overzealous -Wtype-limits bug in GCC fixed in GCC 4.8: // "comparison of unsigned expression >= 0 is always true" // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11856 template static bool IsLessThanOrEqual(T a, T b) { return a <= b; } public: static bool IsLegalValue(E e) { return IsLessThanOrEqual(MinLegal, e) && e < HighBound; } }; template class ContiguousEnumValidatorInclusive { // Silence overzealous -Wtype-limits bug in GCC fixed in GCC 4.8: // "comparison of unsigned expression >= 0 is always true" // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11856 template static bool IsLessThanOrEqual(T a, T b) { return a <= b; } public: static bool IsLegalValue(E e) { return IsLessThanOrEqual(MinLegal, e) && e <= MaxLegal; } }; template struct BitFlagsEnumValidator { static bool IsLegalValue(E e) { return (e & AllBits) == e; } }; /** * Specialization of EnumSerializer for enums with contiguous enum values. * * Provide two values: MinLegal, HighBound. An enum value x will be * considered legal if MinLegal <= x < HighBound. * * For example, following is definition of serializer for enum type FOO. * \code * enum FOO { FOO_FIRST, FOO_SECOND, FOO_LAST, NUM_FOO }; * * template <> * struct ParamTraits: * public ContiguousEnumSerializer {}; * \endcode * FOO_FIRST, FOO_SECOND, and FOO_LAST are valid value. */ template struct ContiguousEnumSerializer : EnumSerializer> {}; /** * This is similar to ContiguousEnumSerializer, but the last template * parameter is expected to be the highest legal value, rather than a * sentinel value. This is intended to support enumerations that don't * have sentinel values. */ template struct ContiguousEnumSerializerInclusive : EnumSerializer> { }; /** * Specialization of EnumSerializer for enums representing bit flags. * * Provide one value: AllBits. An enum value x will be * considered legal if (x & AllBits) == x; * * Example: * \code * enum FOO { * FOO_FIRST = 1 << 0, * FOO_SECOND = 1 << 1, * FOO_LAST = 1 << 2, * ALL_BITS = (1 << 3) - 1 * }; * * template <> * struct ParamTraits: * public BitFlagsEnumSerializer {}; * \endcode */ template struct BitFlagsEnumSerializer : EnumSerializer> {}; } /* namespace IPC */ #endif /* __IPC_GLUE_ENUMSERIALIZER_H__ */