Improved memory usage and readability

Extract the parts for loading the file from application server /
presentation server into two new private methods.
Not only is the code better readable (currently, the very important LOAD
call at the end of the method almost vanishes after all that file
loading code)  - it also saves memory. Currently, when the LOAD message
is processed, not only the EXCEL_DATA xstring, but also BIN_TAB, the
auxiliary table of bytes which is retrieved from GUI_UPLOAD, is kept in
the memory as a redundant copy of the raw data, although during the
parse process it is not needed any more.
This commit is contained in:
Ivan 2014-02-24 16:04:18 -06:00
parent 169764004b
commit ad22cf7eaf

View File

@ -226,7 +226,7 @@
endmethod.</source>
</interfaceMethod>
<interfaceMethod CLSNAME="ZCL_EXCEL_READER_2007" CPDNAME="ZIF_EXCEL_READER~LOAD_FILE">
<source>method ZIF_EXCEL_READER~LOAD_FILE.
<source>METHOD zif_excel_reader~load_file.
*--------------------------------------------------------------------*
* ToDos:
* 2do§1 decision whether to load from frontend or backend
@ -255,129 +255,24 @@
* changes: passing new optional input parameter to private attribute
*--------------------------------------------------------------------*
CONSTANTS: lcv_load_from_frontend TYPE char1 VALUE &apos;F&apos;,
lcv_load_from_backend TYPE char1 VALUE &apos;B&apos;.
DATA: lv_excel_data TYPE xstring.
DATA: lv_load_from_source TYPE char1,
lv_filelength TYPE i,
lt_binary_data TYPE STANDARD TABLE OF x255 WITH NON-UNIQUE DEFAULT KEY,
ls_binary_data LIKE LINE OF lt_binary_data,
* Background processing
lv_max_length_line TYPE i,
lv_actual_length_line TYPE i,
lv_errormessage TYPE string, &quot; Can&apos;t pass &apos;...&apos;(abc) to exception-class
lv_excel_data TYPE xstring. &quot; Binary content of .xlsx file
DATA: lv_filename TYPE string.
*--------------------------------------------------------------------*
* ToDos: 2do§1 Decision whether to load from frontend or backend
*--------------------------------------------------------------------*
*--------------------------------------------------------------------*
* issue#234 - error reading xlsx written by libre office
me-&gt;zif_excel_reader~gv_use_alternate_zip = i_use_alternate_zip.
*--------------------------------------------------------------------*
*--------------------------------------------------------------------*
* Autodecide on frontend or backend reading
* Background-processing --&gt; backend reading
* Online-processing --&gt; frontend reading
*--------------------------------------------------------------------*
IF I_FROM_APPLSERVER = abap_true.
lv_load_from_source = lcv_load_from_backend.
IF i_from_applserver = abap_true.
lv_excel_data = me-&gt;read_from_applserver( i_filename = i_filename ).
ELSE.
lv_load_from_source = lcv_load_from_frontend.
lv_excel_data = me-&gt;read_from_local_file( i_filename = i_filename ).
ENDIF.
move i_filename TO lv_filename.
CASE lv_load_from_source.
*--------------------------------------------------------------------*
* Read from backend
*--------------------------------------------------------------------*
WHEN lcv_load_from_backend.
DESCRIBE FIELD ls_binary_data LENGTH lv_max_length_line IN BYTE MODE.
OPEN DATASET lv_filename FOR INPUT IN BINARY MODE.
IF sy-subrc &lt;&gt; 0.
lv_errormessage = &apos;A problem occured when reading the file&apos;(001).
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
WHILE sy-subrc = 0.
READ DATASET lv_filename INTO ls_binary_data MAXIMUM LENGTH lv_max_length_line ACTUAL LENGTH lv_actual_length_line.
APPEND ls_binary_data TO lt_binary_data.
lv_filelength = lv_filelength + lv_actual_length_line.
ENDWHILE.
CLOSE DATASET lv_filename.
*--------------------------------------------------------------------*
* Read from frontend
*--------------------------------------------------------------------*
WHEN lcv_load_from_frontend.
cl_gui_frontend_services=&gt;gui_upload( EXPORTING
filename = lv_filename
filetype = &apos;BIN&apos; &quot; We are basically working with zipped directories --&gt; force binary read
IMPORTING
filelength = lv_filelength
CHANGING
data_tab = lt_binary_data
EXCEPTIONS
file_open_error = 1
file_read_error = 2
no_batch = 3
gui_refuse_filetransfer = 4
invalid_type = 5
no_authority = 6
unknown_error = 7
bad_data_format = 8
header_not_allowed = 9
separator_not_allowed = 10
header_too_long = 11
unknown_dp_error = 12
access_denied = 13
dp_out_of_memory = 14
disk_full = 15
dp_timeout = 16
not_supported_by_gui = 17
error_no_gui = 18
OTHERS = 19 ).
IF sy-subrc &lt;&gt; 0.
lv_errormessage = &apos;A problem occured when reading the file&apos;(001).
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
ENDCASE.
*--------------------------------------------------------------------*
* Binary data needs to be provided as XSTRING for further processing
*--------------------------------------------------------------------*
CALL FUNCTION &apos;SCMS_BINARY_TO_XSTRING&apos;
EXPORTING
input_length = lv_filelength
IMPORTING
buffer = lv_excel_data
TABLES
binary_tab = lt_binary_data.
*--------------------------------------------------------------------*
* issue#234 - error reading xlsx written by libre office
r_excel = me-&gt;zif_excel_reader~load( i_excel2007 = lv_excel_data
i_use_alternate_zip = i_use_alternate_zip ).
*--------------------------------------------------------------------*
endmethod.</source>
ENDMETHOD.</source>
</interfaceMethod>
<method CLSNAME="ZCL_EXCEL_READER_2007" CMPNAME="FILL_STRUCT_FROM_ATTRIBUTES" VERSION="1" LANGU="E" DESCRIPT="Fills structure fields based on XML node attributes" EXPOSURE="2" STATE="1" EDITORDER="3 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_READER_2007" CMPNAME="FILL_STRUCT_FROM_ATTRIBUTES" SCONAME="IP_ELEMENT" VERSION="1" LANGU="E" DESCRIPT="IF_IXML_ELEMENT" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="3" TYPE="IF_IXML_ELEMENT"/>
@ -2710,11 +2605,6 @@ DATA: lv_filename TYPE string.
path2 = path.
zcl_excel_common=&gt;split_file( EXPORTING ip_file = path2
IMPORTING ep_extension = file_ext2 ).
* CALL FUNCTION &apos;CV120_SPLIT_FILE&apos;
* EXPORTING
* pf_file = path2
* IMPORTING
* pfx_extension = file_ext2.
rel_drawing-file_ext = file_ext2.
&quot;-------------Added by Alessandro Iannacci - Should load graph xml
@ -2766,6 +2656,109 @@ DATA: lv_filename TYPE string.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_READER_2007" CMPNAME="READ_FROM_APPLSERVER" VERSION="1" LANGU="E" DESCRIPT="Load excel data from appserver" EXPOSURE="0" STATE="1" EDITORDER="16 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="0" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_READER_2007" CMPNAME="READ_FROM_APPLSERVER" SCONAME="I_FILENAME" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CSEQUENCE"/>
<parameter CLSNAME="ZCL_EXCEL_READER_2007" CMPNAME="READ_FROM_APPLSERVER" SCONAME="R_EXCEL_DATA" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="XSTRING"/>
<source>METHOD read_from_applserver.
DATA: lv_filelength TYPE i,
lt_binary_data TYPE STANDARD TABLE OF x255 WITH NON-UNIQUE DEFAULT KEY,
ls_binary_data LIKE LINE OF lt_binary_data,
lv_filename TYPE string,
lv_max_length_line TYPE i,
lv_actual_length_line TYPE i,
lv_errormessage TYPE string.
MOVE i_filename TO lv_filename.
DESCRIBE FIELD ls_binary_data LENGTH lv_max_length_line IN BYTE MODE.
OPEN DATASET lv_filename FOR INPUT IN BINARY MODE.
IF sy-subrc &lt;&gt; 0.
lv_errormessage = &apos;A problem occured when reading the file&apos;(001).
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
WHILE sy-subrc = 0.
READ DATASET lv_filename INTO ls_binary_data MAXIMUM LENGTH lv_max_length_line ACTUAL LENGTH lv_actual_length_line.
APPEND ls_binary_data TO lt_binary_data.
lv_filelength = lv_filelength + lv_actual_length_line.
ENDWHILE.
CLOSE DATASET lv_filename.
*--------------------------------------------------------------------*
* Binary data needs to be provided as XSTRING for further processing
*--------------------------------------------------------------------*
CALL FUNCTION &apos;SCMS_BINARY_TO_XSTRING&apos;
EXPORTING
input_length = lv_filelength
IMPORTING
buffer = r_excel_data
TABLES
binary_tab = lt_binary_data.
ENDMETHOD.</source>
</method>
<method CLSNAME="ZCL_EXCEL_READER_2007" CMPNAME="READ_FROM_LOCAL_FILE" VERSION="1" LANGU="E" DESCRIPT="Load excel data from local file" EXPOSURE="0" STATE="1" EDITORDER="17 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="0" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_READER_2007" CMPNAME="READ_FROM_LOCAL_FILE" SCONAME="I_FILENAME" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CSEQUENCE"/>
<parameter CLSNAME="ZCL_EXCEL_READER_2007" CMPNAME="READ_FROM_LOCAL_FILE" SCONAME="R_EXCEL_DATA" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="XSTRING"/>
<source>METHOD read_from_local_file.
DATA: lv_filelength TYPE i,
lt_binary_data TYPE STANDARD TABLE OF x255 WITH NON-UNIQUE DEFAULT KEY,
ls_binary_data LIKE LINE OF lt_binary_data,
lv_filename TYPE string,
lv_errormessage TYPE string.
MOVE i_filename TO lv_filename.
cl_gui_frontend_services=&gt;gui_upload( EXPORTING
filename = lv_filename
filetype = &apos;BIN&apos; &quot; We are basically working with zipped directories --&gt; force binary read
IMPORTING
filelength = lv_filelength
CHANGING
data_tab = lt_binary_data
EXCEPTIONS
file_open_error = 1
file_read_error = 2
no_batch = 3
gui_refuse_filetransfer = 4
invalid_type = 5
no_authority = 6
unknown_error = 7
bad_data_format = 8
header_not_allowed = 9
separator_not_allowed = 10
header_too_long = 11
unknown_dp_error = 12
access_denied = 13
dp_out_of_memory = 14
disk_full = 15
dp_timeout = 16
not_supported_by_gui = 17
error_no_gui = 18
OTHERS = 19 ).
IF sy-subrc &lt;&gt; 0.
lv_errormessage = &apos;A problem occured when reading the file&apos;(001).
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
*--------------------------------------------------------------------*
* Binary data needs to be provided as XSTRING for further processing
*--------------------------------------------------------------------*
CALL FUNCTION &apos;SCMS_BINARY_TO_XSTRING&apos;
EXPORTING
input_length = lv_filelength
IMPORTING
buffer = r_excel_data
TABLES
binary_tab = lt_binary_data.
ENDMETHOD.</source>
</method>
<method CLSNAME="ZCL_EXCEL_READER_2007" CMPNAME="RESOLVE_PATH" VERSION="1" LANGU="E" DESCRIPT="Return path after ../ values are removed" EXPOSURE="1" STATE="1" EDITORDER="1 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_READER_2007" CMPNAME="RESOLVE_PATH" SCONAME="IP_PATH" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="STRING"/>
<parameter CLSNAME="ZCL_EXCEL_READER_2007" CMPNAME="RESOLVE_PATH" SCONAME="RP_RESULT" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="STRING"/>