2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // NaCl-NPAPI Interface
35 #include "native_client/tools/npapi_runtime/npbridge.h"
39 NPObject
* Alloc(NPP npp
, NPClass
* aClass
) {
40 return nacl::NPObjectProxy::GetLastAllocated();
43 void Deallocate(NPObject
* object
) {
44 delete static_cast<nacl::NPObjectProxy
*>(object
);
47 // Invalidate is called after NPP_Destroy...
48 void Invalidate(NPObject
* object
) {
49 return static_cast<nacl::NPObjectProxy
*>(object
)->Invalidate();
52 bool HasMethod(NPObject
* object
, NPIdentifier name
) {
53 return static_cast<nacl::NPObjectProxy
*>(object
)->HasMethod(name
);
56 bool Invoke(NPObject
* object
, NPIdentifier name
,
57 const NPVariant
* args
, uint32_t arg_count
,
59 return static_cast<nacl::NPObjectProxy
*>(object
)->Invoke(
60 name
, args
, arg_count
, result
);
63 bool InvokeDefault(NPObject
* object
, const NPVariant
* args
, uint32_t arg_count
,
65 return static_cast<nacl::NPObjectProxy
*>(object
)->InvokeDefault(
66 args
, arg_count
, result
);
69 bool HasProperty(NPObject
* object
, NPIdentifier name
) {
70 return static_cast<nacl::NPObjectProxy
*>(object
)->HasProperty(name
);
73 bool GetProperty(NPObject
* object
, NPIdentifier name
, NPVariant
* result
) {
74 return static_cast<nacl::NPObjectProxy
*>(object
)->GetProperty(name
, result
);
77 bool SetProperty(NPObject
* object
, NPIdentifier name
, const NPVariant
* value
) {
78 return static_cast<nacl::NPObjectProxy
*>(object
)->SetProperty(name
, value
);
81 bool RemoveProperty(NPObject
* object
, NPIdentifier name
) {
82 return static_cast<nacl::NPObjectProxy
*>(object
)->RemoveProperty(name
);
85 bool Enumeration(NPObject
* object
, NPIdentifier
* *value
, uint32_t* count
) {
86 return static_cast<nacl::NPObjectProxy
*>(object
)->Enumeration(value
, count
);
89 bool Construct(NPObject
* object
, const NPVariant
* args
, uint32_t arg_count
,
91 return static_cast<nacl::NPObjectProxy
*>(object
)->Construct(args
, arg_count
,
99 #if 1 <= NP_VERSION_MAJOR || 19 <= NP_VERSION_MINOR
101 NPClass
NPObjectProxy::np_class
= {
102 NP_CLASS_STRUCT_VERSION_CTOR
,
117 #else // 1 <= NP_VERSION_MAJOR || 19 <= NP_VERSION_MINOR
119 NPClass
NPObjectProxy::np_class
= {
120 NP_CLASS_STRUCT_VERSION
,
133 #endif // 1 <= NP_VERSION_MAJOR || 19 <= NP_VERSION_MINOR
135 NPObject
* NPObjectProxy::last_allocated
;
137 NPObjectProxy::NPObjectProxy(NPBridge
* bridge
, const NPCapability
& capability
)
139 capability_
.CopyFrom(capability
);
140 last_allocated
= this;
141 NPN_CreateObject(bridge
->npp(), &np_class
);
144 NPObjectProxy::~NPObjectProxy() {
145 if (bridge_
== NULL
) {
149 request
.type
= RPC_DEALLOCATE
;
152 vecp
->base
= &request
;
153 vecp
->length
= sizeof request
;
155 vecp
->base
= &capability_
;
156 vecp
->length
= sizeof capability_
;
159 bridge_
->Request(&request
, vecv
, vecp
- vecv
, &length
);
160 bridge_
->RemoveProxy(this);
163 void NPObjectProxy::Invalidate() {
164 // Note Invalidate() can be called after NPP_Destroy() is called.
165 if (bridge_
== NULL
) {
169 request
.type
= RPC_INVALIDATE
;
172 vecp
->base
= &request
;
173 vecp
->length
= sizeof request
;
175 vecp
->base
= &capability_
;
176 vecp
->length
= sizeof capability_
;
179 bridge_
->Request(&request
, vecv
, vecp
- vecv
, &length
);
182 bool NPObjectProxy::HasMethod(NPIdentifier name
) {
183 RpcStack
stack(bridge_
);
184 if (stack
.Push(name
) == NULL
) {
188 request
.type
= RPC_HAS_METHOD
;
191 vecp
->base
= &request
;
192 vecp
->length
= sizeof request
;
194 vecp
->base
= &capability_
;
195 vecp
->length
= sizeof capability_
;
198 vecp
->length
= sizeof name
;
200 vecp
= stack
.SetIOVec(vecp
);
202 RpcHeader
* reply
= bridge_
->Request(&request
, vecv
, vecp
- vecv
, &length
);
206 return reply
->error_code
? true : false;
209 bool NPObjectProxy::Invoke(NPIdentifier name
,
210 const NPVariant
* args
, uint32_t arg_count
,
211 NPVariant
* variant
) {
212 RpcStack
stack(bridge_
);
213 char converted_args
[kNPVariantSizeMax
* kParamMax
];
214 // Avoid stack overflow if too many parameters are passed.
215 if (kParamMax
< arg_count
) {
218 if (bridge_
->peer_npvariant_size() != sizeof(NPVariant
)) {
219 ConvertNPVariants(args
, converted_args
,
220 bridge_
->peer_npvariant_size(),
223 if (stack
.Push(name
) == NULL
) {
226 for (uint32_t i
= 0; i
< arg_count
; ++i
) {
227 if (stack
.Push(args
[i
], true) == NULL
) {
232 request
.type
= RPC_INVOKE
;
233 request
.error_code
= arg_count
;
236 vecp
->base
= &request
;
237 vecp
->length
= sizeof request
;
239 vecp
->base
= &capability_
;
240 vecp
->length
= sizeof capability_
;
243 vecp
->length
= sizeof name
;
246 if (bridge_
->peer_npvariant_size() == sizeof(NPVariant
)) {
247 vecp
->base
= const_cast<NPVariant
*>(args
);
248 vecp
->length
= arg_count
* sizeof(NPVariant
);
250 vecp
->base
= converted_args
;
251 vecp
->length
= arg_count
* bridge_
->peer_npvariant_size();
255 vecp
= stack
.SetIOVec(vecp
);
257 RpcHeader
* reply
= bridge_
->Request(&request
, vecv
, vecp
- vecv
, &length
);
261 RpcArg
result(bridge_
, reply
, length
);
262 result
.Step(sizeof(RpcHeader
));
263 if (reply
->error_code
!= false) {
264 result
.StepOption(sizeof(NPVariant
));
265 *variant
= *result
.GetVariant(false);
271 bool NPObjectProxy::InvokeDefault(const NPVariant
* args
, uint32_t arg_count
,
272 NPVariant
* variant
) {
273 RpcStack
stack(bridge_
);
274 char converted_args
[kNPVariantSizeMax
* kParamMax
];
275 // Avoid stack overflow if too many parameters are passed.
276 if (kParamMax
< arg_count
) {
279 if (bridge_
->peer_npvariant_size() != sizeof(NPVariant
)) {
280 ConvertNPVariants(args
, converted_args
,
281 bridge_
->peer_npvariant_size(),
284 for (uint32_t i
= 0; i
< arg_count
; ++i
) {
285 if (stack
.Push(args
[i
], true) == NULL
) {
290 request
.type
= RPC_INVOKE_DEFAULT
;
291 request
.error_code
= arg_count
;
294 vecp
->base
= &request
;
295 vecp
->length
= sizeof request
;
297 vecp
->base
= &capability_
;
298 vecp
->length
= sizeof capability_
;
301 if (bridge_
->peer_npvariant_size() == sizeof(NPVariant
)) {
302 vecp
->base
= const_cast<NPVariant
*>(args
);
303 vecp
->length
= arg_count
* sizeof(NPVariant
);
305 vecp
->base
= converted_args
;
306 vecp
->length
= arg_count
* bridge_
->peer_npvariant_size();
310 vecp
= stack
.SetIOVec(vecp
);
312 RpcHeader
* reply
= bridge_
->Request(&request
, vecv
, vecp
- vecv
, &length
);
316 RpcArg
result(bridge_
, reply
, length
);
317 result
.Step(sizeof(RpcHeader
));
318 if (reply
->error_code
!= false) {
319 result
.StepOption(sizeof(NPVariant
));
320 *variant
= *result
.GetVariant(false);
326 bool NPObjectProxy::HasProperty(NPIdentifier name
) {
327 RpcStack
stack(bridge_
);
328 if (stack
.Push(name
) == NULL
) {
332 request
.type
= RPC_HAS_PROPERTY
;
335 vecp
->base
= &request
;
336 vecp
->length
= sizeof request
;
338 vecp
->base
= &capability_
;
339 vecp
->length
= sizeof capability_
;
342 vecp
->length
= sizeof name
;
344 vecp
= stack
.SetIOVec(vecp
);
346 RpcHeader
* reply
= bridge_
->Request(&request
, vecv
, vecp
- vecv
, &length
);
350 return reply
->error_code
? true : false;
353 bool NPObjectProxy::GetProperty(NPIdentifier name
, NPVariant
* variant
) {
354 RpcStack
stack(bridge_
);
355 if (stack
.Push(name
) == NULL
) {
359 request
.type
= RPC_GET_PROPERTY
;
362 vecp
->base
= &request
;
363 vecp
->length
= sizeof request
;
365 vecp
->base
= &capability_
;
366 vecp
->length
= sizeof capability_
;
369 vecp
->length
= sizeof name
;
371 vecp
= stack
.SetIOVec(vecp
);
373 RpcHeader
* reply
= bridge_
->Request(&request
, vecv
, vecp
- vecv
, &length
);
377 RpcArg
result(bridge_
, reply
, length
);
378 result
.Step(sizeof(RpcHeader
));
379 if (reply
->error_code
!= false) {
380 result
.StepOption(sizeof(NPVariant
));
381 *variant
= *result
.GetVariant(false);
387 bool NPObjectProxy::SetProperty(NPIdentifier name
, const NPVariant
* value
) {
388 RpcStack
stack(bridge_
);
389 char converted_value
[kNPVariantSizeMax
];
390 if (bridge_
->peer_npvariant_size() != sizeof(NPVariant
)) {
391 ConvertNPVariants(value
, converted_value
,
392 bridge_
->peer_npvariant_size(),
395 if (stack
.Push(name
) == NULL
) {
398 if (stack
.Push(*value
, true) == NULL
) {
402 request
.type
= RPC_SET_PROPERTY
;
405 vecp
->base
= &request
;
406 vecp
->length
= sizeof request
;
408 vecp
->base
= &capability_
;
409 vecp
->length
= sizeof capability_
;
412 vecp
->length
= sizeof name
;
414 if (bridge_
->peer_npvariant_size() == sizeof(NPVariant
)) {
415 vecp
->base
= const_cast<NPVariant
*>(value
);
416 vecp
->length
= sizeof(NPVariant
);
418 vecp
->base
= converted_value
;
419 vecp
->length
= bridge_
->peer_npvariant_size();
422 vecp
= stack
.SetIOVec(vecp
);
424 RpcHeader
* reply
= bridge_
->Request(&request
, vecv
, vecp
- vecv
, &length
);
428 return reply
->error_code
? true : false;
431 bool NPObjectProxy::RemoveProperty(NPIdentifier name
) {
432 RpcStack
stack(bridge_
);
433 if (stack
.Push(name
) == NULL
) {
437 request
.type
= RPC_REMOVE_PROPERTY
;
440 vecp
->base
= &request
;
441 vecp
->length
= sizeof request
;
443 vecp
->base
= &capability_
;
444 vecp
->length
= sizeof capability_
;
447 vecp
->length
= sizeof name
;
449 vecp
= stack
.SetIOVec(vecp
);
451 RpcHeader
* reply
= bridge_
->Request(&request
, vecv
, vecp
- vecv
, &length
);
455 return reply
->error_code
? true : false;
458 bool NPObjectProxy::Enumeration(NPIdentifier
* *value
, uint32_t* count
) {
462 bool NPObjectProxy::Construct(const NPVariant
* args
, uint32_t arg_count
,
467 void NPObjectProxy::SetException(const NPUTF8
* message
) {
469 request
.type
= RPC_SET_EXCEPTION
;
472 vecp
->base
= &request
;
473 vecp
->length
= sizeof request
;
475 vecp
->base
= &capability_
;
476 vecp
->length
= sizeof capability_
;
478 vecp
->base
= const_cast<NPUTF8
*>(message
);
479 vecp
->length
= strlen(message
) + 1;
481 bridge_
->Request(&request
, vecv
, vecp
- vecv
, NULL
);
484 int NPObjectProxy::SetException(RpcHeader
* request
, int len
) {
485 RpcArg
arg(bridge_
, request
, len
);
486 arg
.Step(sizeof(RpcHeader
));
487 arg
.Step(sizeof(NPCapability
));
488 const NPUTF8
* message
= arg
.GetString();
489 NPN_SetException(this, message
? message
: "");
492 vecp
->base
= request
;
493 vecp
->length
= sizeof(RpcHeader
);
495 return bridge_
->Respond(request
, vecv
, vecp
- vecv
);