1af026dba45d947908544bb184b5c666ce4fb26a
[WebKit.git] / Source / WebCore / bindings / js / JSDictionary.cpp
1 /*
2  * Copyright (C) 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 #include "config.h"
27 #include "JSDictionary.h"
28
29 #include "ArrayValue.h"
30 #include "Dictionary.h"
31 #include "JSCSSFontFaceRule.h"
32 #include "JSDOMError.h"
33 #include "JSDOMWindow.h"
34 #include "JSEventTarget.h"
35 #include "JSMessagePortCustom.h"
36 #include "JSNode.h"
37 #include "JSStorage.h"
38 #include "JSTrackCustom.h"
39 #include "JSVoidCallback.h"
40 #include "SerializedScriptValue.h"
41 #include <runtime/JSTypedArrays.h>
42 #include <wtf/HashMap.h>
43 #include <wtf/MathExtras.h>
44 #include <wtf/text/AtomicString.h>
45
46 #if ENABLE(ENCRYPTED_MEDIA)
47 #include "JSMediaKeyError.h"
48 #endif
49
50 #if ENABLE(MEDIA_STREAM)
51 #include "JSMediaStream.h"
52 #include "JSMediaStreamTrack.h"
53 #endif
54
55 #if ENABLE(GAMEPAD)
56 #include "JSGamepad.h"
57 #endif
58
59 using namespace JSC;
60
61 namespace WebCore {
62
63 JSDictionary::GetPropertyResult JSDictionary::tryGetProperty(const char* propertyName, JSValue& finalResult) const
64 {
65     ASSERT(isValid());
66     Identifier identifier(m_exec, propertyName);
67     PropertySlot slot(m_initializerObject.get());
68
69     if (!m_initializerObject.get()->getPropertySlot(m_exec, identifier, slot))
70         return NoPropertyFound;
71
72     if (m_exec->hadException())
73         return ExceptionThrown;
74
75     finalResult = slot.getValue(m_exec, identifier);
76     if (m_exec->hadException())
77         return ExceptionThrown;
78
79     return PropertyFound;
80 }
81
82 void JSDictionary::convertValue(ExecState* exec, JSValue value, bool& result)
83 {
84     result = value.toBoolean(exec);
85 }
86
87 void JSDictionary::convertValue(ExecState* exec, JSValue value, int& result)
88 {
89     result = value.toInt32(exec);
90 }
91
92 void JSDictionary::convertValue(ExecState* exec, JSValue value, unsigned& result)
93 {
94     result = value.toUInt32(exec);
95 }
96
97 void JSDictionary::convertValue(ExecState* exec, JSValue value, unsigned short& result)
98 {
99     result = static_cast<unsigned short>(value.toUInt32(exec));
100 }
101
102 void JSDictionary::convertValue(ExecState* exec, JSValue value, unsigned long& result)
103 {
104     result = static_cast<unsigned long>(value.toUInt32(exec));
105 }
106
107 void JSDictionary::convertValue(ExecState* exec, JSValue value, unsigned long long& result)
108 {
109     double d = value.toNumber(exec);
110     doubleToInteger(d, result);
111 }
112
113 void JSDictionary::convertValue(ExecState* exec, JSValue value, double& result)
114 {
115     result = value.toNumber(exec);
116 }
117
118 void JSDictionary::convertValue(JSC::ExecState* exec, JSC::JSValue value, Dictionary& result)
119 {
120     result = Dictionary(exec, value);
121 }
122
123 void JSDictionary::convertValue(ExecState* exec, JSValue value, String& result)
124 {
125     result = value.toString(exec)->value(exec);
126 }
127
128 void JSDictionary::convertValue(ExecState* exec, JSValue value, Vector<String>& result)
129 {
130     if (value.isUndefinedOrNull())
131         return;
132
133     unsigned length = 0;
134     JSObject* object = toJSSequence(exec, value, length);
135     if (exec->hadException())
136         return;
137
138     for (unsigned i = 0 ; i < length; ++i) {
139         JSValue itemValue = object->get(exec, i);
140         if (exec->hadException())
141             return;
142         result.append(itemValue.toString(exec)->value(exec));
143     }
144 }
145
146 void JSDictionary::convertValue(ExecState* exec, JSValue value, Deprecated::ScriptValue& result)
147 {
148     result = Deprecated::ScriptValue(exec->vm(), value);
149 }
150
151 void JSDictionary::convertValue(ExecState* exec, JSValue value, RefPtr<SerializedScriptValue>& result)
152 {
153     result = SerializedScriptValue::create(exec, value, 0, 0);
154 }
155
156 void JSDictionary::convertValue(ExecState*, JSValue value, RefPtr<DOMWindow>& result)
157 {
158     result = toDOMWindow(value);
159 }
160
161 void JSDictionary::convertValue(ExecState*, JSValue value, RefPtr<EventTarget>& result)
162 {
163     result = toEventTarget(value);
164 }
165
166 void JSDictionary::convertValue(ExecState*, JSValue value, RefPtr<Node>& result)
167 {
168     result = toNode(value);
169 }
170
171 void JSDictionary::convertValue(ExecState*, JSValue value, RefPtr<Storage>& result)
172 {
173     result = toStorage(value);
174 }
175
176 void JSDictionary::convertValue(ExecState* exec, JSValue value, MessagePortArray& result)
177 {
178     ArrayBufferArray arrayBuffers;
179     fillMessagePortArray(exec, value, result, arrayBuffers);
180 }
181
182 #if ENABLE(VIDEO_TRACK)
183 void JSDictionary::convertValue(ExecState*, JSValue value, RefPtr<TrackBase>& result)
184 {
185     result = toTrack(value);
186 }
187 #endif
188
189 void JSDictionary::convertValue(ExecState* exec, JSValue value, HashSet<AtomicString>& result)
190 {
191     result.clear();
192
193     if (value.isUndefinedOrNull())
194         return;
195
196     unsigned length = 0;
197     JSObject* object = toJSSequence(exec, value, length);
198     if (exec->hadException())
199         return;
200
201     for (unsigned i = 0 ; i < length; ++i) {
202         JSValue itemValue = object->get(exec, i);
203         if (exec->hadException())
204             return;
205         result.add(itemValue.toString(exec)->value(exec));
206     }
207 }
208
209 void JSDictionary::convertValue(ExecState* exec, JSValue value, ArrayValue& result)
210 {
211     if (value.isUndefinedOrNull())
212         return;
213
214     result = ArrayValue(exec, value);
215 }
216
217 void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<Uint8Array>& result)
218 {
219     result = toUint8Array(value);
220 }
221
222 #if ENABLE(ENCRYPTED_MEDIA)
223 void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<MediaKeyError>& result)
224 {
225     result = toMediaKeyError(value);
226 }
227 #endif
228
229 #if ENABLE(MEDIA_STREAM)
230 void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<MediaStream>& result)
231 {
232     result = toMediaStream(value);
233 }
234
235 void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<MediaStreamTrack>& result)
236 {
237     result = toMediaStreamTrack(value);
238 }
239 #endif
240
241 #if ENABLE(FONT_LOAD_EVENTS)
242 void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<CSSFontFaceRule>& result)
243 {
244     result = toCSSFontFaceRule(value);
245 }
246
247 void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<DOMError>& result)
248 {
249     result = toDOMError(value);
250 }
251
252 void JSDictionary::convertValue(JSC::ExecState* exec, JSC::JSValue value, RefPtr<VoidCallback>& result)
253 {
254     if (!value.isFunction())
255         return;
256
257     result = JSVoidCallback::create(asObject(value), jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()));
258 }
259 #endif
260
261 #if ENABLE(GAMEPAD)
262 void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<Gamepad>& result)
263 {
264     result = toGamepad(value);
265 }
266 #endif
267
268 bool JSDictionary::getWithUndefinedOrNullCheck(const char* propertyName, String& result) const
269 {
270     ASSERT(isValid());
271     JSValue value;
272     if (tryGetProperty(propertyName, value) != PropertyFound || value.isUndefinedOrNull())
273         return false;
274
275     result = value.toWTFString(m_exec);
276     return true;
277 }
278
279 } // namespace WebCore