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