1/*
2 * Copyright (C) 2010 Apple 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 INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "NPObjectMessageReceiver.h"
28
29#if ENABLE(NETSCAPE_PLUGIN_API)
30
31#include "NPIdentifierData.h"
32#include "NPRemoteObjectMap.h"
33#include "NPRuntimeUtilities.h"
34#include "NPVariantData.h"
35
36namespace WebKit {
37
38NPObjectMessageReceiver::NPObjectMessageReceiver(NPRemoteObjectMap* npRemoteObjectMap, Plugin* plugin, uint64_t npObjectID, NPObject* npObject)
39    : m_npRemoteObjectMap(npRemoteObjectMap)
40    , m_plugin(plugin)
41    , m_npObjectID(npObjectID)
42    , m_npObject(npObject)
43{
44    retainNPObject(m_npObject);
45}
46
47NPObjectMessageReceiver::~NPObjectMessageReceiver()
48{
49    m_npRemoteObjectMap->unregisterNPObject(m_npObjectID);
50
51    releaseNPObject(m_npObject);
52}
53
54void NPObjectMessageReceiver::deallocate()
55{
56    delete this;
57}
58
59void NPObjectMessageReceiver::hasMethod(const NPIdentifierData& methodNameData, bool& returnValue)
60{
61    if (!m_npObject->_class->hasMethod) {
62        returnValue = false;
63        return;
64    }
65
66    returnValue = m_npObject->_class->hasMethod(m_npObject, methodNameData.createNPIdentifier());
67}
68
69void NPObjectMessageReceiver::invoke(const NPIdentifierData& methodNameData, const Vector<NPVariantData>& argumentsData, bool& returnValue, NPVariantData& resultData)
70{
71    if (!m_npObject->_class->invoke) {
72        returnValue = false;
73        return;
74    }
75
76    Vector<NPVariant> arguments;
77    for (size_t i = 0; i < argumentsData.size(); ++i)
78        arguments.append(m_npRemoteObjectMap->npVariantDataToNPVariant(argumentsData[i], m_plugin));
79
80    NPVariant result;
81    VOID_TO_NPVARIANT(result);
82
83    returnValue = m_npObject->_class->invoke(m_npObject, methodNameData.createNPIdentifier(), arguments.data(), arguments.size(), &result);
84    if (returnValue) {
85        // Convert the NPVariant to an NPVariantData.
86        resultData = m_npRemoteObjectMap->npVariantToNPVariantData(result, m_plugin);
87    }
88
89    // Release all arguments.
90    for (size_t i = 0; i < argumentsData.size(); ++i)
91        releaseNPVariantValue(&arguments[i]);
92
93    // And release the result.
94    releaseNPVariantValue(&result);
95}
96
97void NPObjectMessageReceiver::invokeDefault(const Vector<NPVariantData>& argumentsData, bool& returnValue, NPVariantData& resultData)
98{
99    if (!m_npObject->_class->invokeDefault) {
100        returnValue = false;
101        return;
102    }
103
104    Vector<NPVariant> arguments;
105    for (size_t i = 0; i < argumentsData.size(); ++i)
106        arguments.append(m_npRemoteObjectMap->npVariantDataToNPVariant(argumentsData[i], m_plugin));
107
108    NPVariant result;
109    VOID_TO_NPVARIANT(result);
110
111    returnValue = m_npObject->_class->invokeDefault(m_npObject, arguments.data(), arguments.size(), &result);
112    if (returnValue) {
113        // Convert the NPVariant to an NPVariantData.
114        resultData = m_npRemoteObjectMap->npVariantToNPVariantData(result, m_plugin);
115    }
116
117    // Release all arguments.
118    for (size_t i = 0; i < argumentsData.size(); ++i)
119        releaseNPVariantValue(&arguments[i]);
120
121    // And release the result.
122    releaseNPVariantValue(&result);
123}
124
125void NPObjectMessageReceiver::hasProperty(const NPIdentifierData& propertyNameData, bool& returnValue)
126{
127    if (!m_npObject->_class->hasProperty) {
128        returnValue = false;
129        return;
130    }
131
132    returnValue = m_npObject->_class->hasProperty(m_npObject, propertyNameData.createNPIdentifier());
133}
134
135void NPObjectMessageReceiver::getProperty(const NPIdentifierData& propertyNameData, bool& returnValue, NPVariantData& resultData)
136{
137    if (!m_npObject->_class->getProperty) {
138        returnValue = false;
139        return;
140    }
141
142    NPVariant result;
143    VOID_TO_NPVARIANT(result);
144
145    returnValue = m_npObject->_class->getProperty(m_npObject, propertyNameData.createNPIdentifier(), &result);
146    if (!returnValue)
147        return;
148
149    // Convert the NPVariant to an NPVariantData.
150    resultData = m_npRemoteObjectMap->npVariantToNPVariantData(result, m_plugin);
151
152    // And release the result.
153    releaseNPVariantValue(&result);
154}
155
156void NPObjectMessageReceiver::setProperty(const NPIdentifierData& propertyNameData, const NPVariantData& propertyValueData, bool& returnValue)
157{
158    if (!m_npObject->_class->setProperty) {
159        returnValue = false;
160        return;
161    }
162
163    NPVariant propertyValue = m_npRemoteObjectMap->npVariantDataToNPVariant(propertyValueData, m_plugin);
164
165    // Set the property.
166    returnValue = m_npObject->_class->setProperty(m_npObject, propertyNameData.createNPIdentifier(), &propertyValue);
167
168    // And release the value.
169    releaseNPVariantValue(&propertyValue);
170}
171
172void NPObjectMessageReceiver::removeProperty(const NPIdentifierData& propertyNameData, bool& returnValue)
173{
174    if (!m_npObject->_class->removeProperty) {
175        returnValue = false;
176        return;
177    }
178
179    returnValue = m_npObject->_class->removeProperty(m_npObject, propertyNameData.createNPIdentifier());
180}
181
182void NPObjectMessageReceiver::enumerate(bool& returnValue, Vector<NPIdentifierData>& identifiersData)
183{
184    if (!NP_CLASS_STRUCT_VERSION_HAS_ENUM(m_npObject->_class) || !m_npObject->_class->enumerate) {
185        returnValue = false;
186        return;
187    }
188
189    NPIdentifier* identifiers = 0;
190    uint32_t identifierCount = 0;
191
192    returnValue = m_npObject->_class->enumerate(m_npObject, &identifiers, &identifierCount);
193    if (!returnValue)
194        return;
195
196    for (uint32_t i = 0; i < identifierCount; ++i)
197        identifiersData.append(NPIdentifierData::fromNPIdentifier(identifiers[i]));
198
199    npnMemFree(identifiers);
200}
201
202void NPObjectMessageReceiver::construct(const Vector<NPVariantData>& argumentsData, bool& returnValue, NPVariantData& resultData)
203{
204    if (!NP_CLASS_STRUCT_VERSION_HAS_CTOR(m_npObject->_class) || !m_npObject->_class->construct) {
205        returnValue = false;
206        return;
207    }
208
209    Vector<NPVariant> arguments;
210    for (size_t i = 0; i < argumentsData.size(); ++i)
211        arguments.append(m_npRemoteObjectMap->npVariantDataToNPVariant(argumentsData[i], m_plugin));
212
213    NPVariant result;
214    VOID_TO_NPVARIANT(result);
215
216    returnValue = m_npObject->_class->construct(m_npObject, arguments.data(), arguments.size(), &result);
217    if (returnValue) {
218        // Convert the NPVariant to an NPVariantData.
219        resultData = m_npRemoteObjectMap->npVariantToNPVariantData(result, m_plugin);
220    }
221
222    // Release all arguments.
223    for (size_t i = 0; i < argumentsData.size(); ++i)
224        releaseNPVariantValue(&arguments[i]);
225
226    // And release the result.
227    releaseNPVariantValue(&result);
228}
229
230} // namespace WebKit
231
232#endif // ENABLE(NETSCAPE_PLUGIN_API)
233
234