1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 #ifndef ICEPHP_UTIL_H
6 #define ICEPHP_UTIL_H
7 
8 #include <Config.h>
9 
10 //
11 // Global functions.
12 //
13 extern "C"
14 {
15 ZEND_FUNCTION(Ice_stringVersion);
16 ZEND_FUNCTION(Ice_intVersion);
17 ZEND_FUNCTION(Ice_generateUUID);
18 ZEND_FUNCTION(Ice_currentProtocol);
19 ZEND_FUNCTION(Ice_currentProtocolEncoding);
20 ZEND_FUNCTION(Ice_currentEncoding);
21 ZEND_FUNCTION(Ice_protocolVersionToString);
22 ZEND_FUNCTION(Ice_stringToProtocolVersion);
23 ZEND_FUNCTION(Ice_encodingVersionToString);
24 ZEND_FUNCTION(Ice_stringToEncodingVersion);
25 }
26 
27 namespace IcePHP
28 {
29 
30 void* createWrapper(zend_class_entry*, size_t);
31 void* extractWrapper(zval*);
32 
33 //
34 // Wraps a C++ pointer inside a PHP object.
35 //
36 template<typename T>
37 struct Wrapper
38 {
39     T* ptr;
40 
createWrapper41     static Wrapper<T>* create(zend_class_entry* ce)
42     {
43         Wrapper<T>* w = static_cast<Wrapper<T>*>(ecalloc(1, sizeof(Wrapper<T>) + zend_object_properties_size(ce)));
44 
45         zend_object_std_init(&w->zobj, ce);
46         object_properties_init(&w->zobj, ce);
47 
48         w->ptr = 0;
49         return w;
50     }
51 
extractWrapper52     static Wrapper<T>* extract(zval* zv)
53     {
54         return reinterpret_cast<Wrapper<T>*>(reinterpret_cast<char *>(extractWrapper(zv)) - XtOffsetOf(Wrapper<T>, zobj));
55     }
56 
fetchWrapper57     static Wrapper<T>* fetch(zend_object* object)
58     {
59         return reinterpret_cast<Wrapper<T>*>(reinterpret_cast<char *>(object) - XtOffsetOf(Wrapper<T>, zobj));
60     }
61 
valueWrapper62     static T value(zval* zv)
63     {
64         Wrapper<T>* w = extract(zv);
65         if(w)
66         {
67             return *w->ptr;
68         }
69         return 0;
70     }
71 
72     // This must be last element in the struct
73     zend_object zobj;
74 };
75 
76 zend_class_entry* idToClass(const std::string&);
77 zend_class_entry* nameToClass(const std::string&);
78 
79 bool createIdentity(zval*, const Ice::Identity&);
80 bool extractIdentity(zval*, Ice::Identity&);
81 
82 bool createStringMap(zval*, const std::map<std::string, std::string>&);
83 bool extractStringMap(zval*, std::map<std::string, std::string>&);
84 
85 bool createStringArray(zval*, const Ice::StringSeq&);
86 bool extractStringArray(zval*, Ice::StringSeq&);
87 
88 //
89 // Create a PHP instance of Ice_ProtocolVersion.
90 //
91 bool createProtocolVersion(zval*, const Ice::ProtocolVersion&);
92 
93 //
94 // Create a PHP instance of Ice_EncodingVersion.
95 //
96 bool createEncodingVersion(zval*, const Ice::EncodingVersion&);
97 
98 //
99 // Extracts the members of an encoding version.
100 //
101 bool extractEncodingVersion(zval*, Ice::EncodingVersion&);
102 
103 //
104 // Convert the given exception into its PHP equivalent.
105 //
106 void convertException(zval*, const Ice::Exception&);
107 
108 //
109 // Convert the exception and "throw" it.
110 //
111 void throwException(const Ice::Exception&);
112 
113 //
114 // Convert a Zend type (e.g., IS_BOOL, etc.) to a string for use in error messages.
115 //
116 std::string zendTypeToString(int);
117 
118 //
119 // Raise RuntimeException with the given message.
120 //
121 void runtimeError(const char*, ...);
122 
123 //
124 // Raise InvalidArgumentException with the given message.
125 //
126 void invalidArgument(const char*, ...);
127 
128 //
129 // Invoke a method on a PHP object. The method must not take any arguments.
130 //
131 bool invokeMethod(zval*, const std::string&);
132 
133 //
134 // Invoke a method on a PHP object. The method must take one string argument.
135 //
136 bool invokeMethod(zval*, const std::string&, const std::string&);
137 
138 //
139 // Check inheritance.
140 //
141 bool checkClass(zend_class_entry*, zend_class_entry*);
142 
143 //
144 // Exception-safe efree.
145 //
146 class AutoEfree
147 {
148 public:
AutoEfree(void * p)149     AutoEfree(void* p) : _p(p) {}
~AutoEfree()150     ~AutoEfree() { efree(_p); }
151 
152 private:
153     void* _p;
154 };
155 
156 //
157 // Exception-safe zval destroy.
158 //
159 class AutoDestroy
160 {
161 public:
AutoDestroy(zval * zv)162     AutoDestroy(zval* zv) : _zv(zv) {}
~AutoDestroy()163     ~AutoDestroy() { if(_zv) zval_ptr_dtor(_zv); }
164 
release()165     zval* release() { zval* z = _zv; _zv = 0; return z; }
166 
167 private:
168     zval* _zv;
169 };
170 
171 class AutoReleaseString
172 {
173 public:
AutoReleaseString(zend_string * s)174     AutoReleaseString(zend_string* s) : _s(s) {}
~AutoReleaseString()175     ~AutoReleaseString() { if(_s) zend_string_release(_s); }
176 
177 private:
178     zend_string* _s;
179 };
180 
181 } // End of namespace IcePHP
182 
183 #endif
184