您的位置:首页 > 教育 > 锐评 > 沈阳seo博客_有哪些网站可以用_下载安装百度_网站排名优化多少钱

沈阳seo博客_有哪些网站可以用_下载安装百度_网站排名优化多少钱

2025/1/13 13:36:45 来源:https://blog.csdn.net/chbvb4302/article/details/145047130  浏览:    关键词:沈阳seo博客_有哪些网站可以用_下载安装百度_网站排名优化多少钱
沈阳seo博客_有哪些网站可以用_下载安装百度_网站排名优化多少钱

文章来自 SAP根据源码导入/ui2/cl_json类 - pikeduo - 博客园

新建一个se38程序,把源码放到里,源码如下

 
*----------------------------------------------------------------------*
*       CLASS zcl_json DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*CLASS zcl_json DEFINITION.PUBLIC SECTION.TYPE-POOLS abap .CLASS cl_abap_tstmp DEFINITION LOAD .CLASS cx_sy_conversion_error DEFINITION LOAD .TYPES:json TYPE string,BEGIN OF name_mapping,abap TYPE abap_compname,json TYPE string,END OF name_mapping,name_mappings    TYPE HASHED TABLE OF name_mapping WITH UNIQUE KEY abap,ref_tab          TYPE STANDARD TABLE OF REF TO data WITH DEFAULT KEY,bool             TYPE char1,tribool          TYPE char1,pretty_name_mode TYPE char1.CONSTANTS:BEGIN OF pretty_mode,none          TYPE char1  VALUE ``,low_case      TYPE char1  VALUE `L`,camel_case    TYPE char1  VALUE `X`,extended      TYPE char1  VALUE `Y`,user          TYPE char1  VALUE `U`,user_low_case TYPE char1  VALUE `C`,END OF  pretty_mode,BEGIN OF c_bool,true  TYPE bool  VALUE `X`,false TYPE bool  VALUE ``,END OF  c_bool,BEGIN OF c_tribool,true      TYPE tribool  VALUE c_bool-true,false     TYPE tribool  VALUE `-`,undefined TYPE tribool  VALUE ``,END OF  c_tribool,mc_key_separator TYPE string VALUE `-`,               "#EC NOTEXTversion          TYPE i VALUE 15.                     "#EC NOTEXTCLASS-DATA sv_white_space TYPE string READ-ONLY .CLASS-DATA mc_bool_types TYPE string READ-ONLY VALUE `\TYPE-POOL=ABAP\TYPE=ABAP_BOOL\TYPE=BOOLEAN\TYPE=BOOLE_D\TYPE=XFELD`. "#EC NOTEXTCLASS-DATA mc_bool_3state TYPE string READ-ONLY VALUE `\TYPE=BOOLEAN`. "#EC NOTEXTCLASS-DATA mc_json_type TYPE string READ-ONLY .CLASS-METHODS class_constructor .CLASS-METHODS string_to_xstringIMPORTINGin         TYPE stringCHANGINGVALUE(out) TYPE any .CLASS-METHODS xstring_to_stringIMPORTINGin         TYPE anyRETURNINGVALUE(out) TYPE string .CLASS-METHODS raw_to_stringIMPORTINGiv_xstring       TYPE xstringiv_encoding      TYPE abap_encoding OPTIONALRETURNINGVALUE(rv_string) TYPE string .CLASS-METHODS string_to_rawIMPORTINGiv_string         TYPE stringiv_encoding       TYPE abap_encoding OPTIONALRETURNINGVALUE(rv_xstring) TYPE xstring .CLASS-METHODS deserializeIMPORTINGjson             TYPE json OPTIONALjsonx            TYPE xstring OPTIONALpretty_name      TYPE pretty_name_mode DEFAULT pretty_mode-noneassoc_arrays     TYPE bool DEFAULT c_bool-falseassoc_arrays_opt TYPE bool DEFAULT c_bool-falsename_mappings    TYPE name_mappings OPTIONALconversion_exits TYPE bool DEFAULT c_bool-falseCHANGINGdata             TYPE data .CLASS-METHODS serializeIMPORTINGdata             TYPE datacompress         TYPE bool DEFAULT c_bool-falsename             TYPE string OPTIONALpretty_name      TYPE pretty_name_mode DEFAULT pretty_mode-nonetype_descr       TYPE REF TO cl_abap_typedescr OPTIONALassoc_arrays     TYPE bool DEFAULT c_bool-falsets_as_iso8601    TYPE bool DEFAULT c_bool-falseexpand_includes  TYPE bool DEFAULT c_bool-trueassoc_arrays_opt TYPE bool DEFAULT c_bool-falsenumc_as_string   TYPE bool DEFAULT c_bool-falsename_mappings    TYPE name_mappings OPTIONALconversion_exits TYPE bool DEFAULT c_bool-falseRETURNINGVALUE(r_json)    TYPE json .METHODS deserialize_intIMPORTINGjson  TYPE json OPTIONALjsonx TYPE xstring OPTIONALCHANGINGdata  TYPE dataRAISINGcx_sy_move_cast_error .CLASS-METHODS generateIMPORTINGjson           TYPE jsonpretty_name    TYPE pretty_name_mode DEFAULT pretty_mode-nonename_mappings  TYPE name_mappings OPTIONALRETURNINGVALUE(rr_data) TYPE REF TO data .METHODS serialize_intIMPORTINGdata          TYPE dataname          TYPE string OPTIONALtype_descr    TYPE REF TO cl_abap_typedescr OPTIONALRETURNINGVALUE(r_json) TYPE json .METHODS generate_intIMPORTINGjson           TYPE jsonVALUE(length)  TYPE i OPTIONALRETURNINGVALUE(rr_data) TYPE REF TO dataRAISINGcx_sy_move_cast_error .METHODS constructorIMPORTINGcompress         TYPE bool DEFAULT c_bool-falsepretty_name      TYPE pretty_name_mode DEFAULT pretty_mode-noneassoc_arrays     TYPE bool DEFAULT c_bool-falsets_as_iso8601    TYPE bool DEFAULT c_bool-falseexpand_includes  TYPE bool DEFAULT c_bool-trueassoc_arrays_opt TYPE bool DEFAULT c_bool-falsestrict_mode      TYPE bool DEFAULT c_bool-falsenumc_as_string   TYPE bool DEFAULT c_bool-falsename_mappings    TYPE name_mappings OPTIONALconversion_exits TYPE bool DEFAULT c_bool-false .CLASS-METHODS bool_to_triboolIMPORTINGiv_bool           TYPE boolRETURNINGVALUE(rv_tribool) TYPE tribool .CLASS-METHODS tribool_to_boolIMPORTINGiv_tribool     TYPE triboolRETURNINGVALUE(rv_bool) TYPE bool .PROTECTED SECTION.TYPES:BEGIN OF t_s_symbol,header       TYPE string,name         TYPE string,type         TYPE REF TO cl_abap_datadescr,value        TYPE REF TO data,convexit_out TYPE string,convexit_in  TYPE string,compressable TYPE abap_bool,read_only    TYPE abap_bool,END OF t_s_symbol,t_t_symbol TYPE STANDARD TABLE OF t_s_symbol WITH DEFAULT KEY,BEGIN OF t_s_field_cache,name         TYPE string,type         TYPE REF TO cl_abap_datadescr,convexit_out TYPE string,convexit_in  TYPE string,value        TYPE REF TO data,END OF t_s_field_cache,t_t_field_cache  TYPE HASHED TABLE OF t_s_field_cache WITH UNIQUE KEY name,name_mappings_ex TYPE HASHED TABLE OF name_mapping WITH UNIQUE KEY json.DATA mv_compress TYPE bool .DATA mv_pretty_name TYPE pretty_name_mode .DATA mv_assoc_arrays TYPE bool .DATA mv_ts_as_iso8601 TYPE bool .DATA mt_name_mappings TYPE name_mappings .DATA mt_name_mappings_ex TYPE name_mappings_ex .DATA mv_expand_includes TYPE bool .DATA mv_assoc_arrays_opt TYPE bool .DATA mv_strict_mode TYPE bool .DATA mv_numc_as_string TYPE bool .DATA mv_conversion_exits TYPE bool .CLASS-DATA mc_name_symbols_map TYPE string VALUE ` _/_\_:_;_~_._,_-_+_=_>_<_|_(_)_[_]_{_}_@_+_*_?_!_&_$_#_%_^_'_§_` ##NO_TEXT.CLASS-METHODS unescapeIMPORTINGescaped          TYPE stringRETURNINGVALUE(unescaped) TYPE string .CLASS-METHODS get_convexit_funcIMPORTINGelem_descr     TYPE REF TO cl_abap_elemdescrinput          TYPE abap_bool OPTIONALRETURNINGVALUE(rv_func) TYPE string .METHODS dump_symbols FINALIMPORTINGit_symbols    TYPE t_t_symbolRETURNINGVALUE(r_json) TYPE json .METHODS get_symbols FINALIMPORTINGtype_descr      TYPE REF TO cl_abap_typedescrdata            TYPE REF TO data OPTIONALobject          TYPE REF TO object OPTIONALinclude_aliases TYPE abap_bool DEFAULT abap_falseRETURNINGVALUE(result)   TYPE t_t_symbol .METHODS get_fields FINALIMPORTINGtype_descr       TYPE REF TO cl_abap_typedescrdata             TYPE REF TO data OPTIONALobject           TYPE REF TO object OPTIONALRETURNINGVALUE(rt_fields) TYPE t_t_field_cache .METHODS dump_intIMPORTINGdata          TYPE datatype_descr    TYPE REF TO cl_abap_typedescr OPTIONALconvexit      TYPE string OPTIONALRETURNINGVALUE(r_json) TYPE json .METHODS is_compressableIMPORTINGtype_descr         TYPE REF TO cl_abap_typedescrname               TYPE csequenceRETURNINGVALUE(rv_compress) TYPE abap_bool .METHODS restoreIMPORTINGjson              TYPE jsonlength            TYPE iVALUE(type_descr) TYPE REF TO cl_abap_typedescr OPTIONALfield_cache       TYPE t_t_field_cache OPTIONALCHANGINGdata              TYPE data OPTIONALoffset            TYPE i DEFAULT 0RAISINGcx_sy_move_cast_error .METHODS restore_typeIMPORTINGjson              TYPE jsonlength            TYPE iVALUE(type_descr) TYPE REF TO cl_abap_typedescr OPTIONALfield_cache       TYPE t_t_field_cache OPTIONALconvexit          TYPE string OPTIONALCHANGINGdata              TYPE data OPTIONALoffset            TYPE i DEFAULT 0RAISINGcx_sy_move_cast_error .METHODS dump_typeIMPORTINGdata          TYPE datatype_descr    TYPE REF TO cl_abap_elemdescrconvexit      TYPE stringRETURNINGVALUE(r_json) TYPE json .METHODS pretty_name_exIMPORTINGin         TYPE csequenceRETURNINGVALUE(out) TYPE string .METHODS generate_int_ex FINALIMPORTINGjson   TYPE jsonlength TYPE iCHANGINGdata   TYPE dataoffset TYPE i .METHODS pretty_nameIMPORTINGin         TYPE csequenceRETURNINGVALUE(out) TYPE string .CLASS-METHODS escapeIMPORTINGin         TYPE anyRETURNINGVALUE(out) TYPE string .CLASS-METHODS edm_datetime_to_tsIMPORTINGticks         TYPE stringoffset        TYPE string OPTIONALtypekind      TYPE abap_typekindRETURNINGVALUE(r_data) TYPE string .PRIVATE SECTION.DATA mv_extended TYPE bool .CLASS-DATA mc_me_type TYPE string .CLASS-DATA mc_cov_error TYPE c .ENDCLASS.*----------------------------------------------------------------------*
*       CLASS zcl_json MACROS
*----------------------------------------------------------------------*DEFINE escape_json_inplace.
*  replace all occurrences of regex `[\\"]` in &1 with `\\$0`. <-- this is slower than 2 plain replacesREPLACE ALL OCCURRENCES OF `\` IN &1 WITH `\\`.REPLACE ALL OCCURRENCES OF `"` IN &1 WITH `\"`.
END-OF-DEFINITION.
DEFINE escape_json.&2 = &1.escape_json_inplace &2.
END-OF-DEFINITION.
DEFINE is_compressable.IF mv_extended IS INITIAL.&3 = abap_true.ELSE.&3 = is_compressable( type_descr = &1 name = &2 ).ENDIF.
END-OF-DEFINITION.
DEFINE dump_type.IF mv_extended IS INITIAL.dump_type_int &1 &2 &3 &4.ELSE.&3 = dump_type( data = &1 type_descr = &2 convexit = &4 ).ENDIF.
END-OF-DEFINITION.
DEFINE dump_type_int.IF &4 IS NOT INITIAL AND &1 IS NOT INITIAL.TRY.CALL FUNCTION &4EXPORTINGinput    = &1IMPORTINGoutput   = &3EXCEPTIONSOTHERS   = 1.IF sy-subrc IS INITIAL.CONCATENATE `"` &3 `"` INTO &3.ENDIF.CATCH cx_root.                                      "#EC NO_HANDLERENDTRY.ELSE.CASE &2->type_kind.WHEN cl_abap_typedescr=>typekind_float OR cl_abap_typedescr=>typekind_int OR cl_abap_typedescr=>typekind_int1 ORcl_abap_typedescr=>typekind_int2 OR cl_abap_typedescr=>typekind_packed OR `8`. " TYPEKIND_INT8 -> '8' only from 7.40.IF &2->type_kind EQ cl_abap_typedescr=>typekind_packed AND mv_ts_as_iso8601 EQ c_bool-true AND &2->absolute_name CP `\TYPE=TIMESTAMP*`.IF &1 IS INITIAL.&3 = `""`.ELSE.&3 = &1.IF &2->absolute_name EQ `\TYPE=TIMESTAMP`.CONCATENATE `"` &3(4) `-` &3+4(2) `-` &3+6(2) `T` &3+8(2) `:` &3+10(2) `:` &3+12(2) `.0000000Z"`  INTO &3.ELSEIF &2->absolute_name EQ `\TYPE=TIMESTAMPL`.CONCATENATE `"` &3(4) `-` &3+4(2) `-` &3+6(2) `T` &3+8(2) `:` &3+10(2) `:` &3+12(2) `.` &3+15(7) `Z"`  INTO &3.ENDIF.ENDIF.ELSEIF &1 IS INITIAL.&3 = `0`.ELSE.&3 = &1.IF &1 LT 0.IF &2->type_kind <> cl_abap_typedescr=>typekind_float. "float: sign is already at the beginningSHIFT &3 RIGHT CIRCULAR.ENDIF.ELSE.CONDENSE &3.ENDIF.ENDIF.WHEN cl_abap_typedescr=>typekind_num.IF mv_numc_as_string EQ abap_true.IF &1 IS INITIAL.&3 = `""`.ELSE.CONCATENATE `"` &1 `"` INTO &3.ENDIF.ELSE.&3 = &1.SHIFT &3 LEFT DELETING LEADING ` 0`.IF &3 IS INITIAL.&3 = `0`.ENDIF.ENDIF.WHEN cl_abap_typedescr=>typekind_string OR cl_abap_typedescr=>typekind_csequence OR cl_abap_typedescr=>typekind_clike.IF &1 IS INITIAL.&3 = `""`.ELSEIF &2->absolute_name EQ mc_json_type.&3 = &1.ELSE.escape_json &1 &3.CONCATENATE `"` &3 `"` INTO &3.ENDIF.WHEN cl_abap_typedescr=>typekind_xstring OR cl_abap_typedescr=>typekind_hex.IF &1 IS INITIAL.&3 = `""`.ELSE.&3 = xstring_to_string( &1 ).escape_json_inplace &3.CONCATENATE `"` &3 `"` INTO &3.ENDIF.WHEN cl_abap_typedescr=>typekind_char.IF &2->output_length EQ 1 AND mc_bool_types CS &2->absolute_name.IF &1 EQ c_bool-true.&3 = `true`.                                    "#EC NOTEXTELSEIF mc_bool_3state CS &2->absolute_name AND &1 IS INITIAL.&3 = `null`.                                    "#EC NOTEXTELSE.&3 = `false`.                                   "#EC NOTEXTENDIF.ELSE.escape_json &1 &3.CONCATENATE `"` &3 `"` INTO &3.ENDIF.WHEN cl_abap_typedescr=>typekind_date.CONCATENATE `"` &1(4) `-` &1+4(2) `-` &1+6(2) `"` INTO &3.WHEN cl_abap_typedescr=>typekind_time.CONCATENATE `"` &1(2) `:` &1+2(2) `:` &1+4(2) `"` INTO &3.WHEN `k`. " cl_abap_typedescr=>typekind_enum&3 = &1.CONCATENATE `"` &3 `"` INTO &3.WHEN OTHERS.IF &1 IS INITIAL.&3 = `null`.                                      "#EC NOTEXTELSE.&3 = &1.ENDIF.ENDCASE.ENDIF.
END-OF-DEFINITION.
DEFINE format_name.CASE &2.WHEN pretty_mode-camel_case.&3 = pretty_name( &1 ).WHEN pretty_mode-extended.&3 = pretty_name_ex( &1 ).WHEN pretty_mode-user_low_case.READ TABLE mt_name_mappings WITH TABLE KEY abap = &1 ASSIGNING <cache>. "#EC WARNOKIF sy-subrc IS INITIAL.&3 = <cache>-json.ELSE.&3 = &1.TRANSLATE &3 TO LOWER CASE.                       "#EC SYNTCHARENDIF.WHEN pretty_mode-user.READ TABLE mt_name_mappings WITH TABLE KEY abap = &1 ASSIGNING <cache>. "#EC WARNOKIF sy-subrc IS INITIAL.&3 = <cache>-json.ELSE.&3 = &1.ENDIF.WHEN pretty_mode-low_case.&3 = &1.TRANSLATE &3 TO LOWER CASE.                         "#EC SYNTCHARWHEN OTHERS.&3 = &1.ENDCASE.
END-OF-DEFINITION.
DEFINE throw_error.RAISE EXCEPTION TYPE cx_sy_move_cast_error.
END-OF-DEFINITION.
DEFINE while_offset_cs.
*  >= 7.02 alternative
*  pos = find_any_not_of( val = json sub = &1 off = offset ).
*  if pos eq -1. offset = length.
*  else. offset = pos. endif.
* < 7.02WHILE offset < length.FIND FIRST OCCURRENCE OF json+offset(1) IN &1.IF sy-subrc IS NOT INITIAL.EXIT.ENDIF.offset = offset + 1.ENDWHILE.
* < 7.02
END-OF-DEFINITION.
DEFINE while_offset_not_cs.WHILE offset < length.FIND FIRST OCCURRENCE OF &2+offset(1) IN &1.IF sy-subrc IS INITIAL.EXIT.ENDIF.offset = offset + 1.ENDWHILE.
END-OF-DEFINITION.
DEFINE eat_white.while_offset_cs sv_white_space.IF offset GE length.throw_error.ENDIF.
END-OF-DEFINITION.
DEFINE eat_name.IF json+offset(1) EQ `"`.mark   = offset + 1.offset = mark.FIND FIRST OCCURRENCE OF `"` IN SECTION OFFSET offset OF json MATCH OFFSET offset.IF sy-subrc IS NOT INITIAL.throw_error.ENDIF.match = offset - mark.&1 = json+mark(match).offset = offset + 1.ELSE.throw_error.ENDIF.
END-OF-DEFINITION.
DEFINE eat_string.IF json+offset(1) EQ `"`.mark   = offset + 1.offset = mark.DO.FIND FIRST OCCURRENCE OF `"` IN SECTION OFFSET offset OF json MATCH OFFSET pos.IF sy-subrc IS NOT INITIAL.throw_error.ENDIF.offset = pos.pos = pos - 1." if escaped search furtherWHILE pos GE 0 AND json+pos(1) EQ `\`.pos = pos - 1.ENDWHILE.match = ( offset - pos ) MOD 2.IF match NE 0.EXIT.ENDIF.offset = offset + 1.ENDDO.match = offset - mark.&1 = json+mark(match)." unescaped singe characters, e.g \\, \", \/ etc," BUT ONLY if someone really need the dataIF type_descr IS NOT INITIAL.&1 = unescape( &1 ).ENDIF.offset = offset + 1.ELSE.throw_error.ENDIF.
END-OF-DEFINITION.
DEFINE eat_number.mark   = offset.while_offset_cs `0123456789+-eE.`.                        "#EC NOTEXTmatch = offset - mark.&1 = json+mark(match).
END-OF-DEFINITION.
DEFINE eat_bool.mark   = offset.while_offset_cs `aeflnrstu`.                              "#EC NOTEXTmatch = offset - mark.IF json+mark(match) EQ `true`.                            "#EC NOTEXT&1 = c_bool-true.ELSEIF json+mark(match) EQ `false`.                       "#EC NOTEXTIF type_descr IS BOUND AND mc_bool_3state CS type_descr->absolute_name.&1 = c_tribool-false.ELSE.&1 = c_bool-false.ENDIF.ELSEIF json+mark(match) EQ `null`.                        "#EC NOTEXTCLEAR &1.ENDIF.
END-OF-DEFINITION.
DEFINE eat_char.IF offset < length AND json+offset(1) EQ &1.offset = offset + 1.ELSE.throw_error.ENDIF.
END-OF-DEFINITION.
CLASS zcl_json IMPLEMENTATION.METHOD bool_to_tribool.IF iv_bool EQ c_bool-true.rv_tribool = c_tribool-true.ELSEIF iv_bool EQ abap_undefined. " fall back for abap _boolrv_tribool = c_tribool-undefined.ELSE.rv_tribool = c_tribool-false.ENDIF.ENDMETHOD.                    "bool_to_triboolMETHOD class_constructor.DATA: lo_bool_type_descr    TYPE REF TO cl_abap_typedescr,lo_tribool_type_descr TYPE REF TO cl_abap_typedescr,lo_json_type_descr    TYPE REF TO cl_abap_typedescr,lv_pos                LIKE sy-fdpos,lv_json_string        TYPE json.lo_bool_type_descr    = cl_abap_typedescr=>describe_by_data( c_bool-true ).lo_tribool_type_descr = cl_abap_typedescr=>describe_by_data( c_tribool-true ).lo_json_type_descr    = cl_abap_typedescr=>describe_by_data( lv_json_string ).CONCATENATE mc_bool_types lo_bool_type_descr->absolute_name lo_tribool_type_descr->absolute_name INTO mc_bool_types.CONCATENATE mc_bool_3state lo_tribool_type_descr->absolute_name INTO mc_bool_3state.CONCATENATE mc_json_type lo_json_type_descr->absolute_name INTO mc_json_type.FIND FIRST OCCURRENCE OF `\TYPE=` IN lo_json_type_descr->absolute_name MATCH OFFSET lv_pos.IF sy-subrc IS INITIAL.mc_me_type = lo_json_type_descr->absolute_name(lv_pos).ENDIF.sv_white_space = cl_abap_char_utilities=>get_simple_spaces_for_cur_cp( ).mc_cov_error = cl_abap_conv_in_ce=>uccp( '0000' ).ENDMETHOD.                    "class_constructorMETHOD constructor.DATA: rtti TYPE REF TO cl_abap_classdescr,pair LIKE LINE OF name_mappings.mv_compress         = compress.mv_pretty_name      = pretty_name.mv_assoc_arrays     = assoc_arrays.mv_ts_as_iso8601    = ts_as_iso8601.mv_expand_includes  = expand_includes.mv_assoc_arrays_opt = assoc_arrays_opt.mv_strict_mode      = strict_mode.mv_numc_as_string   = numc_as_string.mv_conversion_exits = conversion_exits.LOOP AT name_mappings INTO pair.TRANSLATE pair-abap TO UPPER CASE.INSERT pair INTO TABLE mt_name_mappings.ENDLOOP." if it dumps here, you have passed ambiguous mapping to the API" please check your code for duplicates, pairs ABAP - JSON shall be uniqueINSERT LINES OF mt_name_mappings INTO TABLE mt_name_mappings_ex.IF mt_name_mappings IS NOT INITIAL.IF mv_pretty_name EQ pretty_mode-none.mv_pretty_name = pretty_mode-user.ELSEIF pretty_name EQ pretty_mode-low_case.mv_pretty_name = pretty_mode-user_low_case.ENDIF.ENDIF.rtti ?= cl_abap_classdescr=>describe_by_object_ref( me ).IF rtti->absolute_name NE mc_me_type.mv_extended = c_bool-true.ENDIF.ENDMETHOD.METHOD deserialize.DATA: lo_json TYPE REF TO zcl_json." **********************************************************************" Usage examples and documentation can be found on SCN:" http://wiki.scn.sap.com/wiki/display/Snippets/One+more+ABAP+to+JSON+Serializer+and+Deserializer" **********************************************************************  "IF json IS NOT INITIAL OR jsonx IS NOT INITIAL.CREATE OBJECT lo_jsonEXPORTINGpretty_name      = pretty_namename_mappings    = name_mappingsassoc_arrays     = assoc_arraysconversion_exits = conversion_exitsassoc_arrays_opt = assoc_arrays_opt.TRY .lo_json->deserialize_int( EXPORTING json = json jsonx = jsonx CHANGING data = data ).CATCH cx_sy_move_cast_error.                    "#EC NO_HANDLERENDTRY.ENDIF.ENDMETHOD.                    "deserializeMETHOD deserialize_int.DATA: length    TYPE i,offset    TYPE i,unescaped LIKE json." **********************************************************************" Usage examples and documentation can be found on SCN:" http://wiki.scn.sap.com/wiki/display/Snippets/One+more+ABAP+to+JSON+Serializer+and+Deserializer" **********************************************************************  "IF json IS NOT INITIAL OR jsonx IS NOT INITIAL.IF jsonx IS NOT INITIAL.unescaped = raw_to_string( jsonx ).ELSE.unescaped = json.ENDIF." skip leading BOM signslength = strlen( unescaped ).while_offset_not_cs `"{[` unescaped.unescaped = unescaped+offset.length = length - offset.restore_type( EXPORTING json = unescaped length = length CHANGING data = data ).ENDIF.ENDMETHOD.                    "deserializeMETHOD dump_int.DATA: lo_typedesc   TYPE REF TO cl_abap_typedescr,lo_elem_descr TYPE REF TO cl_abap_elemdescr,lo_classdesc  TYPE REF TO cl_abap_classdescr,lo_structdesc TYPE REF TO cl_abap_structdescr,lo_tabledescr TYPE REF TO cl_abap_tabledescr,lt_symbols    TYPE t_t_symbol,lt_keys       LIKE lt_symbols,lt_properties TYPE STANDARD TABLE OF string,lt_fields     TYPE STANDARD TABLE OF string,lo_obj_ref    TYPE REF TO object,lo_data_ref   TYPE REF TO data,ls_skip_key   TYPE LINE OF abap_keydescr_tab,lv_array_opt  TYPE abap_bool,lv_prop_name  TYPE string,lv_keyval     TYPE string,lv_itemval    TYPE string.FIELD-SYMBOLS: <line>   TYPE any,<value>  TYPE any,<data>   TYPE data,<key>    TYPE LINE OF abap_keydescr_tab,<symbol> LIKE LINE OF lt_symbols,<table>  TYPE ANY TABLE." we need here macro instead of method calls because of the performance reasons." based on SAT measurements.CASE type_descr->kind.WHEN cl_abap_typedescr=>kind_ref.IF data IS INITIAL.r_json = `null`.                                  "#EC NOTEXTELSEIF type_descr->type_kind EQ cl_abap_typedescr=>typekind_dref.lo_data_ref ?= data.lo_typedesc = cl_abap_typedescr=>describe_by_data_ref( lo_data_ref ).ASSIGN lo_data_ref->* TO <data>.r_json = dump_int( data = <data> type_descr = lo_typedesc ).ELSE.lo_obj_ref ?= data.lo_classdesc ?= cl_abap_typedescr=>describe_by_object_ref( lo_obj_ref ).lt_symbols = get_symbols( type_descr = lo_classdesc object = lo_obj_ref ).r_json = dump_symbols( lt_symbols ).ENDIF.WHEN cl_abap_typedescr=>kind_elem.lo_elem_descr ?= type_descr.dump_type data lo_elem_descr r_json convexit.WHEN cl_abap_typedescr=>kind_struct.lo_structdesc ?= type_descr.GET REFERENCE OF data INTO lo_data_ref.lt_symbols = get_symbols( type_descr = lo_structdesc data = lo_data_ref ).r_json = dump_symbols( lt_symbols ).WHEN cl_abap_typedescr=>kind_table.lo_tabledescr ?= type_descr.lo_typedesc = lo_tabledescr->get_table_line_type( ).ASSIGN data TO <table>." optimization for structured tablesIF lo_typedesc->kind EQ cl_abap_typedescr=>kind_struct.lo_structdesc ?= lo_typedesc.CREATE DATA lo_data_ref LIKE LINE OF <table>.ASSIGN lo_data_ref->* TO <line>.lt_symbols = get_symbols( type_descr = lo_structdesc data = lo_data_ref )." here we have differentiation of output of simple table to JSON array" and sorted or hashed table with unique key into JSON associative arrayIF lo_tabledescr->has_unique_key IS NOT INITIAL AND mv_assoc_arrays IS NOT INITIAL.IF lo_tabledescr->key_defkind EQ lo_tabledescr->keydefkind_user.LOOP AT lo_tabledescr->key ASSIGNING <key>.READ TABLE lt_symbols WITH KEY name = <key>-name ASSIGNING <symbol>.APPEND <symbol> TO lt_keys.ENDLOOP.ENDIF.IF lines( lo_tabledescr->key ) EQ 1.READ TABLE lo_tabledescr->key INDEX 1 INTO ls_skip_key.DELETE lt_symbols WHERE name EQ ls_skip_key-name." remove object wrapping for simple name-value tablesIF mv_assoc_arrays_opt EQ abap_true AND lines( lt_symbols ) EQ 1.lv_array_opt = abap_true.ENDIF.ENDIF.LOOP AT <table> INTO <line>.CLEAR: lt_fields, lv_prop_name.LOOP AT lt_symbols ASSIGNING <symbol>.ASSIGN <symbol>-value->* TO <value>.IF mv_compress IS INITIAL OR <value> IS NOT INITIAL OR <symbol>-compressable EQ abap_false.IF <symbol>-type->kind EQ cl_abap_typedescr=>kind_elem.lo_elem_descr ?= <symbol>-type.dump_type <value> lo_elem_descr lv_itemval <symbol>-convexit_out.ELSE.lv_itemval = dump_int( data = <value> type_descr = <symbol>-type convexit = <symbol>-convexit_out ).ENDIF.IF lv_array_opt EQ abap_false.CONCATENATE <symbol>-header lv_itemval INTO lv_itemval.ENDIF.APPEND lv_itemval TO lt_fields.ENDIF.ENDLOOP.IF lo_tabledescr->key_defkind EQ lo_tabledescr->keydefkind_user.LOOP AT lt_keys ASSIGNING <symbol>.ASSIGN <symbol>-value->* TO <value>.lv_keyval = <value>.CONDENSE lv_keyval.IF lv_prop_name IS NOT INITIAL.CONCATENATE lv_prop_name mc_key_separator lv_keyval INTO lv_prop_name.ELSE.lv_prop_name = lv_keyval.ENDIF.ENDLOOP.ELSE.LOOP AT lt_symbols ASSIGNING <symbol>.ASSIGN <symbol>-value->* TO <value>.lv_keyval = <value>.CONDENSE lv_keyval.IF lv_prop_name IS NOT INITIAL.CONCATENATE lv_prop_name mc_key_separator lv_keyval INTO lv_prop_name.ELSE.lv_prop_name = lv_keyval.ENDIF.ENDLOOP.ENDIF.CONCATENATE LINES OF lt_fields INTO lv_itemval SEPARATED BY `,`.IF lv_array_opt EQ abap_false.CONCATENATE `"` lv_prop_name `":{` lv_itemval `}` INTO lv_itemval.ELSE.CONCATENATE `"` lv_prop_name `":` lv_itemval `` INTO lv_itemval.ENDIF.APPEND lv_itemval TO lt_properties.ENDLOOP.CONCATENATE LINES OF lt_properties INTO r_json SEPARATED BY `,`.CONCATENATE `{` r_json `}` INTO r_json.ELSE.LOOP AT <table> INTO <line>.CLEAR lt_fields.LOOP AT lt_symbols ASSIGNING <symbol>.ASSIGN <symbol>-value->* TO <value>.IF mv_compress IS INITIAL OR <value> IS NOT INITIAL OR <symbol>-compressable EQ abap_false.IF <symbol>-type->kind EQ cl_abap_typedescr=>kind_elem.lo_elem_descr ?= <symbol>-type.dump_type <value> lo_elem_descr lv_itemval <symbol>-convexit_out.ELSE.lv_itemval = dump_int( data = <value> type_descr = <symbol>-type convexit = <symbol>-convexit_out ).ENDIF.CONCATENATE <symbol>-header lv_itemval INTO lv_itemval.APPEND lv_itemval TO lt_fields.ENDIF.ENDLOOP.CONCATENATE LINES OF lt_fields INTO lv_itemval SEPARATED BY `,`.CONCATENATE `{` lv_itemval `}` INTO lv_itemval.APPEND lv_itemval TO lt_properties.ENDLOOP.CONCATENATE LINES OF lt_properties INTO r_json SEPARATED BY `,`.CONCATENATE `[` r_json `]` INTO r_json.ENDIF.ELSE.LOOP AT <table> ASSIGNING <value>.lv_itemval = dump_int( data = <value> type_descr = lo_typedesc ).APPEND lv_itemval TO lt_properties.ENDLOOP.CONCATENATE LINES OF lt_properties INTO r_json SEPARATED BY `,`.CONCATENATE `[` r_json `]` INTO r_json.ENDIF.ENDCASE.ENDMETHOD.                    "dumpMETHOD dump_symbols.DATA: lv_properties TYPE STANDARD TABLE OF string,lv_itemval    TYPE string.FIELD-SYMBOLS: <value>  TYPE any,<symbol> LIKE LINE OF it_symbols.LOOP AT it_symbols ASSIGNING <symbol>.ASSIGN <symbol>-value->* TO <value>.IF mv_compress IS INITIAL OR <value> IS NOT INITIAL OR <symbol>-compressable EQ abap_false.lv_itemval = dump_int( data = <value> type_descr = <symbol>-type convexit = <symbol>-convexit_out ).CONCATENATE <symbol>-header lv_itemval INTO lv_itemval.APPEND lv_itemval TO lv_properties.ENDIF.ENDLOOP.CONCATENATE LINES OF lv_properties INTO r_json SEPARATED BY `,`.CONCATENATE `{` r_json `}` INTO r_json.ENDMETHOD.METHOD dump_type.CONSTANTS: lc_typekind_utclong TYPE abap_typekind VALUE 'p', " CL_ABAP_TYPEDESCR=>TYPEKIND_UTCLONG -> 'p' only from 7.60lc_typekind_int8    TYPE abap_typekind VALUE '8'.  " TYPEKIND_INT8 -> '8' only from 7.40IF convexit IS NOT INITIAL AND data IS NOT INITIAL.TRY.CALL FUNCTION convexitEXPORTINGinput  = dataIMPORTINGoutput = r_jsonEXCEPTIONSOTHERS = 1.IF sy-subrc IS INITIAL.CONCATENATE `"` r_json `"` INTO r_json.ENDIF.CATCH cx_root.                                  "#EC NO_HANDLERENDTRY.ELSE.CASE type_descr->type_kind.WHEN cl_abap_typedescr=>typekind_float OR cl_abap_typedescr=>typekind_int OR cl_abap_typedescr=>typekind_int1 ORcl_abap_typedescr=>typekind_int2 OR cl_abap_typedescr=>typekind_packed OR lc_typekind_utclong OR lc_typekind_int8.IF mv_ts_as_iso8601 EQ c_bool-true AND( type_descr->type_kind EQ lc_typekind_utclong OR( type_descr->type_kind EQ cl_abap_typedescr=>typekind_packed AND type_descr->absolute_name CP `\TYPE=TIMESTAMP*` ) ).IF data IS INITIAL.r_json = `""`.ELSE.r_json = data.IF type_descr->absolute_name EQ `\TYPE=TIMESTAMP`.CONCATENATE `"` r_json(4) `-` r_json+4(2) `-` r_json+6(2) `T` r_json+8(2) `:` r_json+10(2) `:` r_json+12(2) `.0000000Z"`  INTO r_json.ELSEIF type_descr->absolute_name EQ `\TYPE=TIMESTAMPL`.CONCATENATE `"` r_json(4) `-` r_json+4(2) `-` r_json+6(2) `T` r_json+8(2) `:` r_json+10(2) `:` r_json+12(2) `.` r_json+15(7) `Z"`  INTO r_json.ENDIF.ENDIF.ELSEIF data IS INITIAL.r_json = `0`.ELSE.r_json = data.IF data LT 0.IF type_descr->type_kind <> cl_abap_typedescr=>typekind_float. "float: sign is already at the beginningSHIFT r_json RIGHT CIRCULAR.ENDIF.ELSE.CONDENSE r_json.ENDIF.ENDIF.WHEN cl_abap_typedescr=>typekind_num.IF mv_numc_as_string EQ abap_true.IF data IS INITIAL.r_json = `""`.ELSE.CONCATENATE `"` data `"` INTO r_json.ENDIF.ELSE.r_json = data.SHIFT r_json LEFT DELETING LEADING ` 0`.IF r_json IS INITIAL.r_json = `0`.ENDIF.ENDIF.WHEN cl_abap_typedescr=>typekind_string OR cl_abap_typedescr=>typekind_csequence OR cl_abap_typedescr=>typekind_clike.IF data IS INITIAL.r_json = `""`.ELSEIF type_descr->absolute_name EQ mc_json_type.r_json = data.ELSE.r_json = escape( data ).CONCATENATE `"` r_json `"` INTO r_json.ENDIF.WHEN cl_abap_typedescr=>typekind_xstring OR cl_abap_typedescr=>typekind_hex.IF data IS INITIAL.r_json = `""`.ELSE.r_json = xstring_to_string( data ).r_json = escape( r_json ).CONCATENATE `"` r_json `"` INTO r_json.ENDIF.WHEN cl_abap_typedescr=>typekind_char.IF type_descr->output_length EQ 1 AND mc_bool_types CS type_descr->absolute_name.IF data EQ c_bool-true.r_json = `true`.                              "#EC NOTEXTELSEIF mc_bool_3state CS type_descr->absolute_name AND data IS INITIAL.r_json = `null`.                              "#EC NOTEXTELSE.r_json = `false`.                             "#EC NOTEXTENDIF.ELSE.r_json = escape( data ).CONCATENATE `"` r_json `"` INTO r_json.ENDIF.WHEN cl_abap_typedescr=>typekind_date.CONCATENATE `"` data(4) `-` data+4(2) `-` data+6(2) `"` INTO r_json.WHEN cl_abap_typedescr=>typekind_time.CONCATENATE `"` data(2) `:` data+2(2) `:` data+4(2) `"` INTO r_json.WHEN 'k'. " cl_abap_typedescr=>typekind_enumr_json = data.CONCATENATE `"` r_json `"` INTO r_json.WHEN OTHERS.IF data IS INITIAL.r_json = `null`.                                "#EC NOTEXTELSE.r_json = data.ENDIF.ENDCASE.ENDIF.ENDMETHOD.                    "dump_typeMETHOD edm_datetime_to_ts.CONSTANTS: lc_epochs TYPE string VALUE `19700101000000`.DATA: lv_ticks      TYPE p,lv_seconds    TYPE p,lv_subsec     TYPE p,lv_timestamps TYPE string,lv_timestamp  TYPE timestampl VALUE `19700101000000.0000000`.lv_ticks     = ticks.lv_seconds   = lv_ticks / 1000. " in secondslv_subsec    = lv_ticks MOD 1000. " in subsecIF lv_subsec GT 0.lv_timestamps = lv_subsec.CONCATENATE lc_epochs `.` lv_timestamps INTO lv_timestamps.lv_timestamp = lv_timestamps.ENDIF.lv_timestamp = cl_abap_tstmp=>add( tstmp = lv_timestamp secs = lv_seconds ).IF offset IS NOT INITIAL.lv_ticks = offset+1.lv_ticks = lv_ticks * 60. "offset is in minutesIF offset(1) = '+'.lv_timestamp = cl_abap_tstmp=>subtractsecs( tstmp = lv_timestamp secs = lv_ticks ).ELSE.lv_timestamp = cl_abap_tstmp=>add( tstmp = lv_timestamp secs = lv_ticks ).ENDIF.ENDIF.CASE typekind.WHEN cl_abap_typedescr=>typekind_time.r_data = lv_timestamp.r_data = r_data+8(6).WHEN cl_abap_typedescr=>typekind_date.r_data = lv_timestamp.r_data = r_data(8).WHEN cl_abap_typedescr=>typekind_packed.r_data = lv_timestamp.ENDCASE.ENDMETHOD.METHOD escape.out = in.REPLACE ALL OCCURRENCES OF `\` IN out WITH `\\`.REPLACE ALL OCCURRENCES OF `"` IN out WITH `\"`.ENDMETHOD.                    "escapeMETHOD generate.DATA: lo_json TYPE REF TO zcl_json,offset  TYPE i,length  TYPE i,lv_json LIKE json." skip leading BOM signslength = strlen( json ).while_offset_not_cs `"{[` json.lv_json = json+offset.length  = length - offset.CREATE OBJECT lo_jsonEXPORTINGpretty_name      = pretty_namename_mappings    = name_mappingsassoc_arrays     = c_bool-trueassoc_arrays_opt = c_bool-true.TRY .rr_data = lo_json->generate_int( json = lv_json length = length ).CATCH cx_sy_move_cast_error.                      "#EC NO_HANDLERENDTRY.ENDMETHOD.METHOD generate_int.TYPES: BEGIN OF ts_field,name  TYPE string,value TYPE json,END OF ts_field.DATA: offset TYPE i.DATA: lt_json      TYPE STANDARD TABLE OF json WITH DEFAULT KEY,lv_comp_name TYPE abap_compname,lt_fields    TYPE SORTED TABLE OF ts_field WITH UNIQUE KEY name,lo_type      TYPE REF TO cl_abap_datadescr,lt_comp      TYPE abap_component_tab,lt_names     TYPE HASHED TABLE OF string WITH UNIQUE KEY table_line,cache        LIKE LINE OF mt_name_mappings_ex,ls_comp      LIKE LINE OF lt_comp.FIELD-SYMBOLS: <data>   TYPE any,<struct> TYPE any,<json>   LIKE LINE OF lt_json,<field>  LIKE LINE OF lt_fields,<table>  TYPE STANDARD TABLE,<cache>  LIKE LINE OF mt_name_mappings_ex.IF length IS NOT SUPPLIED.length = strlen( json ).ENDIF.eat_white.CASE json+offset(1).WHEN `{`."result must be a structurerestore_type( EXPORTING json = json length = length CHANGING  data = lt_fields ).IF lt_fields IS NOT INITIAL.ls_comp-type = cl_abap_refdescr=>get_ref_to_data( ).LOOP AT lt_fields ASSIGNING <field>.READ TABLE mt_name_mappings_ex WITH TABLE KEY json = <field>-name ASSIGNING <cache>.IF sy-subrc IS INITIAL.ls_comp-name = <cache>-abap.ELSE.cache-json = ls_comp-name = <field>-name." remove characters not allowed in component namesTRANSLATE ls_comp-name USING mc_name_symbols_map.IF mv_pretty_name EQ pretty_mode-camel_case OR mv_pretty_name EQ pretty_mode-extended.REPLACE ALL OCCURRENCES OF REGEX `([a-z])([A-Z])` IN ls_comp-name WITH `$1_$2`. "#EC NOTEXTENDIF.TRANSLATE ls_comp-name TO UPPER CASE.cache-abap = ls_comp-name = lv_comp_name = ls_comp-name. " truncate by allowed field name lengthINSERT cache INTO TABLE mt_name_mappings_ex.ENDIF.INSERT ls_comp-name INTO TABLE lt_names.IF sy-subrc IS INITIAL.APPEND ls_comp TO lt_comp.ELSE.DELETE lt_fields.ENDIF.ENDLOOP.TRY.lo_type = cl_abap_structdescr=>create( p_components = lt_comp p_strict = c_bool-false ).CREATE DATA rr_data TYPE HANDLE lo_type.ASSIGN rr_data->* TO <struct>.LOOP AT lt_fields ASSIGNING <field>.ASSIGN COMPONENT sy-tabix OF STRUCTURE <struct> TO <data>.<data> = generate_int( <field>-value ).ENDLOOP.CATCH cx_sy_create_data_error cx_sy_struct_creation. "#EC NO_HANDLERENDTRY.ENDIF.RETURN.WHEN `[`."result must be a table of refrestore_type( EXPORTING json = json length = length CHANGING  data = lt_json ).CREATE DATA rr_data TYPE ref_tab.ASSIGN rr_data->* TO <table>.LOOP AT lt_json ASSIGNING <json>.APPEND INITIAL LINE TO <table> ASSIGNING <data>.<data> = generate_int( <json> ).ENDLOOP.RETURN.WHEN `"`."stringCREATE DATA rr_data TYPE string.WHEN `-` OR `0` OR `1` OR `2` OR `3` OR `4` OR `5` OR `6` OR `7` OR `8` OR `9`. " numberIF json+offset CS '.'.CREATE DATA rr_data TYPE f.ELSEIF length GT 9.CREATE DATA rr_data TYPE p.ELSE.CREATE DATA rr_data TYPE i.ENDIF.WHEN OTHERS.IF json+offset EQ `true` OR json+offset EQ `false`. "#EC NOTEXTCREATE DATA rr_data TYPE abap_bool.ENDIF.ENDCASE.IF rr_data IS BOUND.ASSIGN rr_data->* TO <data>.restore_type( EXPORTING json = json length = length CHANGING  data = <data> ).ENDIF.ENDMETHOD.METHOD generate_int_ex.DATA: lv_assoc_arrays     LIKE mv_assoc_arrays,lv_assoc_arrays_opt LIKE mv_assoc_arrays_opt,lv_mark             LIKE offset,lv_match            LIKE lv_mark,lv_json             TYPE zcl_json=>json.lv_mark = offset.restore_type( EXPORTING json = json length = length CHANGING offset = offset ).lv_match = offset - lv_mark.lv_json = json+lv_mark(lv_match).lv_assoc_arrays     = mv_assoc_arrays.lv_assoc_arrays_opt = mv_assoc_arrays_opt.mv_assoc_arrays     = abap_true.mv_assoc_arrays_opt = abap_true.data = generate_int( lv_json ).mv_assoc_arrays = lv_assoc_arrays.mv_assoc_arrays_opt = lv_assoc_arrays_opt.ENDMETHOD.METHOD get_convexit_func.DATA: ls_dfies     TYPE dfies.elem_descr->get_ddic_field(RECEIVINGp_flddescr   = ls_dfies    " Field DescriptionEXCEPTIONSnot_found    = 1no_ddic_type = 2OTHERS       = 3).IF sy-subrc IS INITIAL AND ls_dfies-convexit IS NOT INITIAL.IF input EQ abap_true.CONCATENATE 'CONVERSION_EXIT_' ls_dfies-convexit '_INPUT' INTO rv_func.ELSE.CONCATENATE 'CONVERSION_EXIT_' ls_dfies-convexit '_OUTPUT' INTO rv_func.ENDIF.ENDIF.ENDMETHOD.METHOD get_fields.DATA: lt_symbols TYPE t_t_symbol,lv_name    TYPE char128,ls_field   LIKE LINE OF rt_fields.FIELD-SYMBOLS: <sym>   LIKE LINE OF lt_symbols,<cache> LIKE LINE OF mt_name_mappings.lt_symbols = get_symbols( type_descr = type_descr data = data object = object include_aliases = abap_true ).LOOP AT lt_symbols ASSIGNING <sym> WHERE read_only EQ abap_false.MOVE-CORRESPONDING <sym> TO ls_field." insert as UPPER CASEINSERT ls_field INTO TABLE rt_fields." insert as lower caseTRANSLATE ls_field-name TO LOWER CASE.INSERT ls_field INTO TABLE rt_fields." as pretty printedIF mv_pretty_name NE pretty_mode-none AND mv_pretty_name NE pretty_mode-low_case.format_name <sym>-name mv_pretty_name ls_field-name.INSERT ls_field INTO TABLE rt_fields." let us check for not well formed canelCase to be compatible with old logiclv_name = ls_field-name.TRANSLATE lv_name(1) TO UPPER CASE.ls_field-name = lv_name.INSERT ls_field INTO TABLE rt_fields.ENDIF.ENDLOOP.ENDMETHOD.METHOD get_symbols.DATA: comp_tab     TYPE cl_abap_structdescr=>component_table,symb_tab     LIKE result,symb         LIKE LINE OF symb_tab,elem_descr   TYPE REF TO cl_abap_elemdescr,class_descr  TYPE REF TO cl_abap_classdescr,struct_descr TYPE REF TO cl_abap_structdescr.FIELD-SYMBOLS: <comp>  LIKE LINE OF comp_tab,<attr>  LIKE LINE OF cl_abap_objectdescr=>attributes,<cache> LIKE LINE OF mt_name_mappings,<field> TYPE any.IF type_descr->kind EQ cl_abap_typedescr=>kind_struct.struct_descr ?= type_descr.comp_tab = struct_descr->get_components( ).LOOP AT comp_tab ASSIGNING <comp>.IF <comp>-name IS NOT INITIAL AND( <comp>-as_include EQ abap_false OR include_aliases EQ abap_true OR mv_expand_includes EQ abap_false ).symb-name = <comp>-name.symb-type = <comp>-type.IF data IS BOUND.IF mv_conversion_exits EQ abap_true AND symb-type->kind EQ cl_abap_typedescr=>kind_elem.elem_descr ?= symb-type.symb-convexit_in = get_convexit_func( elem_descr = elem_descr input = abap_true ).symb-convexit_out = get_convexit_func( elem_descr = elem_descr input = abap_false ).ENDIF.is_compressable symb-type symb-name symb-compressable.ASSIGN data->(symb-name) TO <field>.GET REFERENCE OF <field> INTO symb-value.format_name symb-name mv_pretty_name symb-header.CONCATENATE `"` symb-header  `":` INTO symb-header.ENDIF.APPEND symb TO result.ENDIF.IF <comp>-as_include EQ abap_true AND mv_expand_includes EQ abap_true.struct_descr ?= <comp>-type.symb_tab = get_symbols( type_descr = struct_descr include_aliases = include_aliases ).LOOP AT symb_tab INTO symb.CONCATENATE symb-name <comp>-suffix INTO symb-name.IF data IS BOUND.IF mv_conversion_exits EQ abap_true AND symb-type->kind EQ cl_abap_typedescr=>kind_elem.elem_descr ?= symb-type.symb-convexit_in = get_convexit_func( elem_descr = elem_descr input = abap_true ).symb-convexit_out = get_convexit_func( elem_descr = elem_descr input = abap_false ).ENDIF.is_compressable symb-type symb-name symb-compressable.ASSIGN data->(symb-name) TO <field>.GET REFERENCE OF <field> INTO symb-value.format_name symb-name mv_pretty_name symb-header.CONCATENATE `"` symb-header  `":` INTO symb-header.ENDIF.APPEND symb TO result.ENDLOOP.ENDIF.ENDLOOP.ELSEIF type_descr->type_kind EQ cl_abap_typedescr=>typekind_class.class_descr ?= type_descr.LOOP AT class_descr->attributes ASSIGNING <attr> WHERE is_constant IS INITIAL AND alias_for IS INITIAL AND( is_interface IS INITIAL OR type_kind NE cl_abap_typedescr=>typekind_oref ).ASSIGN object->(<attr>-name) TO <field>.CHECK sy-subrc IS INITIAL. " we can only assign to public attributessymb-name = <attr>-name.symb-read_only = <attr>-is_read_only.symb-type = class_descr->get_attribute_type( <attr>-name ).IF mv_conversion_exits EQ abap_true AND symb-type->kind EQ cl_abap_typedescr=>kind_elem.elem_descr ?= symb-type.symb-convexit_in = get_convexit_func( elem_descr = elem_descr input = abap_true ).symb-convexit_out = get_convexit_func( elem_descr = elem_descr input = abap_false ).ENDIF.is_compressable symb-type symb-name symb-compressable.GET REFERENCE OF <field> INTO symb-value.format_name symb-name mv_pretty_name symb-header.CONCATENATE `"` symb-header  `":` INTO symb-header.APPEND symb TO result.ENDLOOP.ENDIF.ENDMETHOD.                    "GET_SYMBOLSMETHOD is_compressable.rv_compress = abap_true.ENDMETHOD.METHOD pretty_name.DATA: tokens TYPE TABLE OF char128,cache  LIKE LINE OF mt_name_mappings.FIELD-SYMBOLS: <token> LIKE LINE OF tokens,<cache> LIKE LINE OF mt_name_mappings.READ TABLE mt_name_mappings WITH TABLE KEY abap = in ASSIGNING <cache>.IF sy-subrc IS INITIAL.out = <cache>-json.ELSE.out = in.REPLACE ALL OCCURRENCES OF `__` IN out WITH `*`.TRANSLATE out TO LOWER CASE.TRANSLATE out USING `/_:_~_`.SPLIT out AT `_` INTO TABLE tokens.LOOP AT tokens ASSIGNING <token> FROM 2.TRANSLATE <token>(1) TO UPPER CASE.ENDLOOP.CONCATENATE LINES OF tokens INTO out.REPLACE ALL OCCURRENCES OF `*` IN out WITH `_`.cache-abap  = in.cache-json = out.INSERT cache INTO TABLE mt_name_mappings.INSERT cache INTO TABLE mt_name_mappings_ex.ENDIF.ENDMETHOD.                    "pretty_nameMETHOD pretty_name_ex.DATA: tokens TYPE TABLE OF char128,cache  LIKE LINE OF mt_name_mappings.FIELD-SYMBOLS: <token> LIKE LINE OF tokens,<cache> LIKE LINE OF mt_name_mappings.READ TABLE mt_name_mappings WITH TABLE KEY abap = in ASSIGNING <cache>.IF sy-subrc IS INITIAL.out = <cache>-json.ELSE.out = in.TRANSLATE out TO LOWER CASE.TRANSLATE out USING `/_:_~_`.REPLACE ALL OCCURRENCES OF `__e__` IN out WITH `!`.REPLACE ALL OCCURRENCES OF `__n__` IN out WITH `#`.REPLACE ALL OCCURRENCES OF `__d__` IN out WITH `$`.REPLACE ALL OCCURRENCES OF `__p__` IN out WITH `%`.REPLACE ALL OCCURRENCES OF `__m__` IN out WITH `&`.REPLACE ALL OCCURRENCES OF `__s__` IN out WITH `*`.REPLACE ALL OCCURRENCES OF `__h__` IN out WITH `-`.REPLACE ALL OCCURRENCES OF `__t__` IN out WITH `~`.REPLACE ALL OCCURRENCES OF `__l__` IN out WITH `/`.REPLACE ALL OCCURRENCES OF `__c__` IN out WITH `:`.REPLACE ALL OCCURRENCES OF `__v__` IN out WITH `|`.REPLACE ALL OCCURRENCES OF `__a__` IN out WITH `@`.REPLACE ALL OCCURRENCES OF `__o__` IN out WITH `.`.REPLACE ALL OCCURRENCES OF `___`   IN out WITH `.`.REPLACE ALL OCCURRENCES OF `__` IN out WITH `"`.SPLIT out AT `_` INTO TABLE tokens.LOOP AT tokens ASSIGNING <token> FROM 2.TRANSLATE <token>(1) TO UPPER CASE.ENDLOOP.CONCATENATE LINES OF tokens INTO out.REPLACE ALL OCCURRENCES OF `"` IN out WITH `_`.cache-abap  = in.cache-json = out.INSERT cache INTO TABLE mt_name_mappings.INSERT cache INTO TABLE mt_name_mappings_ex.ENDIF.ENDMETHOD.                    "pretty_name_exMETHOD restore.DATA: mark       LIKE offset,match      LIKE offset,ref_descr  TYPE REF TO cl_abap_refdescr,data_descr TYPE REF TO cl_abap_datadescr,data_ref   TYPE REF TO data,object_ref TYPE REF TO object,fields     LIKE field_cache,name_json  TYPE string.FIELD-SYMBOLS: <value>       TYPE any,<field_cache> LIKE LINE OF field_cache.fields = field_cache.IF type_descr IS NOT INITIAL AND type_descr->kind EQ type_descr->kind_ref.ref_descr ?= type_descr.type_descr = ref_descr->get_referenced_type( ).IF ref_descr->type_kind EQ ref_descr->typekind_oref.IF data IS INITIAL." can fire an exception, if type is abstract or constructor protectedCREATE OBJECT data TYPE (type_descr->absolute_name).ENDIF.object_ref ?= data.fields = get_fields( type_descr = type_descr object = object_ref ).ELSEIF ref_descr->type_kind EQ ref_descr->typekind_dref.IF data IS INITIAL.data_descr ?= type_descr.CREATE DATA data TYPE HANDLE data_descr.ENDIF.data_ref ?= data.ASSIGN data_ref->* TO <value>.fields = get_fields( type_descr = type_descr data = data_ref ).restore( EXPORTING json = json length = length type_descr = type_descr field_cache = fieldsCHANGING data = <value> offset = offset ).RETURN.ENDIF.ENDIF.IF fields IS INITIAL AND type_descr IS NOT INITIAL AND type_descr->kind EQ type_descr->kind_struct.GET REFERENCE OF data INTO data_ref.fields = get_fields( type_descr = type_descr data = data_ref ).ENDIF.eat_white.eat_char `{`.eat_white.WHILE offset < length AND json+offset(1) NE `}`.eat_name name_json.eat_white.eat_char `:`.eat_white.READ TABLE fields WITH TABLE KEY name = name_json ASSIGNING <field_cache>.IF sy-subrc IS NOT INITIAL.TRANSLATE name_json TO UPPER CASE.READ TABLE fields WITH TABLE KEY name = name_json ASSIGNING <field_cache>.ENDIF.IF sy-subrc IS INITIAL.ASSIGN <field_cache>-value->* TO <value>.restore_type( EXPORTING json = json length = length type_descr = <field_cache>-type convexit = <field_cache>-convexit_in CHANGING data = <value> offset = offset ).ELSE.restore_type( EXPORTING json = json length = length CHANGING offset = offset ).ENDIF.eat_white.IF offset < length AND json+offset(1) NE `}`.eat_char `,`.eat_white.ELSE.EXIT.ENDIF.ENDWHILE.eat_char `}`.ENDMETHOD.                    "restoreMETHOD restore_type.DATA: mark        LIKE offset,match       LIKE offset,sdummy      TYPE string,                          "#EC NEEDEDrdummy      TYPE REF TO data,                     "#EC NEEDEDpos         LIKE offset,line        TYPE REF TO data,key_ref     TYPE REF TO data,data_ref    TYPE REF TO data,key_name    TYPE string,key_value   TYPE string,lt_fields   LIKE field_cache,lt_symbols  TYPE t_t_symbol,lv_ticks    TYPE string,lv_offset   TYPE string,lv_convexit LIKE convexit,lo_exp      TYPE REF TO cx_root,elem_descr  TYPE REF TO cl_abap_elemdescr,table_descr TYPE REF TO cl_abap_tabledescr,data_descr  TYPE REF TO cl_abap_datadescr.FIELD-SYMBOLS: <line>      TYPE any,<value>     TYPE any,<data>      TYPE data,<field>     LIKE LINE OF lt_fields,<table>     TYPE ANY TABLE,<value_sym> LIKE LINE OF lt_symbols.lv_convexit = convexit.IF type_descr IS INITIAL AND data IS SUPPLIED.type_descr = cl_abap_typedescr=>describe_by_data( data ).IF mv_conversion_exits EQ abap_true AND lv_convexit IS INITIAL AND type_descr->kind EQ cl_abap_typedescr=>kind_elem.elem_descr ?= type_descr.lv_convexit = get_convexit_func( elem_descr = elem_descr input = abap_true ).ENDIF.ENDIF.eat_white.TRY .IF type_descr IS NOT INITIAL AND type_descr->absolute_name EQ mc_json_type." skip deserializationmark = offset.restore_type( EXPORTING json = json length = length CHANGING offset = offset ).match = offset - mark.data = json+mark(match).ENDIF.CASE json+offset(1).WHEN `{`. " objectIF type_descr IS NOT INITIAL.IF mv_assoc_arrays EQ c_bool-true AND type_descr->kind EQ cl_abap_typedescr=>kind_table.table_descr ?= type_descr.data_descr = table_descr->get_table_line_type( ).IF table_descr->has_unique_key IS NOT INITIAL.eat_char `{`.eat_white.IF json+offset(1) NE `}`.ASSIGN data TO <table>.CLEAR <table>.CREATE DATA line LIKE LINE OF <table>.ASSIGN line->* TO <line>.lt_fields = get_fields( type_descr = data_descr data = line ).IF table_descr->key_defkind EQ table_descr->keydefkind_user AND lines( table_descr->key ) EQ 1.READ TABLE table_descr->key INDEX 1 INTO key_name.READ TABLE lt_fields WITH TABLE KEY name = key_name ASSIGNING <field>.key_ref = <field>-value.IF mv_assoc_arrays_opt EQ c_bool-true.lt_symbols = get_symbols( type_descr = data_descr data = line ).DELETE lt_symbols WHERE name EQ key_name.IF lines( lt_symbols ) EQ 1.READ TABLE lt_symbols INDEX 1 ASSIGNING <value_sym>.ENDIF.ENDIF.ENDIF.eat_white.WHILE offset < length AND json+offset(1) NE `}`.CLEAR <line>.eat_name key_value.eat_white.eat_char `:`.eat_white.IF <value_sym> IS ASSIGNED.ASSIGN <value_sym>-value->* TO <value>.restore_type( EXPORTING json = json length = length type_descr = <value_sym>-type convexit = <value_sym>-convexit_inCHANGING data = <value> offset = offset ).ELSE.restore_type( EXPORTING json = json length = length type_descr = data_descr field_cache = lt_fieldsCHANGING data = <line> offset = offset ).ENDIF.IF table_descr->key_defkind EQ table_descr->keydefkind_user.IF key_ref IS BOUND.ASSIGN key_ref->* TO <value>.IF <value> IS INITIAL.<value> = key_value.ENDIF.ENDIF.ELSEIF <line> IS INITIAL.<line> = key_value.ENDIF.INSERT <line> INTO TABLE <table>.eat_white.IF offset < length AND json+offset(1) NE `}`.eat_char `,`.eat_white.ELSE.EXIT.ENDIF.ENDWHILE.ELSE.CLEAR data.ENDIF.eat_char `}`.ELSE.restore( EXPORTING json = json length = length CHANGING  offset = offset ).ENDIF.ELSEIF type_descr->type_kind EQ cl_abap_typedescr=>typekind_dref.IF data IS INITIAL.generate_int_ex( EXPORTING json = json length = length CHANGING offset = offset data = data ).ELSE.data_ref ?= data.type_descr = cl_abap_typedescr=>describe_by_data_ref( data_ref ).ASSIGN data_ref->* TO <data>.restore_type( EXPORTING json = json length = length type_descr = type_descr CHANGING data = <data> offset = offset ).ENDIF.ELSE.restore( EXPORTING json = json length = length type_descr = type_descr field_cache = field_cacheCHANGING data = data offset = offset ).ENDIF.ELSE.restore( EXPORTING json = json length = length CHANGING  offset = offset ).ENDIF.WHEN `[`. " arrayIF type_descr IS NOT INITIAL AND type_descr->type_kind EQ cl_abap_typedescr=>typekind_dref.IF data IS INITIAL.generate_int_ex( EXPORTING json = json length = length CHANGING offset = offset data = data ).ELSE.data_ref ?= data.type_descr = cl_abap_typedescr=>describe_by_data_ref( data_ref ).ASSIGN data_ref->* TO <data>.restore_type( EXPORTING json = json length = length type_descr = type_descr CHANGING data = <data> offset = offset ).ENDIF.ELSE.eat_char `[`.eat_white.IF json+offset(1) NE `]`.IF type_descr IS NOT INITIAL AND type_descr->kind EQ cl_abap_typedescr=>kind_table.table_descr ?= type_descr.data_descr = table_descr->get_table_line_type( ).ASSIGN data TO <table>.CLEAR <table>.CREATE DATA line LIKE LINE OF <table>.ASSIGN line->* TO <line>.lt_fields = get_fields( type_descr = data_descr data = line ).WHILE offset < length AND json+offset(1) NE `]`.CLEAR <line>.restore_type( EXPORTING json = json length = length type_descr = data_descr field_cache = lt_fieldsCHANGING data = <line> offset = offset ).INSERT <line> INTO TABLE <table>.eat_white.IF offset < length AND json+offset(1) NE `]`.eat_char `,`.eat_white.ELSE.EXIT.ENDIF.ENDWHILE.ELSE." skip arrayeat_white.WHILE offset < length AND json+offset(1) NE `]`.restore_type( EXPORTING json = json length = length CHANGING offset = offset ).eat_white.IF offset < length AND json+offset(1) NE `]`.eat_char `,`.eat_white.ELSE.EXIT.ENDIF.ENDWHILE.IF type_descr IS NOT INITIAL.eat_char `]`.throw_error.ENDIF.ENDIF.ELSE.CLEAR data.ENDIF.eat_char `]`.ENDIF.WHEN `"`. " stringeat_string sdummy.IF type_descr IS NOT INITIAL." unescape stringIF sdummy IS NOT INITIAL.IF type_descr->kind EQ cl_abap_typedescr=>kind_elem.elem_descr ?= type_descr.IF lv_convexit IS NOT INITIAL.TRY .CALL FUNCTION lv_convexitEXPORTINGinput         = sdummyIMPORTINGoutput        = dataEXCEPTIONSerror_message = 2OTHERS        = 1.IF sy-subrc IS INITIAL.RETURN.ENDIF.CATCH cx_root.                    "#EC NO_HANDLERENDTRY.ENDIF.CASE elem_descr->type_kind.WHEN cl_abap_typedescr=>typekind_char.IF elem_descr->output_length EQ 1 AND mc_bool_types CS elem_descr->absolute_name.IF sdummy(1) CA `XxTt1`.data = c_bool-true.ELSE.data = c_bool-false.ENDIF.RETURN.ENDIF.WHEN cl_abap_typedescr=>typekind_xstring.string_to_xstring( EXPORTING in = sdummy CHANGING out = data ).RETURN.WHEN cl_abap_typedescr=>typekind_hex." support for Edm.GuidREPLACE FIRST OCCURRENCE OF REGEX `^([0-9A-F]{8})-([0-9A-F]{4})-([0-9A-F]{4})-([0-9A-F]{4})-([0-9A-F]{12})$` IN sdummyWITH `$1$2$3$4$5` REPLACEMENT LENGTH match IGNORING CASE. "#EC NOTEXTIF sy-subrc EQ 0.sdummy = sdummy(match).TRANSLATE sdummy TO UPPER CASE.data = sdummy.ELSE.string_to_xstring( EXPORTING in = sdummy CHANGING out = data ).ENDIF.RETURN.WHEN cl_abap_typedescr=>typekind_date." support for ISO8601 => https://en.wikipedia.org/wiki/ISO_8601REPLACE FIRST OCCURRENCE OF REGEX `^(\d{4})-(\d{2})-(\d{2})` IN sdummy WITH `$1$2$3`REPLACEMENT LENGTH match.             "#EC NOTEXTIF sy-subrc EQ 0.sdummy = sdummy(match).ELSE." support for Edm.DateTime => http://www.odata.org/documentation/odata-version-2-0/json-format/FIND FIRST OCCURRENCE OF REGEX `^\/Date\((-?\d+)([+-]\d{1,4})?\)\/` IN sdummy SUBMATCHES lv_ticks lv_offset IGNORING CASE. "#EC NOTEXTIF sy-subrc EQ 0.sdummy = edm_datetime_to_ts( ticks = lv_ticks offset = lv_offset typekind = elem_descr->type_kind ).ELSE." support for Edm.Time => https://www.w3.org/TR/xmlschema11-2/#nt-durationRepREPLACE FIRST OCCURRENCE OF REGEX `^-?P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)(?:\.(\d+))?S)?)?` IN sdummy WITH `$1$2$3`REPLACEMENT LENGTH match.         "#EC NOTEXTIF sy-subrc EQ 0.sdummy = sdummy(match).ENDIF.ENDIF.ENDIF.WHEN cl_abap_typedescr=>typekind_time." support for ISO8601 => https://en.wikipedia.org/wiki/ISO_8601REPLACE FIRST OCCURRENCE OF REGEX `^(\d{2}):(\d{2}):(\d{2})` IN sdummy WITH `$1$2$3`REPLACEMENT LENGTH match.             "#EC NOTEXTIF sy-subrc EQ 0.sdummy = sdummy(match).ELSE." support for Edm.DateTime => http://www.odata.org/documentation/odata-version-2-0/json-format/FIND FIRST OCCURRENCE OF REGEX '^\/Date\((-?\d+)([+-]\d{1,4})?\)\/' IN sdummy SUBMATCHES lv_ticks lv_offset IGNORING CASE. "#EC NOTEXTIF sy-subrc EQ 0.sdummy = edm_datetime_to_ts( ticks = lv_ticks offset = lv_offset typekind = elem_descr->type_kind ).ELSE." support for Edm.Time => https://www.w3.org/TR/xmlschema11-2/#nt-durationRepREPLACE FIRST OCCURRENCE OF REGEX `^-?P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)(?:\.(\d+))?S)?)?` IN sdummy WITH `$4$5$6`REPLACEMENT LENGTH match.         "#EC NOTEXTIF sy-subrc EQ 0.sdummy = sdummy(match).ENDIF.ENDIF.ENDIF.WHEN cl_abap_typedescr=>typekind_packed.REPLACE FIRST OCCURRENCE OF REGEX `^(\d{4})-?(\d{2})-?(\d{2})T(\d{2}):?(\d{2}):?(\d{2})(?:[\.,](\d{0,7}))?Z?` IN sdummy WITH `$1$2$3$4$5$6.$7`REPLACEMENT LENGTH match.             "#EC NOTEXTIF sy-subrc EQ 0.sdummy = sdummy(match).ELSE.FIND FIRST OCCURRENCE OF REGEX '^\/Date\((-?\d+)([+-]\d{1,4})?\)\/' IN sdummy SUBMATCHES lv_ticks lv_offset IGNORING CASE. "#EC NOTEXTIF sy-subrc EQ 0.sdummy = edm_datetime_to_ts( ticks = lv_ticks offset = lv_offset typekind = elem_descr->type_kind ).ELSE." support for Edm.Time => https://www.w3.org/TR/xmlschema11-2/#nt-durationRepREPLACE FIRST OCCURRENCE OF REGEX `^-?P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)(?:\.(\d+))?S)?)?` IN sdummy WITH `$1$2$3$4$5$6.$7`REPLACEMENT LENGTH match.         "#EC NOTEXTIF sy-subrc EQ 0.sdummy = sdummy(match).ENDIF.ENDIF.ENDIF.WHEN `k`. "cl_abap_typedescr=>typekind_enumTRY.CALL METHOD ('CL_ABAP_XSD')=>('TO_VALUE')EXPORTINGcs  = sdummyCHANGINGval = data.RETURN.CATCH cx_sy_dyn_call_error.throw_error. " Deserialization of enums is not supportedENDTRY.ENDCASE.ELSEIF type_descr->type_kind EQ cl_abap_typedescr=>typekind_dref.CREATE DATA rdummy TYPE string.ASSIGN rdummy->* TO <data>.<data> = sdummy.data ?= rdummy.RETURN.ELSE.throw_error. " Other wise dumps with OBJECTS_MOVE_NOT_SUPPORTEDENDIF.data = sdummy.ELSEIF type_descr->kind EQ cl_abap_typedescr=>kind_elem.CLEAR data.ELSE.throw_error. " Other wise dumps with OBJECTS_MOVE_NOT_SUPPORTEDENDIF.ENDIF.WHEN `-` OR `0` OR `1` OR `2` OR `3` OR `4` OR `5` OR `6` OR `7` OR `8` OR `9`. " numberIF type_descr IS NOT INITIAL.IF type_descr->kind EQ type_descr->kind_ref AND type_descr->type_kind EQ cl_abap_typedescr=>typekind_dref.eat_number sdummy.                          "#EC NOTEXTmatch = strlen( sdummy ).IF sdummy CS '.'. " float.CREATE DATA rdummy TYPE f.ELSEIF match GT 9. " packedCREATE DATA rdummy TYPE p.ELSE. " integerCREATE DATA rdummy TYPE i.ENDIF.ASSIGN rdummy->* TO <data>.<data> = sdummy.data ?= rdummy.ELSEIF type_descr->kind EQ type_descr->kind_elem.IF lv_convexit IS NOT INITIAL.TRY .eat_number sdummy.                    "#EC NOTEXTCALL FUNCTION lv_convexitEXPORTINGinput         = sdummyIMPORTINGoutput        = dataEXCEPTIONSerror_message = 2OTHERS        = 1.IF sy-subrc IS INITIAL.RETURN.ENDIF.CATCH cx_root.                      "#EC NO_HANDLERENDTRY.ENDIF.eat_number data.                            "#EC NOTEXTELSE.eat_number sdummy.                          "#EC NOTEXTthrow_error.ENDIF.ELSE.eat_number sdummy.                            "#EC NOTEXTENDIF.WHEN OTHERS. " boolean, e.g true/false/nullIF type_descr IS NOT INITIAL.IF type_descr->kind EQ type_descr->kind_ref AND type_descr->type_kind EQ cl_abap_typedescr=>typekind_dref.CREATE DATA rdummy TYPE bool.ASSIGN rdummy->* TO <data>.eat_bool <data>.                            "#EC NOTEXTdata ?= rdummy.ELSEIF type_descr->kind EQ type_descr->kind_elem.eat_bool data.                              "#EC NOTEXTELSE.eat_bool sdummy.                            "#EC NOTEXTthrow_error.ENDIF.ELSE.eat_bool sdummy.                              "#EC NOTEXTENDIF.ENDCASE.CATCH cx_sy_move_cast_error cx_sy_conversion_no_number cx_sy_conversion_overflow INTO lo_exp.CLEAR data.IF mv_strict_mode EQ abap_true.RAISE EXCEPTION TYPE cx_sy_move_cast_error EXPORTING previous = lo_exp.ENDIF.ENDTRY.ENDMETHOD.                    "restore_typeMETHOD serialize." **********************************************************************" Usage examples and documentation can be found on SCN:" http://wiki.scn.sap.com/wiki/display/Snippets/One+more+ABAP+to+JSON+Serializer+and+Deserializer" **********************************************************************  "DATA: lo_json  TYPE REF TO zcl_json.CREATE OBJECT lo_jsonEXPORTINGcompress         = compresspretty_name      = pretty_namename_mappings    = name_mappingsassoc_arrays     = assoc_arraysassoc_arrays_opt = assoc_arrays_optexpand_includes  = expand_includesnumc_as_string   = numc_as_stringconversion_exits = conversion_exitsts_as_iso8601    = ts_as_iso8601.r_json = lo_json->serialize_int( name = name data = data type_descr = type_descr ).ENDMETHOD.                    "serializeMETHOD serialize_int." **********************************************************************" Usage examples and documentation can be found on SCN:" http://wiki.scn.sap.com/wiki/display/Snippets/One+more+ABAP+to+JSON+Serializer+and+Deserializer" **********************************************************************  "DATA: lo_descr      TYPE REF TO cl_abap_typedescr,lo_elem_descr TYPE REF TO cl_abap_elemdescr,lv_convexit   TYPE string.IF type_descr IS INITIAL.lo_descr = cl_abap_typedescr=>describe_by_data( data ).ELSE.lo_descr = type_descr.ENDIF.IF mv_conversion_exits EQ abap_true AND lo_descr->kind EQ cl_abap_typedescr=>kind_elem.lo_elem_descr ?= lo_descr.lv_convexit = get_convexit_func( elem_descr = lo_elem_descr input = abap_false ).ENDIF.r_json = dump_int( data = data type_descr = lo_descr convexit = lv_convexit )." we do not do escaping of every single string value for white space characters," but we do it on top, to replace multiple calls by 3 only, while we do not serialize" outlined/formatted JSON this shall not produce any harmREPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>cr_lf          IN r_json WITH `\r\n`.REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>newline        IN r_json WITH `\n`.REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>horizontal_tab IN r_json WITH `\t`.IF name IS NOT INITIAL AND ( mv_compress IS INITIAL OR r_json IS NOT INITIAL ).CONCATENATE `"` name `":` r_json INTO r_json.ENDIF.ENDMETHOD.                    "serializeMETHOD string_to_raw.CALL FUNCTION 'SCMS_STRING_TO_XSTRING'EXPORTINGtext     = iv_stringencoding = iv_encodingIMPORTINGbuffer   = rv_xstringEXCEPTIONSOTHERS   = 1.IF sy-subrc IS NOT INITIAL.CLEAR rv_xstring.ENDIF.ENDMETHOD.METHOD raw_to_string.DATA: lv_output_length TYPE i,lt_binary_tab    TYPE STANDARD TABLE OF sdokcntbin.CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'EXPORTINGbuffer        = iv_xstringIMPORTINGoutput_length = lv_output_lengthTABLESbinary_tab    = lt_binary_tab.CALL FUNCTION 'SCMS_BINARY_TO_STRING'EXPORTINGinput_length  = lv_output_lengthencoding      = iv_encodingIMPORTINGtext_buffer   = rv_stringoutput_length = lv_output_lengthTABLESbinary_tab    = lt_binary_tab.ENDMETHOD.METHOD string_to_xstring.DATA: lv_xstring TYPE xstring.CALL FUNCTION 'SSFC_BASE64_DECODE'EXPORTINGb64data = inIMPORTINGbindata = lv_xstringEXCEPTIONSOTHERS  = 1.IF sy-subrc IS INITIAL.out = lv_xstring.ELSE.out = in.ENDIF.ENDMETHOD.                    "string_to_xstringMETHOD xstring_to_string.DATA: lv_xstring TYPE xstring." let us fix data conversion issues herelv_xstring = in.CALL FUNCTION 'SSFC_BASE64_ENCODE'EXPORTINGbindata = lv_xstringIMPORTINGb64data = outEXCEPTIONSOTHERS  = 1.IF sy-subrc IS NOT INITIAL.out = in.ENDIF.ENDMETHOD.                    "xstring_to_stringMETHOD tribool_to_bool.IF iv_tribool EQ c_tribool-true.rv_bool = c_bool-true.ELSEIF iv_tribool EQ c_tribool-undefined.rv_bool = abap_undefined. " fall back to abap_undefinedENDIF.ENDMETHOD.                    "TRIBOOL_TO_BOOLMETHOD unescape.DATA: lv_offset          TYPE i,lv_match           TYPE i,lv_delta           TYPE i,lv_length          TYPE i,lv_offset_e        TYPE i,lv_length_e        TYPE i,lv_unicode_symb    TYPE c,lv_unicode_escaped TYPE string,lt_matches         TYPE match_result_tab.FIELD-SYMBOLS: <match> LIKE LINE OF lt_matches." see reference for escaping rules in JSON RFC" https://www.ietf.org/rfc/rfc4627.txtunescaped = escaped.lv_length = strlen( unescaped ).FIND FIRST OCCURRENCE OF REGEX `\\[rntfbu]` IN unescaped RESPECTING CASE.IF sy-subrc IS INITIAL.FIND ALL OCCURRENCES OF REGEX `\\.` IN unescaped RESULTS lt_matches RESPECTING CASE.LOOP AT lt_matches ASSIGNING <match>.lv_match  = <match>-offset - lv_delta.lv_offset = lv_match + 1.CASE unescaped+lv_offset(1).WHEN `r`.REPLACE SECTION OFFSET lv_match LENGTH 2 OF unescaped WITH cl_abap_char_utilities=>cr_lf(1).lv_delta = lv_delta + 1.WHEN `n`.REPLACE SECTION OFFSET lv_match LENGTH 2 OF unescaped WITH cl_abap_char_utilities=>newline.lv_delta = lv_delta + 1.WHEN `t`.REPLACE SECTION OFFSET lv_match LENGTH 2 OF unescaped WITH cl_abap_char_utilities=>horizontal_tab.lv_delta = lv_delta + 1.WHEN `f`.REPLACE SECTION OFFSET lv_match LENGTH 2 OF unescaped WITH cl_abap_char_utilities=>form_feed.lv_delta = lv_delta + 1.WHEN `b`.REPLACE SECTION OFFSET lv_match LENGTH 2 OF unescaped WITH cl_abap_char_utilities=>backspace.lv_delta = lv_delta + 1.WHEN `u`.lv_offset   = lv_offset + 1.lv_offset_e = lv_offset + 4.lv_length_e = lv_length + lv_delta.IF lv_offset_e LE lv_length_e.lv_unicode_escaped = unescaped+lv_offset(4).TRANSLATE lv_unicode_escaped TO UPPER CASE.lv_unicode_symb = cl_abap_conv_in_ce=>uccp( lv_unicode_escaped ).IF lv_unicode_symb NE mc_cov_error.REPLACE SECTION OFFSET lv_match LENGTH 6 OF unescaped WITH lv_unicode_symb.lv_delta = lv_delta + 5.ENDIF.ENDIF.ENDCASE.ENDLOOP.ENDIF." based on RFC mentioned above, _any_ character can be escaped, and so shall be enscaped" the only exception is Unicode symbols, that shall be kept untouched, while serializer does not handle them" unescaped singe characters, e.g \\, \", \/ etcREPLACE ALL OCCURRENCES OF REGEX `\\(.)` IN unescaped WITH `$1` RESPECTING CASE.ENDMETHOD.
ENDCLASS.

