Implement KeyedDecoderGeneric and KeyedEncoderGeneric
authorHironori.Fujii@sony.com <Hironori.Fujii@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 Apr 2019 04:26:49 +0000 (04:26 +0000)
committerHironori.Fujii@sony.com <Hironori.Fujii@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 Apr 2019 04:26:49 +0000 (04:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=186410

Reviewed by Don Olmstead.

Implemented KeyedDecoderGeneric and KeyedEncoderGeneric by using
WTF::Persistence::Decoder and WTF::Persistence::Encoder.

No new tests. Covered by existing tests.

* PlatformWin.cmake: Added KeyedDecoderGeneric.cpp and
KeyedEncoderGeneric.cpp, and removed KeyedDecoderCF.cpp and
KeyedEncoderCF.cpp for WinCairo port.
* platform/generic/KeyedDecoderGeneric.cpp:
* platform/generic/KeyedDecoderGeneric.h:
* platform/generic/KeyedEncoderGeneric.cpp:
* platform/generic/KeyedEncoderGeneric.h:

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

Source/WebCore/ChangeLog
Source/WebCore/PlatformWin.cmake
Source/WebCore/platform/generic/KeyedDecoderGeneric.cpp
Source/WebCore/platform/generic/KeyedDecoderGeneric.h
Source/WebCore/platform/generic/KeyedEncoderGeneric.cpp
Source/WebCore/platform/generic/KeyedEncoderGeneric.h

index b882770..70bec1c 100644 (file)
@@ -1,3 +1,23 @@
+2019-04-18  Fujii Hironori  <Hironori.Fujii@sony.com>
+
+        Implement KeyedDecoderGeneric and KeyedEncoderGeneric
+        https://bugs.webkit.org/show_bug.cgi?id=186410
+
+        Reviewed by Don Olmstead.
+
+        Implemented KeyedDecoderGeneric and KeyedEncoderGeneric by using
+        WTF::Persistence::Decoder and WTF::Persistence::Encoder.
+
+        No new tests. Covered by existing tests.
+
+        * PlatformWin.cmake: Added KeyedDecoderGeneric.cpp and
+        KeyedEncoderGeneric.cpp, and removed KeyedDecoderCF.cpp and
+        KeyedEncoderCF.cpp for WinCairo port.
+        * platform/generic/KeyedDecoderGeneric.cpp:
+        * platform/generic/KeyedDecoderGeneric.h:
+        * platform/generic/KeyedEncoderGeneric.cpp:
+        * platform/generic/KeyedEncoderGeneric.h:
+
 2019-04-18  Ross Kirsling  <ross.kirsling@sony.com>
 
         [WinCairo] Non-unified build fails to link Tools
index 0e91f6c..bdc70cd 100644 (file)
@@ -165,8 +165,6 @@ if (USE_CF)
 
         loader/archive/cf/LegacyWebArchive.cpp
 
-        platform/cf/KeyedDecoderCF.cpp
-        platform/cf/KeyedEncoderCF.cpp
         platform/cf/SharedBufferCF.cpp
 
         platform/cf/win/CertificateCFWin.cpp
@@ -184,10 +182,19 @@ if (USE_CF)
     list(APPEND WebCoreTestSupport_LIBRARIES ${COREFOUNDATION_LIBRARY})
 else ()
     list(APPEND WebCore_SOURCES
+        platform/text/Hyphenation.cpp
+    )
+endif ()
+
+if (USE_CF AND NOT WTF_PLATFORM_WIN_CAIRO)
+    list(APPEND WebCore_SOURCES
+        platform/cf/KeyedDecoderCF.cpp
+        platform/cf/KeyedEncoderCF.cpp
+    )
+else ()
+    list(APPEND WebCore_SOURCES
         platform/generic/KeyedDecoderGeneric.cpp
         platform/generic/KeyedEncoderGeneric.cpp
-
-        platform/text/Hyphenation.cpp
     )
 endif ()
 
index ecdfeed..a4a30b5 100644 (file)
 #include "config.h"
 #include "KeyedDecoderGeneric.h"
 
+#include "KeyedEncoderGeneric.h"
+#include <wtf/HashMap.h>
+#include <wtf/Variant.h>
+#include <wtf/Vector.h>
+#include <wtf/persistence/PersistentDecoder.h>
+#include <wtf/text/StringHash.h>
+
 namespace WebCore {
 
-// FIXME: https://bugs.webkit.org/show_bug.cgi?id=186410
-std::unique_ptr<KeyedDecoder> KeyedDecoder::decoder(const uint8_t* data, size_t size)
+class KeyedDecoderGeneric::Dictionary {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    using Node = Variant<Vector<uint8_t>, bool, uint32_t, uint64_t, int32_t, int64_t, float, double, String, std::unique_ptr<Dictionary>, std::unique_ptr<Array>>;
+
+    template <typename T>
+    void add(const String& key, T&& value) { m_map.add(key, std::make_unique<Node>(std::forward<T>(value))); }
+    Node& get(const String& key) { return *m_map.get(key); }
+
+private:
+    HashMap<String, std::unique_ptr<Node>> m_map;
+};
+
+static bool readString(WTF::Persistence::Decoder& decoder, String& result)
 {
-    return std::make_unique<KeyedDecoderGeneric>(data, size);
+    size_t size;
+    if (!decoder.decode(size))
+        return false;
+    Vector<uint8_t> buffer(size);
+    if (!decoder.decodeFixedLengthData(buffer.data(), size))
+        return false;
+    result = String::fromUTF8(buffer.data(), size);
+    return true;
+}
+
+template<typename T>
+static bool readSimpleValue(WTF::Persistence::Decoder& decoder, KeyedDecoderGeneric::Dictionary& dictionary)
+{
+    String key;
+    bool ok = readString(decoder, key);
+    if (!ok)
+        return false;
+    T value;
+    ok = decoder.decode(value);
+    if (!ok)
+        return false;
+    dictionary.add(key, WTFMove(value));
+    return true;
 }
 
-KeyedDecoderGeneric::KeyedDecoderGeneric(const uint8_t*, size_t)
+std::unique_ptr<KeyedDecoder> KeyedDecoder::decoder(const uint8_t* data, size_t size)
 {
+    return std::make_unique<KeyedDecoderGeneric>(data, size);
 }
 
-KeyedDecoderGeneric::~KeyedDecoderGeneric()
+KeyedDecoderGeneric::KeyedDecoderGeneric(const uint8_t* data, size_t size)
 {
+    WTF::Persistence::Decoder decoder(data, size);
+    KeyedEncoderGeneric::Type type;
+    String key;
+
+    m_rootDictionary = std::make_unique<Dictionary>();
+    m_dictionaryStack.append(m_rootDictionary.get());
+
+    bool ok = true;
+    while (ok && decoder.decodeEnum(type)) {
+        switch (type) {
+        case KeyedEncoderGeneric::Type::Bytes: {
+            ok = readString(decoder, key);
+            if (!ok)
+                break;
+            size_t size;
+            ok = decoder.decode(size);
+            if (!ok)
+                break;
+            Vector<uint8_t> buffer(size);
+            ok = decoder.decodeFixedLengthData(buffer.data(), size);
+            if (!ok)
+                break;
+            m_dictionaryStack.last()->add(key, WTFMove(buffer));
+            break;
+        }
+        case KeyedEncoderGeneric::Type::Bool:
+            ok = readSimpleValue<bool>(decoder, *m_dictionaryStack.last());
+            break;
+        case KeyedEncoderGeneric::Type::UInt32:
+            ok = readSimpleValue<uint32_t>(decoder, *m_dictionaryStack.last());
+            break;
+        case KeyedEncoderGeneric::Type::UInt64:
+            ok = readSimpleValue<uint64_t>(decoder, *m_dictionaryStack.last());
+            break;
+        case KeyedEncoderGeneric::Type::Int32:
+            ok = readSimpleValue<int32_t>(decoder, *m_dictionaryStack.last());
+            break;
+        case KeyedEncoderGeneric::Type::Int64:
+            ok = readSimpleValue<int64_t>(decoder, *m_dictionaryStack.last());
+            break;
+        case KeyedEncoderGeneric::Type::Float:
+            ok = readSimpleValue<float>(decoder, *m_dictionaryStack.last());
+            break;
+        case KeyedEncoderGeneric::Type::Double:
+            ok = readSimpleValue<double>(decoder, *m_dictionaryStack.last());
+            break;
+        case KeyedEncoderGeneric::Type::String: {
+            ok = readString(decoder, key);
+            if (!ok)
+                break;
+            String value;
+            ok = readString(decoder, value);
+            if (!ok)
+                break;
+            m_dictionaryStack.last()->add(key, WTFMove(value));
+            break;
+        }
+        case KeyedEncoderGeneric::Type::BeginObject: {
+            ok = readString(decoder, key);
+            if (!ok)
+                break;
+            auto* currentDictinary = m_dictionaryStack.last();
+            auto newDictionary = std::make_unique<Dictionary>();
+            m_dictionaryStack.append(newDictionary.get());
+            currentDictinary->add(key, WTFMove(newDictionary));
+            break;
+        }
+        case KeyedEncoderGeneric::Type::EndObject:
+            m_dictionaryStack.removeLast();
+            break;
+        case KeyedEncoderGeneric::Type::BeginArray: {
+            ok = readString(decoder, key);
+            if (!ok)
+                break;
+            auto newArray = std::make_unique<Array>();
+            m_arrayStack.append(newArray.get());
+            m_dictionaryStack.last()->add(key, WTFMove(newArray));
+            break;
+        }
+        case KeyedEncoderGeneric::Type::BeginArrayElement: {
+            auto newDictionary = std::make_unique<Dictionary>();
+            m_dictionaryStack.append(newDictionary.get());
+            m_arrayStack.last()->append(WTFMove(newDictionary));
+            break;
+        }
+        case KeyedEncoderGeneric::Type::EndArrayElement:
+            m_dictionaryStack.removeLast();
+            break;
+        case KeyedEncoderGeneric::Type::EndArray:
+            m_arrayStack.removeLast();
+            break;
+        }
+    }
+    while (m_dictionaryStack.size() > 1)
+        m_dictionaryStack.removeLast();
+    while (!m_arrayStack.isEmpty())
+        m_arrayStack.removeLast();
 }
 
-bool KeyedDecoderGeneric::decodeBytes(const String&, const uint8_t*&, size_t&)
+bool KeyedDecoderGeneric::decodeBytes(const String& key, const uint8_t*& data, size_t& size)
 {
-    return false;
+    auto* value = WTF::get_if<Vector<uint8_t>>(m_dictionaryStack.last()->get(key));
+    if (!value)
+        return false;
+    data = value->data();
+    size = value->size();
+    return true;
 }
 
-bool KeyedDecoderGeneric::decodeBool(const String&, bool&)
+bool KeyedDecoderGeneric::decodeBool(const String& key, bool& result)
 {
-    return false;
+    auto* value = WTF::get_if<bool>(m_dictionaryStack.last()->get(key));
+    if (!value)
+        return false;
+    result = *value;
+    return true;
 }
 
-bool KeyedDecoderGeneric::decodeUInt32(const String&, uint32_t&)
+bool KeyedDecoderGeneric::decodeUInt32(const String& key, uint32_t& result)
 {
-    return false;
+    auto* value = WTF::get_if<uint32_t>(m_dictionaryStack.last()->get(key));
+    if (!value)
+        return false;
+    result = *value;
+    return true;
 }
 
-bool KeyedDecoderGeneric::decodeUInt64(const String&, uint64_t&)
+bool KeyedDecoderGeneric::decodeUInt64(const String& key, uint64_t& result)
 {
-    return false;
+    auto* value = WTF::get_if<uint64_t>(m_dictionaryStack.last()->get(key));
+    if (!value)
+        return false;
+    result = *value;
+    return true;
 }
 
-bool KeyedDecoderGeneric::decodeInt32(const String&, int32_t&)
+bool KeyedDecoderGeneric::decodeInt32(const String& key, int32_t& result)
 {
-    return false;
+    auto* value = WTF::get_if<int32_t>(m_dictionaryStack.last()->get(key));
+    if (!value)
+        return false;
+    result = *value;
+    return true;
 }
 
-bool KeyedDecoderGeneric::decodeInt64(const String&, int64_t&)
+bool KeyedDecoderGeneric::decodeInt64(const String& key, int64_t& result)
 {
-    return false;
+    auto* value = WTF::get_if<int64_t>(m_dictionaryStack.last()->get(key));
+    if (!value)
+        return false;
+    result = *value;
+    return true;
 }
 
-bool KeyedDecoderGeneric::decodeFloat(const String&, float&)
+bool KeyedDecoderGeneric::decodeFloat(const String& key, float& result)
 {
-    return false;
+    auto* value = WTF::get_if<float>(m_dictionaryStack.last()->get(key));
+    if (!value)
+        return false;
+    result = *value;
+    return true;
 }
 
-bool KeyedDecoderGeneric::decodeDouble(const String&, double&)
+bool KeyedDecoderGeneric::decodeDouble(const String& key, double& result)
 {
-    return false;
+    auto* value = WTF::get_if<double>(m_dictionaryStack.last()->get(key));
+    if (!value)
+        return false;
+    result = *value;
+    return true;
 }
 
-bool KeyedDecoderGeneric::decodeString(const String&, String&)
+bool KeyedDecoderGeneric::decodeString(const String& key, String& result)
 {
-    return false;
+    auto* value = WTF::get_if<String>(m_dictionaryStack.last()->get(key));
+    if (!value)
+        return false;
+    result = *value;
+    return true;
 }
 
-bool KeyedDecoderGeneric::beginObject(const String&)
+bool KeyedDecoderGeneric::beginObject(const String& key)
 {
-    return false;
+    auto* value = WTF::get_if<std::unique_ptr<Dictionary>>(m_dictionaryStack.last()->get(key));
+    if (!value)
+        return false;
+    m_dictionaryStack.append(value->get());
+    return true;
 }
 
 void KeyedDecoderGeneric::endObject()
 {
+    m_dictionaryStack.removeLast();
 }
 
-bool KeyedDecoderGeneric::beginArray(const String&)
+bool KeyedDecoderGeneric::beginArray(const String& key)
 {
-    return false;
+    auto* value = WTF::get_if<std::unique_ptr<Array>>(m_dictionaryStack.last()->get(key));
+    if (!value)
+        return false;
+    m_arrayStack.append(value->get());
+    m_arrayIndexStack.append(0);
+    return true;
 }
 
 bool KeyedDecoderGeneric::beginArrayElement()
 {
-    return false;
+    if (m_arrayIndexStack.last() >= m_arrayStack.last()->size())
+        return false;
+
+    auto dictionary = m_arrayStack.last()->at(m_arrayIndexStack.last()++).get();
+    m_dictionaryStack.append(dictionary);
+    return true;
 }
 
 void KeyedDecoderGeneric::endArrayElement()
 {
+    m_dictionaryStack.removeLast();
 }
 
 void KeyedDecoderGeneric::endArray()
 {
+    m_arrayStack.removeLast();
+    m_arrayIndexStack.removeLast();
 }
 
 } // namespace WebCore
index 9b22b33..56a2f93 100644 (file)
@@ -32,7 +32,9 @@ namespace WebCore {
 class KeyedDecoderGeneric final : public KeyedDecoder {
 public:
     KeyedDecoderGeneric(const uint8_t* data, size_t);
-    ~KeyedDecoderGeneric() override;
+
+    class Dictionary;
+    using Array = Vector<std::unique_ptr<Dictionary>>;
 
 private:
     bool decodeBytes(const String& key, const uint8_t*&, size_t&) override;
@@ -52,6 +54,11 @@ private:
     bool beginArrayElement() override;
     void endArrayElement() override;
     void endArray() override;
+
+    std::unique_ptr<Dictionary> m_rootDictionary;
+    Vector<Dictionary*, 16> m_dictionaryStack;
+    Vector<Array*, 16> m_arrayStack;
+    Vector<size_t, 16> m_arrayIndexStack;
 };
 
 } // namespace WebCore
index 09cf5c2..2f84104 100644 (file)
 #include "KeyedEncoderGeneric.h"
 
 #include "SharedBuffer.h"
+#include <wtf/persistence/PersistentEncoder.h>
 
 namespace WebCore {
 
-// FIXME: https://bugs.webkit.org/show_bug.cgi?id=186410
 std::unique_ptr<KeyedEncoder> KeyedEncoder::encoder()
 {
     return std::make_unique<KeyedEncoderGeneric>();
 }
 
-KeyedEncoderGeneric::KeyedEncoderGeneric()
+void KeyedEncoderGeneric::encodeString(const String& key)
 {
+    auto utf8 = key.utf8();
+    m_encoder << utf8.length();
+    m_encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(utf8.data()), utf8.length());
 }
 
-KeyedEncoderGeneric::~KeyedEncoderGeneric()
+void KeyedEncoderGeneric::encodeBytes(const String& key, const uint8_t* bytes, size_t size)
 {
+    m_encoder << Type::Bytes;
+    encodeString(key);
+    m_encoder << size;
+    m_encoder.encodeFixedLengthData(bytes, size);
 }
 
-void KeyedEncoderGeneric::encodeBytes(const String&, const uint8_t*, size_t)
+void KeyedEncoderGeneric::encodeBool(const String& key, bool value)
 {
+    m_encoder << Type::Bool;
+    encodeString(key);
+    m_encoder << value;
 }
 
-void KeyedEncoderGeneric::encodeBool(const String&, bool)
+void KeyedEncoderGeneric::encodeUInt32(const String& key, uint32_t value)
 {
+    m_encoder << Type::UInt32;
+    encodeString(key);
+    m_encoder << value;
 }
 
-void KeyedEncoderGeneric::encodeUInt32(const String&, uint32_t)
+void KeyedEncoderGeneric::encodeUInt64(const String& key, uint64_t value)
 {
+    m_encoder << Type::UInt64;
+    encodeString(key);
+    m_encoder << value;
 }
 
-void KeyedEncoderGeneric::encodeUInt64(const String&, uint64_t)
+void KeyedEncoderGeneric::encodeInt32(const String& key, int32_t value)
 {
+    m_encoder << Type::Int32;
+    encodeString(key);
+    m_encoder << value;
 }
 
-void KeyedEncoderGeneric::encodeInt32(const String&, int32_t)
+void KeyedEncoderGeneric::encodeInt64(const String& key, int64_t value)
 {
+    m_encoder << Type::Int64;
+    encodeString(key);
+    m_encoder << value;
 }
 
-void KeyedEncoderGeneric::encodeInt64(const String&, int64_t)
+void KeyedEncoderGeneric::encodeFloat(const String& key, float value)
 {
+    m_encoder << Type::Float;
+    encodeString(key);
+    m_encoder << value;
 }
 
-void KeyedEncoderGeneric::encodeFloat(const String&, float)
+void KeyedEncoderGeneric::encodeDouble(const String& key, double value)
 {
+    m_encoder << Type::Double;
+    encodeString(key);
+    m_encoder << value;
 }
 
-void KeyedEncoderGeneric::encodeDouble(const String&, double)
+void KeyedEncoderGeneric::encodeString(const String& key, const String& value)
 {
+    m_encoder << Type::String;
+    encodeString(key);
+    encodeString(value);
 }
 
-void KeyedEncoderGeneric::encodeString(const String&, const String&)
-{
-}
-
-void KeyedEncoderGeneric::beginObject(const String&)
+void KeyedEncoderGeneric::beginObject(const String& key)
 {
+    m_encoder << Type::BeginObject;
+    encodeString(key);
 }
 
 void KeyedEncoderGeneric::endObject()
 {
+    m_encoder << Type::EndObject;
 }
 
-void KeyedEncoderGeneric::beginArray(const String&)
+void KeyedEncoderGeneric::beginArray(const String& key)
 {
+    m_encoder << Type::BeginArray;
+    encodeString(key);
 }
 
 void KeyedEncoderGeneric::beginArrayElement()
 {
+    m_encoder << Type::BeginArrayElement;
 }
 
 void KeyedEncoderGeneric::endArrayElement()
 {
+    m_encoder << Type::EndArrayElement;
 }
 
 void KeyedEncoderGeneric::endArray()
 {
+    m_encoder << Type::EndArray;
 }
 
 RefPtr<SharedBuffer> KeyedEncoderGeneric::finishEncoding()
 {
-    return nullptr;
+    return SharedBuffer::create(m_encoder.buffer(), m_encoder.bufferSize());
 }
 
 } // namespace WebCore
