1/*
2 * Copyright (C) 2010, 2011 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#import "config.h"
27#import "WebPreferences.h"
28
29#import "StringUtilities.h"
30#import "WebPreferencesKeys.h"
31#import <wtf/text/StringConcatenate.h>
32
33namespace WebKit {
34
35static inline NSString* makeKey(NSString *identifier, NSString *keyPrefix, NSString *key)
36{
37    ASSERT(identifier.length);
38    ASSERT(keyPrefix);
39    ASSERT(key);
40
41    return [NSString stringWithFormat:@"%@%@%@", identifier, keyPrefix, key];
42}
43
44bool WebPreferences::platformGetStringUserValueForKey(const String& key, String& userValue)
45{
46    if (!m_identifier)
47        return false;
48
49    id object = [[NSUserDefaults standardUserDefaults] objectForKey:makeKey(m_identifier, m_keyPrefix, key)];
50    if (!object)
51        return false;
52    if (![object isKindOfClass:[NSString class]])
53        return false;
54
55    userValue = (NSString *)object;
56    return true;
57}
58
59bool WebPreferences::platformGetBoolUserValueForKey(const String& key, bool& userValue)
60{
61    if (!m_identifier)
62        return false;
63
64    id object = [[NSUserDefaults standardUserDefaults] objectForKey:makeKey(m_identifier, m_keyPrefix, key)];
65    if (!object)
66        return false;
67    if (![object respondsToSelector:@selector(boolValue)])
68        return false;
69
70    userValue = [object boolValue];
71    return true;
72}
73
74bool WebPreferences::platformGetUInt32UserValueForKey(const String& key, uint32_t& userValue)
75{
76    if (!m_identifier)
77        return false;
78
79    id object = [[NSUserDefaults standardUserDefaults] objectForKey:makeKey(m_identifier, m_keyPrefix, key)];
80    if (!object)
81        return false;
82    if (![object respondsToSelector:@selector(intValue)])
83        return false;
84
85    userValue = [object intValue];
86    return true;
87}
88
89bool WebPreferences::platformGetDoubleUserValueForKey(const String& key, double& userValue)
90{
91    if (!m_identifier)
92        return false;
93
94    id object = [[NSUserDefaults standardUserDefaults] objectForKey:makeKey(m_identifier, m_keyPrefix, key)];
95    if (!object)
96        return false;
97    if (![object respondsToSelector:@selector(doubleValue)])
98        return false;
99
100    userValue = [object doubleValue];
101    return true;
102}
103
104static id debugUserDefaultsValue(NSString *identifier, NSString *keyPrefix, NSString *globalDebugKeyPrefix, NSString *key)
105{
106    ASSERT(keyPrefix);
107    ASSERT(key);
108
109    NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
110    id object = nil;
111
112    if (identifier.length)
113        object = [standardUserDefaults objectForKey:[NSString stringWithFormat:@"%@%@%@", identifier, keyPrefix, key]];
114
115    if (!object) {
116        // Allow debug preferences to be set globally, using the debug key prefix.
117        object = [standardUserDefaults objectForKey:[globalDebugKeyPrefix stringByAppendingString:key]];
118    }
119
120    return object;
121}
122
123static void setDebugBoolValueIfInUserDefaults(const String& identifier, const String& keyPrefix, const String& globalDebugKeyPrefix, const String& key, WebPreferencesStore& store)
124{
125    id object = debugUserDefaultsValue(identifier, keyPrefix, globalDebugKeyPrefix, key);
126    if (!object)
127        return;
128    if (![object respondsToSelector:@selector(boolValue)])
129        return;
130
131    store.setBoolValueForKey(key, [object boolValue]);
132}
133
134void WebPreferences::platformInitializeStore()
135{
136#define INITIALIZE_DEBUG_PREFERENCE_FROM_NSUSERDEFAULTS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) \
137    setDebug##TypeName##ValueIfInUserDefaults(m_identifier, m_keyPrefix, m_globalDebugKeyPrefix, WebPreferencesKey::KeyLower##Key(), m_store);
138
139    FOR_EACH_WEBKIT_DEBUG_PREFERENCE(INITIALIZE_DEBUG_PREFERENCE_FROM_NSUSERDEFAULTS)
140
141#undef INITIALIZE_DEBUG_PREFERENCE_FROM_NSUSERDEFAULTS
142
143    if (!m_identifier)
144        return;
145
146#define INITIALIZE_PREFERENCE_FROM_NSUSERDEFAULTS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) \
147    Type user##KeyUpper##Value; \
148    if (platformGet##TypeName##UserValueForKey(WebPreferencesKey::KeyLower##Key(), user##KeyUpper##Value)) \
149        m_store.set##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key(), user##KeyUpper##Value);
150
151    FOR_EACH_WEBKIT_PREFERENCE(INITIALIZE_PREFERENCE_FROM_NSUSERDEFAULTS)
152
153#undef INITIALIZE_PREFERENCE_FROM_NSUSERDEFAULTS
154}
155
156void WebPreferences::platformUpdateStringValueForKey(const String& key, const String& value)
157{
158    if (!m_identifier)
159        return;
160
161    [[NSUserDefaults standardUserDefaults] setObject:nsStringFromWebCoreString(value) forKey:makeKey(m_identifier, m_keyPrefix, key)];
162}
163
164void WebPreferences::platformUpdateBoolValueForKey(const String& key, bool value)
165{
166    if (!m_identifier)
167        return;
168
169    [[NSUserDefaults standardUserDefaults] setBool:value forKey:makeKey(m_identifier, m_keyPrefix, key)];
170}
171
172void WebPreferences::platformUpdateUInt32ValueForKey(const String& key, uint32_t value)
173{
174    if (!m_identifier)
175        return;
176
177    [[NSUserDefaults standardUserDefaults] setInteger:value forKey:makeKey(m_identifier, m_keyPrefix, key)];
178}
179
180void WebPreferences::platformUpdateDoubleValueForKey(const String& key, double value)
181{
182    if (!m_identifier)
183        return;
184
185    [[NSUserDefaults standardUserDefaults] setDouble:value forKey:makeKey(m_identifier, m_keyPrefix, key)];
186}
187
188void WebPreferences::platformUpdateFloatValueForKey(const String& key, float value)
189{
190    if (!m_identifier)
191        return;
192
193    [[NSUserDefaults standardUserDefaults] setFloat:value forKey:makeKey(m_identifier, m_keyPrefix, key)];
194}
195
196} // namespace WebKit
197