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