diff --git a/package.json b/package.json index 8811523c1..2296909d3 100644 --- a/package.json +++ b/package.json @@ -23,14 +23,14 @@ ] }, "devDependencies": { - "@abaplint/cli": "^2.113.31", + "@abaplint/cli": "^2.113.82", "@abaplint/database-sqlite": "^2.10.20", - "@abaplint/runtime": "^2.10.20", - "express": "^4.21.1", - "@abaplint/transpiler-cli": "^2.10.20", - "globals": "^15.11.0", + "@abaplint/runtime": "^2.10.23", + "express": "^4.21.2", + "@abaplint/transpiler-cli": "^2.10.23", + "globals": "^15.13.0", "abapmerge": "^0.16.6", - "c8": "^10.1.2", - "eslint": "^9.13.0" + "c8": "^10.1.3", + "eslint": "^9.17.0" } } diff --git a/src/env/zcl_abapgit_abap_language_vers.clas.testclasses.abap b/src/env/zcl_abapgit_abap_language_vers.clas.testclasses.abap index c7edd9ac9..7a23bdc35 100644 --- a/src/env/zcl_abapgit_abap_language_vers.clas.testclasses.abap +++ b/src/env/zcl_abapgit_abap_language_vers.clas.testclasses.abap @@ -26,6 +26,8 @@ CLASS lcl_environment IMPLEMENTATION. ENDMETHOD. METHOD zif_abapgit_environment~get_basis_release. ENDMETHOD. + METHOD zif_abapgit_environment~get_available_user_sessions. + ENDMETHOD. METHOD zif_abapgit_environment~get_system_language_filter. ENDMETHOD. METHOD zif_abapgit_environment~is_merged. diff --git a/src/env/zcl_abapgit_environment.clas.abap b/src/env/zcl_abapgit_environment.clas.abap index 5e6922a38..a57f91dab 100644 --- a/src/env/zcl_abapgit_environment.clas.abap +++ b/src/env/zcl_abapgit_environment.clas.abap @@ -81,6 +81,26 @@ CLASS zcl_abapgit_environment IMPLEMENTATION. ENDMETHOD. + METHOD zif_abapgit_environment~get_available_user_sessions. + + DATA: + lv_act_sessions TYPE i, + lv_max_sessions TYPE i, + lv_subrc TYPE sy-subrc. + + CALL FUNCTION 'TH_USER_INFO' + IMPORTING + act_sessions = lv_act_sessions + max_sessions = lv_max_sessions + rc = lv_subrc. + + IF lv_subrc = 0. + rv_sessions = lv_max_sessions - lv_act_sessions. + ENDIF. + + ENDMETHOD. + + METHOD zif_abapgit_environment~get_basis_release. SELECT SINGLE release extrelease FROM cvers INTO (rs_result-release, rs_result-sp) @@ -89,6 +109,78 @@ CLASS zcl_abapgit_environment IMPLEMENTATION. ENDMETHOD. + METHOD zif_abapgit_environment~get_system_language_filter. + DATA lv_translation_detective_lang TYPE spras. + DATA lv_pseudo_translation_language TYPE spras. + FIELD-SYMBOLS LIKE LINE OF rt_system_language_filter. + + " Translation Object Detective + " https://help.sap.com/docs/ABAP_PLATFORM_NEW/ceb25152cb0d4adba664cebea2bf4670/88a3d3cbccf64601975acabaccdfde45.html + CALL FUNCTION 'CONVERSION_EXIT_ISOLA_INPUT' + EXPORTING + input = '1Q' + IMPORTING + output = lv_translation_detective_lang + EXCEPTIONS + unknown_language = 1 + OTHERS = 2. + IF sy-subrc = 1. + " The language for Translation Object Detective was not setup + ENDIF. + IF NOT lv_translation_detective_lang IS INITIAL. + APPEND INITIAL LINE TO rt_system_language_filter ASSIGNING . + -sign = 'E'. + -option = 'EQ'. + -low = lv_translation_detective_lang. + ENDIF. + " 1943470 - Using technical language key 2Q to create pseudo-translations of ABAP developments + " https://launchpad.support.sap.com/#/notes/1943470 + CALL FUNCTION 'CONVERSION_EXIT_ISOLA_INPUT' + EXPORTING + input = '2Q' + IMPORTING + output = lv_pseudo_translation_language + EXCEPTIONS + unknown_language = 1 + OTHERS = 2. + IF sy-subrc = 1. + " The language for Pseudo Translation was not setup + ENDIF. + IF NOT lv_pseudo_translation_language IS INITIAL. + APPEND INITIAL LINE TO rt_system_language_filter ASSIGNING . + -sign = 'E'. + -option = 'EQ'. + -low = lv_pseudo_translation_language. + ENDIF. + ENDMETHOD. + + + METHOD zif_abapgit_environment~init_parallel_processing. + + DATA: lv_group TYPE rzlli_apcl. + + lv_group = iv_group. + + " SPBT_INITIALIZE gives error PBT_ENV_ALREADY_INITIALIZED if called + " multiple times in same session + CALL FUNCTION 'SPBT_INITIALIZE' + EXPORTING + group_name = lv_group + IMPORTING + free_pbt_wps = rv_free_work_processes + EXCEPTIONS + invalid_group_name = 1 + internal_error = 2 + pbt_env_already_initialized = 3 + currently_no_resources_avail = 4 + no_pbt_resources_found = 5 + cant_init_different_pbt_groups = 6 + OTHERS = 7 ##FM_SUBRC_OK. + " If SPBT_INITIALIZE fails, check transactions RZ12, SM50, SM21, SARFC + + ENDMETHOD. + + METHOD zif_abapgit_environment~is_merged. DATA lr_marker TYPE REF TO data ##NEEDED. @@ -155,50 +247,6 @@ CLASS zcl_abapgit_environment IMPLEMENTATION. ENDMETHOD. - METHOD zif_abapgit_environment~get_system_language_filter. - DATA lv_translation_detective_lang TYPE spras. - DATA lv_pseudo_translation_language TYPE spras. - FIELD-SYMBOLS LIKE LINE OF rt_system_language_filter. - - " Translation Object Detective - " https://help.sap.com/docs/ABAP_PLATFORM_NEW/ceb25152cb0d4adba664cebea2bf4670/88a3d3cbccf64601975acabaccdfde45.html - CALL FUNCTION 'CONVERSION_EXIT_ISOLA_INPUT' - EXPORTING - input = '1Q' - IMPORTING - output = lv_translation_detective_lang - EXCEPTIONS - unknown_language = 1 - OTHERS = 2. - IF sy-subrc = 1. - " The language for Translation Object Detective was not setup - ENDIF. - IF NOT lv_translation_detective_lang IS INITIAL. - APPEND INITIAL LINE TO rt_system_language_filter ASSIGNING . - -sign = 'E'. - -option = 'EQ'. - -low = lv_translation_detective_lang. - ENDIF. - " 1943470 - Using technical language key 2Q to create pseudo-translations of ABAP developments - " https://launchpad.support.sap.com/#/notes/1943470 - CALL FUNCTION 'CONVERSION_EXIT_ISOLA_INPUT' - EXPORTING - input = '2Q' - IMPORTING - output = lv_pseudo_translation_language - EXCEPTIONS - unknown_language = 1 - OTHERS = 2. - IF sy-subrc = 1. - " The language for Pseudo Translation was not setup - ENDIF. - IF NOT lv_pseudo_translation_language IS INITIAL. - APPEND INITIAL LINE TO rt_system_language_filter ASSIGNING . - -sign = 'E'. - -option = 'EQ'. - -low = lv_pseudo_translation_language. - ENDIF. - ENDMETHOD. METHOD zif_abapgit_environment~is_variant_maintenance. @@ -212,30 +260,4 @@ CLASS zcl_abapgit_environment IMPLEMENTATION. rv_is_variant_maintenance = boolc( lines( lt_variscreens ) > 0 ). ENDMETHOD. - - METHOD zif_abapgit_environment~init_parallel_processing. - - DATA: lv_group TYPE rzlli_apcl. - - lv_group = iv_group. - - " SPBT_INITIALIZE gives error PBT_ENV_ALREADY_INITIALIZED if called - " multiple times in same session - CALL FUNCTION 'SPBT_INITIALIZE' - EXPORTING - group_name = lv_group - IMPORTING - free_pbt_wps = rv_free_work_processes - EXCEPTIONS - invalid_group_name = 1 - internal_error = 2 - pbt_env_already_initialized = 3 - currently_no_resources_avail = 4 - no_pbt_resources_found = 5 - cant_init_different_pbt_groups = 6 - OTHERS = 7 ##FM_SUBRC_OK. - " If SPBT_INITIALIZE fails, check transactions RZ12, SM50, SM21, SARFC - - ENDMETHOD. - ENDCLASS. diff --git a/src/env/zif_abapgit_environment.intf.abap b/src/env/zif_abapgit_environment.intf.abap index 6fcaa06fb..5aee0824c 100644 --- a/src/env/zif_abapgit_environment.intf.abap +++ b/src/env/zif_abapgit_environment.intf.abap @@ -39,5 +39,8 @@ INTERFACE zif_abapgit_environment iv_group TYPE clike RETURNING VALUE(rv_free_work_processes) TYPE i. + METHODS get_available_user_sessions + RETURNING + VALUE(rv_sessions) TYPE i. ENDINTERFACE. diff --git a/src/objects/core/zcl_abapgit_serialize.clas.abap b/src/objects/core/zcl_abapgit_serialize.clas.abap index fc4ad0c95..b9254c39e 100644 --- a/src/objects/core/zcl_abapgit_serialize.clas.abap +++ b/src/objects/core/zcl_abapgit_serialize.clas.abap @@ -280,6 +280,7 @@ CLASS zcl_abapgit_serialize IMPLEMENTATION. METHOD determine_max_processes. DATA: li_exit TYPE REF TO zif_abapgit_exit. + DATA lv_available_sessions TYPE i. IF iv_force_sequential = abap_true. rv_processes = 1. @@ -319,6 +320,17 @@ CLASS zcl_abapgit_serialize IMPLEMENTATION. ASSERT rv_processes >= 1. " check exit above + " Avoid going over the maximum available user sessions + IF sy-batch IS INITIAL. + lv_available_sessions = zcl_abapgit_factory=>get_environment( )->get_available_user_sessions( ). + + IF rv_processes > lv_available_sessions AND lv_available_sessions <> 0. + rv_processes = lv_available_sessions. + ENDIF. + ENDIF. + + ASSERT rv_processes >= 1. + ENDMETHOD. diff --git a/src/objects/core/zcl_abapgit_serialize.clas.testclasses.abap b/src/objects/core/zcl_abapgit_serialize.clas.testclasses.abap index a224ff5da..3eda1b89b 100644 --- a/src/objects/core/zcl_abapgit_serialize.clas.testclasses.abap +++ b/src/objects/core/zcl_abapgit_serialize.clas.testclasses.abap @@ -70,12 +70,16 @@ CLASS ltd_environment DEFINITION FINAL FOR TESTING set_is_merged IMPORTING iv_is_merged TYPE abap_bool, + set_available_sessions + IMPORTING iv_available_sessions TYPE i, + set_free_work_processes IMPORTING iv_free_work_processes TYPE i. PRIVATE SECTION. DATA: mv_is_merged TYPE abap_bool, + mv_available_sessions TYPE i, mv_free_work_processes TYPE i. ENDCLASS. @@ -89,6 +93,10 @@ CLASS ltd_environment IMPLEMENTATION. METHOD zif_abapgit_environment~get_basis_release. ENDMETHOD. + METHOD zif_abapgit_environment~get_available_user_sessions. + rv_sessions = mv_available_sessions. + ENDMETHOD. + METHOD zif_abapgit_environment~get_system_language_filter. ENDMETHOD. @@ -116,11 +124,16 @@ CLASS ltd_environment IMPLEMENTATION. ENDMETHOD. METHOD set_is_merged. - me->mv_is_merged = iv_is_merged. + mv_is_merged = iv_is_merged. ENDMETHOD. + METHOD set_available_sessions. + mv_available_sessions = iv_available_sessions. + ENDMETHOD. + + METHOD set_free_work_processes. - me->mv_free_work_processes = iv_free_work_processes. + mv_free_work_processes = iv_free_work_processes. ENDMETHOD. ENDCLASS. @@ -255,6 +268,7 @@ CLASS ltcl_determine_max_processes DEFINITION FOR TESTING DURATION SHORT RISK LE determine_max_processes_no_pp FOR TESTING RAISING zcx_abapgit_exception, determine_max_processes_merged FOR TESTING RAISING zcx_abapgit_exception, determine_max_processes_exit FOR TESTING RAISING zcx_abapgit_exception, + determine_max_processes_capped FOR TESTING RAISING zcx_abapgit_exception, force FOR TESTING RAISING zcx_abapgit_exception, teardown, @@ -267,6 +281,10 @@ CLASS ltcl_determine_max_processes DEFINITION FOR TESTING DURATION SHORT RISK LE IMPORTING iv_is_merged TYPE abap_bool, + given_available_sessions + IMPORTING + iv_available_sessions TYPE i, + given_free_work_processes IMPORTING iv_free_work_processes TYPE i, @@ -390,6 +408,19 @@ CLASS ltcl_determine_max_processes IMPLEMENTATION. ENDMETHOD. + METHOD determine_max_processes_capped. + + given_parallel_proc_disabled( abap_false ). + given_is_merged( abap_false ). + given_free_work_processes( 50 ). " big system + given_available_sessions( 10 ). " but user session is capped + + when_determine_max_processes( ). + + then_we_shd_have_n_processes( 10 ). + + ENDMETHOD. + METHOD force. @@ -413,6 +444,12 @@ CLASS ltcl_determine_max_processes IMPLEMENTATION. ENDMETHOD. + METHOD given_available_sessions. + + mo_environment_double->set_available_sessions( iv_available_sessions ). + + ENDMETHOD. + METHOD given_free_work_processes. diff --git a/src/ui/core/zcl_abapgit_html.clas.abap b/src/ui/core/zcl_abapgit_html.clas.abap index a8aaafdf7..f0936f9d6 100644 --- a/src/ui/core/zcl_abapgit_html.clas.abap +++ b/src/ui/core/zcl_abapgit_html.clas.abap @@ -48,6 +48,7 @@ CLASS zcl_abapgit_html DEFINITION within_style TYPE abap_bool, within_js TYPE abap_bool, within_textarea TYPE abap_bool, + within_pre TYPE abap_bool, indent TYPE i, indent_str TYPE string, END OF ty_indent_context . @@ -59,6 +60,8 @@ CLASS zcl_abapgit_html DEFINITION script_close TYPE abap_bool, textarea_open TYPE abap_bool, textarea_close TYPE abap_bool, + pre_open TYPE abap_bool, + pre_close TYPE abap_bool, tag_close TYPE abap_bool, curly_close TYPE abap_bool, openings TYPE i, @@ -85,7 +88,7 @@ ENDCLASS. -CLASS ZCL_ABAPGIT_HTML IMPLEMENTATION. +CLASS zcl_abapgit_html IMPLEMENTATION. METHOD checkbox. @@ -120,10 +123,6 @@ CLASS ZCL_ABAPGIT_HTML IMPLEMENTATION. ENDMETHOD. - METHOD set_debug_mode. - gv_debug_mode = iv_mode. - ENDMETHOD. - METHOD create. CREATE OBJECT ri_instance TYPE zcl_abapgit_html. IF iv_initial_chunk IS NOT INITIAL. @@ -134,11 +133,11 @@ CLASS ZCL_ABAPGIT_HTML IMPLEMENTATION. METHOD icon. - DATA: lv_hint TYPE string, - lv_name TYPE string, - lv_color TYPE string, - lv_class TYPE string, - lv_onclick TYPE string. + DATA: lv_hint TYPE string, + lv_name TYPE string, + lv_color TYPE string, + lv_class TYPE string, + lv_onclick TYPE string. SPLIT iv_name AT '/' INTO lv_name lv_color. @@ -181,6 +180,17 @@ CLASS ZCL_ABAPGIT_HTML IMPLEMENTATION. RETURN. ENDIF. + " No indent for pre tags + IF ls_study-pre_open = abap_true. + cs_context-within_pre = abap_true. + RETURN. + ELSEIF ls_study-pre_close = abap_true. + cs_context-within_pre = abap_false. + RETURN. + ELSEIF cs_context-within_pre = abap_true. + RETURN. + ENDIF. + " First closing tag - shift back exceptionally IF ( ls_study-script_close = abap_true OR ls_study-style_close = abap_true @@ -239,6 +249,11 @@ CLASS ZCL_ABAPGIT_HTML IMPLEMENTATION. ENDMETHOD. + METHOD set_debug_mode. + gv_debug_mode = iv_mode. + ENDMETHOD. + + METHOD study_line. DATA: lv_line TYPE string, @@ -309,6 +324,16 @@ CLASS ZCL_ABAPGIT_HTML IMPLEMENTATION. ENDIF. ENDIF. + " Pre (same assumptions as above) + IF is_context-within_pre = abap_true AND lv_len >= 5 AND lv_line(5) = '= 4 AND lv_line(4) = ' 0. " Not found + rs_result-pre_open = abap_true. + ENDIF. + ENDIF. + ENDMETHOD. @@ -564,10 +589,10 @@ CLASS ZCL_ABAPGIT_HTML IMPLEMENTATION. DATA lv_close_tag TYPE string. DATA ls_data_attr LIKE LINE OF it_data_attrs. - DATA: lv_class TYPE string, - lv_id TYPE string, + DATA: lv_class TYPE string, + lv_id TYPE string, lv_data_attr TYPE string, - lv_title TYPE string. + lv_title TYPE string. IF iv_id IS NOT INITIAL. lv_id = | id="{ iv_id }"|. diff --git a/src/ui/core/zcl_abapgit_html.clas.testclasses.abap b/src/ui/core/zcl_abapgit_html.clas.testclasses.abap index 1e97e3232..09f920dd3 100644 --- a/src/ui/core/zcl_abapgit_html.clas.testclasses.abap +++ b/src/ui/core/zcl_abapgit_html.clas.testclasses.abap @@ -34,6 +34,8 @@ CLASS ltcl_html DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. indent3 FOR TESTING RAISING zcx_abapgit_exception, indent4 FOR TESTING RAISING zcx_abapgit_exception, indent5 FOR TESTING RAISING zcx_abapgit_exception, + indent6 FOR TESTING RAISING zcx_abapgit_exception, + indent7 FOR TESTING RAISING zcx_abapgit_exception, style1 FOR TESTING RAISING zcx_abapgit_exception. METHODS: @@ -130,6 +132,59 @@ CLASS ltcl_html IMPLEMENTATION. ENDMETHOD. + METHOD indent6. + + " Content of textarea must not be indented + DATA lv_exp TYPE string. + + mo_html->add( '' ). + mo_html->add( '' ). + mo_html->add( '' ). + + lv_exp = '' && cl_abap_char_utilities=>newline && + '' && cl_abap_char_utilities=>newline && + ''. + + cl_abap_unit_assert=>assert_equals( + act = mo_html->render( ) + exp = lv_exp ). + + ENDMETHOD. + + METHOD indent7. + + " Content of pre tag must not be indented + DATA lv_exp TYPE string. + + mo_html->add( '' ). + mo_html->add( '
' ).
+    mo_html->add( 'Do not change' ).
+    mo_html->add( '  the indent' ).
+    mo_html->add( '    here' ).
+    mo_html->add( '
' ). + mo_html->add( '' ). + + lv_exp = '' && cl_abap_char_utilities=>newline && + '
' && cl_abap_char_utilities=>newline &&
+             'Do not change' && cl_abap_char_utilities=>newline &&
+             '  the indent' && cl_abap_char_utilities=>newline &&
+             '    here' && cl_abap_char_utilities=>newline &&
+             '
' && cl_abap_char_utilities=>newline && + ''. + + cl_abap_unit_assert=>assert_equals( + act = mo_html->render( ) + exp = lv_exp ). + + ENDMETHOD. + + METHOD style1. DATA lv_exp TYPE string. diff --git a/src/utils/zcl_abapgit_convert.clas.abap b/src/utils/zcl_abapgit_convert.clas.abap index c395457e0..f85d5f97e 100644 --- a/src/utils/zcl_abapgit_convert.clas.abap +++ b/src/utils/zcl_abapgit_convert.clas.abap @@ -85,7 +85,7 @@ CLASS zcl_abapgit_convert DEFINITION VALUE(rv_xstr) TYPE xstring . CLASS-METHODS xstring_to_bintab IMPORTING - !iv_xstr TYPE xstring + !iv_xstr TYPE xsequence EXPORTING !ev_size TYPE i !et_bintab TYPE STANDARD TABLE . @@ -144,6 +144,7 @@ ENDCLASS. CLASS zcl_abapgit_convert IMPLEMENTATION. + METHOD base64_to_xstring. rv_xstr = cl_http_utility=>decode_x_base64( iv_base64 ). @@ -207,32 +208,6 @@ CLASS zcl_abapgit_convert IMPLEMENTATION. ENDMETHOD. - METHOD language_sap1_to_bcp47. - DATA lv_converter_instance TYPE REF TO object. - DATA lv_converter_class_name TYPE string VALUE `CL_AFF_LANGUAGE_CONVERTER`. - - TRY. - CALL METHOD (lv_converter_class_name)=>create_instance - RECEIVING - result = lv_converter_instance. - - TRY. - CALL METHOD lv_converter_instance->(`IF_AFF_LANGUAGE_CONVERTER~SAP1_TO_BCP47`) - EXPORTING - language = im_lang_sap1 - RECEIVING - result = re_lang_bcp47. - CATCH cx_static_check. - RAISE no_assignment. - ENDTRY. - CATCH cx_sy_dyn_call_error. - TRY. - re_lang_bcp47 = lcl_bcp47_language_table=>sap1_to_bcp47( im_lang_sap1 ). - CATCH zcx_abapgit_exception. - RAISE no_assignment. - ENDTRY. - ENDTRY. - ENDMETHOD. METHOD language_bcp47_to_sap1. DATA lv_converter_instance TYPE REF TO object. @@ -289,6 +264,35 @@ CLASS zcl_abapgit_convert IMPLEMENTATION. ENDTRY. ENDMETHOD. + + METHOD language_sap1_to_bcp47. + DATA lv_converter_instance TYPE REF TO object. + DATA lv_converter_class_name TYPE string VALUE `CL_AFF_LANGUAGE_CONVERTER`. + + TRY. + CALL METHOD (lv_converter_class_name)=>create_instance + RECEIVING + result = lv_converter_instance. + + TRY. + CALL METHOD lv_converter_instance->(`IF_AFF_LANGUAGE_CONVERTER~SAP1_TO_BCP47`) + EXPORTING + language = im_lang_sap1 + RECEIVING + result = re_lang_bcp47. + CATCH cx_static_check. + RAISE no_assignment. + ENDTRY. + CATCH cx_sy_dyn_call_error. + TRY. + re_lang_bcp47 = lcl_bcp47_language_table=>sap1_to_bcp47( im_lang_sap1 ). + CATCH zcx_abapgit_exception. + RAISE no_assignment. + ENDTRY. + ENDTRY. + ENDMETHOD. + + METHOD language_sap1_to_sap2. TRY. @@ -381,6 +385,42 @@ CLASS zcl_abapgit_convert IMPLEMENTATION. ENDMETHOD. + METHOD uccp. + + DATA lv_class TYPE string. + DATA lv_xstr TYPE xstring. + DATA lo_instance TYPE REF TO object. + + lv_class = 'CL_ABAP_CONV_IN_CE'. + + TRY. + CALL METHOD (lv_class)=>uccp + EXPORTING + uccp = iv_uccp + RECEIVING + char = rv_char. + CATCH cx_sy_dyn_call_illegal_class. + lv_xstr = iv_uccp. + + CALL METHOD ('CL_ABAP_CONV_CODEPAGE')=>create_in + EXPORTING + codepage = 'UTF-16' + RECEIVING + instance = lo_instance. + +* convert endianness + CONCATENATE lv_xstr+1(1) lv_xstr(1) INTO lv_xstr IN BYTE MODE. + + CALL METHOD lo_instance->('IF_ABAP_CONV_IN~CONVERT') + EXPORTING + source = lv_xstr + RECEIVING + result = rv_char. + ENDTRY. + + ENDMETHOD. + + METHOD xstring_remove_bom. rv_xstr = iv_xstr. @@ -405,10 +445,13 @@ CLASS zcl_abapgit_convert IMPLEMENTATION. FIELD-SYMBOLS TYPE any. - CLEAR et_bintab. ev_size = xstrlen( iv_xstr ). + IF iv_xstr IS INITIAL. + RETURN. + ENDIF. + APPEND INITIAL LINE TO et_bintab ASSIGNING . lv_struct = boolc( cl_abap_typedescr=>describe_by_data( )->type_kind = cl_abap_typedescr=>typekind_struct1 ). @@ -418,7 +461,9 @@ CLASS zcl_abapgit_convert IMPLEMENTATION. = iv_xstr. lv_length = cl_abap_typedescr=>describe_by_data( )->length. - lv_iterations = ev_size DIV lv_length. + ASSERT lv_length > 0. + + lv_iterations = ( ev_size - 1 ) DIV lv_length. DO lv_iterations TIMES. lv_offset = sy-index * lv_length. @@ -493,39 +538,4 @@ CLASS zcl_abapgit_convert IMPLEMENTATION. GET BIT 8 OF iv_x INTO rv_bitbyte+7(1). ENDMETHOD. - - METHOD uccp. - - DATA lv_class TYPE string. - DATA lv_xstr TYPE xstring. - DATA lo_instance TYPE REF TO object. - - lv_class = 'CL_ABAP_CONV_IN_CE'. - - TRY. - CALL METHOD (lv_class)=>uccp - EXPORTING - uccp = iv_uccp - RECEIVING - char = rv_char. - CATCH cx_sy_dyn_call_illegal_class. - lv_xstr = iv_uccp. - - CALL METHOD ('CL_ABAP_CONV_CODEPAGE')=>create_in - EXPORTING - codepage = 'UTF-16' - RECEIVING - instance = lo_instance. - -* convert endianness - CONCATENATE lv_xstr+1(1) lv_xstr(1) INTO lv_xstr IN BYTE MODE. - - CALL METHOD lo_instance->('IF_ABAP_CONV_IN~CONVERT') - EXPORTING - source = lv_xstr - RECEIVING - result = rv_char. - ENDTRY. - - ENDMETHOD. ENDCLASS. diff --git a/src/utils/zcl_abapgit_convert.clas.testclasses.abap b/src/utils/zcl_abapgit_convert.clas.testclasses.abap index 2ee5633a2..5067fc5c4 100644 --- a/src/utils/zcl_abapgit_convert.clas.testclasses.abap +++ b/src/utils/zcl_abapgit_convert.clas.testclasses.abap @@ -19,6 +19,9 @@ CLASS ltcl_convert DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FIN METHODS string_to_xstring FOR TESTING RAISING zcx_abapgit_exception. METHODS xstring_to_bintab FOR TESTING. METHODS xstring_to_bintab_with_field FOR TESTING. + METHODS xstring_to_bintab_initial FOR TESTING. + METHODS xstring_to_bintab_long FOR TESTING. + METHODS xstring_to_bintab_exact FOR TESTING. ENDCLASS. @@ -74,6 +77,89 @@ CLASS ltcl_convert IMPLEMENTATION. ENDMETHOD. + METHOD xstring_to_bintab_initial. + + DATA lt_bintab TYPE TABLE OF w3mime. + DATA lv_size TYPE i. + DATA lv_xstr TYPE xstring. + + zcl_abapgit_convert=>xstring_to_bintab( + EXPORTING + iv_xstr = lv_xstr + IMPORTING + ev_size = lv_size + et_bintab = lt_bintab ). + + cl_abap_unit_assert=>assert_equals( + act = lv_size + exp = 0 ). + + cl_abap_unit_assert=>assert_equals( + act = lines( lt_bintab ) + exp = 0 ). + + ENDMETHOD. + + METHOD xstring_to_bintab_long. + + DATA lt_bintab TYPE TABLE OF w3mime. " x(255) + DATA lv_bin LIKE LINE OF lt_bintab. + DATA lv_size TYPE i. + DATA lv_xstr TYPE xstring. + + lv_xstr = repeat( + val = '1122334455' + occ = 200 ). + + zcl_abapgit_convert=>xstring_to_bintab( + EXPORTING + iv_xstr = lv_xstr + IMPORTING + ev_size = lv_size + et_bintab = lt_bintab ). + + cl_abap_unit_assert=>assert_equals( + act = lv_size + exp = 1000 ). + + cl_abap_unit_assert=>assert_equals( + act = lines( lt_bintab ) + exp = 4 ). + + READ TABLE lt_bintab INTO lv_bin INDEX 4. + + cl_abap_unit_assert=>assert_equals( + act = lv_bin-line+230(10) + exp = '11223344550000000000' ). + + ENDMETHOD. + + METHOD xstring_to_bintab_exact. + + TYPES ty_line TYPE x LENGTH 5. + DATA lv_xdata TYPE x LENGTH 10. + DATA lt_bintab TYPE TABLE OF ty_line. + DATA lv_size TYPE i. + + lv_xdata = '1122334455FFEEDDCCBB'. + + " must not dump if content fits exactly into bintab + zcl_abapgit_convert=>xstring_to_bintab( + EXPORTING + iv_xstr = lv_xdata + IMPORTING + ev_size = lv_size + et_bintab = lt_bintab ). + + cl_abap_unit_assert=>assert_equals( + act = lv_size + exp = 10 ). + + cl_abap_unit_assert=>assert_equals( + act = lines( lt_bintab ) + exp = 2 ). + + ENDMETHOD. METHOD string_to_xstring.