18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2004, 2006 Apple Computer, Inc.  All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(NETSCAPE_PLUGIN_API)
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "c_utility.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
33dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "CRuntimeObject.h"
34dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include "JSDOMBinding.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSDOMWindow.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "NP_jsobject.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "c_instance.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <runtime/JSGlobalObject.h>
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <runtime/JSLock.h>
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "PlatformString.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "npruntime_impl.h"
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "npruntime_priv.h"
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "runtime_object.h"
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "runtime_root.h"
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Assertions.h>
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC { namespace Bindings {
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic String convertUTF8ToUTF16WithLatin1Fallback(const NPUTF8* UTF8Chars, int UTF8Length)
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(UTF8Chars || UTF8Length == 0);
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (UTF8Length == -1)
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        UTF8Length = static_cast<int>(strlen(UTF8Chars));
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String result = String::fromUTF8(UTF8Chars, UTF8Length);
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If we got back a null string indicating an unsuccessful conversion, fall back to latin 1.
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Some plugins return invalid UTF-8 in NPVariantType_String, see <http://bugs.webkit.org/show_bug.cgi?id=5163>
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // There is no "bad data" for latin1. It is unlikely that the plugin was really sending text in this encoding,
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // but it should have used UTF-8, and now we are simply avoiding a crash.
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (result.isNull())
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = String(UTF8Chars, UTF8Length);
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Variant value must be released with NPReleaseVariantValue()
695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid convertValueToNPVariant(ExecState* exec, JSValue value, NPVariant* result)
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    VOID_TO_NPVARIANT(*result);
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
75635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (value.isString()) {
76635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        UString ustring = value.toString(exec);
77f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        CString cstring = ustring.utf8();
78dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        NPString string = { (const NPUTF8*)cstring.data(), static_cast<uint32_t>(cstring.length()) };
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NPN_InitializeVariantWithStringCopy(result, &string);
80635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    } else if (value.isNumber()) {
81635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        DOUBLE_TO_NPVARIANT(value.toNumber(exec), *result);
82635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    } else if (value.isBoolean()) {
83635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        BOOLEAN_TO_NPVARIANT(value.toBoolean(exec), *result);
84635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    } else if (value.isNull()) {
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NULL_TO_NPVARIANT(*result);
86635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    } else if (value.isObject()) {
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JSObject* object = asObject(value);
88dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (object->classInfo() == &CRuntimeObject::s_info) {
89dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            CRuntimeObject* runtimeObject = static_cast<CRuntimeObject*>(object);
90dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            CInstance* instance = runtimeObject->getInternalCInstance();
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (instance) {
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                NPObject* obj = instance->getObject();
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                _NPN_RetainObject(obj);
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                OBJECT_TO_NPVARIANT(obj, *result);
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
97deb796f509e2ad13b4ef4c01b1a1e707b4e762eeKristian Monsen#ifdef ANDROID
98deb796f509e2ad13b4ef4c01b1a1e707b4e762eeKristian Monsen            RootObject* rootObject = findRootObject(exec->dynamicGlobalObject());
99deb796f509e2ad13b4ef4c01b1a1e707b4e762eeKristian Monsen            if (!rootObject)
100deb796f509e2ad13b4ef4c01b1a1e707b4e762eeKristian Monsen                rootObject = findRootObject(exec->lexicalGlobalObject());
101deb796f509e2ad13b4ef4c01b1a1e707b4e762eeKristian Monsen#else
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            JSGlobalObject* globalObject = exec->dynamicGlobalObject();
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            RootObject* rootObject = findRootObject(globalObject);
105deb796f509e2ad13b4ef4c01b1a1e707b4e762eeKristian Monsen#endif
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (rootObject) {
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                NPObject* npObject = _NPN_CreateScriptObject(0, object, rootObject);
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                OBJECT_TO_NPVARIANT(npObject, *result);
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1145f1ab04193ad0130ca8204aadaceae083aca9881Feng QianJSValue convertNPVariantToValue(ExecState* exec, const NPVariant* variant, RootObject* rootObject)
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NPVariantType type = variant->type;
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (type == NPVariantType_Bool)
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return jsBoolean(NPVARIANT_TO_BOOLEAN(*variant));
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (type == NPVariantType_Null)
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return jsNull();
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (type == NPVariantType_Void)
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return jsUndefined();
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (type == NPVariantType_Int32)
127e14391e94c850b8bd03680c23b38978db68687a8John Reck        return jsNumber(NPVARIANT_TO_INT32(*variant));
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (type == NPVariantType_Double)
129e14391e94c850b8bd03680c23b38978db68687a8John Reck        return jsNumber(NPVARIANT_TO_DOUBLE(*variant));
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (type == NPVariantType_String)
131dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        return WebCore::jsString(exec, convertNPStringToUTF16(&variant->value.stringValue));
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (type == NPVariantType_Object) {
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        NPObject* obj = variant->value.objectValue;
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (obj->_class == NPScriptObjectClass)
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Get JSObject from NP_JavaScriptObject.
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return ((JavaScriptObject*)obj)->imp;
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Wrap NPObject in a CInstance.
140635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return CInstance::create(obj, rootObject)->createRuntimeObject(exec);
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return jsUndefined();
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString convertNPStringToUTF16(const NPString* string)
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return String::fromUTF8WithLatin1Fallback(string->UTF8Characters, string->UTF8Length);
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
151dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockIdentifier identifierFromNPIdentifier(ExecState* exec, const NPUTF8* name)
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
153dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    return Identifier(exec, WebCore::stringToUString(convertUTF8ToUTF16WithLatin1Fallback(name, -1)));
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} }
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif // ENABLE(NETSCAPE_PLUGIN_API)
159