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