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