ソースを参照

Feat: nextCellCallback read

viest 5 年 前
コミット
4dd0345229
5 ファイル変更145 行追加15 行削除
  1. 22 8
      .travis.yml
  2. 3 2
      include/read.h
  3. 14 0
      include/xlswriter.h
  4. 30 0
      kernel/excel.c
  5. 76 5
      kernel/read.c

+ 22 - 8
.travis.yml

@@ -7,13 +7,24 @@ compiler:
 os:
   - linux
 
-php:
-  - 7.0
-  - 7.1
-  - 7.2
-  - 7.3
-  - 7.4snapshot
-  - nightly
+matrix:
+  include:
+    - php: 7.0
+      env: USE_VALGRIND=1
+    - php: 7.1
+      env: USE_VALGRIND=1
+    - php: 7.2
+      env: USE_VALGRIND=1
+    - php: 7.3
+      env: USE_VALGRIND=1
+    - php: 7.4snapshot
+      env: USE_VALGRIND=1
+    - php: nightly
+      env: USE_VALGRIND=1
+
+addons:
+  apt:
+    packages: valgrind
 
 notifications:
   email: [email protected]
@@ -27,6 +38,9 @@ branches:
   only:
     - master
     - dev
-    - dev-read
+
 script:
     - ./travis/run-test.sh
+    - make clean && phpize --clean
+    - phpize && ./configure --enable-reader && make clean && make
+    - - if [ -n "$USE_VALGRIND" ]; then REPORT_EXIT_STATUS=1 php -n run-tests.php -m -n -d extension_dir=./modules/ -d extension=xlswriter.so -P --show-diff --set-timeout 120; fi

+ 3 - 2
include/read.h

@@ -16,10 +16,11 @@
 #define READ_SKIP_ROW 0
 #define READ_ROW 0x01
 
-int sheet_read_row(xlsxioreadersheet sheet);
+int sheet_read_row(xlsxioreadersheet sheet_t);
 xlsxioreader file_open(const char *directory, const char *file_name);
 void load_sheet_all_data(xlsxioreadersheet sheet_t, zval *zv_result_t);
-xlsxioreadersheet sheet_open(xlsxioreader file, const zend_string *zs_sheet_name_t);
+xlsxioreadersheet sheet_open(xlsxioreader file_t, const zend_string *zs_sheet_name_t);
 unsigned int load_sheet_current_row_data(xlsxioreadersheet sheet_t, zval *zv_result_t, zval *zv_type, unsigned int flag);
+unsigned int load_sheet_current_row_data_callback(zend_string *zs_sheet_name_t, xlsxioreader file_t, void *callback_data);
 
 #endif //PHP_READ_INCLUDE_H

+ 14 - 0
include/xlswriter.h

@@ -42,6 +42,11 @@ typedef struct {
     xlsxioreader      file_t;
     xlsxioreadersheet sheet_t;
 } xls_resource_read_t;
+
+typedef struct {
+    zend_fcall_info       *fci;
+    zend_fcall_info_cache *fci_cache;
+} xls_read_callback_data;
 #endif
 
 #ifndef ENABLE_READER
@@ -117,6 +122,15 @@ static inline chart_object *php_vtiful_chart_fetch_object(zend_object *obj) {
         }                                                                                                            \
     } while(0);
 
+#define FCALL_TWO_ARGS(bucket)                   \
+    ZVAL_COPY_VALUE(&args[0], &bucket->val); \
+        if (bucket->key) {                       \
+            ZVAL_STR(&args[1], bucket->key);     \
+        } else {                                 \
+            ZVAL_LONG(&args[1], bucket->h);      \
+        }                                        \
+        zend_call_function(&fci, &fci_cache);
+
 #define ROW(range) \
     lxw_name_to_row(range)
 

+ 30 - 0
kernel/excel.c

@@ -782,6 +782,35 @@ PHP_METHOD(vtiful_xls, nextRow)
 }
 /* }}} */
 
+/** {{{ \Vtiful\Kernel\xls::nextCellCallback()
+ */
+PHP_METHOD(vtiful_xls, nextCellCallback)
+{
+    zend_string *zs_sheet_name = NULL;
+    zend_fcall_info       fci       = empty_fcall_info;
+    zend_fcall_info_cache fci_cache = empty_fcall_info_cache;
+
+    ZEND_PARSE_PARAMETERS_START(1, 2)
+            Z_PARAM_FUNC(fci, fci_cache)
+            Z_PARAM_OPTIONAL
+            Z_PARAM_STR(zs_sheet_name)
+    ZEND_PARSE_PARAMETERS_END();
+
+    xls_object *obj = Z_XLS_P(getThis());
+
+    if (!obj->read_ptr.file_t) {
+        RETURN_FALSE;
+    }
+
+    xls_read_callback_data callback_data;
+
+    callback_data.fci = &fci;
+    callback_data.fci_cache = &fci_cache;
+
+    load_sheet_current_row_data_callback(zs_sheet_name, obj->read_ptr.file_t, &callback_data);
+}
+/* }}} */
+
 #endif
 
 /** {{{ xls_methods
@@ -812,6 +841,7 @@ zend_function_entry xls_methods[] = {
         PHP_ME(vtiful_xls, openSheet,     xls_open_sheet_arginfo,     ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_xls, getSheetData,  NULL,                       ZEND_ACC_PUBLIC)
         PHP_ME(vtiful_xls, nextRow,       NULL,                       ZEND_ACC_PUBLIC)
+        PHP_ME(vtiful_xls, nextCellCallback,  NULL,                       ZEND_ACC_PUBLIC)
 #endif
 
         PHP_FE_END

+ 76 - 5
kernel/read.c

@@ -31,20 +31,20 @@ xlsxioreader file_open(const char *directory, const char *file_name) {
 /* }}} */
 
 /* {{{ */
