doc_search

in src/zgoog_cl_content_repo_gcs.clas.abap [0:0]


  METHOD doc_search.
    TYPES:
      BEGIN OF lty_off,
        pos TYPE i,
      END OF lty_off,

      ltt_off TYPE STANDARD TABLE OF lty_off.

    DATA: lo_gcs           TYPE REF TO zgoog_cl_storage_cont_repo_v1,
          lo_abap_sdk_excp TYPE REF TO /goog/cx_sdk.

    DATA: lv_p_bucket   TYPE string,
          lv_p_object   TYPE string,
          lv_ret_code   TYPE i,
          lv_err_text   TYPE string,
          lv_buffer     TYPE xstring,
          lv_msg        TYPE string,
          lv_codepage   TYPE abap_encoding,
          lv_pattern    TYPE xstring,
          lv_upper      TYPE xstring,
          lv_lower      TYPE xstring,
          lv_max_offset TYPE i,
          lv_offset     TYPE i,
          lv_pos        TYPE i,
          ls_off        TYPE lty_off,
          lt_off        TYPE ltt_off,
          lv_cnt        TYPE i,
          lv_pos1       TYPE char20.

    load_goog_repo_config( iv_crep_id ).
    IF gs_error IS NOT INITIAL.
      RETURN.
    ENDIF.

    lv_p_bucket = gs_repo_config-bucket.

    lv_p_object = iv_doc_id && '/' && iv_doc_id && '-' && iv_comp_id.

    TRY.
        CREATE OBJECT lo_gcs EXPORTING iv_key_name = gs_repo_config-keyname.

        lo_gcs->add_common_qparam( iv_name  = 'alt'
                                   iv_value = 'media' ).

        lo_gcs->get_objects( EXPORTING iv_p_bucket = lv_p_bucket
                                       iv_p_object = lv_p_object
                             IMPORTING ev_ret_code = lv_ret_code
                                       ev_err_text = lv_err_text
                                       es_raw      = lv_buffer ).

        IF lo_gcs->is_success( lv_ret_code ) <> abap_true.
          set_error( iv_code = lv_ret_code
                     iv_text = lv_err_text ).
          RETURN.
        ENDIF.

      CATCH /goog/cx_sdk INTO lo_abap_sdk_excp.
        lv_msg = lo_abap_sdk_excp->get_text( ).
        set_error( iv_code = 400
                   iv_text = lv_msg ).
        RETURN.
    ENDTRY.

    lv_codepage = find_codepage( lv_buffer ).

    IF iv_search_text IS INITIAL.
      lv_pattern = url_hex_decode_x( iv_raw_pattern ).
    ELSE.
      lv_pattern = iv_search_text.
    ENDIF.

    IF iv_case_sensitive = space.

      convert_upper_lower( EXPORTING iv_pattern  = lv_pattern
                                     iv_encoding = lv_codepage
                           IMPORTING ev_upper    = lv_upper
                                     ev_lower    = lv_lower ).

      IF     lv_pattern = lv_upper
         AND lv_pattern = lv_lower.
        iv_case_sensitive = 'X'.
      ENDIF.
    ELSE.
      lv_upper = lv_pattern.
      lv_lower = lv_pattern.
    ENDIF.

    lv_max_offset = xstrlen( lv_buffer ) - 1.

    IF iv_offset < 0 OR iv_offset > lv_max_offset.
      iv_offset = lv_max_offset.
    ENDIF.

    IF iv_to_offset < 0 OR iv_to_offset > lv_max_offset.
      iv_to_offset = lv_max_offset.
    ENDIF.

    IF iv_offset < iv_to_offset.
      lv_offset = iv_offset.
      lv_max_offset = iv_to_offset.
    ELSE.
      lv_offset = iv_to_offset.
      lv_max_offset = iv_offset.
    ENDIF.

    " Do search
    SHIFT lv_buffer LEFT BY lv_offset PLACES IN BYTE MODE.
    WHILE lv_buffer IS NOT INITIAL AND lv_offset <= lv_max_offset.
      IF iv_case_sensitive = space.
        search_binary_2( EXPORTING iv_buffer   = lv_buffer
                                   iv_pattern  = lv_lower
                                   iv_pattern2 = lv_upper
                         CHANGING  cv_pos      = lv_pos ).

      ELSE.
        search_binary( EXPORTING iv_buffer  = lv_buffer
                                 iv_pattern = lv_pattern
                       CHANGING  cv_pos     = lv_pos ).
      ENDIF.
      IF lv_pos >= 0.
        ls_off-pos = lv_offset + lv_pos.
        IF ls_off-pos >= lv_offset AND ls_off-pos <= lv_max_offset.
          APPEND ls_off TO lt_off.
        ENDIF.
        lv_pos = lv_pos + 1.
        SHIFT lv_buffer LEFT BY lv_pos PLACES IN BYTE MODE.
        lv_offset = lv_offset + lv_pos.
      ELSE.
        CLEAR lv_buffer.
      ENDIF.
    ENDWHILE.

    " Reduce hitlist according to the request

    DESCRIBE TABLE lt_off LINES lv_cnt.
    WHILE lv_cnt > iv_num_results.
      IF iv_offset < iv_to_offset.
        DELETE lt_off INDEX lv_cnt.
      ELSE.
        DELETE lt_off INDEX 1.
      ENDIF.
      lv_cnt = lv_cnt - 1.
    ENDWHILE.

    " Fill result
    CLEAR et_result[].
    LOOP AT lt_off INTO ls_off.

      lv_pos1 = ls_off-pos.
      IF iv_offset < iv_to_offset.
        APPEND lv_pos1 TO et_result.
      ELSE.
        INSERT lv_pos1 INTO et_result INDEX 1.
      ENDIF.
    ENDLOOP.