Skip to content

Commit 9a0d5ab

Browse files
authored
Merge pull request #520 from viest/fix_455
fix: format memory, close #455
2 parents 54c3e07 + 927562b commit 9a0d5ab

File tree

5 files changed

+88
-49
lines changed

5 files changed

+88
-49
lines changed

include/xlswriter.h

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ typedef struct {
8888
lxw_format *format;
8989
} xls_resource_format_t;
9090

91+
typedef struct {
92+
HashTable *maps;
93+
} xls_resource_formats_cache_t;
94+
9195
typedef struct {
9296
lxw_data_validation *validation;
9397
} xls_resource_validation_t;
@@ -102,11 +106,12 @@ typedef struct {
102106
} xls_resource_rich_string_t;
103107

104108
typedef struct _vtiful_xls_object {
105-
xls_resource_read_t read_ptr;
106-
xls_resource_write_t write_ptr;
107-
zend_long write_line;
108-
xls_resource_format_t format_ptr;
109-
zend_object zo;
109+
xls_resource_read_t read_ptr;
110+
xls_resource_write_t write_ptr;
111+
zend_long write_line;
112+
xls_resource_format_t format_ptr;
113+
xls_resource_formats_cache_t formats_cache_ptr;
114+
zend_object zo;
110115
} xls_object;
111116

112117
typedef struct _vtiful_format_object {
@@ -294,6 +299,10 @@ static inline void php_vtiful_close_resource(zend_object *obj) {
294299
intern->format_ptr.format = NULL;
295300
}
296301

302+
if (intern->formats_cache_ptr.maps != NULL) {
303+
zend_hash_destroy(intern->formats_cache_ptr.maps);
304+
}
305+
297306
#ifdef ENABLE_READER
298307
if (intern->read_ptr.sheet_t != NULL) {
299308
xlsxioread_sheet_close(intern->read_ptr.sheet_t);
@@ -361,4 +370,6 @@ lxw_datetime timestamp_to_datetime(zend_long timestamp);
361370
zend_string* char_join_to_zend_str(const char *left, const char *right);
362371
zend_string* str_pick_up(zend_string *left, const char *right, size_t len);
363372

373+
lxw_format* object_format(xls_object *obj, zend_string *format, lxw_format *format_handle);
374+
364375
#endif

kernel/common.c

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ void call_object_method(zval *object, const char *function_name, uint32_t param_
8888
}
8989
/* }}} */
9090

91+
/* {{{ */
9192
lxw_datetime timestamp_to_datetime(zend_long timestamp)
9293
{
9394
int yearLocal = php_idate('Y', timestamp, 0);
@@ -102,4 +103,53 @@ lxw_datetime timestamp_to_datetime(zend_long timestamp)
102103
};
103104

104105
return datetime;
105-
}
106+
}
107+
/* }}} */
108+
109+
/* {{{ */
110+
lxw_format* object_format(xls_object *obj, zend_string *format, lxw_format *format_handle)
111+
{
112+
if (format == NULL && format_handle == NULL) {
113+
return NULL;
114+
}
115+
116+
if (format != NULL && format_handle != NULL) {
117+
zend_string *_format_key = strpprintf(0, "%p|%s", format_handle, format->val);
118+
119+
void *exit_format = zend_hash_str_find_ptr(obj->formats_cache_ptr.maps, ZEND_STRL(_format_key->val));
120+
121+
if (exit_format != NULL) {
122+
zend_string_release(_format_key);
123+
124+
return (lxw_format *)exit_format;
125+
}
126+
127+
lxw_format *new_format = workbook_add_format((&obj->write_ptr)->workbook);
128+
format_copy(new_format, format_handle);
129+
format_set_num_format(new_format, ZSTR_VAL(format));
130+
131+
zend_hash_str_add_ptr(obj->formats_cache_ptr.maps, ZEND_STRL(_format_key->val), new_format);
132+
133+
zend_string_release(_format_key);
134+
135+
return new_format;
136+
}
137+
138+
if (format != NULL) {
139+
void *exit_format = zend_hash_str_find_ptr(obj->formats_cache_ptr.maps, ZEND_STRL(format->val));
140+
141+
if (exit_format != NULL) {
142+
return (lxw_format *)exit_format;
143+
}
144+
145+
lxw_format *new_format = workbook_add_format((&obj->write_ptr)->workbook);
146+
format_set_num_format(new_format, ZSTR_VAL(format));
147+
148+
zend_hash_str_add_ptr(obj->formats_cache_ptr.maps, ZEND_STRL(format->val), new_format);
149+
150+
return new_format;
151+
}
152+
153+
return format_handle;
154+
}
155+
/* }}} */

