@@ -933,6 +933,30 @@ static HashTable *php_zip_get_properties(zend_object *object)/* {{{ */
933
933
}
934
934
/* }}} */
935
935
936
+ #ifdef HAVE_PROGRESS_CALLBACK
937
+ static void _php_zip_progress_callback_free (void * ptr )
938
+ {
939
+ ze_zip_object * obj = ptr ;
940
+
941
+ if (!Z_ISUNDEF (obj -> progress_callback )) {
942
+ zval_ptr_dtor (& obj -> progress_callback );
943
+ ZVAL_UNDEF (& obj -> progress_callback );
944
+ }
945
+ }
946
+ #endif
947
+
948
+ #ifdef HAVE_CANCEL_CALLBACK
949
+ static void _php_zip_cancel_callback_free (void * ptr )
950
+ {
951
+ ze_zip_object * obj = ptr ;
952
+
953
+ if (!Z_ISUNDEF (obj -> cancel_callback )) {
954
+ zval_ptr_dtor (& obj -> cancel_callback );
955
+ ZVAL_UNDEF (& obj -> cancel_callback );
956
+ }
957
+ }
958
+ #endif
959
+
936
960
static void php_zip_object_free_storage (zend_object * object ) /* {{{ */
937
961
{
938
962
ze_zip_object * intern = php_zip_fetch_object (object );
@@ -959,6 +983,16 @@ static void php_zip_object_free_storage(zend_object *object) /* {{{ */
959
983
efree (intern -> buffers );
960
984
}
961
985
986
+ #ifdef HAVE_PROGRESS_CALLBACK
987
+ /* if not properly called by libzip */
988
+ _php_zip_progress_callback_free (intern );
989
+ #endif
990
+
991
+ #ifdef HAVE_CANCEL_CALLBACK
992
+ /* if not properly called by libzip */
993
+ _php_zip_cancel_callback_free (intern );
994
+ #endif
995
+
962
996
intern -> za = NULL ;
963
997
zend_object_std_dtor (& intern -> zo );
964
998
@@ -2774,6 +2808,121 @@ static ZIPARCHIVE_METHOD(getStream)
2774
2808
}
2775
2809
/* }}} */
2776
2810
2811
+ #ifdef HAVE_PROGRESS_CALLBACK
2812
+ static void _php_zip_progress_callback (zip_t * arch , double state , void * ptr )
2813
+ {
2814
+ zval cb_args [1 ];
2815
+ zval cb_retval ;
2816
+ ze_zip_object * obj = ptr ;
2817
+
2818
+ ZVAL_DOUBLE (& cb_args [0 ], state );
2819
+ if (call_user_function_ex (EG (function_table ), NULL , & obj -> progress_callback , & cb_retval , 1 , cb_args , 0 , NULL ) == SUCCESS && !Z_ISUNDEF (cb_retval )) {
2820
+ zval_ptr_dtor (& cb_retval );
2821
+ }
2822
+ }
2823
+
2824
+ /* {{{ proto bool ZipArchive::registerProgressCallback(double rate, callable callback)
2825
+ register a progression callback: void callback(double state); */
2826
+ static ZIPARCHIVE_METHOD (registerProgressCallback )
2827
+ {
2828
+ struct zip * intern ;
2829
+ zval * self = getThis ();
2830
+ double rate ;
2831
+ zval * callback ;
2832
+ ze_zip_object * obj ;
2833
+
2834
+ if (!self ) {
2835
+ RETURN_FALSE ;
2836
+ }
2837
+
2838
+ ZIP_FROM_OBJECT (intern , self );
2839
+
2840
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "dz" , & rate , & callback ) == FAILURE ) {
2841
+ return ;
2842
+ }
2843
+
2844
+ /* callable? */
2845
+ if (!zend_is_callable (callback , 0 , NULL )) {
2846
+ zend_string * callback_name = zend_get_callable_name (callback );
2847
+ php_error_docref (NULL , E_WARNING , "Invalid callback '%s'" , ZSTR_VAL (callback_name ));
2848
+ zend_string_release_ex (callback_name , 0 );
2849
+ RETURN_FALSE ;
2850
+ }
2851
+
2852
+ obj = Z_ZIP_P (self );
2853
+
2854
+ /* free if called twice */
2855
+ _php_zip_progress_callback_free (obj );
2856
+
2857
+ /* register */
2858
+ ZVAL_COPY (& obj -> progress_callback , callback );
2859
+ if (zip_register_progress_callback_with_state (intern , rate , _php_zip_progress_callback , _php_zip_progress_callback_free , obj )) {
2860
+ RETURN_FALSE ;
2861
+ }
2862
+
2863
+ RETURN_TRUE ;
2864
+ }
2865
+ /* }}} */
2866
+ #endif
2867
+
2868
+ #ifdef HAVE_CANCEL_CALLBACK
2869
+ static int _php_zip_cancel_callback (zip_t * arch , void * ptr )
2870
+ {
2871
+ zval cb_retval ;
2872
+ int retval = 0 ;
2873
+ ze_zip_object * obj = ptr ;
2874
+
2875
+ if (call_user_function_ex (EG (function_table ), NULL , & obj -> cancel_callback , & cb_retval , 0 , NULL , 0 , NULL ) == SUCCESS && !Z_ISUNDEF (cb_retval )) {
2876
+ retval = zval_get_long (& cb_retval );
2877
+ zval_ptr_dtor (& cb_retval );
2878
+ }
2879
+
2880
+ return retval ;
2881
+ }
2882
+
2883
+ /* {{{ proto bool ZipArchive::registerCancelCallback(callable callback)
2884
+ register a progression callback: int callback(double state); */
2885
+ static ZIPARCHIVE_METHOD (registerCancelCallback )
2886
+ {
2887
+ struct zip * intern ;
2888
+ zval * self = getThis ();
2889
+ zval * callback ;
2890
+ ze_zip_object * obj ;
2891
+
2892
+ if (!self ) {
2893
+ RETURN_FALSE ;
2894
+ }
2895
+
2896
+ ZIP_FROM_OBJECT (intern , self );
2897
+
2898
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "z" , & callback ) == FAILURE ) {
2899
+ return ;
2900
+ }
2901
+
2902
+ /* callable? */
2903
+ if (!zend_is_callable (callback , 0 , NULL )) {
2904
+ zend_string * callback_name = zend_get_callable_name (callback );
2905
+ php_error_docref (NULL , E_WARNING , "Invalid callback '%s'" , ZSTR_VAL (callback_name ));
2906
+ zend_string_release_ex (callback_name , 0 );
2907
+ RETURN_FALSE ;
2908
+ }
2909
+
2910
+ obj = Z_ZIP_P (self );
2911
+
2912
+ /* free if called twice */
2913
+ _php_zip_cancel_callback_free (obj );
2914
+
2915
+ /* register */
2916
+ ZVAL_COPY (& obj -> cancel_callback , callback );
2917
+ if (zip_register_cancel_callback_with_state (intern , _php_zip_cancel_callback , _php_zip_cancel_callback_free , obj )) {
2918
+ RETURN_FALSE ;
2919
+ }
2920
+
2921
+ RETURN_TRUE ;
2922
+ }
2923
+ /* }}} */
2924
+ #endif
2925
+
2777
2926
/* {{{ ze_zip_object_class_functions */
2778
2927
static const zend_function_entry zip_class_functions [] = {
2779
2928
ZIPARCHIVE_ME (open , arginfo_class_ZipArchive_open , ZEND_ACC_PUBLIC )
@@ -2824,6 +2973,13 @@ static const zend_function_entry zip_class_functions[] = {
2824
2973
ZIPARCHIVE_ME (setEncryptionName , arginfo_class_ZipArchive_setEncryptionName , ZEND_ACC_PUBLIC )
2825
2974
ZIPARCHIVE_ME (setEncryptionIndex , arginfo_class_ZipArchive_setEncryptionIndex , ZEND_ACC_PUBLIC )
2826
2975
#endif
2976
+ #ifdef HAVE_PROGRESS_CALLBACK
2977
+ ZIPARCHIVE_ME (registerProgressCallback , arginfo_class_ZipArchive_registerProgressCallback , ZEND_ACC_PUBLIC )
2978
+ #endif
2979
+ #ifdef HAVE_CANCEL_CALLBACK
2980
+ ZIPARCHIVE_ME (registerCancelCallback , arginfo_class_ZipArchive_registerCancelCallback , ZEND_ACC_PUBLIC )
2981
+ #endif
2982
+
2827
2983
PHP_FE_END
2828
2984
};
2829
2985
/* }}} */
0 commit comments