1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4
5 #include <Proxy.h>
6 #include <Connection.h>
7 #include <Endpoint.h>
8 #include <Util.h>
9
10 using namespace std;
11 using namespace IcePHP;
12
13 ZEND_EXTERN_MODULE_GLOBALS(ice)
14
15 //
16 // Here's a brief description of how proxies are handled by this extension.
17 //
18 // A single PHP class, ObjectPrx, is registered. This is an "internal" class,
19 // i.e., implemented by this extension, and it is used to represent all proxies
20 // regardless of interface type.
21 //
22 // Like in C++, a proxy is only capable of invoking the Ice::ObjectPrx operations
23 // until it is narrowed with a checked or unchecked cast. Unlike C++, no PHP classes
24 // are created for proxies, because all marshaling activity is driven by the type
25 // definitions, not by statically-generated code.
26 //
27 // In order to perform a checked or unchecked cast, the generated code invokes
28 // ice_checkedCast or ice_uncheckedCast on the proxy to be narrowed, supplying a scoped
29 // name for the desired type. Internally, the proxy validates the scoped name and returns
30 // a new proxy containing the class or interface definition. This proxy is considered
31 // to be narrowed to that interface and therefore supports user-defined operations.
32 //
33 // Naturally, there are many predefined proxy methods (e.g., ice_getIdentity, etc.), but
34 // the proxy also needs to support user-defined operations (if it has type information).
35 // We use a Zend API hook that allows us to intercept the invocation of unknown methods
36 // on the proxy object.
37 //
38
39 //
40 // Class entries represent the PHP class implementations we have registered.
41 //
42 namespace IcePHP
43 {
44 zend_class_entry* proxyClassEntry = 0;
45 }
46
47 //
48 // Ice::ObjectPrx support.
49 //
50 static zend_object_handlers _handlers;
51
52 extern "C"
53 {
54 static zend_object_value handleAlloc(zend_class_entry* TSRMLS_DC);
55 static void handleFreeStorage(void* TSRMLS_DC);
56 static zend_object_value handleClone(zval* TSRMLS_DC);
57 #if PHP_VERSION_ID < 50400
58 static union _zend_function* handleGetMethod(zval**, char*, int TSRMLS_DC);
59 #else
60 static union _zend_function* handleGetMethod(zval**, char*, int, const _zend_literal* TSRMLS_DC);
61 #endif
62 static int handleCompare(zval*, zval* TSRMLS_DC);
63 }
64
65 namespace IcePHP
66 {
67
68 //
69 // Encapsulates proxy and type information.
70 //
71 class Proxy : public IceUtil::Shared
72 {
73 public:
74
75 Proxy(const Ice::ObjectPrx&, const ProxyInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC);
76 ~Proxy();
77
78 bool clone(zval*, const Ice::ObjectPrx& TSRMLS_DC);
79 bool cloneUntyped(zval*, const Ice::ObjectPrx& TSRMLS_DC);
80 static bool create(zval*, const Ice::ObjectPrx&, const ProxyInfoPtr&, const CommunicatorInfoPtr& TSRMLS_DC);
81
82 Ice::ObjectPrx proxy;
83 ProxyInfoPtr info;
84 CommunicatorInfoPtr communicator;
85 zval* connection;
86 zval* cachedConnection;
87 #if ZTS
88 TSRMLS_D;
89 #endif
90 };
91 typedef IceUtil::Handle<Proxy> ProxyPtr;
92
93 } // End of namespace IcePHP
94
ZEND_METHOD(Ice_ObjectPrx,__construct)95 ZEND_METHOD(Ice_ObjectPrx, __construct)
96 {
97 runtimeError("proxies cannot be instantiated, use stringToProxy()" TSRMLS_CC);
98 }
99
ZEND_METHOD(Ice_ObjectPrx,__toString)100 ZEND_METHOD(Ice_ObjectPrx, __toString)
101 {
102 if(ZEND_NUM_ARGS() > 0)
103 {
104 WRONG_PARAM_COUNT;
105 }
106
107 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
108 assert(_this);
109
110 try
111 {
112 string str = _this->proxy->ice_toString();
113 RETURN_STRINGL(STRCAST(str.c_str()), static_cast<int>(str.length()), 1);
114 }
115 catch(const IceUtil::Exception& ex)
116 {
117 throwException(ex TSRMLS_CC);
118 RETURN_NULL();
119 }
120 }
121
ZEND_METHOD(Ice_ObjectPrx,ice_getCommunicator)122 ZEND_METHOD(Ice_ObjectPrx, ice_getCommunicator)
123 {
124 if(ZEND_NUM_ARGS() > 0)
125 {
126 WRONG_PARAM_COUNT;
127 }
128
129 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
130 assert(_this);
131
132 _this->communicator->getZval(return_value TSRMLS_CC);
133 }
134
ZEND_METHOD(Ice_ObjectPrx,ice_toString)135 ZEND_METHOD(Ice_ObjectPrx, ice_toString)
136 {
137 ZEND_MN(Ice_ObjectPrx___toString)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
138 }
139
ZEND_METHOD(Ice_ObjectPrx,ice_getIdentity)140 ZEND_METHOD(Ice_ObjectPrx, ice_getIdentity)
141 {
142 if(ZEND_NUM_ARGS() != 0)
143 {
144 WRONG_PARAM_COUNT;
145 }
146
147 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
148 assert(_this);
149
150 createIdentity(return_value, _this->proxy->ice_getIdentity() TSRMLS_CC);
151 }
152
ZEND_METHOD(Ice_ObjectPrx,ice_identity)153 ZEND_METHOD(Ice_ObjectPrx, ice_identity)
154 {
155 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
156 assert(_this);
157
158 zend_class_entry* cls = idToClass("::Ice::Identity" TSRMLS_CC);
159 assert(cls);
160
161 zval *zid;
162
163 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("O"), &zid, cls) == FAILURE)
164 {
165 RETURN_NULL();
166 }
167
168 Ice::Identity id;
169 if(extractIdentity(zid, id TSRMLS_CC))
170 {
171 try
172 {
173 if(!_this->cloneUntyped(return_value, _this->proxy->ice_identity(id) TSRMLS_CC))
174 {
175 RETURN_NULL();
176 }
177 }
178 catch(const IceUtil::Exception& ex)
179 {
180 throwException(ex TSRMLS_CC);
181 RETURN_NULL();
182 }
183 }
184 }
185
ZEND_METHOD(Ice_ObjectPrx,ice_getContext)186 ZEND_METHOD(Ice_ObjectPrx, ice_getContext)
187 {
188 if(ZEND_NUM_ARGS() != 0)
189 {
190 WRONG_PARAM_COUNT;
191 }
192
193 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
194 assert(_this);
195
196 if(!createStringMap(return_value, _this->proxy->ice_getContext() TSRMLS_CC))
197 {
198 RETURN_NULL();
199 }
200 }
201
ZEND_METHOD(Ice_ObjectPrx,ice_context)202 ZEND_METHOD(Ice_ObjectPrx, ice_context)
203 {
204 zval* arr = 0;
205
206 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("a"), &arr) == FAILURE)
207 {
208 RETURN_NULL();
209 }
210
211 //
212 // Populate the context.
213 //
214 Ice::Context ctx;
215 if(arr && !extractStringMap(arr, ctx TSRMLS_CC))
216 {
217 RETURN_NULL();
218 }
219
220 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
221 assert(_this);
222
223 try
224 {
225 if(!_this->clone(return_value, _this->proxy->ice_context(ctx) TSRMLS_CC))
226 {
227 RETURN_NULL();
228 }
229 }
230 catch(const IceUtil::Exception& ex)
231 {
232 throwException(ex TSRMLS_CC);
233 RETURN_NULL();
234 }
235 }
236
ZEND_METHOD(Ice_ObjectPrx,ice_getFacet)237 ZEND_METHOD(Ice_ObjectPrx, ice_getFacet)
238 {
239 if(ZEND_NUM_ARGS() != 0)
240 {
241 WRONG_PARAM_COUNT;
242 }
243
244 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
245 assert(_this);
246
247 try
248 {
249 string facet = _this->proxy->ice_getFacet();
250 ZVAL_STRINGL(return_value, STRCAST(facet.c_str()), static_cast<int>(facet.length()), 1);
251 }
252 catch(const IceUtil::Exception& ex)
253 {
254 throwException(ex TSRMLS_CC);
255 RETURN_NULL();
256 }
257 }
258
ZEND_METHOD(Ice_ObjectPrx,ice_facet)259 ZEND_METHOD(Ice_ObjectPrx, ice_facet)
260 {
261 char* name;
262 int len;
263
264 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("s"), &name, &len) == FAILURE)
265 {
266 RETURN_NULL();
267 }
268
269 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
270 assert(_this);
271
272 try
273 {
274 if(!_this->cloneUntyped(return_value, _this->proxy->ice_facet(name) TSRMLS_CC))
275 {
276 RETURN_NULL();
277 }
278 }
279 catch(const IceUtil::Exception& ex)
280 {
281 throwException(ex TSRMLS_CC);
282 RETURN_NULL();
283 }
284 }
285
ZEND_METHOD(Ice_ObjectPrx,ice_getAdapterId)286 ZEND_METHOD(Ice_ObjectPrx, ice_getAdapterId)
287 {
288 if(ZEND_NUM_ARGS() != 0)
289 {
290 WRONG_PARAM_COUNT;
291 }
292
293 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
294 assert(_this);
295
296 try
297 {
298 string id = _this->proxy->ice_getAdapterId();
299 ZVAL_STRINGL(return_value, STRCAST(id.c_str()), static_cast<int>(id.length()), 1);
300 }
301 catch(const IceUtil::Exception& ex)
302 {
303 throwException(ex TSRMLS_CC);
304 RETURN_NULL();
305 }
306 }
307
ZEND_METHOD(Ice_ObjectPrx,ice_adapterId)308 ZEND_METHOD(Ice_ObjectPrx, ice_adapterId)
309 {
310 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
311 assert(_this);
312
313 char* id;
314 int len;
315
316 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("s"), &id, &len) == FAILURE)
317 {
318 RETURN_NULL();
319 }
320
321 try
322 {
323 if(!_this->clone(return_value, _this->proxy->ice_adapterId(id) TSRMLS_CC))
324 {
325 RETURN_NULL();
326 }
327 }
328 catch(const IceUtil::Exception& ex)
329 {
330 throwException(ex TSRMLS_CC);
331 RETURN_NULL();
332 }
333 }
334
ZEND_METHOD(Ice_ObjectPrx,ice_getEndpoints)335 ZEND_METHOD(Ice_ObjectPrx, ice_getEndpoints)
336 {
337 if(ZEND_NUM_ARGS() != 0)
338 {
339 WRONG_PARAM_COUNT;
340 }
341
342 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
343 assert(_this);
344
345 try
346 {
347 Ice::EndpointSeq endpoints = _this->proxy->ice_getEndpoints();
348
349 array_init(return_value);
350 uint idx = 0;
351 for(Ice::EndpointSeq::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p, ++idx)
352 {
353 zval* elem;
354 MAKE_STD_ZVAL(elem);
355 if(!createEndpoint(elem, *p TSRMLS_CC))
356 {
357 zval_ptr_dtor(&elem);
358 RETURN_NULL();
359 }
360 add_index_zval(return_value, idx, elem);
361 }
362 }
363 catch(const IceUtil::Exception& ex)
364 {
365 throwException(ex TSRMLS_CC);
366 RETURN_NULL();
367 }
368 }
369
ZEND_METHOD(Ice_ObjectPrx,ice_endpoints)370 ZEND_METHOD(Ice_ObjectPrx, ice_endpoints)
371 {
372 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
373 assert(_this);
374
375 zval* zv;
376
377 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("a"), &zv) == FAILURE)
378 {
379 RETURN_NULL();
380 }
381
382 Ice::EndpointSeq seq;
383
384 HashTable* arr = Z_ARRVAL_P(zv);
385 HashPosition pos;
386 void* data;
387
388 zend_hash_internal_pointer_reset_ex(arr, &pos);
389 while(zend_hash_get_current_data_ex(arr, &data, &pos) != FAILURE)
390 {
391 zval** val = reinterpret_cast<zval**>(data);
392
393 if(Z_TYPE_PP(val) != IS_OBJECT)
394 {
395 runtimeError("expected an element of type Ice::Endpoint" TSRMLS_CC);
396 RETURN_NULL();
397 }
398
399 Ice::EndpointPtr endpoint;
400 if(!fetchEndpoint(*val, endpoint TSRMLS_CC))
401 {
402 RETURN_NULL();
403 }
404
405 seq.push_back(endpoint);
406
407 zend_hash_move_forward_ex(arr, &pos);
408 }
409
410 try
411 {
412 if(!_this->clone(return_value, _this->proxy->ice_endpoints(seq) TSRMLS_CC))
413 {
414 RETURN_NULL();
415 }
416 }
417 catch(const IceUtil::Exception& ex)
418 {
419 throwException(ex TSRMLS_CC);
420 RETURN_NULL();
421 }
422 }
423
ZEND_METHOD(Ice_ObjectPrx,ice_getLocatorCacheTimeout)424 ZEND_METHOD(Ice_ObjectPrx, ice_getLocatorCacheTimeout)
425 {
426 if(ZEND_NUM_ARGS() != 0)
427 {
428 WRONG_PARAM_COUNT;
429 }
430
431 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
432 assert(_this);
433
434 try
435 {
436 Ice::Int timeout = _this->proxy->ice_getLocatorCacheTimeout();
437 ZVAL_LONG(return_value, static_cast<long>(timeout));
438 }
439 catch(const IceUtil::Exception& ex)
440 {
441 throwException(ex TSRMLS_CC);
442 RETURN_NULL();
443 }
444 }
445
ZEND_METHOD(Ice_ObjectPrx,ice_getConnectionId)446 ZEND_METHOD(Ice_ObjectPrx, ice_getConnectionId)
447 {
448 if(ZEND_NUM_ARGS() != 0)
449 {
450 WRONG_PARAM_COUNT;
451 }
452
453 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
454 assert(_this);
455
456 try
457 {
458 string connectionId = _this->proxy->ice_getConnectionId();
459 ZVAL_STRINGL(return_value, STRCAST(connectionId.c_str()), static_cast<int>(connectionId.length()), 1);
460 }
461 catch(const IceUtil::Exception& ex)
462 {
463 throwException(ex TSRMLS_CC);
464 RETURN_NULL();
465 }
466 }
467
ZEND_METHOD(Ice_ObjectPrx,ice_locatorCacheTimeout)468 ZEND_METHOD(Ice_ObjectPrx, ice_locatorCacheTimeout)
469 {
470 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
471 assert(_this);
472
473 long l;
474 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("l"), &l) != SUCCESS)
475 {
476 RETURN_NULL();
477 }
478
479 try
480 {
481 if(!_this->clone(return_value, _this->proxy->ice_locatorCacheTimeout(l) TSRMLS_CC))
482 {
483 RETURN_NULL();
484 }
485 }
486 catch(const IceUtil::Exception& ex)
487 {
488 throwException(ex TSRMLS_CC);
489 RETURN_NULL();
490 }
491 }
492
ZEND_METHOD(Ice_ObjectPrx,ice_isConnectionCached)493 ZEND_METHOD(Ice_ObjectPrx, ice_isConnectionCached)
494 {
495 if(ZEND_NUM_ARGS() != 0)
496 {
497 WRONG_PARAM_COUNT;
498 }
499
500 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
501 assert(_this);
502
503 try
504 {
505 bool b = _this->proxy->ice_isConnectionCached();
506 ZVAL_BOOL(return_value, b ? 1 : 0);
507 }
508 catch(const IceUtil::Exception& ex)
509 {
510 throwException(ex TSRMLS_CC);
511 RETURN_NULL();
512 }
513 }
514
ZEND_METHOD(Ice_ObjectPrx,ice_connectionCached)515 ZEND_METHOD(Ice_ObjectPrx, ice_connectionCached)
516 {
517 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
518 assert(_this);
519
520 zend_bool b;
521 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("b"), &b) != SUCCESS)
522 {
523 RETURN_NULL();
524 }
525
526 try
527 {
528 if(!_this->clone(return_value, _this->proxy->ice_connectionCached(b ? true : false) TSRMLS_CC))
529 {
530 RETURN_NULL();
531 }
532 }
533 catch(const IceUtil::Exception& ex)
534 {
535 throwException(ex TSRMLS_CC);
536 RETURN_NULL();
537 }
538 }
539
ZEND_METHOD(Ice_ObjectPrx,ice_getEndpointSelection)540 ZEND_METHOD(Ice_ObjectPrx, ice_getEndpointSelection)
541 {
542 if(ZEND_NUM_ARGS() != 0)
543 {
544 WRONG_PARAM_COUNT;
545 }
546
547 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
548 assert(_this);
549
550 try
551 {
552 Ice::EndpointSelectionType type = _this->proxy->ice_getEndpointSelection();
553 ZVAL_LONG(return_value, type == Ice::Random ? 0 : 1);
554 }
555 catch(const IceUtil::Exception& ex)
556 {
557 throwException(ex TSRMLS_CC);
558 RETURN_NULL();
559 }
560 }
561
ZEND_METHOD(Ice_ObjectPrx,ice_endpointSelection)562 ZEND_METHOD(Ice_ObjectPrx, ice_endpointSelection)
563 {
564 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
565 assert(_this);
566
567 long l;
568 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("l"), &l) != SUCCESS)
569 {
570 RETURN_NULL();
571 }
572
573 if(l < 0 || l > 1)
574 {
575 runtimeError("expecting Random or Ordered" TSRMLS_CC);
576 RETURN_NULL();
577 }
578
579 try
580 {
581 Ice::EndpointSelectionType type = l == 0 ? Ice::Random : Ice::Ordered;
582 if(!_this->clone(return_value, _this->proxy->ice_endpointSelection(type) TSRMLS_CC))
583 {
584 RETURN_NULL();
585 }
586 }
587 catch(const IceUtil::Exception& ex)
588 {
589 throwException(ex TSRMLS_CC);
590 RETURN_NULL();
591 }
592 }
593
ZEND_METHOD(Ice_ObjectPrx,ice_isSecure)594 ZEND_METHOD(Ice_ObjectPrx, ice_isSecure)
595 {
596 if(ZEND_NUM_ARGS() != 0)
597 {
598 WRONG_PARAM_COUNT;
599 }
600
601 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
602 assert(_this);
603
604 try
605 {
606 bool b = _this->proxy->ice_isSecure();
607 RETURN_BOOL(b ? 1 : 0);
608 }
609 catch(const IceUtil::Exception& ex)
610 {
611 throwException(ex TSRMLS_CC);
612 RETURN_FALSE;
613 }
614 }
615
ZEND_METHOD(Ice_ObjectPrx,ice_secure)616 ZEND_METHOD(Ice_ObjectPrx, ice_secure)
617 {
618 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
619 assert(_this);
620
621 zend_bool b;
622 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("b"), &b TSRMLS_CC) != SUCCESS)
623 {
624 RETURN_NULL();
625 }
626
627 try
628 {
629 if(!_this->clone(return_value, _this->proxy->ice_secure(b ? true : false) TSRMLS_CC))
630 {
631 RETURN_NULL();
632 }
633 }
634 catch(const IceUtil::Exception& ex)
635 {
636 throwException(ex TSRMLS_CC);
637 RETURN_NULL();
638 }
639 }
640
ZEND_METHOD(Ice_ObjectPrx,ice_getEncodingVersion)641 ZEND_METHOD(Ice_ObjectPrx, ice_getEncodingVersion)
642 {
643 if(ZEND_NUM_ARGS() != 0)
644 {
645 WRONG_PARAM_COUNT;
646 }
647
648 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
649 assert(_this);
650
651 try
652 {
653 if(!createEncodingVersion(return_value, _this->proxy->ice_getEncodingVersion() TSRMLS_CC))
654 {
655 RETURN_NULL();
656 }
657 }
658 catch(const IceUtil::Exception& ex)
659 {
660 throwException(ex TSRMLS_CC);
661 RETURN_NULL();
662 }
663 }
664
ZEND_METHOD(Ice_ObjectPrx,ice_encodingVersion)665 ZEND_METHOD(Ice_ObjectPrx, ice_encodingVersion)
666 {
667 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
668 assert(_this);
669
670 zend_class_entry* cls = idToClass("::Ice::EncodingVersion" TSRMLS_CC);
671 assert(cls);
672
673 zval *zv;
674 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("O"), &zv, cls) == FAILURE)
675 {
676 RETURN_NULL();
677 }
678
679 Ice::EncodingVersion v;
680 if(extractEncodingVersion(zv, v TSRMLS_CC))
681 {
682 try
683 {
684 if(!_this->clone(return_value, _this->proxy->ice_encodingVersion(v) TSRMLS_CC))
685 {
686 RETURN_NULL();
687 }
688 }
689 catch(const IceUtil::Exception& ex)
690 {
691 throwException(ex TSRMLS_CC);
692 RETURN_NULL();
693 }
694 }
695 }
696
ZEND_METHOD(Ice_ObjectPrx,ice_isPreferSecure)697 ZEND_METHOD(Ice_ObjectPrx, ice_isPreferSecure)
698 {
699 if(ZEND_NUM_ARGS() != 0)
700 {
701 WRONG_PARAM_COUNT;
702 }
703
704 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
705 assert(_this);
706
707 try
708 {
709 bool b = _this->proxy->ice_isPreferSecure();
710 RETURN_BOOL(b ? 1 : 0);
711 }
712 catch(const IceUtil::Exception& ex)
713 {
714 throwException(ex TSRMLS_CC);
715 RETURN_FALSE;
716 }
717 }
718
ZEND_METHOD(Ice_ObjectPrx,ice_preferSecure)719 ZEND_METHOD(Ice_ObjectPrx, ice_preferSecure)
720 {
721 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
722 assert(_this);
723
724 zend_bool b;
725 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("b"), &b TSRMLS_CC) != SUCCESS)
726 {
727 RETURN_NULL();
728 }
729
730 try
731 {
732 if(!_this->clone(return_value, _this->proxy->ice_preferSecure(b ? true : false) TSRMLS_CC))
733 {
734 RETURN_NULL();
735 }
736 }
737 catch(const IceUtil::Exception& ex)
738 {
739 throwException(ex TSRMLS_CC);
740 RETURN_NULL();
741 }
742 }
743
ZEND_METHOD(Ice_ObjectPrx,ice_getRouter)744 ZEND_METHOD(Ice_ObjectPrx, ice_getRouter)
745 {
746 if(ZEND_NUM_ARGS() != 0)
747 {
748 WRONG_PARAM_COUNT;
749 }
750
751 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
752 assert(_this);
753
754 try
755 {
756 Ice::RouterPrx router = _this->proxy->ice_getRouter();
757 if(router)
758 {
759 ProxyInfoPtr info = getProxyInfo("::Ice::Router" TSRMLS_CC);
760 if(!info)
761 {
762 RETURN_NULL();
763 }
764
765 assert(info);
766
767 if(!createProxy(return_value, router, info, _this->communicator TSRMLS_CC))
768 {
769 RETURN_NULL();
770 }
771 }
772 else
773 {
774 RETURN_NULL();
775 }
776 }
777 catch(const IceUtil::Exception& ex)
778 {
779 throwException(ex TSRMLS_CC);
780 RETURN_FALSE;
781 }
782 }
783
ZEND_METHOD(Ice_ObjectPrx,ice_router)784 ZEND_METHOD(Ice_ObjectPrx, ice_router)
785 {
786 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
787 assert(_this);
788
789 zval* zprx;
790 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("O!"), &zprx, proxyClassEntry TSRMLS_CC) !=
791 SUCCESS)
792 {
793 RETURN_NULL();
794 }
795
796 Ice::ObjectPrx proxy;
797 ProxyInfoPtr def;
798 if(zprx && !fetchProxy(zprx, proxy, def TSRMLS_CC))
799 {
800 RETURN_NULL();
801 }
802
803 Ice::RouterPrx router;
804 if(proxy)
805 {
806 if(!def || !def->isA("::Ice::Router"))
807 {
808 runtimeError("ice_router requires a proxy narrowed to Ice::Router" TSRMLS_CC);
809 RETURN_NULL();
810 }
811 router = Ice::RouterPrx::uncheckedCast(proxy);
812 }
813
814 try
815 {
816 if(!_this->clone(return_value, _this->proxy->ice_router(router) TSRMLS_CC))
817 {
818 RETURN_NULL();
819 }
820 }
821 catch(const IceUtil::Exception& ex)
822 {
823 throwException(ex TSRMLS_CC);
824 RETURN_NULL();
825 }
826 }
827
ZEND_METHOD(Ice_ObjectPrx,ice_getLocator)828 ZEND_METHOD(Ice_ObjectPrx, ice_getLocator)
829 {
830 if(ZEND_NUM_ARGS() != 0)
831 {
832 WRONG_PARAM_COUNT;
833 }
834
835 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
836 assert(_this);
837
838 try
839 {
840 Ice::LocatorPrx locator = _this->proxy->ice_getLocator();
841 if(locator)
842 {
843 ProxyInfoPtr info = getProxyInfo("::Ice::Locator" TSRMLS_CC);
844 if(!info)
845 {
846 RETURN_NULL();
847 }
848
849 if(!createProxy(return_value, locator, info, _this->communicator TSRMLS_CC))
850 {
851 RETURN_NULL();
852 }
853 }
854 else
855 {
856 RETURN_NULL();
857 }
858 }
859 catch(const IceUtil::Exception& ex)
860 {
861 throwException(ex TSRMLS_CC);
862 RETURN_FALSE;
863 }
864 }
865
ZEND_METHOD(Ice_ObjectPrx,ice_locator)866 ZEND_METHOD(Ice_ObjectPrx, ice_locator)
867 {
868 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
869 assert(_this);
870
871 zval* zprx;
872 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("O!"), &zprx, proxyClassEntry TSRMLS_CC) !=
873 SUCCESS)
874 {
875 RETURN_NULL();
876 }
877
878 Ice::ObjectPrx proxy;
879 ProxyInfoPtr def;
880 if(zprx && !fetchProxy(zprx, proxy, def TSRMLS_CC))
881 {
882 RETURN_NULL();
883 }
884
885 Ice::LocatorPrx locator;
886 if(proxy)
887 {
888 if(!def || !def->isA("::Ice::Locator"))
889 {
890 runtimeError("ice_locator requires a proxy narrowed to Ice::Locator" TSRMLS_CC);
891 RETURN_NULL();
892 }
893 locator = Ice::LocatorPrx::uncheckedCast(proxy);
894 }
895
896 try
897 {
898 if(!_this->clone(return_value, _this->proxy->ice_locator(locator) TSRMLS_CC))
899 {
900 RETURN_NULL();
901 }
902 }
903 catch(const IceUtil::Exception& ex)
904 {
905 throwException(ex TSRMLS_CC);
906 RETURN_NULL();
907 }
908 }
909
ZEND_METHOD(Ice_ObjectPrx,ice_twoway)910 ZEND_METHOD(Ice_ObjectPrx, ice_twoway)
911 {
912 if(ZEND_NUM_ARGS() != 0)
913 {
914 WRONG_PARAM_COUNT;
915 }
916
917 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
918 assert(_this);
919
920 try
921 {
922 if(!_this->clone(return_value, _this->proxy->ice_twoway() TSRMLS_CC))
923 {
924 RETURN_NULL();
925 }
926 }
927 catch(const IceUtil::Exception& ex)
928 {
929 throwException(ex TSRMLS_CC);
930 RETURN_NULL();
931 }
932 }
933
ZEND_METHOD(Ice_ObjectPrx,ice_isTwoway)934 ZEND_METHOD(Ice_ObjectPrx, ice_isTwoway)
935 {
936 if(ZEND_NUM_ARGS() != 0)
937 {
938 WRONG_PARAM_COUNT;
939 }
940
941 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
942 assert(_this);
943
944 try
945 {
946 bool b = _this->proxy->ice_isTwoway();
947 RETURN_BOOL(b ? 1 : 0);
948 }
949 catch(const IceUtil::Exception& ex)
950 {
951 throwException(ex TSRMLS_CC);
952 RETURN_FALSE;
953 }
954 }
955
ZEND_METHOD(Ice_ObjectPrx,ice_oneway)956 ZEND_METHOD(Ice_ObjectPrx, ice_oneway)
957 {
958 if(ZEND_NUM_ARGS() != 0)
959 {
960 WRONG_PARAM_COUNT;
961 }
962
963 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
964 assert(_this);
965
966 try
967 {
968 if(!_this->clone(return_value, _this->proxy->ice_oneway() TSRMLS_CC))
969 {
970 RETURN_NULL();
971 }
972 }
973 catch(const IceUtil::Exception& ex)
974 {
975 throwException(ex TSRMLS_CC);
976 RETURN_NULL();
977 }
978 }
979
ZEND_METHOD(Ice_ObjectPrx,ice_isOneway)980 ZEND_METHOD(Ice_ObjectPrx, ice_isOneway)
981 {
982 if(ZEND_NUM_ARGS() != 0)
983 {
984 WRONG_PARAM_COUNT;
985 }
986
987 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
988 assert(_this);
989
990 try
991 {
992 bool b = _this->proxy->ice_isOneway();
993 RETURN_BOOL(b ? 1 : 0);
994 }
995 catch(const IceUtil::Exception& ex)
996 {
997 throwException(ex TSRMLS_CC);
998 RETURN_FALSE;
999 }
1000 }
1001
ZEND_METHOD(Ice_ObjectPrx,ice_batchOneway)1002 ZEND_METHOD(Ice_ObjectPrx, ice_batchOneway)
1003 {
1004 if(ZEND_NUM_ARGS() != 0)
1005 {
1006 WRONG_PARAM_COUNT;
1007 }
1008
1009 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1010 assert(_this);
1011
1012 try
1013 {
1014 if(!_this->clone(return_value, _this->proxy->ice_batchOneway() TSRMLS_CC))
1015 {
1016 RETURN_NULL();
1017 }
1018 }
1019 catch(const IceUtil::Exception& ex)
1020 {
1021 throwException(ex TSRMLS_CC);
1022 RETURN_NULL();
1023 }
1024 }
1025
ZEND_METHOD(Ice_ObjectPrx,ice_isBatchOneway)1026 ZEND_METHOD(Ice_ObjectPrx, ice_isBatchOneway)
1027 {
1028 if(ZEND_NUM_ARGS() != 0)
1029 {
1030 WRONG_PARAM_COUNT;
1031 }
1032
1033 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1034 assert(_this);
1035
1036 try
1037 {
1038 bool b = _this->proxy->ice_isBatchOneway();
1039 RETURN_BOOL(b ? 1 : 0);
1040 }
1041 catch(const IceUtil::Exception& ex)
1042 {
1043 throwException(ex TSRMLS_CC);
1044 RETURN_FALSE;
1045 }
1046 }
1047
ZEND_METHOD(Ice_ObjectPrx,ice_datagram)1048 ZEND_METHOD(Ice_ObjectPrx, ice_datagram)
1049 {
1050 if(ZEND_NUM_ARGS() != 0)
1051 {
1052 WRONG_PARAM_COUNT;
1053 }
1054
1055 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1056 assert(_this);
1057
1058 try
1059 {
1060 if(!_this->clone(return_value, _this->proxy->ice_datagram() TSRMLS_CC))
1061 {
1062 RETURN_NULL();
1063 }
1064 }
1065 catch(const IceUtil::Exception& ex)
1066 {
1067 throwException(ex TSRMLS_CC);
1068 RETURN_NULL();
1069 }
1070 }
1071
ZEND_METHOD(Ice_ObjectPrx,ice_isDatagram)1072 ZEND_METHOD(Ice_ObjectPrx, ice_isDatagram)
1073 {
1074 if(ZEND_NUM_ARGS() != 0)
1075 {
1076 WRONG_PARAM_COUNT;
1077 }
1078
1079 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1080 assert(_this);
1081
1082 try
1083 {
1084 bool b = _this->proxy->ice_isDatagram();
1085 RETURN_BOOL(b ? 1 : 0);
1086 }
1087 catch(const IceUtil::Exception& ex)
1088 {
1089 throwException(ex TSRMLS_CC);
1090 RETURN_FALSE;
1091 }
1092 }
1093
ZEND_METHOD(Ice_ObjectPrx,ice_batchDatagram)1094 ZEND_METHOD(Ice_ObjectPrx, ice_batchDatagram)
1095 {
1096 if(ZEND_NUM_ARGS() != 0)
1097 {
1098 WRONG_PARAM_COUNT;
1099 }
1100
1101 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1102 assert(_this);
1103
1104 try
1105 {
1106 if(!_this->clone(return_value, _this->proxy->ice_batchDatagram() TSRMLS_CC))
1107 {
1108 RETURN_NULL();
1109 }
1110 }
1111 catch(const IceUtil::Exception& ex)
1112 {
1113 throwException(ex TSRMLS_CC);
1114 RETURN_NULL();
1115 }
1116 }
1117
ZEND_METHOD(Ice_ObjectPrx,ice_isBatchDatagram)1118 ZEND_METHOD(Ice_ObjectPrx, ice_isBatchDatagram)
1119 {
1120 if(ZEND_NUM_ARGS() != 0)
1121 {
1122 WRONG_PARAM_COUNT;
1123 }
1124
1125 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1126 assert(_this);
1127
1128 try
1129 {
1130 bool b = _this->proxy->ice_isBatchDatagram();
1131 RETURN_BOOL(b ? 1 : 0);
1132 }
1133 catch(const IceUtil::Exception& ex)
1134 {
1135 throwException(ex TSRMLS_CC);
1136 RETURN_FALSE;
1137 }
1138 }
1139
ZEND_METHOD(Ice_ObjectPrx,ice_compress)1140 ZEND_METHOD(Ice_ObjectPrx, ice_compress)
1141 {
1142 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1143 assert(_this);
1144
1145 zend_bool b;
1146 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("b"), &b) != SUCCESS)
1147 {
1148 RETURN_NULL();
1149 }
1150
1151 try
1152 {
1153 if(!_this->clone(return_value, _this->proxy->ice_compress(b ? true : false) TSRMLS_CC))
1154 {
1155 RETURN_NULL();
1156 }
1157 }
1158 catch(const IceUtil::Exception& ex)
1159 {
1160 throwException(ex TSRMLS_CC);
1161 RETURN_NULL();
1162 }
1163 }
1164
ZEND_METHOD(Ice_ObjectPrx,ice_getCompress)1165 ZEND_METHOD(Ice_ObjectPrx, ice_getCompress)
1166 {
1167 if(ZEND_NUM_ARGS() != 0)
1168 {
1169 WRONG_PARAM_COUNT;
1170 }
1171
1172 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1173 assert(_this);
1174
1175 try
1176 {
1177 IceUtil::Optional<bool> compress = _this->proxy->ice_getCompress();
1178 if(compress)
1179 {
1180 RETURN_BOOL(*compress ? 1 : 0);
1181 }
1182 else
1183 {
1184 assignUnset(return_value TSRMLS_CC);
1185 }
1186 }
1187 catch(const IceUtil::Exception& ex)
1188 {
1189 throwException(ex TSRMLS_CC);
1190 RETURN_NULL();
1191 }
1192 }
1193
ZEND_METHOD(Ice_ObjectPrx,ice_timeout)1194 ZEND_METHOD(Ice_ObjectPrx, ice_timeout)
1195 {
1196 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1197 assert(_this);
1198
1199 try
1200 {
1201 long l;
1202 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("l"), &l) != SUCCESS)
1203 {
1204 RETURN_NULL();
1205 }
1206 // TODO: range check?
1207 if(!_this->clone(return_value, _this->proxy->ice_timeout(l) TSRMLS_CC))
1208 {
1209 RETURN_NULL();
1210 }
1211 }
1212 catch(const IceUtil::Exception& ex)
1213 {
1214 throwException(ex TSRMLS_CC);
1215 RETURN_NULL();
1216 }
1217 }
1218
ZEND_METHOD(Ice_ObjectPrx,ice_getTimeout)1219 ZEND_METHOD(Ice_ObjectPrx, ice_getTimeout)
1220 {
1221 if(ZEND_NUM_ARGS() != 0)
1222 {
1223 WRONG_PARAM_COUNT;
1224 }
1225
1226 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1227 assert(_this);
1228
1229 try
1230 {
1231 IceUtil::Optional<int> timeout = _this->proxy->ice_getTimeout();
1232 if(timeout)
1233 {
1234 ZVAL_LONG(return_value, static_cast<long>(*timeout));
1235 }
1236 else
1237 {
1238 assignUnset(return_value TSRMLS_CC);
1239 }
1240 }
1241 catch(const IceUtil::Exception& ex)
1242 {
1243 throwException(ex TSRMLS_CC);
1244 RETURN_NULL();
1245 }
1246 }
1247
ZEND_METHOD(Ice_ObjectPrx,ice_invocationTimeout)1248 ZEND_METHOD(Ice_ObjectPrx, ice_invocationTimeout)
1249 {
1250 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1251 assert(_this);
1252
1253 try
1254 {
1255 long l;
1256 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("l"), &l) != SUCCESS)
1257 {
1258 RETURN_NULL();
1259 }
1260 // TODO: range check?
1261 if(!_this->clone(return_value, _this->proxy->ice_invocationTimeout(l) TSRMLS_CC))
1262 {
1263 RETURN_NULL();
1264 }
1265 }
1266 catch(const IceUtil::Exception& ex)
1267 {
1268 throwException(ex TSRMLS_CC);
1269 RETURN_NULL();
1270 }
1271 }
1272
ZEND_METHOD(Ice_ObjectPrx,ice_getInvocationTimeout)1273 ZEND_METHOD(Ice_ObjectPrx, ice_getInvocationTimeout)
1274 {
1275 if(ZEND_NUM_ARGS() != 0)
1276 {
1277 WRONG_PARAM_COUNT;
1278 }
1279
1280 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1281 assert(_this);
1282
1283 try
1284 {
1285 ZVAL_LONG(return_value, static_cast<long>(_this->proxy->ice_getInvocationTimeout()));
1286 }
1287 catch(const IceUtil::Exception& ex)
1288 {
1289 throwException(ex TSRMLS_CC);
1290 RETURN_NULL();
1291 }
1292 }
1293
ZEND_METHOD(Ice_ObjectPrx,ice_connectionId)1294 ZEND_METHOD(Ice_ObjectPrx, ice_connectionId)
1295 {
1296 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1297 assert(_this);
1298
1299 try
1300 {
1301 char* id;
1302 int idLen;
1303 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("s"), &id, &idLen) != SUCCESS)
1304 {
1305 RETURN_NULL();
1306 }
1307 if(!_this->clone(return_value, _this->proxy->ice_connectionId(id) TSRMLS_CC))
1308 {
1309 RETURN_NULL();
1310 }
1311 }
1312 catch(const IceUtil::Exception& ex)
1313 {
1314 throwException(ex TSRMLS_CC);
1315 RETURN_NULL();
1316 }
1317 }
1318
ZEND_METHOD(Ice_ObjectPrx,ice_fixed)1319 ZEND_METHOD(Ice_ObjectPrx, ice_fixed)
1320 {
1321 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1322 assert(_this);
1323
1324 zval* zcon;
1325 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("O!"), &zcon, connectionClassEntry TSRMLS_CC) !=
1326 SUCCESS)
1327 {
1328 RETURN_NULL();
1329 }
1330
1331 Ice::ConnectionPtr connection;
1332 if(zcon && !fetchConnection(zcon, connection TSRMLS_CC))
1333 {
1334 RETURN_NULL();
1335 }
1336
1337 try
1338 {
1339 if(!_this->clone(return_value, _this->proxy->ice_fixed(connection) TSRMLS_CC))
1340 {
1341 RETURN_NULL();
1342 }
1343 }
1344 catch(const IceUtil::Exception& ex)
1345 {
1346 throwException(ex TSRMLS_CC);
1347 RETURN_NULL();
1348 }
1349 }
1350
ZEND_METHOD(Ice_ObjectPrx,ice_getConnection)1351 ZEND_METHOD(Ice_ObjectPrx, ice_getConnection)
1352 {
1353 if(ZEND_NUM_ARGS() != 0)
1354 {
1355 WRONG_PARAM_COUNT;
1356 }
1357
1358 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1359 assert(_this);
1360
1361 try
1362 {
1363 Ice::ConnectionPtr con = _this->proxy->ice_getConnection();
1364 if(!createConnection(return_value, con TSRMLS_CC))
1365 {
1366 RETURN_NULL();
1367 }
1368 }
1369 catch(const IceUtil::Exception& ex)
1370 {
1371 throwException(ex TSRMLS_CC);
1372 RETURN_NULL();
1373 }
1374 }
1375
ZEND_METHOD(Ice_ObjectPrx,ice_getCachedConnection)1376 ZEND_METHOD(Ice_ObjectPrx, ice_getCachedConnection)
1377 {
1378 if(ZEND_NUM_ARGS() != 0)
1379 {
1380 WRONG_PARAM_COUNT;
1381 }
1382
1383 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1384 assert(_this);
1385
1386 try
1387 {
1388 Ice::ConnectionPtr con = _this->proxy->ice_getCachedConnection();
1389 if(!con || !createConnection(return_value, con TSRMLS_CC))
1390 {
1391 RETURN_NULL();
1392 }
1393 }
1394 catch(const IceUtil::Exception& ex)
1395 {
1396 throwException(ex TSRMLS_CC);
1397 RETURN_NULL();
1398 }
1399 }
1400
ZEND_METHOD(Ice_ObjectPrx,ice_flushBatchRequests)1401 ZEND_METHOD(Ice_ObjectPrx, ice_flushBatchRequests)
1402 {
1403 if(ZEND_NUM_ARGS() != 0)
1404 {
1405 WRONG_PARAM_COUNT;
1406 }
1407
1408 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1409 assert(_this);
1410
1411 try
1412 {
1413 _this->proxy->ice_flushBatchRequests();
1414 }
1415 catch(const IceUtil::Exception& ex)
1416 {
1417 throwException(ex TSRMLS_CC);
1418 RETURN_NULL();
1419 }
1420 }
1421
1422 static void
do_cast(INTERNAL_FUNCTION_PARAMETERS,bool check)1423 do_cast(INTERNAL_FUNCTION_PARAMETERS, bool check)
1424 {
1425 //
1426 // First argument is required and should be a scoped name. The second and third arguments
1427 // are optional and represent a facet name, a context, or a facet name followed by a context.
1428 //
1429 if(ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 3)
1430 {
1431 WRONG_PARAM_COUNT;
1432 }
1433
1434 char* id;
1435 int idLen;
1436 char* facet = 0;
1437 int facetLen;
1438 zval* arr = 0;
1439
1440 if(zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("s|s!a!"), &id,
1441 &idLen, &facet, &facetLen, &arr) == FAILURE)
1442 {
1443 facet = 0;
1444 if(zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("s|a!"), &id,
1445 &idLen, &arr) == FAILURE)
1446 {
1447 php_error(E_ERROR, "%s() requires a type id followed by an optional facet and/or context",
1448 get_active_function_name(TSRMLS_C));
1449 return;
1450 }
1451 }
1452
1453 ProxyPtr _this = Wrapper<ProxyPtr>::value(getThis() TSRMLS_CC);
1454 assert(_this);
1455
1456 //
1457 // Populate the context.
1458 //
1459 Ice::Context ctx;
1460 if(arr && !extractStringMap(arr, ctx TSRMLS_CC))
1461 {
1462 RETURN_NULL();
1463 }
1464
1465 try
1466 {
1467 ProxyInfoPtr info = getProxyInfo(id TSRMLS_CC);
1468 if(!info)
1469 {
1470 RETURN_NULL();
1471 }
1472
1473 Ice::ObjectPrx prx = _this->proxy;
1474 if(facet)
1475 {
1476 prx = prx->ice_facet(facet);
1477 }
1478
1479 if(arr)
1480 {
1481 prx = prx->ice_context(ctx);
1482 }
1483
1484 if(check)
1485 {
1486 //
1487 // Verify that the object supports the requested type.
1488 //
1489 if(!prx->ice_isA(info->id))
1490 {
1491 RETURN_NULL();
1492 }
1493 }
1494
1495 if(!createProxy(return_value, prx, info, _this->communicator TSRMLS_CC))
1496 {
1497 RETURN_NULL();
1498 }
1499 }
1500 catch(const Ice::FacetNotExistException&)
1501 {
1502 // Ignore.
1503 }
1504 catch(const IceUtil::Exception& ex)
1505 {
1506 throwException(ex TSRMLS_CC);
1507 RETVAL_FALSE;
1508 }
1509 }
1510
ZEND_METHOD(Ice_ObjectPrx,ice_uncheckedCast)1511 ZEND_METHOD(Ice_ObjectPrx, ice_uncheckedCast)
1512 {
1513 do_cast(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
1514 }
1515
ZEND_METHOD(Ice_ObjectPrx,ice_checkedCast)1516 ZEND_METHOD(Ice_ObjectPrx, ice_checkedCast)
1517 {
1518 do_cast(INTERNAL_FUNCTION_PARAM_PASSTHRU, true);
1519 }
1520
Proxy(const Ice::ObjectPrx & p,const ProxyInfoPtr & i,const CommunicatorInfoPtr & comm TSRMLS_DC)1521 IcePHP::Proxy::Proxy(const Ice::ObjectPrx& p, const ProxyInfoPtr& i, const CommunicatorInfoPtr& comm TSRMLS_DC) :
1522 proxy(p), info(i), communicator(comm), connection(0), cachedConnection(0)
1523 {
1524 #ifdef ZTS
1525 this->TSRMLS_C = TSRMLS_C;
1526 #endif
1527
1528 //
1529 // We want to ensure that the PHP object corresponding to the communicator is
1530 // not destroyed until after this proxy is destroyed.
1531 //
1532 communicator->addRef(TSRMLS_C);
1533 }
1534
~Proxy()1535 IcePHP::Proxy::~Proxy()
1536 {
1537 communicator->decRef(TSRMLS_C);
1538 if(connection)
1539 {
1540 zval_ptr_dtor(&connection);
1541 }
1542 if(cachedConnection)
1543 {
1544 zval_ptr_dtor(&cachedConnection);
1545 }
1546 }
1547
1548 bool
clone(zval * zv,const Ice::ObjectPrx & p TSRMLS_DC)1549 IcePHP::Proxy::clone(zval* zv, const Ice::ObjectPrx& p TSRMLS_DC)
1550 {
1551 return create(zv, p, info, communicator TSRMLS_CC);
1552 }
1553
1554 bool
cloneUntyped(zval * zv,const Ice::ObjectPrx & p TSRMLS_DC)1555 IcePHP::Proxy::cloneUntyped(zval* zv, const Ice::ObjectPrx& p TSRMLS_DC)
1556 {
1557 return create(zv, p, 0, communicator TSRMLS_CC);
1558 }
1559
1560 bool
create(zval * zv,const Ice::ObjectPrx & p,const ProxyInfoPtr & info,const CommunicatorInfoPtr & comm TSRMLS_DC)1561 IcePHP::Proxy::create(zval* zv, const Ice::ObjectPrx& p, const ProxyInfoPtr& info, const CommunicatorInfoPtr& comm
1562 TSRMLS_DC)
1563 {
1564 ProxyInfoPtr prx = info;
1565 if(!prx)
1566 {
1567 prx = getProxyInfo("::Ice::Object" TSRMLS_CC);
1568 assert(prx);
1569 }
1570
1571 if(object_init_ex(zv, proxyClassEntry) != SUCCESS)
1572 {
1573 runtimeError("unable to initialize proxy" TSRMLS_CC);
1574 return false;
1575 }
1576
1577 Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::extract(zv TSRMLS_CC);
1578 ProxyPtr proxy = new Proxy(p, prx, comm TSRMLS_CC);
1579 assert(!obj->ptr);
1580 obj->ptr = new ProxyPtr(proxy);
1581
1582 return true;
1583 }
1584
1585 #ifdef _WIN32
1586 extern "C"
1587 #endif
1588 static zend_object_value
handleAlloc(zend_class_entry * ce TSRMLS_DC)1589 handleAlloc(zend_class_entry* ce TSRMLS_DC)
1590 {
1591 zend_object_value result;
1592
1593 Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::create(ce TSRMLS_CC);
1594 assert(obj);
1595
1596 result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleFreeStorage,
1597 0 TSRMLS_CC);
1598 result.handlers = &_handlers;
1599
1600 return result;
1601 }
1602
1603 #ifdef _WIN32
1604 extern "C"
1605 #endif
1606 static void
handleFreeStorage(void * p TSRMLS_DC)1607 handleFreeStorage(void* p TSRMLS_DC)
1608 {
1609 Wrapper<ProxyPtr>* obj = static_cast<Wrapper<ProxyPtr>*>(p);
1610 delete obj->ptr;
1611 zend_object_std_dtor(static_cast<zend_object*>(p) TSRMLS_CC);
1612 efree(p);
1613 }
1614
1615 #ifdef _WIN32
1616 extern "C"
1617 #endif
1618 static zend_object_value
handleClone(zval * zv TSRMLS_DC)1619 handleClone(zval* zv TSRMLS_DC)
1620 {
1621 //
1622 // Create a new object that shares a C++ proxy instance with this object.
1623 //
1624
1625 zend_object_value result;
1626 memset(&result, 0, sizeof(zend_object_value));
1627
1628 ProxyPtr obj = Wrapper<ProxyPtr>::value(zv TSRMLS_CC);
1629 assert(obj);
1630
1631 zval* clone;
1632 MAKE_STD_ZVAL(clone);
1633 if(!obj->clone(clone, obj->proxy TSRMLS_CC))
1634 {
1635 return result;
1636 }
1637
1638 //
1639 // We only need to return the new object's handle, so we must destroy the zval containing
1640 // a reference to the new object. We increment the object's reference count to ensure it
1641 // does not get destroyed.
1642 //
1643 result = clone->value.obj;
1644 Z_OBJ_HT_P(clone)->add_ref(clone TSRMLS_CC);
1645 zval_dtor(clone);
1646 efree(clone);
1647
1648 return result;
1649 }
1650
1651 #ifdef _WIN32
1652 extern "C"
1653 #endif
1654 static union _zend_function*
1655 #if PHP_VERSION_ID < 50400
handleGetMethod(zval ** zv,char * method,int len TSRMLS_DC)1656 handleGetMethod(zval** zv, char* method, int len TSRMLS_DC)
1657 #else
1658 handleGetMethod(zval** zv, char* method, int len, const _zend_literal* key TSRMLS_DC)
1659 #endif
1660 {
1661 zend_function* result;
1662
1663 //
1664 // First delegate to the standard implementation of get_method. This will find
1665 // any of our predefined proxy methods. If it returns 0, then we return a
1666 // function that will check the class definition.
1667 //
1668 #if PHP_VERSION_ID < 50400
1669 result = zend_get_std_object_handlers()->get_method(zv, method, len TSRMLS_CC);
1670 #else
1671 result = zend_get_std_object_handlers()->get_method(zv, method, len, key TSRMLS_CC);
1672 #endif
1673 if(!result)
1674 {
1675 Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::extract(*zv TSRMLS_CC);
1676 assert(obj->ptr);
1677 ProxyPtr _this = *obj->ptr;
1678
1679 ProxyInfoPtr info = _this->info;
1680 assert(info);
1681
1682 OperationPtr op = info->getOperation(method);
1683 if(!op)
1684 {
1685 //
1686 // Returning 0 causes PHP to report an "undefined method" error.
1687 //
1688 return 0;
1689 }
1690
1691 result = op->function();
1692 }
1693
1694 return result;
1695 }
1696
1697 #ifdef _WIN32
1698 extern "C"
1699 #endif
1700 static int
handleCompare(zval * zobj1,zval * zobj2 TSRMLS_DC)1701 handleCompare(zval* zobj1, zval* zobj2 TSRMLS_DC)
1702 {
1703 //
1704 // PHP guarantees that the objects have the same class.
1705 //
1706
1707 Wrapper<ProxyPtr>* obj1 = Wrapper<ProxyPtr>::extract(zobj1 TSRMLS_CC);
1708 assert(obj1->ptr);
1709 ProxyPtr _this1 = *obj1->ptr;
1710 Ice::ObjectPrx prx1 = _this1->proxy;
1711
1712 Wrapper<ProxyPtr>* obj2 = Wrapper<ProxyPtr>::extract(zobj2 TSRMLS_CC);
1713 assert(obj2->ptr);
1714 ProxyPtr _this2 = *obj2->ptr;
1715 Ice::ObjectPrx prx2 = _this2->proxy;
1716
1717 if(prx1 == prx2)
1718 {
1719 return 0;
1720 }
1721 else if(prx1 < prx2)
1722 {
1723 return -1;
1724 }
1725 else
1726 {
1727 return 1;
1728 }
1729 }
1730
1731 //
1732 // Necessary to suppress warnings from zend_function_entry in php-5.2.
1733 //
1734 #if defined(__GNUC__)
1735 # pragma GCC diagnostic ignored "-Wwrite-strings"
1736 #endif
1737
1738 //
1739 // Predefined methods for ObjectPrx.
1740 //
1741 static zend_function_entry _proxyMethods[] =
1742 {
1743 ZEND_ME(Ice_ObjectPrx, __construct, ICE_NULLPTR, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
1744 ZEND_ME(Ice_ObjectPrx, __toString, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1745 ZEND_ME(Ice_ObjectPrx, ice_getCommunicator, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1746 ZEND_ME(Ice_ObjectPrx, ice_toString, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1747 ZEND_ME(Ice_ObjectPrx, ice_getIdentity, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1748 ZEND_ME(Ice_ObjectPrx, ice_identity, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1749 ZEND_ME(Ice_ObjectPrx, ice_getContext, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1750 ZEND_ME(Ice_ObjectPrx, ice_context, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1751 ZEND_ME(Ice_ObjectPrx, ice_getFacet, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1752 ZEND_ME(Ice_ObjectPrx, ice_facet, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1753 ZEND_ME(Ice_ObjectPrx, ice_getAdapterId, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1754 ZEND_ME(Ice_ObjectPrx, ice_adapterId, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1755 ZEND_ME(Ice_ObjectPrx, ice_getEndpoints, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1756 ZEND_ME(Ice_ObjectPrx, ice_endpoints, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1757 ZEND_ME(Ice_ObjectPrx, ice_getLocatorCacheTimeout, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1758 ZEND_ME(Ice_ObjectPrx, ice_getConnectionId, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1759 ZEND_ME(Ice_ObjectPrx, ice_locatorCacheTimeout, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1760 ZEND_ME(Ice_ObjectPrx, ice_isConnectionCached, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1761 ZEND_ME(Ice_ObjectPrx, ice_connectionCached, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1762 ZEND_ME(Ice_ObjectPrx, ice_getEndpointSelection, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1763 ZEND_ME(Ice_ObjectPrx, ice_endpointSelection, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1764 ZEND_ME(Ice_ObjectPrx, ice_isSecure, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1765 ZEND_ME(Ice_ObjectPrx, ice_secure, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1766 ZEND_ME(Ice_ObjectPrx, ice_getEncodingVersion, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1767 ZEND_ME(Ice_ObjectPrx, ice_encodingVersion, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1768 ZEND_ME(Ice_ObjectPrx, ice_isPreferSecure, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1769 ZEND_ME(Ice_ObjectPrx, ice_preferSecure, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1770 ZEND_ME(Ice_ObjectPrx, ice_getRouter, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1771 ZEND_ME(Ice_ObjectPrx, ice_router, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1772 ZEND_ME(Ice_ObjectPrx, ice_getLocator, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1773 ZEND_ME(Ice_ObjectPrx, ice_locator, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1774 ZEND_ME(Ice_ObjectPrx, ice_twoway, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1775 ZEND_ME(Ice_ObjectPrx, ice_isTwoway, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1776 ZEND_ME(Ice_ObjectPrx, ice_oneway, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1777 ZEND_ME(Ice_ObjectPrx, ice_isOneway, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1778 ZEND_ME(Ice_ObjectPrx, ice_batchOneway, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1779 ZEND_ME(Ice_ObjectPrx, ice_isBatchOneway, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1780 ZEND_ME(Ice_ObjectPrx, ice_datagram, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1781 ZEND_ME(Ice_ObjectPrx, ice_isDatagram, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1782 ZEND_ME(Ice_ObjectPrx, ice_batchDatagram, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1783 ZEND_ME(Ice_ObjectPrx, ice_isBatchDatagram, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1784 ZEND_ME(Ice_ObjectPrx, ice_compress, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1785 ZEND_ME(Ice_ObjectPrx, ice_getCompress, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1786 ZEND_ME(Ice_ObjectPrx, ice_timeout, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1787 ZEND_ME(Ice_ObjectPrx, ice_getTimeout, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1788 ZEND_ME(Ice_ObjectPrx, ice_invocationTimeout, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1789 ZEND_ME(Ice_ObjectPrx, ice_getInvocationTimeout, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1790 ZEND_ME(Ice_ObjectPrx, ice_connectionId, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1791 ZEND_ME(Ice_ObjectPrx, ice_fixed, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1792 ZEND_ME(Ice_ObjectPrx, ice_getConnection, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1793 ZEND_ME(Ice_ObjectPrx, ice_getCachedConnection, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1794 ZEND_ME(Ice_ObjectPrx, ice_flushBatchRequests, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1795 ZEND_ME(Ice_ObjectPrx, ice_uncheckedCast, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1796 ZEND_ME(Ice_ObjectPrx, ice_checkedCast, ICE_NULLPTR, ZEND_ACC_PUBLIC)
1797 {0, 0, 0}
1798 };
1799
1800 //
1801 // enable warning again
1802 //
1803 #if defined(__GNUC__)
1804 # pragma GCC diagnostic error "-Wwrite-strings"
1805 #endif
1806
1807 bool
proxyInit(TSRMLS_D)1808 IcePHP::proxyInit(TSRMLS_D)
1809 {
1810 //
1811 // Register the ObjectPrx class.
1812 //
1813 zend_class_entry ce;
1814 #ifdef ICEPHP_USE_NAMESPACES
1815 INIT_NS_CLASS_ENTRY(ce, "Ice", "ObjectPrx", _proxyMethods);
1816 #else
1817 INIT_CLASS_ENTRY(ce, "Ice_ObjectPrx", _proxyMethods);
1818 #endif
1819 ce.create_object = handleAlloc;
1820 proxyClassEntry = zend_register_internal_class(&ce TSRMLS_CC);
1821 //proxyClassEntry->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
1822 memcpy(&_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1823 _handlers.clone_obj = handleClone;
1824 _handlers.get_method = handleGetMethod;
1825 _handlers.compare_objects = handleCompare;
1826
1827 return true;
1828 }
1829
1830 bool
createProxy(zval * zv,const Ice::ObjectPrx & p,const CommunicatorInfoPtr & comm TSRMLS_DC)1831 IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const CommunicatorInfoPtr& comm TSRMLS_DC)
1832 {
1833 return Proxy::create(zv, p, 0, comm TSRMLS_CC);
1834 }
1835
1836 bool
createProxy(zval * zv,const Ice::ObjectPrx & p,const ProxyInfoPtr & info,const CommunicatorInfoPtr & comm TSRMLS_DC)1837 IcePHP::createProxy(zval* zv, const Ice::ObjectPrx& p, const ProxyInfoPtr& info, const CommunicatorInfoPtr& comm
1838 TSRMLS_DC)
1839 {
1840 return Proxy::create(zv, p, info, comm TSRMLS_CC);
1841 }
1842
1843 bool
fetchProxy(zval * zv,Ice::ObjectPrx & prx,ProxyInfoPtr & info TSRMLS_DC)1844 IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ProxyInfoPtr& info TSRMLS_DC)
1845 {
1846 CommunicatorInfoPtr comm;
1847 return fetchProxy(zv, prx, info, comm TSRMLS_CC);
1848 }
1849
1850 bool
fetchProxy(zval * zv,Ice::ObjectPrx & prx,ProxyInfoPtr & info,CommunicatorInfoPtr & comm TSRMLS_DC)1851 IcePHP::fetchProxy(zval* zv, Ice::ObjectPrx& prx, ProxyInfoPtr& info, CommunicatorInfoPtr& comm TSRMLS_DC)
1852 {
1853 if(!ZVAL_IS_NULL(zv))
1854 {
1855 if(Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != proxyClassEntry)
1856 {
1857 invalidArgument("value is not a proxy" TSRMLS_CC);
1858 return false;
1859 }
1860 Wrapper<ProxyPtr>* obj = Wrapper<ProxyPtr>::extract(zv TSRMLS_CC);
1861 if(!obj)
1862 {
1863 runtimeError("unable to retrieve proxy object from object store" TSRMLS_CC);
1864 return false;
1865 }
1866 assert(obj->ptr);
1867 prx = (*obj->ptr)->proxy;
1868 info = (*obj->ptr)->info;
1869 comm = (*obj->ptr)->communicator;
1870 }
1871 return true;
1872 }
1873