Browse Source

Feat(Format): Multiple style overlays

viest 6 years ago
parent
commit
65f556f055
8 changed files with 139 additions and 74 deletions
  1. 95 55
      kernel/format.c
  2. 15 1
      kernel/include.h
  3. 8 5
      tests/007.phpt
  4. 7 4
      tests/008.phpt
  5. 7 4
      tests/009.phpt
  6. 2 1
      tests/011.phpt
  7. 2 1
      tests/012.phpt
  8. 3 3
      tests/format_align.phpt

+ 95 - 55
kernel/format.c

@@ -11,70 +11,105 @@
 */
 
 #include "include.h"
-#include "ext/standard/php_var.h"
 
 zend_class_entry *vtiful_format_ce;
 
-/* {{{ ARG_INFO
+/* {{{ format_objects_new
  */
-ZEND_BEGIN_ARG_INFO_EX(format_bold_arginfo, 0, 0, 1)
-                ZEND_ARG_INFO(0, handle)
-ZEND_END_ARG_INFO()
+static zend_object_handlers format_handlers;
+
+static zend_always_inline void *vtiful_format_object_alloc(size_t obj_size, zend_class_entry *ce) {
+    void *obj = emalloc(obj_size);
+    memset(obj, 0, obj_size);
+    return obj;
+}
+
+PHP_VTIFUL_API zend_object *format_objects_new(zend_class_entry *ce)
+{
+    format_object *format = vtiful_format_object_alloc(sizeof(format_object), ce);
+
+    zend_object_std_init(&format->zo, ce);
+    object_properties_init(&format->zo, ce);
 
-ZEND_BEGIN_ARG_INFO_EX(format_italic_arginfo, 0, 0, 1)
+    format->ptr.format  = NULL;
+    format->zo.handlers = &format_handlers;
+
+    return &format->zo;
+}
+/* }}} */
+
+/* {{{ format_objects_free
+ */
+static void format_objects_free(zend_object *object)
+{
+    format_object *intern = php_vtiful_format_fetch_object(object);
+
+    if (intern->ptr.format != NULL) {
+        // free by workbook
+        intern->ptr.format = NULL;
+    }
+
+    zend_object_std_dtor(&intern->zo);
+}
+/* }}} */
+
+/* {{{ ARG_INFO
+ */
+ZEND_BEGIN_ARG_INFO_EX(format_construct_arginfo, 0, 0, 1)
                 ZEND_ARG_INFO(0, handle)
 ZEND_END_ARG_INFO()
 
-ZEND_BEGIN_ARG_INFO_EX(format_underline_arginfo, 0, 0, 2)
-                ZEND_ARG_INFO(0, handle)
+ZEND_BEGIN_ARG_INFO_EX(format_underline_arginfo, 0, 0, 1)
                 ZEND_ARG_INFO(0, style)
 ZEND_END_ARG_INFO()
 
-ZEND_BEGIN_ARG_INFO_EX(format_align_arginfo, 0, 0, 2)
-                ZEND_ARG_INFO(0, handle)
+ZEND_BEGIN_ARG_INFO_EX(format_align_arginfo, 0, 0, 1)
                 ZEND_ARG_INFO(0, style)
 ZEND_END_ARG_INFO()
 /* }}} */
 
-/** {{{ \Vtiful\Kernel\Format::bold()
+/** {{{ \Vtiful\Kernel\Format::__construct()
  */
-PHP_METHOD(vtiful_format, bold)
+PHP_METHOD(vtiful_format, __construct)
 {
     zval *handle;
-    lxw_format *bold_format;
+    format_object *obj;
     xls_resource_t *xls_res;
 
     ZEND_PARSE_PARAMETERS_START(1, 1)
             Z_PARAM_RESOURCE(handle)
     ZEND_PARSE_PARAMETERS_END();
 
-    xls_res   = zval_get_resource(handle);
-    bold_format = workbook_add_format(xls_res->workbook);
+    ZVAL_COPY(return_value, getThis());
 
-    format_set_bold(bold_format);
+    xls_res = zval_get_resource(handle);
+    obj     = Z_FORMAT_P(getThis());
 
-    RETURN_RES(zend_register_resource(bold_format, le_xls_writer));
+    if (obj->ptr.format == NULL) {
+        obj->ptr.format = workbook_add_format(xls_res->workbook);
+    }
 }
 /* }}} */
 