然后输入事务代码se24,左上角对象类型->导入->程序中的局部类

输入程序名,记得激活源程序,否则不会显示类

左边是源程序里的,右边是要新建的类名,重命名一下,我命名的是ZCL_JSON,记得要Z开头,否则系统判定是要建立系统类,需要输入键值

导入后还不能直接用,因为他这个不会导入宏定义,需要手动导入,宏定义的代码如下:

DEFINE ESCAPE_JSON_INPLACE.
*  replace all occurrences of regex `[\\"]` in &1 with `\\$0`. <-- this is slower than 2 plain replacesREPLACE ALL OCCURRENCES OF `\` IN &1 WITH `\\`.REPLACE ALL OCCURRENCES OF `"` IN &1 WITH `\"`.
END-OF-DEFINITION.
DEFINE ESCAPE_JSON.&2 = &1.ESCAPE_JSON_INPLACE &2.
END-OF-DEFINITION.
DEFINE IS_COMPRESSABLE.IF MV_EXTENDED IS INITIAL.&3 = ABAP_TRUE.ELSE.&3 = IS_COMPRESSABLE( TYPE_DESCR = &1 NAME = &2 ).ENDIF.
END-OF-DEFINITION.
DEFINE DUMP_TYPE.IF MV_EXTENDED IS INITIAL.DUMP_TYPE_INT &1 &2 &3 &4.ELSE.&3 = DUMP_TYPE( DATA = &1 TYPE_DESCR = &2 CONVEXIT = &4 ).ENDIF.
END-OF-DEFINITION.
DEFINE DUMP_TYPE_INT.IF &4 IS NOT INITIAL AND &1 IS NOT INITIAL.TRY.CALL FUNCTION &4EXPORTINGINPUT    = &1IMPORTINGOUTPUT   = &3EXCEPTIONSOTHERS   = 1.IF SY-SUBRC IS INITIAL.CONCATENATE `"` &3 `"` INTO &3.ENDIF.CATCH CX_ROOT.                                    "#EC NO_HANDLERENDTRY.ELSE.CASE &2->TYPE_KIND.WHEN CL_ABAP_TYPEDESCR=>TYPEKIND_FLOAT OR CL_ABAP_TYPEDESCR=>TYPEKIND_INT OR CL_ABAP_TYPEDESCR=>TYPEKIND_INT1 ORCL_ABAP_TYPEDESCR=>TYPEKIND_INT2 OR CL_ABAP_TYPEDESCR=>TYPEKIND_PACKED OR `8`. " TYPEKIND_INT8 -> '8' only from 7.40.IF &2->TYPE_KIND EQ CL_ABAP_TYPEDESCR=>TYPEKIND_PACKED AND MV_TS_AS_ISO8601 EQ C_BOOL-TRUE AND &2->ABSOLUTE_NAME CP `\TYPE=TIMESTAMP*`.IF &1 IS INITIAL.&3 = `""`.ELSE.&3 = &1.IF &2->ABSOLUTE_NAME EQ `\TYPE=TIMESTAMP`.CONCATENATE `"` &3(4) `-` &3+4(2) `-` &3+6(2) `T` &3+8(2) `:` &3+10(2) `:` &3+12(2) `.0000000Z"`  INTO &3.ELSEIF &2->ABSOLUTE_NAME EQ `\TYPE=TIMESTAMPL`.CONCATENATE `"` &3(4) `-` &3+4(2) `-` &3+6(2) `T` &3+8(2) `:` &3+10(2) `:` &3+12(2) `.` &3+15(7) `Z"`  INTO &3.ENDIF.ENDIF.ELSEIF &1 IS INITIAL.&3 = `0`.ELSE.&3 = &1.IF &1 LT 0.IF &2->TYPE_KIND <> CL_ABAP_TYPEDESCR=>TYPEKIND_FLOAT. "float: sign is already at the beginningSHIFT &3 RIGHT CIRCULAR.ENDIF.ELSE.CONDENSE &3.ENDIF.ENDIF.WHEN CL_ABAP_TYPEDESCR=>TYPEKIND_NUM.IF MV_NUMC_AS_STRING EQ ABAP_TRUE.IF &1 IS INITIAL.&3 = `""`.ELSE.CONCATENATE `"` &1 `"` INTO &3.ENDIF.ELSE.&3 = &1.SHIFT &3 LEFT DELETING LEADING ` 0`.IF &3 IS INITIAL.&3 = `0`.ENDIF.ENDIF.WHEN CL_ABAP_TYPEDESCR=>TYPEKIND_STRING OR CL_ABAP_TYPEDESCR=>TYPEKIND_CSEQUENCE OR CL_ABAP_TYPEDESCR=>TYPEKIND_CLIKE.IF &1 IS INITIAL.&3 = `""`.ELSEIF &2->ABSOLUTE_NAME EQ MC_JSON_TYPE.&3 = &1.ELSE.ESCAPE_JSON &1 &3.CONCATENATE `"` &3 `"` INTO &3.ENDIF.WHEN CL_ABAP_TYPEDESCR=>TYPEKIND_XSTRING OR CL_ABAP_TYPEDESCR=>TYPEKIND_HEX.IF &1 IS INITIAL.&3 = `""`.ELSE.&3 = XSTRING_TO_STRING( &1 ).ESCAPE_JSON_INPLACE &3.CONCATENATE `"` &3 `"` INTO &3.ENDIF.WHEN CL_ABAP_TYPEDESCR=>TYPEKIND_CHAR.IF &2->OUTPUT_LENGTH EQ 1 AND MC_BOOL_TYPES CS &2->ABSOLUTE_NAME.IF &1 EQ C_BOOL-TRUE.&3 = `true`.                                    "#EC NOTEXTELSEIF MC_BOOL_3STATE CS &2->ABSOLUTE_NAME AND &1 IS INITIAL.&3 = `null`.                                    "#EC NOTEXTELSE.&3 = `false`.                                   "#EC NOTEXTENDIF.ELSE.ESCAPE_JSON &1 &3.CONCATENATE `"` &3 `"` INTO &3.ENDIF.WHEN CL_ABAP_TYPEDESCR=>TYPEKIND_DATE.CONCATENATE `"` &1(4) `-` &1+4(2) `-` &1+6(2) `"` INTO &3.WHEN CL_ABAP_TYPEDESCR=>TYPEKIND_TIME.CONCATENATE `"` &1(2) `:` &1+2(2) `:` &1+4(2) `"` INTO &3.WHEN `k`. " cl_abap_typedescr=>typekind_enum&3 = &1.CONCATENATE `"` &3 `"` INTO &3.WHEN OTHERS.IF &1 IS INITIAL.&3 = `null`.                                      "#EC NOTEXTELSE.&3 = &1.ENDIF.ENDCASE.ENDIF.
END-OF-DEFINITION.
DEFINE FORMAT_NAME.CASE &2.WHEN PRETTY_MODE-CAMEL_CASE.&3 = PRETTY_NAME( &1 ).WHEN PRETTY_MODE-EXTENDED.&3 = PRETTY_NAME_EX( &1 ).WHEN PRETTY_MODE-USER_LOW_CASE.READ TABLE MT_NAME_MAPPINGS WITH TABLE KEY ABAP = &1 ASSIGNING <CACHE>. "#EC WARNOKIF SY-SUBRC IS INITIAL.&3 = <CACHE>-JSON.ELSE.&3 = &1.TRANSLATE &3 TO LOWER CASE.                       "#EC SYNTCHARENDIF.WHEN PRETTY_MODE-USER.READ TABLE MT_NAME_MAPPINGS WITH TABLE KEY ABAP = &1 ASSIGNING <CACHE>. "#EC WARNOKIF SY-SUBRC IS INITIAL.&3 = <CACHE>-JSON.ELSE.&3 = &1.ENDIF.WHEN PRETTY_MODE-LOW_CASE.&3 = &1.TRANSLATE &3 TO LOWER CASE.                         "#EC SYNTCHARWHEN OTHERS.&3 = &1.ENDCASE.
END-OF-DEFINITION.
DEFINE THROW_ERROR.RAISE EXCEPTION TYPE CX_SY_MOVE_CAST_ERROR.
END-OF-DEFINITION.
DEFINE WHILE_OFFSET_CS.
*  >= 7.02 alternative
*  pos = find_any_not_of( val = json sub = &1 off = offset ).
*  if pos eq -1. offset = length.
*  else. offset = pos. endif.
* < 7.02WHILE OFFSET < LENGTH.FIND FIRST OCCURRENCE OF JSON+OFFSET(1) IN &1.IF SY-SUBRC IS NOT INITIAL.EXIT.ENDIF.OFFSET = OFFSET + 1.ENDWHILE.
* < 7.02
END-OF-DEFINITION.
DEFINE WHILE_OFFSET_NOT_CS.WHILE OFFSET < LENGTH.FIND FIRST OCCURRENCE OF &2+OFFSET(1) IN &1.IF SY-SUBRC IS INITIAL.EXIT.ENDIF.OFFSET = OFFSET + 1.ENDWHILE.
END-OF-DEFINITION.
DEFINE EAT_WHITE.WHILE_OFFSET_CS SV_WHITE_SPACE.IF OFFSET GE LENGTH.THROW_ERROR.ENDIF.
END-OF-DEFINITION.
DEFINE EAT_NAME.IF JSON+OFFSET(1) EQ `"`.MARK   = OFFSET + 1.OFFSET = MARK.FIND FIRST OCCURRENCE OF `"` IN SECTION OFFSET OFFSET OF JSON MATCH OFFSET OFFSET.IF SY-SUBRC IS NOT INITIAL.THROW_ERROR.ENDIF.MATCH = OFFSET - MARK.&1 = JSON+MARK(MATCH).OFFSET = OFFSET + 1.ELSE.THROW_ERROR.ENDIF.
END-OF-DEFINITION.
DEFINE EAT_STRING.IF JSON+OFFSET(1) EQ `"`.MARK   = OFFSET + 1.OFFSET = MARK.DO.FIND FIRST OCCURRENCE OF `"` IN SECTION OFFSET OFFSET OF JSON MATCH OFFSET POS.IF SY-SUBRC IS NOT INITIAL.THROW_ERROR.ENDIF.OFFSET = POS.POS = POS - 1." if escaped search furtherWHILE POS GE 0 AND JSON+POS(1) EQ `\`.POS = POS - 1.ENDWHILE.MATCH = ( OFFSET - POS ) MOD 2.IF MATCH NE 0.EXIT.ENDIF.OFFSET = OFFSET + 1.ENDDO.MATCH = OFFSET - MARK.&1 = JSON+MARK(MATCH)." unescaped singe characters, e.g \\, \", \/ etc," BUT ONLY if someone really need the dataIF TYPE_DESCR IS NOT INITIAL.&1 = UNESCAPE( &1 ).ENDIF.OFFSET = OFFSET + 1.ELSE.THROW_ERROR.ENDIF.
END-OF-DEFINITION.
DEFINE EAT_NUMBER.MARK   = OFFSET.WHILE_OFFSET_CS `0123456789+-eE.`.                        "#EC NOTEXTMATCH = OFFSET - MARK.&1 = JSON+MARK(MATCH).
END-OF-DEFINITION.
DEFINE EAT_BOOL.MARK   = OFFSET.WHILE_OFFSET_CS `aeflnrstu`.                              "#EC NOTEXTMATCH = OFFSET - MARK.IF JSON+MARK(MATCH) EQ `true`.                            "#EC NOTEXT&1 = C_BOOL-TRUE.
ELSEIF JSON+MARK(MATCH) EQ `false`.                       "#EC NOTEXTIF TYPE_DESCR IS BOUND AND MC_BOOL_3STATE CS TYPE_DESCR->ABSOLUTE_NAME.&1 = C_TRIBOOL-FALSE.ELSE.&1 = C_BOOL-FALSE.ENDIF.
ELSEIF JSON+MARK(MATCH) EQ `null`.                        "#EC NOTEXTCLEAR &1.ENDIF.
END-OF-DEFINITION.
DEFINE EAT_CHAR.IF OFFSET < LENGTH AND JSON+OFFSET(1) EQ &1.OFFSET = OFFSET + 1.ELSE.THROW_ERROR.ENDIF.
END-OF-DEFINITION.

