summaryrefslogtreecommitdiff
path: root/zend/method.h
blob: dd18a9aa0e4c0e85b1a744ba471c8a89aac8abcd (plain)
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
/**
 *  Method.h
 *
 *  Internal class that represents a native class method, that can be called
 *  from PHP scripts.
 *
 *  @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
 *  @copyright 2014 Copernica BV
 */

/**
 *  Set up namespace
 */
namespace Php {

/**
 *  Class definition
 */
class Method : public Callable
{
public:
    /**
     *  Constructor 
     * 
     *  @param  name            Method name
     *  @param  callback        Native callback
     *  @param  flags           Access flags
     *  @param  args            Argument description
     */
    Method(const char *name, const method_callback_0 &callback, int flags, const Arguments &args) : Callable(name, args), _type(0),    _flags(flags) { _callback.m0  = callback; }
    Method(const char *name, const method_callback_1 &callback, int flags, const Arguments &args) : Callable(name, args), _type(1),    _flags(flags) { _callback.m1  = callback; }
    Method(const char *name, const method_callback_2 &callback, int flags, const Arguments &args) : Callable(name, args), _type(2),    _flags(flags) { _callback.m2  = callback; }
    Method(const char *name, const method_callback_3 &callback, int flags, const Arguments &args) : Callable(name, args), _type(3),    _flags(flags) { _callback.m3  = callback; }
    Method(const char *name, const method_callback_4 &callback, int flags, const Arguments &args) : Callable(name, args), _type(4),    _flags(flags) { _callback.m4  = callback; }
    Method(const char *name, const method_callback_5 &callback, int flags, const Arguments &args) : Callable(name, args), _type(5),    _flags(flags) { _callback.m5  = callback; }
    Method(const char *name, const method_callback_6 &callback, int flags, const Arguments &args) : Callable(name, args), _type(6),    _flags(flags) { _callback.m6  = callback; }
    Method(const char *name, const method_callback_7 &callback, int flags, const Arguments &args) : Callable(name, args), _type(7),    _flags(flags) { _callback.m7  = callback; }
    Method(const char *name, const native_callback_0 &callback, int flags, const Arguments &args) : Callable(name, args), _type(8),    _flags(flags) { _callback.m8  = callback; }
    Method(const char *name, const native_callback_1 &callback, int flags, const Arguments &args) : Callable(name, args), _type(9),    _flags(flags) { _callback.m9  = callback; }
    Method(const char *name, const native_callback_2 &callback, int flags, const Arguments &args) : Callable(name, args), _type(10),   _flags(flags) { _callback.m10 = callback; }
    Method(const char *name, const native_callback_3 &callback, int flags, const Arguments &args) : Callable(name, args), _type(11),   _flags(flags) { _callback.m11 = callback; }
    Method(const char *name,                                    int flags, const Arguments &args) : Callable(name, args), _type(9999), _flags(flags) { _callback.m0 = nullptr;  }

    /**
     *  Copy and move constructors
     *  @param  that
     */
    Method(const Method &that) : Callable(that), _type(that._type), _flags(that._flags), _callback(that._callback) {}
    Method(Method &&that) : Callable(std::move(that)), _type(that._type), _flags(that._flags), _callback(that._callback) {}

    /**
     *  Destructor
     *  @param  type
     *  @param  callback
     */
    virtual ~Method() {}

    /**
     *  Internal method to fill a function entry
     *  @param  zend_function_entry
     *  @param  classname
     */
    void initialize(struct _zend_function_entry *entry, const std::string &classname)
    {
        // fix the flags, if neither public, private and protected is set, we use public,
        // (this solves php warnings if only "final" or only "abstract" is set
        if ((_flags & (Public|Private|Protected)) == 0) _flags |= Public;
        
        // call base
        Callable::initialize(entry, classname.c_str(), _flags);
    }

    /**
     *  Invoke the method
     *  @param  parameters
     *  @return Value
     */
    virtual Value invoke(Parameters &parameters) override
    {
        // the object to call a method on
        Base *base = parameters.object();
        
        // find out which method to call, and call it
        switch (_type) {
        case 0:     (base->*_callback.m0)(); return Value();
        case 1:     (base->*_callback.m1)(parameters); return Value();
        case 2:     return (base->*_callback.m2)();
        case 3:     return (base->*_callback.m3)(parameters);
        case 4:     (base->*_callback.m4)(); return Value();
        case 5:     (base->*_callback.m5)(parameters); return Value();
        case 6:     return (base->*_callback.m6)();
        case 7:     return (base->*_callback.m7)(parameters);
        case 8:     _callback.m8(); return Value();
        case 9:     _callback.m9(parameters); return Value();
        case 10:    return _callback.m10();
        case 11:    return _callback.m11(parameters);
        default:    return Value();
        }
    }


private:
    /**
     *  Callback type
     *  @var int
     */
    int _type;

    /**
     *  Access flags (protected, public, abstract, final, private, etc)
     *  @var int
     */
    int _flags;
    
    /**
     *  The actual callback
     *  @var void*
     */
    union {
         method_callback_0  m0;
         method_callback_1  m1;
         method_callback_2  m2;
         method_callback_3  m3;
         method_callback_4  m4;
         method_callback_5  m5;
         method_callback_6  m6;
         method_callback_7  m7;
         native_callback_0  m8;
         native_callback_1  m9;
         native_callback_2  m10;
         native_callback_3  m11;
    } _callback;
};

/**
 *  End of namespace
 */
}