xref: /ext-ds/src/php/objects/php_priority_queue.c (revision 8595b29f)
1 #include "../iterators/php_priority_queue_iterator.h"
2 #include "../handlers/php_priority_queue_handlers.h"
3 #include "../classes/php_priority_queue_ce.h"
4 
5 #include "php_priority_queue.h"
6 
php_ds_priority_queue_create_object_ex(ds_priority_queue_t * queue)7 zend_object *php_ds_priority_queue_create_object_ex(ds_priority_queue_t *queue)
8 {
9 #if PHP_VERSION_ID < 70300
10     php_ds_priority_queue_t *obj = ecalloc(1, sizeof(php_ds_priority_queue_t) + zend_object_properties_size(php_ds_priority_queue_ce));
11 #else
12     php_ds_priority_queue_t *obj = zend_object_alloc(sizeof(php_ds_priority_queue_t), php_ds_priority_queue_ce);
13 #endif
14     zend_object_std_init(&obj->std, php_ds_priority_queue_ce);
15     obj->std.handlers = &php_priority_queue_handlers;
16 
17     obj->queue   = queue;
18     obj->gc_data = NULL;
19     obj->gc_size = 0;
20 
21     return &obj->std;
22 }
23 
php_ds_priority_queue_create_object(zend_class_entry * ce)24 zend_object *php_ds_priority_queue_create_object(zend_class_entry *ce)
25 {
26     return php_ds_priority_queue_create_object_ex(ds_priority_queue());
27 }
28 
29 
php_ds_priority_queue_create_clone(ds_priority_queue_t * queue)30 zend_object *php_ds_priority_queue_create_clone(ds_priority_queue_t *queue)
31 {
32     return php_ds_priority_queue_create_object_ex(ds_priority_queue_clone(queue));
33 }
34 
35 
php_ds_priority_queue_serialize(zval * object,unsigned char ** buffer,size_t * length,zend_serialize_data * data)36 int php_ds_priority_queue_serialize(zval *object, unsigned char **buffer, size_t *length, zend_serialize_data *data)
37 {
38     ds_priority_queue_t *queue = Z_DS_PRIORITY_QUEUE_P(object);
39 
40     php_serialize_data_t serialize_data = (php_serialize_data_t) data;
41     PHP_VAR_SERIALIZE_INIT(serialize_data);
42 
43     if (queue->size == 0) {
44         SERIALIZE_SET_ZSTR(ZSTR_EMPTY_ALLOC());
45 
46     } else {
47         ds_priority_queue_node_t *nodes = ds_priority_queue_create_sorted_buffer(queue);
48         ds_priority_queue_node_t *pos   = nodes;
49         ds_priority_queue_node_t *end   = nodes + queue->size;
50 
51         smart_str buf = {0};
52 
53         for (; pos < end; ++pos) {
54             php_var_serialize(&buf, &pos->value, &serialize_data);
55             php_var_serialize(&buf, &pos->priority, &serialize_data);
56         }
57 
58         smart_str_0(&buf);
59         SERIALIZE_SET_ZSTR(buf.s);
60         zend_string_release(buf.s);
61 
62         efree(nodes);
63     }
64 
65     PHP_VAR_SERIALIZE_DESTROY(serialize_data);
66     return SUCCESS;
67 }
68 
php_ds_priority_queue_unserialize(zval * object,zend_class_entry * ce,const unsigned char * buffer,size_t length,zend_unserialize_data * data)69 int php_ds_priority_queue_unserialize(zval *object, zend_class_entry *ce, const unsigned char *buffer, size_t length, zend_unserialize_data *data)
70 {
71     ds_priority_queue_t *queue = ds_priority_queue();
72 
73     php_unserialize_data_t unserialize_data = (php_unserialize_data_t) data;
74 
75     const unsigned char *pos = buffer;
76     const unsigned char *end = buffer + length;
77 
78     PHP_VAR_UNSERIALIZE_INIT(unserialize_data);
79     ZVAL_DS_PRIORITY_QUEUE(object, queue);
80 
81     while (pos != end) {
82         zval *value, *priority;
83 
84         value = var_tmp_var(&unserialize_data);
85         if ( ! php_var_unserialize(value, &pos, end, &unserialize_data)) {
86             goto error;
87         }
88 
89         priority = var_tmp_var(&unserialize_data);
90 
91         if ( ! php_var_unserialize(priority, &pos, end, &unserialize_data)) {
92             goto error;
93         }
94 
95         ds_priority_queue_push(queue, value, priority);
96     }
97 
98     PHP_VAR_UNSERIALIZE_DESTROY(unserialize_data);
99     return SUCCESS;
100 
101 error:
102     ds_priority_queue_free(queue);
103     PHP_VAR_UNSERIALIZE_DESTROY(unserialize_data);
104     UNSERIALIZE_ERROR();
105     return FAILURE;
106 }
107