blob: e53708acd4a8fe4067d439460914d18a0018b568 [file] [log] [blame]
/*
* Copyright (C) 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "JSDictionary.h"
#include "ArrayValue.h"
#include "DOMWindow.h"
#include "Dictionary.h"
#include "JSCSSFontFaceRule.h"
#include "JSDOMError.h"
#include "JSDOMWindow.h"
#include "JSEventTarget.h"
#include "JSMessagePortCustom.h"
#include "JSNode.h"
#include "JSStorage.h"
#include "JSTrackCustom.h"
#include "JSVoidCallback.h"
#include "SerializedScriptValue.h"
#include <runtime/JSTypedArrays.h>
#include <wtf/HashMap.h>
#include <wtf/MathExtras.h>
#include <wtf/text/AtomicString.h>
#if ENABLE(ENCRYPTED_MEDIA)
#include "JSMediaKeyError.h"
#endif
#if ENABLE(FETCH_API)
#include "JSFetchHeaders.h"
#endif
#if ENABLE(MEDIA_STREAM)
#include "JSMediaStream.h"
#include "JSMediaStreamTrack.h"
#include "JSRTCRtpReceiver.h"
#endif
#if ENABLE(GAMEPAD)
#include "JSGamepad.h"
#endif
using namespace JSC;
namespace WebCore {
JSDictionary::GetPropertyResult JSDictionary::tryGetProperty(const char* propertyName, JSValue& finalResult) const
{
ASSERT(isValid());
Identifier identifier = Identifier::fromString(m_exec, propertyName);
PropertySlot slot(m_initializerObject.get(), PropertySlot::InternalMethodType::Get);
if (!m_initializerObject.get()->getPropertySlot(m_exec, identifier, slot))
return NoPropertyFound;
if (m_exec->hadException())
return ExceptionThrown;
finalResult = slot.getValue(m_exec, identifier);
if (m_exec->hadException())
return ExceptionThrown;
return PropertyFound;
}
void JSDictionary::convertValue(ExecState* exec, JSValue value, bool& result)
{
result = value.toBoolean(exec);
}
void JSDictionary::convertValue(ExecState* exec, JSValue value, int& result)
{
result = value.toInt32(exec);
}
void JSDictionary::convertValue(ExecState* exec, JSValue value, unsigned& result)
{
result = value.toUInt32(exec);
}
void JSDictionary::convertValue(ExecState* exec, JSValue value, unsigned short& result)
{
result = static_cast<unsigned short>(value.toUInt32(exec));
}
void JSDictionary::convertValue(ExecState* exec, JSValue value, unsigned long& result)
{
result = static_cast<unsigned long>(value.toUInt32(exec));
}
void JSDictionary::convertValue(ExecState* exec, JSValue value, unsigned long long& result)
{
double d = value.toNumber(exec);
doubleToInteger(d, result);
}
void JSDictionary::convertValue(ExecState* exec, JSValue value, double& result)
{
result = value.toNumber(exec);
}
void JSDictionary::convertValue(JSC::ExecState* exec, JSC::JSValue value, Dictionary& result)
{
result = Dictionary(exec, value);
}
void JSDictionary::convertValue(ExecState* exec, JSValue value, String& result)
{
result = value.toString(exec)->value(exec);
}
void JSDictionary::convertValue(ExecState* exec, JSValue value, Vector<String>& result)
{
if (value.isUndefinedOrNull())
return;
unsigned length = 0;
JSObject* object = toJSSequence(exec, value, length);
if (exec->hadException())
return;
for (unsigned i = 0 ; i < length; ++i) {
JSValue itemValue = object->get(exec, i);
if (exec->hadException())
return;
result.append(itemValue.toString(exec)->value(exec));
}
}
void JSDictionary::convertValue(ExecState* exec, JSValue value, Deprecated::ScriptValue& result)
{
result = Deprecated::ScriptValue(exec->vm(), value);
}
void JSDictionary::convertValue(ExecState* exec, JSValue value, RefPtr<SerializedScriptValue>& result)
{
result = SerializedScriptValue::create(exec, value, 0, 0);
}
void JSDictionary::convertValue(ExecState*, JSValue value, RefPtr<DOMWindow>& result)
{
result = JSDOMWindow::toWrapped(value);
}
void JSDictionary::convertValue(ExecState*, JSValue value, RefPtr<EventTarget>& result)
{
result = JSEventTarget::toWrapped(value);
}
void JSDictionary::convertValue(ExecState*, JSValue value, RefPtr<Node>& result)
{
result = JSNode::toWrapped(value);
}
void JSDictionary::convertValue(ExecState*, JSValue value, RefPtr<Storage>& result)
{
result = JSStorage::toWrapped(value);
}
void JSDictionary::convertValue(ExecState* exec, JSValue value, MessagePortArray& result)
{
ArrayBufferArray arrayBuffers;
fillMessagePortArray(*exec, value, result, arrayBuffers);
}
#if ENABLE(VIDEO_TRACK)
void JSDictionary::convertValue(ExecState*, JSValue value, RefPtr<TrackBase>& result)
{
result = toTrack(value);
}
#endif
void JSDictionary::convertValue(ExecState* exec, JSValue value, HashSet<AtomicString>& result)
{
result.clear();
if (value.isUndefinedOrNull())
return;
unsigned length = 0;
JSObject* object = toJSSequence(exec, value, length);
if (exec->hadException())
return;
for (unsigned i = 0 ; i < length; ++i) {
JSValue itemValue = object->get(exec, i);
if (exec->hadException())
return;
result.add(itemValue.toString(exec)->value(exec));
}
}
void JSDictionary::convertValue(ExecState* exec, JSValue value, ArrayValue& result)
{
if (value.isUndefinedOrNull())
return;
result = ArrayValue(exec, value);
}
void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<Uint8Array>& result)
{
result = toUint8Array(value);
}
#if ENABLE(ENCRYPTED_MEDIA)
void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<MediaKeyError>& result)
{
result = JSMediaKeyError::toWrapped(value);
}
#endif
#if ENABLE(FETCH_API)
void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<FetchHeaders>& result)
{
result = JSFetchHeaders::toWrapped(value);
}
#endif
#if ENABLE(MEDIA_STREAM)
void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<MediaStream>& result)
{
result = JSMediaStream::toWrapped(value);
}
void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<MediaStreamTrack>& result)
{
result = JSMediaStreamTrack::toWrapped(value);
}
void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<RTCRtpReceiver>& result)
{
result = JSRTCRtpReceiver::toWrapped(value);
}
#endif
#if ENABLE(FONT_LOAD_EVENTS)
void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<CSSFontFaceRule>& result)
{
result = JSCSSFontFaceRule::toWrapped(value);
}
void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<DOMError>& result)
{
result = JSDOMError::toWrapped(value);
}
void JSDictionary::convertValue(JSC::ExecState* exec, JSC::JSValue value, RefPtr<VoidCallback>& result)
{
if (!value.isFunction())
return;
result = JSVoidCallback::create(asObject(value), jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()));
}
#endif
#if ENABLE(GAMEPAD)
void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr<Gamepad>& result)
{
result = JSGamepad::toWrapped(value);
}
#endif
void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, JSC::JSFunction*& result)
{
result = jsDynamicCast<JSC::JSFunction*>(value);
}
bool JSDictionary::getWithUndefinedOrNullCheck(const char* propertyName, String& result) const
{
ASSERT(isValid());
JSValue value;
if (tryGetProperty(propertyName, value) != PropertyFound || value.isUndefinedOrNull())
return false;
result = value.toWTFString(m_exec);
return true;
}
} // namespace WebCore