Allow modern decoding of enums and OptionSets
authorachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Sep 2017 21:57:18 +0000 (21:57 +0000)
committerachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Sep 2017 21:57:18 +0000 (21:57 +0000)
https://bugs.webkit.org/show_bug.cgi?id=176480

Reviewed by Andy Estes.

* Platform/IPC/ArgumentCoders.h:
(IPC::ArgumentCoder<OptionSet<T>>::decode):
* Platform/IPC/Decoder.h:
(IPC::Decoder::operator>>):
* Platform/IPC/Encoder.h:
* Shared/WebsitePolicies.h:
(WebKit::WebsitePolicies::encode const):
(WebKit::WebsitePolicies::decode):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221760 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/ChangeLog
Source/WebKit/Platform/IPC/ArgumentCoders.h
Source/WebKit/Platform/IPC/Decoder.h
Source/WebKit/Platform/IPC/Encoder.h
Source/WebKit/Shared/WebsitePolicies.h

index 380a492..90ff6e4 100644 (file)
@@ -1,3 +1,19 @@
+2017-09-07  Alex Christensen  <achristensen@webkit.org>
+
+        Allow modern decoding of enums and OptionSets
+        https://bugs.webkit.org/show_bug.cgi?id=176480
+
+        Reviewed by Andy Estes.
+
+        * Platform/IPC/ArgumentCoders.h:
+        (IPC::ArgumentCoder<OptionSet<T>>::decode):
+        * Platform/IPC/Decoder.h:
+        (IPC::Decoder::operator>>):
+        * Platform/IPC/Encoder.h:
+        * Shared/WebsitePolicies.h:
+        (WebKit::WebsitePolicies::encode const):
+        (WebKit::WebsitePolicies::decode):
+
 2017-09-07  Frederic Wang  <fwang@igalia.com>
 
          Move more code from ScrollingTreeScrollingNodeDelegateIOS to ScrollingTreeScrollingNodeDelegate
index 3732183..d2d0521 100644 (file)
@@ -69,6 +69,15 @@ template<typename T> struct ArgumentCoder<OptionSet<T>> {
         optionSet = OptionSet<T>::fromRaw(value);
         return true;
     }
+
+    static std::optional<OptionSet<T>> decode(Decoder& decoder)
+    {
+        std::optional<uint64_t> value;
+        decoder >> value;
+        if (!value)
+            return std::nullopt;
+        return OptionSet<T>::fromRaw(*value);
+    }
 };
 
 template<typename T> struct ArgumentCoder<std::optional<T>> {
index fbb426e..fea81d8 100644 (file)
@@ -109,6 +109,16 @@ public:
         return true;
     }
 
+    template<typename E, std::enable_if_t<std::is_enum<E>::value>* = nullptr>
+    Decoder& operator>>(std::optional<E>& optional)
+    {
+        std::optional<uint64_t> value;
+        *this >> value;
+        if (value && isValidEnum<E>(*value))
+            optional = static_cast<E>(*value);
+        return *this;
+    }
+
     template<typename T> bool decodeEnum(T& result)
     {
         static_assert(sizeof(T) <= 8, "Enum type T must not be larger than 64 bits!");
index 92f9ba2..d8425af 100644 (file)
@@ -65,13 +65,21 @@ public:
         encode(static_cast<uint64_t>(t));
     }
 
-    template<typename T>
-    auto encode(T&& t) -> std::enable_if_t<!std::is_enum<typename std::remove_const_t<std::remove_reference_t<T>>>::value>
+    template<typename T, std::enable_if_t<!std::is_enum<typename std::remove_const_t<std::remove_reference_t<T>>>::value>* = nullptr>
+    void encode(T&& t)
     {
         ArgumentCoder<typename std::remove_const<typename std::remove_reference<T>::type>::type>::encode(*this, std::forward<T>(t));
     }
 
-    template<typename T> Encoder& operator<<(T&& t)
+    template<typename T, std::enable_if_t<std::is_enum<T>::value>* = nullptr>
+    Encoder& operator<<(T&& t)
+    {
+        encode(static_cast<uint64_t>(t));
+        return *this;
+    }
+
+    template<typename T, std::enable_if_t<!std::is_enum<T>::value>* = nullptr>
+    Encoder& operator<<(T&& t)
     {
         encode(std::forward<T>(t));
         return *this;
index 4019490..0f0151d 100644 (file)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include <wtf/EnumTraits.h>
 #include <wtf/OptionSet.h>
 #include <wtf/Optional.h>
 
@@ -52,28 +53,53 @@ struct WebsitePolicies {
     template<class Decoder> static std::optional<WebsitePolicies> decode(Decoder&);
 };
 
+} // namespace WebKit
+
+namespace WTF {
+
+template<> struct EnumTraits<WebKit::WebsiteAutoplayPolicy> {
+    using values = EnumValues<
+        WebKit::WebsiteAutoplayPolicy,
+        WebKit::WebsiteAutoplayPolicy::Default,
+        WebKit::WebsiteAutoplayPolicy::Allow,
+        WebKit::WebsiteAutoplayPolicy::AllowWithoutSound,
+        WebKit::WebsiteAutoplayPolicy::Deny
+    >;
+};
+
+} // namespace WTF
+
+namespace WebKit {
+
 template<class Encoder> void WebsitePolicies::encode(Encoder& encoder) const
 {
     encoder << contentBlockersEnabled;
-    encoder.encodeEnum(autoplayPolicy);
+    encoder << autoplayPolicy;
     encoder << allowedAutoplayQuirks;
 }
 
 template<class Decoder> std::optional<WebsitePolicies> WebsitePolicies::decode(Decoder& decoder)
 {
-    bool contentBlockersEnabled;
-    if (!decoder.decode(contentBlockersEnabled))
+    std::optional<bool> contentBlockersEnabled;
+    decoder >> contentBlockersEnabled;
+    if (!contentBlockersEnabled)
         return std::nullopt;
     
-    WebsiteAutoplayPolicy autoplayPolicy;
-    if (!decoder.decodeEnum(autoplayPolicy))
+    std::optional<WebsiteAutoplayPolicy> autoplayPolicy;
+    decoder >> autoplayPolicy;
+    if (!autoplayPolicy)
         return std::nullopt;
 
-    OptionSet<WebsiteAutoplayQuirk> allowedAutoplayQuirks;
-    if (!decoder.decode(allowedAutoplayQuirks))
+    std::optional<OptionSet<WebsiteAutoplayQuirk>> allowedAutoplayQuirks;
+    decoder >> allowedAutoplayQuirks;
+    if (!allowedAutoplayQuirks)
         return std::nullopt;
 
-    return { { contentBlockersEnabled, allowedAutoplayQuirks, autoplayPolicy } };
+    return { {
+        WTFMove(*contentBlockersEnabled),
+        WTFMove(*allowedAutoplayQuirks),
+        WTFMove(*autoplayPolicy),
+    } };
 }
 
 } // namespace WebKit