~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/bindings/v8/Dictionary.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#include "config.h"
 
27
#include "Dictionary.h"
 
28
 
 
29
#include "ArrayValue.h"
 
30
#include "DOMStringList.h"
 
31
#include "V8Binding.h"
 
32
#include "V8DOMWindow.h"
 
33
#include "V8Storage.h"
 
34
#include "V8Uint8Array.h"
 
35
#include "V8Utilities.h"
 
36
#include <wtf/MathExtras.h>
 
37
 
 
38
#if ENABLE(INDEXED_DATABASE)
 
39
#include "IDBKeyRange.h"
 
40
#include "V8IDBKeyRange.h"
 
41
#endif
 
42
 
 
43
#if ENABLE(ENCRYPTED_MEDIA)
 
44
#include "V8MediaKeyError.h"
 
45
#endif
 
46
 
 
47
#if ENABLE(VIDEO_TRACK)
 
48
#include "TrackBase.h"
 
49
#include "V8TextTrack.h"
 
50
#endif
 
51
 
 
52
#if ENABLE(SCRIPTED_SPEECH)
 
53
#include "SpeechRecognitionError.h"
 
54
#include "SpeechRecognitionResult.h"
 
55
#include "SpeechRecognitionResultList.h"
 
56
#include "V8SpeechRecognitionError.h"
 
57
#include "V8SpeechRecognitionResult.h"
 
58
#include "V8SpeechRecognitionResultList.h"
 
59
#endif
 
