xref: /ext-ds/src/php/classes/php_map_ce.c (revision 468a68cf)
1 #include "../../common.h"
2 
3 #include "../parameters.h"
4 #include "../arginfo.h"
5 
6 #include "../objects/php_vector.h"
7 #include "../objects/php_map.h"
8 #include "../objects/php_pair.h"
9 #include "../objects/php_set.h"
10 
11 #include "../iterators/php_map_iterator.h"
12 #include "../handlers/php_map_handlers.h"
13 
14 #include "php_collection_ce.h"
15 #include "php_map_ce.h"
16 
17 #define METHOD(name) PHP_METHOD(Map, name)
18 
19 zend_class_entry *php_ds_map_ce;
20 
METHOD(__construct)21 METHOD(__construct)
22 {
23     PARSE_OPTIONAL_ZVAL(values);
24 
25     if (values) {
26         ds_map_put_all(THIS_DS_MAP(), values);
27     }
28 }
29 
METHOD(allocate)30 METHOD(allocate)
31 {
32     PARSE_LONG(capacity);
33     ds_map_allocate(THIS_DS_MAP(), capacity);
34 }
35 
METHOD(apply)36 METHOD(apply)
37 {
38     PARSE_CALLABLE();
39     ds_map_apply(THIS_DS_MAP(), FCI_ARGS);
40 }
41 
METHOD(capacity)42 METHOD(capacity)
43 {
44     PARSE_NONE;
45     RETURN_LONG(ds_map_capacity(THIS_DS_MAP()));
46 }
47 
METHOD(put)48 METHOD(put)
49 {
50     PARSE_ZVAL_ZVAL(key, value);
51     ds_map_put(THIS_DS_MAP(), key, value);
52 }
53 
METHOD(putAll)54 METHOD(putAll)
55 {
56     PARSE_ZVAL(values);
57     ds_map_put_all(THIS_DS_MAP(), values);
58 }
59 
METHOD(get)60 METHOD(get)
61 {
62     PARSE_ZVAL_OPTIONAL_ZVAL(key, def);
63     RETURN_ZVAL_COPY(ds_map_get(THIS_DS_MAP(), key, def));
64 }
65 
METHOD(intersect)66 METHOD(intersect)
67 {
68     PARSE_OBJ(obj, php_ds_map_ce);
69     RETURN_DS_MAP(ds_map_intersect(THIS_DS_MAP(), Z_DS_MAP_P(obj)));
70 }
71 
METHOD(remove)72 METHOD(remove)
73 {
74     PARSE_ZVAL_OPTIONAL_ZVAL(key, def);
75     ds_map_remove(THIS_DS_MAP(), key, def, return_value);
76 }
77 
METHOD(hasKey)78 METHOD(hasKey)
79 {
80     PARSE_ZVAL(key);
81     RETURN_BOOL(ds_map_has_key(THIS_DS_MAP(), key));
82 }
83 
METHOD(hasValue)84 METHOD(hasValue)
85 {
86     PARSE_ZVAL(value);
87     RETURN_BOOL(ds_map_has_value(THIS_DS_MAP(), value));
88 }
89 
METHOD(diff)90 METHOD(diff)
91 {
92     PARSE_OBJ(obj, php_ds_map_ce);
93     RETURN_DS_MAP(ds_map_diff(THIS_DS_MAP(), Z_DS_MAP_P(obj)));
94 }
95 
METHOD(clear)96 METHOD(clear)
97 {
98     PARSE_NONE;
99     ds_map_clear(THIS_DS_MAP());
100 }
101 
METHOD(sort)102 METHOD(sort)
103 {
104     if (ZEND_NUM_ARGS()) {
105         PARSE_COMPARE_CALLABLE();
106         ds_map_sort_by_value_callback(THIS_DS_MAP());
107     } else {
108         ds_map_sort_by_value(THIS_DS_MAP());
109     }
110 }
111 
METHOD(sorted)112 METHOD(sorted)
113 {
114     if (ZEND_NUM_ARGS()) {
115         PARSE_COMPARE_CALLABLE();
116         RETURN_DS_MAP(ds_map_sorted_by_value_callback(THIS_DS_MAP()));
117     } else {
118         RETURN_DS_MAP(ds_map_sorted_by_value(THIS_DS_MAP()));
119     }
120 }
121 
METHOD(ksort)122 METHOD(ksort)
123 {
124     if (ZEND_NUM_ARGS()) {
125         PARSE_COMPARE_CALLABLE();
126         ds_map_sort_by_key_callback(THIS_DS_MAP());
127     } else {
128         ds_map_sort_by_key(THIS_DS_MAP());
129     }
130 }
131 
METHOD(ksorted)132 METHOD(ksorted)
133 {
134     if (ZEND_NUM_ARGS()) {
135         PARSE_COMPARE_CALLABLE();
136         RETURN_DS_MAP(ds_map_sorted_by_key_callback(THIS_DS_MAP()));
137     } else {
138         RETURN_DS_MAP(ds_map_sorted_by_key(THIS_DS_MAP()));
139     }
140 }
141 
METHOD(keys)142 METHOD(keys)
143 {
144     PARSE_NONE;
145     RETURN_DS_SET(ds_set_ex(ds_htable_clone(THIS_DS_MAP()->table)));
146 }
147 
METHOD(last)148 METHOD(last)
149 {
150     PARSE_NONE;
151     RETURN_DS_PAIR(ds_map_last(THIS_DS_MAP()));
152 }
153 
METHOD(merge)154 METHOD(merge)
155 {
156     PARSE_ZVAL(values);
157     RETURN_DS_MAP(ds_map_merge(THIS_DS_MAP(), values));
158 }
159 
METHOD(pairs)160 METHOD(pairs)
161 {
162     ds_map_t *map = THIS_DS_MAP();
163     PARSE_NONE;
164     RETURN_DS_VECTOR(
165         ds_vector_from_buffer(ds_map_pairs(map), DS_MAP_SIZE(map), DS_MAP_SIZE(map)));
166 }
167 
METHOD(toArray)168 METHOD(toArray)
169 {
170     PARSE_NONE;
171     ds_map_to_array(THIS_DS_MAP(), return_value);
172 }
173 
METHOD(count)174 METHOD(count)
175 {
176     PARSE_NONE;
177     RETURN_LONG(DS_MAP_SIZE(THIS_DS_MAP()));
178 }
179 
METHOD(isEmpty)180 METHOD(isEmpty)
181 {
182     PARSE_NONE;
183     RETURN_BOOL(DS_MAP_IS_EMPTY(THIS_DS_MAP()));
184 }
185 
METHOD(copy)186 METHOD(copy)
187 {
188     PARSE_NONE;
189     RETURN_OBJ(php_ds_map_create_clone(THIS_DS_MAP()));
190 }
191 
METHOD(jsonSerialize)192 METHOD(jsonSerialize)
193 {
194     PARSE_NONE;
195     ds_map_to_array(THIS_DS_MAP(), return_value);
196     convert_to_object(return_value);
197 }
198 
METHOD(filter)199 METHOD(filter)
200 {
201     if (ZEND_NUM_ARGS()) {
202         PARSE_CALLABLE();
203         RETURN_DS_MAP(ds_map_filter_callback(THIS_DS_MAP(), FCI_ARGS));
204     } else {
205         RETURN_DS_MAP(ds_map_filter(THIS_DS_MAP()));
206     }
207 }
208 
METHOD(first)209 METHOD(first)
210 {
211     PARSE_NONE;
212     RETURN_DS_PAIR(ds_map_first(THIS_DS_MAP()));
213 }
214 
METHOD(reduce)215 METHOD(reduce)
216 {
217     PARSE_CALLABLE_AND_OPTIONAL_ZVAL(initial);
218     ds_map_reduce(THIS_DS_MAP(), FCI_ARGS, initial, return_value);
219 }
220 
METHOD(reverse)221 METHOD(reverse)
222 {
223     PARSE_NONE;
224     ds_map_reverse(THIS_DS_MAP());
225 }
226 
METHOD(reversed)227 METHOD(reversed)
228 {
229     PARSE_NONE;
230     RETURN_DS_MAP(ds_map_reversed(THIS_DS_MAP()));
231 }
232 
METHOD(skip)233 METHOD(skip)
234 {
235     PARSE_LONG(position);
236     RETURN_DS_PAIR(ds_map_skip(THIS_DS_MAP(), position));
237 }
238 
METHOD(map)239 METHOD(map)
240 {
241     PARSE_CALLABLE();
242     RETURN_DS_MAP(ds_map_map(THIS_DS_MAP(), FCI_ARGS));
243 }
244 
METHOD(slice)245 METHOD(slice)
246 {
247     ds_map_t *map = THIS_DS_MAP();
248 
249     PARSE_LONG_AND_OPTIONAL_ZVAL(index, length);
250 
251     if (ZEND_NUM_ARGS() > 1 && Z_TYPE_P(length) != IS_NULL) {
252         if (Z_TYPE_P(length) != IS_LONG) {
253             INTEGER_LENGTH_REQUIRED(length);
254         } else {
255             RETURN_DS_MAP(ds_map_slice(map, index, Z_LVAL_P(length)));
256         }
257     } else {
258         RETURN_DS_MAP(ds_map_slice(map, index, DS_MAP_SIZE(map)));
259     }
260 }
261 
METHOD(sum)262 METHOD(sum)
263 {
264     PARSE_NONE;
265     ds_map_sum(THIS_DS_MAP(), return_value);
266 }
267 
METHOD(union)268 METHOD(union)
269 {
270     PARSE_OBJ(obj, php_ds_map_ce);
271     RETURN_DS_MAP(ds_map_union(THIS_DS_MAP(), Z_DS_MAP_P(obj)));
272 }
273 
METHOD(values)274 METHOD(values)
275 {
276     ds_map_t *map = THIS_DS_MAP();
277     PARSE_NONE;
278     RETURN_DS_VECTOR(
279         ds_vector_from_buffer(ds_map_values(map), DS_MAP_SIZE(map), DS_MAP_SIZE(map)));
280 }
281 
METHOD(xor)282 METHOD(xor)
283 {
284     PARSE_OBJ(obj, php_ds_map_ce);
285     RETURN_DS_MAP(ds_map_xor(THIS_DS_MAP(), Z_DS_MAP_P(obj)));
286 }
287 
METHOD(getIterator)288 METHOD(getIterator) {
289     PARSE_NONE;
290     ZVAL_COPY(return_value, getThis());
291 }
292 
METHOD(offsetExists)293 METHOD(offsetExists)
294 {
295     PARSE_ZVAL(offset);
296     RETURN_BOOL(ds_htable_isset(THIS_DS_MAP()->table, offset, false));
297 }
298 
METHOD(offsetGet)299 METHOD(offsetGet)
300 {
301     PARSE_ZVAL(offset);
302     RETURN_ZVAL_COPY(ds_map_get(THIS_DS_MAP(), offset, NULL));
303 }
304 
METHOD(offsetSet)305 METHOD(offsetSet)
306 {
307     PARSE_ZVAL_ZVAL(offset, value);
308     ds_map_put(THIS_DS_MAP(), offset, value);
309 }
310 
METHOD(offsetUnset)311 METHOD(offsetUnset)
312 {
313     PARSE_ZVAL(offset);
314     ds_map_remove(THIS_DS_MAP(), offset, NULL, return_value);
315 }
316 
php_ds_register_map()317 void php_ds_register_map()
318 {
319     zend_class_entry ce;
320 
321     zend_function_entry methods[] = {
322         PHP_DS_ME(Map, __construct)
323         PHP_DS_ME(Map, allocate)
324         PHP_DS_ME(Map, apply)
325         PHP_DS_ME(Map, capacity)
326         PHP_DS_ME(Map, diff)
327         PHP_DS_ME(Map, filter)
328         PHP_DS_ME(Map, first)
329         PHP_DS_ME(Map, get)
330         PHP_DS_ME(Map, hasKey)
331         PHP_DS_ME(Map, hasValue)
332         PHP_DS_ME(Map, intersect)
333         PHP_DS_ME(Map, keys)
334         PHP_DS_ME(Map, ksort)
335         PHP_DS_ME(Map, ksorted)
336         PHP_DS_ME(Map, last)
337         PHP_DS_ME(Map, map)
338         PHP_DS_ME(Map, merge)
339         PHP_DS_ME(Map, pairs)
340         PHP_DS_ME(Map, put)
341         PHP_DS_ME(Map, putAll)
342         PHP_DS_ME(Map, reduce)
343         PHP_DS_ME(Map, remove)
344         PHP_DS_ME(Map, reverse)
345         PHP_DS_ME(Map, reversed)
346         PHP_DS_ME(Map, skip)
347         PHP_DS_ME(Map, slice)
348         PHP_DS_ME(Map, sort)
349         PHP_DS_ME(Map, sorted)
350         PHP_DS_ME(Map, sum)
351         PHP_DS_ME(Map, union)
352         PHP_DS_ME(Map, values)
353         PHP_DS_ME(Map, xor)
354         PHP_DS_ME(Map, getIterator)
355 
356         PHP_DS_ME(Map, offsetExists)
357         PHP_DS_ME(Map, offsetGet)
358         PHP_DS_ME(Map, offsetSet)
359         PHP_DS_ME(Map, offsetUnset)
360 
361         PHP_DS_COLLECTION_ME_LIST(Map)
362         PHP_FE_END
363     };
364 
365     INIT_CLASS_ENTRY(ce, PHP_DS_NS(Map), methods);
366 
367     php_ds_map_ce = zend_register_internal_class(&ce);
368     php_ds_map_ce->ce_flags      |= ZEND_ACC_FINAL;
369     php_ds_map_ce->create_object  = php_ds_map_create_object;
370     php_ds_map_ce->get_iterator   = php_ds_map_get_iterator;
371     php_ds_map_ce->serialize      = php_ds_map_serialize;
372     php_ds_map_ce->unserialize    = php_ds_map_unserialize;
373 
374     zend_declare_class_constant_long(
375         php_ds_map_ce,
376         STR_AND_LEN("MIN_CAPACITY"),
377         DS_HTABLE_MIN_CAPACITY
378     );
379 
380     zend_class_implements(php_ds_map_ce, 2,
381         collection_ce,
382         zend_ce_arrayaccess
383     );
384 
385     php_ds_register_map_handlers();
386 }
387