@@ -1075,6 +1075,206 @@ PHP_METHOD(SplPriorityQueue, __debugInfo)
10751075 RETURN_ARR (spl_heap_object_get_debug_info (spl_ce_SplPriorityQueue , Z_OBJ_P (ZEND_THIS )));
10761076} /* }}} */
10771077
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+
10781278/* iterator handler table */
10791279static const zend_object_iterator_funcs spl_heap_it_funcs = {
10801280 spl_heap_it_dtor ,
0 commit comments