激活后就可以使用了。

这里在说一下ui2类的使用技巧,CALL TRANSFORMATION id解析json数据的方式的,列如json格式是这样的

{"IT_ITEM": [{"ZNO": "","POSNR": "","MATNR": "","MENGE": "","MEINS": "","EINDT":"","UMSON": "","EBELP": "","POSNR_VL": "","POSNR_VF": "","MAKTX": "","SERNP": "","GERNR": ""}],"IT_GERNR": [],"IT_LTEXT": [],"CS_HEAD": {"ZNO": "","BSART": "","MWSKZ": "","EKORG": "","EKGRP": "","UMWRK": "","UMLGO": "","WERKS": "","LGORT": "","BWART": "","BKTXT": "","EBELN": "","VBELN_VL": "","VBELN_VF": "","MBLNR": "","MJAHR": "","BUKRS": "","LIFNR": "","RETPO": "","STATUS": "","ZZMSG": "","CRUSR": "","CRDAT": "","CRTIM": "","CHUSR": "","CHDAT": "","CHTIM": "",		"C_SEL": "","ICON": "","OPER01": "","OPER02": "","STATUS_TXT": "","CRUSR_TXT": "","CHUSR_TXT": "","EKORG_TXT": "","EKGRP_TXT": "","WERKS_TXT": "","UMWRK_TXT": "","LGORT_TXT": "","UMLGO_TXT": "","ERROR": "","REMARK": ""}
}