-xlsxioreadersheet sheet_open(xlsxioreader file, const zend_string *zs_sheet_name_t)
+xlsxioreadersheet sheet_open(xlsxioreader file_t, const zend_string *zs_sheet_name_t)
 {
     if (zs_sheet_name_t == NULL) {
-        return xlsxioread_sheet_open(file, NULL, XLSXIOREAD_SKIP_EMPTY_ROWS);
+        return xlsxioread_sheet_open(file_t, NULL, XLSXIOREAD_SKIP_EMPTY_ROWS);
     }
 
-    return xlsxioread_sheet_open(file, ZSTR_VAL(zs_sheet_name_t), XLSXIOREAD_SKIP_EMPTY_ROWS);
+    return xlsxioread_sheet_open(file_t, ZSTR_VAL(zs_sheet_name_t), XLSXIOREAD_SKIP_EMPTY_ROWS);
 }
 /* }}} */
 
 /* {{{ */
-int sheet_read_row(xlsxioreadersheet sheet)
+int sheet_read_row(xlsxioreadersheet sheet_t)
 {
-    return xlsxioread_sheet_next_row(sheet);
+    return xlsxioread_sheet_next_row(sheet_t);
 }
 /* }}} */
 
@@ -111,6 +111,77 @@ unsigned int load_sheet_current_row_data(xlsxioreadersheet sheet_t, zval *zv_res
 }
 /* }}} */
 
+/* {{{ */
+int sheet_row_callback (size_t row, size_t max_col, void* callback_data)
+{
+    if (callback_data == NULL) {
+        return FAILURE;
+    }
+
+    xls_read_callback_data *_callback_data = (xls_read_callback_data *)callback_data;
+
+    zval args[3], retval;
+
+    _callback_data->fci->retval      = &retval;
+    _callback_data->fci->params      = args;
+    _callback_data->fci->param_count = 3;
+
+    ZVAL_LONG(&args[0], row);
+    ZVAL_LONG(&args[1], max_col);
+    ZVAL_STRING(&args[2], "XLSX_ROW_END");
+
+    zend_call_function(_callback_data->fci, _callback_data->fci_cache);
+
+    zval_ptr_dtor(&args[2]);
+    zval_ptr_dtor(&retval);
+
+    return SUCCESS;
+}
+/* }}} */
+
+/* {{{ */
+int sheet_cell_callback (size_t row, size_t col, const char *value, void *callback_data)
+{
+    if (callback_data == NULL) {
+        return FAILURE;
+    }
+
+    xls_read_callback_data *_callback_data = (xls_read_callback_data *)callback_data;
+
+    if (_callback_data->fci == NULL || _callback_data->fci_cache == NULL) {
+        return FAILURE;
+    }
+
+    zval args[3], retval;
+
+    _callback_data->fci->retval      = &retval;
+    _callback_data->fci->params      = args;
+    _callback_data->fci->param_count = 3;
+
+    ZVAL_LONG(&args[0], row);
+    ZVAL_LONG(&args[1], col);
+    ZVAL_STRING(&args[2], value);
+
+    zend_call_function(_callback_data->fci, _callback_data->fci_cache);
+
+    zval_ptr_dtor(&args[2]);
+    zval_ptr_dtor(&retval);
+
+    return SUCCESS;
+}
+/* }}} */
+
+/* {{{ */
+unsigned int load_sheet_current_row_data_callback(zend_string *zs_sheet_name_t, xlsxioreader file_t, void *callback_data)
+{
+    if (zs_sheet_name_t == NULL) {
+        return xlsxioread_process(file_t, NULL, XLSXIOREAD_SKIP_NONE, sheet_cell_callback, sheet_row_callback, callback_data);
+    }
+
+    return xlsxioread_process(file_t, ZSTR_VAL(zs_sheet_name_t), XLSXIOREAD_SKIP_NONE, sheet_cell_callback, sheet_row_callback, callback_data);
+}
+/* }}} */
+
 /* {{{ */
 void load_sheet_all_data(xlsxioreadersheet sheet_t, zval *zv_result_t)
 {