index b8c5447..e968e98 100644 (file)
@@ -26,7 +26,9 @@
 #pragma once
 
 #include "KeyedCoding.h"
+#include <wtf/Forward.h>
 #include <wtf/Vector.h>
+#include <wtf/persistence/PersistentEncoder.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
@@ -35,8 +37,24 @@ class SharedBuffer;
 
 class KeyedEncoderGeneric final : public KeyedEncoder {
 public:
-    KeyedEncoderGeneric();
-    ~KeyedEncoderGeneric();
+
+    enum class Type : uint8_t {
+        Bytes,
+        Bool,
+        UInt32,
+        UInt64,
+        Int32,
+        Int64,
+        Float,
+        Double,
+        String,
+        BeginObject,
+        EndObject,
+        BeginArray,
+        BeginArrayElement,
+        EndArrayElement,
+        EndArray,
+    };
 
 private:
     RefPtr<SharedBuffer> finishEncoding() override;
@@ -58,6 +76,34 @@ private:
     void beginArrayElement() override;
     void endArrayElement() override;
     void endArray() override;
+
+    void encodeString(const String&);
+
+    WTF::Persistence::Encoder m_encoder;
 };
 
 } // namespace WebCore
+
+namespace WTF {
+template<> struct EnumTraits<WebCore::KeyedEncoderGeneric::Type> {
+    using values = EnumValues<
+        WebCore::KeyedEncoderGeneric::Type,
+        WebCore::KeyedEncoderGeneric::Type::Bytes,
+        WebCore::KeyedEncoderGeneric::Type::Bool,
+        WebCore::KeyedEncoderGeneric::Type::UInt32,
+        WebCore::KeyedEncoderGeneric::Type::UInt64,
+        WebCore::KeyedEncoderGeneric::Type::Int32,
+        WebCore::KeyedEncoderGeneric::Type::Int64,
+        WebCore::KeyedEncoderGeneric::Type::Float,
+        WebCore::KeyedEncoderGeneric::Type::Double,
+        WebCore::KeyedEncoderGeneric::Type::String,
+        WebCore::KeyedEncoderGeneric::Type::BeginObject,
+        WebCore::KeyedEncoderGeneric::Type::EndObject,
+        WebCore::KeyedEncoderGeneric::Type::BeginArray,
+        WebCore::KeyedEncoderGeneric::Type::BeginArrayElement,
+        WebCore::KeyedEncoderGeneric::Type::EndArrayElement,
+        WebCore::KeyedEncoderGeneric::Type::EndArray
+    >;
+};
+
+} // namespace WTF