summaryrefslogtreecommitdiff
path: root/include/iterator.h
blob: 7cc99cb6b045e4c6243a278b3b2cc639c0c3f29c (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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/**
 *  Iterator.h
 *
 *  Base class for iterators. Extension writers that want to create traversable
 *  classes, should override this class and implement all pure virtual methods
 *  in it.
 *
 *  @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
 *  @copyright 2014 Copernica BV
 */

/**
 *  Forward declarations
 */
struct _zend_object_iterator_funcs;

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

/**
 *  Class definition
 */
class Iterator
{
public:
    /**
     *  Constructor
     *  @param  base        Class over which the iterator is iterating
     */
    Iterator(Base *base) : _object(base) {}
    
    /**
     *  Destructor
     */
    virtual ~Iterator() {}
    
    /**
     *  Is the iterator on a valid position
     *  @return bool
     */
    virtual bool valid() = 0;
    
    /**
     *  The value at the current position
     *  @return Value
     */
    virtual Value current() = 0;
    
    /**
     *  The key at the current position
     *  @return Value
     */
    virtual Value key() = 0;
    
    /**
     *  Move to the next position
     */
    virtual void next() = 0;
    
    /**
     *  Rewind the iterator to the front position
     */
    virtual void rewind() = 0;
    
private:
    /**
     *  During the lifetime of the iterator, the object over which
     *  it iterates is keps as a private variable. This ensures that
     *  this object is not destructed as long as the iterator exists
     *  @var    Value
     */
    Value _object;
    
    /**
     *  The current() method that is called by the Zend engine wants a 
     *  pointer-to-pointer-to-a-zval. Because of this, we have to keep the 
     *  current value in memory after the current() method returns because 
     *  the pointer would otherwise fall out of scope. This is (once again)
     *  odd behavior of the Zend engine, but we'll have to live with that
     *  @var    Value
     */
    Value _current;
    
    /**
     *  Internal method that returns the implementation object
     *  @return zend_object_iterator
     */
    struct _zend_object_iterator *implementation();
    
    /**
     *  Iterator destructor method
     *  @param  iter
     */
    static void destructor(struct _zend_object_iterator *iter);

    /**
     *  Iterator valid function
     *  Returns FAILURE or SUCCESS
     *  @param  iter
     *  @return int
     */
    static int valid(struct _zend_object_iterator *iter);

    /**
     *  Fetch the current item
     *  @param  iter
     *  @param  data
     */
    static void current(struct _zend_object_iterator *iter, struct _zval_struct ***data);

    /**
     *  Fetch the key for the current element (optional, may be NULL). The key
     *  should be written into the provided zval* using the ZVAL_* macros. If
     *  this handler is not provided auto-incrementing integer keys will be
     *  used.
     *  @param  iter
     *  @param  data
     */
    static void key(struct _zend_object_iterator *iter, struct _zval_struct *data);

    /**
     *  Function to retrieve the current key, php 5.3 style
     *  @param  iter
     *  @param  str_key
     *  @param  str_key_len
     *  @param  int_key
     *  @return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG
     */
    static int key(struct _zend_object_iterator *iter, char **str_key, unsigned int *str_key_len, unsigned long *int_key);

    /**
     *  Step forwards to the next element
     *  @param  iter
     */
    static void next(struct _zend_object_iterator *iter);

    /**
     *  Rewind the iterator back to the start
     *  @param  iter
     */
    static void rewind(struct _zend_object_iterator *iter);

    /**
     *  Get access to all iterator functions
     *  @return zend_object_iterator_funcs
     */
    static struct _zend_object_iterator_funcs *functions();

    /**
     *  Classbase is a friend
     */
    friend class ClassBase;
};
    
/**
 *  End namespace
 */
}