b868869790354991ee68d15c779e50b19818fa57
[WebKit-https.git] / JavaScriptCore / bindings / c / c_utility.cpp
1 /*
2  * Copyright (C) 2004 Apple Computer, 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25 #include <c_instance.h> 
26 #include <c_utility.h> 
27 #include <internal.h>
28 #include <npruntime_impl.h>
29 #include <npruntime_priv.h>
30 #include <runtime.h>
31 #include <runtime_object.h>
32 #include <runtime_root.h>
33 #include <value.h>
34 #include <NP_jsobject.h>
35
36 using namespace KJS;
37 using namespace KJS::Bindings;
38
39 // Requires free() of returned UTF16Chars.
40 void convertNPStringToUTF16(const NPString *string, NPUTF16 **UTF16Chars, unsigned int *UTF16Length)
41 {
42     convertUTF8ToUTF16(string->UTF8Characters, string->UTF8Length, UTF16Chars, UTF16Length);
43 }
44
45 // Requires free() of returned UTF16Chars.
46 void convertUTF8ToUTF16(const NPUTF8 *UTF8Chars, int UTF8Length, NPUTF16 **UTF16Chars, unsigned int *UTF16Length)
47 {
48     assert(UTF8Chars);
49     
50     if (UTF8Length == -1)
51         UTF8Length = strlen(UTF8Chars);
52         
53     CFStringRef stringRef = CFStringCreateWithBytes(NULL, (const UInt8*)UTF8Chars, (CFIndex)UTF8Length, kCFStringEncodingUTF8, false);
54
55     *UTF16Length = (unsigned int)CFStringGetLength(stringRef);
56     *UTF16Chars = (NPUTF16 *)malloc(sizeof(NPUTF16) * (*UTF16Length));
57
58     // Convert the string to UTF16.
59     CFRange range = { 0, *UTF16Length };
60     CFStringGetCharacters(stringRef, range, (UniChar *)*UTF16Chars);
61     CFRelease(stringRef);
62 }
63
64 // Variant value must be released with NPReleaseVariantValue()
65 void coerceValueToNPVariantStringType(ExecState *exec, ValueImp *value, NPVariant *result)
66 {
67     UString ustring = value->toString(exec);
68     CString cstring = ustring.UTF8String();
69     NPString string = { (const NPUTF8 *)cstring.c_str(), cstring.size() };
70     NPN_InitializeVariantWithStringCopy(result, &string);
71 }
72
73 // Variant value must be released with NPReleaseVariantValue()
74 void convertValueToNPVariant(ExecState *exec, ValueImp *value, NPVariant *result)
75 {
76     Type type = value->type();
77     
78     if (type == StringType) {
79         UString ustring = value->toString(exec);
80         CString cstring = ustring.UTF8String();
81         NPString string = { (const NPUTF8 *)cstring.c_str(), cstring.size() };
82         NPN_InitializeVariantWithStringCopy(result, &string );
83     }
84     else if (type == NumberType) {
85         NPN_InitializeVariantWithDouble(result, value->toNumber(exec));
86     }
87     else if (type == BooleanType) {
88         NPN_InitializeVariantWithBool(result, value->toBoolean(exec));
89     }
90     else if (type == UnspecifiedType) {
91         NPN_InitializeVariantAsUndefined(result);
92     }
93     else if (type == NullType) {
94         NPN_InitializeVariantAsNull(result);
95     }
96     else if (type == ObjectType) {
97         ObjectImp *objectImp = static_cast<ObjectImp*>(value);
98         if (objectImp->classInfo() == &RuntimeObjectImp::info) {
99             RuntimeObjectImp *imp = static_cast<RuntimeObjectImp *>(value);
100             CInstance *instance = static_cast<CInstance*>(imp->getInternalInstance());
101             NPN_InitializeVariantWithObject(result, instance->getObject());
102         }
103         else {
104
105             Interpreter *originInterpreter = exec->interpreter();
106             const Bindings::RootObject *originExecutionContext = rootForInterpreter(originInterpreter);
107
108             Interpreter *interpreter = 0;
109             if (originInterpreter->isGlobalObject(value)) {
110                 interpreter = originInterpreter->interpreterForGlobalObject(value);
111             }
112
113             if (!interpreter)
114                 interpreter = originInterpreter;
115                 
116             const Bindings::RootObject *executionContext = rootForInterpreter(interpreter);
117             if (!executionContext) {
118                 Bindings::RootObject *newExecutionContext = new Bindings::RootObject(0);
119                 newExecutionContext->setInterpreter(interpreter);
120                 executionContext = newExecutionContext;
121             }
122     
123             NPObject *obj = (NPObject *)exec->interpreter()->createLanguageInstanceForValue(exec, Instance::CLanguage, value->toObject(exec), originExecutionContext, executionContext);
124             NPN_InitializeVariantWithObject(result, obj);
125             _NPN_ReleaseObject(obj);
126         }
127     }
128     else
129         NPN_InitializeVariantAsUndefined(result);
130 }
131
132 ValueImp *convertNPVariantToValue(ExecState *exec, const NPVariant *variant)
133 {
134     NPVariantType type = variant->type;
135
136     if (type == NPVariantType_Bool) {
137         NPBool aBool;
138         if (NPN_VariantToBool(variant, &aBool))
139             return jsBoolean(aBool);
140         return jsBoolean(false);
141     }
142     else if (type == NPVariantType_Null) {
143         return Null();
144     }
145     else if (type == NPVariantType_Void) {
146         return Undefined();
147     }
148     else if (type == NPVariantType_Int32) {
149         int32_t anInt;
150         if (NPN_VariantToInt32(variant, &anInt))
151             return Number(anInt);
152         return Number(0);
153     }
154     else if (type == NPVariantType_Double) {
155         double aDouble;
156         if (NPN_VariantToDouble(variant, &aDouble))
157             return Number(aDouble);
158         return Number(0);
159     }
160     else if (type == NPVariantType_String) {
161         NPUTF16 *stringValue;
162         unsigned int UTF16Length;
163         convertNPStringToUTF16(&variant->value.stringValue, &stringValue, &UTF16Length);    // requires free() of returned memory.
164         UString resultString((const UChar *)stringValue,UTF16Length);
165         free(stringValue);
166         return jsString(resultString);
167     }
168     else if (type == NPVariantType_Object) {
169         NPObject *obj = variant->value.objectValue;
170         
171         if (obj->_class == NPScriptObjectClass) {
172             // Get ObjectImp from NP_JavaScriptObject.
173             JavaScriptObject *o = (JavaScriptObject *)obj;
174             return const_cast<ObjectImp*>(o->imp);
175         }
176         else {
177             //  Wrap NPObject in a CInstance.
178             return Instance::createRuntimeObject(Instance::CLanguage, (void *)obj);
179         }
180     }
181     
182     return Undefined();
183 }
184