Przeglądaj źródła

Feat(Close): custom free resource

viest 4 lat temu
rodzic
commit
201d45351a
3 zmienionych plików z 104 dodań i 27 usunięć
  1. 64 16
      include/xlswriter.h
  2. 18 11
      kernel/excel.c
  3. 22 0
      tests/close.phpt

+ 64 - 16
include/xlswriter.h

@@ -118,22 +118,6 @@ typedef struct _vtiful_validation_object {
     zend_object zo;
 } validation_object;
 
-static inline xls_object *php_vtiful_xls_fetch_object(zend_object *obj) {
-    return (xls_object *)((char *)(obj) - XtOffsetOf(xls_object, zo));
-}
-
-static inline format_object *php_vtiful_format_fetch_object(zend_object *obj) {
-    return (format_object *)((char *)(obj) - XtOffsetOf(format_object, zo));
-}
-
-static inline chart_object *php_vtiful_chart_fetch_object(zend_object *obj) {
-    return (chart_object *)((char *)(obj) - XtOffsetOf(chart_object, zo));
-}
-
-static inline validation_object *php_vtiful_validation_fetch_object(zend_object *obj) {
-    return (validation_object *)((char *)(obj) - XtOffsetOf(validation_object, zo));
-}
-
 #define REGISTER_CLASS_CONST_LONG(class_name, const_name, value) \
     zend_declare_class_constant_long(class_name, const_name, sizeof(const_name)-1, (zend_long)value);
 
@@ -223,6 +207,70 @@ static inline validation_object *php_vtiful_validation_fetch_object(zend_object
 #define PROP_OBJ(zv) Z_OBJ_P(zv)
 #endif
 
+static inline xls_object *php_vtiful_xls_fetch_object(zend_object *obj) {
+    if (obj == NULL) {
+        return NULL;
+    }
+
+    return (xls_object *)((char *)(obj) - XtOffsetOf(xls_object, zo));
+}
+
+static inline format_object *php_vtiful_format_fetch_object(zend_object *obj) {
+    if (obj == NULL) {
+        return NULL;
+    }
+
+    return (format_object *)((char *)(obj) - XtOffsetOf(format_object, zo));
+}
+
+static inline chart_object *php_vtiful_chart_fetch_object(zend_object *obj) {
+    if (obj == NULL) {
+        return NULL;
+    }
+
+    return (chart_object *)((char *)(obj) - XtOffsetOf(chart_object, zo));
+}
+
+static inline validation_object *php_vtiful_validation_fetch_object(zend_object *obj) {
+    if (obj == NULL) {
+        return NULL;
+    }
+
+    return (validation_object *)((char *)(obj) - XtOffsetOf(validation_object, zo));
+}
+
+static inline void php_vtiful_close_resource(zend_object *obj) {
+    if (obj == NULL) {
+        return;
+    }
+
+    xls_object *intern = php_vtiful_xls_fetch_object(obj);
+
+    SHEET_LINE_INIT(intern);
+
+    if (intern->write_ptr.workbook != NULL) {
+        lxw_workbook_free(intern->write_ptr.workbook);
+        intern->write_ptr.workbook = NULL;
+    }
+
+    if (intern->format_ptr.format != NULL) {
+        intern->format_ptr.format = NULL;
+    }
+
+#ifdef ENABLE_READER
+    if (intern->read_ptr.sheet_t != NULL) {
+        xlsxioread_sheet_close(intern->read_ptr.sheet_t);
+        intern->read_ptr.sheet_t = NULL;
+    }
+
+    if (intern->read_ptr.file_t != NULL) {
+        xlsxioread_close(intern->read_ptr.file_t);
+        intern->read_ptr.file_t = NULL;
+    }
+#endif
+
+    intern->read_ptr.data_type_default = READ_TYPE_EMPTY;
+}
 
 lxw_format           * zval_get_format(zval *handle);
 lxw_data_validation  * zval_get_validation(zval *resource);

+ 18 - 11
kernel/excel.c

@@ -37,7 +37,9 @@ PHP_VTIFUL_API zend_object *vtiful_xls_objects_new(zend_class_entry *ce)
 
     intern->read_ptr.file_t   = NULL;
     intern->read_ptr.sheet_t  = NULL;
-    intern->format_ptr.format = NULL;
+
+    intern->format_ptr.format  = NULL;
+    intern->write_ptr.workbook = NULL;
 
     intern->read_ptr.data_type_default = READ_TYPE_EMPTY;
 
@@ -51,16 +53,7 @@ static void vtiful_xls_objects_free(zend_object *object)
 {
     xls_object *intern = php_vtiful_xls_fetch_object(object);
 
-    lxw_workbook_free(intern->write_ptr.workbook);
-
-#ifdef ENABLE_READER
-    xlsxioread_sheet_close(intern->read_ptr.sheet_t);
-    xlsxioread_close(intern->read_ptr.file_t);
-#endif
-
-    if (intern->format_ptr.format != NULL) {
-        intern->format_ptr.format = NULL;
-    }
+    php_vtiful_close_resource(object);
 
     zend_object_std_dtor(&intern->zo);
 }
@@ -72,6 +65,9 @@ ZEND_BEGIN_ARG_INFO_EX(xls_construct_arginfo, 0, 0, 1)
                 ZEND_ARG_INFO(0, config)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO_EX(xls_close_arginfo, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO_EX(xls_file_name_arginfo, 0, 0, 1)
                 ZEND_ARG_INFO(0, file_name)
                 ZEND_ARG_INFO(0, sheet_name)
@@ -310,6 +306,16 @@ PHP_METHOD(vtiful_xls, __construct)
 }
 /* }}} */
 
+/** {{{ \Vtiful\Kernel\Excel::close()
+ */
+PHP_METHOD(vtiful_xls, close)
+{
+    php_vtiful_close_resource(Z_OBJ_P(getThis()));
+
+    ZVAL_COPY(return_value, getThis());
+}
+/* }}} */
+
 /** {{{ \Vtiful\Kernel\Excel::filename(string $fileName [, string $sheetName])
  */
 PHP_METHOD(vtiful_xls, fileName)
@@ -1489,6 +1495,7 @@ PHP_METHOD(vtiful_xls, nextCellCallback)
 */
 zend_function_entry xls_methods[] = {
         PHP_ME(vtiful_xls, __construct,   xls_construct_arginfo,      ZEND_ACC_PUBLIC)
+        PHP_ME(vtiful_xls, close,         xls_close_arginfo,          ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_xls, fileName,      xls_file_name_arginfo,      ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_xls, addSheet,      xls_file_add_sheet,         ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_xls, checkoutSheet, xls_file_checkout_sheet,    ZEND_ACC_PUBLIC)

+ 22 - 0
tests/close.phpt

@@ -0,0 +1,22 @@
+--TEST--
+Check for vtiful presence
+--SKIPIF--
+<?php if (!extension_loaded("xlswriter")) print "skip"; ?>
+--FILE--
+<?php
+$config = ['path' => './tests'];
+$excel = new \Vtiful\Kernel\Excel($config);
+$filePath = $excel->fileName('tutorial01.xlsx')
+    ->header(['Item', 'Cost'])
+    ->output();
+
+$excel->close();
+
+var_dump($filePath);
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/tutorial01.xlsx');
+?>
+--EXPECT--
+string(23) "./tests/tutorial01.xlsx"