1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
/**
* Callable.h
*
* This is an internal class that is used internally by the Function and Method
* classes, and that wraps the Zend function entry into a CPP object.
*
* This is an internal class, that is not supposed to be used or called from
* outside the PhpCpp library.
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2013 Copernica BV
*/
/**
* Set up namespace
*/
namespace PhpCpp {
/**
* Class definition
*/
class Callable
{
public:
/**
* Constructor
* @param classname Name of the class
* @param function Name of the function or method
* @param type Hint for the return type
* @param arguments The arguments that are passed to the function
* @param flags Optional flags to be passed to the function
*/
Callable(const std::string &classname, const std::string &function, Type type = nullType, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
_classname(classname), _type(type), _flags(flags)
{
// somehow "&this" is not accepted by the compiler, so we make a copy
Callable *callable = this;
// append function name to the data (the data contains a pointer
// to this object, appended with the function name. this is a trick
// so that we have the pointer to this function available in the
// function name by going back a number of bytes)
_data.reserve(function.size() + sizeof(this));
_data.assign(std::string((const char *)&callable, sizeof(callable)));
_data.append(function);
// find the name
_name = _data.c_str() + sizeof(this);
// process the arguments
process(arguments);
}
/**
* Constructor
* @param classname Name of the class
* @param function Name of the function or method
* @param type Hint for the return type
* @param arguments The arguments that are passed to the function
* @param flags Optional flags to be passed to the function
*/
Callable(const std::string &classname, const std::string &function, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
Callable(classname, function, nullType, arguments, flags) {}
/**
* Constructor
* @param function Name of the function or method
* @param type Hint for the return type
* @param arguments The arguments that are passed to the function
* @param flags Optional flags to be passed to the function
*/
Callable(const std::string &function, Type type = nullType, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
Callable("", function, type, arguments, flags) {}
/**
* Constructor
* @param function Name of the function or method
* @param type Hint for the return type
* @param arguments The arguments that are passed to the function
* @param flags Optional flags to be passed to the function
*/
Callable(const std::string &function, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
Callable("", function, nullType, arguments, flags) {}
/**
* Destructor
*/
virtual ~Callable()
{
delete[] _argv;
}
/**
* Fill a function entry
* @param entry
*/
void fill(zend_function_entry *entry);
private:
/**
* Classname
* @var string
*/
std::string _classname;
/**
* Pointer to current object, appended with function name
* @var string
*/
std::string _data;
/**
* Pointer to the function name
* @var char*
*/
const char *_name;
/**
* The return type
* @var Type
*/
Type _type;
/**
* Function flags (like deprecated, abstract, private, etc)
* @var int
*/
int _flags;
/**
* The number of arguments
* @var int
*/
int _argc;
/**
* The number of required arguments
* @var int
*/
int _required;
/**
* The arguments
* @var zend_arg_info[]
*/
zend_arg_info *_argv;
/**
* Another attempt to fill internal function info
* @param entry
*/
void fill(zend_internal_function_info *info);
/**
* Process the arguments
* @param arguments
*/
void process(const std::initializer_list<Argument> &arguments);
};
/**
* End of namespace
*/
}
|