60
 
 
61
namespace WebCore {
 
62
 
 
63
Dictionary::Dictionary()
 
64
    : m_isolate(0)
 
65
{
 
66
}
 
67
 
 
68
Dictionary::Dictionary(const v8::Local<v8::Value>& options, v8::Isolate* isolate)
 
69
    : m_options(options)
 
70
    , m_isolate(isolate)
 
71
{
 
72
    ASSERT(m_isolate);
 
73
}
 
74
 
 
75
Dictionary::~Dictionary()
 
76
{
 
77
}
 
78
 
 
79
Dictionary& Dictionary::operator=(const Dictionary& optionsObject)
 
80
{
 
81
    m_options = optionsObject.m_options;
 
82
    m_isolate = optionsObject.m_isolate;
 
83
    return *this;
 
84
}
 
85
 
 
86
bool Dictionary::isObject() const
 
87
{
 
88
    return !isUndefinedOrNull() && m_options->IsObject();
 
89
}
 
90
 
 
91
bool Dictionary::isUndefinedOrNull() const
 
92
{
 
93
    if (m_options.IsEmpty())
 
94
        return true;
 
95
    return WebCore::isUndefinedOrNull(m_options);
 
96
}
 
97
 
 
98
bool Dictionary::getKey(const String& key, v8::Local<v8::Value>& value) const
 
99
{
 
100
    if (isUndefinedOrNull())
 
101
        return false;
 
102
    v8::Local<v8::Object> options = m_options->ToObject();
 
103
    ASSERT(!options.IsEmpty());
 
104
 
 
105
    v8::Handle<v8::String> v8Key = v8String(key);
 
106
    if (!options->Has(v8Key))
 
107
        return false;
 
108
    value = options->Get(v8Key);
 
109
    if (value.IsEmpty())
 
110
        return false;
 
111
    return true;
 
112
}
 
113
 
 
114
bool Dictionary::get(const String& key, bool& value) const
 
115
{
 
116
    v8::Local<v8::Value> v8Value;
 
117
    if (!getKey(key, v8Value))
 
118
        return false;
 
119
 
 
120
    v8::Local<v8::Boolean> v8Bool = v8Value->ToBoolean();
 
121
    if (v8Bool.IsEmpty())
 
122
        return false;
 
123
    value = v8Bool->Value();
 
124
    return true;
 
125
}
 
126
 
 
127
bool Dictionary::get(const String& key, int32_t& value) const
 
128
{
 
129
    v8::Local<v8::Value> v8Value;
 
130
    if (!getKey(key, v8Value))
 
131
        return false;
 
132
 
 
133
    v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32();
 
134
    if (v8Int32.IsEmpty())
 
135
        return false;
 
136
    value = v8Int32->Value();
 
137
    return true;
 
138
}
 
139
 
 
140
bool Dictionary::get(const String& key, double& value) const
 
141
{
 
142
    v8::Local<v8::Value> v8Value;
 
143
    if (!getKey(key, v8Value))
 
144
        return false;
 
145
 
 
146
    v8::Local<v8::Number> v8Number = v8Value->ToNumber();
 
147
    if (v8Number.IsEmpty())
 
148
        return false;
 
149
    value = v8Number->Value();
 
150
    return true;
 
151
}
 
152
 
 
153
bool Dictionary::get(const String& key, String& value) const
 
154
{
 
155
    v8::Local<v8::Value> v8Value;
 
156
    if (!getKey(key, v8Value))
 
157
        return false;
 
158
 
 
159
    // FIXME: It is possible for this to throw in which case we'd be getting back
 
160
    //        an empty string and returning true when we should be returning false.
 
161
    //        See fast/dom/Geolocation/script-tests/argument-types.js for a similar
 
162
    //        example.
 
163
    value = toWebCoreString(v8Value);
 
164
    return true;
 
165
}
 
166
 
 
167
bool Dictionary::get(const String& key, ScriptValue& value) const
 
168
{
 
169
    v8::Local<v8::Value> v8Value;
 
170
    if (!getKey(key, v8Value))
 
171
        return false;
 
172
 
 
173
    value = ScriptValue(v8Value);
 
174
    return true;
 
175
}
 
176
 
 
177
bool Dictionary::get(const String& key, unsigned short& value) const
 
178
{
 
179
    v8::Local<v8::Value> v8Value;
 
180
    if (!getKey(key, v8Value))
 
181
        return false;
 
182
 
 
183
    v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32();
 
184
    if (v8Int32.IsEmpty())
 
185
        return false;
 
186
    value = static_cast<unsigned short>(v8Int32->Value());
 
187
    return true;
 
188
}
 
189
 
 
190
bool Dictionary::get(const String& key, short& value) const
 
191
{
 
192
    v8::Local<v8::Value> v8Value;
 
193
    if (!getKey(key, v8Value))
 
194
        return false;
 
195
 
 
196
    v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32();
 
197
    if (v8Int32.IsEmpty())
 
198
        return false;
 
199
    value = static_cast<short>(v8Int32->Value());
 
200
    return true;
 
201
}
 
202
 
 
203
bool Dictionary::get(const String& key, unsigned& value) const
 
204
{
 
205
    v8::Local<v8::Value> v8Value;
 
206
    if (!getKey(key, v8Value))
 
207
        return false;
 
208
 
 
209
    v8::Local<v8::Int32> v8Int32 = v8Value->ToInt32();
 
210
    if (v8Int32.IsEmpty())
 
211
        return false;
 
212
    value = static_cast<unsigned>(v8Int32->Value());
 
213
    return true;
 
214
}
 
215
 
 
216
bool Dictionary::get(const String& key, unsigned long long& value) const
 
217
{
 
218
    v8::Local<v8::Value> v8Value;
 
219
    if (!getKey(key, v8Value))
 
220
        return false;
 
221
 
 
222
    v8::Local<v8::Number> v8Number = v8Value->ToNumber();
 
223
    if (v8Number.IsEmpty())
 
224
        return false;
 
225
    double d = v8Number->Value();
 
226
    doubleToInteger(d, value);
 
227
    return true;
 
228
}
 
229
 
 
230
bool Dictionary::get(const String& key, RefPtr<DOMWindow>& value) const
 
231
{
 
232
    v8::Local<v8::Value> v8Value;
 
233
    if (!getKey(key, v8Value))
 
234
        return false;
 
235
 
 
236
    DOMWindow* source = 0;
 
237
    if (v8Value->IsObject()) {
 
238
        v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
 
239
        v8::Handle<v8::Object> window = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), wrapper);
 
240
        if (!window.IsEmpty())
 
241
            source = V8DOMWindow::toNative(window);
 
242
    }
 
