• 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/ScriptValue.h"
32 #include "bindings/v8/V8Binding.h"
33 #include "bindings/v8/V8BindingMacros.h"
34 #include "core/events/EventListener.h"
35 #include "core/dom/MessagePort.h"
36 #include <v8.h>
37 #include "wtf/HashMap.h"
38 #include "wtf/HashSet.h"
39 #include "wtf/Vector.h"
40 #include "wtf/text/AtomicString.h"
41 #include "wtf/text/WTFString.h"
42 
43 namespace WebCore {
44 
45 class ArrayValue;
46 class DOMError;
47 class DOMWindow;
48 class IDBKeyRange;
49 class MIDIPort;
50 class MediaKeyError;
51 class Notification;
52 class SpeechRecognitionError;
53 class SpeechRecognitionResult;
54 class SpeechRecognitionResultList;
55 class Storage;
56 class TrackBase;
57 class VoidCallback;
58 
59 class Dictionary {
60 public:
61     Dictionary();
62     Dictionary(const v8::Handle<v8::Value>& options, v8::Isolate*);
63     ~Dictionary();
64 
65     Dictionary& operator=(const Dictionary&);
66 
67     bool isObject() const;
68     bool isUndefinedOrNull() const;
69 
70     bool get(const String&, bool&) const;
71     bool get(const String&, int32_t&) const;
72     bool get(const String&, double&, bool& hasValue) const;
73     bool get(const String&, double&) const;
74     bool get(const String&, String&) const;
75     bool get(const String&, ScriptValue&) const;
76     bool get(const String&, short&) const;
77     bool get(const String&, unsigned short&) const;
78     bool get(const String&, unsigned&) const;
79     bool get(const String&, unsigned long&) const;
80     bool get(const String&, unsigned long long&) const;
81     bool get(const String&, RefPtr<DOMWindow>&) const;
82     bool get(const String&, RefPtr<Storage>&) const;
83     bool get(const String&, MessagePortArray&) const;
84     bool get(const String&, RefPtr<Uint8Array>&) const;
85     bool get(const String&, RefPtr<ArrayBufferView>&) const;
86     bool get(const String&, RefPtr<MIDIPort>&) const;
87     bool get(const String&, RefPtr<MediaKeyError>&) const;
88     bool get(const String&, RefPtr<TrackBase>&) const;
89     bool get(const String&, RefPtr<SpeechRecognitionError>&) const;
90     bool get(const String&, RefPtr<SpeechRecognitionResult>&) const;
91     bool get(const String&, RefPtr<SpeechRecognitionResultList>&) const;
92     bool get(const String&, RefPtr<MediaStream>&) const;
93     bool get(const String&, RefPtr<EventTarget>&) const;
94     bool get(const String&, HashSet<AtomicString>&) const;
95     bool get(const String&, Dictionary&) const;
96     bool get(const String&, Vector<String>&) const;
97     bool get(const String&, ArrayValue&) const;
98     bool get(const String&, RefPtr<DOMError>&) const;
99     bool get(const String&, OwnPtr<VoidCallback>&) const;
100     bool get(const String&, v8::Local<v8::Value>&) const;
101 
102     class ConversionContext {
103     public:
ConversionContext(const String & interfaceName,const String & methodName,ExceptionState & exceptionState)104         ConversionContext(const String& interfaceName, const String& methodName, ExceptionState& exceptionState)
105             : m_interfaceName(interfaceName)
106             , m_methodName(methodName)
107             , m_exceptionState(exceptionState)
108             , m_dirty(true)
109         {
110             resetPerPropertyContext();
111         }
112 
interfaceName()113         const String& interfaceName() const { return m_interfaceName; }
methodName()114         const String& methodName() const { return m_methodName; }
forConstructor()115         bool forConstructor() const { return m_methodName.isEmpty(); }
exceptionState()116         ExceptionState& exceptionState() const { return m_exceptionState; }
117 
isNullable()118         bool isNullable() const { return m_isNullable; }
typeName()119         String typeName() const { return m_propertyTypeName; }
120 
121         ConversionContext& setConversionType(const String&, bool);
122 
123         void throwTypeError(const String& detail);
124 
125         void resetPerPropertyContext();
126 
127     private:
128         const String m_interfaceName;
129         const String m_methodName;
130         ExceptionState& m_exceptionState;
131         bool m_dirty;
132 
133         bool m_isNullable;
134         String m_propertyTypeName;
135     };
136 
137     class ConversionContextScope {
138     public:
ConversionContextScope(ConversionContext & context)139         ConversionContextScope(ConversionContext& context)
140             : m_context(context) { }
~ConversionContextScope()141         ~ConversionContextScope()
142         {
143             m_context.resetPerPropertyContext();
144         }
145     private:
146         ConversionContext& m_context;
147     };
148 
149     bool convert(ConversionContext&, const String&, bool&) const;
150     bool convert(ConversionContext&, const String&, double&) const;
151     bool convert(ConversionContext&, const String&, String&) const;
152     bool convert(ConversionContext&, const String&, ScriptValue&) const;
153 
154     template<typename IntegralType>
155     bool convert(ConversionContext &, const String&, IntegralType&) const;
156     bool convert(ConversionContext &, const String&, MessagePortArray&) const;
157     bool convert(ConversionContext &, const String&, HashSet<AtomicString>&) const;
158     bool convert(ConversionContext &, const String&, Dictionary&) const;
159     bool convert(ConversionContext &, const String&, Vector<String>&) const;
160     bool convert(ConversionContext &, const String&, ArrayValue&) const;
161     template<typename T>
162     bool convert(ConversionContext &, const String&, RefPtr<T>&) const;
163 
164     bool getOwnPropertiesAsStringHashMap(HashMap<String, String>&) const;
165     bool getOwnPropertyNames(Vector<String>&) const;
166 
167     bool getWithUndefinedOrNullCheck(const String&, String&) const;
168 
169     bool hasProperty(const String&) const;
170 
171     // Only allow inline allocation.
new(size_t,NotNullTag,void * location)172     void* operator new(size_t, NotNullTag, void* location) { return location; }
173 
174 private:
175     // Disallow new allocation.
176     void* operator new(size_t);
177 
178     bool getKey(const String& key, v8::Local<v8::Value>&) const;
179 
180     v8::Handle<v8::Value> m_options;
181     v8::Isolate* m_isolate;
182 };
183 
184 template<>
185 struct NativeValueTraits<Dictionary> {
186     static inline Dictionary nativeValue(const v8::Handle<v8::Value>& value, v8::Isolate* isolate)
187     {
188         return Dictionary(value, isolate);
189     }
190 };
191 
192 template <typename T>
193 struct IntegralTypeTraits {
194 };
195 
196 template <>
197 struct IntegralTypeTraits<uint8_t> {
198     static inline uint8_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
199     {
200         return toUInt8(value, configuration, ok);
201     }
202     static const String typeName() { return "UInt8"; }
203 };
204 
205 template <>
206 struct IntegralTypeTraits<int8_t> {
207     static inline int8_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
208     {
209         return toInt8(value, configuration, ok);
210     }
211     static const String typeName() { return "Int8"; }
212 };
213 
214 template <>
215 struct IntegralTypeTraits<unsigned short> {
216     static inline uint16_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
217     {
218         return toUInt16(value, configuration, ok);
219     }
220     static const String typeName() { return "UInt16"; }
221 };
222 
223 template <>
224 struct IntegralTypeTraits<short> {
225     static inline int16_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
226     {
227         return toInt16(value, configuration, ok);
228     }
229     static const String typeName() { return "Int16"; }
230 };
231 
232 template <>
233 struct IntegralTypeTraits<unsigned> {
234     static inline uint32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
235     {
236         return toUInt32(value, configuration, ok);
237     }
238     static const String typeName() { return "UInt32"; }
239 };
240 
241 template <>
242 struct IntegralTypeTraits<unsigned long> {
243     static inline uint32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
244     {
245         return toUInt32(value, configuration, ok);
246     }
247     static const String typeName() { return "UInt32"; }
248 };
249 
250 template <>
251 struct IntegralTypeTraits<int> {
252     static inline int32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
253     {
254         return toInt32(value, configuration, ok);
255     }
256     static const String typeName() { return "Int32"; }
257 };
258 
259 template <>
260 struct IntegralTypeTraits<long> {
261     static inline int32_t toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
262     {
263         return toInt32(value, configuration, ok);
264     }
265     static const String typeName() { return "Int32"; }
266 };
267 
268 template <>
269 struct IntegralTypeTraits<unsigned long long> {
270     static inline unsigned long long toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
271     {
272         return toUInt64(value, configuration, ok);
273     }
274     static const String typeName() { return "UInt64"; }
275 };
276 
277 template <>
278 struct IntegralTypeTraits<long long> {
279     static inline long long toIntegral(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
280     {
281         return toInt64(value, configuration, ok);
282     }
283     static const String typeName() { return "Int64"; }
284 };
285 
286 template<typename T> bool Dictionary::convert(ConversionContext& context, const String& key, T& value) const
287 {
288     ConversionContextScope scope(context);
289 
290     v8::Local<v8::Value> v8Value;
291     if (!getKey(key, v8Value))
292         return true;
293 
294     bool ok = false;
295     value = IntegralTypeTraits<T>::toIntegral(v8Value, NormalConversion, ok);
296     if (ok)
297         return true;
298 
299     V8TRYCATCH_RETURN(v8::Local<v8::Number>, v8Number, v8Value->ToNumber(), false);
300     ASSERT(v8Number.IsEmpty());
301     context.throwTypeError(ExceptionMessages::incorrectPropertyType(key, "does not have type " + IntegralTypeTraits<T>::typeName() + "."));
302     return false;
303 }
304 
305 template<typename T> bool Dictionary::convert(ConversionContext& context, const String& key, RefPtr<T>& value) const
306 {
307     ConversionContextScope scope(context);
308 
309     if (!get(key, value))
310         return true;
311 
312     if (value)
313         return true;
314 
315     v8::Local<v8::Value> v8Value;
316     getKey(key, v8Value);
317     if (context.isNullable() && WebCore::isUndefinedOrNull(v8Value))
318         return true;
319 
320     context.throwTypeError(ExceptionMessages::incorrectPropertyType(key, "does not have a " + context.typeName() + " type."));
321     return false;
322 }
323 
324 }
325 
326 #endif // Dictionary_h
327