1/*
2 * Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef WebPreferencesStore_h
27#define WebPreferencesStore_h
28
29#include "ArgumentDecoder.h"
30#include "ArgumentEncoder.h"
31#include <wtf/HashMap.h>
32#include <wtf/text/StringHash.h>
33#include <wtf/text/WTFString.h>
34
35namespace WebKit {
36
37struct WebPreferencesStore {
38    WebPreferencesStore();
39
40    void encode(IPC::ArgumentEncoder&) const;
41    static bool decode(IPC::ArgumentDecoder&, WebPreferencesStore&);
42
43    // NOTE: The getters in this class have non-standard names to aid in the use of the preference macros.
44
45    bool setStringValueForKey(const String& key, const String& value);
46    String getStringValueForKey(const String& key) const;
47
48    bool setBoolValueForKey(const String& key, bool value);
49    bool getBoolValueForKey(const String& key) const;
50
51    bool setUInt32ValueForKey(const String& key, uint32_t value);
52    uint32_t getUInt32ValueForKey(const String& key) const;
53
54    bool setDoubleValueForKey(const String& key, double value);
55    double getDoubleValueForKey(const String& key) const;
56
57    void setOverrideDefaultsStringValueForKey(const String& key, String value);
58    void setOverrideDefaultsBoolValueForKey(const String& key, bool value);
59    void setOverrideDefaultsUInt32ValueForKey(const String& key, uint32_t value);
60    void setOverrideDefaultsDoubleValueForKey(const String& key, double value);
61
62    // For WebKitTestRunner usage.
63    static void overrideBoolValueForKey(const String& key, bool value);
64    static void removeTestRunnerOverrides();
65
66    struct Value {
67        enum class Type {
68            None,
69            String,
70            Bool,
71            UInt32,
72            Double,
73        };
74
75        void encode(IPC::ArgumentEncoder&) const;
76        static bool decode(IPC::ArgumentDecoder&, Value&);
77
78        explicit Value() : m_type(Type::None) { }
79        explicit Value(const String& value) : m_type(Type::String), m_string(value) { }
80        explicit Value(bool value) : m_type(Type::Bool), m_bool(value) { }
81        explicit Value(uint32_t value) : m_type(Type::UInt32), m_uint32(value) { }
82        explicit Value(double value) : m_type(Type::Double), m_double(value) { }
83
84        Value(Value&& value)
85            : m_type(value.m_type)
86        {
87            switch (m_type) {
88            case Type::None:
89                break;
90            case Type::String:
91                new (&m_string) String(WTF::move(value.m_string));
92                break;
93            case Type::Bool:
94                m_bool = value.m_bool;
95                break;
96            case Type::UInt32:
97                m_uint32 = value.m_uint32;
98                break;
99            case Type::Double:
100                m_double = value.m_double;
101                break;
102            }
103        }
104
105        Value& operator=(const Value& other)
106        {
107            if (this == &other)
108                return *this;
109
110            destroy();
111
112            m_type = other.m_type;
113            switch (m_type) {
114            case Type::None:
115                break;
116            case Type::String:
117                new (&m_string) String(other.m_string);
118                break;
119            case Type::Bool:
120                m_bool = other.m_bool;
121                break;
122            case Type::UInt32:
123                m_uint32 = other.m_uint32;
124                break;
125            case Type::Double:
126                m_double = other.m_double;
127                break;
128            }
129
130            return *this;
131        }
132
133        ~Value()
134        {
135            destroy();
136        }
137
138        Type type() const { return m_type; }
139
140        String asString() const
141        {
142            ASSERT(m_type == Type::String);
143            return m_string;
144        }
145
146        bool asBool() const
147        {
148            ASSERT(m_type == Type::Bool);
149            return m_bool;
150        }
151
152        uint32_t asUInt32() const
153        {
154            ASSERT(m_type == Type::UInt32);
155            return m_uint32;
156        }
157
158        double asDouble() const
159        {
160            ASSERT(m_type == Type::Double);
161            return m_double;
162        }
163
164    private:
165        void destroy()
166        {
167            if (m_type == Type::String)
168                m_string.~String();
169        }
170
171        Type m_type;
172        union {
173            String m_string;
174            bool m_bool;
175            uint32_t m_uint32;
176            double m_double;
177        };
178    };
179
180    typedef HashMap<String, Value> ValueMap;
181    ValueMap m_values;
182    ValueMap m_overridenDefaults;
183};
184
185} // namespace WebKit
186
187#endif // WebPreferencesStore_h
188