2 * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
25 #include <CoreFoundation/CoreFoundation.h>
27 #include <npruntime.h>
28 #include <c_utility.h>
30 #include <JavaScriptCore/npruntime_impl.h>
32 static Boolean stringIdentifierEqual(const void *value1, const void *value2)
34 return strcmp((const char *)value1, (const char *)value2) == 0;
37 static CFHashCode stringIdentifierHash (const void *value)
39 const char *key = (const char *)value;
40 unsigned int len = strlen(key);
41 unsigned int result = len;
45 while (cnt--) result = result * 257 + *(unsigned char *)key++;
48 for (cnt = 8; cnt > 0; cnt--) result = result * 257 + *(unsigned char *)key++;
50 for (cnt = 8; cnt > 0; cnt--) result = result * 257 + *(unsigned char *)key++;
52 result += (result << (len & 31));
57 CFDictionaryKeyCallBacks stringIdentifierCallbacks = {
62 stringIdentifierEqual,
66 static CFMutableDictionaryRef stringIdentifierDictionary = 0;
68 static CFMutableDictionaryRef getStringIdentifierDictionary()
70 if (!stringIdentifierDictionary)
71 stringIdentifierDictionary = CFDictionaryCreateMutable(NULL, 0, &stringIdentifierCallbacks, NULL);
72 return stringIdentifierDictionary;
75 static Boolean intIdentifierEqual(const void *value1, const void *value2)
77 return value1 == value2;
80 static CFHashCode intIdentifierHash (const void *value)
82 return (CFHashCode)value;
85 CFDictionaryKeyCallBacks intIdentifierCallbacks = {
94 static CFMutableDictionaryRef intIdentifierDictionary = 0;
96 static CFMutableDictionaryRef getIntIdentifierDictionary()
98 if (!intIdentifierDictionary)
99 intIdentifierDictionary = CFDictionaryCreateMutable(NULL, 0, &intIdentifierCallbacks, NULL);
100 return intIdentifierDictionary;
103 NPIdentifier _NPN_GetStringIdentifier (const NPUTF8 *name)
108 PrivateIdentifier *identifier = 0;
110 identifier = (PrivateIdentifier *)CFDictionaryGetValue (getStringIdentifierDictionary(), (const void *)name);
111 if (identifier == 0) {
112 identifier = (PrivateIdentifier *)malloc (sizeof(PrivateIdentifier));
113 // We never release identifier names, so this dictionary will grow, as will
114 // the memory for the identifier name strings.
115 identifier->isString = true;
116 const char *identifierName = strdup (name);
117 identifier->value.string = identifierName;
119 CFDictionaryAddValue (getStringIdentifierDictionary(), identifierName, (const void *)identifier);
121 return (NPIdentifier)identifier;
127 void _NPN_GetStringIdentifiers (const NPUTF8 **names, int32_t nameCount, NPIdentifier *identifiers)
130 assert (identifiers);
132 if (names && identifiers) {
135 for (i = 0; i < nameCount; i++) {
136 identifiers[i] = _NPN_GetStringIdentifier (names[i]);
141 NPIdentifier _NPN_GetIntIdentifier(int32_t intid)
143 PrivateIdentifier *identifier = 0;
145 identifier = (PrivateIdentifier *)CFDictionaryGetValue (getIntIdentifierDictionary(), (const void *)intid);
146 if (identifier == 0) {
147 identifier = (PrivateIdentifier *)malloc (sizeof(PrivateIdentifier));
148 // We never release identifier names, so this dictionary will grow.
149 identifier->isString = false;
150 identifier->value.number = intid;
152 CFDictionaryAddValue (getIntIdentifierDictionary(), (const void *)intid, (const void *)identifier);
154 return (NPIdentifier)identifier;
157 bool _NPN_IdentifierIsString(NPIdentifier identifier)
159 PrivateIdentifier *i = (PrivateIdentifier *)identifier;
163 NPUTF8 *_NPN_UTF8FromIdentifier (NPIdentifier identifier)
165 PrivateIdentifier *i = (PrivateIdentifier *)identifier;
169 return (NPUTF8 *)i->value.string;
172 int32_t _NPN_IntFromIdentifier(NPIdentifier identifier)
178 NPBool NPN_VariantIsVoid (const NPVariant *variant)
180 return variant->type == NPVariantType_Void;
183 NPBool NPN_VariantIsNull (const NPVariant *variant)
185 return variant->type == NPVariantType_Null;
188 NPBool NPN_VariantIsUndefined (const NPVariant *variant)
190 return variant->type == NPVariantType_Void;
193 NPBool NPN_VariantIsBool (const NPVariant *variant)
195 return variant->type == NPVariantType_Bool;
198 NPBool NPN_VariantIsInt32 (const NPVariant *variant)
200 return variant->type == NPVariantType_Int32;
203 NPBool NPN_VariantIsDouble (const NPVariant *variant)
205 return variant->type == NPVariantType_Double;
208 NPBool NPN_VariantIsString (const NPVariant *variant)
210 return variant->type == NPVariantType_String;
213 NPBool NPN_VariantIsObject (const NPVariant *variant)
215 return variant->type == NPVariantType_Object;
218 NPBool NPN_VariantToBool (const NPVariant *variant, NPBool *result)
220 if (variant->type != NPVariantType_Bool)
223 *result = variant->value.boolValue;
228 NPString NPN_VariantToString (const NPVariant *variant)
230 if (variant->type != NPVariantType_String) {
231 NPString emptyString = { 0, 0 };
235 return variant->value.stringValue;
238 NPBool NPN_VariantToInt32 (const NPVariant *variant, int32_t *result)
240 if (variant->type == NPVariantType_Int32)
241 *result = variant->value.intValue;
242 else if (variant->type == NPVariantType_Double)
243 *result = (int32_t)variant->value.doubleValue;
250 NPBool NPN_VariantToDouble (const NPVariant *variant, double *result)
252 if (variant->type == NPVariantType_Int32)
253 *result = (double)variant->value.intValue;
254 else if (variant->type == NPVariantType_Double)
255 *result = variant->value.doubleValue;
262 NPBool NPN_VariantToObject (const NPVariant *variant, NPObject **result)
264 if (variant->type != NPVariantType_Object)
267 *result = variant->value.objectValue;
272 void NPN_InitializeVariantAsVoid (NPVariant *variant)
274 variant->type = NPVariantType_Void;
277 void NPN_InitializeVariantAsNull (NPVariant *variant)
279 variant->type = NPVariantType_Null;
282 void NPN_InitializeVariantAsUndefined (NPVariant *variant)
284 variant->type = NPVariantType_Void;
287 void NPN_InitializeVariantWithBool (NPVariant *variant, NPBool value)
289 variant->type = NPVariantType_Bool;
290 variant->value.boolValue = value;
293 void NPN_InitializeVariantWithInt32 (NPVariant *variant, int32_t value)
295 variant->type = NPVariantType_Int32;
296 variant->value.intValue = value;
299 void NPN_InitializeVariantWithDouble (NPVariant *variant, double value)
301 variant->type = NPVariantType_Double;
302 variant->value.doubleValue = value;
305 void NPN_InitializeVariantWithString (NPVariant *variant, const NPString *value)
307 variant->type = NPVariantType_String;
308 variant->value.stringValue = *value;
311 void NPN_InitializeVariantWithStringCopy (NPVariant *variant, const NPString *value)
313 variant->type = NPVariantType_String;
314 variant->value.stringValue.UTF8Length = value->UTF8Length;
315 variant->value.stringValue.UTF8Characters = (NPUTF8 *)malloc(sizeof(NPUTF8) * value->UTF8Length);
316 memcpy ((void *)variant->value.stringValue.UTF8Characters, value->UTF8Characters, sizeof(NPUTF8) * value->UTF8Length);
319 void NPN_InitializeVariantWithObject (NPVariant *variant, NPObject *value)
321 variant->type = NPVariantType_Object;
322 variant->value.objectValue = _NPN_RetainObject (value);
325 void NPN_InitializeVariantWithVariant (NPVariant *destination, const NPVariant *source)
327 switch (source->type){
328 case NPVariantType_Void: {
329 NPN_InitializeVariantAsVoid (destination);
332 case NPVariantType_Null: {
333 NPN_InitializeVariantAsNull (destination);
336 case NPVariantType_Bool: {
337 NPN_InitializeVariantWithBool (destination, source->value.boolValue);
340 case NPVariantType_Int32: {
341 NPN_InitializeVariantWithInt32 (destination, source->value.intValue);
344 case NPVariantType_Double: {
345 NPN_InitializeVariantWithDouble (destination, source->value.doubleValue);
348 case NPVariantType_String: {
349 NPN_InitializeVariantWithStringCopy (destination, &source->value.stringValue);
352 case NPVariantType_Object: {
353 NPN_InitializeVariantWithObject (destination, source->value.objectValue);
357 NPN_InitializeVariantAsUndefined (destination);
363 void _NPN_ReleaseVariantValue (NPVariant *variant)
367 if (variant->type == NPVariantType_Object) {
368 _NPN_ReleaseObject (variant->value.objectValue);
369 variant->value.objectValue = 0;
371 else if (variant->type == NPVariantType_String) {
372 free ((void *)variant->value.stringValue.UTF8Characters);
373 variant->value.stringValue.UTF8Characters = 0;
374 variant->value.stringValue.UTF8Length = 0;
377 variant->type = NPVariantType_Void;
381 NPObject *_NPN_CreateObject (NPP npp, NPClass *aClass)
388 if (aClass->allocate != NULL)
389 obj = aClass->allocate (npp, aClass);
391 obj = (NPObject *)malloc (sizeof(NPObject));
393 obj->_class = aClass;
394 obj->referenceCount = 1;
403 NPObject *_NPN_RetainObject (NPObject *obj)
408 obj->referenceCount++;
414 void _NPN_ReleaseObject (NPObject *obj)
417 assert (obj->referenceCount >= 1);
419 if (obj && obj->referenceCount >= 1) {
420 obj->referenceCount--;
422 if (obj->referenceCount == 0) {
423 if (obj->_class->deallocate)
424 obj->_class->deallocate (obj);
431 void _NPN_SetExceptionWithUTF8 (NPObject *obj, const NPUTF8 *message, int32_t length)
436 if (obj && message) {
438 string.UTF8Characters = message;
439 string.UTF8Length = length;
440 _NPN_SetException (obj, &string);
445 void _NPN_SetException (NPObject *obj, NPString *message)
447 // FIX ME. Need to implement.