Advertisement
Guest User

Untitled

a guest
Sep 17th, 2019
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.22 KB | None | 0 0
  1. METHOD json_to_data.
  2. DATA: lv_off TYPE i.
  3. DATA: lv_len TYPE i.
  4. DATA: lv_key TYPE string.
  5. DATA: lv_value TYPE string.
  6. DATA: lv_char TYPE char1. "Current chacater
  7. DATA: lv_pchar TYPE char1. "Previous character
  8. DATA: lv_instr TYPE boole_d. "Indicator: cursor in string
  9. DATA: lv_level TYPE i. "Depth inside a block
  10. DATA: lv_table TYPE boole_d.
  11. FIELD-SYMBOLS: <fk> TYPE string.
  12. FIELD-SYMBOLS: <data> TYPE ANY.
  13. FIELD-SYMBOLS: <table> TYPE ANY TABLE.
  14. FIELD-SYMBOLS: <sotab> TYPE SORTED TABLE.
  15. FIELD-SYMBOLS: <sttab> TYPE STANDARD TABLE.
  16. FIELD-SYMBOLS: <line> TYPE ANY.
  17. DATA: ls_line TYPE REF TO data.
  18. DATA: lr_td TYPE REF TO cl_abap_typedescr.
  19. DATA: lr_ttd TYPE REF TO cl_abap_tabledescr.
  20.  
  21.  
  22.  
  23.  
  24. * If the incoming json contains no '{}[]', we are dealing with
  25. * a basic (scalar) value that is simply assigned to the data
  26. * and then we return
  27. IF json NA '{}[]'.
  28. * Replace escape characters (TODO: Check if there are more!)
  29. lv_value = json.
  30. REPLACE ALL OCCURRENCES OF '\n' IN lv_value WITH cl_abap_char_utilities=>newline.
  31. REPLACE ALL OCCURRENCES OF '\t' IN lv_value WITH cl_abap_char_utilities=>horizontal_tab.
  32. REPLACE ALL OCCURRENCES OF '\f' IN lv_value WITH cl_abap_char_utilities=>form_feed.
  33. REPLACE ALL OCCURRENCES OF '\v' IN lv_value WITH cl_abap_char_utilities=>vertical_tab.
  34. REPLACE ALL OCCURRENCES OF '\b' IN lv_value WITH cl_abap_char_utilities=>backspace.
  35. REPLACE ALL OCCURRENCES OF '\\' IN lv_value WITH '\'.
  36. * TODO: Deal with specific data types, e.g. dates etc.
  37. data = lv_value.
  38. EXIT.
  39. ENDIF.
  40.  
  41. lv_len = STRLEN( json ).
  42.  
  43. * Check if we are dealing with a table
  44. lr_td = cl_abap_typedescr=>describe_by_data( data ).
  45. IF lr_td->type_kind = cl_abap_typedescr=>typekind_table.
  46. * This information is used later...
  47. lv_table = 'X'.
  48. ASSIGN data TO <table>.
  49. CREATE DATA ls_line LIKE LINE OF <table>.
  50. ASSIGN ls_line->* TO <line>.
  51. ELSE.
  52. lv_table = ' '.
  53. ENDIF.
  54.  
  55. * Reset counters/flags
  56. lv_off = 0.
  57. lv_instr = ' '.
  58. lv_level = 0.
  59. ASSIGN lv_key TO <fk>.
  60.  
  61. WHILE lv_off < lv_len.
  62. lv_char = json+lv_off(1).
  63.  
  64. **********************************************************************
  65. * IN STRING
  66. **********************************************************************
  67. * Character is in a string delimited by double quotes
  68. IF lv_instr = 'X'.
  69. IF lv_char = '"'.
  70. * Switch out of delimited character string
  71. IF lv_pchar NE '\'.
  72. lv_instr = ' '.
  73. ELSE.
  74. CONCATENATE <fk> lv_char INTO <fk> RESPECTING BLANKS.
  75. ENDIF.
  76. ELSE.
  77. CONCATENATE <fk> lv_char INTO <fk> RESPECTING BLANKS.
  78. ENDIF.
  79.  
  80. **********************************************************************
  81. * OUTSIDE STRING
  82. **********************************************************************
  83. * Character is not in a string delimited by double quotes
  84. ELSE.
  85.  
  86. * On opening character, shift level up
  87. IF lv_char CA '{['.
  88. ADD 1 TO lv_level.
  89. ENDIF.
  90.  
  91. * When the value is contained in a {}/[], the entire value must
  92. * be passed to the next level of processing
  93. IF lv_level > 1.
  94. CONCATENATE <fk> lv_char INTO <fk> RESPECTING BLANKS.
  95. ELSE.
  96. IF lv_char CA '[{'. "<- Chars ignored outside of str
  97. ELSEIF lv_char = ':'.
  98. ASSIGN lv_value TO <fk>.
  99. * The key collected up to now is assigned to the data member
  100. TRANSLATE lv_key TO UPPER CASE.
  101. SHIFT lv_key LEFT DELETING LEADING space.
  102. ASSIGN COMPONENT lv_key OF STRUCTURE data TO <data>.
  103.  
  104. * End of a key/value pair (we bump up against delimiter) - pass to next level
  105. ELSEIF ( lv_char = ',' OR lv_char = '}' ) AND lv_table = space.
  106.  
  107. * Process collected value
  108. ****************************** Inizio modifica [ES] 14/04/2016 Se viene letto un campo non contentuto nella struttura, esco dal metodo.
  109. IF <data> IS NOT ASSIGNED.
  110. RETURN.
  111. ENDIF.
  112. ************************** Fine modifica [ES]
  113. json_to_data( EXPORTING json = lv_value CHANGING data = <data> ).
  114.  
  115.  
  116. * Clear key and value
  117. CLEAR: lv_key, lv_value.
  118.  
  119. ASSIGN lv_key TO <fk>.
  120.  
  121. CLEAR: lv_key, lv_value.
  122.  
  123. * End of a key/value pair (we bump up against delimiter) - pass to next level
  124. * But in table mode, we pass an instance of a row of the table, and afterward
  125. * add it to the table
  126. ELSEIF ( lv_char = ',' OR lv_char = ']' ) AND lv_table = 'X'.
  127.  
  128. * Process collected value
  129. * Inside array in JSON, there are no keys, only list of values, the collected
  130. * value is in lv_key
  131. SHIFT lv_key LEFT DELETING LEADING space.
  132. json_to_data( EXPORTING json = lv_key CHANGING data = <line> ).
  133.  
  134. * On return: if dealing with table, add the record to the table
  135. lr_ttd ?= lr_td.
  136. IF lr_ttd->table_kind = cl_abap_tabledescr=>tablekind_sorted
  137. OR lr_ttd->table_kind = cl_abap_tabledescr=>tablekind_hashed.
  138. ASSIGN data TO <sotab>.
  139. INSERT <line> INTO TABLE <sotab>.
  140. ELSE.
  141. ASSIGN data TO <sttab>.
  142. APPEND <line> TO <sttab>.
  143. ENDIF.
  144. CLEAR <line>.
  145.  
  146. * Clear key and value
  147. CLEAR: lv_key, lv_value.
  148.  
  149. ASSIGN lv_key TO <fk>.
  150.  
  151. CLEAR: lv_key, lv_value.
  152.  
  153. * Switch cursor into delimited string; consecutive characters
  154. * are then treated as part of a key or value, even if they are
  155. * special characters
  156. ELSEIF lv_char = '"'.
  157. lv_instr = 'X'.
  158.  
  159. * Other chars processed as either key or value
  160. ELSE.
  161. CONCATENATE <fk> lv_char INTO <fk> RESPECTING BLANKS.
  162. ENDIF.
  163.  
  164. ENDIF.
  165.  
  166. * On closing character, shift level down again
  167. IF lv_char CA '}]'.
  168. SUBTRACT 1 FROM lv_level.
  169. ENDIF.
  170.  
  171. * END: Are we in string or out?
  172. ENDIF.
  173.  
  174. lv_pchar = lv_char.
  175. ADD 1 TO lv_off.
  176. ENDWHILE.
  177.  
  178.  
  179.  
  180. ENDMETHOD.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement