}
/* }}} */
+#ifdef HAVE_PROGRESS_CALLBACK
+static void _php_zip_progress_callback_free(void *ptr)
+{
+ ze_zip_object *obj = ptr;
+
+ if (!Z_ISUNDEF(obj->progress_callback)) {
+ zval_ptr_dtor(&obj->progress_callback);
+ ZVAL_UNDEF(&obj->progress_callback);
+ }
+}
+#endif
+
+#ifdef HAVE_CANCEL_CALLBACK
+static void _php_zip_cancel_callback_free(void *ptr)
+{
+ ze_zip_object *obj = ptr;
+
+ if (!Z_ISUNDEF(obj->cancel_callback)) {
+ zval_ptr_dtor(&obj->cancel_callback);
+ ZVAL_UNDEF(&obj->cancel_callback);
+ }
+}
+#endif
+
static void php_zip_object_free_storage(zend_object *object) /* {{{ */
{
ze_zip_object * intern = php_zip_fetch_object(object);
efree(intern->buffers);
}
+#ifdef HAVE_PROGRESS_CALLBACK
+ /* if not properly called by libzip */
+ _php_zip_progress_callback_free(intern);
+#endif
+
+#ifdef HAVE_CANCEL_CALLBACK
+ /* if not properly called by libzip */
+ _php_zip_cancel_callback_free(intern);
+#endif
+
intern->za = NULL;
zend_object_std_dtor(&intern->zo);
}
/* }}} */
+#ifdef HAVE_PROGRESS_CALLBACK
+static void _php_zip_progress_callback(zip_t *arch, double state, void *ptr)
+{
+ zval cb_args[1];
+ zval cb_retval;
+ ze_zip_object *obj = ptr;
+
+ ZVAL_DOUBLE(&cb_args[0], state);
+ if (call_user_function_ex(EG(function_table), NULL, &obj->progress_callback, &cb_retval, 1, cb_args, 0, NULL) == SUCCESS && !Z_ISUNDEF(cb_retval)) {
+ zval_ptr_dtor(&cb_retval);
+ }
+}
+
+/* {{{ proto bool ZipArchive::registerProgressCallback(double rate, callable callback)
+register a progression callback: void callback(double state); */
+static ZIPARCHIVE_METHOD(registerProgressCallback)
+{
+ struct zip *intern;
+ zval *self = getThis();
+ double rate;
+ zval *callback;
+ ze_zip_object *obj;
+
+ if (!self) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, self);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "dz", &rate, &callback) == FAILURE) {
+ return;
+ }
+
+ /* callable? */
+ if (!zend_is_callable(callback, 0, NULL)) {
+ zend_string *callback_name = zend_get_callable_name(callback);
+ php_error_docref(NULL, E_WARNING, "Invalid callback '%s'", ZSTR_VAL(callback_name));
+ zend_string_release_ex(callback_name, 0);
+ RETURN_FALSE;
+ }
+
+ obj = Z_ZIP_P(self);
+
+ /* free if called twice */
+ _php_zip_progress_callback_free(obj);
+
+ /* register */
+ ZVAL_COPY(&obj->progress_callback, callback);
+ if (zip_register_progress_callback_with_state(intern, rate, _php_zip_progress_callback, _php_zip_progress_callback_free, obj)) {
+ RETURN_FALSE;
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+#endif
+
+#ifdef HAVE_CANCEL_CALLBACK
+static int _php_zip_cancel_callback(zip_t *arch, void *ptr)
+{
+ zval cb_retval;
+ int retval = 0;
+ ze_zip_object *obj = ptr;
+
+ if (call_user_function_ex(EG(function_table), NULL, &obj->cancel_callback, &cb_retval, 0, NULL, 0, NULL) == SUCCESS && !Z_ISUNDEF(cb_retval)) {
+ retval = zval_get_long(&cb_retval);
+ zval_ptr_dtor(&cb_retval);
+ }
+
+ return retval;
+}
+
+/* {{{ proto bool ZipArchive::registerCancelCallback(callable callback)
+register a progression callback: int callback(double state); */
+static ZIPARCHIVE_METHOD(registerCancelCallback)
+{
+ struct zip *intern;
+ zval *self = getThis();
+ zval *callback;
+ ze_zip_object *obj;
+
+ if (!self) {
+ RETURN_FALSE;
+ }
+
+ ZIP_FROM_OBJECT(intern, self);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &callback) == FAILURE) {
+ return;
+ }
+
+ /* callable? */
+ if (!zend_is_callable(callback, 0, NULL)) {
+ zend_string *callback_name = zend_get_callable_name(callback);
+ php_error_docref(NULL, E_WARNING, "Invalid callback '%s'", ZSTR_VAL(callback_name));
+ zend_string_release_ex(callback_name, 0);
+ RETURN_FALSE;
+ }
+
+ obj = Z_ZIP_P(self);
+
+ /* free if called twice */
+ _php_zip_cancel_callback_free(obj);
+
+ /* register */
+ ZVAL_COPY(&obj->cancel_callback, callback);
+ if (zip_register_cancel_callback_with_state(intern, _php_zip_cancel_callback, _php_zip_cancel_callback_free, obj)) {
+ RETURN_FALSE;
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+#endif
+
/* {{{ ze_zip_object_class_functions */
static const zend_function_entry zip_class_functions[] = {
ZIPARCHIVE_ME(open, arginfo_class_ZipArchive_open, ZEND_ACC_PUBLIC)
ZIPARCHIVE_ME(setEncryptionName, arginfo_class_ZipArchive_setEncryptionName, ZEND_ACC_PUBLIC)
ZIPARCHIVE_ME(setEncryptionIndex, arginfo_class_ZipArchive_setEncryptionIndex, ZEND_ACC_PUBLIC)
#endif
+#ifdef HAVE_PROGRESS_CALLBACK
+ ZIPARCHIVE_ME(registerProgressCallback, arginfo_class_ZipArchive_registerProgressCallback, ZEND_ACC_PUBLIC)
+#endif
+#ifdef HAVE_CANCEL_CALLBACK
+ ZIPARCHIVE_ME(registerCancelCallback, arginfo_class_ZipArchive_registerCancelCallback, ZEND_ACC_PUBLIC)
+#endif
+
PHP_FE_END
};
/* }}} */
ZEND_ARG_TYPE_INFO(0, comment, IS_STRING, 0)
ZEND_END_ARG_INFO()
+#if defined(HAVE_SET_MTIME)
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_setMtimeIndex, 0, 0, 2)
ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0)
ZEND_END_ARG_INFO()
+#endif
+#if defined(HAVE_SET_MTIME)
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_setMtimeName, 0, 0, 2)
ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0)
ZEND_END_ARG_INFO()
+#endif
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_getCommentIndex, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, password, IS_STRING, 0)
ZEND_END_ARG_INFO()
#endif
+
+#if defined(HAVE_PROGRESS_CALLBACK)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_registerProgressCallback, 0, 0, 2)
+ ZEND_ARG_TYPE_INFO(0, rate, IS_DOUBLE, 0)
+ ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0)
+ZEND_END_ARG_INFO()
+#endif
+
+#if defined(HAVE_CANCEL_CALLBACK)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_registerCancelCallback, 0, 0, 1)
+ ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0)
+ZEND_END_ARG_INFO()
+#endif