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