一个键值代表一个表数据,如果让CALL TRANSFORMATION ID来做的话就是这样

  DATA: GT_8101  TYPE TABLE OF ZMMT001D       ,GT_8200  TYPE TABLE OF ZMMS_STO_ITEM  ,GT_GERNR TYPE TABLE OF ZMMS_STO_GERNR ,GS_HEAD  TYPE ZMMS_STO_HEAD.TRY.CALL TRANSFORMATION IDSOURCE XML LV_JSONRESULTCS_HEAD = GS_HEADIT_LTEXT = GT_8101IT_ITEM = GT_8200IT_GERNR = GT_GERNR.CATCH CX_TRANSFORMATION_ERROR INTO ERROR.ERR_TEXT = ERROR->GET_TEXT( ).LV_STATUS = '500'.LV_MESSAGE = ERR_TEXT.ENDTRY.

V_JSON是要解析的json数据,注意表结构要和json里的结果完全一致。

如果要用ui2来达到CALL TRANSFORMATION ID的效果,则要这样做

	DATA: BEGIN OF LS_JSON,IT_LTEXT  TYPE TABLE OF ZMMT001D       ,IT_ITEM  TYPE TABLE OF ZMMS_STO_ITEM  ,IT_GERNR TYPE TABLE OF ZMMS_STO_GERNR ,CS_HEAD  TYPE ZMMS_STO_HEAD,END OF LS_JSON.DATA: GT_8101  TYPE TABLE OF ZMMT001D       ,GT_8200  TYPE TABLE OF ZMMS_STO_ITEM  ,GT_GERNR TYPE TABLE OF ZMMS_STO_GERNR ,GS_HEAD  TYPE ZMMS_STO_HEAD.ZCL_JSON=>DESERIALIZE( EXPORTING JSON = LV_JSONPRETTY_NAME = ZCL_JSON=>PRETTY_MODE-CAMEL_CASECHANGING DATA = LS_JSON ).IF LS_JSON-IT_LTEXT IS NOT INITIAL.GT_8101[] = LS_JSON-IT_LTEXT.ENDIF.IF LS_JSON-IT_GERNR IS NOT INITIAL.GT_GERNR[] = LS_JSON-IT_GERNR.ENDIF.IF LS_JSON-IT_ITEM IS NOT INITIAL.GT_8200[] = LS_JSON-IT_ITEM.ENDIF.IF LS_JSON-CS_HEAD IS NOT INITIAL.GS_HEAD = LS_JSON-CS_HEAD.ENDIF.

先把数据解析到结构体里,再分别将表数据赋值给定义好的表。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com