1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 #include <Logger.h>
6 #include <Util.h>
7 
8 using namespace std;
9 using namespace IcePHP;
10 
11 ZEND_EXTERN_MODULE_GLOBALS(ice)
12 
13 //
14 // Class entries represent the PHP class implementations we have registered.
15 //
16 namespace IcePHP
17 {
18 zend_class_entry* loggerClassEntry = 0;
19 }
20 
21 //
22 // Logger support.
23 //
24 static zend_object_handlers _loggerHandlers;
25 
26 extern "C"
27 {
28 static zend_object* handleAlloc(zend_class_entry*);
29 static void handleFreeStorage(zend_object*);
30 static zend_object* handleClone(zval*);
31 }
32 
ZEND_METHOD(Ice_Logger,__construct)33 ZEND_METHOD(Ice_Logger, __construct)
34 {
35     runtimeError("logger objects cannot be instantiated");
36 }
37 
ZEND_METHOD(Ice_Logger,__toString)38 ZEND_METHOD(Ice_Logger, __toString)
39 {
40     if(ZEND_NUM_ARGS() > 0)
41     {
42         WRONG_PARAM_COUNT;
43     }
44 
45     RETURN_NULL();
46 }
47 
ZEND_METHOD(Ice_Logger,print)48 ZEND_METHOD(Ice_Logger, print)
49 {
50     char* m;
51     size_t mLen;
52 
53     if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &m, &mLen) == FAILURE)
54     {
55         RETURN_NULL();
56     }
57 
58     Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis());
59     assert(_this);
60 
61     string msg(m, mLen);
62     try
63     {
64         _this->print(msg);
65     }
66     catch(const IceUtil::Exception& ex)
67     {
68         throwException(ex);
69         RETURN_NULL();
70     }
71 }
72 
ZEND_METHOD(Ice_Logger,trace)73 ZEND_METHOD(Ice_Logger, trace)
74 {
75     char* c;
76     size_t cLen;
77     char* m;
78     size_t mLen;
79 
80     if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("ss"), &c, &cLen, &m, &mLen) == FAILURE)
81     {
82         RETURN_NULL();
83     }
84 
85     Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis());
86     assert(_this);
87 
88     string category(c, cLen);
89     string msg(m, mLen);
90     try
91     {
92         _this->trace(category, msg);
93     }
94     catch(const IceUtil::Exception& ex)
95     {
96         throwException(ex);
97         RETURN_NULL();
98     }
99 }
100 
ZEND_METHOD(Ice_Logger,warning)101 ZEND_METHOD(Ice_Logger, warning)
102 {
103     char* m;
104     size_t mLen;
105 
106     if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &m, &mLen) == FAILURE)
107     {
108         RETURN_NULL();
109     }
110 
111     Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis());
112     assert(_this);
113 
114     string msg(m, mLen);
115     try
116     {
117         _this->warning(msg);
118     }
119     catch(const IceUtil::Exception& ex)
120     {
121         throwException(ex);
122         RETURN_NULL();
123     }
124 }
125 
ZEND_METHOD(Ice_Logger,error)126 ZEND_METHOD(Ice_Logger, error)
127 {
128     char* m;
129     size_t mLen;
130 
131     if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &m, &mLen) == FAILURE)
132     {
133         RETURN_NULL();
134     }
135 
136     Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis());
137     assert(_this);
138 
139     string msg(m, mLen);
140     try
141     {
142         _this->error(msg);
143     }
144     catch(const IceUtil::Exception& ex)
145     {
146         throwException(ex);
147         RETURN_NULL();
148     }
149 }
150 
ZEND_METHOD(Ice_Logger,cloneWithPrefix)151 ZEND_METHOD(Ice_Logger, cloneWithPrefix)
152 {
153     char* p;
154     size_t pLen;
155 
156     if(zend_parse_parameters(ZEND_NUM_ARGS(), const_cast<char*>("s"), &p, &pLen) == FAILURE)
157     {
158         RETURN_NULL();
159     }
160 
161     Ice::LoggerPtr _this = Wrapper<Ice::LoggerPtr>::value(getThis());
162     assert(_this);
163 
164     Ice::LoggerPtr clone;
165 
166     string prefix(p, pLen);
167     try
168     {
169         clone = _this->cloneWithPrefix(prefix);
170     }
171     catch(const IceUtil::Exception& ex)
172     {
173         throwException(ex);
174         RETURN_NULL();
175     }
176 
177     if(!createLogger(return_value, clone))
178     {
179         RETURN_NULL();
180     }
181 }
182 
183 #ifdef _WIN32
184 extern "C"
185 #endif
186 static zend_object*
handleAlloc(zend_class_entry * ce)187 handleAlloc(zend_class_entry* ce)
188 {
189     Wrapper<Ice::LoggerPtr>* obj = Wrapper<Ice::LoggerPtr>::create(ce);
190     assert(obj);
191 
192     obj->zobj.handlers = &_loggerHandlers;
193 
194     return &obj->zobj;
195 }
196 
197 #ifdef _WIN32
198 extern "C"
199 #endif
200 static void
handleFreeStorage(zend_object * object)201 handleFreeStorage(zend_object* object)
202 {
203     Wrapper<Ice::LoggerPtr>* obj = Wrapper<Ice::LoggerPtr>::fetch(object);
204     delete obj->ptr;
205     zend_object_std_dtor(object);
206 }
207 
208 #ifdef _WIN32
209 extern "C"
210 #endif
211 static zend_object*
handleClone(zval * zv)212 handleClone(zval* zv)
213 {
214     php_error_docref(0, E_ERROR, "loggers cannot be cloned");
215     return 0;
216 }
217 
218 //
219 // Necessary to suppress warnings from zend_function_entry in php-5.2.
220 //
221 #if defined(__GNUC__)
222 #  pragma GCC diagnostic ignored "-Wwrite-strings"
223 #endif
224 
225 //
226 // Predefined methods for Logger.
227 //
228 static zend_function_entry _interfaceMethods[] =
229 {
230     {0, 0, 0}
231 };
232 static zend_function_entry _classMethods[] =
233 {
234     ZEND_ME(Ice_Logger, __construct, ICE_NULLPTR, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
235     ZEND_ME(Ice_Logger, __toString, ICE_NULLPTR, ZEND_ACC_PUBLIC)
236     ZEND_ME(Ice_Logger, print, ICE_NULLPTR, ZEND_ACC_PUBLIC)
237     ZEND_ME(Ice_Logger, trace, ICE_NULLPTR, ZEND_ACC_PUBLIC)
238     ZEND_ME(Ice_Logger, warning, ICE_NULLPTR, ZEND_ACC_PUBLIC)
239     ZEND_ME(Ice_Logger, error, ICE_NULLPTR, ZEND_ACC_PUBLIC)
240     ZEND_ME(Ice_Logger, cloneWithPrefix, ICE_NULLPTR, ZEND_ACC_PUBLIC)
241     {0, 0, 0}
242 };
243 //
244 // enable warning again
245 //
246 #if defined(__GNUC__)
247 #  pragma GCC diagnostic error "-Wwrite-strings"
248 #endif
249 
250 bool
loggerInit(void)251 IcePHP::loggerInit(void)
252 {
253     //
254     // We register an interface and a class that implements the interface. This allows
255     // applications to safely include the Slice-generated code for the type.
256     //
257 
258     //
259     // Register the Logger interface.
260     //
261     zend_class_entry ce;
262 #ifdef ICEPHP_USE_NAMESPACES
263     INIT_NS_CLASS_ENTRY(ce, "Ice", "Logger", _interfaceMethods);
264 #else
265     INIT_CLASS_ENTRY(ce, "Ice_Logger", _interfaceMethods);
266 #endif
267     zend_class_entry* interface = zend_register_internal_interface(&ce);
268 
269     //
270     // Register the Logger class.
271     //
272     INIT_CLASS_ENTRY(ce, "IcePHP_Logger", _classMethods);
273     ce.create_object = handleAlloc;
274     loggerClassEntry = zend_register_internal_class(&ce);
275     memcpy(&_loggerHandlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
276     _loggerHandlers.clone_obj = handleClone;
277     _loggerHandlers.free_obj = handleFreeStorage;
278     _loggerHandlers.offset = XtOffsetOf(Wrapper<Ice::LoggerPtr>, zobj);
279     zend_class_implements(loggerClassEntry, 1, interface);
280 
281     return true;
282 }
283 
284 bool
createLogger(zval * zv,const Ice::LoggerPtr & p)285 IcePHP::createLogger(zval* zv, const Ice::LoggerPtr& p)
286 {
287     if(object_init_ex(zv, loggerClassEntry) != SUCCESS)
288     {
289         runtimeError("unable to initialize logger object");
290         return false;
291     }
292 
293     Wrapper<Ice::LoggerPtr>* obj = Wrapper<Ice::LoggerPtr>::extract(zv);
294     assert(!obj->ptr);
295     obj->ptr = new Ice::LoggerPtr(p);
296 
297     return true;
298 }
299 
300 bool
fetchLogger(zval * zv,Ice::LoggerPtr & p)301 IcePHP::fetchLogger(zval* zv, Ice::LoggerPtr& p)
302 {
303     if(!ZVAL_IS_NULL(zv))
304     {
305         if(Z_TYPE_P(zv) != IS_OBJECT || Z_OBJCE_P(zv) != loggerClassEntry)
306         {
307             invalidArgument("value is not a logger object");
308             return false;
309         }
310         p = Wrapper<Ice::LoggerPtr>::value(zv);
311         if(!p)
312         {
313             runtimeError("unable to retrieve logger object from object store");
314             return false;
315         }
316     }
317     return true;
318 }
319