@@ -1075,6 +1075,206 @@ PHP_METHOD(SplPriorityQueue, __debugInfo)
1075
1075
RETURN_ARR (spl_heap_object_get_debug_info (spl_ce_SplPriorityQueue , Z_OBJ_P (ZEND_THIS )));
1076
1076
} /* }}} */
1077
1077
1078
+ static void spl_heap_serialize_properties (zval * return_value , spl_heap_object * intern )
1079
+ {
1080
+ HashTable * props = zend_std_get_properties (& intern -> std );
1081
+
1082
+ ZVAL_ARR (return_value , props ? zend_array_dup (props ) : zend_new_array (0 ));
1083
+ }
1084
+
1085
+ static void spl_heap_serialize_internal_state (zval * return_value , spl_heap_object * intern , bool is_pqueue )
1086
+ {
1087
+ zval heap_elements ;
1088
+ int heap_count = intern -> heap -> count ;
1089
+
1090
+ array_init (return_value );
1091
+ add_assoc_long (return_value , "flags" , intern -> flags );
1092
+
1093
+ if (heap_count == 0 ) {
1094
+ return ;
1095
+ }
1096
+
1097
+ array_init_size (& heap_elements , heap_count );
1098
+
1099
+ for (int heap_idx = 0 ; heap_idx < heap_count ; ++ heap_idx ) {
1100
+ if (is_pqueue ) {
1101
+ spl_pqueue_elem * elem = spl_heap_elem (intern -> heap , heap_idx );
1102
+ zval entry ;
1103
+ array_init (& entry );
1104
+ add_assoc_zval_ex (& entry , "data" , sizeof ("data" ) - 1 , & elem -> data );
1105
+ Z_TRY_ADDREF (elem -> data );
1106
+ add_assoc_zval_ex (& entry , "priority" , sizeof ("priority" ) - 1 , & elem -> priority );
1107
+ Z_TRY_ADDREF (elem -> priority );
1108
+ zend_hash_next_index_insert (Z_ARRVAL (heap_elements ), & entry );
1109
+ } else {
1110
+ zval * elem = spl_heap_elem (intern -> heap , heap_idx );
1111
+ zend_hash_next_index_insert (Z_ARRVAL (heap_elements ), elem );
1112
+ Z_TRY_ADDREF_P (elem );
1113
+ }
1114
+ }
1115
+
1116
+ add_assoc_zval (return_value , "heap_elements" , & heap_elements );
1117
+ }
1118
+
1119
+ static void spl_heap_unserialize_properties (HashTable * props_ht , spl_heap_object * intern )
1120
+ {
1121
+ object_properties_load (& intern -> std , props_ht );
1122
+ if (!EG (exception )) {
1123
+ return ;
1124
+ }
1125
+
1126
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1127
+ }
1128
+
1129
+ static void spl_heap_unserialize_internal_state (HashTable * state_ht , spl_heap_object * intern , zval * this_ptr , bool is_pqueue )
1130
+ {
1131
+ zval * flags_val = zend_hash_str_find (state_ht , "flags" , sizeof ("flags" ) - 1 );
1132
+ if (!flags_val || Z_TYPE_P (flags_val ) != IS_LONG ) {
1133
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object: missing or invalid flags" , ZSTR_VAL (intern -> std .ce -> name ));
1134
+ return ;
1135
+ }
1136
+
1137
+ intern -> flags = (int ) Z_LVAL_P (flags_val );
1138
+
1139
+ zval * heap_elements = zend_hash_str_find (state_ht , "heap_elements" , sizeof ("heap_elements" ) - 1 );
1140
+ if (!heap_elements ) {
1141
+ return ;
1142
+ }
1143
+
1144
+ if (Z_TYPE_P (heap_elements ) != IS_ARRAY ) {
1145
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object: heap_elements must be an array" , ZSTR_VAL (intern -> std .ce -> name ));
1146
+ return ;
1147
+ }
1148
+
1149
+ zval * val ;
1150
+ ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (heap_elements ), val ) {
1151
+ if (is_pqueue ) {
1152
+ if (Z_TYPE_P (val ) != IS_ARRAY ) {
1153
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object: priority queue elements must be arrays" , ZSTR_VAL (intern -> std .ce -> name ));
1154
+ return ;
1155
+ }
1156
+
1157
+ zval * data_val = zend_hash_str_find (Z_ARRVAL_P (val ), "data" , sizeof ("data" ) - 1 );
1158
+ zval * priority_val = zend_hash_str_find (Z_ARRVAL_P (val ), "priority" , sizeof ("priority" ) - 1 );
1159
+
1160
+ if (!data_val || !priority_val ) {
1161
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object: priority queue elements must have data and priority" , ZSTR_VAL (intern -> std .ce -> name ));
1162
+ return ;
1163
+ }
1164
+
1165
+ spl_pqueue_elem elem ;
1166
+ ZVAL_COPY (& elem .data , data_val );
1167
+ ZVAL_COPY (& elem .priority , priority_val );
1168
+ spl_ptr_heap_insert (intern -> heap , & elem , this_ptr );
1169
+ } else {
1170
+ Z_TRY_ADDREF_P (val );
1171
+ spl_ptr_heap_insert (intern -> heap , val , this_ptr );
1172
+ }
1173
+ } ZEND_HASH_FOREACH_END ();
1174
+ }
1175
+
1176
+ PHP_METHOD (SplPriorityQueue , __serialize )
1177
+ {
1178
+ spl_heap_object * intern = Z_SPLHEAP_P (ZEND_THIS );
1179
+ zval props , state ;
1180
+
1181
+ ZEND_PARSE_PARAMETERS_NONE ();
1182
+
1183
+ array_init (return_value );
1184
+
1185
+ spl_heap_serialize_properties (& props , intern );
1186
+ zend_hash_next_index_insert (Z_ARRVAL_P (return_value ), & props );
1187
+
1188
+ spl_heap_serialize_internal_state (& state , intern , true);
1189
+ zend_hash_next_index_insert (Z_ARRVAL_P (return_value ), & state );
1190
+ }
1191
+
1192
+ PHP_METHOD (SplPriorityQueue , __unserialize )
1193
+ {
1194
+ HashTable * data ;
1195
+ spl_heap_object * intern = Z_SPLHEAP_P (ZEND_THIS );
1196
+ zval * props , * state ;
1197
+
1198
+ ZEND_PARSE_PARAMETERS_START (1 , 1 )
1199
+ Z_PARAM_ARRAY_HT (data )
1200
+ ZEND_PARSE_PARAMETERS_END ();
1201
+
1202
+ if (zend_hash_num_elements (data ) != 2 ) {
1203
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1204
+ RETURN_THROWS ();
1205
+ }
1206
+
1207
+ props = zend_hash_index_find (data , 0 );
1208
+ if (!props || Z_TYPE_P (props ) != IS_ARRAY ) {
1209
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1210
+ RETURN_THROWS ();
1211
+ }
1212
+
1213
+ spl_heap_unserialize_properties (Z_ARRVAL_P (props ), intern );
1214
+ if (EG (exception )) {
1215
+ RETURN_THROWS ();
1216
+ }
1217
+
1218
+ state = zend_hash_index_find (data , 1 );
1219
+ if (!state || Z_TYPE_P (state ) != IS_ARRAY ) {
1220
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1221
+ RETURN_THROWS ();
1222
+ }
1223
+
1224
+ spl_heap_unserialize_internal_state (Z_ARRVAL_P (state ), intern , ZEND_THIS , true);
1225
+ }
1226
+
1227
+ PHP_METHOD (SplHeap , __serialize )
1228
+ {
1229
+ spl_heap_object * intern = Z_SPLHEAP_P (ZEND_THIS );
1230
+ zval props , state ;
1231
+
1232
+ ZEND_PARSE_PARAMETERS_NONE ();
1233
+
1234
+ array_init (return_value );
1235
+
1236
+ spl_heap_serialize_properties (& props , intern );
1237
+ zend_hash_next_index_insert (Z_ARRVAL_P (return_value ), & props );
1238
+
1239
+ spl_heap_serialize_internal_state (& state , intern , false);
1240
+ zend_hash_next_index_insert (Z_ARRVAL_P (return_value ), & state );
1241
+ }
1242
+
1243
+ PHP_METHOD (SplHeap , __unserialize )
1244
+ {
1245
+ HashTable * data ;
1246
+ spl_heap_object * intern = Z_SPLHEAP_P (ZEND_THIS );
1247
+ zval * props , * state ;
1248
+
1249
+ ZEND_PARSE_PARAMETERS_START (1 , 1 )
1250
+ Z_PARAM_ARRAY_HT (data )
1251
+ ZEND_PARSE_PARAMETERS_END ();
1252
+
1253
+ if (zend_hash_num_elements (data ) != 2 ) {
1254
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1255
+ RETURN_THROWS ();
1256
+ }
1257
+
1258
+ props = zend_hash_index_find (data , 0 );
1259
+ if (!props || Z_TYPE_P (props ) != IS_ARRAY ) {
1260
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1261
+ RETURN_THROWS ();
1262
+ }
1263
+
1264
+ spl_heap_unserialize_properties (Z_ARRVAL_P (props ), intern );
1265
+ if (EG (exception )) {
1266
+ RETURN_THROWS ();
1267
+ }
1268
+
1269
+ state = zend_hash_index_find (data , 1 );
1270
+ if (!state || Z_TYPE_P (state ) != IS_ARRAY ) {
1271
+ zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1272
+ RETURN_THROWS ();
1273
+ }
1274
+
1275
+ spl_heap_unserialize_internal_state (Z_ARRVAL_P (state ), intern , ZEND_THIS , false);
1276
+ }
1277
+
1078
1278
/* iterator handler table */
1079
1279
static const zend_object_iterator_funcs spl_heap_it_funcs = {
1080
1280
spl_heap_it_dtor ,
0 commit comments