1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4
5 #include <Connection.h>
6 #include <Endpoint.h>
7 #include <Types.h>
8 #include <Util.h>
9 #include <IceSSL/IceSSL.h>
10
11 using namespace std;
12 using namespace IcePHP;
13
14 ZEND_EXTERN_MODULE_GLOBALS(ice)
15
16 //
17 // Class entries represent the PHP class implementations we have registered.
18 //
19 namespace IcePHP
20 {
21
22 zend_class_entry* connectionClassEntry = 0;
23
24 }
25 static zend_class_entry* connectionInfoClassEntry = 0;
26 static zend_class_entry* ipConnectionInfoClassEntry = 0;
27 static zend_class_entry* tcpConnectionInfoClassEntry = 0;
28 static zend_class_entry* udpConnectionInfoClassEntry = 0;
29 static zend_class_entry* wsConnectionInfoClassEntry = 0;
30 static zend_class_entry* sslConnectionInfoClassEntry = 0;
31
32 //
33 // Ice::Connection support.
34 //
35 static zend_object_handlers _connectionHandlers;
36 static zend_object_handlers _connectionInfoHandlers;
37
38 extern "C"
39 {
40 static zend_object_value handleConnectionAlloc(zend_class_entry* TSRMLS_DC);
41 static void handleConnectionFreeStorage(void* TSRMLS_DC);
42 static int handleConnectionCompare(zval*, zval* TSRMLS_DC);
43
44 static zend_object_value handleConnectionInfoAlloc(zend_class_entry* TSRMLS_DC);
45 static void handleConnectionInfoFreeStorage(void* TSRMLS_DC);
46 }
47
ZEND_METHOD(Ice_Connection,__construct)48 ZEND_METHOD(Ice_Connection, __construct)
49 {
50 runtimeError("Connection cannot be instantiated" TSRMLS_CC);
51 }
52
ZEND_METHOD(Ice_Connection,__toString)53 ZEND_METHOD(Ice_Connection, __toString)
54 {
55 if(ZEND_NUM_ARGS() > 0)
56 {
57 WRONG_PARAM_COUNT;
58 }
59
60 Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
61 assert(_this);
62
63 try
64 {
65 string str = _this->toString();
66 RETURN_STRINGL(STRCAST(str.c_str()), static_cast<int>(str.length()), 1);
67 }
68 catch(const IceUtil::Exception& ex)
69 {
70 throwException(ex TSRMLS_CC);
71 RETURN_NULL();
72 }
73 }
74
ZEND_METHOD(Ice_Connection,close)75 ZEND_METHOD(Ice_Connection, close)
76 {
77 Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
78 assert(_this);
79
80 zval* mode;
81 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("z"), &mode TSRMLS_CC) != SUCCESS)
82 {
83 RETURN_NULL();
84 }
85
86 if(Z_TYPE_P(mode) != IS_LONG)
87 {
88 invalidArgument("value for 'mode' argument must be an enumerator of ConnectionClose" TSRMLS_CC);
89 RETURN_NULL();
90 }
91 Ice::ConnectionClose cc = static_cast<Ice::ConnectionClose>(Z_LVAL_P(mode));
92
93 try
94 {
95 _this->close(cc);
96 }
97 catch(const IceUtil::Exception& ex)
98 {
99 throwException(ex TSRMLS_CC);
100 RETURN_NULL();
101 }
102 }
103
ZEND_METHOD(Ice_Connection,getEndpoint)104 ZEND_METHOD(Ice_Connection, getEndpoint)
105 {
106 if(ZEND_NUM_ARGS() > 0)
107 {
108 WRONG_PARAM_COUNT;
109 }
110
111 Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
112 assert(_this);
113
114 try
115 {
116 if(!createEndpoint(return_value, _this->getEndpoint() TSRMLS_CC))
117 {
118 RETURN_NULL();
119 }
120 }
121 catch(const IceUtil::Exception& ex)
122 {
123 throwException(ex TSRMLS_CC);
124 RETURN_NULL();
125 }
126 }
127
ZEND_METHOD(Ice_Connection,flushBatchRequests)128 ZEND_METHOD(Ice_Connection, flushBatchRequests)
129 {
130 zval* compress;
131 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("z"), &compress TSRMLS_CC) != SUCCESS)
132 {
133 RETURN_NULL();
134 }
135
136 if(Z_TYPE_P(compress) != IS_LONG)
137 {
138 invalidArgument("value for 'compress' argument must be an enumerator of CompressBatch" TSRMLS_CC);
139 RETURN_NULL();
140 }
141 Ice::CompressBatch cb = static_cast<Ice::CompressBatch>(Z_LVAL_P(compress));
142
143 Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
144 assert(_this);
145
146 try
147 {
148 _this->flushBatchRequests(cb);
149 }
150 catch(const IceUtil::Exception& ex)
151 {
152 throwException(ex TSRMLS_CC);
153 RETURN_NULL();
154 }
155 }
156
ZEND_METHOD(Ice_Connection,heartbeat)157 ZEND_METHOD(Ice_Connection, heartbeat)
158 {
159 if(ZEND_NUM_ARGS() > 0)
160 {
161 WRONG_PARAM_COUNT;
162 }
163
164 Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
165 assert(_this);
166
167 try
168 {
169 _this->heartbeat();
170 }
171 catch(const IceUtil::Exception& ex)
172 {
173 throwException(ex TSRMLS_CC);
174 RETURN_NULL();
175 }
176 }
177
ZEND_METHOD(Ice_Connection,setACM)178 ZEND_METHOD(Ice_Connection, setACM)
179 {
180 Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
181 assert(_this);
182
183 zval* t;
184 zval* c;
185 zval* h;
186 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("zzz"), &t, &c, &h TSRMLS_CC) != SUCCESS)
187 {
188 RETURN_NULL();
189 }
190
191 IceUtil::Optional<Ice::Int> timeout;
192 IceUtil::Optional<Ice::ACMClose> close;
193 IceUtil::Optional<Ice::ACMHeartbeat> heartbeat;
194
195 if(!isUnset(t TSRMLS_CC))
196 {
197 if(Z_TYPE_P(t) != IS_LONG)
198 {
199 invalidArgument("value for 'timeout' argument must be Unset or an integer" TSRMLS_CC);
200 RETURN_NULL();
201 }
202 timeout = static_cast<Ice::Int>(Z_LVAL_P(t));
203 }
204
205 if(!isUnset(c TSRMLS_CC))
206 {
207 if(Z_TYPE_P(c) != IS_LONG)
208 {
209 invalidArgument("value for 'close' argument must be Unset or an enumerator of ACMClose" TSRMLS_CC);
210 RETURN_NULL();
211 }
212 close = static_cast<Ice::ACMClose>(Z_LVAL_P(c));
213 }
214
215 if(!isUnset(h TSRMLS_CC))
216 {
217 if(Z_TYPE_P(h) != IS_LONG)
218 {
219 invalidArgument("value for 'heartbeat' argument must be Unset or an enumerator of ACMHeartbeat" TSRMLS_CC);
220 RETURN_NULL();
221 }
222 heartbeat = static_cast<Ice::ACMHeartbeat>(Z_LVAL_P(h));
223 }
224
225 try
226 {
227 _this->setACM(timeout, close, heartbeat);
228 }
229 catch(const IceUtil::Exception& ex)
230 {
231 throwException(ex TSRMLS_CC);
232 RETURN_NULL();
233 }
234 }
235
ZEND_METHOD(Ice_Connection,getACM)236 ZEND_METHOD(Ice_Connection, getACM)
237 {
238 if(ZEND_NUM_ARGS() > 0)
239 {
240 WRONG_PARAM_COUNT;
241 }
242
243 Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
244 assert(_this);
245
246 try
247 {
248 Ice::ACM acm = _this->getACM();
249
250 zend_class_entry* acmClass = idToClass("::Ice::ACM" TSRMLS_CC);
251
252 if(object_init_ex(return_value, const_cast<zend_class_entry*>(acmClass)) != SUCCESS)
253 {
254 runtimeError("unable to initialize object of type %s" TSRMLS_CC, acmClass->name);
255 RETURN_NULL();
256 }
257
258 add_property_long(return_value, STRCAST("timeout"), static_cast<long>(acm.timeout));
259 add_property_long(return_value, STRCAST("close"), static_cast<long>(acm.close));
260 add_property_long(return_value, STRCAST("heartbeat"), static_cast<long>(acm.heartbeat));
261 }
262 catch(const IceUtil::Exception& ex)
263 {
264 throwException(ex TSRMLS_CC);
265 RETURN_NULL();
266 }
267 }
268
ZEND_METHOD(Ice_Connection,type)269 ZEND_METHOD(Ice_Connection, type)
270 {
271 if(ZEND_NUM_ARGS() > 0)
272 {
273 WRONG_PARAM_COUNT;
274 }
275
276 Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
277 assert(_this);
278
279 try
280 {
281 string str = _this->type();
282 RETURN_STRINGL(STRCAST(str.c_str()), str.length(), 1);
283 }
284 catch(const IceUtil::Exception& ex)
285 {
286 throwException(ex TSRMLS_CC);
287 RETURN_NULL();
288 }
289 }
290
ZEND_METHOD(Ice_Connection,timeout)291 ZEND_METHOD(Ice_Connection, timeout)
292 {
293 if(ZEND_NUM_ARGS() != 0)
294 {
295 WRONG_PARAM_COUNT;
296 }
297
298 Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
299 assert(_this);
300
301 try
302 {
303 Ice::Int timeout = _this->timeout();
304 ZVAL_LONG(return_value, static_cast<long>(timeout));
305 }
306 catch(const IceUtil::Exception& ex)
307 {
308 throwException(ex TSRMLS_CC);
309 RETURN_NULL();
310 }
311 }
312
ZEND_METHOD(Ice_Connection,toString)313 ZEND_METHOD(Ice_Connection, toString)
314 {
315 ZEND_MN(Ice_Connection___toString)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
316 }
317
ZEND_METHOD(Ice_Connection,getInfo)318 ZEND_METHOD(Ice_Connection, getInfo)
319 {
320 if(ZEND_NUM_ARGS() != 0)
321 {
322 WRONG_PARAM_COUNT;
323 }
324
325 Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
326 assert(_this);
327
328 try
329 {
330 Ice::ConnectionInfoPtr info = _this->getInfo();
331 if(!createConnectionInfo(return_value, _this->getInfo() TSRMLS_CC))
332 {
333 RETURN_NULL();
334 }
335 }
336 catch(const IceUtil::Exception& ex)
337 {
338 throwException(ex TSRMLS_CC);
339 RETURN_NULL();
340 }
341 }
342
ZEND_METHOD(Ice_Connection,setBufferSize)343 ZEND_METHOD(Ice_Connection, setBufferSize)
344 {
345 Ice::ConnectionPtr _this = Wrapper<Ice::ConnectionPtr>::value(getThis() TSRMLS_CC);
346 assert(_this);
347
348 zval* r;
349 zval* s;
350 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, const_cast<char*>("zz"), &r, &s TSRMLS_CC) != SUCCESS)
351 {
352 RETURN_NULL();
353 }
354
355 int rcvSize = static_cast<int>(Z_LVAL_P(r));
356 int sndSize = static_cast<int>(Z_LVAL_P(s));
357
358 try
359 {
360 _this->setBufferSize(rcvSize, sndSize);
361 }
362 catch(const IceUtil::Exception& ex)
363 {
364 throwException(ex TSRMLS_CC);
365 RETURN_NULL();
366 }
367 }
368
369 #ifdef _WIN32
370 extern "C"
371 #endif
372 static zend_object_value
handleConnectionAlloc(zend_class_entry * ce TSRMLS_DC)373 handleConnectionAlloc(zend_class_entry* ce TSRMLS_DC)
374 {
375 zend_object_value result;
376
377 Wrapper<Ice::ConnectionPtr>* obj = Wrapper<Ice::ConnectionPtr>::create(ce TSRMLS_CC);
378 assert(obj);
379
380 result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleConnectionFreeStorage,
381 0 TSRMLS_CC);
382 result.handlers = &_connectionHandlers;
383
384 return result;
385 }
386
387 #ifdef _WIN32
388 extern "C"
389 #endif
390 static void
handleConnectionFreeStorage(void * p TSRMLS_DC)391 handleConnectionFreeStorage(void* p TSRMLS_DC)
392 {
393 Wrapper<Ice::ConnectionPtr>* obj = static_cast<Wrapper<Ice::ConnectionPtr>*>(p);
394 delete obj->ptr;
395 zend_object_std_dtor(static_cast<zend_object*>(p) TSRMLS_CC);
396 efree(p);
397 }
398
399 #ifdef _WIN32
400 extern "C"
401 #endif
402 static int
handleConnectionCompare(zval * zobj1,zval * zobj2 TSRMLS_DC)403 handleConnectionCompare(zval* zobj1, zval* zobj2 TSRMLS_DC)
404 {
405 //
406 // PHP guarantees that the objects have the same class.
407 //
408
409 Ice::ConnectionPtr con1 = Wrapper<Ice::ConnectionPtr>::value(zobj1 TSRMLS_CC);
410 assert(con1);
411 Ice::ConnectionPtr con2 = Wrapper<Ice::ConnectionPtr>::value(zobj2 TSRMLS_CC);
412 assert(con2);
413
414 if(con1 == con2)
415 {
416 return 0;
417 }
418 else if(con1 < con2)
419 {
420 return -1;
421 }
422 else
423 {
424 return 1;
425 }
426 }
427
428 //
429 // Necessary to suppress warnings from zend_function_entry in php-5.2.
430 //
431 #if defined(__GNUC__)
432 # pragma GCC diagnostic ignored "-Wwrite-strings"
433 #endif
434
435 //
436 // Predefined methods for Connection.
437 //
438 static zend_function_entry _interfaceMethods[] =
439 {
440 {0, 0, 0}
441 };
442 static zend_function_entry _connectionClassMethods[] =
443 {
444 ZEND_ME(Ice_Connection, __construct, ICE_NULLPTR, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
445 ZEND_ME(Ice_Connection, __toString, ICE_NULLPTR, ZEND_ACC_PUBLIC)
446 ZEND_ME(Ice_Connection, close, ICE_NULLPTR, ZEND_ACC_PUBLIC)
447 ZEND_ME(Ice_Connection, getEndpoint, ICE_NULLPTR, ZEND_ACC_PUBLIC)
448 ZEND_ME(Ice_Connection, flushBatchRequests, ICE_NULLPTR, ZEND_ACC_PUBLIC)
449 ZEND_ME(Ice_Connection, heartbeat, ICE_NULLPTR, ZEND_ACC_PUBLIC)
450 ZEND_ME(Ice_Connection, setACM, ICE_NULLPTR, ZEND_ACC_PUBLIC)
451 ZEND_ME(Ice_Connection, getACM, ICE_NULLPTR, ZEND_ACC_PUBLIC)
452 ZEND_ME(Ice_Connection, type, ICE_NULLPTR, ZEND_ACC_PUBLIC)
453 ZEND_ME(Ice_Connection, timeout, ICE_NULLPTR, ZEND_ACC_PUBLIC)
454 ZEND_ME(Ice_Connection, toString, ICE_NULLPTR, ZEND_ACC_PUBLIC)
455 ZEND_ME(Ice_Connection, getInfo, ICE_NULLPTR, ZEND_ACC_PUBLIC)
456 ZEND_ME(Ice_Connection, setBufferSize, ICE_NULLPTR, ZEND_ACC_PUBLIC)
457 {0, 0, 0}
458 };
459
ZEND_METHOD(Ice_ConnectionInfo,__construct)460 ZEND_METHOD(Ice_ConnectionInfo, __construct)
461 {
462 runtimeError("ConnectionInfo cannot be instantiated" TSRMLS_CC);
463 }
464
465 //
466 // Predefined methods for ConnectionInfo.
467 //
468 static zend_function_entry _connectionInfoClassMethods[] =
469 {
470 ZEND_ME(Ice_ConnectionInfo, __construct, ICE_NULLPTR, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
471 {0, 0, 0}
472 };
473 //
474 // enable warning again
475 //
476 #if defined(__GNUC__)
477 # pragma GCC diagnostic error "-Wwrite-strings"
478 #endif
479
480 #ifdef _WIN32
481 extern "C"
482 #endif
483 static zend_object_value
handleConnectionInfoAlloc(zend_class_entry * ce TSRMLS_DC)484 handleConnectionInfoAlloc(zend_class_entry* ce TSRMLS_DC)
485 {
486 zend_object_value result;
487
488 Wrapper<Ice::ConnectionInfoPtr>* obj = Wrapper<Ice::ConnectionInfoPtr>::create(ce TSRMLS_CC);
489 assert(obj);
490
491 result.handle = zend_objects_store_put(obj, 0, (zend_objects_free_object_storage_t)handleConnectionInfoFreeStorage,
492 0 TSRMLS_CC);
493 result.handlers = &_connectionInfoHandlers;
494
495 return result;
496 }
497
498 #ifdef _WIN32
499 extern "C"
500 #endif
501 static void
handleConnectionInfoFreeStorage(void * p TSRMLS_DC)502 handleConnectionInfoFreeStorage(void* p TSRMLS_DC)
503 {
504 Wrapper<Ice::ConnectionInfoPtr>* obj = static_cast<Wrapper<Ice::ConnectionInfoPtr>*>(p);
505 delete obj->ptr;
506 zend_object_std_dtor(static_cast<zend_object*>(p) TSRMLS_CC);
507 efree(p);
508 }
509
510 bool
connectionInit(TSRMLS_D)511 IcePHP::connectionInit(TSRMLS_D)
512 {
513 //
514 // We register an interface and a class that implements the interface. This allows
515 // applications to safely include the Slice-generated code for the type.
516 //
517
518 //
519 // Register the Connection interface.
520 //
521 zend_class_entry ce;
522 #ifdef ICEPHP_USE_NAMESPACES
523 INIT_NS_CLASS_ENTRY(ce, "Ice", "Connection", _interfaceMethods);
524 #else
525 INIT_CLASS_ENTRY(ce, "Ice_Connection", _interfaceMethods);
526 #endif
527 zend_class_entry* interface = zend_register_internal_interface(&ce TSRMLS_CC);
528
529 //
530 // Register the Connection class.
531 //
532 INIT_CLASS_ENTRY(ce, "IcePHP_Connection", _connectionClassMethods);
533 ce.create_object = handleConnectionAlloc;
534 connectionClassEntry = zend_register_internal_class(&ce TSRMLS_CC);
535 memcpy(&_connectionHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
536 _connectionHandlers.compare_objects = handleConnectionCompare;
537 zend_class_implements(connectionClassEntry TSRMLS_CC, 1, interface);
538
539 //
540 // Register the ConnectionInfo class.
541 //
542 #ifdef ICEPHP_USE_NAMESPACES
543 INIT_NS_CLASS_ENTRY(ce, "Ice", "ConnectionInfo", _connectionInfoClassMethods);
544 #else
545 INIT_CLASS_ENTRY(ce, "Ice_ConnectionInfo", _connectionInfoClassMethods);
546 #endif
547 ce.create_object = handleConnectionInfoAlloc;
548 connectionInfoClassEntry = zend_register_internal_class(&ce TSRMLS_CC);
549 memcpy(&_connectionInfoHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
550 zend_declare_property_null(connectionInfoClassEntry, STRCAST("underlying"), sizeof("underlying") - 1,
551 ZEND_ACC_PUBLIC TSRMLS_CC);
552 zend_declare_property_bool(connectionInfoClassEntry, STRCAST("incoming"), sizeof("incoming") - 1, 0,
553 ZEND_ACC_PUBLIC TSRMLS_CC);
554 zend_declare_property_string(connectionInfoClassEntry, STRCAST("adapterName"), sizeof("adapterName") - 1,
555 STRCAST(""), ZEND_ACC_PUBLIC TSRMLS_CC);
556
557 //
558 // Register the IPConnectionInfo class.
559 //
560 #ifdef ICEPHP_USE_NAMESPACES
561 INIT_NS_CLASS_ENTRY(ce, "Ice", "IPConnectionInfo", ICE_NULLPTR);
562 #else
563 INIT_CLASS_ENTRY(ce, "Ice_IPConnectionInfo", ICE_NULLPTR);
564 #endif
565 ce.create_object = handleConnectionInfoAlloc;
566 ipConnectionInfoClassEntry = zend_register_internal_class_ex(&ce, connectionInfoClassEntry, ICE_NULLPTR TSRMLS_CC);
567 zend_declare_property_string(ipConnectionInfoClassEntry, STRCAST("localAddress"), sizeof("localAddress") - 1,
568 STRCAST(""), ZEND_ACC_PUBLIC TSRMLS_CC);
569 zend_declare_property_long(ipConnectionInfoClassEntry, STRCAST("localPort"), sizeof("localPort") - 1, 0,
570 ZEND_ACC_PUBLIC TSRMLS_CC);
571 zend_declare_property_string(ipConnectionInfoClassEntry, STRCAST("remoteAddress"), sizeof("remoteAddress") - 1,
572 STRCAST(""), ZEND_ACC_PUBLIC TSRMLS_CC);
573 zend_declare_property_long(ipConnectionInfoClassEntry, STRCAST("remotePort"), sizeof("remotePort") - 1, 0,
574 ZEND_ACC_PUBLIC TSRMLS_CC);
575
576 //
577 // Register the TCPConnectionInfo class.
578 //
579 #ifdef ICEPHP_USE_NAMESPACES
580 INIT_NS_CLASS_ENTRY(ce, "Ice", "TCPConnectionInfo", ICE_NULLPTR);
581 #else
582 INIT_CLASS_ENTRY(ce, "Ice_TCPConnectionInfo", ICE_NULLPTR);
583 #endif
584 ce.create_object = handleConnectionInfoAlloc;
585 tcpConnectionInfoClassEntry = zend_register_internal_class_ex(&ce, ipConnectionInfoClassEntry, ICE_NULLPTR TSRMLS_CC);
586
587 //
588 // Register the UDPConnectionInfo class.
589 //
590 #ifdef ICEPHP_USE_NAMESPACES
591 INIT_NS_CLASS_ENTRY(ce, "Ice", "UDPConnectionInfo", ICE_NULLPTR);
592 #else
593 INIT_CLASS_ENTRY(ce, "Ice_UDPConnectionInfo", ICE_NULLPTR);
594 #endif
595 ce.create_object = handleConnectionInfoAlloc;
596 udpConnectionInfoClassEntry = zend_register_internal_class_ex(&ce, ipConnectionInfoClassEntry, ICE_NULLPTR TSRMLS_CC);
597 zend_declare_property_string(udpConnectionInfoClassEntry, STRCAST("mcastAddress"), sizeof("mcastAddress") - 1,
598 STRCAST(""), ZEND_ACC_PUBLIC TSRMLS_CC);
599 zend_declare_property_long(udpConnectionInfoClassEntry, STRCAST("mcastPort"), sizeof("mcastPort") - 1, 0,
600 ZEND_ACC_PUBLIC TSRMLS_CC);
601
602 //
603 // Register the WSConnectionInfo class.
604 //
605 #ifdef ICEPHP_USE_NAMESPACES
606 INIT_NS_CLASS_ENTRY(ce, "Ice", "WSConnectionInfo", ICE_NULLPTR);
607 #else
608 INIT_CLASS_ENTRY(ce, "Ice_WSConnectionInfo", ICE_NULLPTR);
609 #endif
610 ce.create_object = handleConnectionInfoAlloc;
611 wsConnectionInfoClassEntry = zend_register_internal_class_ex(&ce, connectionInfoClassEntry, ICE_NULLPTR TSRMLS_CC);
612 zend_declare_property_string(wsConnectionInfoClassEntry, STRCAST("headers"), sizeof("headers") - 1,
613 STRCAST(""), ZEND_ACC_PUBLIC TSRMLS_CC);
614
615 //
616 // Register the SSLConnectionInfo class.
617 //
618 #ifdef ICEPHP_USE_NAMESPACES
619 INIT_NS_CLASS_ENTRY(ce, "Ice", "SSLConnectionInfo", ICE_NULLPTR);
620 #else
621 INIT_CLASS_ENTRY(ce, "Ice_SSLConnectionInfo", ICE_NULLPTR);
622 #endif
623 ce.create_object = handleConnectionInfoAlloc;
624 sslConnectionInfoClassEntry = zend_register_internal_class_ex(&ce, connectionInfoClassEntry, ICE_NULLPTR TSRMLS_CC);
625 zend_declare_property_string(sslConnectionInfoClassEntry, STRCAST("cipher"), sizeof("cipher") - 1,
626 STRCAST(""), ZEND_ACC_PUBLIC TSRMLS_CC);
627 zend_declare_property_string(sslConnectionInfoClassEntry, STRCAST("certs"), sizeof("certs") - 1,
628 STRCAST(""), ZEND_ACC_PUBLIC TSRMLS_CC);
629 zend_declare_property_bool(sslConnectionInfoClassEntry, STRCAST("verified"), sizeof("verified") - 1, 0,
630 ZEND_ACC_PUBLIC TSRMLS_CC);
631
632 return true;
633 }
634
635 bool
createConnection(zval * zv,const Ice::ConnectionPtr & p TSRMLS_DC)636 IcePHP::createConnection(zval* zv, const Ice::ConnectionPtr& p TSRMLS_DC)
637 {
638 if(object_init_ex(zv, connectionClassEntry) != SUCCESS)
639 {
640 runtimeError("unable to initialize connection" TSRMLS_CC);
641 return false;
642 }
643
644 Wrapper<Ice::ConnectionPtr>* obj = Wrapper<Ice::ConnectionPtr>::extract(zv TSRMLS_CC);
645 assert(obj);
646 assert(!obj->ptr);
647 obj->ptr = new Ice::ConnectionPtr(p);
648
649 return true;
650 }
651
652 bool
fetchConnection(zval * zv,Ice::ConnectionPtr & connection TSRMLS_DC)653 IcePHP::fetchConnection(zval* zv, Ice::ConnectionPtr& connection TSRMLS_DC)
654 {
655 if(ZVAL_IS_NULL(zv))
656 {
657 connection = 0;
658 }
659 else
660 {
661 if(Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != connectionClassEntry)
662 {
663 invalidArgument("value is not a connection" TSRMLS_CC);
664 return false;
665 }
666 Wrapper<Ice::ConnectionPtr>* obj = Wrapper<Ice::ConnectionPtr>::extract(zv TSRMLS_CC);
667 if(!obj)
668 {
669 return false;
670 }
671 connection = *obj->ptr;
672 }
673 return true;
674 }
675
676 bool
createConnectionInfo(zval * zv,const Ice::ConnectionInfoPtr & p TSRMLS_DC)677 IcePHP::createConnectionInfo(zval* zv, const Ice::ConnectionInfoPtr& p TSRMLS_DC)
678 {
679 if(!p)
680 {
681 ZVAL_NULL(zv);
682 return true;
683 }
684
685 int status;
686 if(Ice::WSConnectionInfoPtr::dynamicCast(p))
687 {
688 Ice::WSConnectionInfoPtr info = Ice::WSConnectionInfoPtr::dynamicCast(p);
689 if((status = object_init_ex(zv, wsConnectionInfoClassEntry)) == SUCCESS)
690 {
691 zval* zmap;
692 MAKE_STD_ZVAL(zmap);
693 AutoDestroy mapDestroyer(zmap);
694 if(createStringMap(zmap, info->headers TSRMLS_CC))
695 {
696 add_property_zval(zv, STRCAST("headers"), zmap);
697 }
698 else
699 {
700 return false;
701 }
702 }
703 }
704 else if(Ice::TCPConnectionInfoPtr::dynamicCast(p))
705 {
706 Ice::TCPConnectionInfoPtr info = Ice::TCPConnectionInfoPtr::dynamicCast(p);
707 if((status = object_init_ex(zv, tcpConnectionInfoClassEntry)) == SUCCESS)
708 {
709 add_property_long(zv, STRCAST("rcvSize"), static_cast<long>(info->rcvSize));
710 add_property_long(zv, STRCAST("sndSize"), static_cast<long>(info->sndSize));
711 }
712 }
713 else if(Ice::UDPConnectionInfoPtr::dynamicCast(p))
714 {
715 Ice::UDPConnectionInfoPtr info = Ice::UDPConnectionInfoPtr::dynamicCast(p);
716 if((status = object_init_ex(zv, udpConnectionInfoClassEntry)) == SUCCESS)
717 {
718 add_property_string(zv, STRCAST("mcastAddress"), const_cast<char*>(info->mcastAddress.c_str()), 1);
719 add_property_long(zv, STRCAST("mcastPort"), static_cast<long>(info->mcastPort));
720 add_property_long(zv, STRCAST("rcvSize"), static_cast<long>(info->rcvSize));
721 add_property_long(zv, STRCAST("sndSize"), static_cast<long>(info->sndSize));
722 }
723 }
724 else if(IceSSL::ConnectionInfoPtr::dynamicCast(p))
725 {
726 status = object_init_ex(zv, sslConnectionInfoClassEntry);
727 }
728 else if(Ice::IPConnectionInfoPtr::dynamicCast(p))
729 {
730 status = object_init_ex(zv, ipConnectionInfoClassEntry);
731 }
732 else
733 {
734 status = object_init_ex(zv, connectionInfoClassEntry);
735 }
736
737 if(status != SUCCESS)
738 {
739 runtimeError("unable to initialize connection info" TSRMLS_CC);
740 return false;
741 }
742
743 if(IceSSL::ConnectionInfoPtr::dynamicCast(p))
744 {
745 IceSSL::ConnectionInfoPtr info = IceSSL::ConnectionInfoPtr::dynamicCast(p);
746 add_property_string(zv, STRCAST("cipher"), const_cast<char*>(info->cipher.c_str()), 1);
747 add_property_bool(zv, STRCAST("verified"), info->verified ? 1 : 0);
748
749 zval* zarr;
750 MAKE_STD_ZVAL(zarr);
751 AutoDestroy listDestroyer(zarr);
752
753 Ice::StringSeq encoded;
754 for(vector<IceSSL::CertificatePtr>::const_iterator i = info->certs.begin(); i != info->certs.end(); ++i)
755 {
756 encoded.push_back((*i)->encode());
757 }
758
759 if(createStringArray(zarr, encoded TSRMLS_CC))
760 {
761 add_property_zval(zv, STRCAST("certs"), zarr);
762 }
763 else
764 {
765 return false;
766 }
767 }
768
769 if(Ice::IPConnectionInfoPtr::dynamicCast(p))
770 {
771 Ice::IPConnectionInfoPtr info = Ice::IPConnectionInfoPtr::dynamicCast(p);
772 add_property_string(zv, STRCAST("localAddress"), const_cast<char*>(info->localAddress.c_str()), 1);
773 add_property_long(zv, STRCAST("localPort"), static_cast<long>(info->localPort));
774 add_property_string(zv, STRCAST("remoteAddress"), const_cast<char*>(info->remoteAddress.c_str()), 1);
775 add_property_long(zv, STRCAST("remotePort"), static_cast<long>(info->remotePort));
776 }
777
778 zval* underlying;
779 MAKE_STD_ZVAL(underlying);
780 AutoDestroy underlyingDestroyer(underlying);
781 if(!createConnectionInfo(underlying, p->underlying TSRMLS_CC))
782 {
783 runtimeError("unable to initialize connection info" TSRMLS_CC);
784 return false;
785 }
786 add_property_zval(zv, STRCAST("underlying"), underlying);
787 add_property_bool(zv, STRCAST("incoming"), p->incoming ? 1 : 0);
788 add_property_string(zv, STRCAST("adapterName"), const_cast<char*>(p->adapterName.c_str()), 1);
789
790 Wrapper<Ice::ConnectionInfoPtr>* obj = Wrapper<Ice::ConnectionInfoPtr>::extract(zv TSRMLS_CC);
791 assert(obj);
792 assert(!obj->ptr);
793 obj->ptr = new Ice::ConnectionInfoPtr(p);
794
795 return true;
796 }
797