-/** {{{ \Vtiful\Kernel\Format::italic()
+/** {{{ \Vtiful\Kernel\Format::bold()
  */
-PHP_METHOD(vtiful_format, italic)
+PHP_METHOD(vtiful_format, bold)
 {
-    zval *handle;
-    lxw_format *italic_format;
-    xls_resource_t *xls_res;
-
-    ZEND_PARSE_PARAMETERS_START(1, 1)
-            Z_PARAM_RESOURCE(handle)
-    ZEND_PARSE_PARAMETERS_END();
+    ZVAL_COPY(return_value, getThis());
 
-    xls_res   = zval_get_resource(handle);
-    italic_format = workbook_add_format(xls_res->workbook);
+    format_object *obj = Z_FORMAT_P(getThis());
+    format_set_bold(obj->ptr.format);
+}
+/* }}} */
 
-    format_set_italic(italic_format);
+/** {{{ \Vtiful\Kernel\Format::italic()
+ */
+PHP_METHOD(vtiful_format, italic)
+{
+    ZVAL_COPY(return_value, getThis());
 
-    RETURN_RES(zend_register_resource(italic_format, le_xls_writer));
+    format_object *obj = Z_FORMAT_P(getThis());
+    format_set_italic(obj->ptr.format);
 }
 /* }}} */
 
@@ -82,22 +117,16 @@ PHP_METHOD(vtiful_format, italic)
  */
 PHP_METHOD(vtiful_format, underline)
 {
-    zval *handle;
     zend_long style;
-    lxw_format *underline_format;
-    xls_resource_t *xls_res;
 
-    ZEND_PARSE_PARAMETERS_START(2, 2)
-            Z_PARAM_RESOURCE(handle)
+    ZEND_PARSE_PARAMETERS_START(1, 1)
             Z_PARAM_LONG(style)
     ZEND_PARSE_PARAMETERS_END();
 
-    xls_res = zval_get_resource(handle);
-    underline_format = workbook_add_format(xls_res->workbook);
-
-    format_set_underline(underline_format, style);
+    ZVAL_COPY(return_value, getThis());
 
-    RETURN_RES(zend_register_resource(underline_format, le_xls_writer));
+    format_object *obj = Z_FORMAT_P(getThis());
+    format_set_underline(obj->ptr.format, style);
 }
 /* }}} */
 
@@ -105,19 +134,16 @@ PHP_METHOD(vtiful_format, underline)
  */
 PHP_METHOD(vtiful_format, align)
 {
-    zval *handle = NULL, *args = NULL;
+    zval *args = NULL;
     int argc, i;
 
-    lxw_format *align_format;
-    xls_resource_t *xls_res;
-
-    ZEND_PARSE_PARAMETERS_START(2, -1)
-            Z_PARAM_RESOURCE(handle)
+    ZEND_PARSE_PARAMETERS_START(1, -1)
             Z_PARAM_VARIADIC('+', args, argc)
     ZEND_PARSE_PARAMETERS_END();
 
-    xls_res = zval_get_resource(handle);
-    align_format = workbook_add_format(xls_res->workbook);
+    ZVAL_COPY(return_value, getThis());
+
+    format_object *obj = Z_FORMAT_P(getThis());
 
     for (i = 0; i < argc; ++i) {
         zval *arg = args + i;
@@ -126,10 +152,18 @@ PHP_METHOD(vtiful_format, align)
             zend_throw_exception(vtiful_exception_ce, "Format exception, please view the manual", 150);
         }
 
-        format_set_align(align_format, Z_LVAL_P(arg));
+        format_set_align(obj->ptr.format, Z_LVAL_P(arg));
     }
+}
+/* }}} */
 