kernel/excel.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,17 @@ PHP_VTIFUL_API zend_object *vtiful_xls_objects_new(zend_class_entry *ce)
3535

3636
intern->zo.handlers = &vtiful_xls_handlers;
3737

38-
intern->read_ptr.file_t = NULL;
39-
intern->read_ptr.sheet_t = NULL;
38+
HashTable *formats_cache_ht = emalloc(sizeof(HashTable));
39+
zend_hash_init(formats_cache_ht, 0, NULL, ZVAL_PTR_DTOR, 0);
40+
41+
intern->read_ptr.file_t = NULL;
42+
intern->read_ptr.sheet_t = NULL;
4043

4144
intern->format_ptr.format = NULL;
4245
intern->write_ptr.workbook = NULL;
4346

47+
intern->formats_cache_ptr.maps = formats_cache_ht;
48+
4449
intern->read_ptr.data_type_default = READ_TYPE_EMPTY;
4550

4651
return &intern->zo;
@@ -612,7 +617,7 @@ PHP_METHOD(vtiful_xls, header)
612617
}
613618

614619
ZEND_HASH_FOREACH_NUM_KEY_VAL(Z_ARRVAL_P(header), header_l_key, header_value)
615-
type_writer(header_value, 0, header_l_key, &obj->write_ptr, NULL, format_handle);
620+
type_writer(header_value, 0, header_l_key, &obj->write_ptr, NULL, object_format(obj, NULL, format_handle));
616621
ZEND_HASH_FOREACH_END();
617622

618623
// When inserting the header for the first time, the row number is incremented by one,
@@ -657,7 +662,7 @@ PHP_METHOD(vtiful_xls, data)
657662
if (key == NULL) {
658663
column_index = index;
659664
}
660-
type_writer(data, SHEET_CURRENT_LINE(obj), column_index, &obj->write_ptr, NULL, obj->format_ptr.format);
665+
type_writer(data, SHEET_CURRENT_LINE(obj), column_index, &obj->write_ptr, NULL, object_format(obj, NULL, obj->format_ptr.format));
661666

662667
// next number index
663668
++column_index;
@@ -724,9 +729,9 @@ PHP_METHOD(vtiful_xls, insertText)
724729
SHEET_LINE_SET(obj, row);
725730

726731
if (format_handle != NULL) {
727-
type_writer(data, row, column, &obj->write_ptr, format, zval_get_format(format_handle));
732+
type_writer(data, row, column, &obj->write_ptr, format, object_format(obj, format, zval_get_format(format_handle)));
728733
} else {
729-
type_writer(data, row, column, &obj->write_ptr, format, obj->format_ptr.format);
734+
type_writer(data, row, column, &obj->write_ptr, format, object_format(obj, format, obj->format_ptr.format));
730735
}
731736
}
732737
/* }}} */
@@ -799,9 +804,9 @@ PHP_METHOD(vtiful_xls, insertDate)
799804
lxw_datetime datetime = timestamp_to_datetime(data->value.lval);
800805

801806
if (format_handle != NULL) {
802-
datetime_writer(&datetime, row, column, format, &obj->write_ptr, zval_get_format(format_handle));
807+
datetime_writer(&datetime, row, column, format, &obj->write_ptr, object_format(obj, format, zval_get_format(format_handle)));
803808
} else {
804-
datetime_writer(&datetime, row, column, format, &obj->write_ptr, obj->format_ptr.format);
809+
datetime_writer(&datetime, row, column, format, &obj->write_ptr, object_format(obj, format, obj->format_ptr.format));
805810
}
806811

807812
// Release default format
@@ -1007,9 +1012,9 @@ PHP_METHOD(vtiful_xls, mergeCells)
10071012
WORKBOOK_NOT_INITIALIZED(obj);
10081013

10091014
if (argc == 3 && format_handle != NULL) {
1010-
merge_cells(range, data, &obj->write_ptr, zval_get_format(format_handle));
1015+
merge_cells(range, data, &obj->write_ptr, object_format(obj, NULL, zval_get_format(format_handle)));
10111016
} else {
1012-
merge_cells(range, data, &obj->write_ptr, obj->format_ptr.format);
1017+
merge_cells(range, data, &obj->write_ptr, object_format(obj, NULL, obj->format_ptr.format));
10131018
}
10141019
}
10151020
/* }}} */

