0cde43bed4a4bd729fa470a3feef88b3e436a229
[WebKit-https.git] / JavaScriptCore / bindings / npruntime.cpp
1 /*
2  * Copyright (C) 2004, 2006 Apple Computer, Inc.  All rights reserved.
3  * Copyright (C) 2006 Justin Haygood <jhaygood@spsu.edu>.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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 COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #include "config.h"
28 #include "npruntime.h"
29 #include "npruntime_impl.h"
30 #include "npruntime_priv.h"
31
32 #include "c_utility.h"
33
34 #include <assert.h>
35 #include <wtf/HashMap.h>
36
37 using namespace KJS::Bindings;
38
39 typedef HashMap<const char*, PrivateIdentifier*> StringIdentifierDictionary;
40 static StringIdentifierDictionary* getStringIdentifierDictionary()
41 {
42
43     static StringIdentifierDictionary* stringIdentifierDictionary;
44     if (!stringIdentifierDictionary)
45         stringIdentifierDictionary = new StringIdentifierDictionary();
46     return stringIdentifierDictionary;
47 }
48
49 typedef HashMap<int, PrivateIdentifier*> IntIdentifierDictionary;
50 static IntIdentifierDictionary* getIntIdentifierDictionary()
51 {
52     static IntIdentifierDictionary* intIdentifierDictionary;
53     if (!intIdentifierDictionary)
54         intIdentifierDictionary = new IntIdentifierDictionary();
55     return intIdentifierDictionary;
56 }
57
58 NPIdentifier _NPN_GetStringIdentifier(const NPUTF8* name)
59 {
60     assert(name);
61     
62     if (name) {
63         PrivateIdentifier* identifier = 0;
64         
65         identifier = getStringIdentifierDictionary()->get( name );
66         if (identifier == 0) {
67             identifier = (PrivateIdentifier*)malloc(sizeof(PrivateIdentifier));
68             // We never release identifier names, so this dictionary will grow, as will
69             // the memory for the identifier name strings.
70             identifier->isString = true;
71             const char* identifierName = strdup(name);
72             identifier->value.string = identifierName;
73
74             getStringIdentifierDictionary()->add(identifierName, identifier);
75         }
76         return (NPIdentifier)identifier;
77     }
78     
79     return 0;
80 }
81
82 void _NPN_GetStringIdentifiers(const NPUTF8** names, int32_t nameCount, NPIdentifier* identifiers)
83 {
84     assert(names);
85     assert(identifiers);
86     
87     if (names && identifiers)
88         for (int i = 0; i < nameCount; i++)
89             identifiers[i] = _NPN_GetStringIdentifier(names[i]);
90 }
91
92 NPIdentifier _NPN_GetIntIdentifier(int32_t intid)
93 {
94     PrivateIdentifier* identifier = 0;
95     
96     identifier = getIntIdentifierDictionary()->get( intid );
97     if (identifier == 0) {
98         identifier = (PrivateIdentifier*)malloc(sizeof(PrivateIdentifier));
99         // We never release identifier names, so this dictionary will grow.
100         identifier->isString = false;
101         identifier->value.number = intid;
102
103         getIntIdentifierDictionary()->add( intid, identifier );
104     }
105     return (NPIdentifier)identifier;
106 }
107
108 bool _NPN_IdentifierIsString(NPIdentifier identifier)
109 {
110     PrivateIdentifier* i = (PrivateIdentifier*)identifier;
111     return i->isString;
112 }
113
114 NPUTF8 *_NPN_UTF8FromIdentifier(NPIdentifier identifier)
115 {
116     PrivateIdentifier* i = (PrivateIdentifier*)identifier;
117     if (!i->isString || !i->value.string)
118         return NULL;
119         
120     return (NPUTF8 *)strdup(i->value.string);
121 }
122
123 int32_t _NPN_IntFromIdentifier(NPIdentifier identifier)
124 {
125     PrivateIdentifier* i = (PrivateIdentifier*)identifier;
126     if (!i->isString)
127         return 0;
128     return i->value.number;
129 }
130
131 void NPN_InitializeVariantWithStringCopy(NPVariant* variant, const NPString* value)
132 {
133     variant->type = NPVariantType_String;
134     variant->value.stringValue.UTF8Length = value->UTF8Length;
135     variant->value.stringValue.UTF8Characters = (NPUTF8 *)malloc(sizeof(NPUTF8) * value->UTF8Length);
136     memcpy((void*)variant->value.stringValue.UTF8Characters, value->UTF8Characters, sizeof(NPUTF8) * value->UTF8Length);
137 }
138
139 void _NPN_ReleaseVariantValue(NPVariant* variant)
140 {
141     assert(variant);
142
143     if (variant->type == NPVariantType_Object) {
144         _NPN_ReleaseObject(variant->value.objectValue);
145         variant->value.objectValue = 0;
146     } else if (variant->type == NPVariantType_String) {
147         free((void*)variant->value.stringValue.UTF8Characters);
148         variant->value.stringValue.UTF8Characters = 0;
149         variant->value.stringValue.UTF8Length = 0;
150     }
151
152     variant->type = NPVariantType_Void;
153 }
154
155 NPObject *_NPN_CreateObject(NPP npp, NPClass* aClass)
156 {
157     assert(aClass);
158
159     if (aClass) {
160         NPObject* obj;
161         if (aClass->allocate != NULL)
162             obj = aClass->allocate(npp, aClass);
163         else
164             obj = (NPObject*)malloc(sizeof(NPObject));
165
166         obj->_class = aClass;
167         obj->referenceCount = 1;
168
169         return obj;
170     }
171
172     return 0;
173 }
174
175 NPObject* _NPN_RetainObject(NPObject* obj)
176 {
177     assert(obj);
178
179     if (obj)
180         obj->referenceCount++;
181
182     return obj;
183 }
184
185 void _NPN_ReleaseObject(NPObject* obj)
186 {
187     assert(obj);
188     assert(obj->referenceCount >= 1);
189
190     if (obj && obj->referenceCount >= 1) {
191         if (--obj->referenceCount == 0)
192             _NPN_DeallocateObject(obj);
193     }
194 }
195
196 void _NPN_DeallocateObject(NPObject *obj)
197 {
198     assert(obj);
199
200     if (obj) {
201         if (obj->_class->deallocate)
202             obj->_class->deallocate(obj);
203         else
204             free(obj);
205     }
206 }