@@ -1087,6 +1087,206 @@ PHP_METHOD(SplPriorityQueue, __debugInfo)
10871087 RETURN_ARR (spl_heap_object_get_debug_info (spl_ce_SplPriorityQueue , Z_OBJ_P (ZEND_THIS )));
10881088} /* }}} */
10891089
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+
10901290/* iterator handler table */
10911291static const zend_object_iterator_funcs spl_heap_it_funcs = {
10921292 spl_heap_it_dtor ,
0 commit comments