1/*
2 * Copyright (C) 2007 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. ``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 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
26#include "TestObject.h"
27
28#include "PluginObject.h"
29
30#include <string.h>
31#include <stdlib.h>
32
33static bool testEnumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count);
34static bool testHasMethod(NPObject*, NPIdentifier name);
35static bool testInvoke(NPObject*, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result);
36static bool testHasProperty(NPObject*, NPIdentifier name);
37static bool testGetProperty(NPObject*, NPIdentifier name, NPVariant*);
38static NPObject *testAllocate(NPP npp, NPClass *theClass);
39static void testDeallocate(NPObject *obj);
40static bool testConstruct(NPObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result);
41
42static NPClass testClass = {
43 NP_CLASS_STRUCT_VERSION,
44 testAllocate,
45 testDeallocate,
46 0,
47 testHasMethod,
48 testInvoke,
49 0,
50 testHasProperty,
51 testGetProperty,
52 0,
53 0,
54 testEnumerate,
55 testConstruct
56};
57
58NPClass *getTestClass(void)
59{
60 return &testClass;
61}
62
63static int testObjectCount = 0;
64
65int getTestObjectCount()
66{
67 return testObjectCount;
68}
69
70typedef struct {
71 NPObject header;
72 NPObject* testObject;
73} TestObject;
74
75static bool identifiersInitialized = false;
76
77#define NUM_ENUMERATABLE_TEST_IDENTIFIERS 2
78
79enum {
80 ID_PROPERTY_FOO = 0,
81 ID_PROPERTY_BAR,
82 ID_PROPERTY_OBJECT_POINTER,
83 ID_PROPERTY_TEST_OBJECT,
84 ID_PROPERTY_REF_COUNT,
85 NUM_TEST_IDENTIFIERS,
86};
87
88static NPIdentifier testIdentifiers[NUM_TEST_IDENTIFIERS];
89static const NPUTF8 *testIdentifierNames[NUM_TEST_IDENTIFIERS] = {
90 "foo",
91 "bar",
92 "objectPointer",
93 "testObject",
94 "refCount",
95};
96
97#define ID_THROW_EXCEPTION_METHOD 0
98#define NUM_METHOD_IDENTIFIERS 1
99
100static NPIdentifier testMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
101static const NPUTF8 *testMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
102 "throwException",
103};
104
105static void initializeIdentifiers(void)
106{
107 browser->getstringidentifiers(testIdentifierNames, NUM_TEST_IDENTIFIERS, testIdentifiers);
108 browser->getstringidentifiers(testMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, testMethodIdentifiers);
109}
110
111static NPObject* testAllocate(NPP /*npp*/, NPClass* /*theClass*/)
112{
113 TestObject* newInstance = static_cast<TestObject*>(malloc(sizeof(TestObject)));
114 newInstance->testObject = 0;
115 ++testObjectCount;
116
117 if (!identifiersInitialized) {
118 identifiersInitialized = true;
119 initializeIdentifiers();
120 }
121
122 return reinterpret_cast<NPObject*>(newInstance);
123}
124
125static void testDeallocate(NPObject *obj)
126{
127 TestObject* testObject = reinterpret_cast<TestObject*>(obj);
128 if (testObject->testObject)
129 browser->releaseobject(testObject->testObject);
130
131 --testObjectCount;
132 free(obj);
133}
134
135static bool testHasMethod(NPObject*, NPIdentifier name)
136{
137 for (unsigned i = 0; i < NUM_METHOD_IDENTIFIERS; i++) {
138 if (testMethodIdentifiers[i] == name)
139 return true;
140 }
141 return false;
142}
143
144static bool testInvoke(NPObject* header, NPIdentifier name, const NPVariant* /*args*/, uint32_t /*argCount*/, NPVariant* /*result*/)
145{
146 if (name == testMethodIdentifiers[ID_THROW_EXCEPTION_METHOD]) {
147 browser->setexception(header, "test object throwException SUCCESS");
148 return true;
149 }
150 return false;
151}
152
153static bool testHasProperty(NPObject*, NPIdentifier name)
154{
155 for (unsigned i = 0; i < NUM_TEST_IDENTIFIERS; i++) {
156 if (testIdentifiers[i] == name)
157 return true;
158 }
159
160 return false;
161}
162
163static bool testGetProperty(NPObject* npobj, NPIdentifier name, NPVariant* result)
164{
165 if (name == testIdentifiers[ID_PROPERTY_FOO]) {
166 char* mem = static_cast<char*>(browser->memalloc(4));
167 strcpy(mem, "foo");
168 STRINGZ_TO_NPVARIANT(mem, *result);
169 return true;
170 }
171 if (name == testIdentifiers[ID_PROPERTY_OBJECT_POINTER]) {
172 int32_t objectPointer = static_cast<int32_t>(reinterpret_cast<long long>(npobj));
173
174 INT32_TO_NPVARIANT(objectPointer, *result);
175 return true;
176 }
177 if (name == testIdentifiers[ID_PROPERTY_TEST_OBJECT]) {
178 TestObject* testObject = reinterpret_cast<TestObject*>(npobj);
179 if (!testObject->testObject)
180 testObject->testObject = browser->createobject(0, &testClass);
181 browser->retainobject(testObject->testObject);
182 OBJECT_TO_NPVARIANT(testObject->testObject, *result);
183 return true;
184 }
185 if (name == testIdentifiers[ID_PROPERTY_REF_COUNT]) {
186 INT32_TO_NPVARIANT(npobj->referenceCount, *result);
187 return true;
188 }
189
190 return false;
191}
192
193static bool testEnumerate(NPObject* /*npobj*/, NPIdentifier **value, uint32_t *count)
194{
195 *count = NUM_ENUMERATABLE_TEST_IDENTIFIERS;
196
197 *value = (NPIdentifier*)browser->memalloc(NUM_ENUMERATABLE_TEST_IDENTIFIERS * sizeof(NPIdentifier));
198 memcpy(*value, testIdentifiers, sizeof(NPIdentifier) * NUM_ENUMERATABLE_TEST_IDENTIFIERS);
199
200 return true;
201}
202
203static bool testConstruct(NPObject* npobj, const NPVariant* /*args*/, uint32_t /*argCount*/, NPVariant* result)
204{
205 browser->retainobject(npobj);
206
207 // Just return the same object.
208 OBJECT_TO_NPVARIANT(npobj, *result);
209 return true;
210}
211