243
    value = source;
 
244
    return true;
 
245
}
 
246
 
 
247
bool Dictionary::get(const String& key, RefPtr<Storage>& value) const
 
248
{
 
249
    v8::Local<v8::Value> v8Value;
 
250
    if (!getKey(key, v8Value))
 
251
        return false;
 
252
 
 
253
    Storage* source = 0;
 
254
    if (v8Value->IsObject()) {
 
255
        v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
 
256
        v8::Handle<v8::Object> storage = V8DOMWrapper::lookupDOMWrapper(V8Storage::GetTemplate(), wrapper);
 
257
        if (!storage.IsEmpty())
 
258
            source = V8Storage::toNative(storage);
 
259
    }
 
260
    value = source;
 
261
    return true;
 
262
}
 
263
 
 
264
bool Dictionary::get(const String& key, MessagePortArray& value) const
 
265
{
 
266
    v8::Local<v8::Value> v8Value;
 
267
    if (!getKey(key, v8Value))
 
268
        return false;
 
269
 
 
270
    ASSERT(m_isolate);
 
271
    ASSERT(m_isolate == v8::Isolate::GetCurrent());
 
272
    return getMessagePortArray(v8Value, value, m_isolate);
 
273
}
 
274
 
 
275
bool Dictionary::get(const String& key, HashSet<AtomicString>& value) const
 
276
{
 
277
    v8::Local<v8::Value> v8Value;
 
278
    if (!getKey(key, v8Value))
 
279
        return false;
 
280
 
 
281
    // FIXME: Support array-like objects
 
282
    if (!v8Value->IsArray())
 
283
        return false;
 
284
 
 
285
    v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value);
 
286
    for (size_t i = 0; i < v8Array->Length(); ++i) {
 
287
        v8::Local<v8::Value> indexedValue = v8Array->Get(v8Integer(i));
 
288
        value.add(toWebCoreString(indexedValue));
 
289
    }
 
290
 
 
291
    return true;
 
292
}
 
293
 
 
294
bool Dictionary::getWithUndefinedOrNullCheck(const String& key, String& value) const
 
295
{
 
296
    v8::Local<v8::Value> v8Value;
 
297
    if (!getKey(key, v8Value) || v8Value->IsNull() || v8Value->IsUndefined())
 
298
        return false;
 
299
 
 
300
    // FIXME: It is possible for this to throw in which case we'd be getting back
 
301
    //        an empty string and returning true when we should be returning false.
 
302
    //        See fast/dom/Geolocation/script-tests/argument-types.js for a similar
 
303
    //        example.
 
304
    value = WebCore::isUndefinedOrNull(v8Value) ? String() : toWebCoreString(v8Value);
 
305
    return true;
 
306
}
 
307
 
 
308
bool Dictionary::get(const String& key, RefPtr<Uint8Array>& value) const
 
309
{
 
310
    v8::Local<v8::Value> v8Value;
 
311
    if (!getKey(key, v8Value))
 
312
        return false;
 
313
 
 
314
    Uint8Array* source = 0;
 
315
    if (v8Value->IsObject()) {
 
316
        v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
 
317
 
 
318
        v8::Handle<v8::Object> array = V8DOMWrapper::lookupDOMWrapper(V8Uint8Array::GetTemplate(), wrapper);
 
319
        if (!array.IsEmpty())
 
320
            source = V8Uint8Array::toNative(array);
 
321
    }
 
322
    value = source;
 
323
    return true;
 
324
}
 
325
 
 
326
#if ENABLE(ENCRYPTED_MEDIA)
 
327
bool Dictionary::get(const String& key, RefPtr<MediaKeyError>& value) const
 