kernel/write.c

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@ void type_writer(zval *value, zend_long row, zend_long columns, xls_resource_wri
3636

3737
if (value_type == IS_LONG) {
3838
if (format != NULL && format_handle == NULL) {
39-
value_format = workbook_add_format(res->workbook);
40-
41-
format_set_num_format(value_format, ZSTR_VAL(format));
42-
WORKSHEET_WRITER_EXCEPTION(worksheet_write_number(res->worksheet, lxw_row, lxw_col, (double)zval_get_long(value), value_format));
39+
WORKSHEET_WRITER_EXCEPTION(worksheet_write_number(res->worksheet, lxw_row, lxw_col, (double)zval_get_long(value), format_handle));
4340
return;
4441
}
4542

@@ -49,12 +46,7 @@ void type_writer(zval *value, zend_long row, zend_long columns, xls_resource_wri
4946
}
5047

5148
if(format != NULL && format_handle != NULL) {
52-
value_format = workbook_add_format(res->workbook);
53-
54-
format_copy(value_format, format_handle);
55-
format_set_num_format(value_format, ZSTR_VAL(format));
56-
57-
WORKSHEET_WRITER_EXCEPTION(worksheet_write_number(res->worksheet, lxw_row, lxw_col, (double)zval_get_long(value), value_format));
49+
WORKSHEET_WRITER_EXCEPTION(worksheet_write_number(res->worksheet, lxw_row, lxw_col, (double)zval_get_long(value), format_handle));
5850
return;
5951
}
6052

@@ -63,10 +55,7 @@ void type_writer(zval *value, zend_long row, zend_long columns, xls_resource_wri
6355

6456
if (value_type == IS_DOUBLE) {
6557
if (format != NULL && format_handle == NULL) {
66-
value_format = workbook_add_format(res->workbook);
67-
format_set_num_format(value_format, ZSTR_VAL(format));
68-
69-
WORKSHEET_WRITER_EXCEPTION(worksheet_write_number(res->worksheet, lxw_row, lxw_col, zval_get_double(value), value_format));
58+
WORKSHEET_WRITER_EXCEPTION(worksheet_write_number(res->worksheet, lxw_row, lxw_col, zval_get_double(value), format_handle));
7059
return;
7160
}
7261

@@ -76,12 +65,7 @@ void type_writer(zval *value, zend_long row, zend_long columns, xls_resource_wri
7665
}
7766

7867
if(format != NULL && format_handle != NULL) {
79-
value_format = workbook_add_format(res->workbook);
80-
81-
format_copy(value_format, format_handle);
82-
format_set_num_format(value_format, ZSTR_VAL(format));
83-
84-
WORKSHEET_WRITER_EXCEPTION(worksheet_write_number(res->worksheet, lxw_row, lxw_col, zval_get_double(value), value_format));
68+
WORKSHEET_WRITER_EXCEPTION(worksheet_write_number(res->worksheet, lxw_row, lxw_col, zval_get_double(value), format_handle));
8569
return;
8670
}
8771

@@ -255,14 +239,7 @@ void chart_writer(zend_long row, zend_long columns, xls_resource_chart_t *chart_
255239
*/
256240
void datetime_writer(lxw_datetime *datetime, zend_long row, zend_long columns, zend_string *format, xls_resource_write_t *res, lxw_format *format_handle)
257241
{
258-
lxw_format *value_format = workbook_add_format(res->workbook);
259-
260-
if (format_handle != NULL) {
261-
format_copy(value_format, format_handle);
262-
}
263-
264-
format_set_num_format(value_format, ZSTR_VAL(format));
265-
worksheet_write_datetime(res->worksheet, (lxw_row_t)row, (lxw_col_t)columns, datetime, value_format);
242+
worksheet_write_datetime(res->worksheet, (lxw_row_t)row, (lxw_col_t)columns, datetime, format_handle);
266243
}
267244

268245
/*

tests/open_xlsx_next_row_with_data_type_date_array_index.phpt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,7 @@ array(2) {
3636
[1]=>
3737
string(4) "Cost"
3838
}
39-
array(2) {
40-
[0]=>
41-
string(0) ""
42-
[1]=>
43-
string(0) ""
39+
array(0) {
4440
}
4541
array(5) {
4642
[0]=>

0 commit comments

Comments
 (0)