All files / src/git zcl_abapgit_git_delta.clas.abap

92.2% Statements 142/154
63.63% Branches 7/11
100% Functions 3/3
92.2% Lines 142/154

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 1551x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 3x 3x 1x 1x 1x       1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x   1x       1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x           1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
CLASS zcl_abapgit_git_delta DEFINITION PUBLIC.
  PUBLIC SECTION.
 
    CLASS-METHODS decode_deltas
      IMPORTING
        iv_show_progress TYPE abap_bool DEFAULT abap_true
      CHANGING
        !ct_objects      TYPE zif_abapgit_definitions=>ty_objects_tt
      RAISING
        zcx_abapgit_exception .
 
  PRIVATE SECTION.
    CLASS-METHODS delta
      IMPORTING
        !is_object  TYPE zif_abapgit_definitions=>ty_object
      CHANGING
        !ct_objects TYPE zif_abapgit_definitions=>ty_objects_tt
      RAISING
        zcx_abapgit_exception .
 
    CLASS-METHODS delta_header
      IMPORTING
        !io_stream TYPE REF TO lcl_stream.
 
ENDCLASS.
 
CLASS zcl_abapgit_git_delta IMPLEMENTATION.
 
  METHOD decode_deltas.
 
    DATA: ls_object   LIKE LINE OF ct_objects,
          li_progress TYPE REF TO zif_abapgit_progress,
          lt_deltas   LIKE ct_objects.
 
 
    LOOP AT ct_objects INTO ls_object
        USING KEY type
        WHERE type = zif_abapgit_git_definitions=>c_type-ref_d.
      INSERT ls_object INTO TABLE lt_deltas.
    ENDLOOP.
 
    DELETE ct_objects
      USING KEY type
      WHERE type = zif_abapgit_git_definitions=>c_type-ref_d.
 
    "Restore correct Delta Order
    SORT lt_deltas BY index.
 
    IF iv_show_progress = abap_true.
      li_progress = zcl_abapgit_progress=>get_instance( lines( lt_deltas ) ).
    ENDIF.
 
    LOOP AT lt_deltas INTO ls_object.
      IF li_progress IS NOT INITIAL.
        li_progress->show( iv_current = sy-tabix
                           iv_text    = 'Decode deltas' ).
      ENDIF.
 
      delta( EXPORTING is_object = ls_object
             CHANGING ct_objects = ct_objects ).
    ENDLOOP.
 
  ENDMETHOD.
 
  METHOD delta.
 
    CONSTANTS lc_128 TYPE x VALUE '80'.
 
    DATA: lv_base   TYPE xstring,
          lv_result TYPE xstring,
          lv_offset TYPE i,
          lo_stream TYPE REF TO lcl_stream,
          lv_sha1   TYPE zif_abapgit_git_definitions=>ty_sha1,
          ls_object LIKE LINE OF ct_objects,
          lv_len    TYPE i,
          lv_tmp    TYPE xstring,
          lv_org    TYPE x.
 
    FIELD-SYMBOLS: <ls_object> LIKE LINE OF ct_objects.
 
 
    CREATE OBJECT lo_stream
      EXPORTING
        iv_data = is_object-data.
 
* find base
    READ TABLE ct_objects ASSIGNING <ls_object>
      WITH KEY sha COMPONENTS sha1 = is_object-sha1.
    IF sy-subrc <> 0.
      zcx_abapgit_exception=>raise( |Base not found, { is_object-sha1 }| ).
    ELSEIF <ls_object>-type = zif_abapgit_git_definitions=>c_type-ref_d.
* sanity check
      zcx_abapgit_exception=>raise( |Delta, base eq delta| ).
    ENDIF.
 
    lv_base = <ls_object>-data.
 
* skip the 2 headers
    delta_header( lo_stream ).
    delta_header( lo_stream ).
 
    WHILE lo_stream->has_data( ) = abap_true.
 
      lv_org = lo_stream->eat_byte( ).
 
      IF lv_org BIT-AND lc_128 = lc_128. " MSB = 1
* copy from base
        lo_stream->eat_offset_and_length(
          EXPORTING
            iv_instruction = lv_org
          IMPORTING
            ev_offset      = lv_offset
            ev_length      = lv_len ).
 
        CONCATENATE lv_result lv_base+lv_offset(lv_len) INTO lv_result IN BYTE MODE.
      ELSE. " lv_bitbyte(1) = '0'
* insert from delta
        lv_len = lv_org. " convert to int
        lv_tmp = lo_stream->eat_bytes( lv_len ).
        CONCATENATE lv_result lv_tmp INTO lv_result IN BYTE MODE.
      ENDIF.
 
    ENDWHILE.
 
    lv_sha1 = zcl_abapgit_hash=>sha1( iv_type = <ls_object>-type
                                      iv_data = lv_result ).
 
    CLEAR ls_object.
    ls_object-sha1 = lv_sha1.
    ls_object-type = <ls_object>-type.
    ls_object-data = lv_result.
    ls_object-index = <ls_object>-index. "Retain sort index
    APPEND ls_object TO ct_objects.
 
  ENDMETHOD.
 
 
  METHOD delta_header.
 
    DATA lv_x   TYPE x.
    DATA lv_bit TYPE c LENGTH 1.
 
* header is skipped for performance reasons
    DO.
      lv_x = io_stream->eat_byte( ).
      GET BIT 1 OF lv_x INTO lv_bit.
      IF lv_bit = '0'.
        EXIT. " current loop
      ENDIF.
    ENDDO.
 
  ENDMETHOD.
 
ENDCLASS.