328
{
 
329
    v8::Local<v8::Value> v8Value;
 
330
    if (!getKey(key, v8Value))
 
331
        return false;
 
332
 
 
333
    MediaKeyError* source = 0;
 
334
    if (v8Value->IsObject()) {
 
335
        v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
 
336
 
 
337
        v8::Handle<v8::Object> error = V8DOMWrapper::lookupDOMWrapper(V8MediaKeyError::GetTemplate(), wrapper);
 
338
        if (!error.IsEmpty())
 
339
            source = V8MediaKeyError::toNative(error);
 
340
    }
 
341
    value = source;
 
342
    return true;
 
343
}
 
344
#endif
 
345
 
 
346
#if ENABLE(VIDEO_TRACK)
 
347
bool Dictionary::get(const String& key, RefPtr<TrackBase>& value) const
 
348
{
 
349
    v8::Local<v8::Value> v8Value;
 
350
    if (!getKey(key, v8Value))
 
351
        return false;
 
352
 
 
353
    TrackBase* source = 0;
 
354
    if (v8Value->IsObject()) {
 
355
        v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
 
356
 
 
357
        // FIXME: this will need to be changed so it can also return an AudioTrack or a VideoTrack once
 
358
        // we add them.
 
359
        v8::Handle<v8::Object> track = V8DOMWrapper::lookupDOMWrapper(V8TextTrack::GetTemplate(), wrapper);
 
360
        if (!track.IsEmpty())
 
361
            source = V8TextTrack::toNative(track);
 
362
    }
 
363
    value = source;
 
364
    return true;
 
365
}
 
366
#endif
 
367
 
 
368
#if ENABLE(SCRIPTED_SPEECH)
 
369
bool Dictionary::get(const String& key, RefPtr<SpeechRecognitionError>& value) const
 
370
{
 
371
    v8::Local<v8::Value> v8Value;
 
372
    if (!getKey(key, v8Value))
 
373
        return false;
 
374
 
 
375
    SpeechRecognitionError* source = 0;
 
376
    if (v8Value->IsObject()) {
 
377
        v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
 
378
        v8::Handle<v8::Object> speechRecognitionError = V8DOMWrapper::lookupDOMWrapper(V8SpeechRecognitionError::GetTemplate(), wrapper);
 
379
        if (!speechRecognitionError.IsEmpty())
 
380
            source = V8SpeechRecognitionError::toNative(speechRecognitionError);
 
381
    }
 
382
    value = source;
 
383
    return true;
 
384
}
 
385
 
 
386
bool Dictionary::get(const String& key, RefPtr<SpeechRecognitionResult>& value) const
 
387
{
 
388
    v8::Local<v8::Value> v8Value;
 
389
    if (!getKey(key, v8Value))
 
390
        return false;
 
391
 
 
392
    SpeechRecognitionResult* source = 0;
 
393
    if (v8Value->IsObject()) {
 
394
        v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
 
395
        v8::Handle<v8::Object> speechRecognitionResult = V8DOMWrapper::lookupDOMWrapper(V8SpeechRecognitionResult::GetTemplate(), wrapper);
 
396
        if (!speechRecognitionResult.IsEmpty())
 
397
            source = V8SpeechRecognitionResult::toNative(speechRecognitionResult);
 
398
    }
 
399
    value = source;
 
400
    return true;
 
401
}
 
402
 
 
403
bool Dictionary::get(const String& key, RefPtr<SpeechRecognitionResultList>& value) const
 
404
{
 
405
    v8::Local<v8::Value> v8Value;
 
406
    if (!getKey(key, v8Value))
 
407
        return false;
 
408
 
 
409
    SpeechRecognitionResultList* source = 0;
 
410
    if (v8Value->IsObject()) {
 
411
        v8::Handle<v8::Object> wrapper = v8::Handle<v8::Object>::Cast(v8Value);
 
412
        v8::Handle<v8::Object> speechRecognitionResultList = V8DOMWrapper::lookupDOMWrapper(V8SpeechRecognitionResultList::GetTemplate(), wrapper);
 
413
        if (!speechRecognitionResultList.IsEmpty())
 
414
            source = V8SpeechRecognitionResultList::toNative(speechRecognitionResultList);
 
415
    }
 
416
    value = source;
 
417
    return true;
 
418
}
 
