• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 Google 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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #ifndef Dictionary_h
27 #define Dictionary_h
28 
29 #include "bindings/v8/ExceptionMessages.h"
30 #include "bindings/v8/ExceptionState.h"
31 #include "bindings/v8/Nullable.h"
32 #include "bindings/v8/ScriptValue.h"
33 #include "bindings/v8/V8Binding.h"
34 #include "bindings/v8/V8BindingMacros.h"
35 #include "core/events/EventListener.h"
36 #include "core/dom/MessagePort.h"
37 #include <v8.h>
38 #include "wtf/HashMap.h"
39 #include "wtf/HashSet.h"
40 #include "wtf/Vector.h"
41 #include "wtf/text/AtomicString.h"
42 #include "wtf/text/WTFString.h"
43 
44 namespace WebCore {
45 
46 class ArrayValue;
47 class DOMError;
48 class LocalDOMWindow;
49 class Gamepad;
50 class MediaStream;
51 class HeaderMap;
52 class IDBKeyRange;
53 class MIDIPort;
54 class MediaKeyError;
55 class Notification;
56 class SpeechRecognitionResult;
57 class SpeechRecognitionResultList;
58 class Storage;
59 class TrackBase;
60 class VoidCallback;
61 
62 class Dictionary {
63     ALLOW_ONLY_INLINE_ALLOCATION();
64 public:
65     Dictionary();
66     Dictionary(const v8::Handle<v8::Value>& options, v8::Isolate*);
67     ~Dictionary();
68 
69     Dictionary& operator=(const Dictionary&);
70 
71     bool isObject() const;
72     bool isUndefinedOrNull() const;
73 
74     bool get(const String&, bool&) const;
75     bool get(const String&, int32_t&) const;
76     bool get(const String&, double&, bool& hasValue) const;
77     bool get(const String&, double&) const;
78     bool get(const String&, String&) const;
79     bool get(const String&, AtomicString&) const;
80     bool get(const String&, ScriptValue&) const;
81     bool get(const String&, short&) const;
82     bool get(const String&, unsigned short&) const;
83     bool get(const String&, unsigned&) const;
84     bool get(const String&, unsigned long&) const;
85     bool get(const String&, unsigned long long&) const;
86     bool get(const String&, RefPtrWillBeMember<LocalDOMWindow>&) const;
87     bool get(const String&, RefPtrWillBeMember<Storage>&) const;
88     bool get(const String&, MessagePortArray&) const;
89     bool get(const String&, RefPtr<Uint8Array>&) const;
90     bool get(const String&, RefPtr<ArrayBufferView>&) const;
91     bool get(const String&, RefPtrWillBeMember<MIDIPort>&) const;
92     bool get(const String&, RefPtr<MediaKeyError>&) const;
93     bool get(const String&, RefPtrWillBeMember<TrackBase>&) const;
94     bool get(const String&, Member<SpeechRecognitionResult>&) const;
95     bool get(const String&, Member<SpeechRecognitionResultList>&) const;
96     bool get(const String&, Member<Gamepad>&) const;
97     bool get(const String&, RefPtr<MediaStream>&) const;
98     bool get(const String&, RefPtrWillBeMember<EventTarget>&) const;
99     bool get(const String&, HashSet<AtomicString>&) const;
100     bool get(const String&, Dictionary&) const;
101     bool get(const String&, Vector<String>&) const;
102     bool get(const String&, ArrayValue&) const;
103     bool get(const String&, RefPtrWillBeMember<DOMError>&) const;
104     bool get(const String&, v8::Local<v8::Value>&) const;
105     bool get(const String&, RefPtr<HeaderMap>&) const;
106 
107     class ConversionContext {
108     public:
ConversionContext(const String & interfaceName,const String & methodName,ExceptionState & exceptionState)109         ConversionContext(const String& interfaceName, const String& methodName, ExceptionState& exceptionState)
110             : m_interfaceName(interfaceName)
111             , m_methodName(methodName)
112             , m_exceptionState(exceptionState)
113             , m_dirty(true)
114         {
115             resetPerPropertyContext();
116         }
117 
interfaceName()118         const String& interfaceName() const { return m_interfaceName; }
methodName()119         const String& methodName() const { return m_methodName; }
forConstructor()120         bool forConstructor() const { return m_methodName.isEmpty(); }
exceptionState()121         ExceptionState& exceptionState() const { return m_exceptionState; }
122 
isNullable()123         bool isNullable() const { return m_isNullable; }
typeName()124         String typeName() const { return m_propertyTypeName; }
125 
126         ConversionContext& setConversionType(const String&, bool);
127 
128         void throwTypeError(const String& detail);
129 
130         void resetPerPropertyContext();
131 
132     private:
133         const String m_interfaceName;
134         const String m_methodName;
135         ExceptionState& m_exceptionState;
136         bool m_dirty;
137 
138         bool m_isNullable;
139         String m_propertyTypeName;
140     };
141 
142     class ConversionContextScope {
143     public:
ConversionContextScope(ConversionContext & context)144         ConversionContextScope(ConversionContext& context)
145             : m_context(context) { }
~ConversionContextScope()146         ~ConversionContextScope()
147         {
148             m_context.resetPerPropertyContext();
149         }
150     private:
151         ConversionContext& m_context;
152     };
153 
154     bool convert(ConversionContext&, const String&, bool&) const;
155     bool convert(ConversionContext&, const String&, double&) const;
156     bool convert(ConversionContext&, const String&, String&) const;
157     bool convert(ConversionContext&, const String&, ScriptValue&) const;
158 
159     template<typename IntegralType>
160     bool convert(ConversionContext&, const String&, IntegralType&) const;
161     template<typename IntegralType>
162     bool convert(ConversionContext&, const String&, Nullable<IntegralType>&) const;
163 
164     bool convert(ConversionContext&, const String&, MessagePortArray&) const;
165     bool convert(ConversionContext&, const String&, HashSet<AtomicString>&) const;
166     bool convert(ConversionContext&, const String&, Dictionary&) const;
167     bool convert(ConversionContext&, const String&, Vector<String>&) const;
168     bool convert(ConversionContext&, const String&, ArrayValue&) const;
169     template<template <typename> class PointerType, typename T>
170     bool convert(ConversionContext&, const String&, PointerType<T>&) const;
171 
172     template<typename StringType>
173     bool getStringType(const String&, StringType&) const;
174 
175     bool getOwnPropertiesAsStringHashMap(HashMap<String, String>&) const;
176     bool getOwnPropertyNames(Vector<String>&) const;
177 
178     bool getWithUndefinedOrNullCheck(const String&, String&) const;
179 
180     bool hasProperty(const String&) const;
181 
182 private:
183     bool getKey(const String& key, v8::Local<v8::Value>&) const;
184 
185     v8::Handle<v8::Value> m_options;
186     v8::Isolate* m_isolate;
187 };
188 
189 template<>
190 struct NativeValueTraits<Dictionary> {
191     static inline Dictionary nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
192     {
193         return Dictionary(value, isolate);
194     }
195 };
196 
197 template <typename T>
198 struct IntegralTypeTraits {
199 };
200 
201 template <>
202 struct IntegralTypeTraits<uint8_t> {
203     static inline uint8_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
204     {
205         return toUInt8(value, configuration, exceptionState);
206     }
207     static const String typeName() { return "UInt8"; }
208 };
209 
210 template <>
211 struct IntegralTypeTraits<int8_t> {
212     static inline int8_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
213     {
214         return toInt8(value, configuration, exceptionState);
215     }
216     static const String typeName() { return "Int8"; }
217 };
218 
219 template <>
220 struct IntegralTypeTraits<unsigned short> {
221     static inline uint16_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
222     {
223         return toUInt16(value, configuration, exceptionState);
224     }
225     static const String typeName() { return "UInt16"; }
226 };
227 
228 template <>
229 struct IntegralTypeTraits<short> {
230     static inline int16_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
231     {
232         return toInt16(value, configuration, exceptionState);
233     }
234     static const String typeName() { return "Int16"; }
235 };
236 
237 template <>
238 struct IntegralTypeTraits<unsigned> {
239     static inline uint32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
240     {
241         return toUInt32(value, configuration, exceptionState);
242     }
243     static const String typeName() { return "UInt32"; }
244 };
245 
246 template <>
247 struct IntegralTypeTraits<unsigned long> {
248     static inline uint32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
249     {
250         return toUInt32(value, configuration, exceptionState);
251     }
252     static const String typeName() { return "UInt32"; }
253 };
254 
255 template <>
256 struct IntegralTypeTraits<int> {
257     static inline int32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
258     {
259         return toInt32(value, configuration, exceptionState);
260     }
261     static const String typeName() { return "Int32"; }
262 };
263 
264 template <>
265 struct IntegralTypeTraits<long> {
266     static inline int32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
267     {
268         return toInt32(value, configuration, exceptionState);
269     }
270     static const String typeName() { return "Int32"; }
271 };
272 
273 template <>
274 struct IntegralTypeTraits<unsigned long long> {
275     static inline unsigned long long toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
276     {
277         return toUInt64(value, configuration, exceptionState);
278     }
279     static const String typeName() { return "UInt64"; }
280 };
281 
282 template <>
283 struct IntegralTypeTraits<long long> {
284     static inline long long toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
285     {
286         return toInt64(value, configuration, exceptionState);
287     }
288     static const String typeName() { return "Int64"; }
289 };
290 
291 template<typename T> bool Dictionary::convert(ConversionContext& context, const String& key, T& value) const
292 {
293     ConversionContextScope scope(context);
294 
295     v8::Local<v8::Value> v8Value;
296     if (!getKey(key, v8Value))
297         return true;
298 
299     value = IntegralTypeTraits<T>::toIntegral(v8Value, NormalConversion, context.exceptionState());
300     if (context.exceptionState().throwIfNeeded())
301         return false;
302 
303     return true;
304 }
305 
306 template<typename T> bool Dictionary::convert(ConversionContext& context, const String& key, Nullable<T>& value) const
307 {
308     ConversionContextScope scope(context);
309 
310     v8::Local<v8::Value> v8Value;
311     if (!getKey(key, v8Value))
312         return true;
313 
314     if (context.isNullable() && WebCore::isUndefinedOrNull(v8Value)) {
315         value = Nullable<T>();
316         return true;
317     }
318 
319     T converted = IntegralTypeTraits<T>::toIntegral(v8Value, NormalConversion, context.exceptionState());
320 
321     if (context.exceptionState().throwIfNeeded())
322         return false;
323 
324     value = Nullable<T>(converted);
325     return true;
326 }
327 
328 template<template <typename> class PointerType, typename T> bool Dictionary::convert(ConversionContext& context, const String& key, PointerType<T>& value) const
329 {
330     ConversionContextScope scope(context);
331 
332     if (!get(key, value))
333         return true;
334 
335     if (value)
336         return true;
337 
338     v8::Local<v8::Value> v8Value;
339     getKey(key, v8Value);
340     if (context.isNullable() && WebCore::isUndefinedOrNull(v8Value))
341         return true;
342 
343     context.throwTypeError(ExceptionMessages::incorrectPropertyType(key, "does not have a " + context.typeName() + " type."));
344     return false;
345 }
346 
347 }
348 
349 #endif // Dictionary_h
350