-    RETURN_RES(zend_register_resource(align_format, le_xls_writer));
+/** {{{ \Vtiful\Kernel\Format::toResource()
+ */
+PHP_METHOD(vtiful_format, toResource)
+{
+    format_object *obj = Z_FORMAT_P(getThis());
+
+    RETURN_RES(zend_register_resource(obj->ptr.format, le_xls_writer));
 }
 /* }}} */
 
@@ -137,10 +171,12 @@ PHP_METHOD(vtiful_format, align)
 /** {{{ xls_methods
 */
 zend_function_entry format_methods[] = {
-        PHP_ME(vtiful_format, bold,      format_bold_arginfo,      ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-        PHP_ME(vtiful_format, italic,    format_italic_arginfo,    ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-        PHP_ME(vtiful_format, underline, format_underline_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
-        PHP_ME(vtiful_format, align,     format_align_arginfo,     ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+        PHP_ME(vtiful_format, __construct, format_construct_arginfo, ZEND_ACC_PUBLIC)
+        PHP_ME(vtiful_format, bold,        NULL,                     ZEND_ACC_PUBLIC)
+        PHP_ME(vtiful_format, italic,      NULL,                     ZEND_ACC_PUBLIC)
+        PHP_ME(vtiful_format, underline,   format_underline_arginfo, ZEND_ACC_PUBLIC)
+        PHP_ME(vtiful_format, align,       format_align_arginfo,     ZEND_ACC_PUBLIC)
+        PHP_ME(vtiful_format, toResource,  NULL,                     ZEND_ACC_PUBLIC)
         PHP_FE_END
 };
 /* }}} */
@@ -151,9 +187,13 @@ VTIFUL_STARTUP_FUNCTION(format) {
     zend_class_entry ce;
 
     INIT_NS_CLASS_ENTRY(ce, "Vtiful\\Kernel", "Format", format_methods);
-
+    ce.create_object = format_objects_new;
     vtiful_format_ce = zend_register_internal_class(&ce);
 
+    memcpy(&format_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+    format_handlers.offset   = XtOffsetOf(format_object, zo);
+    format_handlers.free_obj = format_objects_free;
+
     REGISTER_CLASS_CONST_LONG(vtiful_format_ce, "UNDERLINE_SINGLE",            LXW_UNDERLINE_SINGLE)
     REGISTER_CLASS_CONST_LONG(vtiful_format_ce, "UNDERLINE_DOUBLE ",           LXW_UNDERLINE_DOUBLE)
     REGISTER_CLASS_CONST_LONG(vtiful_format_ce, "UNDERLINE_SINGLE_ACCOUNTING", LXW_UNDERLINE_SINGLE_ACCOUNTING)

+ 15 - 1
kernel/include.h

@@ -38,23 +38,37 @@ typedef struct {
     lxw_worksheet *worksheet;
 } xls_resource_t;
 
+typedef struct {
+    lxw_format  *format;
+} xls_resource_format_t;
+
 typedef struct _vtiful_xls_object {
     xls_resource_t ptr;
     zend_long      line;
     zend_object    zo;
 } xls_object;
 
+typedef struct _vtiful_format_object {
+    xls_resource_format_t ptr;
+    zend_object zo;
+} format_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));
+}
+
 #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);
 
 #define REGISTER_CLASS_PROPERTY_NULL(class_name, property_name, acc) \
     zend_declare_property_null(class_name, ZEND_STRL(property_name), acc);
 
-#define Z_XLS_P(zv) php_vtiful_xls_fetch_object(Z_OBJ_P(zv));
+#define Z_XLS_P(zv)    php_vtiful_xls_fetch_object(Z_OBJ_P(zv));
+#define Z_FORMAT_P(zv) php_vtiful_format_fetch_object(Z_OBJ_P(zv));
 
 #define ROW(range) \
     lxw_name_to_row(range)

+ 8 - 5
tests/007.phpt

@@ -5,11 +5,14 @@ Check for vtiful presence
 --FILE--
 <?php
 $config = ['path' => './tests'];
-$excel = new \Vtiful\Kernel\Excel($config);
-$handle = $excel->fileName('tutorial01.xlsx')
-    ->getHandle();
-$boldStyle = \Vtiful\Kernel\Format::bold($handle);
-var_dump($boldStyle);
+
+$excel  = new \Vtiful\Kernel\Excel($config);
+$handle = $excel->fileName('tutorial01.xlsx')->getHandle();
+
+$format     = new \Vtiful\Kernel\Format($handle);
+$boldFormat = $format->bold()->toResource();
+
+var_dump($boldFormat);
 ?>
 --EXPECT--
 resource(5) of type (xlsx)

+ 7 - 4
tests/008.phpt

@@ -5,10 +5,13 @@ Check for vtiful presence
 --FILE--
 <?php
 $config = ['path' => './tests'];
-$excel = new \Vtiful\Kernel\Excel($config);
-$handle = $excel->fileName('tutorial01.xlsx')
-    ->getHandle();
-$italicStyle = \Vtiful\Kernel\Format::italic($handle);
+
+$excel  = new \Vtiful\Kernel\Excel($config);
+$handle = $excel->fileName('tutorial01.xlsx')->getHandle();
+
+$format      = new \Vtiful\Kernel\Format($handle);
+$italicStyle = $format->italic()->toResource();
+
 var_dump($italicStyle);
 ?>
 --EXPECT--

+ 7 - 4
tests/009.phpt

@@ -5,10 +5,13 @@ Check for vtiful presence
 --FILE--
 <?php
 $config = ['path' => './tests'];
-$excel = new \Vtiful\Kernel\Excel($config);
-$handle = $excel->fileName('tutorial01.xlsx')
-    ->getHandle();
-$underlineStyle = \Vtiful\Kernel\Format::underline($handle, \Vtiful\Kernel\Format::UNDERLINE_SINGLE);
+
+$excel  = new \Vtiful\Kernel\Excel($config);
+$handle = $excel->fileName('tutorial01.xlsx')->getHandle();
+
+$format         = new \Vtiful\Kernel\Format($handle);
+$underlineStyle = $format->underline(\Vtiful\Kernel\Format::UNDERLINE_SINGLE)->toResource();
+
 var_dump($underlineStyle);
 ?>
 --EXPECT--

+ 2 - 1
tests/011.phpt

@@ -10,7 +10,8 @@ $excel  = new \Vtiful\Kernel\Excel($config);
 $fileObject = $excel->fileName('tutorial01.xlsx');
 $fileHandle = $fileObject->getHandle();
 
-$boldStyle = \Vtiful\Kernel\Format::bold($fileHandle);
+$format    = new \Vtiful\Kernel\Format($fileHandle);
+$boldStyle = $format->bold()->toResource();
 
 $filePath = $fileObject->header(['name', 'age'])
     ->data([['viest', 21]])

+ 2 - 1
tests/012.phpt

@@ -10,7 +10,8 @@ $excel  = new \Vtiful\Kernel\Excel($config);
 $fileObject = $excel->fileName('tutorial01.xlsx');
 $fileHandle = $fileObject->getHandle();
 
-$boldStyle = \Vtiful\Kernel\Format::bold($fileHandle);
+$format    = new \Vtiful\Kernel\Format($fileHandle);
+$boldStyle = $format->bold()->toResource();
 
 $filePath = $fileObject->header(['name', 'age'])
     ->data([

+ 3 - 3
tests/format_align.phpt

@@ -13,11 +13,11 @@ $fileObject  = new \Vtiful\Kernel\Excel($config);
 $fileObject = $fileObject->fileName('tutorial.xlsx');
 $fileHandle = $fileObject->getHandle();
 
-$alignStyle = \Vtiful\Kernel\Format::align(
-    $fileHandle,
+$format     = new \Vtiful\Kernel\Format($fileHandle);
+$alignStyle = $format->align(
     \Vtiful\Kernel\Format::FORMAT_ALIGN_CENTER,
     \Vtiful\Kernel\Format::FORMAT_ALIGN_VERTICAL_CENTER
-);
+)->toResource();
 
 $filePath = $fileObject->header(['name', 'age'])
     ->data([