Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(647)

Side by Side Diff: content/shell/renderer/test_runner/CppBoundClass.cpp

Issue 110533009: Import TestRunner library into chromium. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: updates Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 /*
6 * Copyright (C) 2010 Google Inc. All rights reserved.
7 * Copyright (C) 2009 Pawel Hajdan (phajdan.jr@chromium.org)
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are
11 * met:
12 *
13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following disclaimer
17 * in the documentation and/or other materials provided with the
18 * distribution.
19 * * Neither the name of Google Inc. nor the names of its
20 * contributors may be used to endorse or promote products derived from
21 * this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 // This file contains definitions for CppBoundClass
37
38 // Here's the control flow of a JS method getting forwarded to a class.
39 // - Something calls our NPObject with a function like "Invoke".
40 // - CppNPObject's static invoke() function forwards it to its attached
41 // CppBoundClass's invoke() method.
42 // - CppBoundClass has then overridden invoke() to look up the function
43 // name in its internal map of methods, and then calls the appropriate
44 // method.
45
46 #include "content/shell/renderer/test_runner/CppBoundClass.h"
47
48 #include "content/shell/renderer/test_runner/TestCommon.h"
49 #include "third_party/WebKit/public/platform/WebString.h"
50 #include "third_party/WebKit/public/web/WebBindings.h"
51 #include "third_party/WebKit/public/web/WebFrame.h"
52
53 using namespace blink;
54 using namespace std;
55
56 namespace WebTestRunner {
57
58 namespace {
59
60 class CppVariantPropertyCallback : public CppBoundClass::PropertyCallback {
61 public:
62 CppVariantPropertyCallback(CppVariant* value) : m_value(value) { }
63
64 virtual bool getValue(CppVariant* value)
65 {
66 value->set(*m_value);
67 return true;
68 }
69
70 virtual bool setValue(const CppVariant& value)
71 {
72 m_value->set(value);
73 return true;
74 }
75
76 private:
77 CppVariant* m_value;
78 };
79
80 class GetterPropertyCallback : public CppBoundClass::PropertyCallback {
81 public:
82 GetterPropertyCallback(WebScopedPtr<CppBoundClass::GetterCallback> callback)
83 : m_callback(callback)
84 {
85 }
86
87 virtual bool getValue(CppVariant* value)
88 {
89 m_callback->run(value);
90 return true;
91 }
92
93 virtual bool setValue(const CppVariant& value) { return false; }
94
95 private:
96 WebScopedPtr<CppBoundClass::GetterCallback> m_callback;
97 };
98
99 }
100
101 // Our special NPObject type. We extend an NPObject with a pointer to a
102 // CppBoundClass, which is just a C++ interface that we forward all NPObject
103 // callbacks to.
104 struct CppNPObject {
105 NPObject parent; // This must be the first field in the struct.
106 CppBoundClass* boundClass;
107
108 //
109 // All following objects and functions are static, and just used to interfac e
110 // with NPObject/NPClass.
111 //
112
113 // An NPClass associates static functions of CppNPObject with the
114 // function pointers used by the JS runtime.
115 static NPClass npClass;
116
117 // Allocate a new NPObject with the specified class.
118 static NPObject* allocate(NPP, NPClass*);
119
120 // Free an object.
121 static void deallocate(NPObject*);
122
123 // Returns true if the C++ class associated with this NPObject exposes the
124 // given property. Called by the JS runtime.
125 static bool hasProperty(NPObject*, NPIdentifier);
126
127 // Returns true if the C++ class associated with this NPObject exposes the
128 // given method. Called by the JS runtime.
129 static bool hasMethod(NPObject*, NPIdentifier);
130
131 // If the given method is exposed by the C++ class associated with this
132 // NPObject, invokes it with the given arguments and returns a result. Other wise,
133 // returns "undefined" (in the JavaScript sense). Called by the JS runtime.
134 static bool invoke(NPObject*, NPIdentifier,
135 const NPVariant* arguments, uint32_t argumentCount,
136 NPVariant* result);
137
138 // If the given property is exposed by the C++ class associated with this
139 // NPObject, returns its value. Otherwise, returns "undefined" (in the
140 // JavaScript sense). Called by the JS runtime.
141 static bool getProperty(NPObject*, NPIdentifier, NPVariant* result);
142
143 // If the given property is exposed by the C++ class associated with this
144 // NPObject, sets its value. Otherwise, does nothing. Called by the JS
145 // runtime.
146 static bool setProperty(NPObject*, NPIdentifier, const NPVariant* value);
147 };
148
149 // Build CppNPObject's static function pointers into an NPClass, for use
150 // in constructing NPObjects for the C++ classes.
151 NPClass CppNPObject::npClass = {
152 NP_CLASS_STRUCT_VERSION,
153 CppNPObject::allocate,
154 CppNPObject::deallocate,
155 /* NPInvalidateFunctionPtr */ 0,
156 CppNPObject::hasMethod,
157 CppNPObject::invoke,
158 /* NPInvokeDefaultFunctionPtr */ 0,
159 CppNPObject::hasProperty,
160 CppNPObject::getProperty,
161 CppNPObject::setProperty,
162 /* NPRemovePropertyFunctionPtr */ 0
163 };
164
165 NPObject* CppNPObject::allocate(NPP npp, NPClass* aClass)
166 {
167 CppNPObject* obj = new CppNPObject;
168 // obj->parent will be initialized by the NPObject code calling this.
169 obj->boundClass = 0;
170 return &obj->parent;
171 }
172
173 void CppNPObject::deallocate(NPObject* npObj)
174 {
175 CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
176 delete obj;
177 }
178
179 bool CppNPObject::hasMethod(NPObject* npObj, NPIdentifier ident)
180 {
181 CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
182 return obj->boundClass->hasMethod(ident);
183 }
184
185 bool CppNPObject::hasProperty(NPObject* npObj, NPIdentifier ident)
186 {
187 CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
188 return obj->boundClass->hasProperty(ident);
189 }
190
191 bool CppNPObject::invoke(NPObject* npObj, NPIdentifier ident,
192 const NPVariant* arguments, uint32_t argumentCount,
193 NPVariant* result)
194 {
195 CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
196 return obj->boundClass->invoke(ident, arguments, argumentCount, result);
197 }
198
199 bool CppNPObject::getProperty(NPObject* npObj, NPIdentifier ident, NPVariant* re sult)
200 {
201 CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
202 return obj->boundClass->getProperty(ident, result);
203 }
204
205 bool CppNPObject::setProperty(NPObject* npObj, NPIdentifier ident, const NPVaria nt* value)
206 {
207 CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
208 return obj->boundClass->setProperty(ident, value);
209 }
210
211 CppBoundClass::~CppBoundClass()
212 {
213 for (MethodList::iterator i = m_methods.begin(); i != m_methods.end(); ++i)
214 delete i->second;
215
216 for (PropertyList::iterator i = m_properties.begin(); i != m_properties.end( ); ++i)
217 delete i->second;
218
219 // Unregister ourselves if we were bound to a frame.
220 if (m_boundToFrame)
221 WebBindings::unregisterObject(NPVARIANT_TO_OBJECT(m_selfVariant));
222 }
223
224 bool CppBoundClass::hasMethod(NPIdentifier ident) const
225 {
226 return m_methods.find(ident) != m_methods.end();
227 }
228
229 bool CppBoundClass::hasProperty(NPIdentifier ident) const
230 {
231 return m_properties.find(ident) != m_properties.end();
232 }
233
234 bool CppBoundClass::invoke(NPIdentifier ident,
235 const NPVariant* arguments,
236 size_t argumentCount,
237 NPVariant* result) {
238 MethodList::const_iterator end = m_methods.end();
239 MethodList::const_iterator method = m_methods.find(ident);
240 Callback* callback;
241 if (method == end) {
242 if (!m_fallbackCallback.get()) {
243 VOID_TO_NPVARIANT(*result);
244 return false;
245 }
246 callback = m_fallbackCallback.get();
247 } else
248 callback = (*method).second;
249
250 // Build a CppArgumentList argument vector from the NPVariants coming in.
251 CppArgumentList cppArguments(argumentCount);
252 for (size_t i = 0; i < argumentCount; i++)
253 cppArguments[i].set(arguments[i]);
254
255 CppVariant cppResult;
256 callback->run(cppArguments, &cppResult);
257
258 cppResult.copyToNPVariant(result);
259 return true;
260 }
261
262 bool CppBoundClass::getProperty(NPIdentifier ident, NPVariant* result) const
263 {
264 PropertyList::const_iterator callback = m_properties.find(ident);
265 if (callback == m_properties.end()) {
266 VOID_TO_NPVARIANT(*result);
267 return false;
268 }
269
270 CppVariant cppValue;
271 if (!callback->second->getValue(&cppValue))
272 return false;
273 cppValue.copyToNPVariant(result);
274 return true;
275 }
276
277 bool CppBoundClass::setProperty(NPIdentifier ident, const NPVariant* value)
278 {
279 PropertyList::iterator callback = m_properties.find(ident);
280 if (callback == m_properties.end())
281 return false;
282
283 CppVariant cppValue;
284 cppValue.set(*value);
285 return (*callback).second->setValue(cppValue);
286 }
287
288 void CppBoundClass::bindCallback(const string& name, Callback* callback)
289 {
290 NPIdentifier ident = WebBindings::getStringIdentifier(name.c_str());
291 MethodList::iterator oldCallback = m_methods.find(ident);
292 if (oldCallback != m_methods.end()) {
293 delete oldCallback->second;
294 if (!callback) {
295 m_methods.erase(oldCallback);
296 return;
297 }
298 }
299
300 m_methods[ident] = callback;
301 }
302
303 void CppBoundClass::bindGetterCallback(const string& name, WebScopedPtr<GetterCa llback> callback)
304 {
305 PropertyCallback* propertyCallback = callback.get() ? new GetterPropertyCall back(callback) : 0;
306 bindProperty(name, propertyCallback);
307 }
308
309 void CppBoundClass::bindProperty(const string& name, CppVariant* prop)
310 {
311 PropertyCallback* propertyCallback = prop ? new CppVariantPropertyCallback(p rop) : 0;
312 bindProperty(name, propertyCallback);
313 }
314
315 void CppBoundClass::bindProperty(const string& name, PropertyCallback* callback)
316 {
317 NPIdentifier ident = WebBindings::getStringIdentifier(name.c_str());
318 PropertyList::iterator oldCallback = m_properties.find(ident);
319 if (oldCallback != m_properties.end()) {
320 delete oldCallback->second;
321 if (!callback) {
322 m_properties.erase(oldCallback);
323 return;
324 }
325 }
326
327 m_properties[ident] = callback;
328 }
329
330 bool CppBoundClass::isMethodRegistered(const string& name) const
331 {
332 NPIdentifier ident = WebBindings::getStringIdentifier(name.c_str());
333 MethodList::const_iterator callback = m_methods.find(ident);
334 return callback != m_methods.end();
335 }
336
337 CppVariant* CppBoundClass::getAsCppVariant()
338 {
339 if (!m_selfVariant.isObject()) {
340 // Create an NPObject using our static NPClass. The first argument (a
341 // plugin's instance handle) is passed through to the allocate function
342 // directly, and we don't use it, so it's ok to be 0.
343 NPObject* npObj = WebBindings::createObject(0, &CppNPObject::npClass);
344 CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
345 obj->boundClass = this;
346 m_selfVariant.set(npObj);
347 WebBindings::releaseObject(npObj); // CppVariant takes the reference.
348 }
349 BLINK_ASSERT(m_selfVariant.isObject());
350 return &m_selfVariant;
351 }
352
353 void CppBoundClass::bindToJavascript(WebFrame* frame, const WebString& classname )
354 {
355 // BindToWindowObject will take its own reference to the NPObject, and clean
356 // up after itself. It will also (indirectly) register the object with V8,
357 // so we must remember this so we can unregister it when we're destroyed.
358 frame->bindToWindowObject(classname, NPVARIANT_TO_OBJECT(*getAsCppVariant()) , 0);
359 m_boundToFrame = true;
360 }
361
362 }
OLDNEW
« no previous file with comments | « content/shell/renderer/test_runner/CppBoundClass.h ('k') | content/shell/renderer/test_runner/CppVariant.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698