xref: /ext-ds/src/php/objects/php_pair.c (revision 8595b29f)
1 #include "../handlers/php_pair_handlers.h"
2 #include "../classes/php_pair_ce.h"
3 #include "php_pair.h"
4 
php_ds_pair_create_object(zend_class_entry * ce)5 zend_object *php_ds_pair_create_object(zend_class_entry *ce)
6 {
7 #if PHP_VERSION_ID < 70300
8     php_ds_pair_t *obj = ecalloc(1, sizeof(php_ds_pair_t) + zend_object_properties_size(ce));
9 #else
10     php_ds_pair_t *obj = zend_object_alloc(sizeof(php_ds_pair_t), ce);
11 #endif
12     zend_object_std_init(&obj->std, ce);
13     object_properties_init(&obj->std, ce);
14     obj->std.handlers = &php_pair_handlers;
15 
16     return &obj->std;
17 }
18 
php_ds_pair()19 php_ds_pair_t *php_ds_pair()
20 {
21     return (php_ds_pair_t*) php_ds_pair_create_object(php_ds_pair_ce);
22 }
23 
php_ds_pair_ex(zval * key,zval * value)24 php_ds_pair_t *php_ds_pair_ex(zval *key, zval *value)
25 {
26     php_ds_pair_t *obj = php_ds_pair();
27 
28     php_ds_pair_set_key(obj, key);
29     php_ds_pair_set_value(obj, value);
30 
31     return obj;
32 }
33 
php_ds_pair_create_clone(php_ds_pair_t * obj)34 zend_object *php_ds_pair_create_clone(php_ds_pair_t *obj)
35 {
36     zval *key = php_ds_pair_get_key(obj);
37     zval *val = php_ds_pair_get_value(obj);
38 
39     return (zend_object *) php_ds_pair_ex(key, val);
40 }
41 
php_ds_pair_set_key(php_ds_pair_t * pair,zval * key)42 void php_ds_pair_set_key(php_ds_pair_t *pair, zval *key)
43 {
44 #if PHP_VERSION_ID >= 80000
45     zend_update_property(php_ds_pair_ce, (zend_object*) pair, STR_AND_LEN("key"), key);
46 #else
47     zval tmp;
48     ZVAL_DS_PAIR(&tmp, pair);
49     zend_update_property(php_ds_pair_ce, &tmp, STR_AND_LEN("key"), key);
50 #endif
51 }
52 
php_ds_pair_set_value(php_ds_pair_t * pair,zval * value)53 void php_ds_pair_set_value(php_ds_pair_t *pair, zval *value)
54 {
55 #if PHP_VERSION_ID >= 80000
56     zend_update_property(php_ds_pair_ce, (zend_object*) pair, STR_AND_LEN("value"), value);
57 #else
58     zval tmp;
59     ZVAL_DS_PAIR(&tmp, pair);
60     zend_update_property(php_ds_pair_ce, &tmp, STR_AND_LEN("value"), value);
61 #endif
62 }
63 
php_ds_pair_get_key(php_ds_pair_t * pair)64 zval *php_ds_pair_get_key(php_ds_pair_t *pair)
65 {
66     zval rv;
67 #if PHP_VERSION_ID >= 80000
68     return zend_read_property(php_ds_pair_ce, (zend_object*) pair, STR_AND_LEN("key"), false, &rv);
69 #else
70     zval tmp;
71     ZVAL_DS_PAIR(&tmp, pair);
72     return zend_read_property(php_ds_pair_ce, &tmp, STR_AND_LEN("key"), false, &rv);
73 #endif
74 }
75 
php_ds_pair_get_value(php_ds_pair_t * pair)76 zval *php_ds_pair_get_value(php_ds_pair_t *pair)
77 {
78     zval rv;
79 #if PHP_VERSION_ID >= 80000
80     return zend_read_property(php_ds_pair_ce, (zend_object*) pair, STR_AND_LEN("value"), false, &rv);
81 #else
82     zval tmp;
83     ZVAL_DS_PAIR(&tmp, pair);
84     return zend_read_property(php_ds_pair_ce, &tmp, STR_AND_LEN("value"), false, &rv);
85 #endif
86 }
87 
php_ds_pair_to_array(php_ds_pair_t * obj,zval * result)88 void php_ds_pair_to_array(php_ds_pair_t *obj, zval *result)
89 {
90     zval *key = php_ds_pair_get_key(obj);
91     zval *val = php_ds_pair_get_value(obj);
92 
93     array_init_size(result, 2);
94 
95     add_assoc_zval(result, "key", key);
96     add_assoc_zval(result, "value", val);
97 
98     Z_TRY_ADDREF_P(key);
99     Z_TRY_ADDREF_P(val);
100 }
101 
php_ds_pair_serialize(zval * object,unsigned char ** buffer,size_t * length,zend_serialize_data * data)102 int php_ds_pair_serialize(zval *object, unsigned char **buffer, size_t *length, zend_serialize_data *data)
103 {
104     zval *key, *val;
105     smart_str buf = {0};
106 
107     php_ds_pair_t *pair = Z_DS_PAIR_P(object);
108 
109     php_serialize_data_t serialize_data = (php_serialize_data_t) data;
110     PHP_VAR_SERIALIZE_INIT(serialize_data);
111 
112     key = php_ds_pair_get_key(pair);
113     val = php_ds_pair_get_value(pair);
114 
115     php_var_serialize(&buf, key, &serialize_data);
116     php_var_serialize(&buf, val, &serialize_data);
117 
118     smart_str_0(&buf);
119     SERIALIZE_SET_ZSTR(buf.s);
120     zend_string_release(buf.s);
121 
122     PHP_VAR_SERIALIZE_DESTROY(serialize_data);
123     return SUCCESS;
124 }
125 
php_ds_pair_unserialize(zval * object,zend_class_entry * ce,const unsigned char * buffer,size_t length,zend_unserialize_data * data)126 int php_ds_pair_unserialize(zval *object, zend_class_entry *ce, const unsigned char *buffer, size_t length, zend_unserialize_data *data)
127 {
128     zval *key, *value;
129     php_unserialize_data_t unserialize_data = (php_unserialize_data_t) data;
130 
131     const unsigned char *pos = buffer;
132     const unsigned char *max = buffer + length;
133 
134     PHP_VAR_UNSERIALIZE_INIT(unserialize_data);
135 
136     key = var_tmp_var(&unserialize_data);
137     if ( ! php_var_unserialize(key, &pos, max, &unserialize_data)) {
138         goto error;
139     }
140 
141     value = var_tmp_var(&unserialize_data);
142     if ( ! php_var_unserialize(value, &pos, max, &unserialize_data)) {
143         goto error;
144     }
145 
146     ZVAL_DS_PAIR(object, php_ds_pair_ex(key, value));
147     PHP_VAR_UNSERIALIZE_DESTROY(unserialize_data);
148     return SUCCESS;
149 
150 error:
151     PHP_VAR_UNSERIALIZE_DESTROY(unserialize_data);
152     UNSERIALIZE_ERROR();
153     return FAILURE;
154 }
155