419
 
 
420
#endif
 
421
 
 
422
bool Dictionary::get(const String& key, Dictionary& value) const
 
423
{
 
424
    v8::Local<v8::Value> v8Value;
 
425
    if (!getKey(key, v8Value))
 
426
        return false;
 
427
 
 
428
    if (v8Value->IsObject()) {
 
429
        ASSERT(m_isolate);
 
430
        ASSERT(m_isolate == v8::Isolate::GetCurrent());
 
431
        value = Dictionary(v8Value, m_isolate);
 
432
    }
 
433
 
 
434
    return true;
 
435
}
 
436
 
 
437
bool Dictionary::get(const String& key, Vector<String>& value) const
 
438
{
 
439
    v8::Local<v8::Value> v8Value;
 
440
    if (!getKey(key, v8Value))
 
441
        return false;
 
442
 
 
443
    if (!v8Value->IsArray())
 
444
        return false;
 
445
 
 
446
    v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value);
 
447
    for (size_t i = 0; i < v8Array->Length(); ++i) {
 
448
        v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Uint32::New(i));
 
449
        value.append(toWebCoreString(indexedValue));
 
450
    }
 
451
 
 
452
    return true;
 
453
}
 
454
 
 
455
bool Dictionary::get(const String& key, ArrayValue& value) const
 
456
{
 
457
    v8::Local<v8::Value> v8Value;
 
458
    if (!getKey(key, v8Value))
 
459
        return false;
 
460
 
 
461
    if (!v8Value->IsArray())
 
462
        return false;
 
463
 
 
464
    ASSERT(m_isolate);
 
465
    ASSERT(m_isolate == v8::Isolate::GetCurrent());
 
466
    value = ArrayValue(v8::Local<v8::Array>::Cast(v8Value), m_isolate);
 
467
    return true;
 
468
}
 
469
 
 
470
bool Dictionary::getOwnPropertiesAsStringHashMap(HashMap<String, String>& hashMap) const
 
471
{
 
472
    if (!isObject())
 
473
        return false;
 
474
 
 
475
    v8::Handle<v8::Object> options = m_options->ToObject();
 
476
    if (options.IsEmpty())
 
477
        return false;
 
478
 
 
479
    v8::Local<v8::Array> properties = options->GetOwnPropertyNames();
 
480
    if (properties.IsEmpty())
 
481
        return true;
 
482
    for (uint32_t i = 0; i < properties->Length(); ++i) {
 
483
        v8::Local<v8::String> key = properties->Get(i)->ToString();
 
484
        if (!options->Has(key))
 
485
            continue;
 
486
 
 
487
        v8::Local<v8::Value> value = options->Get(key);
 
488
        String stringKey = toWebCoreString(key);
 
489
        String stringValue = toWebCoreString(value);
 
490
        if (!stringKey.isEmpty())
 
491
            hashMap.set(stringKey, stringValue);
 
492
    }
 
493
 
 
494
    return true;
 
495
}
 
496
 
 
497
bool Dictionary::getOwnPropertyNames(Vector<String>& names) const
 
498
{
 
499
    if (!isObject())
 
500
        return false;
 
501
 
 
502
    v8::Handle<v8::Object> options = m_options->ToObject();
 
503
    if (options.IsEmpty())
 
504
        return false;
 
505
 
 
506
    v8::Local<v8::Array> properties = options->GetOwnPropertyNames();
 
507
    if (properties.IsEmpty())
 
508
        return true;
 
509
    for (uint32_t i = 0; i < properties->Length(); ++i) {
 
510
        v8::Local<v8::String> key = properties->Get(i)->ToString();
 
511
        if (!options->Has(key))
 
512
            continue;
 
513
        names.append(toWebCoreString(key));
 
514
    }
 
515
 
 
516
    return true;
 
517
}
 
518
 
 
519
} // namespace WebCore