@@ -1070,6 +1070,247 @@ 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_internal_state (zval  * return_value , spl_heap_object  * intern , bool  is_pqueue )
1074+ {
1075+ 	zval  heap_elements ;
1076+ 	int  heap_count  =  intern -> heap -> count ;
1077+ 
1078+ 	array_init (return_value );
1079+ 	add_assoc_long (return_value , "flags" , intern -> flags );
1080+ 
1081+ 	array_init_size (& heap_elements , heap_count );
1082+ 
1083+ 	if  (heap_count  ==  0 ) {
1084+ 		add_assoc_zval (return_value , "heap_elements" , & heap_elements );
1085+ 		return ;
1086+ 	}
1087+ 
1088+ 	for  (int  heap_idx  =  0 ; heap_idx  <  heap_count ; ++ heap_idx ) {
1089+ 		if  (is_pqueue ) {
1090+ 			spl_pqueue_elem  * elem  =  spl_heap_elem (intern -> heap , heap_idx );
1091+ 			zval  entry ;
1092+ 			array_init (& entry );
1093+ 			add_assoc_zval_ex (& entry , "data" , strlen ("data" ), & elem -> data );
1094+ 			Z_TRY_ADDREF (elem -> data );
1095+ 			add_assoc_zval_ex (& entry , "priority" , strlen ("priority" ), & elem -> priority );
1096+ 			Z_TRY_ADDREF (elem -> priority );
1097+ 			zend_hash_next_index_insert (Z_ARRVAL (heap_elements ), & entry );
1098+ 		} else  {
1099+ 			zval  * elem  =  spl_heap_elem (intern -> heap , heap_idx );
1100+ 			zend_hash_next_index_insert (Z_ARRVAL (heap_elements ), elem );
1101+ 			Z_TRY_ADDREF_P (elem );
1102+ 		}
1103+ 	}
1104+ 
1105+ 	add_assoc_zval (return_value , "heap_elements" , & heap_elements );
1106+ }
1107+ 
1108+ static  zend_result  spl_heap_unserialize_internal_state (HashTable  * state_ht , spl_heap_object  * intern , zval  * this_ptr , bool  is_pqueue )
1109+ {
1110+ 	zval  * flags_val  =  zend_hash_str_find (state_ht , "flags" , strlen ("flags" ));
1111+ 	if  (!flags_val  ||  Z_TYPE_P (flags_val ) !=  IS_LONG ) {
1112+ 		return  FAILURE ;
1113+ 	}
1114+ 
1115+ 	zend_long  flags_value  =  Z_LVAL_P (flags_val );
1116+ 
1117+ 	if  (is_pqueue ) {
1118+ 		flags_value  &= SPL_PQUEUE_EXTR_MASK ;
1119+ 		if  (!flags_value ) {
1120+ 			return  FAILURE ;
1121+ 		}
1122+ 	} else  if  (flags_value  !=  0 ) { /* Regular heaps should not have user-visible flags */ 
1123+ 		return  FAILURE ;
1124+ 	}
1125+ 
1126+ 	intern -> flags  =  (int ) flags_value ;
1127+ 
1128+ 	zval  * heap_elements  =  zend_hash_str_find (state_ht , "heap_elements" , strlen ("heap_elements" ));
1129+ 	if  (!heap_elements ) {
1130+ 		return  FAILURE ;
1131+ 	}
1132+ 
1133+ 	if  (Z_TYPE_P (heap_elements ) !=  IS_ARRAY ) {
1134+ 		return  FAILURE ;
1135+ 	}
1136+ 
1137+ 	ZEND_HASH_FOREACH_VAL (Z_ARRVAL_P (heap_elements ), zval  * val ) {
1138+ 		if  (is_pqueue ) {
1139+ 			/* PriorityQueue elements are serialized as arrays with 'data' and 'priority' keys */ 
1140+ 			if  (Z_TYPE_P (val ) !=  IS_ARRAY  ||  zend_hash_num_elements (Z_ARRVAL_P (val )) !=  2 ) {
1141+ 				return  FAILURE ;
1142+ 			}
1143+ 
1144+ 			zval  * data_val  =  zend_hash_str_find (Z_ARRVAL_P (val ), "data" , strlen ("data" ) );
1145+ 			zval  * priority_val  =  zend_hash_str_find (Z_ARRVAL_P (val ), "priority" , strlen ("priority" ));
1146+ 
1147+ 			if  (!data_val  ||  !priority_val ) {
1148+ 				return  FAILURE ;
1149+ 			}
1150+ 
1151+ 			spl_pqueue_elem  elem ;
1152+ 			ZVAL_COPY (& elem .data , data_val );
1153+ 			ZVAL_COPY (& elem .priority , priority_val );
1154+ 			spl_ptr_heap_insert (intern -> heap , & elem , this_ptr );
1155+ 			if  (EG (exception )) {
1156+ 				return  FAILURE ;
1157+ 			}
1158+ 		} else  {
1159+ 			Z_TRY_ADDREF_P (val );
1160+ 			spl_ptr_heap_insert (intern -> heap , val , this_ptr );
1161+ 			if  (EG (exception )) {
1162+ 				return  FAILURE ;
1163+ 			}
1164+ 		}
1165+ 	} ZEND_HASH_FOREACH_END ();
1166+ 
1167+ 	return  SUCCESS ;
1168+ }
1169+ 
1170+ PHP_METHOD (SplPriorityQueue , __serialize )
1171+ {
1172+ 	spl_heap_object  * intern  =  Z_SPLHEAP_P (ZEND_THIS );
1173+ 	zval  props , state ;
1174+ 
1175+ 	ZEND_PARSE_PARAMETERS_NONE ();
1176+ 
1177+ 	if  (UNEXPECTED (spl_heap_consistency_validations (intern , false) !=  SUCCESS )) {
1178+ 		RETURN_THROWS ();
1179+ 	}
1180+ 
1181+ 	if  (intern -> heap -> flags  &  SPL_HEAP_WRITE_LOCKED ) {
1182+ 		zend_throw_exception (spl_ce_RuntimeException , "Cannot serialize heap while it is being modified." , 0 );
1183+ 		RETURN_THROWS ();
1184+ 	}
1185+ 
1186+ 	array_init (return_value );
1187+ 
1188+ 	ZVAL_ARR (& props , zend_std_get_properties (& intern -> std ));
1189+ 	Z_TRY_ADDREF (props );
1190+ 	zend_hash_next_index_insert (Z_ARRVAL_P (return_value ), & props );
1191+ 
1192+ 	spl_heap_serialize_internal_state (& state , intern , true);
1193+ 	zend_hash_next_index_insert (Z_ARRVAL_P (return_value ), & state );
1194+ }
1195+ 
1196+ PHP_METHOD (SplPriorityQueue , __unserialize )
1197+ {
1198+ 	HashTable  * data ;
1199+ 	spl_heap_object  * intern  =  Z_SPLHEAP_P (ZEND_THIS );
1200+ 
1201+ 	ZEND_PARSE_PARAMETERS_START (1 , 1 )
1202+ 		Z_PARAM_ARRAY_HT (data )
1203+ 	ZEND_PARSE_PARAMETERS_END ();
1204+ 
1205+ 	if  (zend_hash_num_elements (data ) !=  2 ) {
1206+ 		zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1207+ 		RETURN_THROWS ();
1208+ 	}
1209+ 
1210+ 	zval  * props  =  zend_hash_index_find (data , 0 );
1211+ 	if  (!props  ||  Z_TYPE_P (props ) !=  IS_ARRAY ) {
1212+ 		zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1213+ 		RETURN_THROWS ();
1214+ 	}
1215+ 
1216+ 	object_properties_load (& intern -> std , Z_ARRVAL_P (props ));
1217+ 	if  (EG (exception )) {
1218+ 		zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1219+ 		RETURN_THROWS ();
1220+ 	}
1221+ 
1222+ 	zval  * state  =  zend_hash_index_find (data , 1 );
1223+ 	if  (!state  ||  Z_TYPE_P (state ) !=  IS_ARRAY ) {
1224+ 		zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1225+ 		RETURN_THROWS ();
1226+ 	}
1227+ 
1228+ 	if  (spl_heap_unserialize_internal_state (Z_ARRVAL_P (state ), intern , ZEND_THIS , true) !=  SUCCESS ) {
1229+ 		zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1230+ 		RETURN_THROWS ();
1231+ 	}
1232+ 
1233+ 	if  (EG (exception )) {
1234+ 		RETURN_THROWS ();
1235+ 	}
1236+ 
1237+ 	if  (UNEXPECTED (spl_heap_consistency_validations (intern , false) !=  SUCCESS )) {
1238+ 		RETURN_THROWS ();
1239+ 	}
1240+ }
1241+ 
1242+ PHP_METHOD (SplHeap , __serialize )
1243+ {
1244+ 	spl_heap_object  * intern  =  Z_SPLHEAP_P (ZEND_THIS );
1245+ 	zval  props , state ;
1246+ 
1247+ 	ZEND_PARSE_PARAMETERS_NONE ();
1248+ 
1249+ 	if  (UNEXPECTED (spl_heap_consistency_validations (intern , false) !=  SUCCESS )) {
1250+ 		RETURN_THROWS ();
1251+ 	}
1252+ 
1253+ 	if  (intern -> heap -> flags  &  SPL_HEAP_WRITE_LOCKED ) {
1254+ 		zend_throw_exception (spl_ce_RuntimeException , "Cannot serialize heap while it is being modified." , 0 );
1255+ 		RETURN_THROWS ();
1256+ 	}
1257+ 
1258+ 	array_init (return_value );
1259+ 
1260+ 	ZVAL_ARR (& props , zend_std_get_properties (& intern -> std ));
1261+ 	Z_TRY_ADDREF (props );
1262+ 	zend_hash_next_index_insert (Z_ARRVAL_P (return_value ), & props );
1263+ 
1264+ 	spl_heap_serialize_internal_state (& state , intern , false);
1265+ 	zend_hash_next_index_insert (Z_ARRVAL_P (return_value ), & state );
1266+ }
1267+ 
1268+ PHP_METHOD (SplHeap , __unserialize )
1269+ {
1270+ 	HashTable  * data ;
1271+ 	spl_heap_object  * intern  =  Z_SPLHEAP_P (ZEND_THIS );
1272+ 
1273+ 	ZEND_PARSE_PARAMETERS_START (1 , 1 )
1274+ 		Z_PARAM_ARRAY_HT (data )
1275+ 	ZEND_PARSE_PARAMETERS_END ();
1276+ 
1277+ 	if  (zend_hash_num_elements (data ) !=  2 ) {
1278+ 		zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1279+ 		RETURN_THROWS ();
1280+ 	}
1281+ 
1282+ 	zval  * props  =  zend_hash_index_find (data , 0 );
1283+ 	if  (!props  ||  Z_TYPE_P (props ) !=  IS_ARRAY ) {
1284+ 		zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1285+ 		RETURN_THROWS ();
1286+ 	}
1287+ 
1288+ 	object_properties_load (& intern -> std , Z_ARRVAL_P (props ));
1289+ 	if  (EG (exception )) {
1290+ 		zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1291+ 		RETURN_THROWS ();
1292+ 	}
1293+ 
1294+ 	zval  * state  =  zend_hash_index_find (data , 1 );
1295+ 	if  (!state  ||  Z_TYPE_P (state ) !=  IS_ARRAY ) {
1296+ 		zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1297+ 		RETURN_THROWS ();
1298+ 	}
1299+ 
1300+ 	if  (spl_heap_unserialize_internal_state (Z_ARRVAL_P (state ), intern , ZEND_THIS , false) !=  SUCCESS ) {
1301+ 		zend_throw_exception_ex (NULL , 0 , "Invalid serialization data for %s object" , ZSTR_VAL (intern -> std .ce -> name ));
1302+ 		RETURN_THROWS ();
1303+ 	}
1304+ 
1305+ 	if  (EG (exception )) {
1306+ 		RETURN_THROWS ();
1307+ 	}
1308+ 
1309+ 	if  (UNEXPECTED (spl_heap_consistency_validations (intern , false) !=  SUCCESS )) {
1310+ 		RETURN_THROWS ();
1311+ 	}
1312+ }
1313+ 
10731314/* iterator handler table */ 
10741315static  const  zend_object_iterator_funcs  spl_heap_it_funcs  =  {
10751316	spl_heap_it_dtor ,
0 commit comments