summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt12
-rw-r--r--Makefile.dibs37
-rwxr-xr-xREADME.md1310
-rw-r--r--idlc/CMakeLists.txt13
-rw-r--r--idlc/ast/attribute.cc27
-rw-r--r--idlc/ast/attribute.h13
-rw-r--r--idlc/ast/block.cc13
-rw-r--r--idlc/ast/block.h12
-rw-r--r--idlc/ast/declaration.cc38
-rw-r--r--idlc/ast/declaration.h21
-rw-r--r--idlc/ast/document.cc11
-rw-r--r--idlc/ast/document.h6
-rw-r--r--idlc/ast/element.cc29
-rw-r--r--idlc/ast/element.h22
-rwxr-xr-xidlc/ast/enum.cc97
-rwxr-xr-xidlc/ast/enum.h84
-rw-r--r--idlc/ast/interface.cc6
-rw-r--r--idlc/ast/interface.h4
-rw-r--r--idlc/ast/location.hh179
-rw-r--r--idlc/ast/parameter.cc26
-rw-r--r--idlc/ast/parameter.h13
-rw-r--r--idlc/ast/parser.cc48
-rw-r--r--idlc/ast/parser.h19
-rw-r--r--idlc/ast/position.hh176
-rw-r--r--idlc/ast/preprocessor.cc206
-rw-r--r--idlc/ast/preprocessor.h65
-rw-r--r--idlc/ast/structure.cc83
-rw-r--r--idlc/ast/structure.h16
-rw-r--r--idlc/ast/tidlc.ll41
-rw-r--r--idlc/ast/tidlc.yy521
-rw-r--r--idlc/ast/tidlc_l.cpp863
-rw-r--r--idlc/ast/tidlc_y.cpp2943
-rw-r--r--idlc/ast/tidlc_y.hpp340
-rw-r--r--idlc/ast/type.cc173
-rw-r--r--idlc/ast/type.h65
-rw-r--r--idlc/cion_generator.cc308
-rw-r--r--idlc/cion_generator.hh84
-rw-r--r--idlc/code_generator.hh46
-rw-r--r--idlc/default_generator.cc200
-rw-r--r--idlc/default_generator.hh62
-rw-r--r--idlc/gen/c_body_gen_array_base_cb.h371
-rw-r--r--idlc/gen/c_body_gen_base.cc1635
-rw-r--r--idlc/gen/c_body_gen_base.h80
-rw-r--r--idlc/gen/c_body_gen_base_cb.h815
-rw-r--r--idlc/gen/c_body_gen_list_base_cb.h446
-rw-r--r--idlc/gen/c_gen_base.cc510
-rw-r--r--idlc/gen/c_gen_base.h49
-rw-r--r--idlc/gen/c_gen_base_cb.h18
-rw-r--r--idlc/gen/c_group_body_gen.cc530
-rw-r--r--idlc/gen/c_group_body_gen.h81
-rw-r--r--idlc/gen/c_group_body_gen_cb.h581
-rw-r--r--idlc/gen/c_group_header_gen.cc186
-rw-r--r--idlc/gen/c_group_header_gen.h55
-rw-r--r--idlc/gen/c_group_header_gen_cb.h158
-rw-r--r--idlc/gen/c_header_gen_base.cc355
-rw-r--r--idlc/gen/c_header_gen_base.h20
-rw-r--r--idlc/gen/c_header_gen_base_cb.h323
-rw-r--r--idlc/gen/c_proxy_body_gen.cc1016
-rw-r--r--idlc/gen/c_proxy_body_gen.h105
-rw-r--r--idlc/gen/c_proxy_body_gen_cb.h1259
-rw-r--r--idlc/gen/c_proxy_header_gen.cc221
-rw-r--r--idlc/gen/c_proxy_header_gen.h28
-rw-r--r--idlc/gen/c_proxy_header_gen_cb.h340
-rw-r--r--idlc/gen/c_stub_body_gen.cc1179
-rw-r--r--idlc/gen/c_stub_body_gen.h116
-rw-r--r--idlc/gen/c_stub_body_gen_cb.h1539
-rw-r--r--idlc/gen/c_stub_header_gen.cc286
-rw-r--r--idlc/gen/c_stub_header_gen.h54
-rw-r--r--idlc/gen/c_stub_header_gen_cb.h361
-rw-r--r--idlc/gen/cpp_gen_base.cc621
-rw-r--r--idlc/gen/cpp_gen_base.h18
-rw-r--r--idlc/gen/cpp_gen_base_cb.h146
-rw-r--r--idlc/gen/cpp_group_body_gen.cc196
-rw-r--r--idlc/gen/cpp_group_body_gen.h51
-rw-r--r--idlc/gen/cpp_group_body_gen_cb.h172
-rw-r--r--idlc/gen/cpp_group_header_gen.cc84
-rw-r--r--idlc/gen/cpp_group_header_gen.h45
-rw-r--r--idlc/gen/cpp_group_header_gen_cb.h97
-rw-r--r--idlc/gen/cpp_proxy_body_gen.cc153
-rw-r--r--idlc/gen/cpp_proxy_body_gen.h3
-rw-r--r--idlc/gen/cpp_proxy_body_gen_cb.h84
-rw-r--r--idlc/gen/cpp_proxy_header_gen.cc6
-rw-r--r--idlc/gen/cpp_proxy_header_gen_cb.h8
-rw-r--r--idlc/gen/cpp_stub_body_gen.cc44
-rw-r--r--idlc/gen/cpp_stub_body_gen_cb.h59
-rw-r--r--idlc/gen/cpp_stub_header_gen.cc6
-rw-r--r--idlc/gen/cpp_stub_header_gen_cb.h21
-rw-r--r--idlc/gen/cs_gen_base.cc267
-rw-r--r--idlc/gen/cs_gen_base.h6
-rw-r--r--idlc/gen/cs_gen_base_cb.h51
-rw-r--r--idlc/gen/cs_group_gen.cc155
-rw-r--r--idlc/gen/cs_group_gen.h48
-rw-r--r--idlc/gen/cs_group_gen_cb.h150
-rw-r--r--idlc/gen/cs_proxy_gen.cc37
-rw-r--r--idlc/gen/cs_proxy_gen_cb.h75
-rw-r--r--idlc/gen/cs_stub_gen.cc16
-rw-r--r--idlc/gen/cs_stub_gen_cb.h43
-rw-r--r--idlc/gen/dart_gen_base.cc596
-rw-r--r--idlc/gen/dart_gen_base.h79
-rw-r--r--idlc/gen/dart_gen_base_cb.h307
-rw-r--r--idlc/gen/dart_proxy_gen.cc352
-rw-r--r--idlc/gen/dart_proxy_gen.h60
-rw-r--r--idlc/gen/dart_proxy_gen_cb.h169
-rw-r--r--idlc/gen/dart_stub_gen.cc381
-rw-r--r--idlc/gen/dart_stub_gen.h56
-rw-r--r--idlc/gen/dart_stub_gen_cb.h238
-rw-r--r--idlc/gen/generator.cc53
-rw-r--r--idlc/gen/generator.h39
-rw-r--r--idlc/gen/replace_all.cc128
-rwxr-xr-xidlc/gen/replace_all.h136
-rw-r--r--idlc/gen/version2/c_body_generator_array_base_cb.hh371
-rw-r--r--idlc/gen/version2/c_body_generator_base.cc1511
-rw-r--r--idlc/gen/version2/c_body_generator_base.hh133
-rw-r--r--idlc/gen/version2/c_body_generator_base_cb.hh1279
-rw-r--r--idlc/gen/version2/c_body_generator_list_base_cb.hh491
-rw-r--r--idlc/gen/version2/c_body_generator_map_base_cb.hh816
-rw-r--r--idlc/gen/version2/c_body_generator_set_base_cb.hh528
-rw-r--r--idlc/gen/version2/c_group_body_generator.cc516
-rw-r--r--idlc/gen/version2/c_group_body_generator.hh82
-rw-r--r--idlc/gen/version2/c_group_body_generator_cb.hh668
-rw-r--r--idlc/gen/version2/c_group_header_generator.cc189
-rw-r--r--idlc/gen/version2/c_group_header_generator.hh57
-rw-r--r--idlc/gen/version2/c_group_header_generator_cb.hh158
-rw-r--r--idlc/gen/version2/c_header_generator_array_base_cb.hh111
-rw-r--r--idlc/gen/version2/c_header_generator_base.cc279
-rw-r--r--idlc/gen/version2/c_header_generator_base.hh52
-rw-r--r--idlc/gen/version2/c_header_generator_base_cb.hh280
-rw-r--r--idlc/gen/version2/c_header_generator_list_base_cb.hh145
-rw-r--r--idlc/gen/version2/c_header_generator_map_base_cb.hh209
-rw-r--r--idlc/gen/version2/c_header_generator_set_base_cb.hh173
-rw-r--r--idlc/gen/version2/c_proxy_body_generator.cc638
-rw-r--r--idlc/gen/version2/c_proxy_body_generator.hh98
-rw-r--r--idlc/gen/version2/c_proxy_body_generator_cb.hh1729
-rw-r--r--idlc/gen/version2/c_proxy_header_generator.cc172
-rw-r--r--idlc/gen/version2/c_proxy_header_generator.hh57
-rw-r--r--idlc/gen/version2/c_proxy_header_generator_cb.hh346
-rw-r--r--idlc/gen/version2/c_stub_body_generator.cc800
-rw-r--r--idlc/gen/version2/c_stub_body_generator.hh118
-rw-r--r--idlc/gen/version2/c_stub_body_generator_cb.hh2326
-rw-r--r--idlc/gen/version2/c_stub_header_generator.cc228
-rw-r--r--idlc/gen/version2/c_stub_header_generator.hh65
-rw-r--r--idlc/gen/version2/c_stub_header_generator_cb.hh374
-rw-r--r--idlc/gen/version2/cpp_generator_base.cc1045
-rw-r--r--idlc/gen/version2/cpp_generator_base.hh112
-rw-r--r--idlc/gen/version2/cpp_generator_base_cb.hh1040
-rw-r--r--idlc/gen/version2/cpp_group_body_generator.cc162
-rw-r--r--idlc/gen/version2/cpp_group_body_generator.hh52
-rw-r--r--idlc/gen/version2/cpp_group_body_generator_cb.hh238
-rw-r--r--idlc/gen/version2/cpp_group_header_generator.cc94
-rw-r--r--idlc/gen/version2/cpp_group_header_generator.hh47
-rw-r--r--idlc/gen/version2/cpp_group_header_generator_cb.hh119
-rw-r--r--idlc/gen/version2/cpp_proxy_body_generator.cc248
-rw-r--r--idlc/gen/version2/cpp_proxy_body_generator.hh62
-rw-r--r--idlc/gen/version2/cpp_proxy_body_generator_cb.hh718
-rw-r--r--idlc/gen/version2/cpp_proxy_header_generator.cc122
-rw-r--r--idlc/gen/version2/cpp_proxy_header_generator.hh54
-rw-r--r--idlc/gen/version2/cpp_proxy_header_generator_cb.hh243
-rw-r--r--idlc/gen/version2/cpp_stub_body_generator.cc348
-rw-r--r--idlc/gen/version2/cpp_stub_body_generator.hh69
-rw-r--r--idlc/gen/version2/cpp_stub_body_generator_cb.hh757
-rw-r--r--idlc/gen/version2/cpp_stub_header_generator.cc154
-rw-r--r--idlc/gen/version2/cpp_stub_header_generator.hh56
-rw-r--r--idlc/gen/version2/cpp_stub_header_generator_cb.hh448
-rw-r--r--idlc/gen/version2/cs_generator_base.cc867
-rw-r--r--idlc/gen/version2/cs_generator_base.h123
-rw-r--r--idlc/gen/version2/cs_generator_base_cb.h416
-rw-r--r--idlc/gen/version2/cs_group_generator.cc163
-rw-r--r--idlc/gen/version2/cs_group_generator.h50
-rw-r--r--idlc/gen/version2/cs_group_generator_cb.h153
-rw-r--r--idlc/gen/version2/cs_proxy_generator.cc225
-rw-r--r--idlc/gen/version2/cs_proxy_generator.h52
-rw-r--r--idlc/gen/version2/cs_proxy_generator_cb.h497
-rw-r--r--idlc/gen/version2/cs_stub_generator.cc287
-rw-r--r--idlc/gen/version2/cs_stub_generator.h60
-rw-r--r--idlc/gen/version2/cs_stub_generator_cb.h440
-rw-r--r--idlc/gen_cion/c_cion_body_gen_array_base_cb.h371
-rw-r--r--idlc/gen_cion/c_cion_body_gen_base.cc917
-rw-r--r--idlc/gen_cion/c_cion_body_gen_base.h102
-rw-r--r--idlc/gen_cion/c_cion_body_gen_base_cb.h678
-rw-r--r--idlc/gen_cion/c_cion_body_gen_list_base_cb.h446
-rw-r--r--idlc/gen_cion/c_cion_gen_base.cc509
-rw-r--r--idlc/gen_cion/c_cion_gen_base.h77
-rw-r--r--idlc/gen_cion/c_cion_gen_base_cb.h58
-rw-r--r--idlc/gen_cion/c_cion_group_body_gen.cc552
-rw-r--r--idlc/gen_cion/c_cion_group_body_gen.h83
-rw-r--r--idlc/gen_cion/c_cion_group_body_gen_cb.h516
-rw-r--r--idlc/gen_cion/c_cion_group_header_gen.cc208
-rw-r--r--idlc/gen_cion/c_cion_group_header_gen.h56
-rw-r--r--idlc/gen_cion/c_cion_group_header_gen_cb.h159
-rw-r--r--idlc/gen_cion/c_cion_header_gen_base.cc235
-rw-r--r--idlc/gen_cion/c_cion_header_gen_base.h55
-rw-r--r--idlc/gen_cion/c_cion_header_gen_base_cb.h343
-rw-r--r--idlc/gen_cion/c_cion_proxy_body_gen.cc658
-rw-r--r--idlc/gen_cion/c_cion_proxy_body_gen.h88
-rw-r--r--idlc/gen_cion/c_cion_proxy_body_gen_cb.h981
-rw-r--r--idlc/gen_cion/c_cion_proxy_header_gen.cc192
-rw-r--r--idlc/gen_cion/c_cion_proxy_header_gen.h56
-rw-r--r--idlc/gen_cion/c_cion_proxy_header_gen_cb.h425
-rw-r--r--idlc/gen_cion/c_cion_stub_body_gen.cc712
-rw-r--r--idlc/gen_cion/c_cion_stub_body_gen.h92
-rw-r--r--idlc/gen_cion/c_cion_stub_body_gen_cb.h854
-rw-r--r--idlc/gen_cion/c_cion_stub_header_gen.cc224
-rw-r--r--idlc/gen_cion/c_cion_stub_header_gen.h59
-rw-r--r--idlc/gen_cion/c_cion_stub_header_gen_cb.h397
-rw-r--r--idlc/gen_cion/c_transportable.h100
-rw-r--r--idlc/gen_cion/cion_plugin_base.cc34
-rw-r--r--idlc/gen_cion/cion_plugin_base.h40
-rw-r--r--idlc/gen_cion/cpp_cion_gen_base.cc925
-rw-r--r--idlc/gen_cion/cpp_cion_gen_base.h109
-rw-r--r--idlc/gen_cion/cpp_cion_gen_base_cb.h282
-rw-r--r--idlc/gen_cion/cpp_cion_group_body_gen.cc223
-rw-r--r--idlc/gen_cion/cpp_cion_group_body_gen.h52
-rw-r--r--idlc/gen_cion/cpp_cion_group_body_gen_cb.h103
-rw-r--r--idlc/gen_cion/cpp_cion_group_header_gen.cc141
-rw-r--r--idlc/gen_cion/cpp_cion_group_header_gen.h48
-rw-r--r--idlc/gen_cion/cpp_cion_group_header_gen_cb.h87
-rw-r--r--idlc/gen_cion/cpp_cion_proxy_body_gen.cc307
-rw-r--r--idlc/gen_cion/cpp_cion_proxy_body_gen.h53
-rw-r--r--idlc/gen_cion/cpp_cion_proxy_body_gen_cb.h271
-rw-r--r--idlc/gen_cion/cpp_cion_proxy_header_gen.cc139
-rw-r--r--idlc/gen_cion/cpp_cion_proxy_header_gen.h47
-rw-r--r--idlc/gen_cion/cpp_cion_proxy_header_gen_cb.h171
-rw-r--r--idlc/gen_cion/cpp_cion_stub_body_gen.cc399
-rw-r--r--idlc/gen_cion/cpp_cion_stub_body_gen.h56
-rw-r--r--idlc/gen_cion/cpp_cion_stub_body_gen_cb.h429
-rw-r--r--idlc/gen_cion/cpp_cion_stub_header_gen.cc155
-rw-r--r--idlc/gen_cion/cpp_cion_stub_header_gen.h53
-rw-r--r--idlc/gen_cion/cpp_cion_stub_header_gen_cb.h370
-rw-r--r--idlc/gen_cion/cpp_transportable.h109
-rw-r--r--idlc/gen_cion/cs_cion_cb_version.h26
-rw-r--r--idlc/gen_cion/cs_cion_gen_base.cc643
-rw-r--r--idlc/gen_cion/cs_cion_gen_base.h91
-rw-r--r--idlc/gen_cion/cs_cion_gen_base_cb.h152
-rw-r--r--idlc/gen_cion/cs_cion_group_gen.cc212
-rw-r--r--idlc/gen_cion/cs_cion_group_gen.h54
-rw-r--r--idlc/gen_cion/cs_cion_group_gen_cb.h108
-rw-r--r--idlc/gen_cion/cs_cion_proxy_gen.cc209
-rw-r--r--idlc/gen_cion/cs_cion_proxy_gen.h49
-rw-r--r--idlc/gen_cion/cs_cion_proxy_gen_cb.h208
-rw-r--r--idlc/gen_cion/cs_cion_stub_gen.cc299
-rw-r--r--idlc/gen_cion/cs_cion_stub_gen.h56
-rw-r--r--idlc/gen_cion/cs_cion_stub_gen_cb.h353
-rw-r--r--idlc/gen_cion/cs_transportable.h50
-rw-r--r--idlc/gen_cion/dart_cion_gen_base.cc706
-rw-r--r--idlc/gen_cion/dart_cion_gen_base.h89
-rw-r--r--idlc/gen_cion/dart_cion_gen_base_cb.h325
-rw-r--r--idlc/gen_cion/dart_cion_group_gen.cc283
-rw-r--r--idlc/gen_cion/dart_cion_group_gen.h53
-rw-r--r--idlc/gen_cion/dart_cion_group_gen_cb.h179
-rw-r--r--idlc/gen_cion/dart_cion_proxy_gen.cc387
-rw-r--r--idlc/gen_cion/dart_cion_proxy_gen.h60
-rw-r--r--idlc/gen_cion/dart_cion_proxy_gen_cb.h238
-rw-r--r--idlc/gen_cion/dart_cion_stub_gen.cc434
-rw-r--r--idlc/gen_cion/dart_cion_stub_gen.h57
-rw-r--r--idlc/gen_cion/dart_cion_stub_gen_cb.h308
-rw-r--r--idlc/gen_cion/dart_transportable.h42
-rw-r--r--idlc/gen_cion/default_c_transportable.cc846
-rw-r--r--idlc/gen_cion/default_c_transportable.h101
-rw-r--r--idlc/gen_cion/default_cpp_transportable.cc846
-rw-r--r--idlc/gen_cion/default_cpp_transportable.h111
-rw-r--r--idlc/gen_cion/default_cs_transportable.cc205
-rw-r--r--idlc/gen_cion/default_cs_transportable.h59
-rw-r--r--idlc/gen_cion/default_dart_transportable.cc84
-rw-r--r--idlc/gen_cion/default_dart_transportable.h42
-rw-r--r--idlc/gen_cion/default_java_transportable.cc379
-rw-r--r--idlc/gen_cion/default_java_transportable.h76
-rw-r--r--idlc/gen_cion/java_cion_common_gen.cc109
-rw-r--r--idlc/gen_cion/java_cion_common_gen.h39
-rw-r--r--idlc/gen_cion/java_cion_gen_base.cc702
-rw-r--r--idlc/gen_cion/java_cion_gen_base.h91
-rw-r--r--idlc/gen_cion/java_cion_gen_cb.h492
-rw-r--r--idlc/gen_cion/java_cion_group_gen.cc231
-rw-r--r--idlc/gen_cion/java_cion_group_gen.h52
-rw-r--r--idlc/gen_cion/java_cion_group_gen_cb.h79
-rw-r--r--idlc/gen_cion/java_cion_group_repo_gen.cc74
-rw-r--r--idlc/gen_cion/java_cion_group_repo_gen.h40
-rw-r--r--idlc/gen_cion/java_cion_proxy_gen.cc228
-rw-r--r--idlc/gen_cion/java_cion_proxy_gen.h46
-rw-r--r--idlc/gen_cion/java_cion_proxy_gen_cb.h159
-rw-r--r--idlc/gen_cion/java_cion_proxy_repo_gen.cc81
-rw-r--r--idlc/gen_cion/java_cion_proxy_repo_gen.h40
-rw-r--r--idlc/gen_cion/java_cion_structure_gen.cc136
-rw-r--r--idlc/gen_cion/java_cion_structure_gen.h42
-rw-r--r--idlc/gen_cion/java_cion_stub_gen.cc318
-rw-r--r--idlc/gen_cion/java_cion_stub_gen.h52
-rw-r--r--idlc/gen_cion/java_cion_stub_gen_cb.h323
-rw-r--r--idlc/gen_cion/java_cion_stub_repo_gen.cc77
-rw-r--r--idlc/gen_cion/java_cion_stub_repo_gen.h39
-rw-r--r--idlc/gen_cion/java_cion_utility_gen.cc62
-rw-r--r--idlc/gen_cion/java_cion_utility_gen.h41
-rw-r--r--idlc/gen_cion/java_transportable.h76
-rw-r--r--idlc/gen_cion/plugin_loader.cc59
-rw-r--r--idlc/gen_cion/plugin_loader.h47
-rw-r--r--idlc/gen_cion/transportable.h40
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_c_transportable.cc1191
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_c_transportable.h101
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_cpp_transportable.cc1189
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_cpp_transportable.h111
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_cs_base_gen.cc75
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_cs_base_gen.h42
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_cs_base_gen_cb.h1301
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_cs_interop_gen.cc77
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_cs_interop_gen.h45
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_cs_interop_gen_cb.h371
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_cs_transportable.cc152
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_cs_transportable.h50
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen.cc107
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen.h44
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen_cb.h523
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen.cc64
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen.h38
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen_cb.h211
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_java_transportable.cc146
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_java_transportable.h43
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_loader.cc61
-rw-r--r--idlc/gen_mqtt_plugin/mqtt_plugin_loader.h47
-rw-r--r--idlc/main.cc93
-rw-r--r--idlc/mqtt_generator.cc424
-rw-r--r--idlc/mqtt_generator.hh78
-rw-r--r--idlc/options.cc76
-rw-r--r--idlc/options.h31
-rw-r--r--idlc/version2_default_generator.cc182
-rw-r--r--idlc/version2_default_generator.hh62
-rwxr-xr-xpackage/build.linux7
-rwxr-xr-xpackage/build.macos9
-rw-r--r--package/build.windows9
-rw-r--r--package/pkginfo.manifest12
-rwxr-xr-xpackage/tidlc.install.linux2
-rwxr-xr-xpackage/tidlc.install.macos2
-rw-r--r--package/tidlc.install.windows2
-rw-r--r--package/tidlc.remove.windows2
-rw-r--r--packaging/tidl.spec10
-rwxr-xr-xrelease/windows-32/tidlc.exebin3449179 -> 63015008 bytes
-rwxr-xr-xrelease/windows-64/tidlc.exebin4246301 -> 63015008 bytes
-rw-r--r--tests/CMakeLists.txt4
-rw-r--r--tests/unit_tests/CMakeLists.txt (renamed from unit_tests/CMakeLists.txt)34
-rw-r--r--tests/unit_tests/attribute_unittest.cc (renamed from unit_tests/attribute_unittest.cc)38
-rw-r--r--tests/unit_tests/block_unittest.cc (renamed from unit_tests/block_unittest.cc)6
-rw-r--r--tests/unit_tests/cs_gen/cs_proxy_gen_unittest.cc (renamed from unit_tests/cs_gen/cs_proxy_gen_unittest.cc)0
-rw-r--r--tests/unit_tests/cs_gen/cs_stub_gen_unittest.cc (renamed from unit_tests/cs_gen/cs_stub_gen_unittest.cc)0
-rw-r--r--tests/unit_tests/declaration_unittest.cc160
-rw-r--r--tests/unit_tests/document_unittest.cc (renamed from unit_tests/document_unittest.cc)4
-rw-r--r--tests/unit_tests/element_unittest.cc104
-rw-r--r--tests/unit_tests/generator_unittest.cc (renamed from unit_tests/generator_unittest.cc)0
-rw-r--r--tests/unit_tests/interface_unittest.cc (renamed from unit_tests/interface_unittest.cc)27
-rw-r--r--tests/unit_tests/main.cc (renamed from unit_tests/main.cc)0
-rw-r--r--tests/unit_tests/parser_unittest.cc (renamed from unit_tests/parser_unittest.cc)0
-rw-r--r--tests/unit_tests/structure_unittest.cc (renamed from unit_tests/structure_unittest.cc)22
-rw-r--r--tests/unit_tests/test.tidl (renamed from unit_tests/test.tidl)0
-rw-r--r--tests/unit_tests/test_error.tidl (renamed from unit_tests/test_error.tidl)0
-rw-r--r--tests/unit_tests/type_unittest.cc (renamed from unit_tests/type_unittest.cc)2
-rwxr-xr-xtests/unit_tests/unit_tests.sh (renamed from unit_tests/unit_tests.sh)0
-rw-r--r--unit_tests/declaration_unittest.cc179
-rw-r--r--unit_tests/element_unittest.cc134
354 files changed, 77902 insertions, 7528 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fd0ec2d..99e1da6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
-PROJECT(tidlc CXX)
+PROJECT(tidlc)
INCLUDE(FindPkgConfig)
@@ -8,13 +8,11 @@ FIND_PACKAGE(FLEX REQUIRED)
IF(NOT DEFINED MINIMUM_BUILD)
ENABLE_TESTING()
-SET(TIDL_UNIT_TESTS tidl-unit-tests)
+SET(TARGET_TIDL_BUILD_TESTS "tidl-build-tests")
+SET(TIDL_UNIT_TESTS "tidl-unit-tests")
ADD_TEST(NAME ${TIDL_UNIT_TESTS} COMMAND ${TIDL_UNIT_TESTS} test.tidl test_error.tidl
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/unit_tests)
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests/unit_tests)
ENDIF(NOT DEFINED MINIMUM_BUILD)
ADD_SUBDIRECTORY(idlc)
-IF(NOT DEFINED MINIMUM_BUILD)
-ADD_SUBDIRECTORY(unit_tests)
-ADD_DEPENDENCIES(${TIDL_UNIT_TESTS} ${PROJECT_NAME})
-ENDIF(NOT DEFINED MINIMUM_BUILD)
+ADD_SUBDIRECTORY(tests)
diff --git a/Makefile.dibs b/Makefile.dibs
index 7ec6a32..a98690c 100644
--- a/Makefile.dibs
+++ b/Makefile.dibs
@@ -1,41 +1,18 @@
+SRCDIR = idlc
+STRUCTURE := $(shell find $(SRCDIR) -type d)
+CODEFILES := $(addsuffix /*,$(STRUCTURE))
+CODEFILES := $(wildcard $(CODEFILES))
+
SRC_FILES := \
- idlc/ast/attribute.cc \
- idlc/ast/block.cc \
- idlc/ast/declaration.cc \
- idlc/ast/document.cc \
- idlc/ast/element.cc \
- idlc/ast/interface.cc \
- idlc/ast/parameter.cc \
- idlc/ast/parser.cc \
- idlc/ast/structure.cc \
idlc/ast/tidlc_l.cpp \
idlc/ast/tidlc_y.cpp \
- idlc/ast/type.cc \
- idlc/gen/c_body_gen_base.cc \
- idlc/gen/c_gen_base.cc \
- idlc/gen/c_header_gen_base.cc \
- idlc/gen/c_proxy_body_gen.cc \
- idlc/gen/c_proxy_header_gen.cc \
- idlc/gen/c_stub_body_gen.cc \
- idlc/gen/c_stub_header_gen.cc \
- idlc/gen/cpp_gen_base.cc \
- idlc/gen/cpp_proxy_body_gen.cc \
- idlc/gen/cpp_proxy_header_gen.cc \
- idlc/gen/cpp_stub_body_gen.cc \
- idlc/gen/cpp_stub_header_gen.cc \
- idlc/gen/cs_gen_base.cc \
- idlc/gen/cs_lib_gen.cc \
- idlc/gen/cs_proxy_gen.cc \
- idlc/gen/cs_stub_gen.cc \
- idlc/gen/generator.cc \
- idlc/options.cc \
- idlc/main.cc
+ $(filter %.cc,$(CODEFILES))
INCS := \
-I$(CURDIR)
CXXFLAGS := \
- -O2 -Wall -Wno-unused-function -Wno-sign-compare -std=c++11 -DFULLVER=\"$(FULLVER)\"
+ -O2 -Wall -Wno-unused-function -Wno-sign-compare -std=c++17 -DFULLVER=\"$(FULLVER)\"
OBJDIR := build
BINDIR := build/idlc
diff --git a/README.md b/README.md
index ac16a11..c94e6be 100755
--- a/README.md
+++ b/README.md
@@ -1,12 +1,43 @@
-
+<a name="welcome-to-tidl"></a>
# Welcome to TIDL!
-
TIDL is programming language to define interfaces for communicating among apps in Tizen. It provides methods to make a RPC(Remote Procedure Call) or RMI (Remote Method Invocation) in Tizen.
-## TIDLC
+<a name="contents"></a>
+## Contents
+- [Welcome to TIDL!](#welcome-to-tidl)
+ - [Contents](#contents)
+ - [TIDLC](#tidlc)
+ - [Usage](#usage)
+ - [TIDL Syntax](#tidl-syntax)
+ - ['interface'](#interface)
+ - [Attributes](#attributes)
+ - ['async'](#async)
+ - ['delegate'](#delegate)
+ - ['struct'](#struct)
+ - [TIDL Type System](#tidl-type-system)
+ - [TIDL Generated Code](#tidl-generated-code)
+ - [Struct](#struct-1)
+ - [Proxy Interface](#proxy-interface)
+ - [Stub Interface](#stub-interface)
+ - [Protocol version 2](#protocol-version-2)
+ - [Enum type](#enum-type)
+ - [Import another TIDL file](#import-another-tidl-file)
+ - [Method privilege](#method-privilege)
+ - [Map and set container type](#map-and-set-container-type)
+ - [Marshalling type info](#marshalling-type-info)
+ - [Struct inheritance](#struct-inheritance)
+ - [Remote exception](#remote-exception)
+ - [Local execution mode](#local-execution-mode)
+ - [Private sharing](#private-sharing)
+ - [TIDL generated code for protocol version 2](#tidl-generated-code-for-protocol-version-2)
+ - [Proxy interface](#proxy-interface-1)
+ - [Stub interface](#stub-interface-1)
+<a name="tidlc"></a>
+## TIDLC
**TIDLC** is a compiler for making stub or proxy code block from **TIDL** file.
+<a name="usage"></a>
### Usage
```
Usage:
@@ -18,7 +49,7 @@ Help Options:
--help-option Additional options
Additional Options:
- -l, --language=LANGUAGE Select generating language (C, C++, C#).
+ -l, --language=LANGUAGE Select generating language (C, C++, C#, Dart).
-i, --input=INPUT A tidl interface file.
-o, --output=OUTPUT The generated interface file.
-n, --namespace Add the prefix in the funtion name as output file name (C language only).
@@ -32,9 +63,10 @@ Application Options:
-v, --version Show version information
```
-
+<a name="tidlc-syntax"></a>
## TIDL Syntax
+<a name="interface"></a>
### 'interface'
It makes an interface to communicate between proxy and stub.
@@ -58,6 +90,7 @@ interface ITest {
}
```
+<a name="attributes"></a>
### Attributes
It indicates required privileges and trusted signature.
By default, ‘trusted” is ‘false’.
@@ -82,6 +115,7 @@ interface ITest {}
interface ITest2 {}
```
+<a name="async"></a>
### 'async'
It denotes one-way-call.
@@ -113,6 +147,7 @@ interface ITest {
}
```
+<a name="struct"></a>
### 'struct'
It allows developers to define user-defined types.
It is also possible to be used in other user-defined types or method syntax.
@@ -134,21 +169,22 @@ struct Student {
}
```
+<a name="tidl-type-system"></a>
## TIDL Type System
- Built-in type (‘in’ direction case)
- | TIDL type |Size |C# type |C++ type |C type|
- |------------|------|--------|----------|------|
- | void |0|void |void |void|void|
- | char|1|byte|char|char|
- | short|2|short|short int|short int|
- | int|4|int |int |int|
- | long|8|long|long long|long long|
- | float|4|float|float|float|
- | double|8|double|double|double|
- | bundle|variable|Bundle|Bundle|bundle *|
- | string|variable|string|std::string|const char *|
- | bool|1|bool|bool|bool|
+ | TIDL type | Size | C# type | C++ type | C type | Dart Type |
+ |-----------|----------|---------|-------------|--------------|---------------|
+ | void | 0 | void | void | void | void |
+ | char | 1 | byte | char | char | int |
+ | short | 2 | short | short int | short int | int |
+ | int | 4 | int | int | int | int |
+ | long | 8 | long | long long | long long | int |
+ | float | 4 | float | float | float | Not supported |
+ | double | 8 | double | double | double | double |
+ | bundle | variable | Bundle | Bundle | bundle * | Bundle |
+ | string | variable | string | std::string | const char * | String |
+ | bool | 1 | bool | bool | bool | bool |
- Container type
- **list< [type] >** Or **array<[type]>**
@@ -156,36 +192,39 @@ struct Student {
- Similar to c++ std::list / std::vector
- Can be nested
- | TIDL type | C# type| C++ type |C type |
- |--|--|--|--|
- | list<> | LinkedList<> |std::list<> |Handle (pointer)|
- | array<> | List<>|std::vector<> |Handle (pointer)|
+ | TIDL type | C# type | C++ type | C type | Dart type |
+ |------------|--------------|---------------|------------------|-----------|
+ | list<> | LinkedList<> | std::list<> | Handle (pointer) | List<> |
+ | array<> | List<> | std::vector<> | Handle (pointer) | List<> |
- User-defined type
- Name defined by ‘struct’ syntax
+<a name="tidl-generated-code"></a>
## TIDL Generated Code
+<a name="struct-1"></a>
### Struct
**TIDL**
```csharp
struct Foo {
- int Age;
- string Name;
+ int Age;
+ string Name;
}
```
**C++**
```cpp
class Foo final { // Copyable and movable class
- Foo(); // Constructor
- Foo(int age, std::string name); // Constructor
- int GetAge() const; // Getter for property ‘Age’
- void SetAge(int age); // Setter for property ‘Age’
- const std::string& GetName() const; // Getter for property ‘Name’
- void SetName(std::string name); // Setter for property ‘Name’
+ Foo(); // Constructor
+ Foo(int age, std::string name); // Constructor
+ int GetAge() const; // Getter for property ‘Age’
+ void SetAge(int age); // Setter for property ‘Age’
+ const std::string& GetName() const; // Getter for property ‘Name’
+ void SetName(std::string name); // Setter for property ‘Name’
};
```
+
**C#**
```csharp
public selaed class Foo { // Class for Foo
@@ -193,6 +232,7 @@ public selaed class Foo { // Class for Foo
public string Name { get; set; } // Property for ‘Name’
};
```
+
**C**
```c
typedef struct Foo_s *rpc_port_Foo_h; // Handle for Foo
@@ -203,8 +243,39 @@ int rpc_port_set_Foo_Age(rpc_port_Foo_h h, int Age); // Setter for property ‘A
int rpc_port_set_Foo_Name(rpc_port_Foo_h h, const char* Name); // Setter for property ‘Name’
int rpc_port_get_Foo_Age(rpc_port_Foo_h h, int* Age); // Getter for property ‘Age’
int rpc_port_get_Foo_Name(rpc_port_Foo_h h, char** Name); // Getter for property ‘Name’
+
+// Proxy (Since TIDLC version 1.5.0)
+typedef struct rpc_port_proxy_Foo_s *rpc_port_proxy_Foo_h; // Handle for Foo
+int rpc_port_proxy_create_Foo(rpc_port_proxy_Foo_h* h); // Constructor for Foo
+int rpc_port_proxy_destroy_Foo(rpc_port_proxy_Foo_h h); // Destructor for Foo
+int rpc_port_proxy_clone_Foo(rpc_port_proxy_Foo_h h, rpc_port_proxy_Foo_h* clone); // Copy constructor for Foo
+int rpc_port_proxy_set_Foo_Age(rpc_port_proxy_Foo_h h, int Age); // Setter for property ‘Age’
+int rpc_port_proxy_set_Foo_Name(rpc_port_proxy_Foo_h h, const char* Name); // Setter for property ‘Name’
+int rpc_port_proxy_get_Foo_Age(rpc_port_proxy_Foo_h h, int* Age); // Getter for property ‘Age’
+int rpc_port_proxy_get_Foo_Name(rpc_port_proxy_Foo_h h, char** Name); // Getter for property ‘Name’
+
+// Stub (Since TIDLC version 1.5.0)
+typedef struct rpc_port_stub_Foo_s *rpc_port_stub_Foo_h; // Handle for Foo
+int rpc_port_stub_create_Foo(rpc_port_stub_Foo_h* h); // Constructor for Foo
+int rpc_port_stub_destroy_Foo(rpc_port_stub_Foo_h h); // Destructor for Foo
+int rpc_port_stub_clone_Foo(rpc_port_stub_Foo_h h, rpc_port_stub_Foo_h* clone); // Copy constructor for Foo
+int rpc_port_stub_set_Foo_Age(rpc_port_stub_Foo_h h, int Age); // Setter for property ‘Age’
+int rpc_port_stub_set_Foo_Name(rpc_port_stub_Foo_h h, const char* Name); // Setter for property ‘Name’
+int rpc_port_stub_get_Foo_Age(rpc_port_stub_Foo_h h, int* Age); // Getter for property ‘Age’
+int rpc_port_stub_get_Foo_Name(rpc_port_stub_Foo_h h, char** Name); // Getter for property ‘Name’
```
+**Dart**
+```dart
+class Foo {
+ Foo(this.age, this.name);
+
+ int age;
+ String name;
+}
+```
+
+<a name="proxy-interface"></a>
### Proxy Interface
**TIDL**
@@ -225,8 +296,9 @@ class Runnable {
Runnable(IEventListener* listener, const std::string& target_appid); // Constructor
virtual ~Runnable(); // Destructor
- int Connect(); // Method for connecting service app
+ int Connect(); // Method for connecting to the stub
int Run(Foo foo); //Method from TIDL
+ void Disconnect(); // Method for disconnecting from the stub (Since TIDLC version 1.6.1)
};
```
@@ -237,18 +309,22 @@ public class Runnable : IDisposable {
public event EventHandler Disconnected; // Event handler
public event EventHandler Rejected; // Event handler
public Runnable(string appId); // Constructor
- public void Connect(); // Method for connecting service app
- public int Run(Foo foo); //Method from TIDL
+ public void Connect(); // Method for connecting to the stub
+ public int Run(Foo foo); //Method from TIDL
+ public void Disconnect(); // Method for disconnecting from the stub (Since TIDLC version 1.6.1)
};
```
+
**C**
```c
+// Previous version
typedef struct Runnable_s* rpc_port_proxy_Runnable_h; // Handle for ‘Runnable’
+
typedef struct {
- void (*connected)(rpc_port_proxy_Runnable_h h, void* user_data); // Connected event callback
- void (*disconnected)(rpc_port_proxy_Runnable_h h, void* user_data); // Disconnected event callback
- void (*rejected)(rpc_port_proxy_Runnable_h h, void* user_data); // Rejected event callback
+ void (*connected)(rpc_port_proxy_Runnable_h h, void* user_data); // Connected event callback
+ void (*disconnected)(rpc_port_proxy_Runnable_h h, void* user_data); // Disconnected event callback
+ void (*rejected)(rpc_port_proxy_Runnable_h h, void* user_data); // Rejected event callback
} rpc_port_proxy_Runnable_callback_s;
// Function for creating Runnable proxy handle
@@ -264,6 +340,65 @@ int rpc_port_proxy_Runnable_destroy(rpc_port_proxy_Runnable_h h);
int rpc_port_proxy_Runnable_invoke_Run(rpc_port_proxy_Runnable_h h, rpc_port_Foo_h foo);
```
+```c
+// Since TIDLC version 1.5.0
+typedef struct rpc_port_proxy_Runnable_s* rpc_port_proxy_Runnable_h; // Handle for ‘Runnable’
+
+// Called when the port is connected
+typedef void (*rpc_port_proxy_Runnable_connected_cb)(rpc_port_proxy_Runnable_h h, void *user_data);
+
+// Called when the port is disconnected
+typedef void (*rpc_port_proxy_Runnable_disconnected_cb)(rpc_port_proxy_Runnable_h h, void *user_data);
+
+// Called when the connection request is rejected
+typedef void (*rpc_port_proxy_Runnable_rejected_cb)(rpc_port_proxy_Runnable_h h, void *user_data);
+
+// The structure type containing the set of callback functions for handling proxy events
+typedef struct {
+ rpc_port_proxy_Runnable_connected_cb connected;
+ rpc_port_proxy_Runnable_disconnected_cb disconnected;
+ rpc_port_proxy_Runnable_rejected_cb rejected;
+} rpc_port_proxy_Runnable_callback_s;
+
+// Function for creating Runnable proxy handle
+int rpc_port_proxy_Runnable_create(const char* stub_appid, rpc_port_proxy_Runnable_callback_s* callback, void* user_data, rpc_port_proxy_Runnable_h* h);
+
+// Function for connecting to the stub
+int rpc_port_proxy_Runnable_connect(rpc_port_proxy_Runnable_h h);
+
+// Function for destroying Runnable proxy handle
+int rpc_port_proxy_Runnable_destroy(rpc_port_proxy_Runnable_h h);
+
+// Function from TIDL
+int rpc_port_proxy_Runnable_invoke_Run(rpc_port_proxy_Runnable_h h, rpc_port_Foo_h foo);
+
+// Function for disconnection from the stub (Since TIDLC version 1.6.1)
+int rpc_port_proxy_Runnable_disconnect(rpc_port_proxy_Runnable_h h);
+```
+
+**Dart**
+```dart
+class Runnable extends ProxyBase {
+ Runnable(String appid) : super(appid, 'Runnable');
+
+ Future<int> Run(Foo foo);
+
+ /// Connects with the stub.
+ ///
+ /// The following privileges are required to use this API.
+ /// - `http://tizen.org/privilege/appmanager.launch`
+ /// - `http://tizen.org/privilege/datasharing`
+ Future<void> connect({OnDisconnected? onDisconnected});
+
+ /// Disconnects with the stub.
+ Future<void> disconnect();
+
+ // Disposes of registered delegate interface.
+ void disposeCallback(Function callback);
+}
+```
+
+<a name="stub-interface"></a>
### Stub Interface
**TIDL**
@@ -278,17 +413,20 @@ interface Runnable {
class Runnable {
class ServiceBase { // Abstract class for RPC service
class Factory { // Factory class to make real service object
- virtual std::unique_ptr<ServiceBase> CreateService(std::string sender) = 0;
+ virtual std::unique_ptr<ServiceBase> CreateService(std::string sender) = 0;
};
- virtual void OnCreate() = 0; // Called when service object is created
- virtual void OnTerminate() = 0; // Called when service object is terminated
- virtual int Run(Foo foo) = 0; // Method to implement
+ virtual void OnCreate() = 0; // Called when service object is created
+ virtual void OnTerminate() = 0; // Called when service object is terminated
+ virtual int Run(Foo foo) = 0; // Method to implement
+
+ ...
+ void Disconnect(); // Method for disconnecting from the RPC service (Since TIDLC version 1.6.1)
};
Runnable(); // Constructor
~Runnable(); // Destructor
- void Listen(std::shared\_ptr<ServiceBase::Factory> service\_factory); // Method for listening
+ void Listen(std::shared\_ptr<ServiceBase::Factory> service_factory); // Method for listening
};
```
@@ -299,16 +437,18 @@ public sealed class Runnable : IDisposable {
public abstract void OnCreate(); // Called when service object is created
public abstract void OnTerminate(); // Called when service object is terminated
public abstract int Run(Foo foo); // Method to implement
- …
+ …
+ public void Disconnect(); // Method for disconnecting from the RPC service (Since TIDLC version 1.6.1)
};
public Runnable(); // Constructor
- public void Listen(Type serviceType); // Method for listening
- …
+ public void Listen(Type serviceType); // Method for listening
+ …
};
```
**C**
```c
+// Previous version
// Handle for ‘Runnable’
typedef struct Runnable_context_s* rpc_port_stub_Runnable_context_h;
@@ -336,3 +476,1087 @@ int rpc_port_stub_Runnable_register(rpc_port_stub_Runnable_callback_s* callback,
int rpc_port_stub_Runnable_unregister(void);
```
+```c
+// Since TIDLC version 1.5.0
+// Handle for ‘Runnable’
+typedef struct rpc_port_stub_Runnable_context_s* rpc_port_stub_Runnable_context_h;
+
+// Set extra data into the context
+int rpc_port_stub_Runnable_context_set_tag(rpc_port_stub_Runnable_context_h context, void* tag);
+
+// Get extra data from the context
+int rpc_port_stub_Runnable_context_get_tag(rpc_port_stub_Runnable_context_h context, void** tag);
+
+// Disconnect from the proxy
+int rpc_port_stub_Runnable_context_disconnect(rpc_port_stub_Runnable_context_h context);
+
+// Called when the service object is created
+typedef void (*rpc_port_stub_Runnable_create_cb)(rpc_port_stub_Runnable_context_h context, void *user_data);
+
+// Called when the service object is terminated
+typedef void (*rpc_port_stub_Runnable_terminate_cb)(rpc_port_stub_Runnable_context_h context, void *user_data);
+
+// Called when the proxy sends the request for 'Run'
+typedef void (*rpc_port_stub_Runnable_Run_cb)(rpc-port_stub_Runnable_context_h context, rpc_port_stub_Foo_h foo, void *user_data);
+
+// The structure type containing the set of callback functions for handling stub events
+typedef struct {
+ rpc_port_stub_Runnable_create_cb create;
+ rpc_port_stub_Runnable_terminate_cb terminate;
+ rpc_port_stub_Runnable_Run_cb Run;
+} rpc_port_stub_Runnable_callback_s;
+
+// Initialize interface ‘Runnable’
+int rpc_port_stub_Runnable_register(rpc_port_stub_Runnable_callback_s* callback, void* user_data);
+
+// Deinitialize interface ‘Runnable’
+int rpc_port_stub_Runnable_unregister(void);
+
+// Gets the number of connected clients
+int rpc_port_stub_Runnable_get_client_number(unsigned int *client_number);
+```
+
+**Dart**
+```dart
+abstract class ServiceBase {
+ ServiceBase(this.sender, this.instance);
+
+ final String sender;
+ final String instance;
+ Port? _port;
+
+ void disconnect() {
+ _port?.disconnect();
+ _port = null;
+ }
+
+ Future<void> onCreate();
+ Future<void> onTerminate();
+ Future<int> onRun(Foo foo);
+}
+
+typedef ServiceBuilder = ServiceBase Function(String sender, String instance);
+
+class Runnable extends StubBase {
+ Runnable({required ServiceBuilder serviceBuilder})
+ : _serviceBuilder = serviceBuilder,
+ super('Runnable');
+
+ final List<ServiceBase> services = <ServiceBase>[];
+ final Map<int, dynamic> _methodHandlers = <int, dynamic>{};
+ final ServiceBuilder _serviceBuilder;
+}
+```
+
+<a name="protocol-version-2"></a>
+## Protocol version 2
+To use 'protocol version 2', you must fill **'protocol 2'** in the .tidl file.
+'protocol version 2' of **TIDL** supports the following features:
+ > [!NOTE]
+ > **TIDLC** supports 'protocol version 2' since Tizen 8.0.
+
+<a name="enum-type"></a>
+### Enum type
+ - **'enum'** type is added.
+ - You can declare an **enum** type inside a 'struct' or 'interface' and use it as a member variable or parameter.
+ ```tidl
+ struct Message {
+ enum Type {
+ T1 = 0,
+ T2,
+ T3
+ }
+
+ Type t;
+ int id;
+ string str;
+ }
+
+ interface Hello {
+ enum Version {
+ V1,
+ V2,
+ V3
+ }
+
+ string SayHello(Version ver, string str, Message.Type msg);
+ }
+ ```
+- When using a struct's enum type as a method parameter, it must be specified as **"<struct_name>.<enum_type>"**.
+
+<a name="import-another-tidl-file"></a>
+### Import another TIDL file
+- **'import'** keyword is added.
+- You can add and use other TIDL files in the same directory as the current TIDL file using the **'import'** keyword.
+- During the compilation process, the contents of other TIDL files are integrated and generated as one code.
+- The following example shows how to use the **'import'** keyword:
+ ```tidl
+ import <another.tidl>
+
+ interface Message {
+ int Send(string name, string msg);
+ }
+ ```
+
+<a name="method-privilege"></a>
+### Method privilege
+- The protocol version 2 of TIDL supports the method privilege feature.
+- You can set privileges for each method of an interface by writing them as below:
+ ```tidl
+ interface PackageManager {
+ [privilege = "http://tizen.org/privilege/packagemanager.info"]
+ int GetPackages(out list<string> packages);
+
+ [privilege = "http://tizen.org/privilege/packagemanager.admin"]
+ int Install(file path);
+
+ [privilege = "http://tizen.org/privilege/packagemanager.admin"]
+ int Uninstall(string package);
+ }
+ ```
+- To use the GetPackages method in the example, the client application needs to have the privilege that is "[http://tizen.org/privilege/packagemanager.info](http://tizen.org/privilege/packagemanager.info){:target="_blank"}".
+
+<a name="map-and-set-container-type"></a>
+### Map and set container type
+- You can use map and set container types in TIDL.
+- The map type is **'map\<K, V\>'**. The set type is **'set\<K\>'**.
+ ```tidl
+ struct Message {
+ string name;
+ map<string, string> envelope;
+ set<string> keys;
+ }
+ ```
+ > [!NOTE]
+ > The key type of map and set container must be TIDL's built-in types.
+
+<a name="marshalling-type-info"></a>
+### Marshalling type info
+- From protocol version 2, the type information and variable names of method parameters are also transmitted.
+- Even if variable names are changed, added, or deleted due to interface modifications, it does not affect communication.
+- If there are no variables to be passed, they are passed as initial values.
+ - The following code is an example of an original TIDL code:
+
+ ```tidl
+ interface Hello {
+ int GetPackages(out list<string> packages);
+ }
+ ```
+ - The following code is an example of a revised TIDL code:
+ ```tidl
+ interface Hello {
+ int GetPackages(out list<string> packages, out int size);
+ }
+ ``````
+- In the example, the `GetPackages()` method has an added size parameter.
+- Even if the stub only returns the existing packages parameter, there is no problem with communication.
+
+<a name="struct-inheritance"></a>
+### Struct inheritance
+- **'struct'** inheritance is supported.
+- Here is an example that supports **'struct'** inheritance:
+ ```tidl
+ struct MessageBase {
+ int id;
+ string name;
+ }
+
+ struct MessageDerived : MessageBase {
+ string msg;
+ }
+ ```
+- In this example, **MessageDerived** inherits **MessageBase**.
+ > [!Note]
+ > The inherited struct must not have elements of the base struct.
+
+- If the method of the interface is a base struct, communication can be performed using the derived struct that is inherited. (Polymorphism)
+ ```tidl
+ struct MessageBase {
+ int id;
+ string name;
+ }
+
+ struct MessageDerived : MessageBase {
+ string msg;
+ }
+
+ struct Envelope : MessageBase {
+ string address;
+ string msg;
+ }
+
+ interface Message {
+ int SendMessage(MessageBase msg);
+ }
+ ```
+- When using the **Message** interface, you can use **Envelope** or **MessageDerived** to call the **`SendMessage()`** method.
+
+<a name="remote-exception"></a>
+### Remote exception
+- The stub can use **RemoteException** to throw an exception to the proxy.
+- This feature is available when the method operates synchronously.
+- When the proxy sends a request and waits for a result, if the stub throws an exception, it is passed to the proxy.
+
+<a name="local-execution-mode"></a>
+### Local execution mode
+- If the stub that the proxy sends a request to is in the same application, a function call occurs instead of RPC.
+
+<a name="private-sharing"></a>
+### Private sharing
+- Since protocol version 2, the **file** keyword can be used without the '-b' option.
+- The proxy or the stub can use this to share a specific file in the data directory with the intended recipient for communication.
+- The recipient who receives the shared file can access it with read-only permission.
+
+<a name="tidl-generated-code-for-protocol-version-2"></a>
+### TIDL generated code for protocol version 2
+
+**TIDL**
+```tidl
+protocol 2
+
+struct MessageBase {
+ int id;
+ string name;
+ string msg;
+}
+
+struct MessageDerived : MessageBase {
+ string address;
+}
+
+interface Message {
+ void OnReceived(string sender, MessageBase message) delegate;
+
+ int Register(string sender, OnReceived callback);
+ void Unregister() async;
+ int Send(MessageBase message);
+}
+```
+- In the example above, the **MessageDerived** structure inherits from **MessageBase**.
+- When calling the Send method of the Message interface, you can use a MessageDerived instance.
+
+<a name="proxy-interface-1"></a>
+#### Proxy interface
+
+**C**
+```c
+// Handle for 'MessageBase' structure.
+typedef void *rpc_port_proxy_MessageBase_h;
+
+// Handle for 'MessageDerived' structure.
+typedef void *rpc_port_proxy_MessageDerived_h;
+
+// Handle for Remote Exception.
+typedef struct rpc_port_proxy_remote_exception_s *rpc_port_proxy_remote_exception_h;
+
+// Handle for 'Message' interface.
+typedef struct rpc_port_proxy_Message_s *rpc_port_proxy_Message_h;
+
+// Handle for 'OnReceived' delegate of 'Message' interface.
+typedef struct rpc_port_proxy_Message_OnReceived_s *rpc_port_proxy_Message_OnReceived_h;
+
+// Function for creating MessageBase handle.
+int rpc_port_proxy_MessageBase_create(rpc_port_proxy_MessageBase_h *h);
+
+// Function for destroying MessageBase handle.
+int rpc_port_proxy_MessageBase_destroy(rpc_port_proxy_MessageBase_h h);
+
+// Function for cloning MessageBase handle.
+int rpc_port_proxy_MessageBase_clone(rpc_port_proxy_MessageBase_h h, rpc_port_proxy_MessageBase_h *clone);
+
+// Function for setting id to MessageBase handle.
+int rpc_port_proxy_MessageBase_set_id(rpc_port_proxy_MessageBase_h h, int value);
+
+// Function for getting id from MessageBase handle.
+int rpc_port_proxy_MessageBase_get_id(rpc_port_proxy_MessageBase_h h, int *value);
+
+// Function for setting name to MessageBase handle.
+int rpc_port_proxy_MessageBase_set_name(rpc_port_proxy_MessageBase_h h, const char *value);
+
+// Function for getting name from MessageBase handle.
+int rpc_port_proxy_MessageBase_get_name(rpc_port_proxy_MessageBase_h h, char **value);
+
+// Function for setting msg to MessageBase handle.
+int rpc_port_proxy_MessageBase_set_msg(rpc_port_proxy_MessageBase_h h, const char *value);
+
+// Function for getting msg from MessageBase handle.
+int rpc_port_proxy_MessageBase_get_msg(rpc_port_proxy_MessageBase_h h, char **value);
+
+// Function for creating MessageDerived handle.
+int rpc_port_proxy_MessageDerived_create(rpc_port_proxy_MessageDerived_h *h);
+
+// Function for destroying MessageDerived handle.
+int rpc_port_proxy_MessageDerived_destroy(rpc_port_proxy_MessageDerived_h h);
+
+// Function for cloning MessageDerived handle.
+int rpc_port_proxy_MessageDerived_clone(rpc_port_proxy_MessageDerived_h h, rpc_port_proxy_MessageDerived_h *clone);
+
+// Function for setting id to MessageDerived handle.
+int rpc_port_proxy_MessageDerived_set_id(rpc_port_proxy_MessageDerived_h h, int value);
+
+// Function for getting id from MessageDerived handle.
+int rpc_port_proxy_MessageDerived_get_id(rpc_port_proxy_MessageDerived_h h, int *value);
+
+// Function for setting id to MessageDerived handle.
+int rpc_port_proxy_MessageDerived_set_name(rpc_port_proxy_MessageDerived_h h, const char *value);
+
+// Function for getting name from MessageDerived handle.
+int rpc_port_proxy_MessageDerived_get_name(rpc_port_proxy_MessageDerived_h h, char **value);
+
+// Function for setting msg to MessageDerived handle.
+int rpc_port_proxy_MessageDerived_set_msg(rpc_port_proxy_MessageDerived_h h, const char *value);
+
+// Function for getting msg from MessageDerived handle.
+int rpc_port_proxy_MessageDerived_get_msg(rpc_port_proxy_MessageDerived_h h, char **value);
+
+// Function for setting address to MessageDerived handle.
+int rpc_port_proxy_MessageDerived_set_address(rpc_port_proxy_MessageDerived_h h, const char *value);
+
+// Function for getting address from MessageDerived handle.
+int rpc_port_proxy_MessageDerived_get_address(rpc_port_proxy_MessageDerived_h h, char **value);
+
+// Function for creating Remote Exception handle.
+int rpc_port_proxy_remote_exception_create(rpc_port_proxy_remote_exception_h *h);
+
+// Function for setting cause to Remote Exception handle.
+int rpc_port_proxy_remote_exception_set_cause(rpc_port_proxy_remote_exception_h h, int cause);
+
+// Function for setting msessage to Remote Exception handle.
+int rpc_port_proxy_remote_exception_set_message(rpc_port_proxy_remote_exception_h h, const char *message);
+
+// Function for getting cause from Remote Exception handle.
+int rpc_port_proxy_remote_exception_get_cause(rpc_port_proxy_remote_exception_h h, int *cause);
+
+// Function for getting message from Remote Exception handle.
+int rpc_port_proxy_remote_exception_get_message(rpc_port_proxy_remote_exception_h, char **message);
+
+// Function for destroying Remote Exception handle.
+int rpc_port_proxy_remote_exception_destroy(rpc_port_proxy_remote_exception_h h);
+
+// Function for getting Remote Exception handle.
+int rpc_port_proxy_get_remote_exception(rpc_port_proxy_remote_exception_h *h);
+
+// Callback function for OnReceived of Message interface.
+typedef void (*rpc_port_proxy_Message_OnReceived_cb)(void *user_data, const char *sender, rpc_port_proxy_MessageBase_h message);
+
+// Function for creating OnReceived handle.
+int rpc_port_proxy_Message_OnReceived_create(rpc_port_proxy_Message_OnReceived_h *h);
+
+// Function for destroying OnReceived handle.
+int rpc_port_proxy_Message_OnReceived_destroy(rpc_port_proxy_Message_OnReceived_h h);
+
+// Function for cloning OnReceived handle.
+int rpc_port_proxy_Message_OnReceived_clone(rpc_port_proxy_Message_OnReceived_h h, rpc_port_proxy_Message_OnReceived_h *clone);
+
+// Function for setting callback to OnReceived handle.
+int rpc_port_proxy_Message_OnReceived_set_callback(rpc_port_proxy_Message_OnReceived_h h, rpc_port_proxy_Message_OnReceived_cb callback, void *user_data);
+
+// Function for setting once flag to OnReceived handle.
+int rpc_port_proxy_Message_OnReceived_set_once(rpc_port_proxy_Message_OnReceived_h h, bool once);
+
+// Function for getting id from OnReceived handle.
+int rpc_port_proxy_Message_OnReceived_get_id(rpc_port_proxy_Message_OnReceived_h h, int *id);
+
+// Function for getting seq_id from OnReceived handle.
+int rpc_port_proxy_Message_OnReceived_get_seq_id(rpc_port_proxy_Message_OnReceived_h h, int *seq_id);
+
+// Function for checking once flag from OnReceived handle.
+int rpc_port_proxy_Message_OnReceived_is_once(rpc_port_proxy_Message_OnReceived_h h, bool *once);
+
+// Function for getting tag from OnReceived handle.
+int rpc_port_proxy_Message_OnReceived_get_tag(rpc_port_proxy_Message_OnReceived_h h, char **tag);
+
+// Function for dispoing OnReceived handle.
+int rpc_port_proxy_Message_OnReceived_dispose(rpc_port_proxy_Message_h proxy, rpc_port_proxy_Message_OnReceived_h h);
+
+// Called when receiving connected event.
+typedef void (*rpc_port_proxy_Message_connected_cb)(rpc_port_proxy_Message_h h, void *user_data);
+
+// Called when receiving disconnected event.
+typedef void (*rpc_port_proxy_Message_disconnected_cb)(rpc_port_proxy_Message_h h, void *user_data);
+
+// Called when receiving rejected event.
+typedef void (*rpc_port_proxy_Message_rejected_cb)(rpc_port_proxy_Message_h h, void *user_data);
+
+// Structure for receiving events of Message interface.
+typedef struct {
+ rpc_port_proxy_Message_connected_cb connected;
+ rpc_port_proxy_Message_disconnected_cb disconnected;
+ rpc_port_proxy_Message_rejected_cb rejected;
+} rpc_port_proxy_Message_callback_s;
+
+// Function for creating Message handle.
+int rpc_port_proxy_Message_create(const char *stub_appid, rpc_port_proxy_Message_callback_s *callback, void *user_data, rpc_port_proxy_Message_h *h);
+
+// Function for destroying Message handle.
+int rpc_port_proxy_Message_destroy(rpc_port_proxy_Message_h h);
+
+// Function for connecting to Message server.
+int rpc_port_proxy_Message_connect(rpc_port_proxy_Message_h h);
+
+// Function for connecting to Message server synchronously.
+int rpc_port_proxy_Message_connect_sync(rpc_port_proxy_Message_h h);
+
+// Function for disconnecting from Message server.
+int rpc_port_proxy_Message_disconnect(rpc_port_proxy_Message_h h);
+
+// Function for Register method of Message interface.
+int rpc_port_proxy_Message_invoke_Register(rpc_port_proxy_Message_h h, const char *sender, rpc_port_proxy_Message_OnReceived_h callback);
+
+// Function for Unregister method of Message interface.
+void rpc_port_proxy_Message_invoke_Unregister(rpc_port_proxy_Message_h h);
+
+// Function for Send method of Message interface.
+int rpc_port_proxy_Message_invoke_Send(rpc_port_proxy_Message_h h, rpc_port_proxy_MessageBase_h message);
+```
+
+**C++**
+```cpp
+// Class for Bundle.
+class Bundle final {
+ public:
+ Bundle();
+ explicit Bundle(bundle* handle, bool copy = true, bool own = true);
+ Bundle(std::string raw);
+ ~Bundle();
+
+ Bundle(const Bundle& b);
+ Bundle& operator = (const Bundle& b);
+ Bundle(Bundle&& b) noexcept;
+ Bundle& operator = (Bundle&&) noexcept;
+
+ bundle* GetHandle() const;
+ bundle* Detach();
+};
+
+// class for File.
+class File final {
+ public:
+ File(std::string filename = "");
+
+ const std::string& GetFileName() const;
+ int Share(rpc_port_h port);
+};
+
+// class for 'MessageBase' structure.
+class MessageBase {
+ public:
+ MessageBase();
+ MessageBase(int id, std::string name, std::string msg);
+
+ int Getid() const;
+ void Setid(int id);
+
+ const std::string& Getname() const;
+ void Setname(std::string name);
+
+ const std::string& Getmsg() const;
+ void Setmsg(std::string msg);
+};
+
+// class for 'MessageDerived' structure.
+class MessageDerived : public MessageBase {
+ public:
+ MessageDerived();
+ MessageDerived(int id, std::string name, std::string msg, std::string address);
+
+ const std::string& Getaddress() const;
+ void Setaddress(std::string address);
+};
+
+namespace proxy {
+class Exception {};
+class NotConnectedSocketException : public Exception {};
+class InvalidProtocolException : public Exception {};
+class InvalidIOException : public Exception {};
+class PermissionDeniedException : public Exception {};
+class InvalidIDException : public Exception {};
+class InvalidArgumentException : public Exception {};
+class OutOfMemoryException : public Exception {};
+
+// class for RemoteException.
+class RemoteException : public Exception {
+ public:
+ RemoteException();
+ RemoteException(std::string message);
+ RemoteException(int cause, std::string message);
+
+ int GetCause() const;
+ const std::string& GetMessage() const;
+};
+
+// class for 'Message' interface.
+class Message : public LocalExecution::IEvent {
+ public:
+
+ class CallbackBase {
+ public:
+ CallbackBase() = default;
+ CallbackBase(int delegate_id, bool once);
+ virtual ~CallbackBase() = default;
+
+ virtual void OnReceivedEvent(const UnitMap& unit_map);
+ int GetId() const;
+ void SetId(int id);
+ int GetSeqId() const;
+ void SetSeqId(int seq_id);
+ bool IsOnce() const;
+ void SetOnce(bool once);
+ std::string GetTag() const;
+ };
+
+ class OnReceived : public CallbackBase {
+ public:
+ OnReceived(bool once = false);
+ virtual void OnReceived(std::string sender, MessageBase message);
+ };
+
+ class IEventListener {
+ public:
+ virtual ~IEventListener() = 0;
+ // Called when connected event is delivered.
+ virtual void OnConnected() = 0;
+
+ // Called when disconnected event is delivered.
+ virtual void OnDisconnected() = 0;
+
+ // Called when rejected event is delivered.
+ virtual void OnRejected() = 0;
+ };
+
+ // Constructor.
+ Message(IEventListener* listener, std::string target_appid);
+
+ // Desctructor.
+ virtual ~Message();
+
+ // Method for connecting to 'Message' server.
+ void Connect(bool sync = false);
+
+ // Method for disconnecting from 'Message' server.
+ void Disconnect();
+
+ // Method for disposing delegate from Message intstance.
+ void DisposeCallback(const std::string& tag);
+
+ // Method for 'Register' method of 'Message' interface.
+ int Register(std::string sender, std::unique_ptr<OnReceived> callback);
+
+ // Method for 'Unregister' method of 'Message' interface.
+ void Unregister();
+
+ // Method for 'Send' method of 'Message' interface.
+ int Send(MessageBase message);
+};
+} // namespace proxy
+```
+
+**C#**
+```csharp
+// class for 'MessageBase' structure.
+public class MessageBase
+{
+ public int id;
+ public string name;
+ public string msg;
+
+ public MessageBase();
+}
+
+// class for 'MessageDerived' structure.
+public class MessageDerived : MessageBase
+{
+ public string address;
+
+ public MessageDerived();
+}
+
+// class for RemoteException.
+public class RemoteException : Exception
+{
+ public RemoteException();
+ public RemoteException(string message);
+ public RemoteException(string message, int cause);
+ public new string Message;
+ public int Cause;
+}
+
+namespace Proxy
+{
+ // class for 'Message' interface.
+ public class Message : ProxyBase
+ {
+ public event EventHandler Connected;
+ public event EventHandler Disconnected;
+ public event EventHandler Rejected;
+
+ public class CallbackBase
+ {
+ public string Tag;
+ public CallbackBase(int delegateId, bool once)
+ }
+
+ public sealed class OnReceived : CallbackBase
+ {
+ public OnReceived(bool once = false) : base((int)DelegateId.OnReceived, once);
+ public delegate void Callback(string sender, MessageBase message);
+ public event Callback Received;
+ }
+
+ // Called when connected event is delivered.
+ protected override void OnConnectedEvent(string endPoint, string portName, Port port);
+
+ // Called when disconnected event is delivered.
+ protected override void OnDisconnectedEvent(string endPoint, string portName);
+
+ // Called when rejected event is delivered.
+ protected override void OnRejectedEvent(string endPoint, string portName);
+
+ // Called when received event is delivered.
+ protected override void OnReceivedEvent(string endPoint, string portName);
+
+ // Constructor.
+ public Message(string appId);
+
+ // Method for connecting to 'Message' server.
+ public void Connect();
+
+ // Method for disconnecting from 'Message' server.
+ public void Disconnect();
+
+ // Method for connecting to 'Message' server sychronously.
+ public void ConnectSync();
+
+ // Method for disposing delegate from Message instance.
+ void DisposeCallback(string tag);
+
+ // Method for 'Register' method of 'Message' interface.
+ public int Register(string sender, OnReceived callback);
+
+ // Method for 'Unregister' method of 'Message' interface.
+ public void Unregister();
+
+ // Method for 'Send' method of 'Message' interface.
+ public int Send(MessageBase message);
+ }
+}
+```
+
+
+<a name="stub-interface-1"></a>
+#### Stub interface
+
+**C**
+```c
+// Handle for 'MessageBase' structure.
+typedef void *rpc_port_stub_MessageBase_h;
+
+// Handle for 'MessageDerived' structure.
+typedef void *rpc_port_stub_MessageDerived_h;
+
+// Handle for Remote Exception.
+typedef struct rpc_port_stub_remote_exception_s *rpc_port_stub_remote_exception_h;
+
+// Handle for context of 'Message' interface.
+typedef struct rpc_port_stub_Message_context_s *rpc_port_stub_Message_context_h;
+
+// Handle for 'OnReceived' delegate of 'Message' interface.
+typedef struct rpc_port_stub_Message_OnReceived_s *rpc_port_stub_Message_OnReceived_h;
+
+// Function for creating MessageBase handle.
+int rpc_port_stub_MessageBase_create(rpc_port_stub_MessageBase_h *h);
+
+// Function for destroying MessageBase handle.
+int rpc_port_stub_MessageBase_destroy(rpc_port_stub_MessageBase_h h);
+
+// Function for cloning MessageBase handle.
+int rpc_port_stub_MessageBase_clone(rpc_port_stub_MessageBase_h h, rpc_port_stub_MessageBase_h *clone);
+
+// Function for setting id to MessageBase handle.
+int rpc_port_stub_MessageBase_set_id(rpc_port_stub_MessageBase_h h, int value);
+
+// Function for getting id from MessageBase handle.
+int rpc_port_stub_MessageBase_get_id(rpc_port_stub_MessageBase_h h, int *value);
+
+// Function for setting name to MessageBase handle.
+int rpc_port_stub_MessageBase_set_name(rpc_port_stub_MessageBase_h h, const char *value);
+
+// Function for getting name from MessageBase handle.
+int rpc_port_stub_MessageBase_get_name(rpc_port_stub_MessageBase_h h, char **value);
+
+// Function for setting msg to MessageBase handle.
+int rpc_port_stub_MessageBase_set_msg(rpc_port_stub_MessageBase_h h, const char *value);
+
+// Function for getting msg to MessageBase handle.
+int rpc_port_stub_MessageBase_get_msg(rpc_port_stub_MessageBase_h h, char **value);
+
+// Function for creating MessageDerived handle.
+int rpc_port_stub_MessageDerived_create(rpc_port_stub_MessageDerived_h *h);
+
+// Function for destroying MessageDerived handle.
+int rpc_port_stub_MessageDerived_destroy(rpc_port_stub_MessageDerived_h h);
+
+// Function for cloning MessageDerived handle.
+int rpc_port_stub_MessageDerived_clone(rpc_port_stub_MessageDerived_h h, rpc_port_stub_MessageDerived_h *clone);
+
+// Function for setting id to MessageDerived handle.
+int rpc_port_stub_MessageDerived_set_id(rpc_port_stub_MessageDerived_h h, int value);
+
+// Function for getting id from MessageDerived handle.
+int rpc_port_stub_MessageDerived_get_id(rpc_port_stub_MessageDerived_h h, int *value);
+
+// Function for setting name to MessageDerived handle.
+int rpc_port_stub_MessageDerived_set_name(rpc_port_stub_MessageDerived_h h, const char *value);
+
+// Function for getting name from MessageDerived handle.
+int rpc_port_stub_MessageDerived_get_name(rpc_port_stub_MessageDerived_h h, char **value);
+
+// Function for setting msg to MessageDerived handle.
+int rpc_port_stub_MessageDerived_set_msg(rpc_port_stub_MessageDerived_h h, const char *value);
+
+// Function for getting msg to MessageDerived handle.
+int rpc_port_stub_MessageDerived_get_msg(rpc_port_stub_MessageDerived_h h, char **value);
+
+// Function for setting address to MessageDerived handle.
+int rpc_port_stub_MessageDerived_set_address(rpc_port_stub_MessageDerived_h h, const char *value);
+
+// Function for getting address from MessageDerived handle.
+int rpc_port_stub_MessageDerived_get_address(rpc_port_stub_MessageDerived_h h, char **value);
+
+// Function for creating Remote Exception handle.
+int rpc_port_stub_remote_exception_create(rpc_port_stub_remote_exception_h *h);
+
+// Function for setting cause to Remote Exception handle.
+int rpc_port_stub_remote_exception_set_cause(rpc_port_stub_remote_exception_h h, int cause);
+
+// Function for setting message to Remote Exception handle.
+int rpc_port_stub_remote_exception_set_message(rpc_port_stub_remote_exception_h h, const char *message);
+
+// Function for getting cause from Remote Exception handle.
+int rpc_port_stub_remote_exception_get_cause(rpc_port_stub_remote_exception_h h, int *cause);
+
+// Function for getting message from Remote Exception handle.
+int rpc_port_stub_remote_exception_get_message(rpc_port_stub_remote_exception_h, char **message);
+
+// Function for destroying Remote Exception handle.
+int rpc_port_stub_remote_exception_destroy(rpc_port_stub_remote_exception_h h);
+
+// Function for throwing Remote Exception handle.
+int rpc_port_stub_remote_exception_throw(rpc_port_stub_remote_exception_h h);
+
+// Called when client is connected.
+typedef void (*rpc_port_stub_Message_create_cb)(rpc_port_stub_Message_context_h context, void *user_data);
+
+// Called when client is disconnected.
+typedef void (*rpc_port_stub_Message_terminate_cb)(rpc_port_stub_Message_context_h context, void *user_data);
+
+// Called when retreiving contexts of Message handle.
+typedef bool (*rpc_port_stub_Message_context_cb)(rpc_port_stub_Message_context_h context, void *user_data);
+
+// Called when receiving 'Register' event from client.
+typedef int (*rpc_port_stub_Message_Register_cb)(rpc_port_stub_Message_context_h context, const char *sender, rpc_port_stub_Message_OnReceived_h callback, void *user_data);
+
+// Called when receiving 'Unregister' event from client.
+typedef void (*rpc_port_stub_Message_Unregister_cb)(rpc_port_stub_Message_context_h context, void *user_data);
+
+// Called when receiving 'Send' event from client.
+typedef int (*rpc_port_stub_Message_Send_cb)(rpc_port_stub_Message_context_h context, rpc_port_stub_MessageBase_h message, void *user_data);
+
+// Function for setting tag to Message context handle.
+int rpc_port_stub_Message_context_set_tag(rpc_port_stub_Message_context_h context, void *tag);
+
+// Function for getting tag from Message context handle.
+int rpc_port_stub_Message_context_get_tag(rpc_port_stub_Message_context_h context, void **tag);
+
+// Function for getting sender from Message context handle.
+int rpc_port_stub_Message_context_get_sender(rpc_port_stub_Message_context_h context, char **sender);
+
+// Function for getting instance from Message context handle.
+int rpc_port_stub_Message_context_get_instance(rpc_port_stub_Message_context_h context, char **instance);
+
+// Function for disconnecting from client.
+int rpc_port_stub_Message_context_disconnect(rpc_port_stub_Message_context_h context);
+
+// Function for creating OnReceived handle.
+int rpc_port_stub_Message_OnReceived_create(rpc_port_stub_Message_OnReceived_h *h);
+
+// Function for destroying OnReceived handle.
+int rpc_port_stub_Message_OnReceived_destroy(rpc_port_stub_Message_OnReceived_h h);
+
+// Function for cloning OnReceived handle.
+int rpc_port_stub_Message_OnReceived_clone(rpc_port_stub_Message_OnReceived_h h, rpc_port_stub_Message_OnReceived_h *clone);
+
+// Function for getting id from OnReceived handle.
+int rpc_port_stub_Message_OnReceived_get_id(rpc_port_stub_Message_OnReceived_h h, int *id);
+
+// Function for getting seq_id from OnReceived handle.
+int rpc_port_stub_Message_OnReceived_get_seq_id(rpc_port_stub_Message_OnReceived_h h, int *seq_id);
+
+// Function for checking once flag from OnReceived handle.
+int rpc_port_stub_Message_OnReceived_is_once(rpc_port_stub_Message_OnReceived_h h, bool *once);
+
+// Function for getting tag from OnReceived handle.
+int rpc_port_stub_Message_OnReceived_get_tag(rpc_port_stub_Message_OnReceived_h h, char **tag);
+
+// Function for invoking OnReceived callback function of 'Message' client.
+int rpc_port_stub_Message_OnReceived_invoke(rpc_port_stub_Message_OnReceived_h h, const char *sender, rpc_port_stub_MessageBase_h message);
+
+// Structure for receiving events of Message interface.
+typedef struct {
+ rpc_port_stub_Message_create_cb create;
+ rpc_port_stub_Message_terminate_cb terminate;
+ rpc_port_stub_Message_Register_cb Register;
+ rpc_port_stub_Message_Unregister_cb Unregister;
+ rpc_port_stub_Message_Send_cb Send;
+} rpc_port_stub_Message_callback_s;
+
+// Function for registering callback functions of Message interface to be invoked when events are received.
+int rpc_port_stub_Message_register(rpc_port_stub_Message_callback_s *callback, void *user_data);
+
+// Function for unregistering callback functions of Message interface.
+int rpc_port_stub_Message_unregister(void);
+
+// Function for retreving connected context of clients of Message interface.
+int rpc_port_stub_Message_foreach_context(rpc_port_stub_Message_context_cb callback, void *user_data);
+
+// Function for getting client number from Message interface.
+int rpc_port_stub_Message_get_client_number(unsigned int *client_number);
+```
+
+**C++**
+```cpp
+// class for Bundle.
+class Bundle final {
+ public:
+ Bundle();
+ explicit Bundle(bundle* handle, bool copy = true, bool own = true);
+ Bundle(std::string raw);
+ ~Bundle();
+
+ Bundle(const Bundle& b);
+ Bundle& operator = (const Bundle& b);
+ Bundle(Bundle&& b) noexcept;
+ Bundle& operator = (Bundle&&) noexcept;
+
+ bundle* GetHandle() const;
+ bundle* Detach();
+};
+
+
+// class for File.
+class File final {
+ public:
+ File(std::string filename = "");
+
+ const std::string& GetFileName() const;
+ int Share(rpc_port_h port);
+};
+
+// class for 'MessageBase' structure.
+class MessageBase {
+ public:
+ MessageBase();
+ MessageBase(int id, std::string name, std::string msg);
+
+ int Getid() const;
+ void Setid(int id);
+ const std::string& Getname() const;
+ void Setname(std::string name);
+ const std::string& Getmsg() const;
+ void Setmsg(std::string msg);
+};
+
+// class for 'MessageDerived' structure.
+class MessageDerived : public MessageBase {
+ public:
+ MessageDerived();
+ MessageDerived(int id, std::string name, std::string msg, std::string address);
+
+ const std::string& Getaddress() const;
+ void Setaddress(std::string address);
+};
+
+namespace stub {
+
+class Exception {};
+class NotConnectedSocketException : public Exception {};
+class InvalidProtocolException : public Exception {};
+class InvalidIOException : public Exception {};
+class PermissionDeniedException : public Exception {};
+class InvalidIDException : public Exception {};
+class InvalidArgumentException : public Exception {};
+class OutOfMemoryException : public Exception {};
+
+// class for Remote Exception.
+class RemoteException : public Exception {
+ public:
+ RemoteException();
+ RemoteException(std::string message);
+ RemoteException(int cause, std::string message);
+
+ int GetCause() const;
+ const std::string& GetMessage() const;
+};
+
+// class for 'Message' interface.
+class Message : public LocalExecution::IEvent {
+ public:
+ class ServiceBase;
+ class CallbackBase {
+ public:
+ CallbackBase(int delegate_id, bool once);
+ CallbackBase() = default;
+ virtual ~CallbackBase() = default;
+
+ int GetId() const;
+ void SetId(int id);
+ int GetSeqId() const;
+ void SetSeqId(int seq_id);
+ bool IsOnce() const;
+ void SetOnce(bool once);
+
+ std::string GetTag() const;
+
+ void SetContext(void* context);
+ void* GetContext() const;
+ };
+
+ class OnReceived : public CallbackBase {
+ public:
+ OnReceived(rpc_port_h callback_port, std::weak_ptr<ServiceBase> service) : CallbackBase(static_cast<int>(DelegateId::OnReceived), false), callback_port_(callback_port), service_(std::move(service)) {}
+
+ void Invoke(std::string sender, MessageBase message);
+ };
+
+ class ServiceBase : public std::enable_shared_from_this<ServiceBase> {
+ public:
+ class Factory {
+ public:
+ virtual ~Factory() = default;
+ virtual std::unique_ptr<ServiceBase> CreateService(std::string sender, std::string instance) = 0;
+ };
+
+ virtual ~ServiceBase() = default;
+ const std::string& GetSender() const {
+ return sender_;
+ }
+ const std::string& GetInstance() const {
+ return instance_;
+ }
+
+ void SetPort(rpc_port_h port);
+ void Disconnect();
+ virtual void OnCreate() = 0;
+ virtual void OnTerminate() = 0;
+ void SetContext(void* context);
+ void* GetContext() const;
+ void Dispatch(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel, std::shared_ptr<ServiceBase> service);
+ void Dispatch(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel);
+
+ virtual int Register(std::string sender, std::unique_ptr<OnReceived> callback) = 0;
+ virtual void Unregister() = 0;
+ virtual int Send(MessageBase message) = 0;
+
+ protected:
+ ServiceBase(std::string sender, std::string instance);
+ };
+
+ // Constructor.
+ Message();
+
+ // Destructor.
+ ~Message();
+
+ // Method for listening Message events.
+ void Listen(std::shared_ptr<ServiceBase::Factory> service_factory);
+
+ // Method for getting instance of ServiceBase of clients.
+ const std::list<std::shared_ptr<ServiceBase>>& GetServices() const {
+ return services_;
+ }
+};
+
+} // namespace stub
+```
+
+**C#**
+```csharp
+// class for 'MessageBase' structure.
+public class MessageBase
+{
+ public int id;
+ public string name;
+ public string msg;
+
+ public MessageBase();
+}
+
+// class for 'MessageDerived' structure.
+public class MessageDerived : MessageBase
+{
+ public string address;
+
+ public MessageDerived();
+}
+
+// class for Remote Exception.
+public class RemoteException : Exception
+{
+ public RemoteException();
+ public RemoteException(string message);
+ public RemoteException(string message, int cause);
+ public new string Message;
+ public int Cause;
+}
+
+namespace Stub
+{
+ public sealed class Message : StubBase
+ {
+ public abstract class ServiceBase
+ {
+ public string Sender;
+ public string Instance;
+ public Port Port;
+ protected ServiceBase();
+ public void Disconnect();
+ public abstract void OnCreate();
+ public abstract void OnTerminate();
+ public abstract int Register(string sender, OnReceived callback);
+ public abstract void Unregister();
+ public abstract int Send(MessageBase message);
+ }
+
+ public class CallbackBase
+ {
+ public string Tag;
+ public CallbackBase(int delegateId, bool once);
+ }
+
+ public sealed class OnReceived : CallbackBase
+ {
+ public void Invoke(string sender, MessageBase message);
+ }
+
+ // Called when client sends a request.
+ protected override bool OnReceivedEvent(string sender, string instance, Port port);
+
+ // Called when client is connected.
+ protected override void OnConnectedEvent(string sender, string instance);
+
+ // Called when client is disconnected.
+ protected override void OnDisconnectedEvent(string sender, string instance);
+
+ // Constructor.
+ public Message();
+
+ // Method for listening events of Message interface.
+ public void Listen(Type serviceType);
+
+ // Method for getting instance of connected clients.
+ public IEnumerable<ServiceBase> GetServices();
+
+ ...
+ }
+}
+```
diff --git a/idlc/CMakeLists.txt b/idlc/CMakeLists.txt
index 1d60f9f..e55bfed 100644
--- a/idlc/CMakeLists.txt
+++ b/idlc/CMakeLists.txt
@@ -17,7 +17,8 @@ ENDIF(DEFINED BUILD_WIN)
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wno-unused-function -Wno-sign-compare")
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++11")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++17")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}")
SET(CMAKE_EXE_LINKER_FLAGS "-static-libstdc++ -static-libgcc")
SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
@@ -27,6 +28,9 @@ ADD_DEFINITIONS("-DFULLVER=\"${FULLVER}\"")
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCES)
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ast AST_GEN_SOURCES)
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/gen GEN_SOURCES)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/gen/version2 GEN_VERSION2_SOURCES)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/gen_mqtt_plugin GEN_MQTT_PLUGIN_SOURCES)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/gen_cion GEN_CION_SOURCES)
BISON_TARGET(TIDLC ${CMAKE_CURRENT_SOURCE_DIR}/ast/tidlc.yy ${CMAKE_CURRENT_SOURCE_DIR}/ast/tidlc_y.cpp)
FLEX_TARGET(TIDLC ${CMAKE_CURRENT_SOURCE_DIR}/ast/tidlc.ll ${CMAKE_CURRENT_SOURCE_DIR}/ast/tidlc_l.cpp)
@@ -35,10 +39,13 @@ ADD_EXECUTABLE(${PROJECT_NAME}
${AST_GEN_SOURCES}
${BISON_TIDLC_OUTPUTS}
${FLEX_TIDLC_OUTPUTS}
+ ${GEN_MQTT_PLUGIN_SOURCES}
+ ${GEN_CION_SOURCES}
${GEN_SOURCES}
${SOURCES}
- )
+ ${GEN_VERSION2_SOURCES}
+)
+
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIBPKGS_LIBRARIES} ${EXE_STATIC})
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
-
diff --git a/idlc/ast/attribute.cc b/idlc/ast/attribute.cc
index 6fcf86d..88e6d82 100644
--- a/idlc/ast/attribute.cc
+++ b/idlc/ast/attribute.cc
@@ -20,7 +20,7 @@
namespace tidl {
-Attribute::Attribute(std::string key, std::string value, unsigned line)
+Attribute::Attribute(std::string key, std::string value, unsigned int line)
: key_(std::move(key)), value_(std::move(value)), line_(line) {
}
@@ -32,26 +32,31 @@ const std::string& Attribute::GetValue() const {
return value_;
}
-const unsigned Attribute::GetLine() const {
+const unsigned int Attribute::GetLine() const {
return line_;
}
-void Attributes::Add(Attribute* attr) {
- attrs_.emplace_back(attr);
+void Attributes::Add(std::unique_ptr<Attribute> attr) {
+ attrs_.push_back(std::move(attr));
}
-const std::list<std::unique_ptr<Attribute>>& Attributes::GetAttrs() const {
- return attrs_;
-}
-
-bool Attributes::Exist(Attribute* attr) const {
+bool Attributes::Exist(const Attribute& attr) const {
for (auto& a : attrs_) {
- if (a->GetKey() == attr->GetKey() &&
- a->GetValue() == attr->GetValue())
+ if (a->GetKey() == attr.GetKey() &&
+ a->GetValue() == attr.GetValue())
return true;
}
return false;
}
+std::list<std::unique_ptr<Attribute>>::const_iterator
+Attributes::begin() const {
+ return attrs_.cbegin();
+}
+
+std::list<std::unique_ptr<Attribute>>::const_iterator Attributes::end() const {
+ return attrs_.cend();
+}
+
} // namespace tidl
diff --git a/idlc/ast/attribute.h b/idlc/ast/attribute.h
index 360348e..2cf95cc 100644
--- a/idlc/ast/attribute.h
+++ b/idlc/ast/attribute.h
@@ -25,23 +25,24 @@ namespace tidl {
class Attribute {
public:
- Attribute(std::string key, std::string value, unsigned line);
+ Attribute(std::string key, std::string value, unsigned int line);
const std::string& GetKey() const;
const std::string& GetValue() const;
- const unsigned GetLine() const;
+ const unsigned int GetLine() const;
private:
std::string key_;
std::string value_;
- unsigned line_;
+ unsigned int line_;
};
class Attributes {
public:
- void Add(Attribute* attr);
- const std::list<std::unique_ptr<Attribute>>& GetAttrs() const;
- bool Exist(Attribute* attr) const;
+ void Add(std::unique_ptr<Attribute> attr);
+ bool Exist(const Attribute& attr) const;
+ std::list<std::unique_ptr<Attribute>>::const_iterator begin() const;
+ std::list<std::unique_ptr<Attribute>>::const_iterator end() const;
private:
std::list<std::unique_ptr<Attribute>> attrs_;
diff --git a/idlc/ast/block.cc b/idlc/ast/block.cc
index 3630155..0724e0f 100644
--- a/idlc/ast/block.cc
+++ b/idlc/ast/block.cc
@@ -21,10 +21,10 @@
namespace tidl {
-Block::Block(std::string id, Block::Type type,
- std::string comments, unsigned line)
- : id_(std::move(id)), type_(type), comments_(std::move(comments)),
- line_(line) {}
+Block::Block(std::string id, Block::Type type, Enums* enums,
+ std::string comments, unsigned int line)
+ : id_(std::move(id)), type_(type), enums_(enums),
+ comments_(std::move(comments)), line_(line) {}
const std::string& Block::GetID() const {
return id_;
@@ -34,7 +34,7 @@ const Block::Type& Block::GetType() const {
return type_;
}
-const unsigned Block::GetLine() const {
+const unsigned int Block::GetLine() const {
return line_;
}
@@ -42,4 +42,7 @@ const std::string& Block::GetComments() const {
return comments_;
}
+const Enums& Block::GetEnums() const {
+ return *enums_;
+}
} // namespace tidl
diff --git a/idlc/ast/block.h b/idlc/ast/block.h
index ea2e19d..c83402d 100644
--- a/idlc/ast/block.h
+++ b/idlc/ast/block.h
@@ -21,6 +21,7 @@
#include <memory>
#include "idlc/ast/declaration.h"
+#include "idlc/ast/enum.h"
namespace tidl {
@@ -31,20 +32,23 @@ class Block {
TYPE_STRUCTURE,
};
- Block(std::string id, Block::Type type, std::string comments,
- unsigned line);
+ Block(std::string id, Block::Type type, Enums* enums,
+ std::string comments, unsigned int line);
+
virtual ~Block() = default;
const std::string& GetID() const;
const Block::Type& GetType() const;
- const unsigned GetLine() const;
+ const unsigned int GetLine() const;
const std::string& GetComments() const;
+ const Enums& GetEnums() const;
private:
std::string id_;
Block::Type type_;
+ std::unique_ptr<Enums> enums_;
std::string comments_;
- unsigned line_;
+ unsigned int line_;
};
} // namespace tidl
diff --git a/idlc/ast/declaration.cc b/idlc/ast/declaration.cc
index 400225a..b3c1b47 100644
--- a/idlc/ast/declaration.cc
+++ b/idlc/ast/declaration.cc
@@ -22,15 +22,17 @@
namespace tidl {
-Declaration::Declaration(std::string id, BaseType* ret_type,
- Parameters* params, std::string comments,
- unsigned line, MethodType mtype)
+Declaration::Declaration(std::string id, std::unique_ptr<BaseType> ret_type,
+ std::unique_ptr<Parameters> params, std::string comments,
+ unsigned int line, MethodType mtype, Attributes* attrs)
: id_(std::move(id)),
- ret_type_(ret_type),
- params_(params),
+ ret_type_(std::move(ret_type)),
+ params_(std::move(params)),
comments_(std::move(comments)),
line_(line),
- mtype_(mtype) {}
+ mtype_(mtype),
+ attrs_(attrs) {
+}
const std::string& Declaration::GetID() const {
return id_;
@@ -44,7 +46,7 @@ const Parameters& Declaration::GetParameters() const {
return *params_;
}
-const unsigned Declaration::GetLine() const {
+const unsigned int Declaration::GetLine() const {
return line_;
}
@@ -52,21 +54,31 @@ const std::string& Declaration::GetComments() const {
return comments_;
}
-void Declarations::Add(Declaration* decl) {
- decls_.emplace_back(decl);
+const Attributes& Declaration::GetAttributes() const {
+ return *attrs_;
}
-const std::list<std::unique_ptr<Declaration>>& Declarations::GetDecls() const {
- return decls_;
+void Declarations::Add(std::unique_ptr<Declaration> decl) {
+ decls_.push_back(std::move(decl));
}
-bool Declarations::Exist(Declaration* decl) const {
+bool Declarations::Exist(const Declaration& decl) const {
for (auto& d : decls_) {
- if (d->GetID() == decl->GetID())
+ if (d->GetID() == decl.GetID())
return true;
}
return false;
}
+std::list<std::unique_ptr<Declaration>>::const_iterator
+Declarations::begin() const {
+ return decls_.cbegin();
+}
+
+std::list<std::unique_ptr<Declaration>>::const_iterator
+Declarations::end() const {
+ return decls_.cend();
+}
+
} // namespace tidl
diff --git a/idlc/ast/declaration.h b/idlc/ast/declaration.h
index 13f81dd..495fbf7 100644
--- a/idlc/ast/declaration.h
+++ b/idlc/ast/declaration.h
@@ -21,6 +21,7 @@
#include <list>
#include <memory>
+#include "idlc/ast/attribute.h"
#include "idlc/ast/type.h"
#include "idlc/ast/parameter.h"
@@ -34,31 +35,35 @@ class Declaration {
DELEGATE
};
- Declaration(std::string id, BaseType* ret_type, Parameters* params,
- std::string comments, unsigned line,
- MethodType mtype = MethodType::SYNC);
+ Declaration(std::string id, std::unique_ptr<BaseType> ret_type,
+ std::unique_ptr<Parameters> params, std::string comments,
+ unsigned int line, MethodType mtype = MethodType::SYNC,
+ Attributes* attr = new Attributes());
const std::string& GetID() const;
const BaseType& GetType() const;
const Parameters& GetParameters() const;
MethodType GetMethodType() const { return mtype_; }
- const unsigned GetLine() const;
+ const unsigned int GetLine() const;
const std::string& GetComments() const;
+ const Attributes& GetAttributes() const;
private:
std::string id_;
std::unique_ptr<BaseType> ret_type_;
std::unique_ptr<Parameters> params_;
std::string comments_;
- unsigned line_;
+ unsigned int line_;
MethodType mtype_;
+ std::unique_ptr<Attributes> attrs_;
};
class Declarations {
public:
- void Add(Declaration* decl);
- const std::list<std::unique_ptr<Declaration>>& GetDecls() const;
- bool Exist(Declaration* decl) const;
+ void Add(std::unique_ptr<Declaration> decl);
+ bool Exist(const Declaration& decl) const;
+ std::list<std::unique_ptr<Declaration>>::const_iterator begin() const;
+ std::list<std::unique_ptr<Declaration>>::const_iterator end() const;
private:
std::list<std::unique_ptr<Declaration>> decls_;
diff --git a/idlc/ast/document.cc b/idlc/ast/document.cc
index d59e1bb..c726a2d 100644
--- a/idlc/ast/document.cc
+++ b/idlc/ast/document.cc
@@ -25,7 +25,7 @@ void Document::AddBlock(Block* block) {
blocks_.emplace_back(block);
}
-const std::list<std::unique_ptr<Block>>& Document::GetBlocks() const {
+const std::list<std::shared_ptr<Block>>& Document::GetBlocks() const {
return blocks_;
}
@@ -39,4 +39,13 @@ bool Document::ExistBlock(Block* block) const {
return false;
}
+std::shared_ptr<Block> Document::FindBlock(const std::string& id) {
+ for (auto& b : blocks_) {
+ if (b->GetID() == id)
+ return b;
+ }
+
+ return nullptr;
+}
+
} // namespace tidl
diff --git a/idlc/ast/document.h b/idlc/ast/document.h
index 2c8a3d6..a2a4f6e 100644
--- a/idlc/ast/document.h
+++ b/idlc/ast/document.h
@@ -19,6 +19,7 @@
#include <list>
#include <memory>
+#include <string>
#include "idlc/ast/interface.h"
@@ -29,11 +30,12 @@ class Document {
Document();
void AddBlock(Block* block);
- const std::list<std::unique_ptr<Block>>& GetBlocks() const;
+ const std::list<std::shared_ptr<Block>>& GetBlocks() const;
bool ExistBlock(Block* block) const;
+ std::shared_ptr<Block> FindBlock(const std::string& id);
private:
- std::list<std::unique_ptr<Block>> blocks_;
+ std::list<std::shared_ptr<Block>> blocks_;
};
} // namespace tidl
diff --git a/idlc/ast/element.cc b/idlc/ast/element.cc
index 1594a2a..580a764 100644
--- a/idlc/ast/element.cc
+++ b/idlc/ast/element.cc
@@ -22,7 +22,7 @@
namespace tidl {
Element::Element(std::string id, BaseType* type,
- std::string comments, unsigned line)
+ std::string comments, unsigned int line)
: id_(std::move(id)), type_(type), comments_(std::move(comments)),
line_(line) {}
@@ -34,7 +34,7 @@ const BaseType& Element::GetType() const {
return *type_;
}
-const unsigned Element::GetLine() const {
+const unsigned int Element::GetLine() const {
return line_;
}
@@ -42,21 +42,30 @@ const std::string& Element::GetComments() const {
return comments_;
}
-void Elements::Add(Element* elm) {
- elms_.emplace_back(elm);
+void Elements::Add(std::shared_ptr<Element> elm) {
+ elms_.push_back(std::move(elm));
}
-const std::list<std::unique_ptr<Element>>& Elements::GetElms() const {
- return elms_;
-}
-
-bool Elements::Exist(Element* elm) const {
+bool Elements::Exist(const Element& elm) const {
for (auto& e : elms_) {
- if (e->GetID() == elm->GetID())
+ if (e->GetID() == elm.GetID())
return true;
}
return false;
}
+std::list<std::shared_ptr<Element>>::const_iterator
+Elements::begin() const {
+ return elms_.cbegin();
+}
+
+std::list<std::shared_ptr<Element>>::const_iterator Elements::end() const {
+ return elms_.cend();
+}
+
+bool Elements::Empty() const {
+ return elms_.empty();
+}
+
} // namespace tidl
diff --git a/idlc/ast/element.h b/idlc/ast/element.h
index ca1b56c..531617b 100644
--- a/idlc/ast/element.h
+++ b/idlc/ast/element.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef IDLC_ELEMENT_H_
-#define IDLC_ELEMENT_H_
+#ifndef IDLC_AST_ELEMENT_H_
+#define IDLC_AST_ELEMENT_H_
#include <string>
#include <list>
@@ -29,30 +29,32 @@ namespace tidl {
class Element {
public:
Element(std::string id, BaseType* type,
- std::string comments, unsigned line);
+ std::string comments, unsigned int line);
const std::string& GetID() const;
const BaseType& GetType() const;
- const unsigned GetLine() const;
+ const unsigned int GetLine() const;
const std::string& GetComments() const;
private:
std::string id_;
std::unique_ptr<BaseType> type_;
std::string comments_;
- unsigned line_;
+ unsigned int line_;
};
class Elements {
public:
- void Add(Element* elm);
- const std::list<std::unique_ptr<Element>>& GetElms() const;
- bool Exist(Element* elm) const;
+ void Add(std::shared_ptr<Element> elm);
+ bool Exist(const Element& elm) const;
+ std::list<std::shared_ptr<Element>>::const_iterator begin() const;
+ std::list<std::shared_ptr<Element>>::const_iterator end() const;
+ bool Empty() const;
private:
- std::list<std::unique_ptr<Element>> elms_;
+ std::list<std::shared_ptr<Element>> elms_;
};
} // namespace tidl
-#endif // IDLC_ELEMENT_H_
+#endif // IDLC_AST_ELEMENT_H_
diff --git a/idlc/ast/enum.cc b/idlc/ast/enum.cc
new file mode 100755
index 0000000..3798ca3
--- /dev/null
+++ b/idlc/ast/enum.cc
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utility>
+
+#include "idlc/ast/enum.h"
+
+namespace tidl {
+
+Field::Field(std::string id, std::string value, std::string comments,
+ unsigned int line)
+ : id_(std::move(id)),
+ value_(std::move(value)),
+ comments_(std::move(comments)),
+ line_(line) {}
+
+const std::string& Field::GetID() const { return id_; }
+
+const std::string& Field::GetValue() const { return value_; }
+
+const unsigned int Field::GetLine() const { return line_; }
+
+const std::string& Field::GetComments() const { return comments_; }
+
+void Fields::Add(std::unique_ptr<Field> field) {
+ field_.push_back(std::move(field));
+}
+
+bool Fields::Exist(const Field& field) const {
+ for (auto& e : field_) {
+ if (e->GetID() == field.GetID()) return true;
+ }
+
+ return false;
+}
+
+std::list<std::unique_ptr<Field>>::const_iterator Fields::begin() const {
+ return field_.cbegin();
+}
+
+std::list<std::unique_ptr<Field>>::const_iterator Fields::end() const {
+ return field_.cend();
+}
+
+Enum::Enum(std::string id, Fields* fields, std::string comments,
+ unsigned int line)
+ : id_(std::move(id)), fields_(fields), comments_(std::move(comments)),
+ line_(line) {}
+
+const std::string& Enum::GetID() const { return id_; }
+
+const unsigned int Enum::GetLine() const { return line_; }
+
+const std::string& Enum::GetComments() const { return comments_; }
+
+const Fields& Enum::GetFields() const { return *fields_; }
+
+void Enums::Add(std::unique_ptr<Enum> elm) { enums_.push_back(std::move(elm)); }
+
+bool Enums::Exist(const Enum& elm) const {
+ for (auto& e : enums_) {
+ if (e->GetID() == elm.GetID()) return true;
+ }
+
+ return false;
+}
+
+bool Enums::Exist(const std::string& id) const {
+ for (auto& e : enums_) {
+ if (e->GetID() == id) return true;
+ }
+
+ return false;
+}
+
+std::list<std::unique_ptr<Enum>>::const_iterator Enums::begin() const {
+ return enums_.cbegin();
+}
+
+std::list<std::unique_ptr<Enum>>::const_iterator Enums::end() const {
+ return enums_.cend();
+}
+
+} // namespace tidl
diff --git a/idlc/ast/enum.h b/idlc/ast/enum.h
new file mode 100755
index 0000000..3edb656
--- /dev/null
+++ b/idlc/ast/enum.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_ENUM_H_
+#define IDLC_ENUM_H_
+
+#include <string>
+#include <list>
+#include <memory>
+
+namespace tidl {
+
+class Field {
+ public:
+ Field(std::string id, std::string value, std::string comments,
+ unsigned int line);
+
+ const std::string& GetID() const;
+ const std::string& GetValue() const;
+ const unsigned int GetLine() const;
+ const std::string& GetComments() const;
+
+ private:
+ std::string id_;
+ std::string value_;
+ std::string comments_;
+ unsigned int line_;
+};
+
+class Fields {
+ public:
+ void Add(std::unique_ptr<Field> field);
+ bool Exist(const Field& field) const;
+ std::list<std::unique_ptr<Field>>::const_iterator begin() const;
+ std::list<std::unique_ptr<Field>>::const_iterator end() const;
+
+ private:
+ std::list<std::unique_ptr<Field>> field_;
+};
+
+class Enum {
+ public:
+ Enum(std::string id, Fields* fields, std::string comments, unsigned int line);
+
+ const std::string& GetID() const;
+ const unsigned int GetLine() const;
+ const std::string& GetComments() const;
+ const Fields& GetFields() const;
+
+ private:
+ std::string id_;
+ std::unique_ptr<Fields> fields_;
+ std::string comments_;
+ unsigned int line_;
+};
+
+class Enums {
+ public:
+ void Add(std::unique_ptr<Enum> elm);
+ bool Exist(const Enum& elm) const;
+ bool Exist(const std::string& id) const;
+ std::list<std::unique_ptr<Enum>>::const_iterator begin() const;
+ std::list<std::unique_ptr<Enum>>::const_iterator end() const;
+
+ private:
+ std::list<std::unique_ptr<Enum>> enums_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_ENUM_H_
diff --git a/idlc/ast/interface.cc b/idlc/ast/interface.cc
index 40587a2..46013d9 100644
--- a/idlc/ast/interface.cc
+++ b/idlc/ast/interface.cc
@@ -23,9 +23,9 @@
namespace tidl {
-Interface::Interface(std::string id, Declarations* decls, std::string comments,
- Attributes* attrs, unsigned line)
- : Block::Block(std::move(id), Block::TYPE_INTERFACE,
+Interface::Interface(std::string id, Declarations* decls, Enums* enums,
+ std::string comments, Attributes* attrs, unsigned line)
+ : Block::Block(std::move(id), Block::TYPE_INTERFACE, enums,
std::move(comments), line),
decls_(decls),
attrs_(attrs) {}
diff --git a/idlc/ast/interface.h b/idlc/ast/interface.h
index d7463f7..ee4f4ed 100644
--- a/idlc/ast/interface.h
+++ b/idlc/ast/interface.h
@@ -28,8 +28,8 @@ namespace tidl {
class Interface : public Block {
public:
- Interface(std::string id, Declarations* decls, std::string comments,
- Attributes* attrs, unsigned line);
+ Interface(std::string id, Declarations* decls, Enums* enums,
+ std::string comments, Attributes* attrs, unsigned line);
const Declarations& GetDeclarations() const;
const Attributes& GetAttributes() const;
diff --git a/idlc/ast/location.hh b/idlc/ast/location.hh
index 7971b93..c045e77 100644
--- a/idlc/ast/location.hh
+++ b/idlc/ast/location.hh
@@ -1,8 +1,8 @@
-// A Bison parser, made by GNU Bison 3.0.4.
+// A Bison parser, made by GNU Bison 3.5.1.
// Locations for Bison parsers in C++
-// Copyright (C) 2002-2015 Free Software Foundation, Inc.
+// Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -31,27 +31,153 @@
// version 2.2 of Bison.
/**
- ** \file /home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/location.hh
+ ** \file /opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/location.hh
** Define the yy::location class.
*/
-#ifndef YY_YY_HOME_HYUNHO_FULL_SOURCES_TIZEN_TIDL_THREAD_PROJ_TIDL_IDLC_AST_LOCATION_HH_INCLUDED
-# define YY_YY_HOME_HYUNHO_FULL_SOURCES_TIZEN_TIDL_THREAD_PROJ_TIDL_IDLC_AST_LOCATION_HH_INCLUDED
+#ifndef YY_YY_OPT_DATA_TIZEN_PUBLIC_PLATFORM_CORE_APPFW_TIDL_IDLC_AST_LOCATION_HH_INCLUDED
+# define YY_YY_OPT_DATA_TIZEN_PUBLIC_PLATFORM_CORE_APPFW_TIDL_IDLC_AST_LOCATION_HH_INCLUDED
-# include "position.hh"
+# include <iostream>
+# include <string>
+# ifndef YY_NULLPTR
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# else
+# define YY_NULLPTR ((void*)0)
+# endif
+# endif
namespace yy {
-#line 46 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/location.hh" // location.cc:296
- /// Abstract a location.
+#line 58 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/location.hh"
+
+ /// A point in a source file.
+ class position
+ {
+ public:
+ /// Type for line and column numbers.
+ typedef int counter_type;
+
+ /// Initialization.
+ void initialize (std::string* fn = YY_NULLPTR,
+ counter_type l = 1,
+ counter_type c = 1)
+ {
+ filename = fn;
+ line = l;
+ column = c;
+ }
+
+ /** \name Line and Column related manipulators
+ ** \{ */
+ /// (line related) Advance to the COUNT next lines.
+ void lines (counter_type count = 1)
+ {
+ if (count)
+ {
+ column = 1;
+ line = add_ (line, count, 1);
+ }
+ }
+
+ /// (column related) Advance to the COUNT next columns.
+ void columns (counter_type count = 1)
+ {
+ column = add_ (column, count, 1);
+ }
+ /** \} */
+
+ /// File name to which this position refers.
+ std::string* filename;
+ /// Current line number.
+ counter_type line;
+ /// Current column number.
+ counter_type column;
+
+ private:
+ /// Compute max (min, lhs+rhs).
+ static counter_type add_ (counter_type lhs, counter_type rhs, counter_type min)
+ {
+ return lhs + rhs < min ? min : lhs + rhs;
+ }
+ };
+
+ /// Add \a width columns, in place.
+ inline position&
+ operator+= (position& res, position::counter_type width)
+ {
+ res.columns (width);
+ return res;
+ }
+
+ /// Add \a width columns.
+ inline position
+ operator+ (position res, position::counter_type width)
+ {
+ return res += width;
+ }
+
+ /// Subtract \a width columns, in place.
+ inline position&
+ operator-= (position& res, position::counter_type width)
+ {
+ return res += -width;
+ }
+
+ /// Subtract \a width columns.
+ inline position
+ operator- (position res, position::counter_type width)
+ {
+ return res -= width;
+ }
+
+ /// Compare two position objects.
+ inline bool
+ operator== (const position& pos1, const position& pos2)
+ {
+ return (pos1.line == pos2.line
+ && pos1.column == pos2.column
+ && (pos1.filename == pos2.filename
+ || (pos1.filename && pos2.filename
+ && *pos1.filename == *pos2.filename)));
+ }
+
+ /// Compare two position objects.
+ inline bool
+ operator!= (const position& pos1, const position& pos2)
+ {
+ return !(pos1 == pos2);
+ }
+
+ /** \brief Intercept output stream redirection.
+ ** \param ostr the destination output stream
+ ** \param pos a reference to the position to redirect
+ */
+ template <typename YYChar>
+ std::basic_ostream<YYChar>&
+ operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
+ {
+ if (pos.filename)
+ ostr << *pos.filename << ':';
+ return ostr << pos.line << '.' << pos.column;
+ }
+
+ /// Two points in a source file.
class location
{
public:
+ /// Type for line and column numbers.
+ typedef position::counter_type counter_type;
/// Initialization.
void initialize (std::string* f = YY_NULLPTR,
- unsigned int l = 1u,
- unsigned int c = 1u)
+ counter_type l = 1,
+ counter_type c = 1)
{
begin.initialize (f, l, c);
end = begin;
@@ -67,13 +193,13 @@ namespace yy {
}
/// Extend the current location to the COUNT next columns.
- void columns (int count = 1)
+ void columns (counter_type count = 1)
{
end += count;
}
/// Extend the current location to the COUNT next lines.
- void lines (int count = 1)
+ void lines (counter_type count = 1)
{
end.lines (count);
}
@@ -88,39 +214,45 @@ namespace yy {
};
/// Join two locations, in place.
- inline location& operator+= (location& res, const location& end)
+ inline location&
+ operator+= (location& res, const location& end)
{
res.end = end.end;
return res;
}
/// Join two locations.
- inline location operator+ (location res, const location& end)
+ inline location
+ operator+ (location res, const location& end)
{
return res += end;
}
/// Add \a width columns to the end position, in place.
- inline location& operator+= (location& res, int width)
+ inline location&
+ operator+= (location& res, location::counter_type width)
{
res.columns (width);
return res;
}
/// Add \a width columns to the end position.
- inline location operator+ (location res, int width)
+ inline location
+ operator+ (location res, location::counter_type width)
{
return res += width;
}
/// Subtract \a width columns to the end position, in place.
- inline location& operator-= (location& res, int width)
+ inline location&
+ operator-= (location& res, location::counter_type width)
{
return res += -width;
}
/// Subtract \a width columns to the end position.
- inline location operator- (location res, int width)
+ inline location
+ operator- (location res, location::counter_type width)
{
return res -= width;
}
@@ -146,10 +278,11 @@ namespace yy {
** Avoid duplicate information.
*/
template <typename YYChar>
- inline std::basic_ostream<YYChar>&
+ std::basic_ostream<YYChar>&
operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
{
- unsigned int end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
+ location::counter_type end_col
+ = 0 < loc.end.column ? loc.end.column - 1 : 0;
ostr << loc.begin;
if (loc.end.filename
&& (!loc.begin.filename
@@ -162,7 +295,7 @@ namespace yy {
return ostr;
}
-
} // yy
-#line 168 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/location.hh" // location.cc:296
-#endif // !YY_YY_HOME_HYUNHO_FULL_SOURCES_TIZEN_TIDL_THREAD_PROJ_TIDL_IDLC_AST_LOCATION_HH_INCLUDED
+#line 300 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/location.hh"
+
+#endif // !YY_YY_OPT_DATA_TIZEN_PUBLIC_PLATFORM_CORE_APPFW_TIDL_IDLC_AST_LOCATION_HH_INCLUDED
diff --git a/idlc/ast/parameter.cc b/idlc/ast/parameter.cc
index 1199bb2..0c564c5 100644
--- a/idlc/ast/parameter.cc
+++ b/idlc/ast/parameter.cc
@@ -21,7 +21,7 @@
namespace tidl {
-Parameter::Parameter(std::string id, ParameterType* type, unsigned line)
+Parameter::Parameter(std::string id, ParameterType* type, unsigned int line)
: type_(type), id_(std::move(id)), line_(line) {}
const std::string& Parameter::GetID() const {
@@ -32,21 +32,17 @@ const ParameterType& Parameter::GetParameterType() const {
return *type_;
}
-const unsigned Parameter::GetLine() const {
+const unsigned int Parameter::GetLine() const {
return line_;
}
-void Parameters::Add(Parameter* param) {
- params_.emplace_back(param);
+void Parameters::Add(std::unique_ptr<Parameter> param) {
+ params_.push_back(std::move(param));
}
-const std::list<std::unique_ptr<Parameter>>& Parameters::GetParams() const {
- return params_;
-}
-
-bool Parameters::Exist(Parameter* param) const {
+bool Parameters::Exist(const Parameter& param) const {
for (auto& p : params_) {
- if (p->GetID() == param->GetID())
+ if (p->GetID() == param.GetID())
return true;
}
@@ -62,5 +58,13 @@ bool Parameters::Exist(std::string type_name) const {
return false;
}
-} // namespace tidl
+std::list<std::unique_ptr<Parameter>>::const_iterator
+Parameters::begin() const {
+ return params_.cbegin();
+}
+std::list<std::unique_ptr<Parameter>>::const_iterator Parameters::end() const {
+ return params_.cend();
+}
+
+} // namespace tidl
diff --git a/idlc/ast/parameter.h b/idlc/ast/parameter.h
index 2e7abe8..2e32d65 100644
--- a/idlc/ast/parameter.h
+++ b/idlc/ast/parameter.h
@@ -27,24 +27,25 @@ namespace tidl {
class Parameter {
public:
- Parameter(std::string id, ParameterType* type, unsigned line);
+ Parameter(std::string id, ParameterType* type, unsigned int line);
const std::string& GetID() const;
const ParameterType& GetParameterType() const;
- const unsigned GetLine() const;
+ const unsigned int GetLine() const;
private:
std::unique_ptr<ParameterType> type_;
std::string id_;
- unsigned line_;
+ unsigned int line_;
};
class Parameters {
public:
- void Add(Parameter* param);
- const std::list<std::unique_ptr<Parameter>>& GetParams() const;
- bool Exist(Parameter* param) const;
+ void Add(std::unique_ptr<Parameter> param);
+ bool Exist(const Parameter& param) const;
bool Exist(std::string type_name) const;
+ std::list<std::unique_ptr<Parameter>>::const_iterator begin() const;
+ std::list<std::unique_ptr<Parameter>>::const_iterator end() const;
private:
std::list<std::unique_ptr<Parameter>> params_;
diff --git a/idlc/ast/parser.cc b/idlc/ast/parser.cc
index bf76910..a074863 100644
--- a/idlc/ast/parser.cc
+++ b/idlc/ast/parser.cc
@@ -33,8 +33,11 @@ void yylex_destroy(void*);
namespace tidl {
-Parser::Parser(bool beta_enable) : scanner_(nullptr), error_(false),
- beta_enable_(beta_enable) {
+Parser::Parser(bool beta_enable, bool cion_enable, bool mqtt_enable,
+ bool group_enable)
+ : scanner_(nullptr), error_(false), beta_enable_(beta_enable),
+ cion_enable_(cion_enable), mqtt_enable_(mqtt_enable),
+ group_enable_(group_enable), ver_(1) {
yylex_init(&scanner_);
}
@@ -46,7 +49,7 @@ void Parser::SetDoc(Document* doc) {
doc_ = std::shared_ptr<Document>(doc);
}
-std::shared_ptr<Document> Parser::GetDoc() {
+std::shared_ptr<Document> Parser::GetDoc() const {
return doc_;
}
@@ -64,21 +67,50 @@ bool Parser::Parse(const std::string& input) {
return true;
}
+void Parser::SetVersion(int ver) {
+ ver_ = ver;
+}
+
+int Parser::GetVersion() const {
+ return ver_;
+}
+
bool Parser::ParseFromFile(const std::string& path) {
- std::ifstream inFile(path);
+ pr_.reset(new Preprocessor(path));
+ if (pr_->Process() == false) {
+ pr_.reset();
+ std::cerr << "[TIDL:Parser] error" << std::endl;
+ return false;
+ }
+
+ std::ifstream inFile(pr_->GetInputPath());
std::string str((std::istreambuf_iterator<char>(inFile)),
std::istreambuf_iterator<char>());
- path_ = path;
- return Parse(str);
+ bool ret = Parse(str);
+ pr_.reset();
+
+ return ret;
}
void Parser::ReportError(const std::string& err, unsigned line) {
- std::cerr << path_ << ":" << line << ": " << err << std::endl;
+ pr_->ReportError("[TIDL:Parser] error " + err, line);
error_ = true;
}
-bool Parser::IsBetaEnabled() {
+bool Parser::IsBetaEnabled() const {
return beta_enable_;
}
+bool Parser::IsCionEnabled() const {
+ return cion_enable_;
+}
+
+bool Parser::IsMqttEnabled() const {
+ return mqtt_enable_;
+}
+
+bool Parser::IsGroupEnabled() const {
+ return group_enable_;
+}
+
} // namespace tidl
diff --git a/idlc/ast/parser.h b/idlc/ast/parser.h
index 3d74bfe..20fb6a1 100644
--- a/idlc/ast/parser.h
+++ b/idlc/ast/parser.h
@@ -22,28 +22,39 @@
#include <list>
#include "idlc/ast/document.h"
+#include "idlc/ast/preprocessor.h"
namespace tidl {
class Parser {
public:
- Parser(bool beta_enable = false);
+ Parser(bool beta_enable = false, bool cion_enable = false,
+ bool mqtt_enable = false, bool group_enable = false);
~Parser();
void* Scanner() const { return scanner_; }
bool Parse(const std::string& input);
bool ParseFromFile(const std::string& path);
void SetDoc(Document* doc);
- std::shared_ptr<Document> GetDoc();
+ std::shared_ptr<Document> GetDoc() const;
void ReportError(const std::string& err, unsigned line);
- bool IsBetaEnabled();
+ bool IsBetaEnabled() const;
+ bool IsCionEnabled() const;
+ bool IsMqttEnabled() const;
+ bool IsGroupEnabled() const;
+ void SetVersion(int ver);
+ int GetVersion() const;
private:
void* scanner_;
std::shared_ptr<Document> doc_;
- std::string path_;
bool error_;
bool beta_enable_;
+ bool cion_enable_;
+ bool mqtt_enable_;
+ bool group_enable_;
+ int ver_;
+ std::unique_ptr<Preprocessor> pr_;
};
} // namespace tidl
diff --git a/idlc/ast/position.hh b/idlc/ast/position.hh
index b687a5f..bf34c1c 100644
--- a/idlc/ast/position.hh
+++ b/idlc/ast/position.hh
@@ -1,169 +1,11 @@
-// A Bison parser, made by GNU Bison 3.0.4.
+// A Bison parser, made by GNU Bison 3.5.1.
-// Positions for Bison parsers in C++
+// Starting with Bison 3.2, this file is useless: the structure it
+// used to define is now defined in "location.hh".
+//
+// To get rid of this file:
+// 1. add '%require "3.2"' (or newer) to your grammar file
+// 2. remove references to this file from your build system
+// 3. if you used to include it, include "location.hh" instead.
-// Copyright (C) 2002-2015 Free Software Foundation, Inc.
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-// As a special exception, you may create a larger work that contains
-// part or all of the Bison parser skeleton and distribute that work
-// under terms of your choice, so long as that work isn't itself a
-// parser generator using the skeleton or a modified version thereof
-// as a parser skeleton. Alternatively, if you modify or redistribute
-// the parser skeleton itself, you may (at your option) remove this
-// special exception, which will cause the skeleton and the resulting
-// Bison output files to be licensed under the GNU General Public
-// License without this special exception.
-
-// This special exception was added by the Free Software Foundation in
-// version 2.2 of Bison.
-
-/**
- ** \file /home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/position.hh
- ** Define the yy::position class.
- */
-
-#ifndef YY_YY_HOME_HYUNHO_FULL_SOURCES_TIZEN_TIDL_THREAD_PROJ_TIDL_IDLC_AST_POSITION_HH_INCLUDED
-# define YY_YY_HOME_HYUNHO_FULL_SOURCES_TIZEN_TIDL_THREAD_PROJ_TIDL_IDLC_AST_POSITION_HH_INCLUDED
-
-# include <algorithm> // std::max
-# include <iostream>
-# include <string>
-
-# ifndef YY_NULLPTR
-# if defined __cplusplus && 201103L <= __cplusplus
-# define YY_NULLPTR nullptr
-# else
-# define YY_NULLPTR 0
-# endif
-# endif
-
-
-namespace yy {
-#line 56 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/position.hh" // location.cc:296
- /// Abstract a position.
- class position
- {
- public:
- /// Initialization.
- void initialize (std::string* fn = YY_NULLPTR,
- unsigned int l = 1u,
- unsigned int c = 1u)
- {
- filename = fn;
- line = l;
- column = c;
- }
-
- /** \name Line and Column related manipulators
- ** \{ */
- /// (line related) Advance to the COUNT next lines.
- void lines (int count = 1)
- {
- if (count)
- {
- column = 1u;
- line = add_ (line, count, 1);
- }
- }
-
- /// (column related) Advance to the COUNT next columns.
- void columns (int count = 1)
- {
- column = add_ (column, count, 1);
- }
- /** \} */
-
- /// File name to which this position refers.
- std::string* filename;
- /// Current line number.
- unsigned int line;
- /// Current column number.
- unsigned int column;
-
- private:
- /// Compute max(min, lhs+rhs) (provided min <= lhs).
- static unsigned int add_ (unsigned int lhs, int rhs, unsigned int min)
- {
- return (0 < rhs || -static_cast<unsigned int>(rhs) < lhs
- ? rhs + lhs
- : min);
- }
- };
-
- /// Add \a width columns, in place.
- inline position&
- operator+= (position& res, int width)
- {
- res.columns (width);
- return res;
- }
-
- /// Add \a width columns.
- inline position
- operator+ (position res, int width)
- {
- return res += width;
- }
-
- /// Subtract \a width columns, in place.
- inline position&
- operator-= (position& res, int width)
- {
- return res += -width;
- }
-
- /// Subtract \a width columns.
- inline position
- operator- (position res, int width)
- {
- return res -= width;
- }
-
- /// Compare two position objects.
- inline bool
- operator== (const position& pos1, const position& pos2)
- {
- return (pos1.line == pos2.line
- && pos1.column == pos2.column
- && (pos1.filename == pos2.filename
- || (pos1.filename && pos2.filename
- && *pos1.filename == *pos2.filename)));
- }
-
- /// Compare two position objects.
- inline bool
- operator!= (const position& pos1, const position& pos2)
- {
- return !(pos1 == pos2);
- }
-
- /** \brief Intercept output stream redirection.
- ** \param ostr the destination output stream
- ** \param pos a reference to the position to redirect
- */
- template <typename YYChar>
- inline std::basic_ostream<YYChar>&
- operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)
- {
- if (pos.filename)
- ostr << *pos.filename << ':';
- return ostr << pos.line << '.' << pos.column;
- }
-
-
-} // yy
-#line 169 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/position.hh" // location.cc:296
-#endif // !YY_YY_HOME_HYUNHO_FULL_SOURCES_TIZEN_TIDL_THREAD_PROJ_TIDL_IDLC_AST_POSITION_HH_INCLUDED
+#include "location.hh"
diff --git a/idlc/ast/preprocessor.cc b/idlc/ast/preprocessor.cc
new file mode 100644
index 0000000..44dba0b
--- /dev/null
+++ b/idlc/ast/preprocessor.cc
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/ast/preprocessor.h"
+
+#include <dirent.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <cstring>
+#include <cctype>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <utility>
+
+namespace tidl {
+
+Preprocessor::Preprocessor(const std::string& input)
+ : input_(input), has_import_(false) {
+}
+
+bool Preprocessor::Process() {
+ if (HasImport() == false)
+ return true;
+
+ size_t pos = input_.find_last_of("/\\");
+ std::string folder = input_.substr(0, pos);
+ std::string file = input_.substr(pos + 1);
+
+ has_import_ = true;
+
+ std::string tmp_file = folder + "/.tidl_tmp_" + file;
+ std::ifstream src;
+ src.open(input_);
+
+ std::ofstream dst;
+ dst.open(tmp_file);
+
+ node_tree_ = std::make_shared<NodeInfo>(file, nullptr, file, 1);
+ node_list_.emplace_back(file);
+
+ bool ret = GenTidl(&src, &dst, folder, file, node_tree_);
+
+ src.close();
+ dst.close();
+
+ input_ = tmp_file;
+
+ return ret;
+}
+
+bool Preprocessor::ExistNode(const std::string& file) {
+ for (auto node_name : node_list_) {
+ if (node_name == file)
+ return true;
+ }
+ return false;
+}
+
+bool Preprocessor::GenTidl(std::ifstream *src, std::ofstream *dst,
+ const std::string& src_dir, const std::string& src_file,
+ std::shared_ptr<NodeInfo> node) {
+ int line_num = 0;
+ std::string line;
+ while (std::getline(*src, line)) {
+ line_num++;
+ std::string import_file = GetTidlFile(line);
+
+ if (import_file.empty()) {
+ line += "\n";
+ dst->write(line.c_str(), line.size());
+ line_info_.emplace_back(line_num, node->parent_ == nullptr ?
+ std::make_shared<NodeInfo>(src_file, nullptr, src_file, line_num) :
+ node);
+
+ } else if (!ExistNode(import_file)) {
+ std::ifstream import_src(src_dir + "/" + import_file);
+ if (!import_src.is_open()) {
+ std::cerr << "Unable to open " << import_file << std::endl;
+ return false;
+ }
+
+ auto n = std::make_shared<NodeInfo>(
+ src_file, node, import_file, line_num);
+ node_list_.emplace_back(import_file);
+ if (!GenTidl(&import_src, dst, src_dir, import_file, n)) {
+ import_src.close();
+ return false;
+ }
+ import_src.close();
+ }
+ }
+ return true;
+}
+
+std::string Preprocessor::GetTidlFile(std::string line) {
+ std::string keyword("import");
+ std::string extension(".tidl>");
+
+ line.erase(std::remove_if(line.begin(),
+ line.end(), [](unsigned char x){ return std::isspace(x); }), line.end());
+
+ size_t pos = line.find("//");
+ if (pos != std::string::npos)
+ line = line.substr(0, pos);
+
+ pos = line.find(keyword);
+ if (pos != 0)
+ return {};
+
+ line = line.substr(keyword.length());
+
+
+ pos = line.find(extension);
+ if (pos != line.length() - extension.length())
+ return {};
+
+ pos = line.find('<');
+ if (pos != 0)
+ return {};
+
+ return line.substr(1, line.length() - 2);
+}
+
+bool Preprocessor::HasImport() {
+ std::ifstream stream(input_);
+ if (!stream.is_open())
+ return false;
+
+ std::string line;
+ while (std::getline(stream, line)) {
+ if (!GetTidlFile(line).empty()) {
+ stream.close();
+ return true;
+ }
+ }
+
+ stream.close();
+ return false;
+}
+
+Preprocessor::~Preprocessor() {
+ if (has_import_)
+ unlink(input_.c_str());
+}
+
+void Preprocessor::PrintError(std::shared_ptr<NodeInfo> node) {
+ if (node->parent_ != nullptr) {
+ PrintError(node->parent_);
+ std::cerr << "In file included from " << node->source_name_ << ":" <<
+ std::to_string(node->import_line_) << std::endl;
+ }
+}
+
+void Preprocessor::ReportError(const std::string& err, unsigned line) {
+ if (has_import_ == false) {
+ std::cerr << input_ << ":" << line << ": \t" << err << std::endl;
+ return;
+ }
+
+ if (line <= 0 || line - 1 > line_info_.size()) {
+ std::cerr << input_ << ":" << line << ": " << err << std::endl;
+ return;
+ }
+
+ auto info = line_info_[line - 1];
+ auto node = info.second;
+
+ if (node->parent_) {
+ std::cerr << std::endl;
+ PrintError(node);
+ }
+
+ std::cerr << std::endl;
+ std::cerr << node->import_name_ << ":" << info.first << ": \t" << err <<
+ std::endl << std::endl;
+}
+
+std::string Preprocessor::GetInputPath() {
+ return input_;
+}
+
+Preprocessor::NodeInfo::NodeInfo(std::string source_name,
+ std::shared_ptr<NodeInfo> parent, std::string import_name,
+ int import_line) :
+ source_name_(std::move(source_name)), parent_(parent),
+ import_name_(std::move(import_name)), import_line_(import_line) {
+}
+} // namespace tidl
diff --git a/idlc/ast/preprocessor.h b/idlc/ast/preprocessor.h
new file mode 100644
index 0000000..e4510fa
--- /dev/null
+++ b/idlc/ast/preprocessor.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_PREPORCESSOR_H_
+#define IDLC_PREPORCESSOR_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace tidl {
+
+class Preprocessor {
+ private:
+ class NodeInfo {
+ public:
+ NodeInfo(std::string source_name, std::shared_ptr<NodeInfo> parent,
+ std::string import_name, int import_line);
+ std::string source_name_;
+ std::shared_ptr<NodeInfo> parent_;
+ std::string import_name_;
+ int import_line_;
+ };
+
+ public:
+ Preprocessor(const std::string& input);
+ ~Preprocessor();
+ bool Process();
+ std::string GetInputPath();
+ void ReportError(const std::string& err, unsigned line);
+ void PrintError(std::shared_ptr<NodeInfo> node);
+
+ private:
+ bool HasImport();
+ bool GenTidl(std::ifstream *src, std::ofstream *dst,
+ const std::string& src_dir, const std::string& src_file,
+ std::shared_ptr<NodeInfo> node);
+ std::string GetTidlFile(std::string line);
+ bool ExistNode(const std::string& file);
+
+ std::string input_;
+ bool has_import_ ;
+ std::string tmp_path_ ;
+ std::shared_ptr<NodeInfo> node_tree_;
+ std::string tmp_line_num_;
+ std::vector<std::pair<int, std::shared_ptr<NodeInfo>>> line_info_;
+ std::vector<std::string> node_list_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_PREPORCESSOR_H_
diff --git a/idlc/ast/structure.cc b/idlc/ast/structure.cc
index 5e7eae6..94aedba 100644
--- a/idlc/ast/structure.cc
+++ b/idlc/ast/structure.cc
@@ -14,21 +14,92 @@
* limitations under the License.
*/
+#include "idlc/ast/structure.h"
+
+#include <iostream>
#include <utility>
-#include "idlc/ast/element.h"
-#include "idlc/ast/structure.h"
#include "idlc/ast/block.h"
+#include "idlc/ast/element.h"
namespace tidl {
+namespace {
+
+bool ValidateElement(const Structure* st, const std::string& id) {
+ if (st->GetEnums().Exist(id)) {
+ std::cerr << "[TIDL:Parsr] error syntax error. already exists. "
+ << id << " of " << st->GetID() << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateParent(const Structure* st, const std::string& id) {
+ if (st->GetBase() != nullptr) {
+ if (!ValidateParent(st->GetBase().get(), id))
+ return false;
+ }
+
+ for (auto& elm : st->GetElements()) {
+ if (elm->GetID() == id) {
+ std::cerr << "[TIDL:Parsr] error syntax error. already exists. "
+ << id << " of " << st->GetID() << std::endl;
+ return false;
+ }
+ }
+
+ if (st->GetEnums().Exist(id)) {
+ std::cerr << "[TIDL:Parsr] error syntax error. already exists. "
+ << id << " of " << st->GetID() << std::endl;
+ return false;
+ }
+
+ return true;
+}
-Structure::Structure(std::string id, Elements* elms, std::string comments,
- unsigned line)
- : Block::Block(std::move(id), Block::TYPE_STRUCTURE,
- std::move(comments), line), elms_(elms) {}
+} // namespace
+
+Structure::Structure(std::string id, Elements* elms, Enums* enums,
+ std::string comments, unsigned line)
+ : Block::Block(std::move(id), Block::TYPE_STRUCTURE, enums,
+ std::move(comments), line),
+ elms_(elms),
+ base_(nullptr) {
+}
const Elements& Structure::GetElements() const {
return *elms_;
}
+void Structure::SetBase(std::shared_ptr<Structure> base) {
+ base_ = std::move(base);
+}
+
+const std::shared_ptr<Structure>& Structure::GetBase() const {
+ return base_;
+}
+
+bool Structure::FindAndValidateElements() const {
+ for (auto& elm : GetElements()) {
+ if (!ValidateElement(this, elm->GetID()))
+ return false;
+ }
+
+ if (GetBase() == nullptr)
+ return true;
+
+ for (auto& elm : GetElements()) {
+ if (!ValidateParent(GetBase().get(), elm->GetID()))
+ return false;
+ }
+
+ for (auto& enm : GetEnums()) {
+ if (!ValidateParent(GetBase().get(), enm->GetID()))
+ return false;
+ }
+
+ return true;
+}
+
} // namespace tidl
diff --git a/idlc/ast/structure.h b/idlc/ast/structure.h
index f9b93b8..816ea02 100644
--- a/idlc/ast/structure.h
+++ b/idlc/ast/structure.h
@@ -14,29 +14,35 @@
* limitations under the License.
*/
-#ifndef IDLC_STRUCTURE_H_
-#define IDLC_STRUCTURE_H_
+#ifndef IDLC_AST_STRUCTURE_H_
+#define IDLC_AST_STRUCTURE_H_
#include <string>
#include <memory>
#include "idlc/ast/block.h"
#include "idlc/ast/element.h"
+#include "idlc/ast/enum.h"
namespace tidl {
class Structure : public Block {
public:
- Structure(std::string id, Elements* elms, std::string comments,
- unsigned line);
+ Structure(std::string id, Elements* elms, Enums* enums, std::string comments,
+ unsigned line);
const Elements& GetElements() const;
+ void SetBase(std::shared_ptr<Structure> base);
+ const std::shared_ptr<Structure>& GetBase() const;
+
+ bool FindAndValidateElements() const;
private:
std::unique_ptr<Elements> elms_;
+ std::shared_ptr<Structure> base_;
};
} // namespace tidl
-#endif // IDLC_STRUCTURE_H_
+#endif // IDLC_AST_STRUCTURE_H_
diff --git a/idlc/ast/tidlc.ll b/idlc/ast/tidlc.ll
index 546da14..319f792 100644
--- a/idlc/ast/tidlc.ll
+++ b/idlc/ast/tidlc.ll
@@ -31,15 +31,15 @@
std::string values;
%}
-"/*" { comments += yytext; BEGIN(COMMENT); }
-<COMMENT>"*/"+\/ { comments += yytext; yylloc->step(); BEGIN(INITIAL); }
-<COMMENT>"*/" { comments += yytext; comments += "\n"; BEGIN(INITIAL); }
-<COMMENT>"*/"\n+ { comments += yytext; yylloc->step(); BEGIN(INITIAL); }
-<COMMENT>\n+ { comments += yytext; yylloc->lines(yyleng); }
-<COMMENT>([^*]\n)+|. { comments += yytext; yylloc->step(); }
+("/*".*"*/")+\n { comments += yytext; yylloc->lines(1); yylloc->step(); BEGIN(INITIAL); }
+"/*" { comments += yytext; yylloc->step(); BEGIN(COMMENT); }
+<COMMENT>"*/" { comments += yytext; yylloc->lines(1); yylloc->step(); comments += "\n"; BEGIN(INITIAL); }
+<COMMENT>"*/"\n { comments += yytext; yylloc->lines(1); yylloc->step(); BEGIN(INITIAL); }
+<COMMENT>\n { comments += yytext; yylloc->lines(1); }
+<COMMENT>[^\n] { comments += yytext;}
<COMMENT><<EOF>> { return 0; }
-"//".*\n { comments += yytext; yylloc->step(); }
+"//".*\n { comments += yytext; yylloc->lines(1); yylloc->step(); }
"\"" { BEGIN(VALUE); }
<VALUE>"\"" {
@@ -58,6 +58,7 @@
"(" { return yy::parser::token::T_LEFT; }
")" { return yy::parser::token::T_RIGHT; }
";" { return yy::parser::token::T_SEMICOLON; }
+":" { return yy::parser::token::T_COLON; }
"void" {
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_VOID;
@@ -102,6 +103,10 @@
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_BOOL;
}
+"protocol" {
+ yylval->token = new tidl::Token(yytext, comments);
+ return yy::parser::token::T_PROTOCOL;
+ }
"in" { return yy::parser::token::T_IN; }
"out" { return yy::parser::token::T_OUT; }
"ref" { return yy::parser::token::T_REF; }
@@ -113,10 +118,22 @@
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_LIST;
}
+"enum" {
+ yylval->token = new tidl::Token(yytext, comments);
+ return yy::parser::token::T_ENUM;
+ }
"array" {
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_ARRAY;
}
+"map" {
+ yylval->token = new tidl::Token(yytext, comments);
+ return yy::parser::token::T_MAP;
+ }
+"set" {
+ yylval->token = new tidl::Token(yytext, comments);
+ return yy::parser::token::T_SET;
+ }
"struct" {
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_STRUCTURE;
@@ -129,6 +146,14 @@
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_ID;
}
+-?[0-9]+ {
+ yylval->token = new tidl::Token(yytext, comments);
+ return yy::parser::token::T_NUMBER;
+ }
+-?0x[0-9a-f]+ {
+ yylval->token = new tidl::Token(yytext, comments);
+ return yy::parser::token::T_HEX_NUMBER;
+ }
"[" { // Square Bracket
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_SB_OPEN;
@@ -138,7 +163,7 @@
return yy::parser::token::T_SB_CLOSE;
}
"=" { return yy::parser::token::T_EQUAL; }
-. { return yy::parser::token::T_UNKNOWN; }
+. { return yy::parser::token::T_DOT; }
%%
diff --git a/idlc/ast/tidlc.yy b/idlc/ast/tidlc.yy
index 7fd3848..7a7d5df 100644
--- a/idlc/ast/tidlc.yy
+++ b/idlc/ast/tidlc.yy
@@ -10,6 +10,7 @@
#include "idlc/ast/parameter.h"
#include "idlc/ast/interface.h"
#include "idlc/ast/element.h"
+#include "idlc/ast/enum.h"
#include "idlc/ast/structure.h"
#include "idlc/ast/block.h"
#include "idlc/ast/attribute.h"
@@ -19,15 +20,18 @@ int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
#define lex_scanner ps->Scanner()
+tidl::Enums* currentInterfaceEnums;
+tidl::Declarations* currentDeclarations = nullptr;
+tidl::Document* document = nullptr;
%}
%parse-param { tidl::Parser* ps }
%lex-param { void *lex_scanner }
-%token T_LEFT T_RIGHT T_COMMA T_SEMICOLON T_BRACE_OPEN T_BRACE_CLOSE
+%token T_LEFT T_RIGHT T_COMMA T_SEMICOLON T_COLON T_BRACE_OPEN T_BRACE_CLOSE
%token T_IN T_OUT T_REF T_ASYNC
%token T_META_OPEN T_META_CLOSE
-%token T_EQUAL T_DELEGATE T_UNKNOWN
+%token T_EQUAL T_DELEGATE T_DOT
%start start
@@ -46,14 +50,21 @@ int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
tidl::Parameters* params;
tidl::Token* token;
tidl::Structure* structure;
+ tidl::Block* protocol;
tidl::Element* elm;
tidl::Elements* elms;
tidl::Block* blk;
tidl::Attribute* attr;
tidl::Attributes* attrs;
+ tidl::Enum* enumeration;
+ tidl::Enums* enumerations;
+ tidl::Field* enum_field;
+ tidl::Fields* enum_fields;
}
%token<token> T_ID
+%token<token> T_NUMBER
+%token<token> T_HEX_NUMBER
%token<token> T_STRUCTURE
%token<token> T_INTERFACE
%token<token> T_CHAR
@@ -68,14 +79,19 @@ int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
%token<token> T_BOOL
%token<token> T_LIST
%token<token> T_ARRAY
+%token<token> T_MAP
+%token<token> T_SET
%token<token> T_VALUE
%token<token> T_SB_OPEN
%token<token> T_SB_CLOSE
%token<token> T_FILE
+%token<token> T_PROTOCOL
+%token<token> T_ENUM
%type<doc> blocks
%type<blk> block
%type<structure> structure_block
%type<interf> interface_block
+%type<blk> protocol_block
%type<decls> declarations
%type<decl> declaration
%type<p_type> parameter_type
@@ -90,6 +106,10 @@ int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
%type<elms> elements
%type<attr> attribute
%type<attrs> attributes
+%type<enumeration> enum
+%type<enumerations> enums
+%type<enum_field> field
+%type<enum_fields> fields
%%
@@ -100,6 +120,7 @@ start: blocks {
blocks: block {
$$ = new tidl::Document();
+ document = $$;
if ($1 != NULL)
$$->AddBlock($1);
}
@@ -119,17 +140,157 @@ blocks: block {
block: interface_block {
$$ = $1;
+ currentInterfaceEnums = nullptr;
}
| structure_block {
$$ = $1;
+ currentInterfaceEnums = nullptr;
+ }
+ | protocol_block {
+ $$ = $1;
+ }
+;
+
+protocol_block: T_PROTOCOL T_NUMBER {
+ int ver = atoi($2->ToString().c_str());
+
+ if (ver < 1) {
+ ps->ReportError("syntax error in protocol version : " + $2->ToString(),
+ @1.begin.line);
+ } else {
+ ps->SetVersion(ver);
+ }
+ $$ = NULL;
+ delete $1;
+ delete $2;
+ }
+ | T_PROTOCOL T_ID {
+ ps->ReportError("syntax error in protocol version : " + $2->ToString(),
+ @1.begin.line);
+ $$ = NULL;
+ delete $1;
+ delete $2;
}
;
structure_block: T_STRUCTURE T_ID T_BRACE_OPEN elements T_BRACE_CLOSE {
- $$ = new tidl::Structure($2->ToString(), $4, $1->GetComments(),
+ $$ = new tidl::Structure($2->ToString(), $4, new tidl::Enums(),
+ $1->GetComments(), @1.begin.line);
+ if (!$$->FindAndValidateElements()) {
+ ps->ReportError("syntax error. invalid element : " + $2->ToString(), @1.begin.line);
+ $$ = NULL;
+ delete $$;
+ }
+
+ delete $1;
+ delete $2;
+ }
+ | T_STRUCTURE T_ID T_BRACE_OPEN enums elements T_BRACE_CLOSE {
+ $$ = new tidl::Structure($2->ToString(), $5, $4, $1->GetComments(),
+ @1.begin.line);
+ if (!$$->FindAndValidateElements()) {
+ ps->ReportError("syntax error. invalid element : " + $2->ToString(), @1.begin.line);
+ $$ = NULL;
+ delete $$;
+ }
+
+ delete $1;
+ delete $2;
+ }
+ | T_STRUCTURE T_ID T_BRACE_OPEN enums T_BRACE_CLOSE {
+ $$ = new tidl::Structure($2->ToString(), new tidl::Elements(), $4, $1->GetComments(),
@1.begin.line);
+ if (!$$->FindAndValidateElements()) {
+ ps->ReportError("syntax error. invalid element : " + $2->ToString(), @1.begin.line);
+ $$ = NULL;
+ delete $$;
+ }
+
+ delete $1;
+ delete $2;
+ }
+ | T_STRUCTURE T_ID T_COLON T_ID T_BRACE_OPEN elements T_BRACE_CLOSE {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. Please try to use protocol 2.", @1.begin.line);
+ delete $6;
+ } else {
+ std::shared_ptr<tidl::Block> block = nullptr;
+ if (document != nullptr)
+ block = document->FindBlock($4->ToString());
+
+ if (block == nullptr || block->GetType() != tidl::Block::Type::TYPE_STRUCTURE) {
+ ps->ReportError("syntax error. " + $4->ToString() + " does not exist.", @1.begin.line);
+ delete $6;
+ } else {
+ $$ = new tidl::Structure($2->ToString(), $6, new tidl::Enums(),
+ $1->GetComments(), @1.begin.line);
+ $$->SetBase(std::dynamic_pointer_cast<tidl::Structure>(block));
+ if (!$$->FindAndValidateElements()) {
+ ps->ReportError("syntax error. invalid element : " + $2->ToString(), @1.begin.line);
+ $$ = NULL;
+ delete $$;
+ }
+ }
+ }
+ delete $1;
+ delete $2;
+ delete $4;
+ }
+ | T_STRUCTURE T_ID T_COLON T_ID T_BRACE_OPEN enums elements T_BRACE_CLOSE {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. Please try to use protocol 2.", @1.begin.line);
+ delete $6;
+ delete $7;
+ } else {
+ std::shared_ptr<tidl::Block> block = nullptr;
+ if (document != nullptr)
+ block = document->FindBlock($4->ToString());
+
+ if (block == nullptr || block->GetType() != tidl::Block::Type::TYPE_STRUCTURE) {
+ ps->ReportError("syntax error. " + $4->ToString() + " does not exist.", @1.begin.line);
+ delete $6;
+ delete $7;
+ } else {
+ $$ = new tidl::Structure($2->ToString(), $7, $6, $1->GetComments(),
+ @1.begin.line);
+ $$->SetBase(std::dynamic_pointer_cast<tidl::Structure>(block));
+ if (!$$->FindAndValidateElements()) {
+ ps->ReportError("syntax error. invalid element : " + $2->ToString(), @1.begin.line);
+ $$ = NULL;
+ delete $$;
+ }
+ }
+ }
+ delete $1;
+ delete $2;
+ delete $4;
+ }
+ | T_STRUCTURE T_ID T_COLON T_ID T_BRACE_OPEN enums T_BRACE_CLOSE {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. Please try to use protocol 2.", @1.begin.line);
+ delete $6;
+ } else {
+ std::shared_ptr<tidl::Block> block = nullptr;
+ if (document != nullptr)
+ block = document->FindBlock($4->ToString());
+
+ if (block == nullptr || block->GetType() != tidl::Block::Type::TYPE_STRUCTURE) {
+ ps->ReportError("syntax error. " + $4->ToString() + " does not exist.", @1.begin.line);
+ delete $6;
+ } else {
+ $$ = new tidl::Structure($2->ToString(), new tidl::Elements(), $6, $1->GetComments(),
+ @1.begin.line);
+ $$->SetBase(std::dynamic_pointer_cast<tidl::Structure>(block));
+ if (!$$->FindAndValidateElements()) {
+ ps->ReportError("syntax error. invalid element : " + $2->ToString(), @1.begin.line);
+ delete $$;
+ $$ = NULL;
+ }
+ }
+ }
delete $1;
delete $2;
+ delete $4;
}
| T_STRUCTURE T_BRACE_OPEN elements T_BRACE_CLOSE {
ps->ReportError("syntax error. \"No identifier\".", @1.begin.line);
@@ -149,20 +310,103 @@ structure_block: T_STRUCTURE T_ID T_BRACE_OPEN elements T_BRACE_CLOSE {
}
;
+enums: enum {
+ $$ = new (std::nothrow) tidl::Enums();
+ currentInterfaceEnums = $$;
+ if ($$ != nullptr) {
+ if ($1 != nullptr) {
+ $$->Add(std::unique_ptr<tidl::Enum>($1));
+ }
+ }
+ }
+ | enums enum {
+ $$ = $1;
+ if ($2 != nullptr) {
+ if ($$->Exist(*$2)) {
+ ps->ReportError("syntax error. \"Already Exists\".", $2->GetLine());
+ delete $2;
+ } else {
+ $$->Add(std::unique_ptr<tidl::Enum>($2));
+ }
+ }
+ }
+;
+
+enum: T_ENUM T_ID T_BRACE_OPEN fields T_BRACE_CLOSE {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. \"enum is supported from protocol version 2\".", @1.begin.line);
+ ps->ReportError("try to use protocol version 2.", @1.begin.line);
+ } else {
+ $$ = new tidl::Enum($2->ToString(), $4, $1->GetComments(),
+ @1.begin.line);
+ }
+ delete $2;
+ }
+;
+
+fields: field {
+ $$ = new (std::nothrow) tidl::Fields();
+ if ($$ != nullptr) {
+ if ($1 != nullptr) {
+ $$->Add(std::unique_ptr<tidl::Field>($1));
+ }
+ }
+ }
+ | fields field {
+ $$ = $1;
+ if ($2 != nullptr) {
+ if ($$->Exist(*$2)) {
+ ps->ReportError("syntax error. \"Already Exists\".", $2->GetLine());
+ delete $2;
+ } else {
+ $$->Add(std::unique_ptr<tidl::Field>($2));
+ }
+ }
+ }
+;
+
+field: T_ID T_COMMA {
+ $$ = new (std::nothrow) tidl::Field($1->ToString(), "", $1->GetComments(),
+ @1.begin.line);
+ }
+ | T_ID T_EQUAL T_NUMBER T_COMMA {
+ $$ = new (std::nothrow) tidl::Field($1->ToString(), $3->ToString(),
+ $1->GetComments(), @1.begin.line);
+ }
+ | T_ID T_EQUAL T_HEX_NUMBER T_COMMA {
+ $$ = new (std::nothrow) tidl::Field($1->ToString(), $3->ToString(),
+ $1->GetComments(), @1.begin.line);
+ }
+ | T_ID {
+ $$ = new (std::nothrow) tidl::Field($1->ToString(), "", $1->GetComments(),
+ @1.begin.line);
+ }
+ | T_ID T_EQUAL T_NUMBER {
+ $$ = new (std::nothrow) tidl::Field($1->ToString(), $3->ToString(),
+ $1->GetComments(), @1.begin.line);
+ }
+ | T_ID T_EQUAL T_HEX_NUMBER {
+ $$ = new (std::nothrow) tidl::Field($1->ToString(), $3->ToString(),
+ $1->GetComments(), @1.begin.line);
+ }
+;
+
elements: element {
$$ = new (std::nothrow) tidl::Elements();
if ($$ != nullptr) {
- $$->Add($1);
+ if ($1 != nullptr) {
+ $$->Add(std::unique_ptr<tidl::Element>($1));
+ }
}
}
| elements element {
$$ = $1;
if ($2 != nullptr) {
- if ($$->Exist($2)) {
+ if ($$->Exist(*$2)) {
ps->ReportError("syntax error. \"Already Exists\".", $2->GetLine());
delete $2;
} else {
- $$->Add($2);
+ $$->Add(std::unique_ptr<tidl::Element>($2));
}
}
}
@@ -173,9 +417,14 @@ elements: element {
;
element: raw_type T_ID T_SEMICOLON {
- $$ = new tidl::Element($2->ToString(), $1, $1->GetComments(),
- @1.begin.line);
- delete $2;
+ if (tidl::BaseType::IsFile($1)) {
+ ps->ReportError("syntax error. \"The file cannot be included in the struct.\"", @2.begin.line);
+ $$ = NULL;
+ } else {
+ $$ = new tidl::Element($2->ToString(), $1, $1->GetComments(),
+ @1.begin.line);
+ delete $2;
+ }
}
| raw_type T_SEMICOLON {
ps->ReportError("syntax error. \"No identifier\".", @2.begin.line);
@@ -194,17 +443,19 @@ element: raw_type T_ID T_SEMICOLON {
attributes: attribute {
$$ = new (std::nothrow) tidl::Attributes();
if ($$ != nullptr) {
- $$->Add($1);
+ if ($1 != nullptr) {
+ $$->Add(std::unique_ptr<tidl::Attribute>($1));
+ }
}
}
| attributes T_COMMA attribute {
$$ = $1;
if ($3 != nullptr) {
- if ($$->Exist($3)) {
+ if ($$->Exist(*$3)) {
ps->ReportError("syntax error. \"Already Exist\".", $3->GetLine());
delete $3;
} else {
- $$->Add($3);
+ $$->Add(std::unique_ptr<tidl::Attribute>($3));
}
}
}
@@ -233,13 +484,27 @@ attribute: T_ID T_EQUAL T_VALUE {
;
interface_block: T_INTERFACE T_ID T_BRACE_OPEN declarations T_BRACE_CLOSE {
- $$ = new tidl::Interface($2->ToString(), $4, $1->GetComments(),
+ $$ = new tidl::Interface($2->ToString(), $4, new tidl::Enums(), $1->GetComments(),
new tidl::Attributes(), @1.begin.line);
delete $1;
delete $2;
}
| T_SB_OPEN attributes T_SB_CLOSE T_INTERFACE T_ID T_BRACE_OPEN declarations T_BRACE_CLOSE {
- $$ = new tidl::Interface($5->ToString(), $7, $1->GetComments(), $2,
+ $$ = new tidl::Interface($5->ToString(), $7, new tidl::Enums(),
+ $1->GetComments(), $2, @1.begin.line);
+ delete $1;
+ delete $3;
+ delete $4;
+ delete $5;
+ }
+ | T_INTERFACE T_ID T_BRACE_OPEN enums declarations T_BRACE_CLOSE {
+ $$ = new tidl::Interface($2->ToString(), $5, $4, $1->GetComments(),
+ new tidl::Attributes(), @1.begin.line);
+ delete $1;
+ delete $2;
+ }
+ | T_SB_OPEN attributes T_SB_CLOSE T_INTERFACE T_ID T_BRACE_OPEN enums declarations T_BRACE_CLOSE {
+ $$ = new tidl::Interface($5->ToString(), $8, $7, $1->GetComments(), $2,
@1.begin.line);
delete $1;
delete $3;
@@ -265,18 +530,21 @@ interface_block: T_INTERFACE T_ID T_BRACE_OPEN declarations T_BRACE_CLOSE {
declarations: declaration {
$$ = new (std::nothrow) tidl::Declarations();
+ currentDeclarations = $$;
if ($$ != nullptr) {
- $$->Add($1);
+ if ($1 != nullptr) {
+ $$->Add(std::unique_ptr<tidl::Declaration>($1));
+ }
}
}
| declarations declaration {
$$ = $1;
if ($2 != nullptr) {
- if ($$->Exist($2)) {
+ if ($$->Exist(*$2)) {
ps->ReportError("syntax error. \"Already Exists\".", $2->GetLine());
delete $2;
} else {
- $$->Add($2);
+ $$->Add(std::unique_ptr<tidl::Declaration>($2));
}
}
}
@@ -287,24 +555,72 @@ declarations: declaration {
;
declaration: base_type T_ID T_LEFT parameter_list T_RIGHT T_SEMICOLON {
- $$ = new tidl::Declaration($2->ToString(), $1, $4, $1->GetComments(),
- @1.begin.line, tidl::Declaration::MethodType::SYNC);
- delete $2;
+ if (ps->IsGroupEnabled()) {
+ ps->ReportError("Group does not support 'sync' method type", @1.begin.line);
+ $$ = NULL;
+ delete $2;
+ } else {
+ $$ = new tidl::Declaration($2->ToString(),
+ std::unique_ptr<tidl::BaseType>($1),
+ std::unique_ptr<tidl::Parameters>($4), $1->GetComments(),
+ @1.begin.line, tidl::Declaration::MethodType::SYNC);
+ delete $2;
+ }
+ }
+ | T_SB_OPEN attributes T_SB_CLOSE base_type T_ID T_LEFT parameter_list T_RIGHT T_SEMICOLON {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. \"method attributes is supported from protocol version 2\".", @1.begin.line);
+ ps->ReportError("try to use protocol version 2.", @1.begin.line);
+ }
+
+ if (ps->IsGroupEnabled()) {
+ ps->ReportError("Group does not support 'sync' method type", @1.begin.line);
+ $$ = NULL;
+ delete $5;
+ } else {
+ $$ = new tidl::Declaration($5->ToString(),
+ std::unique_ptr<tidl::BaseType>($4),
+ std::unique_ptr<tidl::Parameters>($7), $1->GetComments(),
+ @1.begin.line, tidl::Declaration::MethodType::SYNC,
+ $2);
+ delete $5;
+ }
}
| T_VOID T_ID T_LEFT parameter_list T_RIGHT T_ASYNC T_SEMICOLON {
$$ = new tidl::Declaration($2->ToString(),
- new tidl::BaseType("void", $1->GetComments()), $4,
- $1->GetComments(), @1.begin.line, tidl::Declaration::MethodType::ASYNC);
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("void", $1->GetComments())),
+ std::unique_ptr<tidl::Parameters>($4), $1->GetComments(),
+ @1.begin.line, tidl::Declaration::MethodType::ASYNC);
delete $1;
delete $2;
}
+ | T_SB_OPEN attributes T_SB_CLOSE T_VOID T_ID T_LEFT parameter_list T_RIGHT T_ASYNC T_SEMICOLON {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. \"method attributes is supported from protocol version 2\".", @1.begin.line);
+ ps->ReportError("try to use protocol version 2.", @1.begin.line);
+ }
+
+ $$ = new tidl::Declaration($5->ToString(),
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("void", $1->GetComments())),
+ std::unique_ptr<tidl::Parameters>($7), $1->GetComments(),
+ @1.begin.line, tidl::Declaration::MethodType::ASYNC, $2);
+ delete $4;
+ delete $5;
+ }
| T_VOID T_ID T_LEFT parameter_list T_RIGHT T_DELEGATE T_SEMICOLON {
- $$ = new tidl::Declaration($2->ToString(),
- new tidl::BaseType("void", $1->GetComments()), $4,
- $1->GetComments(), @1.begin.line,
- tidl::Declaration::MethodType::DELEGATE);
- delete $1;
- delete $2;
+ if (ps->IsGroupEnabled()) {
+ ps->ReportError("Group does not support 'delegate' method type", @1.begin.line);
+ $$ = NULL;
+ delete $1;
+ delete $2;
+ } else {
+ $$ = new tidl::Declaration($2->ToString(),
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("void", $1->GetComments())),
+ std::unique_ptr<tidl::Parameters>($4), $1->GetComments(),
+ @1.begin.line, tidl::Declaration::MethodType::DELEGATE);
+ delete $1;
+ delete $2;
+ }
}
| base_type T_ID T_LEFT parameter_list T_RIGHT T_ASYNC T_SEMICOLON {
ps->ReportError("syntax error in method declaration.", @2.begin.line);
@@ -345,18 +661,20 @@ declaration: base_type T_ID T_LEFT parameter_list T_RIGHT T_SEMICOLON {
parameter_list: parameter {
$$ = new tidl::Parameters();
- if ($1 != nullptr) {
- $$->Add($1);
+ if ($$ != nullptr) {
+ if ($1 != nullptr) {
+ $$->Add(std::unique_ptr<tidl::Parameter>($1));
+ }
}
}
| parameter_list T_COMMA parameter {
$$ = $1;
if ($3 != nullptr) {
- if ($$->Exist($3)) {
+ if ($$->Exist(*$3)) {
ps->ReportError("syntax error. \"Already Exists\".", $3->GetLine());
delete $3;
} else {
- $$->Add($3);
+ $$->Add(std::unique_ptr<tidl::Parameter>($3));
}
}
}
@@ -403,7 +721,11 @@ base_type: raw_type {
$$ = $1;
}
| T_FILE {
- if (!ps->IsBetaEnabled()) {
+ if (ps->IsGroupEnabled()) {
+ ps->ReportError("Group does not support 'file' type", @1.begin.line);
+ $$ = NULL;
+ delete $1;
+ } else if (!ps->IsBetaEnabled() && ps->GetVersion() < 2) {
ps->ReportError("syntax error. \"No identifier\".", @1.begin.line);
ps->ReportError("try to use beta version (-b option).", @1.begin.line);
$$ = NULL;
@@ -447,8 +769,14 @@ raw_type: container_type {
delete $1;
}
| T_BUNDLE {
- $$ = new tidl::BaseType("bundle", $1->GetComments());
- delete $1;
+ if (ps->IsCionEnabled()) {
+ ps->ReportError("Cion does not support 'bundle' type", @1.begin.line);
+ $$ = NULL;
+ delete $1;
+ } else {
+ $$ = new tidl::BaseType("bundle", $1->GetComments());
+ delete $1;
+ }
}
| T_STRING {
$$ = new tidl::BaseType("string", $1->GetComments());
@@ -459,15 +787,114 @@ raw_type: container_type {
delete $1;
}
| T_ID {
- $$ = new tidl::BaseType($1->ToString(), $1->GetComments(), true);
+ if (ps->GetVersion() < 2) {
+ $$ = new tidl::BaseType($1->ToString(), $1->GetComments(), true);
+ } else {
+ std::string name = $1->ToString();
+ bool found = false;
+ tidl::BaseType::UserType type;
+ if (currentInterfaceEnums) {
+ for (auto& e : *currentInterfaceEnums) {
+ if (e->GetID() == name) {
+ type = tidl::BaseType::UserType::ENUM;
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found && document) {
+ for (auto& b : document->GetBlocks()) {
+ if (b->GetType() == tidl::Block::TYPE_STRUCTURE) {
+ if (b->GetID() == name) {
+ type = tidl::BaseType::UserType::STRUCTURE;
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!found && currentDeclarations) {
+ for (auto& d : *currentDeclarations) {
+ if (d->GetMethodType() == tidl::Declaration::MethodType::DELEGATE) {
+ if (d->GetID() == name) {
+ type = tidl::BaseType::UserType::DELEGATE;
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+
+ $$ = new tidl::BaseType(name, $1->GetComments(), type);
+ if (!found) {
+ ps->ReportError("Unknown type : " + $1->ToString(), @1.begin.line);
+ }
+ }
+ delete $1;
+ }
+ | T_ID T_DOT T_ID {
+ bool found = false;
+ if (document) {
+ for (auto& b : document->GetBlocks()) {
+ if (b->GetType() == tidl::Block::TYPE_STRUCTURE
+ && b->GetID() == $1->ToString()) {
+ for (auto& e : b->GetEnums()) {
+ if (e->GetID() == $3->ToString()) {
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (found) {
+ $$ = new tidl::BaseType($1->ToString() + "." + $3->ToString() , $1->GetComments(), tidl::BaseType::UserType::ENUM);
+ } else {
+ ps->ReportError("Unknown type : " + $1->ToString() + "." + $3->ToString(),
+ @1.begin.line);
+ $$ = NULL;
+ }
delete $1;
}
;
container_type: container_type_name T_META_OPEN base_type T_META_CLOSE {
- $$ = new tidl::BaseType($1->ToString(), $1->GetComments());
- $$->SetMetaType($3);
- delete $1;
+ if ($1->ToString() == "map") {
+ ps->ReportError("syntax error. The value must be existed.", @1.begin.line);
+ delete $1;
+ } else {
+ if ($3->GetMetaType() != nullptr && tidl::BaseType::IsFile($3)) {
+ ps->ReportError("syntax error. The file should be included in only one container.", @1.begin.line);
+ }
+
+ if ($1->ToString() == "set") {
+ if (!tidl::BaseType::IsKeyType($3)) {
+ ps->ReportError("syntax error. The key type should be 'char', 'int', 'short', 'long', 'string', 'bool', 'float' and 'double.", @1.begin.line);
+ }
+ }
+
+ $$ = new tidl::BaseType($1->ToString(), $1->GetComments());
+ $$->SetMetaType($3);
+ delete $1;
+ }
+ }
+ | container_type_name T_META_OPEN base_type T_COMMA base_type T_META_CLOSE {
+ if ($1->ToString() != "map") {
+ ps->ReportError("syntax error. The container type must be \"map\".", @1.begin.line);
+ delete $1;
+ } else {
+ if (!tidl::BaseType::IsKeyType($3)) {
+ ps->ReportError("syntax error. The key type should be 'char', 'int', 'short', 'long', 'string', 'bool', 'float' and 'double.", @1.begin.line);
+ }
+
+ $$ = new tidl::BaseType($1->ToString(), $1->GetComments());
+ $$->SetKeyType($3);
+ $$->SetValueType($5);
+ delete $1;
+ }
}
;
@@ -479,6 +906,22 @@ container_type_name: T_LIST {
$$ = new tidl::Token("array", $1->GetComments());
delete $1;
}
+ | T_MAP {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. \"No identifier\".", @1.begin.line);
+ ps->ReportError("try to use protocol version 2.", @1.begin.line);
+ }
+ $$ = new tidl::Token("map", $1->GetComments());
+ delete $1;
+ }
+ | T_SET {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. \"No identifier\".", @1.begin.line);
+ ps->ReportError("try to use protocol version 2.", @1.begin.line);
+ }
+ $$ = new tidl::Token("set", $1->GetComments());
+ delete $1;
+ }
;
%%
diff --git a/idlc/ast/tidlc_l.cpp b/idlc/ast/tidlc_l.cpp
index 585435c..b1d4ab7 100644
--- a/idlc/ast/tidlc_l.cpp
+++ b/idlc/ast/tidlc_l.cpp
@@ -1,6 +1,6 @@
-#line 2 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_l.cpp"
+#line 2 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_l.cpp"
-#line 4 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_l.cpp"
+#line 4 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_l.cpp"
#define YY_INT_ALIGNED short int
@@ -9,11 +9,35 @@
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 0
+#define YY_FLEX_SUBMINOR_VERSION 4
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
+#ifdef yyget_lval
+#define yyget_lval_ALREADY_DEFINED
+#else
+#define yyget_lval yyget_lval
+#endif
+
+#ifdef yyset_lval
+#define yyset_lval_ALREADY_DEFINED
+#else
+#define yyset_lval yyset_lval
+#endif
+
+#ifdef yyget_lloc
+#define yyget_lloc_ALREADY_DEFINED
+#else
+#define yyget_lloc yyget_lloc
+#endif
+
+#ifdef yyset_lloc
+#define yyset_lloc_ALREADY_DEFINED
+#else
+#define yyset_lloc yyset_lloc
+#endif
+
/* First, we deal with platform-specific or compiler-specific issues. */
/* begin standard C headers. */
@@ -84,40 +108,32 @@ typedef unsigned int flex_uint32_t;
#define UINT32_MAX (4294967295U)
#endif
+#ifndef SIZE_MAX
+#define SIZE_MAX (~(size_t)0)
+#endif
+
#endif /* ! C99 */
#endif /* ! FLEXINT_H */
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
+/* begin standard C++ headers. */
-#endif /* defined (__STDC__) */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
+/* TODO: this is always defined, so inline it */
#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
#else
-#define yyconst
+#define yynoreturn
#endif
/* Returned upon end-of-file. */
#define YY_NULL 0
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
+/* Promotes a possibly negative, possibly signed char to an
+ * integer in range [0..255] for use as an array index.
*/
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
/* An opaque pointer. */
#ifndef YY_TYPEDEF_YY_SCANNER_T
@@ -141,20 +157,16 @@ typedef void* yyscan_t;
* definition of BEGIN.
*/
#define BEGIN yyg->yy_start = 1 + 2 *
-
/* Translate the current start state into a value that can be later handed
* to BEGIN to return to the state. The YYSTATE alias is for lex
* compatibility.
*/
#define YY_START ((yyg->yy_start - 1) / 2)
#define YYSTATE YY_START
-
/* Action number for EOF rule of a given start state. */
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart(yyin ,yyscanner )
-
+#define YY_NEW_FILE yyrestart( yyin , yyscanner )
#define YY_END_OF_BUFFER_CHAR 0
/* Size of default input buffer. */
@@ -187,10 +199,10 @@ typedef size_t yy_size_t;
#define EOB_ACT_CONTINUE_SCAN 0
#define EOB_ACT_END_OF_FILE 1
#define EOB_ACT_LAST_MATCH 2
-
+
/* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
* access to the local variable yy_act. Since yyless() is a macro, it would break
- * existing scanners that call yyless() from OUTSIDE yylex.
+ * existing scanners that call yyless() from OUTSIDE yylex.
* One obvious solution it to make yy_act a global. I tried that, and saw
* a 5% performance hit in a non-yylineno scanner, because yy_act is
* normally declared as a register variable-- so it is not worth it.
@@ -223,7 +235,6 @@ typedef size_t yy_size_t;
YY_DO_BEFORE_ACTION; /* set up yytext again */ \
} \
while ( 0 )
-
#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
#ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -238,7 +249,7 @@ struct yy_buffer_state
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
- yy_size_t yy_buf_size;
+ int yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
@@ -266,7 +277,7 @@ struct yy_buffer_state
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
-
+
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
@@ -300,89 +311,79 @@ struct yy_buffer_state
#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
: NULL)
-
/* Same as previous macro, but useful when we know that the buffer stack is not
* NULL or when we need an lvalue. For internal use only.
*/
#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
-void yyrestart (FILE *input_file ,yyscan_t yyscanner );
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void yypop_buffer_state (yyscan_t yyscanner );
+void yyrestart ( FILE *input_file , yyscan_t yyscanner );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
+void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+void yypop_buffer_state ( yyscan_t yyscanner );
-static void yyensure_buffer_stack (yyscan_t yyscanner );
-static void yy_load_buffer_state (yyscan_t yyscanner );
-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+static void yyensure_buffer_stack ( yyscan_t yyscanner );
+static void yy_load_buffer_state ( yyscan_t yyscanner );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner)
-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
-
-void *yyalloc (yy_size_t ,yyscan_t yyscanner );
-void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void yyfree (void * ,yyscan_t yyscanner );
+void *yyalloc ( yy_size_t , yyscan_t yyscanner );
+void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
+void yyfree ( void * , yyscan_t yyscanner );
#define yy_new_buffer yy_create_buffer
-
#define yy_set_interactive(is_interactive) \
{ \
if ( ! YY_CURRENT_BUFFER ){ \
yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
}
-
#define yy_set_bol(at_bol) \
{ \
if ( ! YY_CURRENT_BUFFER ){\
yyensure_buffer_stack (yyscanner); \
YY_CURRENT_BUFFER_LVALUE = \
- yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
} \
YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
}
-
#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
/* Begin user sect3 */
#define yywrap(yyscanner) (/*CONSTCOND*/1)
#define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
+typedef flex_uint8_t YY_CHAR;
typedef int yy_state_type;
#define yytext_ptr yytext_r
-static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
-static int yy_get_next_buffer (yyscan_t yyscanner );
-#if defined(__GNUC__) && __GNUC__ >= 3
-__attribute__((__noreturn__))
-#endif
-static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+static yy_state_type yy_get_previous_state ( yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner);
+static int yy_get_next_buffer ( yyscan_t yyscanner );
+static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
/* Done after the current pattern has been matched and before the
* corresponding action - sets up yytext.
*/
#define YY_DO_BEFORE_ACTION \
yyg->yytext_ptr = yy_bp; \
- yyleng = (size_t) (yy_cp - yy_bp); \
+ yyleng = (int) (yy_cp - yy_bp); \
yyg->yy_hold_char = *yy_cp; \
*yy_cp = '\0'; \
yyg->yy_c_buf_p = yy_cp;
-
-#define YY_NUM_RULES 46
-#define YY_END_OF_BUFFER 47
+#define YY_NUM_RULES 53
+#define YY_END_OF_BUFFER 54
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -390,41 +391,43 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[132] =
+static const flex_int16_t yy_accept[156] =
{ 0,
- 0, 0, 0, 0, 0, 0, 47, 45, 12, 11,
- 8, 16, 17, 13, 45, 18, 35, 44, 36, 41,
- 42, 43, 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 14, 15, 6, 5, 6, 10, 46,
- 9, 10, 11, 1, 0, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 30, 41, 41, 41, 41,
- 41, 41, 41, 6, 5, 3, 10, 0, 7, 41,
- 41, 41, 41, 41, 41, 41, 41, 41, 22, 41,
- 41, 31, 32, 41, 41, 41, 0, 5, 4, 0,
- 2, 0, 41, 41, 29, 41, 20, 41, 41, 27,
-
- 41, 41, 37, 23, 41, 41, 41, 19, 0, 38,
- 33, 41, 41, 41, 24, 41, 21, 41, 41, 26,
- 41, 25, 41, 28, 39, 41, 41, 34, 41, 40,
- 0
+ 0, 0, 0, 0, 0, 0, 54, 52, 12, 11,
+ 8, 16, 17, 13, 52, 52, 47, 47, 19, 18,
+ 37, 51, 38, 46, 49, 50, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 14, 15, 6, 5, 6, 10, 53, 9, 10, 11,
+ 47, 47, 2, 0, 0, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 32, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 3, 10, 0,
+ 0, 0, 7, 48, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 23, 46, 46, 42, 33, 46,
+
+ 34, 43, 46, 46, 46, 4, 0, 0, 46, 46,
+ 30, 46, 21, 46, 46, 40, 28, 46, 46, 39,
+ 24, 46, 46, 46, 46, 20, 1, 0, 41, 35,
+ 46, 46, 46, 25, 46, 46, 22, 46, 46, 0,
+ 27, 46, 26, 46, 46, 29, 44, 46, 46, 46,
+ 36, 46, 31, 45, 0
} ;
-static yyconst YY_CHAR yy_ec[256] =
+static const YY_CHAR yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 1, 4, 1, 1, 1, 1, 1, 5,
- 6, 7, 1, 8, 1, 1, 9, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 1, 11, 12,
- 13, 14, 1, 1, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 16, 1, 17, 1, 15, 1, 18, 19, 20, 21,
-
- 22, 23, 24, 25, 26, 15, 15, 27, 15, 28,
- 29, 15, 15, 30, 31, 32, 33, 34, 15, 15,
- 35, 15, 36, 1, 37, 1, 1, 1, 1, 1,
+ 6, 7, 1, 8, 9, 1, 10, 11, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 13, 14, 15,
+ 16, 17, 1, 1, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+ 19, 1, 20, 1, 18, 1, 21, 22, 23, 24,
+
+ 25, 26, 27, 28, 29, 18, 18, 30, 31, 32,
+ 33, 34, 18, 35, 36, 37, 38, 39, 18, 40,
+ 41, 18, 42, 1, 43, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -441,110 +444,127 @@ static yyconst YY_CHAR yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst YY_CHAR yy_meta[38] =
+static const YY_CHAR yy_meta[44] =
{ 0,
- 1, 1, 1, 1, 1, 1, 2, 1, 1, 3,
- 1, 1, 1, 1, 3, 1, 1, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 1, 1
+ 1, 1, 2, 1, 1, 1, 3, 1, 1, 1,
+ 4, 4, 1, 1, 1, 1, 1, 5, 1, 1,
+ 4, 4, 4, 4, 4, 4, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 1, 1
} ;
-static yyconst flex_uint16_t yy_base[138] =
+static const flex_int16_t yy_base[163] =
{ 0,
- 0, 0, 35, 36, 37, 42, 156, 157, 157, 152,
- 157, 157, 157, 157, 41, 157, 157, 157, 157, 0,
- 157, 157, 21, 24, 129, 25, 29, 125, 32, 119,
- 129, 34, 121, 157, 157, 146, 145, 138, 143, 142,
- 141, 157, 140, 157, 139, 0, 111, 105, 110, 110,
- 119, 109, 102, 107, 104, 100, 100, 102, 97, 105,
- 98, 96, 99, 0, 121, 60, 0, 120, 157, 104,
- 93, 93, 98, 88, 95, 97, 93, 96, 91, 80,
- 87, 0, 0, 80, 38, 88, 105, 104, 103, 96,
- 157, 101, 68, 82, 0, 74, 0, 76, 72, 0,
-
- 66, 67, 0, 0, 64, 67, 74, 0, 53, 0,
- 0, 71, 74, 69, 0, 67, 0, 65, 56, 0,
- 55, 0, 67, 0, 0, 60, 50, 0, 46, 0,
- 157, 71, 74, 62, 77, 80, 83
+ 0, 0, 41, 42, 43, 48, 199, 200, 200, 195,
+ 200, 200, 200, 200, 42, 49, 46, 49, 200, 200,
+ 200, 200, 200, 0, 200, 200, 27, 31, 169, 40,
+ 164, 37, 163, 39, 173, 155, 157, 166, 46, 157,
+ 200, 200, 200, 200, 179, 185, 184, 183, 200, 182,
+ 64, 66, 177, 180, 0, 0, 147, 140, 147, 147,
+ 157, 147, 138, 137, 144, 140, 135, 135, 138, 135,
+ 131, 134, 140, 128, 131, 128, 133, 158, 0, 153,
+ 72, 156, 200, 0, 137, 125, 126, 131, 119, 128,
+ 130, 120, 125, 128, 123, 110, 119, 0, 0, 108,
+
+ 0, 0, 109, 51, 119, 200, 139, 78, 100, 117,
+ 0, 109, 0, 111, 107, 0, 0, 99, 100, 0,
+ 0, 101, 96, 100, 106, 0, 200, 111, 0, 0,
+ 78, 81, 76, 0, 74, 76, 0, 71, 60, 77,
+ 0, 59, 0, 74, 61, 0, 0, 68, 69, 61,
+ 0, 65, 0, 0, 200, 104, 109, 111, 116, 121,
+ 66, 126
} ;
-static yyconst flex_int16_t yy_def[138] =
+static const flex_int16_t yy_def[163] =
{ 0,
- 131, 1, 132, 132, 133, 133, 131, 131, 131, 131,
- 131, 131, 131, 131, 131, 131, 131, 131, 131, 134,
- 131, 131, 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 131, 131, 131, 131, 131, 131, 131,
- 131, 131, 131, 131, 135, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 136, 136, 131, 137, 135, 131, 134,
- 134, 134, 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 131, 131, 131, 131,
- 131, 131, 134, 134, 134, 134, 134, 134, 134, 134,
-
- 134, 134, 134, 134, 134, 134, 134, 134, 131, 134,
- 134, 134, 134, 134, 134, 134, 134, 134, 134, 134,
- 134, 134, 134, 134, 134, 134, 134, 134, 134, 134,
- 0, 131, 131, 131, 131, 131, 131
+ 155, 1, 156, 156, 157, 157, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 158, 155, 155, 158, 158, 158, 158,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 159, 160, 161, 158, 158, 158, 158, 158,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
+ 158, 158, 158, 158, 158, 158, 158, 155, 162, 159,
+ 159, 160, 155, 161, 158, 158, 158, 158, 158, 158,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
+
+ 158, 158, 158, 158, 158, 155, 155, 159, 158, 158,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
+ 158, 158, 158, 158, 158, 158, 155, 159, 158, 158,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 159,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
+ 158, 158, 158, 158, 0, 155, 155, 155, 155, 155,
+ 155, 155
} ;
-static yyconst flex_uint16_t yy_nxt[195] =
+static const flex_int16_t yy_nxt[244] =
{ 0,
- 8, 9, 10, 11, 12, 13, 8, 14, 15, 8,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
- 26, 20, 27, 20, 20, 28, 29, 20, 30, 31,
- 32, 20, 20, 33, 20, 34, 35, 37, 37, 40,
- 41, 38, 38, 42, 40, 41, 52, 44, 42, 45,
- 47, 48, 49, 53, 54, 55, 50, 57, 61, 90,
- 58, 91, 89, 106, 46, 62, 90, 130, 91, 129,
- 107, 36, 36, 36, 39, 39, 39, 68, 68, 68,
- 87, 128, 87, 92, 127, 92, 126, 125, 124, 123,
- 122, 121, 120, 119, 118, 117, 116, 115, 114, 113,
-
- 112, 111, 110, 67, 109, 89, 65, 64, 108, 105,
- 104, 103, 102, 101, 100, 99, 98, 97, 96, 95,
- 94, 93, 69, 88, 86, 85, 84, 83, 82, 81,
- 80, 79, 78, 77, 76, 75, 74, 73, 72, 71,
- 70, 69, 43, 67, 67, 67, 66, 65, 64, 63,
- 60, 59, 56, 51, 43, 131, 7, 131, 131, 131,
- 131, 131, 131, 131, 131, 131, 131, 131, 131, 131,
- 131, 131, 131, 131, 131, 131, 131, 131, 131, 131,
- 131, 131, 131, 131, 131, 131, 131, 131, 131, 131,
- 131, 131, 131, 131
-
+ 8, 9, 10, 11, 12, 13, 8, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 24, 24, 33, 34,
+ 35, 24, 36, 37, 38, 39, 24, 24, 40, 24,
+ 24, 41, 42, 44, 44, 47, 48, 45, 45, 49,
+ 47, 48, 51, 52, 49, 53, 52, 52, 54, 52,
+ 52, 57, 58, 59, 62, 65, 66, 68, 60, 84,
+ 74, 69, 63, 75, 52, 52, 52, 52, 81, 124,
+ 127, 108, 76, 81, 81, 55, 108, 128, 125, 154,
+ 153, 152, 151, 150, 149, 148, 147, 146, 145, 144,
+
+ 143, 142, 141, 55, 43, 43, 43, 43, 43, 46,
+ 46, 46, 46, 46, 56, 56, 80, 140, 80, 80,
+ 80, 82, 82, 82, 82, 82, 107, 107, 139, 107,
+ 107, 138, 137, 136, 135, 134, 133, 132, 131, 130,
+ 129, 79, 126, 123, 122, 121, 120, 119, 118, 117,
+ 116, 115, 114, 113, 112, 111, 110, 109, 83, 81,
+ 106, 105, 104, 103, 102, 101, 100, 99, 98, 97,
+ 96, 95, 94, 93, 92, 91, 90, 89, 88, 87,
+ 86, 85, 83, 81, 50, 79, 79, 79, 78, 77,
+ 73, 72, 71, 70, 67, 64, 61, 50, 155, 7,
+
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155
} ;
-static yyconst flex_int16_t yy_chk[195] =
+static const flex_int16_t yy_chk[244] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 3, 4, 5,
- 5, 3, 4, 5, 6, 6, 26, 15, 6, 15,
- 23, 23, 24, 26, 27, 27, 24, 29, 32, 109,
- 29, 109, 66, 85, 134, 32, 66, 129, 66, 127,
- 85, 132, 132, 132, 133, 133, 133, 135, 135, 135,
- 136, 126, 136, 137, 123, 137, 121, 119, 118, 116,
- 114, 113, 112, 107, 106, 105, 102, 101, 99, 98,
-
- 96, 94, 93, 92, 90, 89, 88, 87, 86, 84,
- 81, 80, 79, 78, 77, 76, 75, 74, 73, 72,
- 71, 70, 68, 65, 63, 62, 61, 60, 59, 58,
- 57, 56, 55, 54, 53, 52, 51, 50, 49, 48,
- 47, 45, 43, 41, 40, 39, 38, 37, 36, 33,
- 31, 30, 28, 25, 10, 7, 131, 131, 131, 131,
- 131, 131, 131, 131, 131, 131, 131, 131, 131, 131,
- 131, 131, 131, 131, 131, 131, 131, 131, 131, 131,
- 131, 131, 131, 131, 131, 131, 131, 131, 131, 131,
- 131, 131, 131, 131
-
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 3, 4, 5, 5, 3, 4, 5,
+ 6, 6, 15, 15, 6, 16, 17, 17, 16, 18,
+ 18, 27, 27, 28, 30, 32, 32, 34, 28, 161,
+ 39, 34, 30, 39, 51, 51, 52, 52, 81, 104,
+ 108, 81, 39, 140, 108, 17, 140, 108, 104, 152,
+ 150, 149, 148, 145, 144, 142, 139, 138, 136, 135,
+
+ 133, 132, 131, 51, 156, 156, 156, 156, 156, 157,
+ 157, 157, 157, 157, 158, 158, 159, 128, 159, 159,
+ 159, 160, 160, 160, 160, 160, 162, 162, 125, 162,
+ 162, 124, 123, 122, 119, 118, 115, 114, 112, 110,
+ 109, 107, 105, 103, 100, 97, 96, 95, 94, 93,
+ 92, 91, 90, 89, 88, 87, 86, 85, 82, 80,
+ 78, 77, 76, 75, 74, 73, 72, 71, 70, 69,
+ 68, 67, 66, 65, 64, 63, 62, 61, 60, 59,
+ 58, 57, 54, 53, 50, 48, 47, 46, 45, 40,
+ 38, 37, 36, 35, 33, 31, 29, 10, 7, 155,
+
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155
} ;
/* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[47] =
+static const flex_int32_t yy_rule_can_match_eol[54] =
{ 0,
-0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
+1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, };
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
/* The intent behind this definition is that it'll catch
* any uses of REJECT which flex missed.
@@ -553,8 +573,8 @@ static yyconst flex_int32_t yy_rule_can_match_eol[47] =
#define yymore() yymore_used_but_not_detected
#define YY_MORE_ADJ 0
#define YY_RESTORE_YY_MORE_OFFSET
-#line 1 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
-#line 2 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 1 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+#line 2 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
#include <stdio.h>
#include <string>
@@ -571,8 +591,9 @@ static yyconst flex_int32_t yy_rule_can_match_eol[47] =
#include "idlc/ast/tidlc_y.hpp"
#define YY_USER_ACTION yylloc->columns(yyleng);
+#line 595 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_l.cpp"
-#line 576 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_l.cpp"
+#line 597 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_l.cpp"
#define INITIAL 0
#define COMMENT 1
@@ -604,7 +625,7 @@ struct yyguts_t
YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
char yy_hold_char;
int yy_n_chars;
- yy_size_t yyleng_r;
+ int yyleng_r;
char *yy_c_buf_p;
int yy_init;
int yy_start;
@@ -628,7 +649,7 @@ struct yyguts_t
}; /* end struct yyguts_t */
-static int yy_init_globals (yyscan_t yyscanner );
+static int yy_init_globals ( yyscan_t yyscanner );
/* This must go here because YYSTYPE and YYLTYPE are included
* from bison output in section 1.*/
@@ -638,48 +659,48 @@ static int yy_init_globals (yyscan_t yyscanner );
int yylex_init (yyscan_t* scanner);
-int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
/* Accessor methods to globals.
These are made visible to non-reentrant scanners for convenience. */
-int yylex_destroy (yyscan_t yyscanner );
+int yylex_destroy ( yyscan_t yyscanner );
-int yyget_debug (yyscan_t yyscanner );
+int yyget_debug ( yyscan_t yyscanner );
-void yyset_debug (int debug_flag ,yyscan_t yyscanner );
+void yyset_debug ( int debug_flag , yyscan_t yyscanner );
-YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner );
+YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
-void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
-FILE *yyget_in (yyscan_t yyscanner );
+FILE *yyget_in ( yyscan_t yyscanner );
-void yyset_in (FILE * _in_str ,yyscan_t yyscanner );
+void yyset_in ( FILE * _in_str , yyscan_t yyscanner );
-FILE *yyget_out (yyscan_t yyscanner );
+FILE *yyget_out ( yyscan_t yyscanner );
-void yyset_out (FILE * _out_str ,yyscan_t yyscanner );
+void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
-yy_size_t yyget_leng (yyscan_t yyscanner );
+ int yyget_leng ( yyscan_t yyscanner );
-char *yyget_text (yyscan_t yyscanner );
+char *yyget_text ( yyscan_t yyscanner );
-int yyget_lineno (yyscan_t yyscanner );
+int yyget_lineno ( yyscan_t yyscanner );
-void yyset_lineno (int _line_number ,yyscan_t yyscanner );
+void yyset_lineno ( int _line_number , yyscan_t yyscanner );
-int yyget_column (yyscan_t yyscanner );
+int yyget_column ( yyscan_t yyscanner );
-void yyset_column (int _column_no ,yyscan_t yyscanner );
+void yyset_column ( int _column_no , yyscan_t yyscanner );
-YYSTYPE * yyget_lval (yyscan_t yyscanner );
+YYSTYPE * yyget_lval ( yyscan_t yyscanner );
-void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
- YYLTYPE *yyget_lloc (yyscan_t yyscanner );
+ YYLTYPE *yyget_lloc ( yyscan_t yyscanner );
- void yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
+ void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner );
/* Macros after this point can all be overridden by user definitions in
* section 1.
@@ -687,32 +708,31 @@ void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
-extern "C" int yywrap (yyscan_t yyscanner );
+extern "C" int yywrap ( yyscan_t yyscanner );
#else
-extern int yywrap (yyscan_t yyscanner );
+extern int yywrap ( yyscan_t yyscanner );
#endif
#endif
#ifndef YY_NO_UNPUT
- static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner);
+ static void yyunput ( int c, char *buf_ptr , yyscan_t yyscanner);
#endif
#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
#endif
#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
#endif
#ifndef YY_NO_INPUT
-
#ifdef __cplusplus
-static int yyinput (yyscan_t yyscanner );
+static int yyinput ( yyscan_t yyscanner );
#else
-static int input (yyscan_t yyscanner );
+static int input ( yyscan_t yyscanner );
#endif
#endif
@@ -732,7 +752,7 @@ static int input (yyscan_t yyscanner );
/* This used to be an fputs(), but since the string might contain NUL's,
* we now use fwrite().
*/
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
#endif
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
@@ -743,7 +763,7 @@ static int input (yyscan_t yyscanner );
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
int c = '*'; \
- size_t n; \
+ int n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
@@ -756,7 +776,7 @@ static int input (yyscan_t yyscanner );
else \
{ \
errno=0; \
- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
{ \
if( errno != EINTR) \
{ \
@@ -798,7 +818,7 @@ static int input (yyscan_t yyscanner );
#define YY_DECL_IS_OURS 1
extern int yylex \
- (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
+ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner);
#define YY_DECL int yylex \
(YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
@@ -852,21 +872,22 @@ YY_DECL
if ( ! YY_CURRENT_BUFFER ) {
yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
}
- yy_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
}
{
-#line 28 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 28 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+#line 31 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
std::string comments;
std::string values;
-#line 870 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_l.cpp"
+#line 891 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_l.cpp"
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{
@@ -893,13 +914,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 132 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ if ( yy_current_state >= 156 )
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
++yy_cp;
}
- while ( yy_base[yy_current_state] != 157 );
+ while ( yy_base[yy_current_state] != 200 );
yy_find_action:
yy_act = yy_accept[yy_current_state];
@@ -914,10 +935,10 @@ yy_find_action:
if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
{
- yy_size_t yyl;
+ int yyl;
for ( yyl = 0; yyl < yyleng; ++yyl )
if ( yytext[yyl] == '\n' )
-
+
do{ yylineno++;
yycolumn=0;
}while(0)
@@ -936,56 +957,56 @@ do_action: /* This label is used only to access EOF actions. */
goto yy_find_action;
case 1:
+/* rule 1 can match eol */
YY_RULE_SETUP
-#line 34 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
-{ comments += yytext; BEGIN(COMMENT); }
+#line 35 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+{ comments += yytext; yylloc->lines(1); yylloc->step(); BEGIN(INITIAL); }
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 35 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
-{ comments += yytext; yylloc->step(); BEGIN(INITIAL); }
+#line 36 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+{ comments += yytext; yylloc->step(); BEGIN(COMMENT); }
YY_BREAK
case 3:
YY_RULE_SETUP
-#line 36 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
-{ comments += yytext; comments += "\n"; BEGIN(INITIAL); }
+#line 37 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+{ comments += yytext; yylloc->lines(1); yylloc->step(); comments += "\n"; BEGIN(INITIAL); }
YY_BREAK
case 4:
/* rule 4 can match eol */
YY_RULE_SETUP
-#line 37 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
-{ comments += yytext; yylloc->step(); BEGIN(INITIAL); }
+#line 38 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+{ comments += yytext; yylloc->lines(1); yylloc->step(); BEGIN(INITIAL); }
YY_BREAK
case 5:
/* rule 5 can match eol */
YY_RULE_SETUP
-#line 38 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
-{ comments += yytext; yylloc->lines(yyleng); }
+#line 39 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+{ comments += yytext; yylloc->lines(1); }
YY_BREAK
case 6:
-/* rule 6 can match eol */
YY_RULE_SETUP
-#line 39 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
-{ comments += yytext; yylloc->step(); }
+#line 40 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+{ comments += yytext;}
YY_BREAK
case YY_STATE_EOF(COMMENT):
-#line 40 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 41 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ return 0; }
YY_BREAK
case 7:
/* rule 7 can match eol */
YY_RULE_SETUP
-#line 42 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
-{ comments += yytext; yylloc->step(); }
+#line 43 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+{ comments += yytext; yylloc->lines(1); yylloc->step(); }
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 44 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 45 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ BEGIN(VALUE); }
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 45 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 46 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
BEGIN(INITIAL);
yylval->token = new tidl::Token(values, comments);
@@ -995,246 +1016,299 @@ YY_RULE_SETUP
case 10:
/* rule 10 can match eol */
YY_RULE_SETUP
-#line 50 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 51 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ values += yytext; yylloc->step(); }
YY_BREAK
case 11:
/* rule 11 can match eol */
YY_RULE_SETUP
-#line 52 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 53 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ yylloc->lines(yyleng); yylloc->step(); }
YY_BREAK
case 12:
/* rule 12 can match eol */
YY_RULE_SETUP
-#line 54 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 55 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
; // ignore all whitespace
YY_BREAK
case 13:
YY_RULE_SETUP
-#line 55 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 56 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ return yy::parser::token::T_COMMA; }
YY_BREAK
case 14:
YY_RULE_SETUP
-#line 56 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 57 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ return yy::parser::token::T_BRACE_OPEN; }
YY_BREAK
case 15:
YY_RULE_SETUP
-#line 57 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 58 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ return yy::parser::token::T_BRACE_CLOSE; }
YY_BREAK
case 16:
YY_RULE_SETUP
-#line 58 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 59 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ return yy::parser::token::T_LEFT; }
YY_BREAK
case 17:
YY_RULE_SETUP
-#line 59 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 60 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ return yy::parser::token::T_RIGHT; }
YY_BREAK
case 18:
YY_RULE_SETUP
-#line 60 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 61 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ return yy::parser::token::T_SEMICOLON; }
YY_BREAK
case 19:
YY_RULE_SETUP
-#line 61 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 62 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+{ return yy::parser::token::T_COLON; }
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 63 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_VOID;
}
YY_BREAK
-case 20:
+case 21:
YY_RULE_SETUP
-#line 65 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 67 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_CHAR;
}
YY_BREAK
-case 21:
+case 22:
YY_RULE_SETUP
-#line 69 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 71 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_SHORT;
}
YY_BREAK
-case 22:
+case 23:
YY_RULE_SETUP
-#line 73 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 75 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_INT;
}
YY_BREAK
-case 23:
+case 24:
YY_RULE_SETUP
-#line 77 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 79 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_LONG;
}
YY_BREAK
-case 24:
+case 25:
YY_RULE_SETUP
-#line 81 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 83 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_FLOAT;
}
YY_BREAK
-case 25:
+case 26:
YY_RULE_SETUP
-#line 85 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 87 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_DOUBLE;
}
YY_BREAK
-case 26:
+case 27:
YY_RULE_SETUP
-#line 89 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 91 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_BUNDLE;
}
YY_BREAK
-case 27:
+case 28:
YY_RULE_SETUP
-#line 93 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 95 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_FILE;
}
YY_BREAK
-case 28:
+case 29:
YY_RULE_SETUP
-#line 97 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 99 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_STRING;
}
YY_BREAK
-case 29:
+case 30:
YY_RULE_SETUP
-#line 101 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 103 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_BOOL;
}
YY_BREAK
-case 30:
+case 31:
YY_RULE_SETUP
-#line 105 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 107 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+{
+ yylval->token = new tidl::Token(yytext, comments);
+ return yy::parser::token::T_PROTOCOL;
+ }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 111 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ return yy::parser::token::T_IN; }
YY_BREAK
-case 31:
+case 33:
YY_RULE_SETUP
-#line 106 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 112 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ return yy::parser::token::T_OUT; }
YY_BREAK
-case 32:
+case 34:
YY_RULE_SETUP
-#line 107 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 113 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ return yy::parser::token::T_REF; }
YY_BREAK
-case 33:
+case 35:
YY_RULE_SETUP
-#line 108 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 114 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ return yy::parser::token::T_ASYNC; }
YY_BREAK
-case 34:
+case 36:
YY_RULE_SETUP
-#line 109 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 115 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ return yy::parser::token::T_DELEGATE; }
YY_BREAK
-case 35:
+case 37:
YY_RULE_SETUP
-#line 110 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 116 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ return yy::parser::token::T_META_OPEN; }
YY_BREAK
-case 36:
+case 38:
YY_RULE_SETUP
-#line 111 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 117 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ return yy::parser::token::T_META_CLOSE; }
YY_BREAK
-case 37:
+case 39:
YY_RULE_SETUP
-#line 112 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 118 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_LIST;
}
YY_BREAK
-case 38:
+case 40:
+YY_RULE_SETUP
+#line 122 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+{
+ yylval->token = new tidl::Token(yytext, comments);
+ return yy::parser::token::T_ENUM;
+ }
+ YY_BREAK
+case 41:
YY_RULE_SETUP
-#line 116 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 126 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_ARRAY;
}
YY_BREAK
-case 39:
+case 42:
+YY_RULE_SETUP
+#line 130 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+{
+ yylval->token = new tidl::Token(yytext, comments);
+ return yy::parser::token::T_MAP;
+ }
+ YY_BREAK
+case 43:
YY_RULE_SETUP
-#line 120 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 134 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+{
+ yylval->token = new tidl::Token(yytext, comments);
+ return yy::parser::token::T_SET;
+ }
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 138 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_STRUCTURE;
}
YY_BREAK
-case 40:
+case 45:
YY_RULE_SETUP
-#line 124 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 142 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_INTERFACE;
}
YY_BREAK
-case 41:
+case 46:
YY_RULE_SETUP
-#line 128 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 146 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_ID;
}
YY_BREAK
-case 42:
+case 47:
+YY_RULE_SETUP
+#line 150 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+{
+ yylval->token = new tidl::Token(yytext, comments);
+ return yy::parser::token::T_NUMBER;
+ }
+ YY_BREAK
+case 48:
YY_RULE_SETUP
-#line 132 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 154 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+{
+ yylval->token = new tidl::Token(yytext, comments);
+ return yy::parser::token::T_HEX_NUMBER;
+ }
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 158 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ // Square Bracket
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_SB_OPEN;
}
YY_BREAK
-case 43:
+case 50:
YY_RULE_SETUP
-#line 136 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 162 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ // Square Bracket
yylval->token = new tidl::Token(yytext, comments);
return yy::parser::token::T_SB_CLOSE;
}
YY_BREAK
-case 44:
+case 51:
YY_RULE_SETUP
-#line 140 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 166 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
{ return yy::parser::token::T_EQUAL; }
YY_BREAK
-case 45:
+case 52:
YY_RULE_SETUP
-#line 141 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
-{ return yy::parser::token::T_UNKNOWN; }
+#line 167 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
+{ return yy::parser::token::T_DOT; }
YY_BREAK
-case 46:
+case 53:
YY_RULE_SETUP
-#line 143 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
+#line 169 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
ECHO;
YY_BREAK
-#line 1238 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_l.cpp"
+#line 1312 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_l.cpp"
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(VALUE):
yyterminate();
@@ -1313,7 +1387,7 @@ case YY_STATE_EOF(VALUE):
{
yyg->yy_did_buffer_switch_on_eof = 0;
- if ( yywrap(yyscanner ) )
+ if ( yywrap( yyscanner ) )
{
/* Note: because we've taken care in
* yy_get_next_buffer() to have set up
@@ -1381,7 +1455,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
char *source = yyg->yytext_ptr;
- yy_size_t number_to_move, i;
+ int number_to_move, i;
int ret_val;
if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
@@ -1410,7 +1484,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
/* Try to read more data. */
/* First move last chars to start of buffer. */
- number_to_move = (yy_size_t) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1);
for ( i = 0; i < number_to_move; ++i )
*(dest++) = *(source++);
@@ -1423,7 +1497,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
{
- yy_size_t num_to_read =
+ int num_to_read =
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 )
@@ -1437,7 +1511,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( b->yy_is_our_buffer )
{
- yy_size_t new_size = b->yy_buf_size * 2;
+ int new_size = b->yy_buf_size * 2;
if ( new_size <= 0 )
b->yy_buf_size += b->yy_buf_size / 8;
@@ -1446,11 +1520,12 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
b->yy_ch_buf = (char *)
/* Include room in for 2 EOB chars. */
- yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+ yyrealloc( (void *) b->yy_ch_buf,
+ (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
}
else
/* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
+ b->yy_ch_buf = NULL;
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR(
@@ -1478,7 +1553,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( number_to_move == YY_MORE_ADJ )
{
ret_val = EOB_ACT_END_OF_FILE;
- yyrestart(yyin ,yyscanner);
+ yyrestart( yyin , yyscanner);
}
else
@@ -1492,12 +1567,15 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
ret_val = EOB_ACT_CONTINUE_SCAN;
- if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
/* Extend the array by 50%, plus the number we really need. */
int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+ (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner );
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
}
yyg->yy_n_chars += number_to_move;
@@ -1530,10 +1608,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 132 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ if ( yy_current_state >= 156 )
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
}
return yy_current_state;
@@ -1559,11 +1637,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 132 )
- yy_c = yy_meta[(unsigned int) yy_c];
+ if ( yy_current_state >= 156 )
+ yy_c = yy_meta[yy_c];
}
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 131);
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ yy_is_jam = (yy_current_state == 155);
(void)yyg;
return yy_is_jam ? 0 : yy_current_state;
@@ -1584,7 +1662,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
{ /* need to shift things up to make room */
/* +2 for EOB chars. */
- yy_size_t number_to_move = yyg->yy_n_chars + 2;
+ int number_to_move = yyg->yy_n_chars + 2;
char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
char *source =
@@ -1596,7 +1674,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
yy_cp += (int) (dest - source);
yy_bp += (int) (dest - source);
YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+ yyg->yy_n_chars = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
YY_FATAL_ERROR( "flex scanner push-back overflow" );
@@ -1640,7 +1718,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
else
{ /* need more input */
- yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr);
++yyg->yy_c_buf_p;
switch ( yy_get_next_buffer( yyscanner ) )
@@ -1657,14 +1735,14 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
*/
/* Reset buffer status. */
- yyrestart(yyin ,yyscanner);
+ yyrestart( yyin , yyscanner);
/*FALLTHROUGH*/
case EOB_ACT_END_OF_FILE:
{
- if ( yywrap(yyscanner ) )
- return EOF;
+ if ( yywrap( yyscanner ) )
+ return 0;
if ( ! yyg->yy_did_buffer_switch_on_eof )
YY_NEW_FILE;
@@ -1687,7 +1765,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
yyg->yy_hold_char = *++yyg->yy_c_buf_p;
if ( c == '\n' )
-
+
do{ yylineno++;
yycolumn=0;
}while(0)
@@ -1709,11 +1787,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
if ( ! YY_CURRENT_BUFFER ){
yyensure_buffer_stack (yyscanner);
YY_CURRENT_BUFFER_LVALUE =
- yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
}
- yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
- yy_load_buffer_state(yyscanner );
+ yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner);
+ yy_load_buffer_state( yyscanner );
}
/** Switch to a different input buffer.
@@ -1742,7 +1820,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
}
YY_CURRENT_BUFFER_LVALUE = new_buffer;
- yy_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
/* We don't actually know whether we did this switch during
* EOF (yywrap()) processing, but the only time this flag
@@ -1771,22 +1849,22 @@ static void yy_load_buffer_state (yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
- b->yy_buf_size = (yy_size_t)size;
+ b->yy_buf_size = size;
/* yy_ch_buf has to be 2 characters longer than the size given because
* we need to put in 2 end-of-buffer characters.
*/
- b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ,yyscanner );
+ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
if ( ! b->yy_ch_buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
b->yy_is_our_buffer = 1;
- yy_init_buffer(b,file ,yyscanner);
+ yy_init_buffer( b, file , yyscanner);
return b;
}
@@ -1806,9 +1884,9 @@ static void yy_load_buffer_state (yyscan_t yyscanner)
YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
if ( b->yy_is_our_buffer )
- yyfree((void *) b->yy_ch_buf ,yyscanner );
+ yyfree( (void *) b->yy_ch_buf , yyscanner );
- yyfree((void *) b ,yyscanner );
+ yyfree( (void *) b , yyscanner );
}
/* Initializes or reinitializes a buffer.
@@ -1821,7 +1899,7 @@ static void yy_load_buffer_state (yyscan_t yyscanner)
int oerrno = errno;
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yy_flush_buffer(b ,yyscanner);
+ yy_flush_buffer( b , yyscanner);
b->yy_input_file = file;
b->yy_fill_buffer = 1;
@@ -1865,7 +1943,7 @@ static void yy_load_buffer_state (yyscan_t yyscanner)
b->yy_buffer_status = YY_BUFFER_NEW;
if ( b == YY_CURRENT_BUFFER )
- yy_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
}
/** Pushes the new state onto the stack. The new state becomes
@@ -1897,7 +1975,7 @@ void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
YY_CURRENT_BUFFER_LVALUE = new_buffer;
/* copied from yy_switch_to_buffer. */
- yy_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
@@ -1911,13 +1989,13 @@ void yypop_buffer_state (yyscan_t yyscanner)
if (!YY_CURRENT_BUFFER)
return;
- yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner);
YY_CURRENT_BUFFER_LVALUE = NULL;
if (yyg->yy_buffer_stack_top > 0)
--yyg->yy_buffer_stack_top;
if (YY_CURRENT_BUFFER) {
- yy_load_buffer_state(yyscanner );
+ yy_load_buffer_state( yyscanner );
yyg->yy_did_buffer_switch_on_eof = 1;
}
}
@@ -1936,15 +2014,15 @@ static void yyensure_buffer_stack (yyscan_t yyscanner)
* scanner will even need a stack. We use 2 instead of 1 to avoid an
* immediate realloc on the next call.
*/
- num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc
(num_to_alloc * sizeof(struct yy_buffer_state*)
, yyscanner);
if ( ! yyg->yy_buffer_stack )
YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-
+
memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
+
yyg->yy_buffer_stack_max = num_to_alloc;
yyg->yy_buffer_stack_top = 0;
return;
@@ -1973,7 +2051,7 @@ static void yyensure_buffer_stack (yyscan_t yyscanner)
* @param base the character buffer
* @param size the size in bytes of the character buffer
* @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
+ * @return the newly allocated buffer state object.
*/
YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
{
@@ -1983,23 +2061,23 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscann
base[size-2] != YY_END_OF_BUFFER_CHAR ||
base[size-1] != YY_END_OF_BUFFER_CHAR )
/* They forgot to leave room for the EOB's. */
- return 0;
+ return NULL;
- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */
b->yy_buf_pos = b->yy_ch_buf = base;
b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
+ b->yy_input_file = NULL;
b->yy_n_chars = b->yy_buf_size;
b->yy_is_interactive = 0;
b->yy_at_bol = 1;
b->yy_fill_buffer = 0;
b->yy_buffer_status = YY_BUFFER_NEW;
- yy_switch_to_buffer(b ,yyscanner );
+ yy_switch_to_buffer( b , yyscanner );
return b;
}
@@ -2012,10 +2090,10 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscann
* @note If you want to scan bytes that may contain NUL values, then use
* yy_scan_bytes() instead.
*/
-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner)
{
- return yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+ return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner);
}
/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
@@ -2025,16 +2103,16 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
* @param yyscanner The scanner object.
* @return the newly allocated buffer state object.
*/
-YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner)
{
YY_BUFFER_STATE b;
char *buf;
yy_size_t n;
- yy_size_t i;
+ int i;
/* Get memory for full buffer, including space for trailing EOB's. */
- n = _yybytes_len + 2;
- buf = (char *) yyalloc(n ,yyscanner );
+ n = (yy_size_t) (_yybytes_len + 2);
+ buf = (char *) yyalloc( n , yyscanner );
if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
@@ -2043,7 +2121,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len
buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
- b = yy_scan_buffer(buf,n ,yyscanner);
+ b = yy_scan_buffer( buf, n , yyscanner);
if ( ! b )
YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
@@ -2059,11 +2137,11 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len
#define YY_EXIT_FAILURE 2
#endif
-static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
- (void) fprintf( stderr, "%s\n", msg );
+ fprintf( stderr, "%s\n", msg );
exit( YY_EXIT_FAILURE );
}
@@ -2101,7 +2179,7 @@ YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner)
int yyget_lineno (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+
if (! YY_CURRENT_BUFFER)
return 0;
@@ -2114,7 +2192,7 @@ int yyget_lineno (yyscan_t yyscanner)
int yyget_column (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
+
if (! YY_CURRENT_BUFFER)
return 0;
@@ -2142,7 +2220,7 @@ FILE *yyget_out (yyscan_t yyscanner)
/** Get the length of the current token.
* @param yyscanner The scanner object.
*/
-yy_size_t yyget_leng (yyscan_t yyscanner)
+int yyget_leng (yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
return yyleng;
@@ -2260,9 +2338,7 @@ void yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner)
* the ONLY reentrant function that doesn't take the scanner as the last argument.
* That's why we explicitly handle the declaration, instead of using our macros.
*/
-
int yylex_init(yyscan_t* ptr_yy_globals)
-
{
if (ptr_yy_globals == NULL){
errno = EINVAL;
@@ -2289,9 +2365,7 @@ int yylex_init(yyscan_t* ptr_yy_globals)
* The user defined value in the first argument will be available to yyalloc in
* the yyextra field.
*/
-
-int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
-
+int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals )
{
struct yyguts_t dummy_yyguts;
@@ -2301,20 +2375,20 @@ int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
errno = EINVAL;
return 1;
}
-
+
*ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-
+
if (*ptr_yy_globals == NULL){
errno = ENOMEM;
return 1;
}
-
+
/* By setting to 0xAA, we expose bugs in
yy_init_globals. Leave at 0x00 for releases. */
memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
+
yyset_extra (yy_user_defined, *ptr_yy_globals);
-
+
return yy_init_globals ( *ptr_yy_globals );
}
@@ -2325,10 +2399,10 @@ static int yy_init_globals (yyscan_t yyscanner)
* This function is called from yylex_destroy(), so don't allocate here.
*/
- yyg->yy_buffer_stack = 0;
+ yyg->yy_buffer_stack = NULL;
yyg->yy_buffer_stack_top = 0;
yyg->yy_buffer_stack_max = 0;
- yyg->yy_c_buf_p = (char *) 0;
+ yyg->yy_c_buf_p = NULL;
yyg->yy_init = 0;
yyg->yy_start = 0;
@@ -2341,8 +2415,8 @@ static int yy_init_globals (yyscan_t yyscanner)
yyin = stdin;
yyout = stdout;
#else
- yyin = (FILE *) 0;
- yyout = (FILE *) 0;
+ yyin = NULL;
+ yyout = NULL;
#endif
/* For future reference: Set errno on error, since we are called by
@@ -2358,17 +2432,17 @@ int yylex_destroy (yyscan_t yyscanner)
/* Pop the buffer stack, destroying each element. */
while(YY_CURRENT_BUFFER){
- yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner );
YY_CURRENT_BUFFER_LVALUE = NULL;
yypop_buffer_state(yyscanner);
}
/* Destroy the stack itself. */
- yyfree(yyg->yy_buffer_stack ,yyscanner);
+ yyfree(yyg->yy_buffer_stack , yyscanner);
yyg->yy_buffer_stack = NULL;
/* Destroy the start condition stack. */
- yyfree(yyg->yy_start_stack ,yyscanner );
+ yyfree( yyg->yy_start_stack , yyscanner );
yyg->yy_start_stack = NULL;
/* Reset the globals. This is important in a non-reentrant scanner so the next time
@@ -2386,7 +2460,7 @@ int yylex_destroy (yyscan_t yyscanner)
*/
#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
@@ -2398,7 +2472,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yysca
#endif
#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+static int yy_flex_strlen (const char * s , yyscan_t yyscanner)
{
int n;
for ( n = 0; s[n]; ++n )
@@ -2412,7 +2486,7 @@ void *yyalloc (yy_size_t size , yyscan_t yyscanner)
{
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
(void)yyg;
- return (void *) malloc( size );
+ return malloc(size);
}
void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
@@ -2427,7 +2501,7 @@ void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
* any pointer type to void*, and deal with argument conversions
* as though doing an assignment.
*/
- return (void *) realloc( (char *) ptr, size );
+ return realloc(ptr, size);
}
void yyfree (void * ptr , yyscan_t yyscanner)
@@ -2439,8 +2513,7 @@ void yyfree (void * ptr , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables"
-#line 143 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.ll"
-
+#line 169 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.ll"
diff --git a/idlc/ast/tidlc_y.cpp b/idlc/ast/tidlc_y.cpp
index 4a686f0..a649126 100644
--- a/idlc/ast/tidlc_y.cpp
+++ b/idlc/ast/tidlc_y.cpp
@@ -1,8 +1,8 @@
-// A Bison parser, made by GNU Bison 3.0.4.
+// A Bison parser, made by GNU Bison 3.5.1.
// Skeleton implementation for Bison GLR parsers in C
-// Copyright (C) 2002-2015 Free Software Foundation, Inc.
+// Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -32,11 +32,14 @@
/* C GLR parser skeleton written by Paul Hilfinger. */
+// Undocumented macros, especially those whose name start with YY_,
+// are private implementation details. Do not rely on them.
+
/* Identify Bison output. */
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.0.4"
+#define YYBISON_VERSION "3.5.1"
/* Skeleton name. */
#define YYSKELETON_NAME "glr.cc"
@@ -49,8 +52,8 @@
-/* First part of user declarations. */
-#line 1 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:240
+// First part of user prologue.
+#line 1 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
#include <stdio.h>
#include <stdlib.h>
@@ -63,6 +66,7 @@
#include "idlc/ast/parameter.h"
#include "idlc/ast/interface.h"
#include "idlc/ast/element.h"
+#include "idlc/ast/enum.h"
#include "idlc/ast/structure.h"
#include "idlc/ast/block.h"
#include "idlc/ast/attribute.h"
@@ -72,14 +76,30 @@ int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
#define lex_scanner ps->Scanner()
+tidl::Enums* currentInterfaceEnums;
+tidl::Declarations* currentDeclarations = nullptr;
+tidl::Document* document = nullptr;
-#line 77 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:240
+#line 84 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+# ifndef YY_CAST
+# ifdef __cplusplus
+# define YY_CAST(Type, Val) static_cast<Type> (Val)
+# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)
+# else
+# define YY_CAST(Type, Val) ((Type) (Val))
+# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))
+# endif
+# endif
# ifndef YY_NULLPTR
-# if defined __cplusplus && 201103L <= __cplusplus
-# define YY_NULLPTR nullptr
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
# else
-# define YY_NULLPTR 0
+# define YY_NULLPTR ((void*)0)
# endif
# endif
@@ -104,35 +124,73 @@ static YYLTYPE yyloc_default
# endif
;
-/* Copy the second part of user declarations. */
-#line 109 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:263
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
- If N is 0, then set CURRENT to the empty location which ends
- the previous symbol: RHS[0] (always defined). */
-
-# ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- do \
- if (N) \
- { \
- (Current).begin = YYRHSLOC (Rhs, 1).begin; \
- (Current).end = YYRHSLOC (Rhs, N).end; \
- } \
- else \
- { \
- (Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end; \
- } \
- while (/*CONSTCOND*/ false)
-# endif
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)
+// Second part of user prologue.
+#line 129 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
static void yyerror (const yy::parser::location_type *yylocationp, yy::parser& yyparser, tidl::Parser* ps, const char* msg);
-#line 131 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:263
+#line 131 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+
+#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
+ <limits.h> and (if available) <stdint.h> are included
+ so that the code can choose integer types of a good width. */
+
+#ifndef __PTRDIFF_MAX__
+# include <limits.h> /* INFRINGES ON USER NAME SPACE */
+# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+# include <stdint.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_STDINT_H
+# endif
+#endif
+
+/* Narrow types that promote to a signed type and that can represent a
+ signed or unsigned integer of at least N bits. In tables they can
+ save space and decrease cache pressure. Promoting to a signed type
+ helps avoid bugs in integer arithmetic. */
+
+#ifdef __INT_LEAST8_MAX__
+typedef __INT_LEAST8_TYPE__ yytype_int8;
+#elif defined YY_STDINT_H
+typedef int_least8_t yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef __INT_LEAST16_MAX__
+typedef __INT_LEAST16_TYPE__ yytype_int16;
+#elif defined YY_STDINT_H
+typedef int_least16_t yytype_int16;
+#else
+typedef short yytype_int16;
+#endif
+
+#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST8_TYPE__ yytype_uint8;
+#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
+ && UINT_LEAST8_MAX <= INT_MAX)
+typedef uint_least8_t yytype_uint8;
+#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
+typedef unsigned char yytype_uint8;
+#else
+typedef short yytype_uint8;
+#endif
+
+#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST16_TYPE__ yytype_uint16;
+#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
+ && UINT_LEAST16_MAX <= INT_MAX)
+typedef uint_least16_t yytype_uint16;
+#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
+typedef unsigned short yytype_uint16;
+#else
+typedef int yytype_uint16;
+#endif
+
#ifndef YY_
# if defined YYENABLE_NLS && YYENABLE_NLS
# if ENABLE_NLS
@@ -155,48 +213,64 @@ static void yyerror (const yy::parser::location_type *yylocationp, yy::parser& y
# define YYREALLOC realloc
#endif
-#define YYSIZEMAX ((size_t) -1)
+#define YYSIZEMAX \
+ (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : YY_CAST (ptrdiff_t, SIZE_MAX))
#ifdef __cplusplus
- typedef bool yybool;
+ typedef bool yybool;
+# define yytrue true
+# define yyfalse false
#else
- typedef unsigned char yybool;
+ /* When we move to stdbool, get rid of the various casts to yybool. */
+ typedef signed char yybool;
+# define yytrue 1
+# define yyfalse 0
#endif
-#define yytrue 1
-#define yyfalse 0
#ifndef YYSETJMP
# include <setjmp.h>
# define YYJMP_BUF jmp_buf
# define YYSETJMP(Env) setjmp (Env)
-/* Pacify clang. */
-# define YYLONGJMP(Env, Val) (longjmp (Env, Val), YYASSERT (0))
+/* Pacify Clang and ICC. */
+# define YYLONGJMP(Env, Val) \
+ do { \
+ longjmp (Env, Val); \
+ YY_ASSERT (0); \
+ } while (yyfalse)
#endif
-#ifndef YY_ATTRIBUTE
-# if (defined __GNUC__ \
- && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
- || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
-# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+#ifndef YY_ATTRIBUTE_PURE
+# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
# else
-# define YY_ATTRIBUTE(Spec) /* empty */
+# define YY_ATTRIBUTE_PURE
# endif
#endif
-#ifndef YY_ATTRIBUTE_PURE
-# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
-#endif
-
#ifndef YY_ATTRIBUTE_UNUSED
-# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+# else
+# define YY_ATTRIBUTE_UNUSED
+# endif
#endif
-#if !defined _Noreturn \
- && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
+/* The _Noreturn keyword of C11. */
+#ifndef _Noreturn
+# if (defined __cplusplus \
+ && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \
+ || (defined _MSC_VER && 1900 <= _MSC_VER)))
+# define _Noreturn [[noreturn]]
+# elif ((!defined __cplusplus || defined __clang__) \
+ && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
+ || 4 < __GNUC__ + (7 <= __GNUC_MINOR__)))
+ /* _Noreturn works as-is. */
+# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C
+# define _Noreturn __attribute__ ((__noreturn__))
+# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)
# define _Noreturn __declspec (noreturn)
# else
-# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
+# define _Noreturn
# endif
#endif
@@ -207,13 +281,13 @@ static void yyerror (const yy::parser::location_type *yylocationp, yy::parser& y
# define YYUSE(E) /* empty */
#endif
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
/* Suppress an incorrect diagnostic about yylval being uninitialized. */
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
- _Pragma ("GCC diagnostic push") \
- _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
_Pragma ("GCC diagnostic pop")
#else
# define YY_INITIAL_VALUE(Value) Value
@@ -226,39 +300,57 @@ static void yyerror (const yy::parser::location_type *yylocationp, yy::parser& y
# define YY_INITIAL_VALUE(Value) /* Nothing. */
#endif
-
-#ifndef YYASSERT
-# define YYASSERT(Condition) ((void) ((Condition) || (abort (), 0)))
+#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
+# define YY_IGNORE_USELESS_CAST_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
+# define YY_IGNORE_USELESS_CAST_END \
+ _Pragma ("GCC diagnostic pop")
#endif
+#ifndef YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_END
+#endif
+
+
+#define YY_ASSERT(E) ((void) (0 && (E)))
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 19
+#define YYFINAL 23
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 388
+#define YYLAST 819
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 37
+#define YYNTOKENS 44
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 20
+#define YYNNTS 25
/* YYNRULES -- Number of rules. */
-#define YYNRULES 70
-/* YYNRULES -- Number of states. */
-#define YYNSTATES 135
+#define YYNRULES 97
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES 197
/* YYMAXRHS -- Maximum number of symbols on right-hand side of rule. */
-#define YYMAXRHS 8
+#define YYMAXRHS 10
/* YYMAXLEFT -- Maximum number of symbols to the left of a handle
accessed by $0, $-1, etc., in any rule. */
#define YYMAXLEFT 0
-/* YYTRANSLATE(X) -- Bison symbol number corresponding to X. */
+/* YYMAXUTOK -- Last valid token number (for yychar). */
+#define YYMAXUTOK 298
+/* YYFAULTYTOK -- Token number (for yychar) that denotes a
+ syntax_error thrown from the scanner. */
+#define YYFAULTYTOK (YYMAXUTOK + 1)
+/* YYUNDEFTOK -- Symbol number (for yytoken) that denotes an unknown
+ token. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 291
-#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, with out-of-bounds checking. */
+#define YYTRANSLATE(YYX) \
+ (0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
-static const unsigned char yytranslate[] =
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex. */
+static const yytype_int8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -289,21 +381,23 @@ static const unsigned char yytranslate[] =
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
+ 35, 36, 37, 38, 39, 40, 41, 42, 43
};
#if YYDEBUG
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const unsigned short int yyrline[] =
-{
- 0, 96, 96, 101, 106, 120, 123, 128, 134, 139,
- 145, 152, 158, 169, 175, 180, 184, 188, 194, 200,
- 211, 217, 222, 228, 235, 241, 249, 254, 259, 266,
- 272, 283, 289, 294, 301, 309, 314, 319, 324, 328,
- 332, 336, 340, 346, 352, 363, 369, 372, 375, 380,
- 383, 387, 393, 396, 402, 405, 417, 420, 424, 428,
- 432, 436, 440, 444, 448, 452, 456, 460, 466, 473,
- 477
+static const yytype_int16 yyrline[] =
+{
+ 0, 116, 116, 121, 127, 141, 145, 149, 154, 167,
+ 176, 188, 200, 212, 239, 268, 295, 300, 306, 313,
+ 322, 335, 347, 355, 368, 372, 376, 380, 384, 388,
+ 394, 402, 413, 419, 429, 433, 437, 443, 451, 462,
+ 468, 473, 479, 486, 492, 500, 506, 514, 519, 524,
+ 531, 540, 551, 557, 570, 589, 597, 610, 625, 630,
+ 635, 640, 644, 648, 652, 656, 662, 670, 681, 687,
+ 690, 693, 698, 701, 705, 711, 714, 720, 723, 740,
+ 743, 747, 751, 755, 759, 763, 767, 771, 781, 785,
+ 789, 837, 864, 884, 901, 905, 909, 917
};
#endif
@@ -313,215 +407,327 @@ static const unsigned short int yyrline[] =
static const char *const yytname[] =
{
"$end", "error", "$undefined", "T_LEFT", "T_RIGHT", "T_COMMA",
- "T_SEMICOLON", "T_BRACE_OPEN", "T_BRACE_CLOSE", "T_IN", "T_OUT", "T_REF",
- "T_ASYNC", "T_META_OPEN", "T_META_CLOSE", "T_EQUAL", "T_DELEGATE",
- "T_UNKNOWN", "T_ID", "T_STRUCTURE", "T_INTERFACE", "T_CHAR", "T_SHORT",
- "T_INT", "T_LONG", "T_FLOAT", "T_DOUBLE", "T_VOID", "T_BUNDLE",
- "T_STRING", "T_BOOL", "T_LIST", "T_ARRAY", "T_VALUE", "T_SB_OPEN",
- "T_SB_CLOSE", "T_FILE", "$accept", "start", "blocks", "block",
- "structure_block", "elements", "element", "attributes", "attribute",
- "interface_block", "declarations", "declaration", "parameter_list",
- "direction_specifier", "parameter", "parameter_type", "base_type",
- "raw_type", "container_type", "container_type_name", YY_NULLPTR
+ "T_SEMICOLON", "T_COLON", "T_BRACE_OPEN", "T_BRACE_CLOSE", "T_IN",
+ "T_OUT", "T_REF", "T_ASYNC", "T_META_OPEN", "T_META_CLOSE", "T_EQUAL",
+ "T_DELEGATE", "T_DOT", "T_ID", "T_NUMBER", "T_HEX_NUMBER", "T_STRUCTURE",
+ "T_INTERFACE", "T_CHAR", "T_SHORT", "T_INT", "T_LONG", "T_FLOAT",
+ "T_DOUBLE", "T_VOID", "T_BUNDLE", "T_STRING", "T_BOOL", "T_LIST",
+ "T_ARRAY", "T_MAP", "T_SET", "T_VALUE", "T_SB_OPEN", "T_SB_CLOSE",
+ "T_FILE", "T_PROTOCOL", "T_ENUM", "$accept", "start", "blocks", "block",
+ "protocol_block", "structure_block", "enums", "enum", "fields", "field",
+ "elements", "element", "attributes", "attribute", "interface_block",
+ "declarations", "declaration", "parameter_list", "direction_specifier",
+ "parameter", "parameter_type", "base_type", "raw_type", "container_type",
+ "container_type_name", YY_NULLPTR
};
#endif
-#define YYPACT_NINF -67
-#define YYTABLE_NINF -58
+#define YYPACT_NINF (-83)
+#define YYTABLE_NINF (-81)
// YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
// STATE-NUM.
-static const short int yypact[] =
-{
- -4, 24, 45, 21, 10, -4, -67, -67, -67, 69,
- 296, 5, 87, 336, 13, -67, 49, 6, -67, -67,
- -67, 296, -67, -67, -67, -67, -67, -67, -67, -67,
- -67, -67, -67, -67, -67, -67, -67, 217, -67, 20,
- -67, 4, 296, 336, -67, 42, -67, 89, -67, 52,
- -67, 336, 14, 2, 33, 34, 249, 51, -67, -67,
- 65, -67, 67, 352, 281, 121, 85, 57, 93, 117,
- -67, -67, 118, 57, 98, 153, -67, -67, -67, -67,
- 108, -67, -67, -67, -67, 113, -67, -67, -67, -67,
- -67, -67, -67, 110, 95, 352, -67, 112, -67, 57,
- -67, -67, 99, 57, -67, 124, -67, 7, 320, -67,
- -67, 101, 126, 104, 336, 127, 128, -67, 53, -67,
- 86, 185, -67, -67, -67, 129, 130, -67, 131, 132,
- -67, -67, -67, -67, -67
+static const yytype_int16 yypact[] =
+{
+ 28, 7, 15, 21, 10, 49, 28, -83, -83, -83,
+ -83, 53, 672, 71, 87, 740, 46, -83, 55, -1,
+ -83, -83, -83, -83, -83, 672, -83, -83, 40, -83,
+ -83, -83, -83, -83, -83, -83, -83, -83, -83, -83,
+ -83, -83, -83, 468, -83, 41, -83, 72, 63, 172,
+ 740, -83, 80, 21, -83, 246, -83, 84, -83, 719,
+ 69, 6, 93, 95, 505, 102, 127, -83, -83, 129,
+ -83, 131, 759, 130, 113, 115, -83, 542, 283, 148,
+ 209, 153, 5, 149, -83, -83, 151, 209, 156, 719,
+ 320, -83, -83, -83, -83, 141, -83, -83, -83, -83,
+ -83, 4, 172, 154, -83, -83, 579, -83, -83, -83,
+ -83, -83, -83, -83, 144, 101, 759, -83, 145, -83,
+ 209, 778, -83, -83, 106, 209, 357, -83, 157, 759,
+ -83, 152, 616, 147, -83, 8, 700, -83, -83, 110,
+ 150, 155, 161, 122, -83, 719, 160, -83, 653, -83,
+ 1, 57, -83, 162, 164, -83, 42, 169, 187, -83,
+ 85, 719, 394, -83, -83, -83, 68, -83, -83, -83,
+ -83, -83, 186, 188, 209, 209, -83, 205, 206, 431,
+ -83, 211, 212, -83, -83, 124, 126, -83, -83, -83,
+ -83, -83, 180, 216, 217, -83, -83
};
// YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
// Performed when YYTABLE does not specify something else to do. Zero
// means the default is an error.
-static const unsigned char yydefact[] =
-{
- 0, 0, 0, 0, 0, 2, 3, 6, 5, 0,
- 0, 0, 0, 0, 0, 20, 0, 0, 18, 1,
- 4, 0, 10, 17, 67, 58, 59, 60, 61, 62,
- 63, 57, 64, 65, 66, 69, 70, 0, 11, 0,
- 56, 0, 0, 0, 28, 0, 55, 0, 29, 0,
- 54, 0, 0, 0, 0, 0, 0, 17, 8, 12,
- 0, 15, 0, 0, 0, 0, 0, 0, 0, 0,
- 26, 30, 0, 0, 0, 0, 22, 23, 21, 19,
- 0, 9, 13, 16, 14, 0, 7, 27, 42, 45,
- 46, 47, 48, 50, 0, 0, 43, 0, 52, 0,
- 31, 41, 0, 0, 24, 0, 68, 0, 49, 53,
- 51, 0, 0, 0, 0, 0, 0, 44, 0, 38,
- 0, 0, 39, 40, 37, 0, 0, 32, 0, 0,
- 25, 33, 34, 35, 36
+static const yytype_int8 yydefact[] =
+{
+ 0, 0, 0, 0, 0, 0, 2, 3, 7, 6,
+ 5, 0, 0, 0, 0, 0, 0, 39, 0, 0,
+ 37, 9, 8, 1, 4, 0, 18, 36, 90, 81,
+ 82, 83, 84, 85, 86, 80, 87, 88, 89, 94,
+ 95, 96, 97, 0, 30, 0, 79, 0, 0, 0,
+ 0, 49, 0, 0, 78, 0, 50, 0, 77, 0,
+ 0, 0, 0, 0, 0, 0, 36, 16, 31, 0,
+ 34, 0, 0, 0, 0, 0, 19, 0, 0, 0,
+ 0, 0, 0, 0, 47, 51, 0, 0, 0, 0,
+ 0, 41, 42, 40, 38, 0, 17, 91, 32, 35,
+ 33, 0, 0, 0, 12, 20, 0, 10, 48, 65,
+ 68, 69, 70, 71, 73, 0, 0, 66, 0, 75,
+ 0, 0, 52, 64, 0, 0, 0, 43, 0, 0,
+ 92, 0, 0, 0, 11, 0, 72, 76, 74, 0,
+ 0, 0, 0, 0, 45, 0, 0, 15, 0, 13,
+ 27, 0, 22, 0, 0, 67, 0, 0, 0, 61,
+ 0, 0, 0, 93, 14, 24, 0, 21, 23, 62,
+ 63, 60, 0, 0, 0, 0, 53, 0, 0, 0,
+ 44, 28, 29, 55, 57, 0, 0, 58, 59, 46,
+ 25, 26, 0, 0, 0, 54, 56
};
// YYPGOTO[NTERM-NUM].
-static const short int yypgoto[] =
+static const yytype_int16 yypgoto[] =
{
- -67, -67, -67, 135, -67, -15, -32, -67, 102, -67,
- -42, -47, -66, -67, 47, -67, -59, -8, -67, -67
+ -83, -83, -83, 218, -83, -83, -45, -57, -83, 67,
+ -22, -31, 173, 163, -83, -48, -54, -82, -83, 91,
+ -83, -52, -12, -83, -83
};
// YYDEFGOTO[NTERM-NUM].
-static const signed char yydefgoto[] =
+static const yytype_int16 yydefgoto[] =
{
- -1, 4, 5, 6, 7, 37, 38, 17, 18, 8,
- 47, 48, 94, 95, 96, 97, 49, 50, 40, 41
+ -1, 5, 6, 7, 8, 9, 75, 76, 151, 152,
+ 43, 44, 19, 20, 10, 55, 56, 115, 116, 117,
+ 118, 57, 58, 46, 47
};
// YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
// positive, shift that token. If negative, reduce the rule whose
// number is the opposite. If YYTABLE_NINF, syntax error.
-static const short int yytable[] =
-{
- 71, 65, 39, 77, 85, 59, 56, 102, 98, 75,
- 19, 54, 42, 39, 98, 1, 2, 63, 71, 115,
- 51, 60, 15, 116, 59, 9, 61, 64, 71, 39,
- 3, 10, 59, 111, 39, 78, 109, 113, 62, 16,
- 98, 55, 11, 66, 98, 67, 12, 76, 39, 98,
- 52, 16, 13, 72, 80, 73, 39, 82, 89, 124,
- 68, -49, -49, 14, 53, 125, 90, 91, 92, 126,
- 74, 83, 121, 84, 71, 24, 21, 22, 25, 26,
- 27, 28, 29, 30, 93, 32, 33, 34, 35, 36,
- 69, 88, 127, 46, 43, 44, 99, 70, 128, 107,
- 108, 103, 129, 112, 108, 118, 108, 24, 120, 108,
- 25, 26, 27, 28, 29, 30, 45, 32, 33, 34,
- 35, 36, 69, 100, 101, 46, 105, 106, -57, 87,
- 110, 114, 119, 122, 123, 131, 132, 133, 134, 24,
- 20, 0, 25, 26, 27, 28, 29, 30, 45, 32,
- 33, 34, 35, 36, 69, 117, 79, 46, 0, 0,
- 0, 104, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 24, 0, 0, 25, 26, 27, 28, 29, 30,
- 45, 32, 33, 34, 35, 36, 69, 0, 0, 46,
- 0, 0, 0, 130, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 24, 0, 0, 25, 26, 27, 28,
- 29, 30, 45, 32, 33, 34, 35, 36, 57, 0,
- 0, 46, 0, 0, 0, 58, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 24, 0, 0, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 57, 0, 0, 0, 0, 0, 0, 81, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 24, 0, 0,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 57, 0, 0, 0, 0, 0, 0, 86,
- 0, 0, 0, 0, 0, 0, 0, 23, 0, 24,
- 0, 0, 25, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 24, 0, 0, 25, 26, 27,
- 28, 29, 30, 31, 32, 33, 34, 35, 36, 90,
- 91, 92, 0, 0, 0, 0, 0, 0, 24, 0,
- 0, 25, 26, 27, 28, 29, 30, 93, 32, 33,
- 34, 35, 36, 0, 24, 0, 46, 25, 26, 27,
- 28, 29, 30, 45, 32, 33, 34, 35, 36, 0,
- 24, 0, 46, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 0, 0, 0, 46
+static const yytype_int16 yytable[] =
+{
+ 45, 85, 78, 64, 62, 124, 165, 92, 11, 129,
+ 62, 90, 68, 45, 89, 12, 14, 166, 105, 130,
+ 101, 153, 17, 15, 85, 154, 13, 77, 119, 21,
+ 22, 45, 105, 68, 16, 119, 85, 45, 139, 63,
+ 18, 126, 69, 143, 93, 121, 68, 70, 171, 23,
+ 1, 2, 45, 106, 59, 172, 60, 131, 65, 173,
+ 71, 25, 26, 45, 137, 45, 167, 3, 119, 141,
+ 4, 61, 85, 119, 105, 68, 150, 146, 48, 49,
+ 132, 79, 73, 80, 119, 86, 72, 87, 181, 182,
+ 45, 176, 185, 186, 45, 50, 51, 162, 177, 81,
+ 161, 68, 178, 88, 105, 135, 136, 91, 85, 148,
+ 142, 136, 18, 179, 156, 136, 27, 68, 95, 45,
+ 45, 97, 119, 119, 104, 85, 160, 136, 192, 136,
+ 193, 136, 103, 98, 28, 99, 45, 100, 102, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 27, 109, 122, 120, 123, 74, 125,
+ 128, 147, 133, -80, 138, 145, 150, 159, 169, 157,
+ 170, 28, 174, 27, 158, 163, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+ 175, 28, 183, 194, 184, 74, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+ 110, 187, 188, -72, -72, 74, 190, 191, 168, 111,
+ 112, 113, 195, 196, 24, 94, 82, 155, 28, 0,
+ 0, 0, 0, 29, 30, 31, 32, 33, 34, 114,
+ 36, 37, 38, 39, 40, 41, 42, 83, 0, 0,
+ 54, 0, 0, 0, 0, 84, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 28, 0, 0, 0, 0,
+ 29, 30, 31, 32, 33, 34, 52, 36, 37, 38,
+ 39, 40, 41, 42, 83, 53, 0, 54, 0, 0,
+ 0, 0, 108, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 28, 0, 0, 0, 0, 29, 30, 31,
+ 32, 33, 34, 52, 36, 37, 38, 39, 40, 41,
+ 42, 83, 53, 0, 54, 0, 0, 0, 0, 127,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 28,
+ 0, 0, 0, 0, 29, 30, 31, 32, 33, 34,
+ 52, 36, 37, 38, 39, 40, 41, 42, 83, 53,
+ 0, 54, 0, 0, 0, 0, 144, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 28, 0, 0, 0,
+ 0, 29, 30, 31, 32, 33, 34, 52, 36, 37,
+ 38, 39, 40, 41, 42, 83, 53, 0, 54, 0,
+ 0, 0, 0, 180, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 28, 0, 0, 0, 0, 29, 30,
+ 31, 32, 33, 34, 52, 36, 37, 38, 39, 40,
+ 41, 42, 83, 53, 0, 54, 0, 0, 0, 0,
+ 189, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 28, 0, 0, 0, 0, 29, 30, 31, 32, 33,
+ 34, 52, 36, 37, 38, 39, 40, 41, 42, 66,
+ 53, 0, 54, 0, 0, 0, 0, 67, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 28, 0, 0,
+ 0, 0, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 66, 0, 0, 0,
+ 0, 0, 0, 0, 96, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 28, 0, 0, 0, 0, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 66, 0, 0, 0, 0, 0, 0,
+ 0, 107, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 28, 0, 0, 0, 0, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+ 66, 0, 0, 0, 0, 0, 0, 0, 134, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 28, 0,
+ 0, 0, 0, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 66, 0, 0,
+ 0, 0, 0, 0, 0, 149, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 28, 0, 0, 0, 0,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, 42, 66, 0, 0, 0, 0, 0,
+ 0, 0, 164, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 28, 27, 0, 0, 0, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 28, 0, 0, 0, 0, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+ 111, 112, 113, 0, 0, 0, 0, 0, 0, 28,
+ 0, 0, 0, 0, 29, 30, 31, 32, 33, 34,
+ 114, 36, 37, 38, 39, 40, 41, 42, 28, 0,
+ 0, 54, 0, 29, 30, 31, 32, 33, 34, 52,
+ 36, 37, 38, 39, 40, 41, 42, 0, 53, 28,
+ 54, 0, 74, 0, 29, 30, 31, 32, 33, 34,
+ 52, 36, 37, 38, 39, 40, 41, 42, 28, 53,
+ 0, 54, 0, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 28, 0, 0,
+ 54, 0, 29, 30, 31, 32, 33, 34, 140, 36,
+ 37, 38, 39, 40, 41, 42, 0, 0, 0, 54
};
-static const signed char yycheck[] =
-{
- 47, 43, 10, 1, 63, 37, 21, 73, 67, 51,
- 0, 5, 7, 21, 73, 19, 20, 13, 65, 12,
- 7, 1, 1, 16, 56, 1, 6, 42, 75, 37,
- 34, 7, 64, 99, 42, 33, 95, 103, 18, 18,
- 99, 35, 18, 1, 103, 3, 1, 33, 56, 108,
- 1, 18, 7, 1, 20, 3, 64, 6, 1, 6,
- 18, 4, 5, 18, 15, 12, 9, 10, 11, 16,
- 18, 6, 114, 6, 121, 18, 7, 8, 21, 22,
- 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
- 1, 6, 6, 36, 7, 8, 3, 8, 12, 4,
- 5, 3, 16, 4, 5, 4, 5, 18, 4, 5,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, 1, 6, 6, 36, 18, 14, 18, 8,
- 18, 7, 6, 6, 6, 6, 6, 6, 6, 18,
- 5, -1, 21, 22, 23, 24, 25, 26, 27, 28,
- 29, 30, 31, 32, 1, 108, 54, 36, -1, -1,
- -1, 8, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 18, -1, -1, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 30, 31, 32, 1, -1, -1, 36,
- -1, -1, -1, 8, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 18, -1, -1, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 1, -1,
- -1, 36, -1, -1, -1, 8, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 18, -1, -1, 21, 22,
- 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
- 1, -1, -1, -1, -1, -1, -1, 8, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 18, -1, -1,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, 1, -1, -1, -1, -1, -1, -1, 8,
- -1, -1, -1, -1, -1, -1, -1, 1, -1, 18,
- -1, -1, 21, 22, 23, 24, 25, 26, 27, 28,
- 29, 30, 31, 32, 18, -1, -1, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 9,
- 10, 11, -1, -1, -1, -1, -1, -1, 18, -1,
- -1, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, -1, 18, -1, 36, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32, -1,
- 18, -1, 36, 21, 22, 23, 24, 25, 26, 27,
- 28, 29, 30, 31, 32, -1, -1, -1, 36
+static const yytype_int16 yycheck[] =
+{
+ 12, 55, 50, 25, 5, 87, 5, 1, 1, 5,
+ 5, 59, 43, 25, 59, 8, 1, 16, 75, 15,
+ 72, 13, 1, 8, 78, 17, 19, 49, 80, 19,
+ 20, 43, 89, 64, 19, 87, 90, 49, 120, 40,
+ 19, 89, 1, 125, 38, 40, 77, 6, 6, 0,
+ 22, 23, 64, 75, 8, 13, 1, 102, 18, 17,
+ 19, 8, 9, 75, 116, 77, 9, 39, 120, 121,
+ 42, 16, 126, 125, 131, 106, 19, 129, 7, 8,
+ 102, 1, 19, 3, 136, 1, 14, 3, 20, 21,
+ 102, 6, 174, 175, 106, 8, 9, 145, 13, 19,
+ 145, 132, 17, 19, 161, 4, 5, 38, 162, 131,
+ 4, 5, 19, 161, 4, 5, 1, 148, 23, 131,
+ 132, 19, 174, 175, 9, 179, 4, 5, 4, 5,
+ 4, 5, 19, 6, 19, 6, 148, 6, 8, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 1, 6, 6, 3, 6, 43, 3,
+ 19, 9, 8, 19, 19, 8, 19, 6, 6, 19,
+ 6, 19, 3, 1, 19, 15, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 3, 19, 6, 13, 6, 43, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 1, 6, 6, 4, 5, 43, 5, 5, 151, 10,
+ 11, 12, 6, 6, 6, 62, 53, 136, 19, -1,
+ -1, -1, -1, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 1, -1, -1,
+ 41, -1, -1, -1, -1, 9, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 19, -1, -1, -1, -1,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 1, 39, -1, 41, -1, -1,
+ -1, -1, 9, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 19, -1, -1, -1, -1, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 1, 39, -1, 41, -1, -1, -1, -1, 9,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 19,
+ -1, -1, -1, -1, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 1, 39,
+ -1, 41, -1, -1, -1, -1, 9, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 19, -1, -1, -1,
+ -1, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 1, 39, -1, 41, -1,
+ -1, -1, -1, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 19, -1, -1, -1, -1, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 1, 39, -1, 41, -1, -1, -1, -1,
+ 9, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 19, -1, -1, -1, -1, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 1,
+ 39, -1, 41, -1, -1, -1, -1, 9, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 19, -1, -1,
+ -1, -1, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 1, -1, -1, -1,
+ -1, -1, -1, -1, 9, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 19, -1, -1, -1, -1, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 1, -1, -1, -1, -1, -1, -1,
+ -1, 9, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 19, -1, -1, -1, -1, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 1, -1, -1, -1, -1, -1, -1, -1, 9, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 19, -1,
+ -1, -1, -1, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 1, -1, -1,
+ -1, -1, -1, -1, -1, 9, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 19, -1, -1, -1, -1,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 1, -1, -1, -1, -1, -1,
+ -1, -1, 9, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 19, 1, -1, -1, -1, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 19, -1, -1, -1, -1, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 10, 11, 12, -1, -1, -1, -1, -1, -1, 19,
+ -1, -1, -1, -1, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 19, -1,
+ -1, 41, -1, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, -1, 39, 19,
+ 41, -1, 43, -1, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 19, 39,
+ -1, 41, -1, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 19, -1, -1,
+ 41, -1, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, -1, -1, -1, 41
};
// YYSTOS[STATE-NUM] -- The (internal number of the) accessing
// symbol of state STATE-NUM.
-static const unsigned char yystos[] =
-{
- 0, 19, 20, 34, 38, 39, 40, 41, 46, 1,
- 7, 18, 1, 7, 18, 1, 18, 44, 45, 0,
- 40, 7, 8, 1, 18, 21, 22, 23, 24, 25,
- 26, 27, 28, 29, 30, 31, 32, 42, 43, 54,
- 55, 56, 7, 7, 8, 27, 36, 47, 48, 53,
- 54, 7, 1, 15, 5, 35, 42, 1, 8, 43,
- 1, 6, 18, 13, 42, 47, 1, 3, 18, 1,
- 8, 48, 1, 3, 18, 47, 33, 1, 33, 45,
- 20, 8, 6, 6, 6, 53, 8, 8, 6, 1,
- 9, 10, 11, 27, 49, 50, 51, 52, 53, 3,
- 6, 6, 49, 3, 8, 18, 14, 4, 5, 53,
- 18, 49, 4, 49, 7, 12, 16, 51, 4, 6,
- 4, 47, 6, 6, 6, 12, 16, 6, 12, 16,
- 8, 6, 6, 6, 6
+static const yytype_int8 yystos[] =
+{
+ 0, 22, 23, 39, 42, 45, 46, 47, 48, 49,
+ 58, 1, 8, 19, 1, 8, 19, 1, 19, 56,
+ 57, 19, 20, 0, 47, 8, 9, 1, 19, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 54, 55, 66, 67, 68, 7, 8,
+ 8, 9, 30, 39, 41, 59, 60, 65, 66, 8,
+ 1, 16, 5, 40, 54, 18, 1, 9, 55, 1,
+ 6, 19, 14, 19, 43, 50, 51, 54, 59, 1,
+ 3, 19, 56, 1, 9, 60, 1, 3, 19, 50,
+ 59, 38, 1, 38, 57, 23, 9, 19, 6, 6,
+ 6, 65, 8, 19, 9, 51, 54, 9, 9, 6,
+ 1, 10, 11, 12, 30, 61, 62, 63, 64, 65,
+ 3, 40, 6, 6, 61, 3, 59, 9, 19, 5,
+ 15, 50, 54, 8, 9, 4, 5, 65, 19, 61,
+ 30, 65, 4, 61, 9, 8, 65, 9, 54, 9,
+ 19, 52, 53, 13, 17, 63, 4, 19, 19, 6,
+ 4, 50, 59, 15, 9, 5, 16, 9, 53, 6,
+ 6, 6, 13, 17, 3, 3, 6, 13, 17, 59,
+ 9, 20, 21, 6, 6, 61, 61, 6, 6, 9,
+ 5, 5, 4, 4, 13, 6, 6
};
// YYR1[YYN] -- Symbol number of symbol that rule YYN derives.
-static const unsigned char yyr1[] =
-{
- 0, 37, 38, 39, 39, 40, 40, 41, 41, 41,
- 41, 42, 42, 42, 43, 43, 43, 43, 44, 44,
- 44, 45, 45, 45, 46, 46, 46, 46, 46, 47,
- 47, 47, 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 49, 49, 49, 50, 50, 50, 51,
- 51, 51, 52, 52, 53, 53, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54, 55, 56,
- 56
+static const yytype_int8 yyr1[] =
+{
+ 0, 44, 45, 46, 46, 47, 47, 47, 48, 48,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 50,
+ 50, 51, 52, 52, 53, 53, 53, 53, 53, 53,
+ 54, 54, 54, 55, 55, 55, 55, 56, 56, 56,
+ 57, 57, 57, 58, 58, 58, 58, 58, 58, 58,
+ 59, 59, 59, 60, 60, 60, 60, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 61, 61, 61, 62,
+ 62, 62, 63, 63, 63, 64, 64, 65, 65, 66,
+ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+ 66, 66, 67, 67, 68, 68, 68, 68
};
// YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.
-static const unsigned char yyr2[] =
-{
- 0, 2, 1, 1, 2, 1, 1, 5, 4, 5,
- 3, 1, 2, 3, 3, 2, 3, 1, 1, 3,
- 1, 3, 3, 3, 5, 8, 4, 5, 3, 1,
- 2, 3, 6, 7, 7, 7, 7, 6, 5, 6,
- 6, 3, 3, 1, 3, 1, 1, 1, 1, 0,
- 1, 2, 1, 2, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 4, 1,
- 1
+static const yytype_int8 yyr2[] =
+{
+ 0, 2, 1, 1, 2, 1, 1, 1, 2, 2,
+ 5, 6, 5, 7, 8, 7, 4, 5, 3, 1,
+ 2, 5, 1, 2, 2, 4, 4, 1, 3, 3,
+ 1, 2, 3, 3, 2, 3, 1, 1, 3, 1,
+ 3, 3, 3, 5, 8, 6, 9, 4, 5, 3,
+ 1, 2, 3, 6, 9, 7, 10, 7, 7, 7,
+ 6, 5, 6, 6, 3, 3, 1, 3, 1, 1,
+ 1, 1, 0, 1, 2, 1, 2, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 3, 4, 6, 1, 1, 1, 1
};
/* YYDPREC[RULE-NUM] -- Dynamic precedence of rule #RULE-NUM (0 if none). */
-static const unsigned char yydprec[] =
+static const yytype_int8 yydprec[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -530,11 +736,13 @@ static const unsigned char yydprec[] =
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
};
/* YYMERGER[RULE-NUM] -- Index of merging function for rule #RULE-NUM. */
-static const unsigned char yymerger[] =
+static const yytype_int8 yymerger[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -543,7 +751,9 @@ static const unsigned char yymerger[] =
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
};
/* YYIMMEDIATE[RULE-NUM] -- True iff rule #RULE-NUM is not to be deferred, as
@@ -557,14 +767,16 @@ static const yybool yyimmediate[] =
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
};
/* YYCONFLP[YYPACT[STATE-NUM]] -- Pointer into YYCONFL of start of
list of conflicting reductions corresponding to action entry for
state STATE-NUM in yytable. 0 means no conflicts. The list in
yyconfl is terminated by a rule number of 0. */
-static const unsigned char yyconflp[] =
+static const yytype_int8 yyconflp[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -604,12 +816,55 @@ static const unsigned char yyconflp[] =
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* YYCONFL[I] -- lists of conflicting rule numbers, each terminated by
0, pointed into by YYCONFLP. */
-static const short int yyconfl[] =
+static const short yyconfl[] =
{
0
};
@@ -634,7 +889,7 @@ static const short int yyconfl[] =
{ \
(Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end; \
} \
- while (/*CONSTCOND*/ false)
+ while (false)
# endif
# define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)
@@ -669,6 +924,25 @@ typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG;
# define YYFPRINTF fprintf
# endif
+# define YY_FPRINTF \
+ YY_IGNORE_USELESS_CAST_BEGIN YY_FPRINTF_
+
+# define YY_FPRINTF_(Args) \
+ do { \
+ YYFPRINTF Args; \
+ YY_IGNORE_USELESS_CAST_END \
+ } while (0)
+
+# define YY_DPRINTF \
+ YY_IGNORE_USELESS_CAST_BEGIN YY_DPRINTF_
+
+# define YY_DPRINTF_(Args) \
+ do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+ YY_IGNORE_USELESS_CAST_END \
+ } while (0)
+
/* YY_LOCATION_PRINT -- Print the location on the stream.
This macro was not mandated originally: define only if we know
@@ -680,10 +954,10 @@ typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG;
/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
YY_ATTRIBUTE_UNUSED
-static unsigned
+static int
yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
{
- unsigned res = 0;
+ int res = 0;
int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
if (0 <= yylocp->first_line)
{
@@ -714,12 +988,6 @@ yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
#endif
-# define YYDPRINTF(Args) \
- do { \
- if (yydebug) \
- YYFPRINTF Args; \
- } while (0)
-
/*--------------------.
| Print this symbol. |
@@ -738,9 +1006,9 @@ yy_symbol_print (FILE *, int yytype, const yy::parser::semantic_type *yyvaluep,
do { \
if (yydebug) \
{ \
- YYFPRINTF (stderr, "%s ", Title); \
+ YY_FPRINTF ((stderr, "%s ", Title)); \
yy_symbol_print (stderr, Type, Value, Location, yyparser, ps); \
- YYFPRINTF (stderr, "\n"); \
+ YY_FPRINTF ((stderr, "\n")); \
} \
} while (0)
@@ -749,14 +1017,14 @@ yy_symbol_print (FILE *, int yytype, const yy::parser::semantic_type *yyvaluep,
int yydebug;
struct yyGLRStack;
-static void yypstack (struct yyGLRStack* yystackp, size_t yyk)
+static void yypstack (struct yyGLRStack* yystackp, ptrdiff_t yyk)
YY_ATTRIBUTE_UNUSED;
static void yypdumpstack (struct yyGLRStack* yystackp)
YY_ATTRIBUTE_UNUSED;
#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
+# define YY_DPRINTF(Args) do {} while (yyfalse)
# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
#endif /* !YYDEBUG */
@@ -833,12 +1101,12 @@ yystpcpy (char *yydest, const char *yysrc)
backslash-backslash). YYSTR is taken from yytname. If YYRES is
null, do not copy; instead, return the length of what the result
would have been. */
-static size_t
+static ptrdiff_t
yytnamerr (char *yyres, const char *yystr)
{
if (*yystr == '"')
{
- size_t yyn = 0;
+ ptrdiff_t yyn = 0;
char const *yyp = yystr;
for (;;)
@@ -851,7 +1119,10 @@ yytnamerr (char *yyres, const char *yystr)
case '\\':
if (*++yyp != '\\')
goto do_not_strip_quotes;
- /* Fall through. */
+ else
+ goto append;
+
+ append:
default:
if (yyres)
yyres[yyn] = *yyp;
@@ -866,26 +1137,26 @@ yytnamerr (char *yyres, const char *yystr)
do_not_strip_quotes: ;
}
- if (! yyres)
- return strlen (yystr);
-
- return yystpcpy (yyres, yystr) - yyres;
+ if (yyres)
+ return yystpcpy (yyres, yystr) - yyres;
+ else
+ return YY_CAST (ptrdiff_t, strlen (yystr));
}
# endif
#endif /* !YYERROR_VERBOSE */
-/** State numbers, as in LALR(1) machine */
+/** State numbers. */
typedef int yyStateNum;
-/** Rule numbers, as in LALR(1) machine */
+/** Rule numbers. */
typedef int yyRuleNum;
-/** Grammar symbol */
+/** Grammar symbol. */
typedef int yySymbol;
-/** Item references, as in LALR(1) machine */
-typedef short int yyItemNum;
+/** Item references. */
+typedef short yyItemNum;
typedef struct yyGLRState yyGLRState;
typedef struct yyGLRStateSet yyGLRStateSet;
@@ -904,10 +1175,10 @@ struct yyGLRState {
/** Preceding state in this stack */
yyGLRState* yypred;
/** Source position of the last token produced by my symbol */
- size_t yyposn;
+ ptrdiff_t yyposn;
union {
/** First in a chain of alternative reductions producing the
- * non-terminal corresponding to this state, threaded through
+ * nonterminal corresponding to this state, threaded through
* yynext. */
yySemanticOption* yyfirstVal;
/** Semantic value for this state. */
@@ -924,7 +1195,8 @@ struct yyGLRStateSet {
* operation, yylookaheadNeeds[0] is not maintained since it would merely
* duplicate yychar != YYEMPTY. */
yybool* yylookaheadNeeds;
- size_t yysize, yycapacity;
+ ptrdiff_t yysize;
+ ptrdiff_t yycapacity;
};
struct yySemanticOption {
@@ -963,7 +1235,7 @@ struct yyGLRStack {
YYJMP_BUF yyexception_buffer;
yyGLRStackItem* yyitems;
yyGLRStackItem* yynextFree;
- size_t yyspaceLeft;
+ ptrdiff_t yyspaceLeft;
yyGLRState* yysplitPoint;
yyGLRState* yylastDeleted;
yyGLRStateSet yytops;
@@ -973,7 +1245,7 @@ struct yyGLRStack {
static void yyexpandGLRStack (yyGLRStack* yystackp);
#endif
-static _Noreturn void
+_Noreturn static void
yyFail (yyGLRStack* yystackp, YYLTYPE *yylocp, yy::parser& yyparser, tidl::Parser* ps, const char* yymsg)
{
if (yymsg != YY_NULLPTR)
@@ -981,7 +1253,7 @@ yyFail (yyGLRStack* yystackp, YYLTYPE *yylocp, yy::parser& yyparser, tidl::Parse
YYLONGJMP (yystackp->yyexception_buffer, 1);
}
-static _Noreturn void
+_Noreturn static void
yyMemoryExhausted (yyGLRStack* yystackp)
{
YYLONGJMP (yystackp->yyexception_buffer, 2);
@@ -992,10 +1264,7 @@ yyMemoryExhausted (yyGLRStack* yystackp)
static inline const char*
yytokenName (yySymbol yytoken)
{
- if (yytoken == YYEMPTY)
- return "";
-
- return yytname[yytoken];
+ return yytoken == YYEMPTY ? "" : yytname[yytoken];
}
#endif
@@ -1025,6 +1294,49 @@ yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
}
}
+
+/** If yychar is empty, fetch the next token. */
+static inline yySymbol
+yygetToken (int *yycharp, yyGLRStack* yystackp, yy::parser& yyparser, tidl::Parser* ps)
+{
+ yySymbol yytoken;
+ YYUSE (yyparser);
+ YYUSE (ps);
+ if (*yycharp == YYEMPTY)
+ {
+ YY_DPRINTF ((stderr, "Reading a token: "));
+#if YY_EXCEPTIONS
+ try
+ {
+#endif // YY_EXCEPTIONS
+ *yycharp = yylex (&yylval, &yylloc, lex_scanner);
+#if YY_EXCEPTIONS
+ }
+ catch (const yy::parser::syntax_error& yyexc)
+ {
+ YY_DPRINTF ((stderr, "Caught exception: %s\n", yyexc.what()));
+ yylloc = yyexc.location;
+ yyerror (&yylloc, yyparser, ps, yyexc.what ());
+ // Map errors caught in the scanner to the undefined token
+ // (YYUNDEFTOK), so that error handling is started.
+ // However, record this with this special value of yychar.
+ *yycharp = YYFAULTYTOK;
+ }
+#endif // YY_EXCEPTIONS
+ }
+ if (*yycharp <= YYEOF)
+ {
+ *yycharp = yytoken = YYEOF;
+ YY_DPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (*yycharp);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+ return yytoken;
+}
+
/* Do nothing if YYNORMAL or if *YYLOW <= YYLOW1. Otherwise, fill in
* YYVSP[YYLOW1 .. *YYLOW-1] as in yyfillin and set *YYLOW = YYLOW1.
* For convenience, always return YYLOW1. */
@@ -1047,11 +1359,11 @@ yyfill (yyGLRStackItem *yyvsp, int *yylow, int yylow1, yybool yynormal)
* (@$). Returns yyok for normal return, yyaccept for YYACCEPT,
* yyerr for YYERROR, yyabort for YYABORT. */
static YYRESULTTAG
-yyuserAction (yyRuleNum yyn, size_t yyrhslen, yyGLRStackItem* yyvsp,
+yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
yyGLRStack* yystackp,
YYSTYPE* yyvalp, YYLTYPE *yylocp, yy::parser& yyparser, tidl::Parser* ps)
{
- yybool yynormal YY_ATTRIBUTE_UNUSED = (yystackp->yysplitPoint == YY_NULLPTR);
+ yybool yynormal YY_ATTRIBUTE_UNUSED = yystackp->yysplitPoint == YY_NULLPTR;
int yylow;
YYUSE (yyvalp);
YYUSE (yylocp);
@@ -1071,7 +1383,7 @@ yyuserAction (yyRuleNum yyn, size_t yyrhslen, yyGLRStackItem* yyvsp,
# undef yyclearin
# define yyclearin (yychar = YYEMPTY)
# undef YYFILL
-# define YYFILL(N) yyfill (yyvsp, &yylow, N, yynormal)
+# define YYFILL(N) yyfill (yyvsp, &yylow, (N), yynormal)
# undef YYBACKUP
# define YYBACKUP(Token, Value) \
return yyerror (yylocp, yyparser, ps, YY_("syntax error: cannot back up")), \
@@ -1082,709 +1394,1275 @@ yyuserAction (yyRuleNum yyn, size_t yyrhslen, yyGLRStackItem* yyvsp,
*yyvalp = yyval_default;
else
*yyvalp = yyvsp[YYFILL (1-yyrhslen)].yystate.yysemantics.yysval;
+ /* Default location. */
YYLLOC_DEFAULT ((*yylocp), (yyvsp - yyrhslen), yyrhslen);
yystackp->yyerror_range[1].yystate.yyloc = *yylocp;
+#if YY_EXCEPTIONS
+ typedef yy::parser::syntax_error syntax_error;
+ try
+ {
+#endif // YY_EXCEPTIONS
switch (yyn)
{
- case 2:
-#line 96 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->SetDoc((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.doc));
+ case 2:
+#line 116 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->SetDoc((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.doc));
}
-#line 1096 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1414 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 3:
-#line 101 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
+#line 121 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
((*yyvalp).doc) = new tidl::Document();
- if ((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.blk) != NULL)
- ((*yyvalp).doc)->AddBlock((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.blk));
+ document = ((*yyvalp).doc);
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.blk) != NULL)
+ ((*yyvalp).doc)->AddBlock((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.blk));
}
-#line 1106 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1425 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 4:
-#line 106 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).doc) = (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.doc);
-
- if ((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.blk) != NULL) {
- if (((*yyvalp).doc)->ExistBlock((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.blk))) {
- ps->ReportError("syntax error. \"Already Exists\".", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.blk)->GetLine());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.blk);
+#line 127 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).doc) = (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.doc);
+
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.blk) != NULL) {
+ if (((*yyvalp).doc)->ExistBlock((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.blk))) {
+ ps->ReportError("syntax error. \"Already Exists\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.blk)->GetLine());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.blk);
} else {
- ((*yyvalp).doc)->AddBlock((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.blk));
+ ((*yyvalp).doc)->AddBlock((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.blk));
}
}
}
-#line 1123 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1442 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 5:
-#line 120 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).blk) = (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.interf);
+#line 141 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).blk) = (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.interf);
+ currentInterfaceEnums = nullptr;
}
-#line 1131 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1451 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 6:
-#line 123 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).blk) = (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.structure);
+#line 145 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).blk) = (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.structure);
+ currentInterfaceEnums = nullptr;
}
-#line 1139 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1460 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 7:
-#line 128 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).structure) = new tidl::Structure((((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString(), (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.elms), (((yyGLRStackItem const *)yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token)->GetComments(),
- (((yyGLRStackItem const *)yyvsp)[YYFILL (-4)].yystate.yyloc).begin.line);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
+#line 149 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).blk) = (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.blk);
}
-#line 1150 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1468 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 8:
-#line 134 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error. \"No identifier\".", (((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
- ((*yyvalp).structure) = NULL;
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
+#line 154 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ int ver = atoi((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString().c_str());
+
+ if (ver < 1) {
+ ps->ReportError("syntax error in protocol version : " + (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
+ } else {
+ ps->SetVersion(ver);
+ }
+ ((*yyvalp).blk) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
}
-#line 1160 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1486 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 9:
-#line 139 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error. \"Please check it before an open brace.\"",
- (((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
- ((*yyvalp).structure) = NULL;
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
+#line 167 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in protocol version : " + (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
+ ((*yyvalp).blk) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
}
-#line 1171 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1498 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 10:
-#line 145 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error in structure declaration.", (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
- ((*yyvalp).structure) = NULL;
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token);
+#line 176 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).structure) = new tidl::Structure((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.elms), new tidl::Enums(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token)->GetComments(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yyloc).begin.line);
+ if (!((*yyvalp).structure)->FindAndValidateElements()) {
+ ps->ReportError("syntax error. invalid element : " + (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yyloc).begin.line);
+ ((*yyvalp).structure) = NULL;
+ delete ((*yyvalp).structure);
+ }
+
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
}
-#line 1181 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1515 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 11:
-#line 152 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).elms) = new (std::nothrow) tidl::Elements();
- if (((*yyvalp).elms) != nullptr) {
- ((*yyvalp).elms)->Add((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.elm));
+#line 188 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).structure) = new tidl::Structure((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.elms), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.enumerations), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->GetComments(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yyloc).begin.line);
+ if (!((*yyvalp).structure)->FindAndValidateElements()) {
+ ps->ReportError("syntax error. invalid element : " + (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yyloc).begin.line);
+ ((*yyvalp).structure) = NULL;
+ delete ((*yyvalp).structure);
}
+
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
}
-#line 1192 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1532 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 12:
-#line 158 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).elms) = (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.elms);
- if ((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.elm) != nullptr) {
- if (((*yyvalp).elms)->Exist((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.elm))) {
- ps->ReportError("syntax error. \"Already Exists\".", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.elm)->GetLine());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.elm);
- } else {
- ((*yyvalp).elms)->Add((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.elm));
- }
+#line 200 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).structure) = new tidl::Structure((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString(), new tidl::Elements(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.enumerations), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token)->GetComments(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yyloc).begin.line);
+ if (!((*yyvalp).structure)->FindAndValidateElements()) {
+ ps->ReportError("syntax error. invalid element : " + (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yyloc).begin.line);
+ ((*yyvalp).structure) = NULL;
+ delete ((*yyvalp).structure);
}
+
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
}
-#line 1208 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1549 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 13:
-#line 169 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error in elements declarations.", (((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yyloc).begin.line);
- ((*yyvalp).elms) = (((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.elms);
+#line 212 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. Please try to use protocol 2.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yyloc).begin.line);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.elms);
+ } else {
+ std::shared_ptr<tidl::Block> block = nullptr;
+ if (document != nullptr)
+ block = document->FindBlock((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString());
+
+ if (block == nullptr || block->GetType() != tidl::Block::Type::TYPE_STRUCTURE) {
+ ps->ReportError("syntax error. " + (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString() + " does not exist.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yyloc).begin.line);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.elms);
+ } else {
+ ((*yyvalp).structure) = new tidl::Structure((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.elms), new tidl::Enums(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token)->GetComments(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yyloc).begin.line);
+ ((*yyvalp).structure)->SetBase(std::dynamic_pointer_cast<tidl::Structure>(block));
+ if (!((*yyvalp).structure)->FindAndValidateElements()) {
+ ps->ReportError("syntax error. invalid element : " + (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yyloc).begin.line);
+ ((*yyvalp).structure) = NULL;
+ delete ((*yyvalp).structure);
+ }
+ }
+ }
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
}
-#line 1217 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1581 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 14:
-#line 175 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).elm) = new tidl::Element((((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.token)->ToString(), (((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.b_type), (((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.b_type)->GetComments(),
- (((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yyloc).begin.line);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.token);
+#line 239 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. Please try to use protocol 2.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-7)].yystate.yyloc).begin.line);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.enumerations);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.elms);
+ } else {
+ std::shared_ptr<tidl::Block> block = nullptr;
+ if (document != nullptr)
+ block = document->FindBlock((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token)->ToString());
+
+ if (block == nullptr || block->GetType() != tidl::Block::Type::TYPE_STRUCTURE) {
+ ps->ReportError("syntax error. " + (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token)->ToString() + " does not exist.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-7)].yystate.yyloc).begin.line);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.enumerations);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.elms);
+ } else {
+ ((*yyvalp).structure) = new tidl::Structure((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.elms), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.enumerations), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-7)].yystate.yysemantics.yysval.token)->GetComments(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-7)].yystate.yyloc).begin.line);
+ ((*yyvalp).structure)->SetBase(std::dynamic_pointer_cast<tidl::Structure>(block));
+ if (!((*yyvalp).structure)->FindAndValidateElements()) {
+ ps->ReportError("syntax error. invalid element : " + (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-7)].yystate.yyloc).begin.line);
+ ((*yyvalp).structure) = NULL;
+ delete ((*yyvalp).structure);
+ }
+ }
+ }
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-7)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
}
-#line 1227 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1615 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 15:
-#line 180 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error. \"No identifier\".", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
- ((*yyvalp).elm) = NULL;
+#line 268 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. Please try to use protocol 2.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yyloc).begin.line);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.enumerations);
+ } else {
+ std::shared_ptr<tidl::Block> block = nullptr;
+ if (document != nullptr)
+ block = document->FindBlock((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString());
+
+ if (block == nullptr || block->GetType() != tidl::Block::Type::TYPE_STRUCTURE) {
+ ps->ReportError("syntax error. " + (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString() + " does not exist.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yyloc).begin.line);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.enumerations);
+ } else {
+ ((*yyvalp).structure) = new tidl::Structure((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->ToString(), new tidl::Elements(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.enumerations), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token)->GetComments(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yyloc).begin.line);
+ ((*yyvalp).structure)->SetBase(std::dynamic_pointer_cast<tidl::Structure>(block));
+ if (!((*yyvalp).structure)->FindAndValidateElements()) {
+ ps->ReportError("syntax error. invalid element : " + (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yyloc).begin.line);
+ delete ((*yyvalp).structure);
+ ((*yyvalp).structure) = NULL;
+ }
+ }
+ }
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
}
-#line 1236 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1647 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 16:
-#line 184 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error in element declaration.", (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
- ((*yyvalp).elm) = NULL;
+#line 295 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error. \"No identifier\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
+ ((*yyvalp).structure) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
}
-#line 1245 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1657 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 17:
-#line 188 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error in element declaration.", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
- ((*yyvalp).elm) = NULL;
+#line 300 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error. \"Please check it before an open brace.\"",
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
+ ((*yyvalp).structure) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
}
-#line 1254 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1668 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 18:
-#line 194 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).attrs) = new (std::nothrow) tidl::Attributes();
- if (((*yyvalp).attrs) != nullptr) {
- ((*yyvalp).attrs)->Add((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.attr));
- }
+#line 306 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in structure declaration.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
+ ((*yyvalp).structure) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token);
}
-#line 1265 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1678 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 19:
-#line 200 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).attrs) = (((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.attrs);
- if ((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.attr) != nullptr) {
- if (((*yyvalp).attrs)->Exist((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.attr))) {
- ps->ReportError("syntax error. \"Already Exist\".", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.attr)->GetLine());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.attr);
- } else {
- ((*yyvalp).attrs)->Add((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.attr));
+#line 313 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).enumerations) = new (std::nothrow) tidl::Enums();
+ currentInterfaceEnums = ((*yyvalp).enumerations);
+ if (((*yyvalp).enumerations) != nullptr) {
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.enumeration) != nullptr) {
+ ((*yyvalp).enumerations)->Add(std::unique_ptr<tidl::Enum>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.enumeration)));
}
}
}
-#line 1281 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1692 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 20:
-#line 211 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error in attributes", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
- ((*yyvalp).attrs) = new tidl::Attributes();
+#line 322 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).enumerations) = (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.enumerations);
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.enumeration) != nullptr) {
+ if (((*yyvalp).enumerations)->Exist(*(YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.enumeration))) {
+ ps->ReportError("syntax error. \"Already Exists\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.enumeration)->GetLine());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.enumeration);
+ } else {
+ ((*yyvalp).enumerations)->Add(std::unique_ptr<tidl::Enum>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.enumeration)));
+ }
+ }
}
-#line 1290 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1708 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 21:
-#line 217 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).attr) = new tidl::Attribute((((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token)->ToString(), (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString(), (((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yyloc).begin.line);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+#line 335 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. \"enum is supported from protocol version 2\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yyloc).begin.line);
+ ps->ReportError("try to use protocol version 2.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yyloc).begin.line);
+ } else {
+ ((*yyvalp).enumeration) = new tidl::Enum((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.enum_fields), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token)->GetComments(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yyloc).begin.line);
+ }
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
}
-#line 1300 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1723 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 22:
-#line 222 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error in attribute declaration.", (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
- ((*yyvalp).attr) = NULL;
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
- }
-#line 1311 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 347 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).enum_fields) = new (std::nothrow) tidl::Fields();
+ if (((*yyvalp).enum_fields) != nullptr) {
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.enum_field) != nullptr) {
+ ((*yyvalp).enum_fields)->Add(std::unique_ptr<tidl::Field>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.enum_field)));
+ }
+ }
+ }
+#line 1736 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 23:
-#line 228 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error in attribute declaration.", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
- ((*yyvalp).attr) = NULL;
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token);
+#line 355 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).enum_fields) = (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.enum_fields);
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.enum_field) != nullptr) {
+ if (((*yyvalp).enum_fields)->Exist(*(YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.enum_field))) {
+ ps->ReportError("syntax error. \"Already Exists\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.enum_field)->GetLine());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.enum_field);
+ } else {
+ ((*yyvalp).enum_fields)->Add(std::unique_ptr<tidl::Field>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.enum_field)));
+ }
+ }
}
-#line 1321 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1752 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 24:
-#line 235 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).interf) = new tidl::Interface((((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString(), (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.decls), (((yyGLRStackItem const *)yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token)->GetComments(),
- new tidl::Attributes(), (((yyGLRStackItem const *)yyvsp)[YYFILL (-4)].yystate.yyloc).begin.line);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
+#line 368 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).enum_field) = new (std::nothrow) tidl::Field((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.token)->ToString(), "", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.token)->GetComments(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
}
-#line 1332 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1761 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 25:
-#line 241 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).interf) = new tidl::Interface((((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString(), (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.decls), (((yyGLRStackItem const *)yyvsp)[YYFILL (-7)].yystate.yysemantics.yysval.token)->GetComments(), (((yyGLRStackItem const *)yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.attrs),
- (((yyGLRStackItem const *)yyvsp)[YYFILL (-7)].yystate.yyloc).begin.line);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-7)].yystate.yysemantics.yysval.token);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
+#line 372 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).enum_field) = new (std::nothrow) tidl::Field((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.token)->ToString(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->GetComments(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
}
-#line 1345 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1770 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 26:
-#line 249 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error. \"No identifier\".", (((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
- ((*yyvalp).interf) = NULL;
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
+#line 376 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).enum_field) = new (std::nothrow) tidl::Field((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.token)->ToString(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->GetComments(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
}
-#line 1355 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1779 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 27:
-#line 254 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error in interface declaration.", (((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
- ((*yyvalp).interf) = NULL;
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
+#line 380 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).enum_field) = new (std::nothrow) tidl::Field((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString(), "", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
}
-#line 1365 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1788 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 28:
-#line 259 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error in interface declaration.", (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
- ((*yyvalp).interf) = NULL;
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token);
+#line 384 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).enum_field) = new (std::nothrow) tidl::Field((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token)->GetComments(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yyloc).begin.line);
}
-#line 1375 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1797 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 29:
-#line 266 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).decls) = new (std::nothrow) tidl::Declarations();
- if (((*yyvalp).decls) != nullptr) {
- ((*yyvalp).decls)->Add((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.decl));
- }
+#line 388 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).enum_field) = new (std::nothrow) tidl::Field((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token)->GetComments(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yyloc).begin.line);
}
-#line 1386 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1806 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 30:
-#line 272 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).decls) = (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.decls);
- if ((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.decl) != nullptr) {
- if (((*yyvalp).decls)->Exist((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.decl))) {
- ps->ReportError("syntax error. \"Already Exists\".", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.decl)->GetLine());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.decl);
- } else {
- ((*yyvalp).decls)->Add((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.decl));
+#line 394 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).elms) = new (std::nothrow) tidl::Elements();
+ if (((*yyvalp).elms) != nullptr) {
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.elm) != nullptr) {
+ ((*yyvalp).elms)->Add(std::unique_ptr<tidl::Element>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.elm)));
}
}
}
-#line 1402 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1819 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 31:
-#line 283 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error in methods declaration.", (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
- ((*yyvalp).decls) = (((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.decls);
+#line 402 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).elms) = (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.elms);
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.elm) != nullptr) {
+ if (((*yyvalp).elms)->Exist(*(YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.elm))) {
+ ps->ReportError("syntax error. \"Already Exists\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.elm)->GetLine());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.elm);
+ } else {
+ ((*yyvalp).elms)->Add(std::unique_ptr<tidl::Element>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.elm)));
+ }
+ }
}
-#line 1411 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1835 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 32:
-#line 289 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).decl) = new tidl::Declaration((((yyGLRStackItem const *)yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token)->ToString(), (((yyGLRStackItem const *)yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.b_type), (((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.params), (((yyGLRStackItem const *)yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.b_type)->GetComments(),
- (((yyGLRStackItem const *)yyvsp)[YYFILL (-5)].yystate.yyloc).begin.line, tidl::Declaration::MethodType::SYNC);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
+#line 413 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in elements declarations.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yyloc).begin.line);
+ ((*yyvalp).elms) = (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.elms);
}
-#line 1421 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1844 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 33:
-#line 294 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).decl) = new tidl::Declaration((((yyGLRStackItem const *)yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->ToString(),
- new tidl::BaseType("void", (((yyGLRStackItem const *)yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token)->GetComments()), (((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.params),
- (((yyGLRStackItem const *)yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token)->GetComments(), (((yyGLRStackItem const *)yyvsp)[YYFILL (-6)].yystate.yyloc).begin.line, tidl::Declaration::MethodType::ASYNC);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+#line 419 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if (tidl::BaseType::IsFile((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.b_type))) {
+ ps->ReportError("syntax error. \"The file cannot be included in the struct.\"", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
+ ((*yyvalp).elm) = NULL;
+ } else {
+ ((*yyvalp).elm) = new tidl::Element((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.b_type), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.b_type)->GetComments(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yyloc).begin.line);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.token);
+ }
}
-#line 1433 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1859 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 34:
-#line 301 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).decl) = new tidl::Declaration((((yyGLRStackItem const *)yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->ToString(),
- new tidl::BaseType("void", (((yyGLRStackItem const *)yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token)->GetComments()), (((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.params),
- (((yyGLRStackItem const *)yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token)->GetComments(), (((yyGLRStackItem const *)yyvsp)[YYFILL (-6)].yystate.yyloc).begin.line,
- tidl::Declaration::MethodType::DELEGATE);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+#line 429 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error. \"No identifier\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
+ ((*yyvalp).elm) = NULL;
}
-#line 1446 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1868 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 35:
-#line 309 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error in method declaration.", (((yyGLRStackItem const *)yyvsp)[YYFILL (-5)].yystate.yyloc).begin.line);
- ((*yyvalp).decl) = NULL;
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+#line 433 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in element declaration.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
+ ((*yyvalp).elm) = NULL;
}
-#line 1456 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1877 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 36:
-#line 314 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error in method declaration.", (((yyGLRStackItem const *)yyvsp)[YYFILL (-5)].yystate.yyloc).begin.line);
- ((*yyvalp).decl) = NULL;
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+#line 437 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in element declaration.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
+ ((*yyvalp).elm) = NULL;
}
-#line 1466 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1886 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 37:
-#line 319 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error. \"No async\".", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
- ((*yyvalp).decl) = NULL;
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
+#line 443 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).attrs) = new (std::nothrow) tidl::Attributes();
+ if (((*yyvalp).attrs) != nullptr) {
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.attr) != nullptr) {
+ ((*yyvalp).attrs)->Add(std::unique_ptr<tidl::Attribute>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.attr)));
+ }
+ }
}
-#line 1476 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1899 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 38:
-#line 324 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error. \"No identifier\".", (((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
- ((*yyvalp).decl) = NULL;
+#line 451 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).attrs) = (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.attrs);
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.attr) != nullptr) {
+ if (((*yyvalp).attrs)->Exist(*(YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.attr))) {
+ ps->ReportError("syntax error. \"Already Exist\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.attr)->GetLine());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.attr);
+ } else {
+ ((*yyvalp).attrs)->Add(std::unique_ptr<tidl::Attribute>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.attr)));
+ }
+ }
}
-#line 1485 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1915 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 39:
-#line 328 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error. \"No identifier\".", (((yyGLRStackItem const *)yyvsp)[YYFILL (-4)].yystate.yyloc).begin.line);
- ((*yyvalp).decl) = NULL;
+#line 462 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in attributes", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
+ ((*yyvalp).attrs) = new tidl::Attributes();
}
-#line 1494 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1924 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 40:
-#line 332 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error. \"No identifier\".", (((yyGLRStackItem const *)yyvsp)[YYFILL (-4)].yystate.yyloc).begin.line);
- ((*yyvalp).decl) = NULL;
+#line 468 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).attr) = new tidl::Attribute((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yyloc).begin.line);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
}
-#line 1503 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1934 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 41:
-#line 336 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error in method declaration.", (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
- ((*yyvalp).decl) = NULL;
+#line 473 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in attribute declaration.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
+ ((*yyvalp).attr) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
}
-#line 1512 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1945 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 42:
-#line 340 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error in method declaration.", (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
- ((*yyvalp).decl) = NULL;
+#line 479 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in attribute declaration.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
+ ((*yyvalp).attr) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token);
}
-#line 1521 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1955 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 43:
-#line 346 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).params) = new tidl::Parameters();
- if ((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.param) != nullptr) {
- ((*yyvalp).params)->Add((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.param));
- }
+#line 486 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).interf) = new tidl::Interface((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.decls), new tidl::Enums(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token)->GetComments(),
+ new tidl::Attributes(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yyloc).begin.line);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
}
-#line 1532 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1966 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 44:
-#line 352 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).params) = (((yyGLRStackItem const *)yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.params);
- if ((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.param) != nullptr) {
- if (((*yyvalp).params)->Exist((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.param))) {
- ps->ReportError("syntax error. \"Already Exists\".", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.param)->GetLine());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.param);
- } else {
- ((*yyvalp).params)->Add((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.param));
- }
- }
+#line 492 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).interf) = new tidl::Interface((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.decls), new tidl::Enums(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-7)].yystate.yysemantics.yysval.token)->GetComments(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.attrs), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-7)].yystate.yyloc).begin.line);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-7)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
}
-#line 1548 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1979 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 45:
-#line 363 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ps->ReportError("syntax error in parameter list", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
- ((*yyvalp).params) = new tidl::Parameters();
+#line 500 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).interf) = new tidl::Interface((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.decls), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.enumerations), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->GetComments(),
+ new tidl::Attributes(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yyloc).begin.line);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
}
-#line 1557 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 1990 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 46:
-#line 369 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).direction) = new tidl::Token("in", "");
+#line 506 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).interf) = new tidl::Interface((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.decls), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.enumerations), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-8)].yystate.yysemantics.yysval.token)->GetComments(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-7)].yystate.yysemantics.yysval.attrs),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-8)].yystate.yyloc).begin.line);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-8)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
}
-#line 1565 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 2003 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 47:
-#line 372 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).direction) = new tidl::Token("out", "");
+#line 514 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error. \"No identifier\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
+ ((*yyvalp).interf) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
}
-#line 1573 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 2013 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 48:
-#line 375 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).direction) = new tidl::Token("ref", "");
+#line 519 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in interface declaration.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
+ ((*yyvalp).interf) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
}
-#line 1581 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 2023 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 49:
-#line 380 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).param) = nullptr;
+#line 524 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in interface declaration.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
+ ((*yyvalp).interf) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token);
}
-#line 1589 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 2033 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 50:
-#line 383 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).param) = nullptr;
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+#line 531 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).decls) = new (std::nothrow) tidl::Declarations();
+ currentDeclarations = ((*yyvalp).decls);
+ if (((*yyvalp).decls) != nullptr) {
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.decl) != nullptr) {
+ ((*yyvalp).decls)->Add(std::unique_ptr<tidl::Declaration>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.decl)));
+ }
+ }
}
-#line 1598 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 2047 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 51:
-#line 387 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).param) = new tidl::Parameter((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString(), (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.p_type), (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+#line 540 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).decls) = (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.decls);
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.decl) != nullptr) {
+ if (((*yyvalp).decls)->Exist(*(YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.decl))) {
+ ps->ReportError("syntax error. \"Already Exists\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.decl)->GetLine());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.decl);
+ } else {
+ ((*yyvalp).decls)->Add(std::unique_ptr<tidl::Declaration>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.decl)));
+ }
+ }
}
-#line 1607 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 2063 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 52:
-#line 393 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).p_type) = new tidl::ParameterType((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.b_type));
- }
-#line 1615 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 551 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in methods declaration.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
+ ((*yyvalp).decls) = (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.decls);
+ }
+#line 2072 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 53:
-#line 396 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).p_type) = new tidl::ParameterType((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.b_type), (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.direction)->ToString());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.direction);
+#line 557 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if (ps->IsGroupEnabled()) {
+ ps->ReportError("Group does not support 'sync' method type", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yyloc).begin.line);
+ ((*yyvalp).decl) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
+ } else {
+ ((*yyvalp).decl) = new tidl::Declaration((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token)->ToString(),
+ std::unique_ptr<tidl::BaseType>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.b_type)),
+ std::unique_ptr<tidl::Parameters>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.params)), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.b_type)->GetComments(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yyloc).begin.line, tidl::Declaration::MethodType::SYNC);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
}
-#line 1624 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+ }
+#line 2090 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 54:
-#line 402 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).b_type) = (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.b_type);
+#line 570 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. \"method attributes is supported from protocol version 2\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-8)].yystate.yyloc).begin.line);
+ ps->ReportError("try to use protocol version 2.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-8)].yystate.yyloc).begin.line);
+ }
+
+ if (ps->IsGroupEnabled()) {
+ ps->ReportError("Group does not support 'sync' method type", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-8)].yystate.yyloc).begin.line);
+ ((*yyvalp).decl) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
+ } else {
+ ((*yyvalp).decl) = new tidl::Declaration((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token)->ToString(),
+ std::unique_ptr<tidl::BaseType>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.b_type)),
+ std::unique_ptr<tidl::Parameters>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.params)), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-8)].yystate.yysemantics.yysval.token)->GetComments(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-8)].yystate.yyloc).begin.line, tidl::Declaration::MethodType::SYNC,
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-7)].yystate.yysemantics.yysval.attrs));
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
}
-#line 1632 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+ }
+#line 2114 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 55:
-#line 405 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- if (!ps->IsBetaEnabled()) {
- ps->ReportError("syntax error. \"No identifier\".", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
- ((*yyvalp).b_type) = NULL;
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
- } else {
- ((*yyvalp).b_type) = new tidl::BaseType("file", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
- }
- }
-#line 1647 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 589 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).decl) = new tidl::Declaration((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->ToString(),
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("void", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token)->GetComments())),
+ std::unique_ptr<tidl::Parameters>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.params)), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token)->GetComments(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yyloc).begin.line, tidl::Declaration::MethodType::ASYNC);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+ }
+#line 2127 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 56:
-#line 417 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).b_type) = (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.b_type);
+#line 597 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. \"method attributes is supported from protocol version 2\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-9)].yystate.yyloc).begin.line);
+ ps->ReportError("try to use protocol version 2.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-9)].yystate.yyloc).begin.line);
}
-#line 1655 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+
+ ((*yyvalp).decl) = new tidl::Declaration((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->ToString(),
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("void", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-9)].yystate.yysemantics.yysval.token)->GetComments())),
+ std::unique_ptr<tidl::Parameters>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.params)), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-9)].yystate.yysemantics.yysval.token)->GetComments(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-9)].yystate.yyloc).begin.line, tidl::Declaration::MethodType::ASYNC, (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-8)].yystate.yysemantics.yysval.attrs));
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+ }
+#line 2145 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 57:
-#line 420 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).b_type) = new tidl::BaseType("void", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+#line 610 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if (ps->IsGroupEnabled()) {
+ ps->ReportError("Group does not support 'delegate' method type", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yyloc).begin.line);
+ ((*yyvalp).decl) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+ } else {
+ ((*yyvalp).decl) = new tidl::Declaration((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->ToString(),
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("void", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token)->GetComments())),
+ std::unique_ptr<tidl::Parameters>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.params)), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token)->GetComments(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yyloc).begin.line, tidl::Declaration::MethodType::DELEGATE);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-6)].yystate.yysemantics.yysval.token);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
}
-#line 1664 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+ }
+#line 2165 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 58:
-#line 424 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).b_type) = new tidl::BaseType("char", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
- }
-#line 1673 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 625 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in method declaration.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yyloc).begin.line);
+ ((*yyvalp).decl) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+ }
+#line 2175 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 59:
-#line 428 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).b_type) = new tidl::BaseType("short", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
- }
-#line 1682 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 630 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in method declaration.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yyloc).begin.line);
+ ((*yyvalp).decl) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+ }
+#line 2185 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 60:
-#line 432 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).b_type) = new tidl::BaseType("int", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
- }
-#line 1691 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 635 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error. \"No async\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
+ ((*yyvalp).decl) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yysemantics.yysval.token);
+ }
+#line 2195 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 61:
-#line 436 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).b_type) = new tidl::BaseType("long", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
- }
-#line 1700 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 640 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error. \"No identifier\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
+ ((*yyvalp).decl) = NULL;
+ }
+#line 2204 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 62:
-#line 440 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).b_type) = new tidl::BaseType("float", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
- }
-#line 1709 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 644 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error. \"No identifier\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yyloc).begin.line);
+ ((*yyvalp).decl) = NULL;
+ }
+#line 2213 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 63:
-#line 444 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).b_type) = new tidl::BaseType("double", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
- }
-#line 1718 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 648 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error. \"No identifier\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-4)].yystate.yyloc).begin.line);
+ ((*yyvalp).decl) = NULL;
+ }
+#line 2222 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 64:
-#line 448 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).b_type) = new tidl::BaseType("bundle", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
- }
-#line 1727 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 652 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in method declaration.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
+ ((*yyvalp).decl) = NULL;
+ }
+#line 2231 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 65:
-#line 452 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).b_type) = new tidl::BaseType("string", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
- }
-#line 1736 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 656 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in method declaration.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
+ ((*yyvalp).decl) = NULL;
+ }
+#line 2240 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 66:
-#line 456 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).b_type) = new tidl::BaseType("bool", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+#line 662 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).params) = new tidl::Parameters();
+ if (((*yyvalp).params) != nullptr) {
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.param) != nullptr) {
+ ((*yyvalp).params)->Add(std::unique_ptr<tidl::Parameter>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.param)));
+ }
}
-#line 1745 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+ }
+#line 2253 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 67:
-#line 460 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).b_type) = new tidl::BaseType((((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString(), (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments(), true);
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+#line 670 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).params) = (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.params);
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.param) != nullptr) {
+ if (((*yyvalp).params)->Exist(*(YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.param))) {
+ ps->ReportError("syntax error. \"Already Exists\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.param)->GetLine());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.param);
+ } else {
+ ((*yyvalp).params)->Add(std::unique_ptr<tidl::Parameter>((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.param)));
+ }
}
-#line 1754 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+ }
+#line 2269 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 68:
-#line 466 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).b_type) = new tidl::BaseType((((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString(), (((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->GetComments());
- ((*yyvalp).b_type)->SetMetaType((((yyGLRStackItem const *)yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.b_type));
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
- }
-#line 1764 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 681 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ps->ReportError("syntax error in parameter list", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
+ ((*yyvalp).params) = new tidl::Parameters();
+ }
+#line 2278 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 69:
-#line 473 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).token) = new tidl::Token("list", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
- }
-#line 1773 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 687 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).direction) = new tidl::Token("in", "");
+ }
+#line 2286 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
case 70:
-#line 477 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:816
- {
- ((*yyvalp).token) = new tidl::Token("array", (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
- delete (((yyGLRStackItem const *)yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+#line 690 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).direction) = new tidl::Token("out", "");
+ }
+#line 2294 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 71:
+#line 693 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).direction) = new tidl::Token("ref", "");
+ }
+#line 2302 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 72:
+#line 698 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).param) = nullptr;
+ }
+#line 2310 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 73:
+#line 701 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).param) = nullptr;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+#line 2319 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 74:
+#line 705 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).param) = new tidl::Parameter((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.p_type), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yyloc).begin.line);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+#line 2328 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 75:
+#line 711 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).p_type) = new tidl::ParameterType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.b_type));
+ }
+#line 2336 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 76:
+#line 714 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).p_type) = new tidl::ParameterType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.b_type), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.direction)->ToString());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.direction);
+ }
+#line 2345 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 77:
+#line 720 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).b_type) = (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.b_type);
+ }
+#line 2353 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 78:
+#line 723 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if (ps->IsGroupEnabled()) {
+ ps->ReportError("Group does not support 'file' type", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
+ ((*yyvalp).b_type) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ } else if (!ps->IsBetaEnabled() && ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. \"No identifier\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
+ ps->ReportError("try to use beta version (-b option).", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
+ ((*yyvalp).b_type) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ } else {
+ ((*yyvalp).b_type) = new tidl::BaseType("file", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+ }
+#line 2373 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 79:
+#line 740 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).b_type) = (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.b_type);
+ }
+#line 2381 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 80:
+#line 743 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).b_type) = new tidl::BaseType("void", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+#line 2390 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 81:
+#line 747 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).b_type) = new tidl::BaseType("char", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+#line 2399 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 82:
+#line 751 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).b_type) = new tidl::BaseType("short", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
}
-#line 1782 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
+#line 2408 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
break;
+ case 83:
+#line 755 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).b_type) = new tidl::BaseType("int", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+#line 2417 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 84:
+#line 759 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).b_type) = new tidl::BaseType("long", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+#line 2426 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 85:
+#line 763 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).b_type) = new tidl::BaseType("float", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+#line 2435 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 86:
+#line 767 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).b_type) = new tidl::BaseType("double", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+#line 2444 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 87:
+#line 771 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if (ps->IsCionEnabled()) {
+ ps->ReportError("Cion does not support 'bundle' type", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
+ ((*yyvalp).b_type) = NULL;
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ } else {
+ ((*yyvalp).b_type) = new tidl::BaseType("bundle", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+ }
+#line 2459 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 88:
+#line 781 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).b_type) = new tidl::BaseType("string", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+#line 2468 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 89:
+#line 785 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).b_type) = new tidl::BaseType("bool", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+#line 2477 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 90:
+#line 789 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if (ps->GetVersion() < 2) {
+ ((*yyvalp).b_type) = new tidl::BaseType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments(), true);
+ } else {
+ std::string name = (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString();
+ bool found = false;
+ tidl::BaseType::UserType type;
+ if (currentInterfaceEnums) {
+ for (auto& e : *currentInterfaceEnums) {
+ if (e->GetID() == name) {
+ type = tidl::BaseType::UserType::ENUM;
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found && document) {
+ for (auto& b : document->GetBlocks()) {
+ if (b->GetType() == tidl::Block::TYPE_STRUCTURE) {
+ if (b->GetID() == name) {
+ type = tidl::BaseType::UserType::STRUCTURE;
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!found && currentDeclarations) {
+ for (auto& d : *currentDeclarations) {
+ if (d->GetMethodType() == tidl::Declaration::MethodType::DELEGATE) {
+ if (d->GetID() == name) {
+ type = tidl::BaseType::UserType::DELEGATE;
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+
+ ((*yyvalp).b_type) = new tidl::BaseType(name, (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments(), type);
+ if (!found) {
+ ps->ReportError("Unknown type : " + (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
+ }
+ }
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+#line 2530 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 91:
+#line 837 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ bool found = false;
+ if (document) {
+ for (auto& b : document->GetBlocks()) {
+ if (b->GetType() == tidl::Block::TYPE_STRUCTURE
+ && b->GetID() == (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token)->ToString()) {
+ for (auto& e : b->GetEnums()) {
+ if (e->GetID() == (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString()) {
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (found) {
+ ((*yyvalp).b_type) = new tidl::BaseType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token)->ToString() + "." + (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString() , (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token)->GetComments(), tidl::BaseType::UserType::ENUM);
+ } else {
+ ps->ReportError("Unknown type : " + (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token)->ToString() + "." + (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->ToString(),
+ (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yyloc).begin.line);
+ ((*yyvalp).b_type) = NULL;
+ }
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-2)].yystate.yysemantics.yysval.token);
+ }
+#line 2560 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 92:
+#line 864 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString() == "map") {
+ ps->ReportError("syntax error. The value must be existed.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
+ } else {
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.b_type)->GetMetaType() != nullptr && tidl::BaseType::IsFile((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.b_type))) {
+ ps->ReportError("syntax error. The file should be included in only one container.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
+ }
+
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString() == "set") {
+ if (!tidl::BaseType::IsKeyType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.b_type))) {
+ ps->ReportError("syntax error. The key type should be 'char', 'int', 'short', 'long', 'string', 'bool', 'float' and 'double.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
+ }
+ }
+
+ ((*yyvalp).b_type) = new tidl::BaseType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->GetComments());
+ ((*yyvalp).b_type)->SetMetaType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.b_type));
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
+ }
+ }
+#line 2585 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 93:
+#line 884 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->ToString() != "map") {
+ ps->ReportError("syntax error. The container type must be \"map\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yyloc).begin.line);
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+ } else {
+ if (!tidl::BaseType::IsKeyType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.b_type))) {
+ ps->ReportError("syntax error. The key type should be 'char', 'int', 'short', 'long', 'string', 'bool', 'float' and 'double.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yyloc).begin.line);
+ }
+
+ ((*yyvalp).b_type) = new tidl::BaseType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->GetComments());
+ ((*yyvalp).b_type)->SetKeyType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.b_type));
+ ((*yyvalp).b_type)->SetValueType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.b_type));
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
+ }
+ }
+#line 2605 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 94:
+#line 901 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).token) = new tidl::Token("list", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+#line 2614 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 95:
+#line 905 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ ((*yyvalp).token) = new tidl::Token("array", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+#line 2623 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 96:
+#line 909 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. \"No identifier\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
+ ps->ReportError("try to use protocol version 2.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
+ }
+ ((*yyvalp).token) = new tidl::Token("map", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+#line 2636 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+ case 97:
+#line 917 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+ {
+ if (ps->GetVersion() < 2) {
+ ps->ReportError("syntax error. \"No identifier\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
+ ps->ReportError("try to use protocol version 2.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
+ }
+ ((*yyvalp).token) = new tidl::Token("set", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
+ delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
+ }
+#line 2649 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+ break;
+
+
+#line 2653 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
-#line 1786 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:816
default: break;
}
+#if YY_EXCEPTIONS
+ }
+ catch (const syntax_error& yyexc)
+ {
+ YY_DPRINTF ((stderr, "Caught exception: %s\n", yyexc.what()));
+ *yylocp = yyexc.location;
+ yyerror (yylocp, yyparser, ps, yyexc.what ());
+ YYERROR;
+ }
+#endif // YY_EXCEPTIONS
return yyok;
# undef yyerrok
@@ -1851,9 +2729,9 @@ yydestroyGLRState (char const *yymsg, yyGLRState *yys, yy::parser& yyparser, tid
if (yydebug)
{
if (yys->yysemantics.yyfirstVal)
- YYFPRINTF (stderr, "%s unresolved", yymsg);
+ YY_FPRINTF ((stderr, "%s unresolved", yymsg));
else
- YYFPRINTF (stderr, "%s incomplete", yymsg);
+ YY_FPRINTF ((stderr, "%s incomplete", yymsg));
YY_SYMBOL_PRINT ("", yystos[yys->yylrState], YY_NULLPTR, &yys->yyloc);
}
#endif
@@ -1878,8 +2756,8 @@ yylhsNonterm (yyRuleNum yyrule)
return yyr1[yyrule];
}
-#define yypact_value_is_default(Yystate) \
- (!!((Yystate) == (-67)))
+#define yypact_value_is_default(Yyn) \
+ ((Yyn) == YYPACT_NINF)
/** True iff LR state YYSTATE has only a default reduction (regardless
* of token). */
@@ -1896,10 +2774,10 @@ yydefaultAction (yyStateNum yystate)
return yydefact[yystate];
}
-#define yytable_value_is_error(Yytable_value) \
+#define yytable_value_is_error(Yyn) \
0
-/** Set *YYACTION to the action to take in YYSTATE on seeing YYTOKEN.
+/** The action to take in YYSTATE on seeing YYTOKEN.
* Result R means
* R < 0: Reduce on rule -R.
* R = 0: Error.
@@ -1907,26 +2785,25 @@ yydefaultAction (yyStateNum yystate)
* Set *YYCONFLICTS to a pointer into yyconfl to a 0-terminated list
* of conflicting reductions.
*/
-static inline void
-yygetLRActions (yyStateNum yystate, int yytoken,
- int* yyaction, const short int** yyconflicts)
+static inline int
+yygetLRActions (yyStateNum yystate, yySymbol yytoken, const short** yyconflicts)
{
int yyindex = yypact[yystate] + yytoken;
- if (yypact_value_is_default (yypact[yystate])
+ if (yyisDefaultedState (yystate)
|| yyindex < 0 || YYLAST < yyindex || yycheck[yyindex] != yytoken)
{
- *yyaction = -yydefact[yystate];
*yyconflicts = yyconfl;
+ return -yydefact[yystate];
}
else if (! yytable_value_is_error (yytable[yyindex]))
{
- *yyaction = yytable[yyindex];
*yyconflicts = yyconfl + yyconflp[yyindex];
+ return yytable[yyindex];
}
else
{
- *yyaction = 0;
*yyconflicts = yyconfl + yyconflp[yyindex];
+ return 0;
}
}
@@ -1978,12 +2855,12 @@ yynewGLRStackItem (yyGLRStack* yystackp, yybool yyisState)
* alternative actions for YYSTATE. Assumes that YYRHS comes from
* stack #YYK of *YYSTACKP. */
static void
-yyaddDeferredAction (yyGLRStack* yystackp, size_t yyk, yyGLRState* yystate,
+yyaddDeferredAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyGLRState* yystate,
yyGLRState* yyrhs, yyRuleNum yyrule)
{
yySemanticOption* yynewOption =
&yynewGLRStackItem (yystackp, yyfalse)->yyoption;
- YYASSERT (!yynewOption->yyisState);
+ YY_ASSERT (!yynewOption->yyisState);
yynewOption->yystate = yyrhs;
yynewOption->yyrule = yyrule;
if (yystackp->yytops.yylookaheadNeeds[yyk])
@@ -2008,17 +2885,25 @@ yyinitStateSet (yyGLRStateSet* yyset)
{
yyset->yysize = 1;
yyset->yycapacity = 16;
- yyset->yystates = (yyGLRState**) YYMALLOC (16 * sizeof yyset->yystates[0]);
+ yyset->yystates
+ = YY_CAST (yyGLRState**,
+ YYMALLOC (YY_CAST (size_t, yyset->yycapacity)
+ * sizeof yyset->yystates[0]));
if (! yyset->yystates)
return yyfalse;
yyset->yystates[0] = YY_NULLPTR;
- yyset->yylookaheadNeeds =
- (yybool*) YYMALLOC (16 * sizeof yyset->yylookaheadNeeds[0]);
+ yyset->yylookaheadNeeds
+ = YY_CAST (yybool*,
+ YYMALLOC (YY_CAST (size_t, yyset->yycapacity)
+ * sizeof yyset->yylookaheadNeeds[0]));
if (! yyset->yylookaheadNeeds)
{
YYFREE (yyset->yystates);
return yyfalse;
}
+ memset (yyset->yylookaheadNeeds,
+ 0,
+ YY_CAST (size_t, yyset->yycapacity) * sizeof yyset->yylookaheadNeeds[0]);
return yytrue;
}
@@ -2031,13 +2916,15 @@ static void yyfreeStateSet (yyGLRStateSet* yyset)
/** Initialize *YYSTACKP to a single empty stack, with total maximum
* capacity for all stacks of YYSIZE. */
static yybool
-yyinitGLRStack (yyGLRStack* yystackp, size_t yysize)
+yyinitGLRStack (yyGLRStack* yystackp, ptrdiff_t yysize)
{
yystackp->yyerrState = 0;
yynerrs = 0;
yystackp->yyspaceLeft = yysize;
- yystackp->yyitems =
- (yyGLRStackItem*) YYMALLOC (yysize * sizeof yystackp->yynextFree[0]);
+ yystackp->yyitems
+ = YY_CAST (yyGLRStackItem*,
+ YYMALLOC (YY_CAST (size_t, yysize)
+ * sizeof yystackp->yynextFree[0]));
if (!yystackp->yyitems)
return yyfalse;
yystackp->yynextFree = yystackp->yyitems;
@@ -2048,8 +2935,9 @@ yyinitGLRStack (yyGLRStack* yystackp, size_t yysize)
#if YYSTACKEXPANDABLE
-# define YYRELOC(YYFROMITEMS,YYTOITEMS,YYX,YYTYPE) \
- &((YYTOITEMS) - ((YYFROMITEMS) - (yyGLRStackItem*) (YYX)))->YYTYPE
+# define YYRELOC(YYFROMITEMS, YYTOITEMS, YYX, YYTYPE) \
+ &((YYTOITEMS) \
+ - ((YYFROMITEMS) - YY_REINTERPRET_CAST (yyGLRStackItem*, (YYX))))->YYTYPE
/** If *YYSTACKP is expandable, extend it. WARNING: Pointers into the
stack from outside should be considered invalid after this call.
@@ -2061,15 +2949,18 @@ yyexpandGLRStack (yyGLRStack* yystackp)
{
yyGLRStackItem* yynewItems;
yyGLRStackItem* yyp0, *yyp1;
- size_t yynewSize;
- size_t yyn;
- size_t yysize = yystackp->yynextFree - yystackp->yyitems;
+ ptrdiff_t yynewSize;
+ ptrdiff_t yyn;
+ ptrdiff_t yysize = yystackp->yynextFree - yystackp->yyitems;
if (YYMAXDEPTH - YYHEADROOM < yysize)
yyMemoryExhausted (yystackp);
yynewSize = 2*yysize;
if (YYMAXDEPTH < yynewSize)
yynewSize = YYMAXDEPTH;
- yynewItems = (yyGLRStackItem*) YYMALLOC (yynewSize * sizeof yynewItems[0]);
+ yynewItems
+ = YY_CAST (yyGLRStackItem*,
+ YYMALLOC (YY_CAST (size_t, yynewSize)
+ * sizeof yynewItems[0]));
if (! yynewItems)
yyMemoryExhausted (yystackp);
for (yyp0 = yystackp->yyitems, yyp1 = yynewItems, yyn = yysize;
@@ -2077,7 +2968,7 @@ yyexpandGLRStack (yyGLRStack* yystackp)
yyn -= 1, yyp0 += 1, yyp1 += 1)
{
*yyp1 = *yyp0;
- if (*(yybool *) yyp0)
+ if (*YY_REINTERPRET_CAST (yybool *, yyp0))
{
yyGLRState* yys0 = &yyp0->yystate;
yyGLRState* yys1 = &yyp1->yystate;
@@ -2133,7 +3024,7 @@ yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys)
/** Invalidate stack #YYK in *YYSTACKP. */
static inline void
-yymarkStackDeleted (yyGLRStack* yystackp, size_t yyk)
+yymarkStackDeleted (yyGLRStack* yystackp, ptrdiff_t yyk)
{
if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
yystackp->yylastDeleted = yystackp->yytops.yystates[yyk];
@@ -2150,23 +3041,21 @@ yyundeleteLastStack (yyGLRStack* yystackp)
return;
yystackp->yytops.yystates[0] = yystackp->yylastDeleted;
yystackp->yytops.yysize = 1;
- YYDPRINTF ((stderr, "Restoring last deleted stack as stack #0.\n"));
+ YY_DPRINTF ((stderr, "Restoring last deleted stack as stack #0.\n"));
yystackp->yylastDeleted = YY_NULLPTR;
}
static inline void
yyremoveDeletes (yyGLRStack* yystackp)
{
- size_t yyi, yyj;
+ ptrdiff_t yyi, yyj;
yyi = yyj = 0;
while (yyj < yystackp->yytops.yysize)
{
if (yystackp->yytops.yystates[yyi] == YY_NULLPTR)
{
if (yyi == yyj)
- {
- YYDPRINTF ((stderr, "Removing dead stacks.\n"));
- }
+ YY_DPRINTF ((stderr, "Removing dead stacks.\n"));
yystackp->yytops.yysize -= 1;
}
else
@@ -2180,10 +3069,8 @@ yyremoveDeletes (yyGLRStack* yystackp)
yystackp->yytops.yylookaheadNeeds[yyj] =
yystackp->yytops.yylookaheadNeeds[yyi];
if (yyj != yyi)
- {
- YYDPRINTF ((stderr, "Rename stack %lu -> %lu.\n",
- (unsigned long int) yyi, (unsigned long int) yyj));
- }
+ YY_DPRINTF ((stderr, "Rename stack %ld -> %ld.\n",
+ YY_CAST (long, yyi), YY_CAST (long, yyj)));
yyj += 1;
}
yyi += 1;
@@ -2194,8 +3081,8 @@ yyremoveDeletes (yyGLRStack* yystackp)
* state YYLRSTATE, at input position YYPOSN, with (resolved) semantic
* value *YYVALP and source location *YYLOCP. */
static inline void
-yyglrShift (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState,
- size_t yyposn,
+yyglrShift (yyGLRStack* yystackp, ptrdiff_t yyk, yyStateNum yylrState,
+ ptrdiff_t yyposn,
YYSTYPE* yyvalp, YYLTYPE* yylocp)
{
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
@@ -2215,11 +3102,11 @@ yyglrShift (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState,
* state YYLRSTATE, at input position YYPOSN, with the (unresolved)
* semantic value of YYRHS under the action for YYRULE. */
static inline void
-yyglrShiftDefer (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState,
- size_t yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
+yyglrShiftDefer (yyGLRStack* yystackp, ptrdiff_t yyk, yyStateNum yylrState,
+ ptrdiff_t yyposn, yyGLRState* yyrhs, yyRuleNum yyrule)
{
yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
- YYASSERT (yynewState->yyisState);
+ YY_ASSERT (yynewState->yyisState);
yynewState->yylrState = yylrState;
yynewState->yyposn = yyposn;
@@ -2236,38 +3123,37 @@ yyglrShiftDefer (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState,
# define YY_REDUCE_PRINT(Args)
#else
# define YY_REDUCE_PRINT(Args) \
-do { \
- if (yydebug) \
- yy_reduce_print Args; \
-} while (0)
+ do { \
+ if (yydebug) \
+ yy_reduce_print Args; \
+ } while (0)
/*----------------------------------------------------------------------.
| Report that stack #YYK of *YYSTACKP is going to be reduced by YYRULE. |
`----------------------------------------------------------------------*/
static inline void
-yy_reduce_print (int yynormal, yyGLRStackItem* yyvsp, size_t yyk,
+yy_reduce_print (yybool yynormal, yyGLRStackItem* yyvsp, ptrdiff_t yyk,
yyRuleNum yyrule, yy::parser& yyparser, tidl::Parser* ps)
{
int yynrhs = yyrhsLength (yyrule);
int yylow = 1;
int yyi;
- YYFPRINTF (stderr, "Reducing stack %lu by rule %d (line %lu):\n",
- (unsigned long int) yyk, yyrule - 1,
- (unsigned long int) yyrline[yyrule]);
+ YY_FPRINTF ((stderr, "Reducing stack %ld by rule %d (line %d):\n",
+ YY_CAST (long, yyk), yyrule - 1, yyrline[yyrule]));
if (! yynormal)
yyfillin (yyvsp, 1, -yynrhs);
/* The symbols being reduced. */
for (yyi = 0; yyi < yynrhs; yyi++)
{
- YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ YY_FPRINTF ((stderr, " $%d = ", yyi + 1));
yy_symbol_print (stderr,
yystos[yyvsp[yyi - yynrhs + 1].yystate.yylrState],
- &yyvsp[yyi - yynrhs + 1].yystate.yysemantics.yysval
- , &(((yyGLRStackItem const *)yyvsp)[YYFILL ((yyi + 1) - (yynrhs))].yystate.yyloc) , yyparser, ps);
+ &yyvsp[yyi - yynrhs + 1].yystate.yysemantics.yysval,
+ &(YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL ((yyi + 1) - (yynrhs))].yystate.yyloc) , yyparser, ps);
if (!yyvsp[yyi - yynrhs + 1].yystate.yyresolved)
- YYFPRINTF (stderr, " (unresolved)");
- YYFPRINTF (stderr, "\n");
+ YY_FPRINTF ((stderr, " (unresolved)"));
+ YY_FPRINTF ((stderr, "\n"));
}
}
#endif
@@ -2279,7 +3165,7 @@ yy_reduce_print (int yynormal, yyGLRStackItem* yyvsp, size_t yyk,
* and *YYLOCP to the computed location (if any). Return value is as
* for userAction. */
static inline YYRESULTTAG
-yydoAction (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
+yydoAction (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
YYSTYPE* yyvalp, YYLTYPE *yylocp, yy::parser& yyparser, tidl::Parser* ps)
{
int yynrhs = yyrhsLength (yyrule);
@@ -2287,33 +3173,33 @@ yydoAction (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
if (yystackp->yysplitPoint == YY_NULLPTR)
{
/* Standard special case: single stack. */
- yyGLRStackItem* yyrhs = (yyGLRStackItem*) yystackp->yytops.yystates[yyk];
- YYASSERT (yyk == 0);
+ yyGLRStackItem* yyrhs
+ = YY_REINTERPRET_CAST (yyGLRStackItem*, yystackp->yytops.yystates[yyk]);
+ YY_ASSERT (yyk == 0);
yystackp->yynextFree -= yynrhs;
yystackp->yyspaceLeft += yynrhs;
yystackp->yytops.yystates[0] = & yystackp->yynextFree[-1].yystate;
- YY_REDUCE_PRINT ((1, yyrhs, yyk, yyrule, yyparser, ps));
+ YY_REDUCE_PRINT ((yytrue, yyrhs, yyk, yyrule, yyparser, ps));
return yyuserAction (yyrule, yynrhs, yyrhs, yystackp,
yyvalp, yylocp, yyparser, ps);
}
else
{
- int yyi;
- yyGLRState* yys;
yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
- yys = yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred
+ yyGLRState* yys = yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred
= yystackp->yytops.yystates[yyk];
+ int yyi;
if (yynrhs == 0)
/* Set default location. */
yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].yystate.yyloc = yys->yyloc;
for (yyi = 0; yyi < yynrhs; yyi += 1)
{
yys = yys->yypred;
- YYASSERT (yys);
+ YY_ASSERT (yys);
}
yyupdateSplit (yystackp, yys);
yystackp->yytops.yystates[yyk] = yys;
- YY_REDUCE_PRINT ((0, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1, yyk, yyrule, yyparser, ps));
+ YY_REDUCE_PRINT ((yyfalse, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1, yyk, yyrule, yyparser, ps));
return yyuserAction (yyrule, yynrhs, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
yystackp, yyvalp, yylocp, yyparser, ps);
}
@@ -2331,10 +3217,10 @@ yydoAction (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
* added to the options for the existing state's semantic value.
*/
static inline YYRESULTTAG
-yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
+yyglrReduce (yyGLRStack* yystackp, ptrdiff_t yyk, yyRuleNum yyrule,
yybool yyforceEval, yy::parser& yyparser, tidl::Parser* ps)
{
- size_t yyposn = yystackp->yytops.yystates[yyk]->yyposn;
+ ptrdiff_t yyposn = yystackp->yytops.yystates[yyk]->yyposn;
if (yyforceEval || yystackp->yysplitPoint == YY_NULLPTR)
{
@@ -2343,10 +3229,9 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
YYRESULTTAG yyflag = yydoAction (yystackp, yyk, yyrule, &yysval, &yyloc, yyparser, ps);
if (yyflag == yyerr && yystackp->yysplitPoint != YY_NULLPTR)
- {
- YYDPRINTF ((stderr, "Parse on stack %lu rejected by rule #%d.\n",
- (unsigned long int) yyk, yyrule - 1));
- }
+ YY_DPRINTF ((stderr,
+ "Parse on stack %ld rejected by rule %d (line %d).\n",
+ YY_CAST (long, yyk), yyrule - 1, yyrline[yyrule - 1]));
if (yyflag != yyok)
return yyflag;
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyrule], &yysval, &yyloc);
@@ -2357,7 +3242,7 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
}
else
{
- size_t yyi;
+ ptrdiff_t yyi;
int yyn;
yyGLRState* yys, *yys0 = yystackp->yytops.yystates[yyk];
yyStateNum yynewLRState;
@@ -2366,14 +3251,15 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
0 < yyn; yyn -= 1)
{
yys = yys->yypred;
- YYASSERT (yys);
+ YY_ASSERT (yys);
}
yyupdateSplit (yystackp, yys);
yynewLRState = yyLRgotoState (yys->yylrState, yylhsNonterm (yyrule));
- YYDPRINTF ((stderr,
- "Reduced stack %lu by rule #%d; action deferred. "
- "Now in state %d.\n",
- (unsigned long int) yyk, yyrule - 1, yynewLRState));
+ YY_DPRINTF ((stderr,
+ "Reduced stack %ld by rule %d (line %d); action deferred. "
+ "Now in state %d.\n",
+ YY_CAST (long, yyk), yyrule - 1, yyrline[yyrule - 1],
+ yynewLRState));
for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
if (yyi != yyk && yystackp->yytops.yystates[yyi] != YY_NULLPTR)
{
@@ -2385,9 +3271,8 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
{
yyaddDeferredAction (yystackp, yyk, yyp, yys0, yyrule);
yymarkStackDeleted (yystackp, yyk);
- YYDPRINTF ((stderr, "Merging stack %lu into stack %lu.\n",
- (unsigned long int) yyk,
- (unsigned long int) yyi));
+ YY_DPRINTF ((stderr, "Merging stack %ld into stack %ld.\n",
+ YY_CAST (long, yyk), YY_CAST (long, yyi)));
return yyok;
}
yyp = yyp->yypred;
@@ -2399,48 +3284,50 @@ yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
return yyok;
}
-static size_t
-yysplitStack (yyGLRStack* yystackp, size_t yyk)
+static ptrdiff_t
+yysplitStack (yyGLRStack* yystackp, ptrdiff_t yyk)
{
if (yystackp->yysplitPoint == YY_NULLPTR)
{
- YYASSERT (yyk == 0);
+ YY_ASSERT (yyk == 0);
yystackp->yysplitPoint = yystackp->yytops.yystates[yyk];
}
- if (yystackp->yytops.yysize >= yystackp->yytops.yycapacity)
+ if (yystackp->yytops.yycapacity <= yystackp->yytops.yysize)
{
- yyGLRState** yynewStates;
- yybool* yynewLookaheadNeeds;
-
- yynewStates = YY_NULLPTR;
-
- if (yystackp->yytops.yycapacity
- > (YYSIZEMAX / (2 * sizeof yynewStates[0])))
+ ptrdiff_t state_size = sizeof yystackp->yytops.yystates[0];
+ ptrdiff_t half_max_capacity = YYSIZEMAX / 2 / state_size;
+ if (half_max_capacity < yystackp->yytops.yycapacity)
yyMemoryExhausted (yystackp);
yystackp->yytops.yycapacity *= 2;
- yynewStates =
- (yyGLRState**) YYREALLOC (yystackp->yytops.yystates,
- (yystackp->yytops.yycapacity
- * sizeof yynewStates[0]));
- if (yynewStates == YY_NULLPTR)
- yyMemoryExhausted (yystackp);
- yystackp->yytops.yystates = yynewStates;
+ {
+ yyGLRState** yynewStates
+ = YY_CAST (yyGLRState**,
+ YYREALLOC (yystackp->yytops.yystates,
+ (YY_CAST (size_t, yystackp->yytops.yycapacity)
+ * sizeof yynewStates[0])));
+ if (yynewStates == YY_NULLPTR)
+ yyMemoryExhausted (yystackp);
+ yystackp->yytops.yystates = yynewStates;
+ }
- yynewLookaheadNeeds =
- (yybool*) YYREALLOC (yystackp->yytops.yylookaheadNeeds,
- (yystackp->yytops.yycapacity
- * sizeof yynewLookaheadNeeds[0]));
- if (yynewLookaheadNeeds == YY_NULLPTR)
- yyMemoryExhausted (yystackp);
- yystackp->yytops.yylookaheadNeeds = yynewLookaheadNeeds;
+ {
+ yybool* yynewLookaheadNeeds
+ = YY_CAST (yybool*,
+ YYREALLOC (yystackp->yytops.yylookaheadNeeds,
+ (YY_CAST (size_t, yystackp->yytops.yycapacity)
+ * sizeof yynewLookaheadNeeds[0])));
+ if (yynewLookaheadNeeds == YY_NULLPTR)
+ yyMemoryExhausted (yystackp);
+ yystackp->yytops.yylookaheadNeeds = yynewLookaheadNeeds;
+ }
}
yystackp->yytops.yystates[yystackp->yytops.yysize]
= yystackp->yytops.yystates[yyk];
yystackp->yytops.yylookaheadNeeds[yystackp->yytops.yysize]
= yystackp->yytops.yylookaheadNeeds[yyk];
yystackp->yytops.yysize += 1;
- return yystackp->yytops.yysize-1;
+ return yystackp->yytops.yysize - 1;
}
/** True iff YYY0 and YYY1 represent identical options at the top level.
@@ -2474,7 +3361,7 @@ yymergeOptionSets (yySemanticOption* yyy0, yySemanticOption* yyy1)
int yyn;
for (yys0 = yyy0->yystate, yys1 = yyy1->yystate,
yyn = yyrhsLength (yyy0->yyrule);
- yyn > 0;
+ 0 < yyn;
yys0 = yys0->yypred, yys1 = yys1->yypred, yyn -= 1)
{
if (yys0 == yys1)
@@ -2556,7 +3443,7 @@ yyresolveStates (yyGLRState* yys, int yyn,
{
if (0 < yyn)
{
- YYASSERT (yys->yypred);
+ YY_ASSERT (yys->yypred);
YYCHK (yyresolveStates (yys->yypred, yyn-1, yystackp, yyparser, ps));
if (! yys->yyresolved)
YYCHK (yyresolveValue (yys, yystackp, yyparser, ps));
@@ -2627,26 +3514,26 @@ yyreportTree (yySemanticOption* yyx, int yyindent)
yystates[0] = yys;
if (yyx->yystate->yyposn < yys->yyposn + 1)
- YYFPRINTF (stderr, "%*s%s -> <Rule %d, empty>\n",
- yyindent, "", yytokenName (yylhsNonterm (yyx->yyrule)),
- yyx->yyrule - 1);
+ YY_FPRINTF ((stderr, "%*s%s -> <Rule %d, empty>\n",
+ yyindent, "", yytokenName (yylhsNonterm (yyx->yyrule)),
+ yyx->yyrule - 1));
else
- YYFPRINTF (stderr, "%*s%s -> <Rule %d, tokens %lu .. %lu>\n",
- yyindent, "", yytokenName (yylhsNonterm (yyx->yyrule)),
- yyx->yyrule - 1, (unsigned long int) (yys->yyposn + 1),
- (unsigned long int) yyx->yystate->yyposn);
+ YY_FPRINTF ((stderr, "%*s%s -> <Rule %d, tokens %ld .. %ld>\n",
+ yyindent, "", yytokenName (yylhsNonterm (yyx->yyrule)),
+ yyx->yyrule - 1, YY_CAST (long, yys->yyposn + 1),
+ YY_CAST (long, yyx->yystate->yyposn)));
for (yyi = 1; yyi <= yynrhs; yyi += 1)
{
if (yystates[yyi]->yyresolved)
{
if (yystates[yyi-1]->yyposn+1 > yystates[yyi]->yyposn)
- YYFPRINTF (stderr, "%*s%s <empty>\n", yyindent+2, "",
- yytokenName (yystos[yystates[yyi]->yylrState]));
+ YY_FPRINTF ((stderr, "%*s%s <empty>\n", yyindent+2, "",
+ yytokenName (yystos[yystates[yyi]->yylrState])));
else
- YYFPRINTF (stderr, "%*s%s <tokens %lu .. %lu>\n", yyindent+2, "",
- yytokenName (yystos[yystates[yyi]->yylrState]),
- (unsigned long int) (yystates[yyi-1]->yyposn + 1),
- (unsigned long int) yystates[yyi]->yyposn);
+ YY_FPRINTF ((stderr, "%*s%s <tokens %ld .. %ld>\n", yyindent+2, "",
+ yytokenName (yystos[yystates[yyi]->yylrState]),
+ YY_CAST (long, yystates[yyi-1]->yyposn + 1),
+ YY_CAST (long, yystates[yyi]->yyposn)));
}
else
yyreportTree (yystates[yyi]->yysemantics.yyfirstVal, yyindent+2);
@@ -2662,12 +3549,12 @@ yyreportAmbiguity (yySemanticOption* yyx0,
YYUSE (yyx1);
#if YYDEBUG
- YYFPRINTF (stderr, "Ambiguity detected.\n");
- YYFPRINTF (stderr, "Option 1,\n");
+ YY_FPRINTF ((stderr, "Ambiguity detected.\n"));
+ YY_FPRINTF ((stderr, "Option 1,\n"));
yyreportTree (yyx0, 2);
- YYFPRINTF (stderr, "\nOption 2,\n");
+ YY_FPRINTF ((stderr, "\nOption 2,\n"));
yyreportTree (yyx1, 2);
- YYFPRINTF (stderr, "\n");
+ YY_FPRINTF ((stderr, "\n"));
#endif
yyerror (yylocp, yyparser, ps, YY_("syntax is ambiguous"));
@@ -2678,7 +3565,7 @@ yyreportAmbiguity (yySemanticOption* yyx0,
* ending at YYS1. Has no effect on previously resolved states.
* The first semantic option of a state is always chosen. */
static void
-yyresolveLocations (yyGLRState* yys1, int yyn1,
+yyresolveLocations (yyGLRState *yys1, int yyn1,
yyGLRStack *yystackp, yy::parser& yyparser, tidl::Parser* ps)
{
if (0 < yyn1)
@@ -2689,9 +3576,9 @@ yyresolveLocations (yyGLRState* yys1, int yyn1,
yyGLRStackItem yyrhsloc[1 + YYMAXRHS];
int yynrhs;
yySemanticOption *yyoption = yys1->yysemantics.yyfirstVal;
- YYASSERT (yyoption != YY_NULLPTR);
+ YY_ASSERT (yyoption);
yynrhs = yyrhsLength (yyoption->yyrule);
- if (yynrhs > 0)
+ if (0 < yynrhs)
{
yyGLRState *yys;
int yyn;
@@ -2714,18 +3601,7 @@ yyresolveLocations (yyGLRState* yys1, int yyn1,
yyGLRState *yyprevious = yyoption->yystate;
yyrhsloc[0].yystate.yyloc = yyprevious->yyloc;
}
- {
- int yychar_current = yychar;
- YYSTYPE yylval_current = yylval;
- YYLTYPE yylloc_current = yylloc;
- yychar = yyoption->yyrawchar;
- yylval = yyoption->yyval;
- yylloc = yyoption->yyloc;
- YYLLOC_DEFAULT ((yys1->yyloc), yyrhsloc, yynrhs);
- yychar = yychar_current;
- yylval = yylval_current;
- yylloc = yylloc_current;
- }
+ YYLLOC_DEFAULT ((yys1->yyloc), yyrhsloc, yynrhs);
}
}
}
@@ -2775,7 +3651,7 @@ yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp, yy::parser& yyparser, tid
yymerge = yyfalse;
break;
default:
- /* This cannot happen so it is not worth a YYASSERT (yyfalse),
+ /* This cannot happen so it is not worth a YY_ASSERT (yyfalse),
but some compilers complain if the default case is
omitted. */
break;
@@ -2853,7 +3729,7 @@ yycompressStack (yyGLRStack* yystackp)
yyp->yypred = yyr;
yystackp->yyspaceLeft += yystackp->yynextFree - yystackp->yyitems;
- yystackp->yynextFree = ((yyGLRStackItem*) yystackp->yysplitPoint) + 1;
+ yystackp->yynextFree = YY_REINTERPRET_CAST (yyGLRStackItem*, yystackp->yysplitPoint) + 1;
yystackp->yyspaceLeft -= yystackp->yynextFree - yystackp->yyitems;
yystackp->yysplitPoint = YY_NULLPTR;
yystackp->yylastDeleted = YY_NULLPTR;
@@ -2870,16 +3746,16 @@ yycompressStack (yyGLRStack* yystackp)
}
static YYRESULTTAG
-yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
- size_t yyposn, YYLTYPE *yylocp, yy::parser& yyparser, tidl::Parser* ps)
+yyprocessOneStack (yyGLRStack* yystackp, ptrdiff_t yyk,
+ ptrdiff_t yyposn, YYLTYPE *yylocp, yy::parser& yyparser, tidl::Parser* ps)
{
while (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
{
yyStateNum yystate = yystackp->yytops.yystates[yyk]->yylrState;
- YYDPRINTF ((stderr, "Stack %lu Entering state %d\n",
- (unsigned long int) yyk, yystate));
+ YY_DPRINTF ((stderr, "Stack %ld Entering state %d\n",
+ YY_CAST (long, yyk), yystate));
- YYASSERT (yystate != YYFINAL);
+ YY_ASSERT (yystate != YYFINAL);
if (yyisDefaultedState (yystate))
{
@@ -2887,18 +3763,17 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
yyRuleNum yyrule = yydefaultAction (yystate);
if (yyrule == 0)
{
- YYDPRINTF ((stderr, "Stack %lu dies.\n",
- (unsigned long int) yyk));
+ YY_DPRINTF ((stderr, "Stack %ld dies.\n", YY_CAST (long, yyk)));
yymarkStackDeleted (yystackp, yyk);
return yyok;
}
yyflag = yyglrReduce (yystackp, yyk, yyrule, yyimmediate[yyrule], yyparser, ps);
if (yyflag == yyerr)
{
- YYDPRINTF ((stderr,
- "Stack %lu dies "
- "(predicate failure or explicit user error).\n",
- (unsigned long int) yyk));
+ YY_DPRINTF ((stderr,
+ "Stack %ld dies "
+ "(predicate failure or explicit user error).\n",
+ YY_CAST (long, yyk)));
yymarkStackDeleted (yystackp, yyk);
return yyok;
}
@@ -2907,37 +3782,17 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
}
else
{
- yySymbol yytoken;
- int yyaction;
- const short int* yyconflicts;
-
+ yySymbol yytoken = yygetToken (&yychar, yystackp, yyparser, ps);
+ const short* yyconflicts;
+ const int yyaction = yygetLRActions (yystate, yytoken, &yyconflicts);
yystackp->yytops.yylookaheadNeeds[yyk] = yytrue;
- if (yychar == YYEMPTY)
- {
- YYDPRINTF ((stderr, "Reading a token: "));
- yychar = yylex (&yylval, &yylloc, lex_scanner);
- }
-
- if (yychar <= YYEOF)
- {
- yychar = yytoken = YYEOF;
- YYDPRINTF ((stderr, "Now at end of input.\n"));
- }
- else
- {
- yytoken = YYTRANSLATE (yychar);
- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
- }
-
- yygetLRActions (yystate, yytoken, &yyaction, &yyconflicts);
while (*yyconflicts != 0)
{
YYRESULTTAG yyflag;
- size_t yynewStack = yysplitStack (yystackp, yyk);
- YYDPRINTF ((stderr, "Splitting off stack %lu from %lu.\n",
- (unsigned long int) yynewStack,
- (unsigned long int) yyk));
+ ptrdiff_t yynewStack = yysplitStack (yystackp, yyk);
+ YY_DPRINTF ((stderr, "Splitting off stack %ld from %ld.\n",
+ YY_CAST (long, yynewStack), YY_CAST (long, yyk)));
yyflag = yyglrReduce (yystackp, yynewStack,
*yyconflicts,
yyimmediate[*yyconflicts], yyparser, ps);
@@ -2946,8 +3801,7 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
yyposn, yylocp, yyparser, ps));
else if (yyflag == yyerr)
{
- YYDPRINTF ((stderr, "Stack %lu dies.\n",
- (unsigned long int) yynewStack));
+ YY_DPRINTF ((stderr, "Stack %ld dies.\n", YY_CAST (long, yynewStack)));
yymarkStackDeleted (yystackp, yynewStack);
}
else
@@ -2959,8 +3813,7 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
break;
else if (yyisErrorAction (yyaction))
{
- YYDPRINTF ((stderr, "Stack %lu dies.\n",
- (unsigned long int) yyk));
+ YY_DPRINTF ((stderr, "Stack %ld dies.\n", YY_CAST (long, yyk)));
yymarkStackDeleted (yystackp, yyk);
break;
}
@@ -2970,10 +3823,10 @@ yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
yyimmediate[-yyaction], yyparser, ps);
if (yyflag == yyerr)
{
- YYDPRINTF ((stderr,
- "Stack %lu dies "
- "(predicate failure or explicit user error).\n",
- (unsigned long int) yyk));
+ YY_DPRINTF ((stderr,
+ "Stack %ld dies "
+ "(predicate failure or explicit user error).\n",
+ YY_CAST (long, yyk)));
yymarkStackDeleted (yystackp, yyk);
break;
}
@@ -2995,18 +3848,18 @@ yyreportSyntaxError (yyGLRStack* yystackp, yy::parser& yyparser, tidl::Parser* p
#else
{
yySymbol yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
- size_t yysize0 = yytnamerr (YY_NULLPTR, yytokenName (yytoken));
- size_t yysize = yysize0;
yybool yysize_overflow = yyfalse;
char* yymsg = YY_NULLPTR;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
const char *yyformat = YY_NULLPTR;
- /* Arguments of yyformat. */
+ /* Arguments of yyformat: reported tokens (one for the "unexpected",
+ one per "expected"). */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- /* Number of reported tokens (one for the "unexpected", one per
- "expected"). */
+ /* Actual size of YYARG. */
int yycount = 0;
+ /* Cumulated lengths of YYARG. */
+ ptrdiff_t yysize = 0;
/* There are many possibilities here to consider:
- If this state is a consistent state with a default action, then
@@ -3034,6 +3887,8 @@ yyreportSyntaxError (yyGLRStack* yystackp, yy::parser& yyparser, tidl::Parser* p
if (yytoken != YYEMPTY)
{
int yyn = yypact[yystackp->yytops.yystates[0]->yylrState];
+ ptrdiff_t yysize0 = yytnamerr (YY_NULLPTR, yytokenName (yytoken));
+ yysize = yysize0;
yyarg[yycount++] = yytokenName (yytoken);
if (!yypact_value_is_default (yyn))
{
@@ -3057,9 +3912,11 @@ yyreportSyntaxError (yyGLRStack* yystackp, yy::parser& yyparser, tidl::Parser* p
}
yyarg[yycount++] = yytokenName (yyx);
{
- size_t yysz = yysize + yytnamerr (YY_NULLPTR, yytokenName (yyx));
- yysize_overflow |= yysz < yysize;
- yysize = yysz;
+ ptrdiff_t yysz = yytnamerr (YY_NULLPTR, yytokenName (yyx));
+ if (YYSIZEMAX - yysize < yysz)
+ yysize_overflow = yytrue;
+ else
+ yysize += yysz;
}
}
}
@@ -3071,6 +3928,7 @@ yyreportSyntaxError (yyGLRStack* yystackp, yy::parser& yyparser, tidl::Parser* p
case N: \
yyformat = S; \
break
+ default: /* Avoid compiler warnings. */
YYCASE_(0, YY_("syntax error"));
YYCASE_(1, YY_("syntax error, unexpected %s"));
YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
@@ -3081,13 +3939,17 @@ yyreportSyntaxError (yyGLRStack* yystackp, yy::parser& yyparser, tidl::Parser* p
}
{
- size_t yysz = yysize + strlen (yyformat);
- yysize_overflow |= yysz < yysize;
- yysize = yysz;
+ /* Don't count the "%s"s in the final size, but reserve room for
+ the terminator. */
+ ptrdiff_t yysz = YY_CAST (ptrdiff_t, strlen (yyformat)) - 2 * yycount + 1;
+ if (YYSIZEMAX - yysize < yysz)
+ yysize_overflow = yytrue;
+ else
+ yysize += yysz;
}
if (!yysize_overflow)
- yymsg = (char *) YYMALLOC (yysize);
+ yymsg = YY_CAST (char *, YYMALLOC (YY_CAST (size_t, yysize)));
if (yymsg)
{
@@ -3102,8 +3964,8 @@ yyreportSyntaxError (yyGLRStack* yystackp, yy::parser& yyparser, tidl::Parser* p
}
else
{
- yyp++;
- yyformat++;
+ ++yyp;
+ ++yyformat;
}
}
yyerror (&yylloc, yyparser, ps, yymsg);
@@ -3125,15 +3987,13 @@ yyreportSyntaxError (yyGLRStack* yystackp, yy::parser& yyparser, tidl::Parser* p
static void
yyrecoverSyntaxError (yyGLRStack* yystackp, yy::parser& yyparser, tidl::Parser* ps)
{
- size_t yyk;
- int yyj;
-
if (yystackp->yyerrState == 3)
/* We just shifted the error token and (perhaps) took some
reductions. Skip tokens until we can proceed. */
while (yytrue)
{
yySymbol yytoken;
+ int yyj;
if (yychar == YYEOF)
yyFail (yystackp, &yylloc, yyparser, ps, YY_NULLPTR);
if (yychar != YYEMPTY)
@@ -3148,19 +4008,9 @@ yyrecoverSyntaxError (yyGLRStack* yystackp, yy::parser& yyparser, tidl::Parser*
yytoken = YYTRANSLATE (yychar);
yydestruct ("Error: discarding",
yytoken, &yylval, &yylloc, yyparser, ps);
+ yychar = YYEMPTY;
}
- YYDPRINTF ((stderr, "Reading a token: "));
- yychar = yylex (&yylval, &yylloc, lex_scanner);
- if (yychar <= YYEOF)
- {
- yychar = yytoken = YYEOF;
- YYDPRINTF ((stderr, "Now at end of input.\n"));
- }
- else
- {
- yytoken = YYTRANSLATE (yychar);
- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
- }
+ yytoken = yygetToken (&yychar, yystackp, yyparser, ps);
yyj = yypact[yystackp->yytops.yystates[0]->yylrState];
if (yypact_value_is_default (yyj))
return;
@@ -3175,22 +4025,25 @@ yyrecoverSyntaxError (yyGLRStack* yystackp, yy::parser& yyparser, tidl::Parser*
}
/* Reduce to one stack. */
- for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1)
- if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
- break;
- if (yyk >= yystackp->yytops.yysize)
- yyFail (yystackp, &yylloc, yyparser, ps, YY_NULLPTR);
- for (yyk += 1; yyk < yystackp->yytops.yysize; yyk += 1)
- yymarkStackDeleted (yystackp, yyk);
- yyremoveDeletes (yystackp);
- yycompressStack (yystackp);
+ {
+ ptrdiff_t yyk;
+ for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1)
+ if (yystackp->yytops.yystates[yyk] != YY_NULLPTR)
+ break;
+ if (yyk >= yystackp->yytops.yysize)
+ yyFail (yystackp, &yylloc, yyparser, ps, YY_NULLPTR);
+ for (yyk += 1; yyk < yystackp->yytops.yysize; yyk += 1)
+ yymarkStackDeleted (yystackp, yyk);
+ yyremoveDeletes (yystackp);
+ yycompressStack (yystackp);
+ }
/* Now pop stack until we find a state that shifts the error token. */
yystackp->yyerrState = 3;
while (yystackp->yytops.yystates[0] != YY_NULLPTR)
{
yyGLRState *yys = yystackp->yytops.yystates[0];
- yyj = yypact[yys->yylrState];
+ int yyj = yypact[yys->yylrState];
if (! yypact_value_is_default (yyj))
{
yyj += YYTERROR;
@@ -3198,13 +4051,14 @@ yyrecoverSyntaxError (yyGLRStack* yystackp, yy::parser& yyparser, tidl::Parser*
&& yyisShiftAction (yytable[yyj]))
{
/* Shift the error token. */
+ int yyaction = yytable[yyj];
/* First adjust its location.*/
YYLTYPE yyerrloc;
yystackp->yyerror_range[2].yystate.yyloc = yylloc;
YYLLOC_DEFAULT (yyerrloc, (yystackp->yyerror_range), 2);
- YY_SYMBOL_PRINT ("Shifting", yystos[yytable[yyj]],
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyaction],
&yylval, &yyerrloc);
- yyglrShift (yystackp, 0, yytable[yyj],
+ yyglrShift (yystackp, 0, yyaction,
yys->yyposn, &yylval, &yyerrloc);
yys = yystackp->yytops.yystates[0];
break;
@@ -3247,17 +4101,18 @@ yyparse (yy::parser& yyparser, tidl::Parser* ps)
int yyresult;
yyGLRStack yystack;
yyGLRStack* const yystackp = &yystack;
- size_t yyposn;
+ ptrdiff_t yyposn;
- YYDPRINTF ((stderr, "Starting parse\n"));
+ YY_DPRINTF ((stderr, "Starting parse\n"));
yychar = YYEMPTY;
yylval = yyval_default;
yylloc = yyloc_default;
- /* User initialization code. */
- yylloc.initialize ();
-#line 3261 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:2270
+ // User initialization code.
+yylloc.initialize ();
+#line 4115 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+
if (! yyinitGLRStack (yystackp, YYINITDEPTH))
goto yyexhaustedlab;
@@ -3279,20 +4134,16 @@ yyparse (yy::parser& yyparser, tidl::Parser* ps)
/* Standard mode */
while (yytrue)
{
- yyRuleNum yyrule;
- int yyaction;
- const short int* yyconflicts;
-
yyStateNum yystate = yystack.yytops.yystates[0]->yylrState;
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ YY_DPRINTF ((stderr, "Entering state %d\n", yystate));
if (yystate == YYFINAL)
goto yyacceptlab;
if (yyisDefaultedState (yystate))
{
- yyrule = yydefaultAction (yystate);
+ yyRuleNum yyrule = yydefaultAction (yystate);
if (yyrule == 0)
{
- yystack.yyerror_range[1].yystate.yyloc = yylloc;
+ yystack.yyerror_range[1].yystate.yyloc = yylloc;
yyreportSyntaxError (&yystack, yyparser, ps);
goto yyuser_error;
}
@@ -3300,25 +4151,9 @@ yyparse (yy::parser& yyparser, tidl::Parser* ps)
}
else
{
- yySymbol yytoken;
- if (yychar == YYEMPTY)
- {
- YYDPRINTF ((stderr, "Reading a token: "));
- yychar = yylex (&yylval, &yylloc, lex_scanner);
- }
-
- if (yychar <= YYEOF)
- {
- yychar = yytoken = YYEOF;
- YYDPRINTF ((stderr, "Now at end of input.\n"));
- }
- else
- {
- yytoken = YYTRANSLATE (yychar);
- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
- }
-
- yygetLRActions (yystate, yytoken, &yyaction, &yyconflicts);
+ yySymbol yytoken = yygetToken (&yychar, yystackp, yyparser, ps);
+ const short* yyconflicts;
+ int yyaction = yygetLRActions (yystate, yytoken, &yyconflicts);
if (*yyconflicts != 0)
break;
if (yyisShiftAction (yyaction))
@@ -3332,8 +4167,11 @@ yyparse (yy::parser& yyparser, tidl::Parser* ps)
}
else if (yyisErrorAction (yyaction))
{
- yystack.yyerror_range[1].yystate.yyloc = yylloc;
- yyreportSyntaxError (&yystack, yyparser, ps);
+ yystack.yyerror_range[1].yystate.yyloc = yylloc;
+ /* Don't issue an error message again for exceptions
+ thrown from the scanner. */
+ if (yychar != YYFAULTYTOK)
+ yyreportSyntaxError (&yystack, yyparser, ps);
goto yyuser_error;
}
else
@@ -3344,7 +4182,7 @@ yyparse (yy::parser& yyparser, tidl::Parser* ps)
while (yytrue)
{
yySymbol yytoken_to_shift;
- size_t yys;
+ ptrdiff_t yys;
for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
yystackp->yytops.yylookaheadNeeds[yys] = yychar != YYEMPTY;
@@ -3377,8 +4215,8 @@ yyparse (yy::parser& yyparser, tidl::Parser* ps)
if (yystack.yytops.yysize == 0)
yyFail (&yystack, &yylloc, yyparser, ps, YY_("syntax error"));
YYCHK1 (yyresolveStack (&yystack, yyparser, ps));
- YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
- yystack.yyerror_range[1].yystate.yyloc = yylloc;
+ YY_DPRINTF ((stderr, "Returning to deterministic operation.\n"));
+ yystack.yyerror_range[1].yystate.yyloc = yylloc;
yyreportSyntaxError (&yystack, yyparser, ps);
goto yyuser_error;
}
@@ -3393,25 +4231,24 @@ yyparse (yy::parser& yyparser, tidl::Parser* ps)
yyposn += 1;
for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
{
- int yyaction;
- const short int* yyconflicts;
yyStateNum yystate = yystack.yytops.yystates[yys]->yylrState;
- yygetLRActions (yystate, yytoken_to_shift, &yyaction,
+ const short* yyconflicts;
+ int yyaction = yygetLRActions (yystate, yytoken_to_shift,
&yyconflicts);
/* Note that yyconflicts were handled by yyprocessOneStack. */
- YYDPRINTF ((stderr, "On stack %lu, ", (unsigned long int) yys));
+ YY_DPRINTF ((stderr, "On stack %ld, ", YY_CAST (long, yys)));
YY_SYMBOL_PRINT ("shifting", yytoken_to_shift, &yylval, &yylloc);
yyglrShift (&yystack, yys, yyaction, yyposn,
&yylval, &yylloc);
- YYDPRINTF ((stderr, "Stack %lu now in state #%d\n",
- (unsigned long int) yys,
- yystack.yytops.yystates[yys]->yylrState));
+ YY_DPRINTF ((stderr, "Stack %ld now in state #%d\n",
+ YY_CAST (long, yys),
+ yystack.yytops.yystates[yys]->yylrState));
}
if (yystack.yytops.yysize == 1)
{
YYCHK1 (yyresolveStack (&yystack, yyparser, ps));
- YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
+ YY_DPRINTF ((stderr, "Returning to deterministic operation.\n"));
yycompressStack (&yystack);
break;
}
@@ -3427,7 +4264,7 @@ yyparse (yy::parser& yyparser, tidl::Parser* ps)
goto yyreturn;
yybuglab:
- YYASSERT (yyfalse);
+ YY_ASSERT (yyfalse);
goto yyabortlab;
yyabortlab:
@@ -3452,16 +4289,16 @@ yyparse (yy::parser& yyparser, tidl::Parser* ps)
yyGLRState** yystates = yystack.yytops.yystates;
if (yystates)
{
- size_t yysize = yystack.yytops.yysize;
- size_t yyk;
+ ptrdiff_t yysize = yystack.yytops.yysize;
+ ptrdiff_t yyk;
for (yyk = 0; yyk < yysize; yyk += 1)
if (yystates[yyk])
{
while (yystates[yyk])
{
yyGLRState *yys = yystates[yyk];
- yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;
- if (yys->yypred != YY_NULLPTR)
+ yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;
+ if (yys->yypred != YY_NULLPTR)
yydestroyGLRState ("Cleanup: popping", yys, yyparser, ps);
yystates[yyk] = yys->yypred;
yystack.yynextFree -= 1;
@@ -3484,70 +4321,74 @@ yy_yypstack (yyGLRState* yys)
if (yys->yypred)
{
yy_yypstack (yys->yypred);
- YYFPRINTF (stderr, " -> ");
+ YY_FPRINTF ((stderr, " -> "));
}
- YYFPRINTF (stderr, "%d@%lu", yys->yylrState,
- (unsigned long int) yys->yyposn);
+ YY_FPRINTF ((stderr, "%d@%ld", yys->yylrState, YY_CAST (long, yys->yyposn)));
}
static void
yypstates (yyGLRState* yyst)
{
if (yyst == YY_NULLPTR)
- YYFPRINTF (stderr, "<null>");
+ YY_FPRINTF ((stderr, "<null>"));
else
yy_yypstack (yyst);
- YYFPRINTF (stderr, "\n");
+ YY_FPRINTF ((stderr, "\n"));
}
static void
-yypstack (yyGLRStack* yystackp, size_t yyk)
+yypstack (yyGLRStack* yystackp, ptrdiff_t yyk)
{
yypstates (yystackp->yytops.yystates[yyk]);
}
-#define YYINDEX(YYX) \
- ((YYX) == YY_NULLPTR ? -1 : (yyGLRStackItem*) (YYX) - yystackp->yyitems)
-
-
static void
yypdumpstack (yyGLRStack* yystackp)
{
+#define YYINDEX(YYX) \
+ YY_CAST (long, \
+ ((YYX) \
+ ? YY_REINTERPRET_CAST (yyGLRStackItem*, (YYX)) - yystackp->yyitems \
+ : -1))
+
yyGLRStackItem* yyp;
- size_t yyi;
for (yyp = yystackp->yyitems; yyp < yystackp->yynextFree; yyp += 1)
{
- YYFPRINTF (stderr, "%3lu. ",
- (unsigned long int) (yyp - yystackp->yyitems));
- if (*(yybool *) yyp)
+ YY_FPRINTF ((stderr, "%3ld. ",
+ YY_CAST (long, yyp - yystackp->yyitems)));
+ if (*YY_REINTERPRET_CAST (yybool *, yyp))
{
- YYASSERT (yyp->yystate.yyisState);
- YYASSERT (yyp->yyoption.yyisState);
- YYFPRINTF (stderr, "Res: %d, LR State: %d, posn: %lu, pred: %ld",
- yyp->yystate.yyresolved, yyp->yystate.yylrState,
- (unsigned long int) yyp->yystate.yyposn,
- (long int) YYINDEX (yyp->yystate.yypred));
+ YY_ASSERT (yyp->yystate.yyisState);
+ YY_ASSERT (yyp->yyoption.yyisState);
+ YY_FPRINTF ((stderr, "Res: %d, LR State: %d, posn: %ld, pred: %ld",
+ yyp->yystate.yyresolved, yyp->yystate.yylrState,
+ YY_CAST (long, yyp->yystate.yyposn),
+ YYINDEX (yyp->yystate.yypred)));
if (! yyp->yystate.yyresolved)
- YYFPRINTF (stderr, ", firstVal: %ld",
- (long int) YYINDEX (yyp->yystate
- .yysemantics.yyfirstVal));
+ YY_FPRINTF ((stderr, ", firstVal: %ld",
+ YYINDEX (yyp->yystate.yysemantics.yyfirstVal)));
}
else
{
- YYASSERT (!yyp->yystate.yyisState);
- YYASSERT (!yyp->yyoption.yyisState);
- YYFPRINTF (stderr, "Option. rule: %d, state: %ld, next: %ld",
- yyp->yyoption.yyrule - 1,
- (long int) YYINDEX (yyp->yyoption.yystate),
- (long int) YYINDEX (yyp->yyoption.yynext));
+ YY_ASSERT (!yyp->yystate.yyisState);
+ YY_ASSERT (!yyp->yyoption.yyisState);
+ YY_FPRINTF ((stderr, "Option. rule: %d, state: %ld, next: %ld",
+ yyp->yyoption.yyrule - 1,
+ YYINDEX (yyp->yyoption.yystate),
+ YYINDEX (yyp->yyoption.yynext)));
}
- YYFPRINTF (stderr, "\n");
+ YY_FPRINTF ((stderr, "\n"));
}
- YYFPRINTF (stderr, "Tops:");
- for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
- YYFPRINTF (stderr, "%lu: %ld; ", (unsigned long int) yyi,
- (long int) YYINDEX (yystackp->yytops.yystates[yyi]));
- YYFPRINTF (stderr, "\n");
+
+ YY_FPRINTF ((stderr, "Tops:"));
+ {
+ ptrdiff_t yyi;
+ for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
+ YY_FPRINTF ((stderr, "%ld: %ld; ", YY_CAST (long, yyi),
+ YYINDEX (yystackp->yytops.yystates[yyi])));
+ YY_FPRINTF ((stderr, "\n"));
+ }
+#undef YYINDEX
}
#endif
@@ -3558,7 +4399,7 @@ yypdumpstack (yyGLRStack* yystackp)
-#line 483 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.c:2584
+#line 927 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
#include <ctype.h>
@@ -3570,7 +4411,7 @@ void yy::parser::error(const yy::parser::location_type& l,
}
-#line 3574 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:2584
+#line 4415 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
/*------------------.
| Report an error. |
@@ -3585,9 +4426,9 @@ yyerror (const yy::parser::location_type *yylocationp, yy::parser& yyparser, tid
}
-
namespace yy {
-#line 3591 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:2584
+#line 4431 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+
/// Build a parser object.
parser::parser (tidl::Parser* ps_yyarg)
:
@@ -3595,11 +4436,18 @@ namespace yy {
yycdebug_ (&std::cerr),
#endif
ps (ps_yyarg)
- {
- }
+ {}
parser::~parser ()
+ {}
+
+ parser::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW
+ {}
+
+ int
+ parser::operator() ()
{
+ return parse ();
}
int
@@ -3613,16 +4461,16 @@ namespace yy {
| Print this symbol. |
`--------------------*/
- inline void
+ void
parser::yy_symbol_value_print_ (int yytype,
const semantic_type* yyvaluep,
const location_type* yylocationp)
{
YYUSE (yylocationp);
YYUSE (yyvaluep);
- std::ostream& yyoutput = debug_stream ();
- std::ostream& yyo = yyoutput;
- YYUSE (yyo);
+ std::ostream& yyo = debug_stream ();
+ std::ostream& yyoutput = yyo;
+ YYUSE (yyoutput);
YYUSE (yytype);
}
@@ -3666,6 +4514,5 @@ namespace yy {
}
#endif
-
} // yy
-#line 3672 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.cpp" // glr.c:2584
+#line 4519 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
diff --git a/idlc/ast/tidlc_y.hpp b/idlc/ast/tidlc_y.hpp
index a6fc076..0ecc24e 100644
--- a/idlc/ast/tidlc_y.hpp
+++ b/idlc/ast/tidlc_y.hpp
@@ -1,8 +1,8 @@
-// A Bison parser, made by GNU Bison 3.0.4.
+// A Bison parser, made by GNU Bison 3.5.1.
// Skeleton interface for Bison GLR parsers in C++
-// Copyright (C) 2002-2015 Free Software Foundation, Inc.
+// Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -32,23 +32,154 @@
// C++ GLR parser skeleton written by Akim Demaille.
-#ifndef YY_YY_HOME_HYUNHO_FULL_SOURCES_TIZEN_TIDL_THREAD_PROJ_TIDL_IDLC_AST_TIDLC_Y_HPP_INCLUDED
-# define YY_YY_HOME_HYUNHO_FULL_SOURCES_TIZEN_TIDL_THREAD_PROJ_TIDL_IDLC_AST_TIDLC_Y_HPP_INCLUDED
+// Undocumented macros, especially those whose name start with YY_,
+// are private implementation details. Do not rely on them.
+#ifndef YY_YY_OPT_DATA_TIZEN_PUBLIC_PLATFORM_CORE_APPFW_TIDL_IDLC_AST_TIDLC_Y_HPP_INCLUDED
+# define YY_YY_OPT_DATA_TIZEN_PUBLIC_PLATFORM_CORE_APPFW_TIDL_IDLC_AST_TIDLC_Y_HPP_INCLUDED
+#include <iostream>
#include <stdexcept>
#include <string>
-#include <iostream>
-#include "location.hh"
+
+#if defined __cplusplus
+# define YY_CPLUSPLUS __cplusplus
+#else
+# define YY_CPLUSPLUS 199711L
+#endif
+
+// Support move semantics when possible.
+#if 201103L <= YY_CPLUSPLUS
+# define YY_MOVE std::move
+# define YY_MOVE_OR_COPY move
+# define YY_MOVE_REF(Type) Type&&
+# define YY_RVREF(Type) Type&&
+# define YY_COPY(Type) Type
+#else
+# define YY_MOVE
+# define YY_MOVE_OR_COPY copy
+# define YY_MOVE_REF(Type) Type&
+# define YY_RVREF(Type) const Type&
+# define YY_COPY(Type) const Type&
+#endif
+
+// Support noexcept when possible.
+#if 201103L <= YY_CPLUSPLUS
+# define YY_NOEXCEPT noexcept
+# define YY_NOTHROW
+#else
+# define YY_NOEXCEPT
+# define YY_NOTHROW throw ()
+#endif
+
+// Support constexpr when possible.
+#if 201703 <= YY_CPLUSPLUS
+# define YY_CONSTEXPR constexpr
+#else
+# define YY_CONSTEXPR
+#endif
+# include "location.hh"
+
+
+#ifndef YY_ATTRIBUTE_PURE
+# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
+# else
+# define YY_ATTRIBUTE_PURE
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+# else
+# define YY_ATTRIBUTE_UNUSED
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(E) ((void) (E))
+#else
+# define YYUSE(E) /* empty */
+#endif
+
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
+# define YY_IGNORE_USELESS_CAST_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
+# define YY_IGNORE_USELESS_CAST_END \
+ _Pragma ("GCC diagnostic pop")
+#endif
+#ifndef YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_END
+#endif
+
+# ifndef YY_NULLPTR
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# else
+# define YY_NULLPTR ((void*)0)
+# endif
+# endif
+
+// This skeleton is based on C, yet compiles it as C++.
+// So expect warnings about C style casts.
+#if defined __clang__ && 306 <= __clang_major__ * 100 + __clang_minor__
+# pragma clang diagnostic ignored "-Wold-style-cast"
+#elif defined __GNUC__ && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
+# pragma GCC diagnostic ignored "-Wold-style-cast"
+#endif
+
+// On MacOS, PTRDIFF_MAX is defined as long long, which Clang's
+// -pedantic reports as being a C++11 extension.
+#if defined __APPLE__ && YY_CPLUSPLUS < 201103L \
+ && defined __clang__ && 4 <= __clang_major__
+# pragma clang diagnostic ignored "-Wc++11-long-long"
+#endif
+
+// Whether we are compiled with exception support.
+#ifndef YY_EXCEPTIONS
+# if defined __GNUC__ && !defined __EXCEPTIONS
+# define YY_EXCEPTIONS 0
+# else
+# define YY_EXCEPTIONS 1
+# endif
+#endif
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
-
namespace yy {
-#line 52 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.hpp" // glr.cc:329
+#line 181 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.hpp"
+
+
/// A Bison parser.
@@ -59,7 +190,7 @@ namespace yy {
/// Symbol semantic values.
union semantic_type
{
- #line 37 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc.yy" // glr.cc:329
+#line 41 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
tidl::Document* doc;
tidl::Interface* interf;
@@ -72,13 +203,19 @@ namespace yy {
tidl::Parameters* params;
tidl::Token* token;
tidl::Structure* structure;
+ tidl::Block* protocol;
tidl::Element* elm;
tidl::Elements* elms;
tidl::Block* blk;
tidl::Attribute* attr;
tidl::Attributes* attrs;
+ tidl::Enum* enumeration;
+ tidl::Enums* enumerations;
+ tidl::Field* enum_field;
+ tidl::Fields* enum_fields;
+
+#line 218 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.hpp"
-#line 82 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.hpp" // glr.cc:329
};
#else
typedef YYSTYPE semantic_type;
@@ -89,7 +226,18 @@ namespace yy {
/// Syntax errors thrown from user actions.
struct syntax_error : std::runtime_error
{
- syntax_error (const location_type& l, const std::string& m);
+ syntax_error (const location_type& l, const std::string& m)
+ : std::runtime_error (m)
+ , location (l)
+ {}
+
+ syntax_error (const syntax_error& s)
+ : std::runtime_error (s.what ())
+ , location (s.location)
+ {}
+
+ ~syntax_error () YY_NOEXCEPT YY_NOTHROW;
+
location_type location;
};
@@ -102,36 +250,43 @@ namespace yy {
T_RIGHT = 259,
T_COMMA = 260,
T_SEMICOLON = 261,
- T_BRACE_OPEN = 262,
- T_BRACE_CLOSE = 263,
- T_IN = 264,
- T_OUT = 265,
- T_REF = 266,
- T_ASYNC = 267,
- T_META_OPEN = 268,
- T_META_CLOSE = 269,
- T_EQUAL = 270,
- T_DELEGATE = 271,
- T_UNKNOWN = 272,
- T_ID = 273,
- T_STRUCTURE = 274,
- T_INTERFACE = 275,
- T_CHAR = 276,
- T_SHORT = 277,
- T_INT = 278,
- T_LONG = 279,
- T_FLOAT = 280,
- T_DOUBLE = 281,
- T_VOID = 282,
- T_BUNDLE = 283,
- T_STRING = 284,
- T_BOOL = 285,
- T_LIST = 286,
- T_ARRAY = 287,
- T_VALUE = 288,
- T_SB_OPEN = 289,
- T_SB_CLOSE = 290,
- T_FILE = 291
+ T_COLON = 262,
+ T_BRACE_OPEN = 263,
+ T_BRACE_CLOSE = 264,
+ T_IN = 265,
+ T_OUT = 266,
+ T_REF = 267,
+ T_ASYNC = 268,
+ T_META_OPEN = 269,
+ T_META_CLOSE = 270,
+ T_EQUAL = 271,
+ T_DELEGATE = 272,
+ T_DOT = 273,
+ T_ID = 274,
+ T_NUMBER = 275,
+ T_HEX_NUMBER = 276,
+ T_STRUCTURE = 277,
+ T_INTERFACE = 278,
+ T_CHAR = 279,
+ T_SHORT = 280,
+ T_INT = 281,
+ T_LONG = 282,
+ T_FLOAT = 283,
+ T_DOUBLE = 284,
+ T_VOID = 285,
+ T_BUNDLE = 286,
+ T_STRING = 287,
+ T_BOOL = 288,
+ T_LIST = 289,
+ T_ARRAY = 290,
+ T_MAP = 291,
+ T_SET = 292,
+ T_VALUE = 293,
+ T_SB_OPEN = 294,
+ T_SB_CLOSE = 295,
+ T_FILE = 296,
+ T_PROTOCOL = 297,
+ T_ENUM = 298
};
};
@@ -145,105 +300,22 @@ namespace yy {
enum { empty_symbol = -2 };
/// Internal symbol number for tokens (subsumed by symbol_number_type).
- typedef unsigned char token_number_type;
-
- /// A complete symbol.
- ///
- /// Expects its Base type to provide access to the symbol type
- /// via type_get().
- ///
- /// Provide access to semantic value and location.
- template <typename Base>
- struct basic_symbol : Base
- {
- /// Alias to Base.
- typedef Base super_type;
-
- /// Default constructor.
- basic_symbol ();
-
- /// Copy constructor.
- basic_symbol (const basic_symbol& other);
-
- /// Constructor for valueless symbols.
- basic_symbol (typename Base::kind_type t,
- const location_type& l);
-
- /// Constructor for symbols with semantic value.
- basic_symbol (typename Base::kind_type t,
- const semantic_type& v,
- const location_type& l);
-
- /// Destroy the symbol.
- ~basic_symbol ();
-
- /// Destroy contents, and record that is empty.
- void clear ();
-
- /// Whether empty.
- bool empty () const;
-
- /// Destructive move, \a s is emptied into this.
- void move (basic_symbol& s);
-
- /// The semantic value.
- semantic_type value;
-
- /// The location.
- location_type location;
-
- private:
- /// Assignment operator.
- basic_symbol& operator= (const basic_symbol& other);
- };
-
- /// Type access provider for token (enum) based symbols.
- struct by_type
- {
- /// Default constructor.
- by_type ();
-
- /// Copy constructor.
- by_type (const by_type& other);
-
- /// The symbol type as needed by the constructor.
- typedef token_type kind_type;
-
- /// Constructor from (external) token numbers.
- by_type (kind_type t);
-
- /// Record that this symbol is empty.
- void clear ();
-
- /// Steal the symbol type from \a that.
- void move (by_type& that);
-
- /// The (internal) type number (corresponding to \a type).
- /// \a empty when empty.
- symbol_number_type type_get () const;
-
- /// The token.
- token_type token () const;
-
- /// The symbol type.
- /// \a empty_symbol when empty.
- /// An int, not token_number_type, to be able to store empty_symbol.
- int type;
- };
-
- /// "External" symbols: returned by the scanner.
- typedef basic_symbol<by_type> symbol_type;
-
+ typedef signed char token_number_type;
/// Build a parser object.
parser (tidl::Parser* ps_yyarg);
virtual ~parser ();
+ /// Parse. An alias for parse ().
+ /// \returns 0 iff parsing succeeded.
+ int operator() ();
+
/// Parse.
/// \returns 0 iff parsing succeeded.
virtual int parse ();
+#if YYDEBUG
/// The current debugging stream.
std::ostream& debug_stream () const;
/// Set the current debugging stream.
@@ -255,8 +327,8 @@ namespace yy {
debug_level_type debug_level () const;
/// Set the current debugging level.
void set_debug_level (debug_level_type l);
+#endif
- public:
/// Report a syntax error.
/// \param loc where the syntax error is found.
/// \param msg a description of the syntax error.
@@ -297,9 +369,9 @@ namespace yy {
# define YYLTYPE yy::parser::location_type
#endif
-
} // yy
-#line 303 "/home/hyunho/full-sources/tizen/tidl_thread_proj/tidl/idlc/ast/tidlc_y.hpp" // glr.cc:329
+#line 374 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.hpp"
+
-#endif // !YY_YY_HOME_HYUNHO_FULL_SOURCES_TIZEN_TIDL_THREAD_PROJ_TIDL_IDLC_AST_TIDLC_Y_HPP_INCLUDED
+#endif // !YY_YY_OPT_DATA_TIZEN_PUBLIC_PLATFORM_CORE_APPFW_TIDL_IDLC_AST_TIDLC_Y_HPP_INCLUDED
diff --git a/idlc/ast/type.cc b/idlc/ast/type.cc
index 09ad70e..802d51b 100644
--- a/idlc/ast/type.cc
+++ b/idlc/ast/type.cc
@@ -25,23 +25,177 @@ Token::Token(std::string name, std::string comments)
: name_(std::move(name)), comments_(std::move(comments)) {
}
-BaseType::BaseType(std::string name, std::string comments,
- bool user_defined)
+BaseType::BaseType(std::string name, std::string comments, bool user_defined)
: Token(std::move(name), std::move(comments)), user_defined_(user_defined) {
+ if (user_defined)
+ user_type_ = UserType::STRUCTURE;
+ else
+ user_type_ = UserType::DEFAULT;
}
+BaseType::BaseType(std::string name, std::string comments, UserType user_type)
+ : Token(std::move(name), std::move(comments)), user_defined_(true),
+ user_type_(user_type) {}
+
BaseType::BaseType(const BaseType& type)
- : Token(type.ToString(), type.GetComments()),
- user_defined_(type.IsUserDefinedType()) {
- if (type.GetMetaType() != nullptr) {
+ : Token(type.ToString(), type.GetComments()),
+ user_defined_(type.IsUserDefinedType()),
+ user_type_(type.GetUserDefinedType()) {
+ if (type.GetMetaType() != nullptr)
SetMetaType(new BaseType(*type.GetMetaType()));
+
+ if (type.GetKeyType() != nullptr)
+ SetKeyType(new BaseType(*type.GetKeyType()));
+
+ if (type.GetValueType() != nullptr)
+ SetValueType(new BaseType(*type.GetValueType()));
+}
+
+BaseType& BaseType::operator = (const BaseType& type) {
+ if (this != &type) {
+ name_ = type.name_;
+ comments_ = type.comments_;
+ user_defined_ = type.user_defined_;
+ user_type_ = type.user_type_;
+ if (type.GetMetaType() != nullptr)
+ SetMetaType(new BaseType(*type.GetMetaType()));
+
+ if (type.GetKeyType() != nullptr)
+ SetKeyType(new BaseType(*type.GetKeyType()));
+
+ if (type.GetValueType() != nullptr)
+ SetValueType(new BaseType(*type.GetValueType()));
}
+
+ return *this;
+}
+
+BaseType::BaseType(BaseType&& type) noexcept {
+ name_ = std::move(type.name_);
+ comments_ = std::move(type.comments_);
+ user_defined_ = type.user_defined_;
+ user_type_ = type.user_type_;
+ meta_type_ = std::move(type.meta_type_);
+ key_type_ = std::move(type.key_type_);
+ value_type_ = std::move(type.value_type_);
+}
+
+BaseType& BaseType::operator = (BaseType&& type) noexcept {
+ if (this != &type) {
+ name_ = std::move(type.name_);
+ comments_ = std::move(type.comments_);
+ user_defined_ = type.user_defined_;
+ user_type_ = type.user_type_;
+ meta_type_ = std::move(type.meta_type_);
+ key_type_ = std::move(type.key_type_);
+ value_type_ = std::move(type.value_type_);
+ }
+
+ return *this;
}
void BaseType::SetMetaType(BaseType* type) {
meta_type_.reset(type);
}
+const BaseType* BaseType::GetMetaType() const {
+ return meta_type_.get();
+}
+
+void BaseType::SetKeyType(BaseType* type) {
+ key_type_.reset(type);
+}
+
+const BaseType* BaseType::GetKeyType() const {
+ return key_type_.get();
+}
+
+void BaseType::SetValueType(BaseType* type) {
+ value_type_.reset(type);
+}
+
+const BaseType* BaseType::GetValueType() const {
+ return value_type_.get();
+}
+
+std::string BaseType::GetFullName(bool use_underbar) const {
+ std::string name = ToString();
+
+ if (meta_type_.get() != nullptr) {
+ name += use_underbar ? "_" : "<";
+ name += meta_type_->GetFullName(use_underbar);
+ name += use_underbar ? "" : ">";
+ } else if (key_type_.get() != nullptr) {
+ name += use_underbar ? "_" : "<";
+ name += key_type_->GetFullName(use_underbar);
+
+ if (value_type_.get() != nullptr) {
+ name += use_underbar ? "_" : ", ";
+ name += value_type_->GetFullName(use_underbar);
+ }
+
+ name += use_underbar ? "" : ">";
+ }
+
+ return name;
+}
+
+bool BaseType::IsUserDefinedType() const {
+ return user_defined_;
+}
+
+bool BaseType::IsEnumType() const {
+ return user_type_ == UserType::ENUM;
+}
+
+bool BaseType::IsStructureType() const {
+ return user_type_ == UserType::STRUCTURE;
+}
+
+bool BaseType::IsDelegateType() const {
+ return user_type_ == UserType::DELEGATE;
+}
+
+bool BaseType::IsFile(const BaseType* type) {
+ if (type == nullptr)
+ return false;
+
+ if (type->GetMetaType() != nullptr)
+ return IsFile(type->GetMetaType());
+
+ if (type->GetKeyType() != nullptr) {
+ if (IsFile(type->GetKeyType()))
+ return true;
+ }
+
+ if (type->GetValueType() != nullptr) {
+ if (IsFile(type->GetValueType()))
+ return true;
+ }
+
+ return type->ToString() == "file";
+}
+
+bool BaseType::IsKeyType(const BaseType* type) {
+ if (type == nullptr)
+ return false;
+
+ if (type->GetMetaType() != nullptr ||
+ type->GetKeyType() != nullptr)
+ return false;
+
+ if (type->ToString() == "char" ||
+ type->ToString() == "int" ||
+ type->ToString() == "short" ||
+ type->ToString() == "string" ||
+ type->ToString() == "bool" ||
+ type->ToString() == "float" ||
+ type->ToString() == "double")
+ return true;
+
+ return false;
+}
+
ParameterType::ParameterType(BaseType* type)
: type_(type),
dir_(Direction::IN) {
@@ -59,4 +213,13 @@ ParameterType::ParameterType(BaseType* type, const std::string& dir)
dir_ = Direction::IN;
}
+ParameterType::ParameterType(BaseType* type, ParameterType::Direction dir)
+ : type_(type), dir_(dir) {
+}
+
+ParameterType::ParameterType(const ParameterType& param_type) {
+ type_.reset(new BaseType(*param_type.type_));
+ dir_ = param_type.dir_;
+}
+
} // namespace tidl
diff --git a/idlc/ast/type.h b/idlc/ast/type.h
index e3cf288..1d39e1b 100644
--- a/idlc/ast/type.h
+++ b/idlc/ast/type.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef IDLC_TYPE_H_
-#define IDLC_TYPE_H_
+#ifndef IDLC_AST_TYPE_H_
+#define IDLC_AST_TYPE_H_
#include <string>
#include <memory>
@@ -24,47 +24,69 @@ namespace tidl {
class Token {
public:
+ Token() = default;
Token(std::string name, std::string comments);
virtual ~Token() = default;
virtual std::string ToString() const { return name_; }
virtual std::string GetComments() const { return comments_; }
- private:
+ protected:
std::string name_;
std::string comments_;
};
class BaseType : public Token {
public:
- explicit BaseType(std::string name, std::string comments,
+ enum class UserType {
+ DEFAULT,
+ STRUCTURE,
+ DELEGATE,
+ ENUM,
+ };
+
+ BaseType() = default;
+ virtual ~BaseType() = default;
+
+ BaseType(std::string name, std::string comments,
bool user_defined = false);
+ BaseType(std::string name, std::string comments,
+ UserType user_type);
BaseType(const BaseType& type);
+ BaseType& operator = (const BaseType& type);
+
+ BaseType(BaseType&& type) noexcept;
+ BaseType& operator = (BaseType&& type) noexcept;
void SetMetaType(BaseType* type);
- const BaseType* GetMetaType() const {
- return meta_type_.get();
- }
+ const BaseType* GetMetaType() const;
- std::string GetFullName() const {
- std::string str = ToString();
+ void SetKeyType(BaseType* type);
+ const BaseType* GetKeyType() const;
- if (meta_type_.get() != nullptr) {
- str += "<";
- str += meta_type_->GetFullName();
- str += ">";
- }
+ void SetValueType(BaseType* type);
+ const BaseType* GetValueType() const;
- return str;
- }
+ std::string GetFullName(bool use_underbar = false) const;
+ bool IsUserDefinedType() const;
- bool IsUserDefinedType() const {
- return user_defined_;
+ BaseType::UserType GetUserDefinedType() const {
+ return user_type_;
}
+ bool IsEnumType() const;
+ bool IsStructureType() const;
+ bool IsDelegateType() const;
+
+ static bool IsFile(const BaseType* type);
+ static bool IsKeyType(const BaseType* type);
+
private:
std::unique_ptr<BaseType> meta_type_;
- bool user_defined_;
+ std::unique_ptr<BaseType> key_type_;
+ std::unique_ptr<BaseType> value_type_;
+ bool user_defined_ = false;
+ UserType user_type_ = UserType::DEFAULT;
};
class ParameterType {
@@ -76,7 +98,10 @@ class ParameterType {
};
ParameterType(BaseType* type, const std::string& dir);
+ ParameterType(BaseType* type, Direction dir);
explicit ParameterType(BaseType* type);
+ ParameterType(const ParameterType& param_type);
+
Direction GetDirection() const { return dir_; }
const BaseType& GetBaseType() const { return *type_; }
@@ -87,4 +112,4 @@ class ParameterType {
} // namespace tidl
-#endif // IDLC_TYPE_H_
+#endif // IDLC_AST_TYPE_H_
diff --git a/idlc/cion_generator.cc b/idlc/cion_generator.cc
new file mode 100644
index 0000000..81504e4
--- /dev/null
+++ b/idlc/cion_generator.cc
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/cion_generator.hh"
+
+#include <utility>
+
+#include "idlc/gen_cion/c_cion_group_body_gen.h"
+#include "idlc/gen_cion/c_cion_group_header_gen.h"
+#include "idlc/gen_cion/c_cion_proxy_body_gen.h"
+#include "idlc/gen_cion/c_cion_proxy_header_gen.h"
+#include "idlc/gen_cion/c_cion_stub_body_gen.h"
+#include "idlc/gen_cion/c_cion_stub_header_gen.h"
+#include "idlc/gen_cion/cpp_cion_group_body_gen.h"
+#include "idlc/gen_cion/cpp_cion_group_header_gen.h"
+#include "idlc/gen_cion/cpp_cion_proxy_body_gen.h"
+#include "idlc/gen_cion/cpp_cion_proxy_header_gen.h"
+#include "idlc/gen_cion/cpp_cion_stub_body_gen.h"
+#include "idlc/gen_cion/cpp_cion_stub_header_gen.h"
+#include "idlc/gen_cion/cs_cion_group_gen.h"
+#include "idlc/gen_cion/cs_cion_proxy_gen.h"
+#include "idlc/gen_cion/cs_cion_stub_gen.h"
+#include "idlc/gen_cion/dart_cion_group_gen.h"
+#include "idlc/gen_cion/dart_cion_proxy_gen.h"
+#include "idlc/gen_cion/dart_cion_stub_gen.h"
+#include "idlc/gen_cion/java_cion_common_gen.h"
+#include "idlc/gen_cion/java_cion_group_gen.h"
+#include "idlc/gen_cion/java_cion_group_repo_gen.h"
+#include "idlc/gen_cion/java_cion_proxy_gen.h"
+#include "idlc/gen_cion/java_cion_proxy_repo_gen.h"
+#include "idlc/gen_cion/java_cion_structure_gen.h"
+#include "idlc/gen_cion/java_cion_stub_gen.h"
+#include "idlc/gen_cion/java_cion_stub_repo_gen.h"
+#include "idlc/gen_cion/java_cion_utility_gen.h"
+#include "idlc/gen_cion/plugin_loader.h"
+
+namespace tidl {
+
+CionGenerator::CionGenerator() {
+ cion_funcs_ = {
+ // Stub
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_C),
+ std::bind(&CionGenerator::GenCionCStubCode, this, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_CPP),
+ std::bind(&CionGenerator::GenCionCppStubCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_CSHARP),
+ std::bind(&CionGenerator::GenCionCsharpStubCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_JAVA),
+ std::bind(&CionGenerator::GenCionJavaStubCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_DART),
+ std::bind(&CionGenerator::GenCionDartStubCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+
+ // Proxy
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_C),
+ std::bind(&CionGenerator::GenCionCProxyCode, this, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_CPP),
+ std::bind(&CionGenerator::GenCionCppProxyCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_CSHARP),
+ std::bind(&CionGenerator::GenCionCsharpProxyCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_JAVA),
+ std::bind(&CionGenerator::GenCionJavaProxyCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_DART),
+ std::bind(&CionGenerator::GenCionDartProxyCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+
+ // Group
+ {std::make_pair(Options::Type::TYPE_GROUP, Options::LANGUAGE_TYPE_C),
+ std::bind(&CionGenerator::GenCionCGroupCode, this, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_GROUP, Options::LANGUAGE_TYPE_CPP),
+ std::bind(&CionGenerator::GenCionCppGroupCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_GROUP, Options::LANGUAGE_TYPE_CSHARP),
+ std::bind(&CionGenerator::GenCionCsharpGroupCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_GROUP, Options::LANGUAGE_TYPE_JAVA),
+ std::bind(&CionGenerator::GenCionJavaGroupCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_GROUP, Options::LANGUAGE_TYPE_DART),
+ std::bind(&CionGenerator::GenCionDartGroupCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ };
+}
+
+void CionGenerator::Generate(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ auto found = cion_funcs_.find(
+ std::make_pair(options->GetType(), options->GetLanguage()));
+ if (found == cion_funcs_.end()) return;
+
+ auto trans = std::shared_ptr<Transportable>(new PluginLoader(""));
+ auto& func = found->second;
+ func(std::move(options), ps, std::move(trans));
+}
+
+void CionGenerator::GenCionCStubCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ CCionStubHeaderGen stub_header(ps.GetDoc(), trans);
+ stub_header.EnableNamespace(options->HasNamespace());
+ stub_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ stub_header.Run(options->GetOutput() + ".h");
+
+ CCionStubBodyGen stub_body(ps.GetDoc(), options, trans);
+ stub_body.EnableNamespace(options->HasNamespace());
+ stub_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ stub_body.Run(options->GetOutput() + ".c");
+}
+
+void CionGenerator::GenCionCppStubCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ CppCionStubHeaderGen stub_header(ps.GetDoc(), options, trans);
+ stub_header.Run(options->GetOutput() + ".h");
+
+ CppCionStubBodyGen stub_body(ps.GetDoc(), options, trans);
+ stub_body.Run(options->GetOutput() + ".cc");
+}
+
+void CionGenerator::GenCionCsharpStubCode(
+ std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ CsCionStubGen stub(ps.GetDoc(), trans);
+ stub.Run(options->GetOutput() + ".cs");
+}
+
+void CionGenerator::GenCionJavaStubCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ JavaCionStubRepoGen repo(ps.GetDoc(), trans);
+ repo.Run(options->GetOutput(), true);
+
+ JavaCionStubGen view_model(ps.GetDoc(), trans);
+ view_model.Run(options->GetOutput(), true);
+
+ JavaCionUtilityGen utilities(ps.GetDoc(), trans);
+ utilities.Run(options->GetOutput(), true);
+
+ JavaCionStructureGen structures(ps.GetDoc(), trans);
+ structures.Run(options->GetOutput(), true);
+
+ JavaCionCommonGen cgen(ps.GetDoc(), trans);
+ cgen.Run(options->GetOutput(), true);
+}
+
+void CionGenerator::GenCionDartStubCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ DartCionStubGen stub(ps.GetDoc(), trans);
+ stub.EnableProxy(false);
+ stub.Run(options->GetOutput() + ".dart");
+}
+
+void CionGenerator::GenCionCProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ CCionProxyHeaderGen proxy_header(ps.GetDoc(), trans);
+ proxy_header.EnableNamespace(options->HasNamespace());
+ proxy_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ proxy_header.Run(options->GetOutput() + ".h");
+
+ CCionProxyBodyGen proxy_body(ps.GetDoc(), options, trans);
+ proxy_body.EnableNamespace(options->HasNamespace());
+ proxy_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ proxy_body.Run(options->GetOutput() + ".c");
+}
+
+void CionGenerator::GenCionCppProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ CppCionProxyHeaderGen proxy_header(ps.GetDoc(), trans);
+ proxy_header.Run(options->GetOutput() + ".h");
+
+ CppCionProxyBodyGen proxy_body(ps.GetDoc(), trans);
+ proxy_body.Run(options->GetOutput() + ".cc");
+}
+
+void CionGenerator::GenCionCsharpProxyCode(
+ std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ CsCionProxyGen proxy(ps.GetDoc(), trans);
+ proxy.Run(options->GetOutput() + ".cs");
+}
+
+void CionGenerator::GenCionJavaProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ JavaCionProxyRepoGen base_files(ps.GetDoc(), trans);
+ base_files.Run(options->GetOutput(), true);
+
+ JavaCionProxyGen view_model(ps.GetDoc(), trans);
+ view_model.Run(options->GetOutput(), true);
+
+ JavaCionUtilityGen utilities(ps.GetDoc(), trans);
+ utilities.Run(options->GetOutput(), true);
+
+ JavaCionStructureGen structures(ps.GetDoc(), trans);
+ structures.Run(options->GetOutput(), true);
+
+ JavaCionCommonGen cgen(ps.GetDoc(), trans);
+ cgen.Run(options->GetOutput(), true);
+}
+
+void CionGenerator::GenCionDartProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ DartCionProxyGen proxy(ps.GetDoc(), trans);
+ proxy.Run(options->GetOutput() + ".dart");
+}
+
+void CionGenerator::GenCionCGroupCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ CCionGroupHeaderGen group_header(ps.GetDoc(), trans);
+ group_header.EnableNamespace(options->HasNamespace());
+ group_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ group_header.Run(options->GetOutput() + ".h");
+
+ CCionGroupBodyGen group_body(ps.GetDoc(), options, trans);
+ group_body.EnableNamespace(options->HasNamespace());
+ group_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ group_body.Run(options->GetOutput() + ".c");
+}
+
+void CionGenerator::GenCionCppGroupCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ CppCionGroupHeaderGen group_header(ps.GetDoc(), trans);
+ group_header.Run(options->GetOutput() + ".h");
+
+ CppCionGroupBodyGen group_body(ps.GetDoc(), trans);
+ group_body.Run(options->GetOutput() + ".cc");
+}
+
+void CionGenerator::GenCionCsharpGroupCode(
+ std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ CsCionGroupGen group(ps.GetDoc(), trans);
+ group.Run(options->GetOutput() + ".cs");
+}
+
+void CionGenerator::GenCionJavaGroupCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ JavaCionGroupRepoGen repo(ps.GetDoc(), trans);
+ repo.Run(options->GetOutput(), true);
+
+ JavaCionGroupGen view_model(ps.GetDoc(), trans);
+ view_model.Run(options->GetOutput(), true);
+
+ JavaCionUtilityGen utilities(ps.GetDoc(), trans);
+ utilities.Run(options->GetOutput(), true);
+
+ JavaCionStructureGen structures(ps.GetDoc(), trans);
+ structures.Run(options->GetOutput(), true);
+
+ JavaCionCommonGen cgen(ps.GetDoc(), trans);
+ cgen.Run(options->GetOutput(), true);
+}
+
+void CionGenerator::GenCionDartGroupCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ DartCionGroupGen group(ps.GetDoc(), trans);
+ group.Run(options->GetOutput() + ".dart");
+}
+
+} // namespace tidl
diff --git a/idlc/cion_generator.hh b/idlc/cion_generator.hh
new file mode 100644
index 0000000..815d36e
--- /dev/null
+++ b/idlc/cion_generator.hh
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CION_GENERATOR_HH_
+#define IDLC_CION_GENERATOR_HH_
+
+#include <functional>
+#include <memory>
+#include <unordered_map>
+
+#include "idlc/code_generator.hh"
+#include "idlc/gen_cion/transportable.h"
+
+namespace tidl {
+
+class CionGenerator : public CodeGenerator {
+ public:
+ CionGenerator();
+ virtual ~CionGenerator() = default;
+
+ void Generate(std::shared_ptr<Options> options, const Parser& ps) override;
+
+ private:
+ using GeneratorCionFunc = std::function<void(
+ std::shared_ptr<Options>, const Parser&, std::shared_ptr<Transportable>)>;
+
+ /// Stub
+ void GenCionCStubCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenCionCppStubCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenCionCsharpStubCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenCionJavaStubCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenCionDartStubCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+
+ /// Proxy
+ void GenCionCProxyCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenCionCppProxyCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenCionCsharpProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenCionJavaProxyCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenCionDartProxyCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+
+ /// Group
+ void GenCionCGroupCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenCionCppGroupCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenCionCsharpGroupCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenCionJavaGroupCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenCionDartGroupCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+
+ private:
+ std::unordered_map<GeneratorCond, GeneratorCionFunc, PairHash> cion_funcs_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_CION_GENERATOR_HH_
diff --git a/idlc/code_generator.hh b/idlc/code_generator.hh
new file mode 100644
index 0000000..544147f
--- /dev/null
+++ b/idlc/code_generator.hh
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CODE_GENERATOR_HH_
+#define IDLC_CODE_GENERATOR_HH_
+
+#include <memory>
+#include <utility>
+
+#include "idlc/ast/parser.h"
+#include "idlc/options.h"
+
+namespace tidl {
+
+class CodeGenerator {
+ public:
+ struct PairHash {
+ template <class T1, class T2>
+ std::size_t operator()(const std::pair<T1, T2>& pair) const {
+ return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second);
+ }
+ };
+
+ using GeneratorCond = std::pair<int, int>;
+
+ virtual ~CodeGenerator() = default;
+
+ virtual void Generate(std::shared_ptr<Options> options, const Parser& ps) = 0;
+};
+
+} // namespace tidl
+
+#endif // IDLC_CODE_GENERATOR_HH_
diff --git a/idlc/default_generator.cc b/idlc/default_generator.cc
new file mode 100644
index 0000000..41db8a1
--- /dev/null
+++ b/idlc/default_generator.cc
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/default_generator.hh"
+
+#include <utility>
+
+#include "idlc/ast/parser.h"
+#include "idlc/gen/c_group_body_gen.h"
+#include "idlc/gen/c_group_header_gen.h"
+#include "idlc/gen/c_proxy_body_gen.h"
+#include "idlc/gen/c_proxy_header_gen.h"
+#include "idlc/gen/c_stub_body_gen.h"
+#include "idlc/gen/c_stub_header_gen.h"
+#include "idlc/gen/cpp_group_body_gen.h"
+#include "idlc/gen/cpp_group_header_gen.h"
+#include "idlc/gen/cpp_proxy_body_gen.h"
+#include "idlc/gen/cpp_proxy_header_gen.h"
+#include "idlc/gen/cpp_stub_body_gen.h"
+#include "idlc/gen/cpp_stub_header_gen.h"
+#include "idlc/gen/cs_group_gen.h"
+#include "idlc/gen/cs_lib_gen.h"
+#include "idlc/gen/cs_proxy_gen.h"
+#include "idlc/gen/cs_stub_gen.h"
+#include "idlc/gen/dart_proxy_gen.h"
+#include "idlc/gen/dart_stub_gen.h"
+#include "idlc/options.h"
+
+namespace tidl {
+
+DefaultGenerator::DefaultGenerator() {
+ funcs_ = {
+ // Stub
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_C),
+ std::bind(&DefaultGenerator::GenCStubCode, this, std::placeholders::_1,
+ std::placeholders::_2)},
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_CPP),
+ std::bind(&DefaultGenerator::GenCppStubCode, this, std::placeholders::_1,
+ std::placeholders::_2)},
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_CSHARP),
+ std::bind(&DefaultGenerator::GenCsharpStubCode, this,
+ std::placeholders::_1, std::placeholders::_2)},
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_DART),
+ std::bind(&DefaultGenerator::GenDartStubCode, this,
+ std::placeholders::_1, std::placeholders::_2)},
+
+ // Proxy
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_C),
+ std::bind(&DefaultGenerator::GenCProxyCode, this, std::placeholders::_1,
+ std::placeholders::_2)},
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_CPP),
+ std::bind(&DefaultGenerator::GenCppProxyCode, this,
+ std::placeholders::_1, std::placeholders::_2)},
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_CSHARP),
+ std::bind(&DefaultGenerator::GenCsharpProxyCode, this,
+ std::placeholders::_1, std::placeholders::_2)},
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_DART),
+ std::bind(&DefaultGenerator::GenDartProxyCode, this,
+ std::placeholders::_1, std::placeholders::_2)},
+
+ // Group
+ {std::make_pair(Options::Type::TYPE_GROUP, Options::LANGUAGE_TYPE_C),
+ std::bind(&DefaultGenerator::GenCGroupCode, this, std::placeholders::_1,
+ std::placeholders::_2)},
+ {std::make_pair(Options::Type::TYPE_GROUP, Options::LANGUAGE_TYPE_CPP),
+ std::bind(&DefaultGenerator::GenCppGroupCode, this,
+ std::placeholders::_1, std::placeholders::_2)},
+ {std::make_pair(Options::Type::TYPE_GROUP, Options::LANGUAGE_TYPE_CSHARP),
+ std::bind(&DefaultGenerator::GenCsharpGroupCode, this,
+ std::placeholders::_1, std::placeholders::_2)},
+ };
+}
+
+void DefaultGenerator::Generate(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ auto found = funcs_.find(
+ std::make_pair(options->GetType(), options->GetLanguage()));
+ if (found == funcs_.end()) return;
+
+ auto& func = found->second;
+ func(std::move(options), ps);
+}
+
+void DefaultGenerator::GenCStubCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CStubHeaderGen stub_header(ps.GetDoc());
+ stub_header.EnableNamespace(options->HasNamespace());
+ stub_header.EnableProxy(false);
+ stub_header.Run(options->GetOutput() + ".h");
+
+ CStubBodyGen stub_body(ps.GetDoc(), options);
+ stub_body.EnableNamespace(options->HasNamespace());
+ stub_body.EnableProxy(false);
+ stub_body.Run(options->GetOutput() + ".c");
+}
+
+void DefaultGenerator::GenCppStubCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CppStubHeaderGen stub_header(ps.GetDoc(), options);
+ stub_header.Run(options->GetOutput() + ".h");
+
+ CppStubBodyGen stub_body(ps.GetDoc(), options);
+ stub_body.Run(options->GetOutput() + ".cc");
+}
+
+void DefaultGenerator::GenCsharpStubCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CsStubGen stub(ps.GetDoc());
+ stub.Run(options->GetOutput() + ".cs");
+
+ if (options->HasRpcPortLib()) {
+ CsLibGen lib(ps.GetDoc());
+ lib.Run("rpc-port.cs");
+ }
+}
+
+void DefaultGenerator::GenDartStubCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ DartStubGen stub(ps.GetDoc());
+ stub.EnableProxy(false);
+ stub.Run(options->GetOutput() + ".dart");
+}
+
+void DefaultGenerator::GenCProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CProxyHeaderGen proxy_header(ps.GetDoc());
+ proxy_header.EnableNamespace(options->HasNamespace());
+ proxy_header.EnableProxy(true);
+ proxy_header.Run(options->GetOutput() + ".h");
+
+ CProxyBodyGen proxy_body(ps.GetDoc(), options);
+ proxy_body.EnableNamespace(options->HasNamespace());
+ proxy_body.EnableProxy(true);
+ proxy_body.Run(options->GetOutput() + ".c");
+}
+
+void DefaultGenerator::GenCppProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CppProxyHeaderGen proxy_header(ps.GetDoc());
+ proxy_header.Run(options->GetOutput() + ".h");
+
+ CppProxyBodyGen proxy_body(ps.GetDoc());
+ proxy_body.Run(options->GetOutput() + ".cc");
+}
+
+void DefaultGenerator::GenCsharpProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CsProxyGen proxy(ps.GetDoc());
+ proxy.Run(options->GetOutput() + ".cs");
+
+ if (options->HasRpcPortLib()) {
+ CsLibGen lib(ps.GetDoc());
+ lib.Run("rpc-port.cs");
+ }
+}
+
+void DefaultGenerator::GenDartProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ DartProxyGen proxy(ps.GetDoc());
+ proxy.Run(options->GetOutput() + ".dart");
+}
+
+void DefaultGenerator::GenCGroupCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CGroupHeaderGen group_header(ps.GetDoc());
+ group_header.Run(options->GetOutput() + ".h");
+
+ CGroupBodyGen group_body(ps.GetDoc());
+ group_body.Run(options->GetOutput() + ".c");
+}
+
+void DefaultGenerator::GenCppGroupCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CppGroupHeaderGen group_header(ps.GetDoc());
+ group_header.Run(options->GetOutput() + ".h");
+
+ CppGroupBodyGen group_body(ps.GetDoc());
+ group_body.Run(options->GetOutput() + ".cc");
+}
+
+void DefaultGenerator::GenCsharpGroupCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CsGroupGen group(ps.GetDoc());
+ group.Run(options->GetOutput() + ".cs");
+}
+
+} // namespace tidl
diff --git a/idlc/default_generator.hh b/idlc/default_generator.hh
new file mode 100644
index 0000000..e2c12b6
--- /dev/null
+++ b/idlc/default_generator.hh
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_DEFAULT_GENERATOR_HH_
+#define IDLC_DEFAULT_GENERATOR_HH_
+
+#include <functional>
+#include <memory>
+#include <unordered_map>
+
+#include "idlc/code_generator.hh"
+
+namespace tidl {
+
+class DefaultGenerator : public CodeGenerator {
+ public:
+ DefaultGenerator();
+ virtual ~DefaultGenerator() = default;
+
+ void Generate(std::shared_ptr<Options> options, const Parser& ps) override;
+
+ private:
+ using GeneratorFunc =
+ std::function<void(std::shared_ptr<Options>, const Parser&)>;
+
+ /// Stub
+ void GenCStubCode(std::shared_ptr<Options> options, const Parser& ps);
+ void GenCppStubCode(std::shared_ptr<Options> options, const Parser& ps);
+ void GenCsharpStubCode(std::shared_ptr<Options> options, const Parser& ps);
+ void GenDartStubCode(std::shared_ptr<Options> options, const Parser& ps);
+
+ /// Proxy
+ void GenCProxyCode(std::shared_ptr<Options> options, const Parser& ps);
+ void GenCppProxyCode(std::shared_ptr<Options> options, const Parser& ps);
+ void GenCsharpProxyCode(std::shared_ptr<Options> options, const Parser& ps);
+ void GenDartProxyCode(std::shared_ptr<Options> options, const Parser& ps);
+
+ /// Group
+ void GenCGroupCode(std::shared_ptr<Options> options, const Parser& ps);
+ void GenCppGroupCode(std::shared_ptr<Options> options, const Parser& ps);
+ void GenCsharpGroupCode(std::shared_ptr<Options> options, const Parser& ps);
+
+ private:
+ std::unordered_map<GeneratorCond, GeneratorFunc, PairHash> funcs_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_DEFAULT_GENERATOR_HH_
diff --git a/idlc/gen/c_body_gen_array_base_cb.h b/idlc/gen/c_body_gen_array_base_cb.h
new file mode 100644
index 0000000..e152a7d
--- /dev/null
+++ b/idlc/gen/c_body_gen_array_base_cb.h
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_GEN_C_BODY_GEN_ARRAY_BASE_CB_H_
+#define IDLC_C_GEN_C_BODY_GEN_ARRAY_BASE_CB_H_
+
+/**
+ * <PREFIX> The prefix of the array structure.
+ * <NAME> The name of the array structure.
+ * <ELEMENT_TYPE> The type of the element of the array.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ <ELEMENT_TYPE>*value;
+ int size;
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the array structure.
+ * <NAME> The name of the array structure.
+ * <PARCEL_WRITE> The implementation to write the value to the parcel.
+ * <PARCEL_READ> The implemention to read the value from the parcel.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ * <ELEMENT_TYPE> The type of the element of the array.
+ * <ELEMENT_TYPE_SIZE> The size of the type of the element.
+ * <ELEMENTS_FREE> The implementation to release elements.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+ int i;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ rpc_port_parcel_write_array_count(parcel, h->size);
+
+ for (i = 0; i < h->size; ++i)
+ <PARCEL_WRITE>
+}
+
+static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+ <ELEMENT_TYPE>value;
+ int ret;
+ int i;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ ret = rpc_port_parcel_read_array_count(parcel, &h->size);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read array count. error(%d)", ret);
+ set_last_result(ret);
+ return;
+ }
+
+ h->value = calloc(h->size, sizeof(<ELEMENT_TYPE_SIZE>));
+ if (h->value == nullptr) {
+ _E("Out of memory");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ for (i = 0; i < h->size; ++i) {
+ <PARCEL_READ>
+ }
+
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_from;
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ <ELEMENTS_FREE>
+
+ free(h);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
+{
+ <PREFIX>_<NAME>_h handle;
+ rpc_port_parcel_h parcel;
+ int ret;
+
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_create(&handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ ret = rpc_port_parcel_create(&parcel);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ rpc_port_parcel_write(parcel, &h->parcelable, h);
+ rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+ ret = get_last_result();
+ rpc_port_parcel_destroy(parcel);
+
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ *clone = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_set(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>*value, int size)
+{
+ <PREFIX>_<NAME>_h handle;
+ <PREFIX>_<NAME>_h clone;
+ int ret;
+
+ if (h == nullptr || value == nullptr || size <= 0) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_create(&handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ handle->value = (<ELEMENT_TYPE>*)value;
+ handle->size = size;
+
+ ret = <PREFIX>_<NAME>_clone(handle, &clone);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ handle->value = nullptr;
+ handle->size = 0;
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ handle->value = h->value;
+ handle->size = h->size;
+ <PREFIX>_<NAME>_destroy(handle);
+
+ h->value = clone->value;
+ h->size = clone->size;
+
+ clone->value = nullptr;
+ clone->size = 0;
+ <PREFIX>_<NAME>_destroy(clone);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_get(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>*value, int *size)
+{
+ <PREFIX>_<NAME>_h handle;
+ int ret;
+
+ if (h == nullptr || value == nullptr || size == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_clone(h, &handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ return ret;
+ }
+
+ *value = handle->value;
+ *size = handle->size;
+
+ handle->value = nullptr;
+ handle->size = 0;
+ <PREFIX>_<NAME>_destroy(handle);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel, &h->value[i]->parcelable, h->value[i]);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel, h->value[i]);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel, STRING_GET(h->value[i]));
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel of the value.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel, h->value[i]);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user-defined type.
+ * <NAME> The name of the user-defined type.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+ret = <PREFIX>_<NAME>_create(&value);
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ set_last_result(ret);
+ return;
+}
+
+rpc_port_parcel_read(parcel, &value->parcelable, value);
+if (get_last_result() != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", get_last_result());
+ <PREFIX>_<NAME>_destroy(value);
+ return;
+}
+
+h->value[i] = value;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+value = nullptr;
+rpc_port_parcel_read_bundle(parcel, &value);
+if (value == nullptr) {
+ _E("Failed to read data");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+h->value[i] = value;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_STRING_PARCEL_READ[] =
+R"__c_cb(
+value = nullptr;
+rpc_port_parcel_read_string(parcel, &value);
+if (value == nullptr) {
+ _E("Failed to read data");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+h->value[i] = value;
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel of the value.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &value);
+h->value[i] = value;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_USER_DEFINED_FREE[] =
+R"__c_cb(
+if (h->value) {
+ for (int i = 0; i < h->size; ++i) {
+ if (h->value[i])
+ <PREFIX>_<NAME>_destroy(h->value[i]);
+ }
+
+ free(h->value);
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BUNDLE_FREE[] =
+R"__c_cb(
+if (h->value) {
+ for (int i = 0; i < h->size; ++i) {
+ if (h->value[i])
+ bundle_free(h->value[i]);
+ }
+
+ free(h->value);
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_STRING_FREE[] =
+R"__c_cb(
+if (h->value) {
+ for (int i = 0; i < h->size; ++i) {
+ if (h->value[i])
+ free(h->value[i]);
+ }
+
+ free(h->value);
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BASE_FREE[] =
+R"__c_cb(
+if (h->value)
+ free(h->value);
+)__c_cb";
+
+#endif // IDLC_C_GEN_C_BODY_GEN_ARRAY_BASE_CB_H_
diff --git a/idlc/gen/c_body_gen_base.cc b/idlc/gen/c_body_gen_base.cc
index 50f61bb..e187f37 100644
--- a/idlc/gen/c_body_gen_base.cc
+++ b/idlc/gen/c_body_gen_base.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,19 +14,20 @@
* limitations under the License.
*/
+#include <cstring>
#include <vector>
+#include "idlc/gen/c_body_gen_array_base_cb.h"
#include "idlc/gen/c_body_gen_base.h"
-
-namespace {
#include "idlc/gen/c_body_gen_base_cb.h"
-}
+#include "idlc/gen/c_body_gen_list_base_cb.h"
namespace tidl {
CBodyGeneratorBase::CBodyGeneratorBase(std::shared_ptr<Document> doc)
: CGeneratorBase(doc) {
parcel_type_map_ = {
+ {"none", ""},
{"char", "byte"},
{"int", "int32"},
{"short", "int16"},
@@ -38,1165 +39,695 @@ CBodyGeneratorBase::CBodyGeneratorBase(std::shared_ptr<Document> doc)
{"bundle", "bundle"},
{"file", "string"},
};
-}
-void CBodyGeneratorBase::GenStructures(std::ofstream& stream) {
- for (auto& i : GetDocument().GetBlocks()) {
- if (i->GetType() == Block::TYPE_STRUCTURE) {
- const Structure &st = static_cast<const Structure&>(*i);
- GenStructure(stream, st);
- for (auto& j : st.GetElements().GetElms()) {
- auto& t = j->GetType();
- AddStructureFromType(t);
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ for (const auto& e : st.GetElements()) {
+ auto& type = e->GetType();
+ AddStructureFromType(type);
}
} else {
- const Interface &inf = static_cast<const Interface&>(*i);
- for (auto& d : inf.GetDeclarations().GetDecls()) {
- for (auto& p : d->GetParameters().GetParams()) {
- if (IsDelegateType(inf, p->GetParameterType().GetBaseType()))
+ auto& iface = static_cast<const Interface&>(*b);
+ for (const auto& d : iface.GetDeclarations()) {
+ for (const auto& p : d->GetParameters()) {
+ auto& type = p->GetParameterType().GetBaseType();
+ if (IsDelegateType(iface, type))
continue;
- AddStructureFromType(p->GetParameterType().GetBaseType());
+
+ AddStructureFromType(type, iface);
+ }
+
+ if (d->GetMethodType() == Declaration::MethodType::SYNC) {
+ auto& type = d->GetType();
+ AddStructureFromType(type, iface);
}
}
}
}
-
- for (auto& p : GetStructures()) {
- const Structure& st = *p.second;
- GenStructure(stream, st);
- }
-}
-
-void CBodyGeneratorBase::GenStructure(std::ofstream& stream,
- const Structure& st) {
- GenStructureDeclaration(stream, st);
- GenStructureParcelSerializer(stream, st);
- GenStructureParcelDeserializer(stream, st);
- GenStructureConstructor(stream, st);
- GenStructureDestructor(stream, st);
- GenStructureCloner(stream, st);
- GenStructureSetter(stream, st);
- GenStructureGetter(stream, st);
- GenStructureIterator(stream, st);
- GenStructureRemover(stream, st);
- GenStructureLengthGetter(stream, st);
}
-void CBodyGeneratorBase::GenStructureDeclaration(std::ofstream& stream,
- const Structure& st) {
- stream << SmartIndent(GenTemplateString(CB_STRUCT_DECL,
- [&]()->std::string {
- return st.GetComments();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- std::string str;
- for (auto& i : st.GetElements().GetElms()) {
- str += NLine(1) + GetStringFromElementType(i->GetType()) +
- i->GetID() + ";";
- if (i->GetType().ToString() == "array")
- str += NLine(1) + "int " + i->GetID() + "_size;";
- }
- return str;
- }));
+void CBodyGeneratorBase::GenIncludeHeader(std::ofstream& stream) {
+ std::string code;
+ code += "#include \"";
+ code += FileName.substr(0, FileName.length() - 2);
+ code += ".h\"";
+ stream << NLine(1);
+ stream << code;
+ stream << NLine(1);
}
-void CBodyGeneratorBase::GenStructureParcelSerializer(std::ofstream& stream,
- const Structure& st) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_STRUCT_SERIALIZER, "##", GetStructIdWithNamespace(st)),
- [&]()->std::string {
- std::string str;
- for (auto& i : st.GetElements().GetElms()) {
- str += NLine(1);
- str += GetParcelWriteString(i->GetID(), i->GetType());
- }
- return str;
- }));
+void CBodyGeneratorBase::GenLogTag(std::ofstream& stream,
+ const std::string& log_tag) {
+ ReplaceAll(CB_LOG_TAG, "<LOG_TAG>", log_tag).Out(stream);
}
-void CBodyGeneratorBase::GenStructureParcelDeserializer(std::ofstream& stream,
- const Structure& st) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_STRUCT_DESERIALIZER, "##", GetStructIdWithNamespace(st)),
- [&]()->std::string {
- std::string str;
- for (auto& i : st.GetElements().GetElms()) {
- str += NLine(1);
- str += GetParcelReadString(i->GetID(), i->GetType());
- }
- return str;
- }));
+void CBodyGeneratorBase::GenLogDefinition(std::ofstream& stream) {
+ stream << SmartIndent(CB_LOG_DEF);
}
-void CBodyGeneratorBase::GenStructureConstructor(std::ofstream& stream,
- const Structure& st) {
- stream << SmartIndent(ReplaceAll(CB_STRUCT_CTOR, "##",
- GetStructIdWithNamespace(st)));
+void CBodyGeneratorBase::GenVersionDefinition(std::ofstream& stream) {
+ ReplaceAll(CB_VERSION_DEF, "<VERSION>", FULLVER).Out(stream);
}
-void CBodyGeneratorBase::GenStructureDestructor(std::ofstream& stream,
- const Structure& st) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_STRUCT_DTOR, "##",
- GetStructIdWithNamespace(st)),
- [&]()->std::string {
- std::string str;
- for (auto& i : st.GetElements().GetElms()) {
- str += GetFinalizeString(i->GetID(), i->GetType(), "h->");
- }
- return str;
- }));
+void CBodyGeneratorBase::GenBaseDefinition(std::ofstream& stream) {
+ stream << SmartIndent(CB_BASE_DEF);
}
-void CBodyGeneratorBase::GenStructureSetter(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- stream << SmartIndent(GenTemplateString(CB_STRUCT_SETTER,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "list")
- return "add";
- return "set";
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().IsUserDefinedType())
- return GetParcelParamTypeString(i->GetType());
-
- if (i->GetType().ToString() == "list") {
- if (i->GetType().GetMetaType()->IsUserDefinedType() ||
- i->GetType().GetMetaType()->ToString() == "list" ||
- i->GetType().GetMetaType()->ToString() == "array") {
- return GetParcelParamTypeString(*i->GetType().GetMetaType());
- } else {
- return ConvertTypeToString(ParameterType::Direction::IN,
- *i->GetType().GetMetaType());
- }
- }
-
- if (i->GetType().ToString() == "array") {
- return GetStringFromElementType(i->GetType());
- }
-
- return ConvertTypeToString(ParameterType::Direction::IN,
- i->GetType());
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "array") {
- std::string str;
- str += i->GetID();
- str += ", ";
- str += "int " + i->GetID() + "_size";
- return str;
- }
- return i->GetID();
- },
- [&]()->std::string {
- if ((i->GetType().IsUserDefinedType() ||
- i->GetType().ToString() == "string" ||
- i->GetType().ToString() == "bundle" ||
- i->GetType().ToString() == "file") ||
- ((i->GetType().ToString() == "list" ||
- i->GetType().ToString() == "array") &&
- (i->GetType().GetMetaType()->IsUserDefinedType() ||
- i->GetType().GetMetaType()->ToString() == "list" ||
- i->GetType().GetMetaType()->ToString() == "array" ||
- i->GetType().GetMetaType()->ToString() == "string" ||
- i->GetType().GetMetaType()->ToString() == "bundle" ||
- i->GetType().GetMetaType()->ToString() == "file")))
- return "!h || !" + i->GetID();
-
- return "!h";
- },
- [&]()->std::string {
- std::string str;
- str += NLine(1);
- str += GetSetterString(i->GetID(), i->GetType());
- return str;
- }));
+void CBodyGeneratorBase::GenStructureDefs(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructureDef(stream, st);
+ }
}
-}
-
-void CBodyGeneratorBase::GenStructureGetter(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() == "list")
- continue;
- stream << SmartIndent(GenTemplateString(CB_STRUCT_GETTER,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "array")
- return GetStringFromElementType(i->GetType()) + "*";
-
- return ConvertTypeToString(ParameterType::Direction::OUT,
- i->GetType());
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "array") {
- std::string str;
- str += i->GetID();
- str += ", ";
- str += "int *" + i->GetID() + "_size";
- return str;
- }
- return i->GetID();
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "array") {
- std::string str;
- str += "!";
- str += i->GetID();
- str += " || ";
- str += "!" + i->GetID() + "_size";
- return str;
- }
- return "!" + i->GetID();
- },
- [&]()->std::string {
- std::string str;
- str += NLine(1);
- str += GetGetterString(i->GetID(), i->GetType());
- return str;
- }));
+ for (auto& i : GetStructures()) {
+ auto& st = i.second;
+ GenStructureDef(stream, *st);
}
}
-void CBodyGeneratorBase::GenStructureIterator(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() != "list")
- continue;
-
- stream << SmartIndent(GenTemplateString(CB_STRUCT_ITERATOR,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().GetMetaType()->IsUserDefinedType() ||
- i->GetType().GetMetaType()->ToString() == "list" ||
- i->GetType().GetMetaType()->ToString() == "array")
- return GetParcelParamTypeString(*i->GetType().GetMetaType());
-
- return ConvertTypeToString(ParameterType::Direction::IN,
- *i->GetType().GetMetaType());
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- std::string str;
- str += NLine(1);
- str += GetIteratorString(i->GetID(), i->GetType());
- return str;
- }));
- }
+void CBodyGeneratorBase::GenStructureDef(std::ofstream& stream,
+ const Structure& st) {
+ if (st.GetID().compare(0, strlen("array"), "array") == 0)
+ GenStructureArrayDef(stream, st);
+ else if (st.GetID().compare(0, strlen("list"), "list") == 0)
+ GenStructureListDef(stream, st);
+ else
+ GenStructureBaseDef(stream, st);
+}
+
+// @see #CB_STRUCTURE_ARRAY_DEF
+void CBodyGeneratorBase::GenStructureArrayDef(std::ofstream& stream,
+ const Structure& st) {
+ auto& elm = *(st.GetElements().begin());
+ auto& type = elm->GetType();
+ auto element_type = GetDataTypeString(type, false);
+
+ ReplaceAll(CB_STRUCTURE_ARRAY_DEF, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", st.GetID() },
+ { "<ELEMENT_TYPE>", element_type }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_STRUCTURE_LIST_DEF
+void CBodyGeneratorBase::GenStructureListDef(std::ofstream& stream,
+ const Structure& st) {
+ ReplaceAll(CB_STRUCTURE_LIST_DEF, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", st.GetID() }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_STRUCTURE_BASE_DEF
+void CBodyGeneratorBase::GenStructureBaseDef(std::ofstream& stream,
+ const Structure& st) {
+ auto& elms = st.GetElements();
+ ReplaceAll(CB_STRUCTURE_BASE_DEF, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", st.GetID() },
+ { "<ELEMENTS>", GenBaseElements(elms) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
}
-void CBodyGeneratorBase::GenStructureRemover(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() != "list")
- continue;
+void CBodyGeneratorBase::GenStructures(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructure(stream, st);
+ }
+ }
- stream << SmartIndent(GenTemplateString(CB_STRUCT_REMOVER,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- if (i->GetType().GetMetaType()->IsUserDefinedType() ||
- i->GetType().GetMetaType()->ToString() == "list" ||
- i->GetType().GetMetaType()->ToString() == "array" ||
- i->GetType().GetMetaType()->ToString() == "string" ||
- i->GetType().GetMetaType()->ToString() == "bundle" ||
- i->GetType().GetMetaType()->ToString() == "file")
- return GetParcelParamTypeString(*i->GetType().GetMetaType());
-
- return ConvertTypeToString(ParameterType::Direction::IN,
- *i->GetType().GetMetaType(), false);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- std::string str;
-
- if (i->GetType().GetMetaType()->IsUserDefinedType() ||
- i->GetType().GetMetaType()->ToString() == "list" ||
- i->GetType().GetMetaType()->ToString() == "array") {
- str = GetHandlePrefix()
- + GetFullNameFromType(*i->GetType().GetMetaType())
- + "_destroy(value);";
- } else {
- str = GetFinalizeString("value", *i->GetType().GetMetaType(), "");
- }
-
- if (str == "")
- return "free(value);\n";
- return str;
- }));
+ for (auto& i : GetStructures()) {
+ auto& st = i.second;
+ GenStructure(stream, *st);
}
}
-void CBodyGeneratorBase::GenStructureLengthGetter(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() != "list")
- continue;
-
- stream << SmartIndent(GenTemplateString(CB_STRUCT_LENGTH_GETTER,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- }));
+void CBodyGeneratorBase::GenStructure(std::ofstream& stream,
+ const Structure& st) {
+ if (st.GetID().compare(0, strlen("array"), "array") == 0)
+ GenStructureArrayBase(stream, st);
+ else if (st.GetID().compare(0, strlen("list"), "list") == 0)
+ GenStructureListBase(stream, st);
+ else
+ GenStructureBase(stream, st);
+}
+
+// @see #CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_WRITE
+// @see #CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_WRITE
+// @see #CB_STRUCTURE_ARRAY_STRING_PARCEL_WRITE
+// @see #CB_STRUCTURE_ARRAY_BASE_PARCEL_WRITE
+std::string CBodyGeneratorBase::GenArrayParcelWrite(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = std::string(CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_WRITE);
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_WRITE);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_ARRAY_STRING_PARCEL_WRITE);
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_BASE_PARCEL_WRITE, "<PARCEL_TYPE>",
+ GetParcelType(type));
}
-}
-void CBodyGeneratorBase::GenStructureCloner(std::ofstream& stream,
- const Structure& st) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_STRUCT_CLONER, "##", GetStructIdWithNamespace(st)),
- [&]()->std::string {
- std::string str;
- for (auto& i : st.GetElements().GetElms()) {
- str += NLine(1);
- str += GetClonerString(i->GetID(), i->GetType(), st);
- }
- return str;
- }));
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetParcelTypeString(const BaseType& type,
- bool meta_type) {
- if (type.IsUserDefinedType())
- return "";
-
- if (type.ToString() == "list" ||
+// @see #CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_READ
+// @see #CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_READ
+// @see #CB_STRUCTURE_ARRAY_STRING_PARCEL_READ
+// @see #CB_STRUCTURE_ARRAY_BASE_PARCEL_READ
+std::string CBodyGeneratorBase::GenArrayParcelRead(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
type.ToString() == "array") {
- if (meta_type)
- return "";
- return "array_count";
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_READ);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_ARRAY_STRING_PARCEL_READ);
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_BASE_PARCEL_READ, "<PARCEL_TYPE>",
+ GetParcelType(type));
}
- return parcel_type_map_[type.ToString()];
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetParcelWriteFunctionString(
- const BaseType& type, bool meta_type) {
- std::string str = "rpc_port_parcel_write";
- std::string parcel_type = GetParcelTypeString(type, meta_type);
- if (parcel_type != "")
- str += "_" + parcel_type;
-
- return str;
-}
+// @see #CB_STRUCTURE_ARRAY_USER_DEFINED_FREE
+// @see #CB_STRUCTURE_ARRAY_BUNDLE_FREE
+// @see #CB_STRUCTURE_ARRAY_STRING_FREE
+// @see #CB_STRUCTURE_ARRAY_BASE_FREE
+std::string CBodyGeneratorBase::GenArrayElementsFree(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_USER_DEFINED_FREE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_ARRAY_BUNDLE_FREE);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_ARRAY_STRING_FREE);
+ } else {
+ code = std::string(CB_STRUCTURE_ARRAY_BASE_FREE);
+ }
-std::string CBodyGeneratorBase::GetParcelWriteString(const std::string& id,
- const BaseType& type) {
- std::string str;
- const char parcel[] = "$$(parcel, $$);";
- const char ternary_operation[] = "## ? ## : \"\"";
-
- str += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelWriteFunctionString(type);
- },
- [&]()->std::string {
- if (type.IsUserDefinedType())
- return "&h->" + id + "->parcelable, h->" + id;
- if (type.ToString() == "list")
- return "g_list_length(h->" + id + ")";
- if (type.ToString() == "array")
- return "h->" + id + "_size";
- if (type.ToString() == "string")
- return ReplaceAll(ternary_operation, "##", "h->" + id);
- return "h->" + id;
- });
-
- if (type.ToString() == "list") {
- str += GenTemplateString(CB_WRITE_LIST_BLOCK,
- [&]()->std::string {
- return "h->" + id;
- },
- [&]()->std::string {
- return GetParcelParamTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- return GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelWriteFunctionString(*type.GetMetaType(), true);
- },
- [&]()->std::string {
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array")
- return "&value->parcelable, value";
- if (type.GetMetaType()->ToString() == "bundle")
- return "value";
- if (type.GetMetaType()->ToString() == "string"
- || type.GetMetaType()->ToString() == "file")
- return ReplaceAll(ternary_operation, "##", "value");
- return "*value";
- });
- });
- } else if (type.ToString() == "array") {
- str += GenTemplateString(CB_WRITE_ARRAY_BLOCK,
- [&]()->std::string {
- return "h->" + id + "_size";
- },
- [&]()->std::string {
- return GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelWriteFunctionString(*type.GetMetaType(), true);
- },
- [&]()->std::string {
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array")
- return "&h->" + id + "[i]->parcelable, h->" + id +"[i]";
- if (type.GetMetaType()->ToString() == "string" ||
- type.GetMetaType()->ToString() == "file")
- return ReplaceAll(ternary_operation, "##", "h->" + id
- + "[i]");
- return "h->" + id + "[i]";
- });
- });
+ return RemoveLine(code);
+}
+
+// @see #CB_STRUCTURE_ARRAY_BASE
+void CBodyGeneratorBase::GenStructureArrayBase(std::ofstream& stream,
+ const Structure& st) {
+ auto& elm = *(st.GetElements().begin());
+ auto& type = elm->GetType();
+ auto param_type_in = GetParamTypeString(ParameterType::Direction::IN, type);
+ auto param_type_out = GetParamTypeString(ParameterType::Direction::OUT, type);
+ auto element_type = GetDataTypeString(type, false);
+ auto element_type_size = GetDataTypeString(type, false);
+ element_type_size = RemoveLastSpaces(element_type_size);
+
+ ReplaceAll(CB_STRUCTURE_ARRAY_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", st.GetID() },
+ { "<PARCEL_WRITE>", GenArrayParcelWrite(elm) },
+ { "<PARCEL_READ>", GenArrayParcelRead(elm) },
+ { "<PARAM_TYPE_IN>", param_type_in },
+ { "<PARAM_TYPE_OUT>", param_type_out },
+ { "<ELEMENT_TYPE>", element_type },
+ { "<ELEMENT_TYPE_SIZE>", element_type_size },
+ { "<ELEMENTS_FREE>", GenArrayElementsFree(elm) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_STRUCTURE_LIST_USER_DEFINED_FREE
+// @see #CB_STRUCTURE_LIST_BUNDLE_FREE
+// @see #CB_STRUCTURE_LIST_STRING_FREE
+// @see #CB_STRUCTURE_LIST_BASE_FREE
+std::string CBodyGeneratorBase::GenListDataFree(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_FREE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_FREE);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_FREE);
+ } else {
+ code = std::string(CB_STRUCTURE_LIST_BASE_FREE);
}
- return str;
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetParcelReadFunctionString(
- const BaseType& type, bool meta_type) {
- std::string str = "rpc_port_parcel_read";
- std::string parcel_type = GetParcelTypeString(type, meta_type);
- if (parcel_type != "")
- str += "_" + parcel_type;
+// @see #CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_WRITE
+// @see #CB_STRUCTURE_LIST_BUNDLE_PARCEL_WRITE
+// @see #CB_STRUCTURE_LIST_STRING_PARCEL_WRITE
+// @see #CB_STRUCTURE_LIST_BASE_PARCEL_WRITE
+std::string CBodyGeneratorBase::GenListParcelWrite(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = std::string(CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_WRITE);
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_PARCEL_WRITE);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_PARCEL_WRITE);
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_LIST_BASE_PARCEL_WRITE, "<PARCEL_TYPE>",
+ GetParcelType(type));
+ }
- return str;
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetParcelReadString(const std::string& id,
- const BaseType& type) {
- std::string str;
- const char parcel[] = "$$(parcel, $$);";
-
- if (type.ToString() == "list") {
- str += GenTemplateString(CB_READ_LIST_BLOCK,
- [&]()->std::string {
- return GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(type);
- },
- [&]()->std::string {
- return "&len";
- });
- },
- [&]()->std::string {
- return GetParcelParamTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- std::string s;
-
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array") {
- s += GetConstructorString(*type.GetMetaType(), "value");
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!value";
- },
- [&]()->std::string {
- std::string ss;
- ss += "_E(\"Failed to create handle\");" + NLine(1);
- ss += "return;";
- return ss;
- });
- s += NLine(1);
- s += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(*type.GetMetaType(), true);
- },
- [&]()->std::string {
- return "&value->parcelable, value";
- });
- } else if (type.GetMetaType()->ToString() == "string" ||
- type.GetMetaType()->ToString() == "bundle"||
- type.GetMetaType()->ToString() == "file") {
- s += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(*type.GetMetaType());
- },
- [&]()->std::string {
- return "&value";
- });
- } else {
- s += "value = calloc(1, sizeof(*value));" + NLine(1);
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!value";
- },
- [&]()->std::string {
- std::string ss;
- ss += "_E(\"Out of memory\");" + NLine(1);
- ss += "return;";
- return ss;
- });
- s += NLine(1);
- s += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(*type.GetMetaType());
- },
- [&]()->std::string {
- return "value";
- });
- }
-
- return s;
- },
- [&]()->std::string {
- return "h->" + id;
- },
- [&]()->std::string {
- return "h->" + id;
- });
- } else if (type.ToString() == "array") {
- str += GenTemplateString(ReplaceAll(CB_READ_ARRAY_BLOCK, "##", id),
- [&]()->std::string {
- return GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(type);
- },
- [&]()->std::string {
- return "&h->" + id + "_size";
- });
- },
- [&]()->std::string {
- return GetReturnTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- return GetErrorValue(*type.GetMetaType());
- },
- [&]()->std::string {
- std::string s;
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array") {
- s += GetConstructorString(*type.GetMetaType(), "value");
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!value";
- },
- [&]()->std::string {
- std::string ss;
- ss += "_E(\"Failed to create handle\");" + NLine(1);
- ss += "return;";
- return ss;
- });
- s += NLine(1);
- s += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(*type.GetMetaType(), true);
- },
- [&]()->std::string {
- return "&value->parcelable, value";
- });
- } else {
- s += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(*type.GetMetaType());
- },
- [&]()->std::string {
- return "&value";
- });
- }
- s += NLine(1);
- s += GetSetterString("h->" + id + "[i]", "value");
- return s;
- });
- } else if (type.IsUserDefinedType()) {
- str += GenTemplateString(ReplaceAll(CB_READ_USER_DEFINED_BLOCK, "##", id),
- [&]()->std::string {
- return GetFullNameFromType(type);
- });
+// @see #CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_READ
+// @see #CB_STRUCTURE_LIST_BUNDLE_PARCEL_READ
+// @see #CB_STRUCTURE_LIST_STRING_PARCEL_READ
+// @see #CB_STRUCTURE_LIST_BASE_PARCEL_READ
+std::string CBodyGeneratorBase::GenListParcelRead(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_PARCEL_READ);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_PARCEL_READ);
} else {
- str += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(type);
- },
- [&]()->std::string {
- if (type.IsUserDefinedType())
- return "&h->" + id + "->parcelable, h->" + id;
- return "&h->" + id;
- });
+ auto value_type = GetParamTypeString(ParameterType::Direction::IN, type);
+ value_type = RemoveLastSpaces(value_type);
+ code = ReplaceAll(CB_STRUCTURE_LIST_BASE_PARCEL_READ, "<VALUE_TYPE>",
+ value_type);
+ code = ReplaceAll(code, "<PARCEL_TYPE>", GetParcelType(type));
}
- return str;
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetFinalizeString(const std::string& id,
- const BaseType& type, const std::string& handle) {
- std::string str;
-
- if (!type.IsUserDefinedType() &&
- type.ToString() != "list" &&
- type.ToString() != "array" &&
- type.ToString() != "string" &&
- type.ToString() != "bundle" &&
- type.ToString() != "file")
- return str;
-
- if (type.ToString() == "list") {
- str += GenTemplateString(CB_FINALIZE_LIST_BLOCK,
- [&]()->std::string {
- return handle + id;
- },
- [&]()->std::string {
- return GetParcelParamTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- return GenTemplateString(CB_IF_STATEMENT,
- [&]()->std::string {
- return "value";
- },
- [&]()->std::string {
- return GetDestructorString(*type.GetMetaType(),
- "value", true) + NLine(1);
- });
- },
- [&]()->std::string {
- return handle + id;
- });
- } else if (type.ToString() == "array") {
- if (!type.GetMetaType()->IsUserDefinedType() &&
- type.GetMetaType()->ToString() != "list" &&
- type.GetMetaType()->ToString() != "array" &&
- type.GetMetaType()->ToString() != "string" &&
- type.GetMetaType()->ToString() != "bundle" &&
- type.GetMetaType()->ToString() != "file") {
- return GenTemplateString(CB_IF_STATEMENT,
- [&]()->std::string {
- return handle + id;
- },
- [&]()->std::string {
- return "free(" + handle + id + ");";
- });
- }
- str += GenTemplateString(CB_FINALIZE_ARRAY_BLOCK,
- [&]()->std::string {
- return handle + id + "_size";
- },
- [&]()->std::string {
- return GenTemplateString(CB_IF_STATEMENT,
- [&]()->std::string {
- return handle + id + "[i]";
- },
- [&]()->std::string {
- return GetDestructorString(*type.GetMetaType(),
- handle + id + "[i]", true) + NLine(1);
- });
- },
- [&]()->std::string {
- return handle + id;
- });
+// @see #CB_STRUCTURE_LIST_USER_DEFINED_ADD
+// @see #CB_STRUCTURE_LIST_BUNDLE_ADD
+// @see #CB_STRUCTURE_LIST_STRING_ADD
+// @see #CB_STRUCTURE_LIST_BASE_ADD
+std::string CBodyGeneratorBase::GenListAdd(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_ADD, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_ADD);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_ADD);
} else {
- str += GenTemplateString(CB_IF_STATEMENT,
- [&]()->std::string {
- return handle + id;
- },
- [&]()->std::string {
- return GetDestructorString(type, handle + id) + NLine(1);
- });
+ auto value_type = GetParamTypeString(ParameterType::Direction::IN, type);
+ code = ReplaceAll(CB_STRUCTURE_LIST_BASE_ADD, "<VALUE_TYPE>",
+ value_type);
}
- return str;
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetSetterString(const std::string& id,
- const BaseType& type) {
- std::string str;
-
+std::string CBodyGeneratorBase::GenListCallbackParamType(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
if (type.IsUserDefinedType() ||
- type.ToString() == "string" ||
+ type.ToString() == "list" ||
+ type.ToString() == "array"||
type.ToString() == "bundle" ||
- type.ToString() == "file") {
- str += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "h->" + id;
- },
- [&]()->std::string {
- std::string s;
- s += GetDestructorString(type, "h->" + id) + NLine(1);
- s += GetSetterString("h->" + id, "NULL");
- return s;
- });
- str += NLine(1);
-
- str += NLine(1);
- str += GetSetterString(type, "h->" + id, id);
- str += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!h->" + id;
- },
- [&]()->std::string {
- std::string s;
- s += "_E(\"Failed to duplicate data\");" + NLine(1);
- s += "return -1;";
- return s;
- });
- str += NLine(1);
- } else if (type.ToString() == "list") {
- str += GenTemplateString(CB_SETTER_LIST_BLOCK,
- [&]()->std::string {
- return GetParcelParamTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- std::string s;
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "string" ||
- type.GetMetaType()->ToString() == "bundle" ||
- type.GetMetaType()->ToString() == "file" ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array") {
- s += GetSetterString(*type.GetMetaType(), "value", id);
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!value";
- },
- [&]()->std::string {
- std::string s;
- s += "_E(\"Out of memory\");" + NLine(1);
- s += "return -1;";
- return s;
- });
- s += NLine(1);
- } else {
- s += "value = calloc(1, sizeof(*value));" + NLine(1);
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!value";
- },
- [&]()->std::string {
- std::string s;
- s += "_E(\"Out of memory\");" + NLine(1);
- s += "return -1;";
- return s;
- });
- s += NLine(1);
- s += GetSetterString("*value", id);
- }
- return s;
- },
- [&]()->std::string {
- return "h->" + id;
- },
- [&]()->std::string {
- return "h->" + id;
- });
- } else if (type.ToString() == "array") {
- str += GetFinalizeString(id, type, "h->") + NLine(1);
- str += GetSetterString("h->" + id, "NULL");
- str += NLine(1);
- str += GenTemplateString(ReplaceAll(CB_SETTER_ARRAY_BLOCK, "##", id),
- [&]()->std::string {
- return GetSetterString(*type.GetMetaType(),
- "h->" + id + "[i]", id + "[i]");
- });
- } else {
- str += GetSetterString(type, "h->" + id, id);
+ type.ToString() == "string" ||
+ type.ToString() == "file")
+ code = std::string("value");
+ else
+ code = std::string ("*value");
+
+ return code;
+}
+
+// @see #CB_STRUCTURE_LIST_BASE
+void CBodyGeneratorBase::GenStructureListBase(std::ofstream& stream,
+ const Structure& st) {
+ auto& elm = *(st.GetElements().begin());
+ auto& type = elm->GetType();
+ auto param_type = GetParamTypeString(ParameterType::Direction::IN, type);
+
+ ReplaceAll(CB_STRUCTURE_LIST_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", st.GetID() },
+ { "<DATA_TYPE>", GetDataTypeString(type, true) },
+ { "<DATA_FREE>", GenListDataFree(elm) },
+ { "<PARAM_TYPE_IN>", param_type },
+ { "<PARCEL_WRITE>", GenListParcelWrite(elm) },
+ { "<PARCEL_READ>", GenListParcelRead(elm) },
+ { "<LIST_ADD>", GenListAdd(elm) },
+ { "<CALLBACK_PARAM_TYPE>", GenListCallbackParamType(elm) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+std::string CBodyGeneratorBase::GenBaseElements(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ auto& type = elm->GetType();
+ auto param_type = GetDataTypeString(type, false);
+ code += param_type + elm->GetID() + ";";
+ code += NLine(1);
}
- return str;
+ return code;
}
-std::string CBodyGeneratorBase::GetGetterString(const std::string& id,
- const BaseType& type) {
- std::string str;
+// @see #CB_STRUCTURE_BASE_USER_DEFINED_FREE
+// @see #CB_STRUCTURE_BASE_BUNDLE_FREE
+// @see #CB_STRUCTURE_BASE_STRING_FREE
+std::string CBodyGeneratorBase::GenBaseElementFree(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_USER_DEFINED_FREE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+ code = ReplaceAll(code, "<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "bundle") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_FREE, "<ELEMENT_NAME>",
+ elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_STRING_FREE, "<ELEMENT_NAME>",
+ elm->GetID());
+ }
- if (type.ToString() == "array") {
- str += GenTemplateString(ReplaceAll(CB_GETTER_ARRAY_BLOCK, "##", id),
- [&]()->std::string {
- return GetSetterString(*type.GetMetaType(),
- "(*" + id + ")[i]", "h->" + id + "[i]");
- });
- } else {
- if (type.IsUserDefinedType() ||
- type.ToString() == "string" ||
- type.ToString() == "bundle" ||
- type.ToString() == "file") {
- str += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!h->" + id;
- },
- [&]()->std::string {
- std::string s;
- s += "_E(\"Invalid parameter: h->" + id + " is NULL\");" + NLine(1);
- s += "return -1;";
- return s;
- });
- str += NLine(1);
- str += NLine(1);
- }
+ return code;
+}
- if (type.IsUserDefinedType()) {
- str += GetHandlePrefix() + GetFullNameFromType(type) +
- "_clone(h->"+ id + ", " + id +");" + NLine(1);
- } else {
- str += GetSetterString(type, "*" + id, "h->" + id);
- }
+std::string CBodyGeneratorBase::GenBaseElementsFree(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms)
+ code += GenBaseElementFree(elm);
+ return RemoveLine(code);
+}
+
+// @see #CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_WRITE
+// @see #CB_STRUCTURE_BASE_BUNDLE_PARCEL_WRITE
+// @see #CB_STRUCTURE_BASE_STRING_PARCEL_WRITE
+// @see #CB_STRUCTURE_BASE_BASE_PARCEL_WRITE
+std::string CBodyGeneratorBase::GenBaseParcelWrite(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ std::string parcel_write_code;
+ auto& type = elm->GetType();
if (type.IsUserDefinedType() ||
- type.ToString() == "string" ||
- type.ToString() == "bundle" ||
- type.ToString() == "file") {
- str += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "*" + id + " == NULL";
- },
- [&]()->std::string {
- std::string s;
- s += "_E(\"Failed to duplicate " + id + "\");" + NLine(1);
- s += "return -1;";
- return s;
- });
- str += NLine(1);
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_WRITE, "<ELEMENT_NAME>",
+ elm->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_PARCEL_WRITE,
+ "<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_STRUCTURE_BASE_STRING_PARCEL_WRITE,
+ "<ELEMENT_NAME>", elm->GetID());
+ } else {
+ parcel_write_code = ReplaceAll(CB_STRUCTURE_BASE_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ELEMENT_NAME>",
+ elm->GetID());
}
+
+ code += parcel_write_code;
}
- return str;
-}
-std::string CBodyGeneratorBase::GetIteratorString(const std::string& id,
- const BaseType& type) {
- std::string str;
-
- str += GenTemplateString(CB_ITERATOR_BLOCK,
- [&]()->std::string {
- return "h->" + id;
- },
- [&]()->std::string {
- return GetParcelParamTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array" ||
- type.GetMetaType()->ToString() == "string" ||
- type.GetMetaType()->ToString() == "bundle" ||
- type.GetMetaType()->ToString() == "file")
- return "value";
-
- return "*value";
- });
-
- return str;
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetClonerString(const std::string& id,
- const BaseType& type,
- const Structure& st) {
- std::string str;
+// @see #CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_READ
+// @see #CB_STRUCTURE_BASE_BUNDLE_PARCEL_READ
+// @see #CB_STRUCTURE_BASE_STRING_PARCEL_READ
+// @see #CB_STRUCTURE_BASE_BASE_PARCEL_READ
+std::string CBodyGeneratorBase::GenBaseParcelRead(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ std::string parcel_read_code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_read_code = ReplaceAll(
+ CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>",
+ GetFullNameFromType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ELEMENT_NAME>",
+ elm->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_PARCEL_READ,
+ "<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ parcel_read_code = ReplaceAll(CB_STRUCTURE_BASE_STRING_PARCEL_READ,
+ "<ELEMENT_NAME>", elm->GetID());
+ } else {
+ parcel_read_code = ReplaceAll(CB_STRUCTURE_BASE_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ELEMENT_NAME>",
+ elm->GetID());
+ }
- if (type.IsUserDefinedType() ||
- type.ToString() == "string" ||
- type.ToString() == "bundle" ||
- type.ToString() == "file") {
- str += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "h->" + id;
- },
- [&]()->std::string {
- std::string s;
- s += GetSetterString(type, "handle->" + id, "h->" + id);
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!handle->" + id;
- },
- [&]()->std::string {
- std::string ss;
- ss += "_E(\"Failed to duplicate h->" + id + "\");" + NLine(1);
- ss += "rpc_port_" + GetStructIdWithNamespace(st)
- + "_destroy(handle);" + NLine(1);
- ss += "return -1;";
- return ss;
- });
- return s;
- });
- str += NLine(1);
- } else if (type.ToString() == "list") {
- str += GenTemplateString(CB_CLONER_LIST_BLOCK,
- [&]()->std::string {
- return "h->" + id;
- },
- [&]()->std::string {
- return GetParcelParamTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- return GetParcelParamTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- std::string s;
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array" ||
- type.GetMetaType()->ToString() == "string" ||
- type.GetMetaType()->ToString() == "bundle" ||
- type.GetMetaType()->ToString() == "file") {
- s += GetSetterString(*type.GetMetaType(),
- "new_value", "value");
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!new_value";
- },
- [&]()->std::string {
- std::string ss;
- ss += "_E(\"Failed to duplicate value\");" + NLine(1);
- ss += "rpc_port_" + GetStructIdWithNamespace(st)
- + "_destroy(handle);" + NLine(1);
- ss += "return -1;";
- return ss;
- });
- } else {
- s += "new_value = calloc(1, sizeof(*new_value));" + NLine(1);
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!new_value";
- },
- [&]()->std::string {
- std::string tmp;
- tmp += "_E(\"Out of memory\");" + NLine(1);
- tmp += "rpc_port_" + GetStructIdWithNamespace(st)
- + "_destroy(handle);" + NLine(1);
- tmp += "return -1;";
- return tmp;
- });
- s += NLine(1);
- s += GetSetterString(*type.GetMetaType(),
- "*new_value", "*value");
- }
- s += NLine(1);
- return s;
- },
- [&]()->std::string {
- return "handle->" + id;
- },
- [&]()->std::string {
- return "handle->" + id;
- });
- } else if (type.ToString() == "array") {
- str += GenTemplateString(ReplaceAll(CB_CLONER_ARRAY_BLOCK, "##", id),
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return GetSetterString(*type.GetMetaType(),
- "handle->" + id + "[i]", "h->" + id + "[i]");
- });
- } else {
- str += GetSetterString(type, "handle->" + id, "h->" + id);
+ code += parcel_read_code;
}
- return str;
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetDestructorString(const BaseType& type,
- const std::string& value,
- bool container_value) {
- std::string str;
-
+// @see #CB_STRUCTURE_BASE_USER_DEFINED_SET
+// @see #CB_STRUCTURE_BASE_BUNDLE_SET
+// @see #CB_STRUCTURE_BASE_STRING_SET
+// @see #CB_STRUCTURE_BASE_BASE_SET
+std::string CBodyGeneratorBase::GenBaseSet(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
if (type.IsUserDefinedType() ||
type.ToString() == "list" ||
type.ToString() == "array") {
- str += GetHandlePrefix() + GetFullNameFromType(type) +
- "_destroy(" + value + ");";
+ code = ReplaceAll(CB_STRUCTURE_BASE_USER_DEFINED_SET, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+
+ auto element_free_code = RemoveLine(GenBaseElementFree(elm));
+ code = ReplaceAll(code, "<ELEMENT_FREE>", element_free_code);
+ code = ReplaceAll(code, "<ELEMENT_NAME>", elm->GetID());
} else if (type.ToString() == "bundle") {
- str += "bundle_free(" + value + ");";
- } else if (type.ToString() == "string" || type.ToString() == "file" || container_value) {
- str += "free(" + value + ");";
+ auto element_free_code = RemoveLine(GenBaseElementFree(elm));
+ code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_SET, "<ELEMENT_FREE>",
+ element_free_code);
+ code = ReplaceAll(code, "<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ auto element_free_code = RemoveLine(GenBaseElementFree(elm));
+ code = ReplaceAll(CB_STRUCTURE_BASE_STRING_SET, "<ELEMENT_FREE>",
+ element_free_code);
+ code = ReplaceAll(code, "<ELEMENT_NAME>", elm->GetID());
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_BASE_BASE_SET, "<ELEMENT_NAME>",
+ elm->GetID());
}
- return str;
-}
-
-std::string CBodyGeneratorBase::GetConstructorString(const BaseType& type,
- const std::string& value) {
- std::string str;
- str += GetHandlePrefix() + GetFullNameFromType(type) +
- "_create(&" + value + ");" + NLine(1);
- return str;
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetSetterString(const BaseType& type,
- const std::string& lvalue,
- const std::string& rvalue) {
- std::string str;
-
+// @see #CB_STRUCTURE_BASE_USER_DEFINED_GET
+// @see #CB_STRUCTURE_BASE_BUNDLE_GET
+// @see #CB_STRUCTURE_BASE_STRING_GET
+// @see #CB_STRUCTURE_BASE_BASE_GET
+std::string CBodyGeneratorBase::GenBaseGet(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
if (type.IsUserDefinedType() ||
type.ToString() == "list" ||
type.ToString() == "array") {
- str += GetHandlePrefix() + GetFullNameFromType(type) +
- "_clone(" + rvalue + ", &" + lvalue +");" + NLine(1);
- } else if (type.ToString() == "string" || type.ToString() == "file") {
- str += lvalue + " = strdup(" + rvalue + ");" + NLine(1);
+ code = ReplaceAll(CB_STRUCTURE_BASE_USER_DEFINED_GET, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+ code = ReplaceAll(code, "<ELEMENT_NAME>", elm->GetID());
} else if (type.ToString() == "bundle") {
- str += lvalue + " = bundle_dup(" + rvalue + ");" + NLine(1);
+ code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_GET, "<ELEMENT_NAME>",
+ elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_STRING_GET, "<ELEMENT_NAME>",
+ elm->GetID());
} else {
- str += GetSetterString(lvalue, rvalue);
+ code = ReplaceAll(CB_STRUCTURE_BASE_BASE_GET, "<ELEMENT_NAME>",
+ elm->GetID());
}
- return str;
-}
+ return RemoveLine(code);
+}
+
+// @see #CB_STRUCTURE_BASE_SET_GET
+std::string CBodyGeneratorBase::GenBaseSetGet(const std::string& name,
+ const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ auto& type = elm->GetType();
+ auto param_type_in = GetParamTypeString(ParameterType::Direction::IN, type);
+ auto param_type_out = GetParamTypeString(ParameterType::Direction::OUT,
+ type);
+
+ std::string set_get_code(ReplaceAll(CB_STRUCTURE_BASE_SET_GET, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", name },
+ { "<ELEMENT_NAME>", elm->GetID() },
+ { "<PARAM_TYPE_IN>", param_type_in },
+ { "<PARAM_TYPE_OUT>", param_type_out },
+ { "<BASE_SET>", GenBaseSet(elm) },
+ { "<BASE_GET>", GenBaseGet(elm) }
+ }));
+
+ code += set_get_code;
+ }
-std::string CBodyGeneratorBase::GetSetterString(const std::string& lvalue,
- const std::string& rvalue) {
- std::string str;
- str += lvalue + " = " + rvalue + ";";
- return str;
+ return RemoveLine(code);
}
-void CBodyGeneratorBase::GenIncludeHeader(std::ofstream& stream) {
- std::string str;
- str += "#include \"";
- str += FileName.substr(0, FileName.length() - 2);
- str += ".h\"";
- stream << NLine(1);
- stream << str;
- stream << NLine(1);
-}
+// @see #CB_STRUCTURE_BASE
+void CBodyGeneratorBase::GenStructureBase(std::ofstream& stream,
+ const Structure& st) {
+ auto& elms = st.GetElements();
-void CBodyGeneratorBase::GenLogTag(std::ofstream& stream,
- const std::string& log_tag) {
- GenTemplate(CB_LOG_TAG, stream,
- [&]()->std::string {
- return log_tag;
- });
+ ReplaceAll(CB_STRUCTURE_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", st.GetID() },
+ { "<ELEMENTS_FREE>", GenBaseElementsFree(elms) },
+ { "<PARCEL_WRITE>", GenBaseParcelWrite(elms) },
+ { "<PARCEL_READ>", GenBaseParcelRead(elms) }
+ })
+ .Transform([&](std::string code) {
+ code += GenBaseSetGet(st.GetID(), elms);
+ return SmartIndent(code);
+ })
+ .Out(stream);
}
-void CBodyGeneratorBase::GenInterfaceEnumerations(std::ofstream& stream,
- const Interface& inf) {
- GenInterfaceMethodEnumeration(stream, inf);
- GenInterfaceDelegateEnumeration(stream, inf);
+const std::string& CBodyGeneratorBase::GetParcelType(const BaseType& type) {
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array")
+ return parcel_type_map_["none"];
+
+ return parcel_type_map_[type.ToString()];
}
-bool CBodyGeneratorBase::HasDelegate(const Interface& inf) const {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE) {
- return true;
+bool CBodyGeneratorBase::HasListFile(const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ if (IsProxy() && d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ for (const auto& p : d->GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ auto name = GetFullNameFromType(type, iface);
+ if (name == "list_file")
+ return true;
}
}
return false;
}
-void CBodyGeneratorBase::GenInterfaceDelegateEnumeration(
- std::ofstream& stream, const Interface& inf) {
- int count = 1;
+// @see #CB_PRIVATE_SHARING_LIST_SET
+void CBodyGeneratorBase::GenPrivateSharingListSet(std::ofstream& stream) {
+ bool has_list_file = false;
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*i);
+ has_list_file = HasListFile(iface);
+ if (has_list_file)
+ break;
+ }
- if (!HasDelegate(inf))
+ if (!has_list_file)
return;
- stream << SmartIndent(GenTemplateString(CB_DELEGATE_ENUM,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- std::string str;
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
- continue;
-
- str += GenTemplateString(CB_DELEGATE_ENUM_FORMAT,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return std::to_string(count++);
- });
- }
- return str;
- }));
-}
-
-void CBodyGeneratorBase::GenInterfaceMethodEnumeration(
- std::ofstream& stream, const Interface& inf) {
- stream << SmartIndent(GenTemplateString(CB_METHOD_ENUM,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- std::string str;
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
- continue;
- str += GenTemplateString(CB_METHOD_ENUM_FORMAT,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return i->GetID();
- });
- }
- return str;
- }));
-}
+ stream << SmartIndent(std::string(CB_PRIVATE_SHARING_LIST_SET));
+}
+
+// @see #CB_LIST_FILE_SET_PRIVATE_SHARING
+// @see #CB_ARRAY_FILE_SET_PRIVATE_SHARING
+// @see #CB_FILE_SET_PRIVATE_SHARING
+std::string CBodyGeneratorBase::GetPrivateSharingString(const BaseType& type,
+ const Interface& iface, const std::string& port, const std::string& arg) {
+ std::string code;
+ std::string name = GetFullNameFromType(type, iface);
+ if (name == "list_file") {
+ code = ReplaceAll(CB_LIST_FILE_SET_PRIVATE_SHARING, "<PORT>", port);
+ code = ReplaceAll(code, "<ARG>", arg);
+ } else if (name == "array_file") {
+ code = ReplaceAll(CB_ARRAY_FILE_SET_PRIVATE_SHARING, "<PORT>", port);
+ code = ReplaceAll(code, "<ARG>", arg);
+ } else if (name == "file") {
+ code = ReplaceAll(CB_FILE_SET_PRIVATE_SHARING, "<PORT>", port);
+ code = ReplaceAll(code, "<ARG>", arg);
+ }
-void CBodyGeneratorBase::GenLogDefinition(std::ofstream& stream) {
- stream << SmartIndent(CB_LOG_DEF);
+ return code;
}
} // namespace tidl
diff --git a/idlc/gen/c_body_gen_base.h b/idlc/gen/c_body_gen_base.h
index 7de8246..9e6f517 100644
--- a/idlc/gen/c_body_gen_base.h
+++ b/idlc/gen/c_body_gen_base.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,58 +30,50 @@ class CBodyGeneratorBase : public CGeneratorBase {
explicit CBodyGeneratorBase(std::shared_ptr<Document> doc);
virtual ~CBodyGeneratorBase() = default;
+ void GenStructureDefs(std::ofstream& stream);
void GenStructures(std::ofstream& stream);
void GenIncludeHeader(std::ofstream& stream);
void GenLogTag(std::ofstream& stream, const std::string& log_tag);
- void GenInterfaceEnumerations(std::ofstream& stream, const Interface& inf);
- std::string GetParcelWriteFunctionString(const BaseType& type,
- bool meta_type = false);
- std::string GetParcelReadFunctionString(const BaseType& type,
- bool meta_type = false);
- std::string GetDestructorString(const BaseType& type,
- const std::string& value,
- bool container_value = false);
- std::string GetConstructorString(const BaseType& type,
- const std::string& value);
- bool HasDelegate(const Interface& inf) const;
void GenLogDefinition(std::ofstream& stream);
+ void GenVersionDefinition(std::ofstream& stream);
+ void GenBaseDefinition(std::ofstream& stream);
+ const std::string& GetParcelType(const BaseType& type);
- private:
- void GenInterfaceMethodEnumeration(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceDelegateEnumeration(std::ofstream& stream,
- const Interface& inf);
+ void GenPrivateSharingListSet(std::ofstream& stream);
+ std::string GetPrivateSharingString(const BaseType& type,
+ const Interface& iface, const std::string& port, const std::string& arg);
private:
+ void GenStructureDef(std::ofstream& stream, const Structure& st);
+ void GenStructureBaseDef(std::ofstream& stream, const Structure& st);
+ void GenStructureArrayDef(std::ofstream& stream, const Structure& st);
+ void GenStructureListDef(std::ofstream& stream, const Structure& st);
+
void GenStructure(std::ofstream& stream, const Structure& st);
- void GenStructureDeclaration(std::ofstream& stream, const Structure& st);
- void GenStructureParcelSerializer(std::ofstream& stream, const Structure& st);
- void GenStructureParcelDeserializer(std::ofstream& stream,
- const Structure& st);
- void GenStructureConstructor(std::ofstream& stream, const Structure& st);
- void GenStructureDestructor(std::ofstream& stream, const Structure& st);
- void GenStructureSetter(std::ofstream& stream, const Structure& st);
- void GenStructureGetter(std::ofstream& stream, const Structure& st);
- void GenStructureIterator(std::ofstream& stream, const Structure& st);
- void GenStructureCloner(std::ofstream& stream, const Structure& st);
- void GenStructureRemover(std::ofstream& stream, const Structure& st);
- void GenStructureLengthGetter(std::ofstream& stream, const Structure& st);
+ void GenStructureBase(std::ofstream& stream, const Structure& st);
+ void GenStructureArrayBase(std::ofstream& stream, const Structure& st);
+ void GenStructureListBase(std::ofstream& stream, const Structure& st);
- private:
- std::string GetParcelTypeString(const BaseType& type, bool meta_type);
- std::string GetParcelWriteString(const std::string& id, const BaseType& type);
- std::string GetParcelReadString(const std::string& id, const BaseType& type);
- std::string GetFinalizeString(const std::string& id, const BaseType& type,
- const std::string& handle);
- std::string GetSetterString(const std::string& id, const BaseType& type);
- std::string GetGetterString(const std::string& id, const BaseType& type);
- std::string GetIteratorString(const std::string& id, const BaseType& type);
- std::string GetClonerString(const std::string& id, const BaseType& type,
- const Structure& st);
- std::string GetSetterString(const BaseType& type, const std::string& lvalue,
- const std::string& rvalue);
- std::string GetSetterString(const std::string& lvalue,
- const std::string& rvalue);
+ std::string GenArrayParcelWrite(const std::shared_ptr<Element>& elm);
+ std::string GenArrayParcelRead(const std::shared_ptr<Element>& elm);
+ std::string GenArrayElementsFree(const std::shared_ptr<Element>& elm);
+
+ std::string GenListDataFree(const std::shared_ptr<Element>& elm);
+ std::string GenListParcelWrite(const std::shared_ptr<Element>& elm);
+ std::string GenListParcelRead(const std::shared_ptr<Element>& elm);
+ std::string GenListAdd(const std::shared_ptr<Element>& elm);
+ std::string GenListCallbackParamType(const std::shared_ptr<Element>& elm);
+
+ std::string GenBaseElements(const Elements& elms);
+ std::string GenBaseElementFree(const std::shared_ptr<Element>& elm);
+ std::string GenBaseElementsFree(const Elements& elms);
+ std::string GenBaseParcelWrite(const Elements& elms);
+ std::string GenBaseParcelRead(const Elements& elms);
+ std::string GenBaseSetGet(const std::string& name, const Elements& elms);
+ std::string GenBaseSet(const std::shared_ptr<Element>& elm);
+ std::string GenBaseGet(const std::shared_ptr<Element>& elm);
+
+ bool HasListFile(const Interface& iface);
private:
std::map<std::string, std::string> parcel_type_map_;
diff --git a/idlc/gen/c_body_gen_base_cb.h b/idlc/gen/c_body_gen_base_cb.h
index a9d7ef1..acfe626 100644
--- a/idlc/gen/c_body_gen_base_cb.h
+++ b/idlc/gen/c_body_gen_base_cb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,457 +17,590 @@
#ifndef IDLC_C_GEN_C_BODY_GEN_BASE_CB_H_
#define IDLC_C_GEN_C_BODY_GEN_BASE_CB_H_
-const char CB_STRUCT_DECL[] =
+/**
+ * <LOG_TAG> The log tag.
+ */
+constexpr const char CB_LOG_TAG[] =
R"__c_cb(
-$$struct $$_s {
- rpc_port_parcelable_t parcelable;$$
-};
+#undef LOG_TAG
+#define LOG_TAG "<LOG_TAG>"
)__c_cb";
-const char CB_STRUCT_SERIALIZER[] =
+constexpr const char CB_LOG_DEF[] =
R"__c_cb(
-static void __##_to(rpc_port_parcel_h parcel, void *data)
-{
- rpc_port_##_h h = data;
+#undef _E
+#define _E(fmt, ...) dlog_print(DLOG_ERROR, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
- if (!parcel || !h) {
- _E("Invalid parameter");
- return;
- }
-$$
-}
+#undef _W
+#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _I
+#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _D
+#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
)__c_cb";
-const char CB_STRUCT_DESERIALIZER[] =
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
+constexpr const char CB_VERSION_DEF[] =
R"__c_cb(
-static void __##_from(rpc_port_parcel_h parcel, void *data)
-{
- rpc_port_##_h h = data;
+#ifndef TIDL_VERSION
+#define TIDL_VERSION "<VERSION>"
+#endif
+)__c_cb";
+
+constexpr const char CB_BASE_DEF[] =
+R"__c_cb(
+#ifndef nullptr
+#define nullptr NULL
+#endif
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
+#ifndef STRING_GET
+#define STRING_GET(x) ((x) ? x : "")
+#endif
+
+#ifndef EXPORT_API
+#define EXPORT_API extern "C" __attribute__ ((visibility("default")))
+#endif
- if (!parcel || !h) {
- _E("Invalid parameter");
- return;
- }
-$$
-}
)__c_cb";
-const char CB_STRUCT_CTOR[] =
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ELEMENTS> Elements of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_DEF[] =
R"__c_cb(
-int rpc_port_##_create(rpc_port_##_h *h)
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ <ELEMENTS>
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ELEMENTS_FREE> The implementation to release elements of the structure.
+ * <PARCEL_WRITE> The implementation to write the data to the parcel.
+ * <PARCEL_READ> The implementation to read the data from the parcel.
+ */
+constexpr const char CB_STRUCTURE_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
{
- struct ##_s *handle;
+ <PREFIX>_<NAME>_h h = data;
- if (!h) {
- _E("Invalid parameter");
- return -1;
- }
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
- handle = calloc(1, sizeof(struct ##_s));
- if (!handle) {
- _E("Out of memory");
- return -1;
- }
+ <PARCEL_WRITE>
+}
- handle->parcelable.to = __##_to;
- handle->parcelable.from = __##_from;
+static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
- *h = handle;
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
- return 0;
+ <PARCEL_READ>
+
+ set_last_result(RPC_PORT_ERROR_NONE);
}
-)__c_cb";
-const char CB_STRUCT_DTOR[] =
-R"__c_cb(
-int rpc_port_##_destroy(rpc_port_##_h h)
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h)
{
- if (!h) {
- _E("Invalid parameter");
- return -1;
- }
+ <PREFIX>_<NAME>_t *handle;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
-$$
- free(h);
+ handle->parcelable.to = __<PREFIX>_<NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_from;
- return 0;
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_STRUCT_SETTER[] =
-R"__c_cb(
-int rpc_port_$$_$$_$$(rpc_port_$$_h h, $$$$)
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
{
- if ($$) {
- _E("Invalid parameter");
- return -1;
- }
-$$
- return 0;
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ <ELEMENTS_FREE>
+
+ free(h);
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_STRUCT_GETTER[] =
-R"__c_cb(
-int rpc_port_$$_get_$$(rpc_port_$$_h h, $$$$)
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
{
- if (!h || $$) {
- _E("Invalid parameter");
- return -1;
- }
-$$
- return 0;
+ <PREFIX>_<NAME>_h handle;
+ rpc_port_parcel_h parcel;
+ int ret;
+
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_create(&handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ ret = rpc_port_parcel_create(&parcel);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ rpc_port_parcel_write(parcel, &h->parcelable, h);
+ rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+ ret = get_last_result();
+ rpc_port_parcel_destroy(parcel);
+
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ *clone = handle;
+
+ return RPC_PORT_ERROR_NONE;
}
)__c_cb";
-const char CB_STRUCT_ITERATOR[] =
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <PARAM_TYPE_IN> The type of the input paramter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * <BASE_SET> The implementation to set the data to the structure.
+ * <BASE_GET> The implementation to get the data from the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_SET_GET[] =
R"__c_cb(
-int rpc_port_$$_foreach_$$(rpc_port_$$_h h,
- bool (*callback)($$$$, void *user_data), void *user_data)
+int <PREFIX>_<NAME>_set_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value)
{
- if (!h || !callback) {
- _E("Invalid parameter");
- return -1;
- }
-$$
- return 0;
+ <BASE_SET>
}
-)__c_cb";
-const char CB_STRUCT_REMOVER[] =
-R"__c_cb(
-int rpc_port_$$_remove_$$(rpc_port_$$_h h, unsigned int nth)
+int <PREFIX>_<NAME>_get_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>value)
{
- GList *iter;
+ <BASE_GET>
+}
+)__c_cb";
- if (!h) {
- _E("Invalid parameter");
- return -1;
- }
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel, &h-><ELEMENT_NAME>->parcelable, h-><ELEMENT_NAME>);
+)__c_cb";
- iter = g_list_nth(h->$$, nth);
- if (iter == NULL)
- return -1;
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel, h-><ELEMENT_NAME>);
+)__c_cb";
- $$value = iter->data;
- h->$$ = g_list_remove_link(h->$$, iter);
-$$
- g_list_free(iter);
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel, STRING_GET(h-><ELEMENT_NAME>));
+)__c_cb";
- return 0;
-}
+/**
+ * <PARCEL_TYPE> The type of the parcel of the element.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel, h-><ELEMENT_NAME>);
)__c_cb";
-const char CB_STRUCT_LENGTH_GETTER[] =
+/**
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_READ[] =
R"__c_cb(
-int rpc_port_$$_get_$$_length(rpc_port_$$_h h, unsigned int *length)
-{
- if (!h || !length) {
- _E("Invalid parameter");
- return -1;
- }
+<PREFIX>_<NAME>_create(&h-><ELEMENT_NAME>);
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("Failed to create handle");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+}
- *length = g_list_length(h->$$);
+rpc_port_parcel_read(parcel, &h-><ELEMENT_NAME>->parcelable, h-><ELEMENT_NAME>);
+if (get_last_result() != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data");
+ return;
+}
+)__c_cb";
- return 0;
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_bundle(parcel, &h-><ELEMENT_NAME>);
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("Failed to read data");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
}
)__c_cb";
-const char CB_STRUCT_CLONER[] =
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_PARCEL_READ[] =
R"__c_cb(
-int rpc_port_##_clone(rpc_port_##_h h, rpc_port_##_h *clone)
-{
- rpc_port_##_h handle = NULL;
-
- if (!h || !clone) {
- _E("Invalid parameter");
- return -1;
- }
-
- rpc_port_##_create(&handle);
- if (!handle) {
- _E("Failed to create ## handle");
- return -1;
- }
-$$
- *clone = handle;
-
- return 0;
+rpc_port_parcel_read_string(parcel, &h-><ELEMENT_NAME>);
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("Failed to read data");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
}
)__c_cb";
-const char CB_WRITE_LIST_BLOCK[] =
+/**
+ * <PARCEL_TYPE> The type of the parcel of the element.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BASE_PARCEL_READ[] =
R"__c_cb(
-do {
- GList *iter;
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &h-><ELEMENT_NAME>);
+)__c_cb";
- iter = $$;
- while (iter) {
- $$value = iter->data;
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_FREE[] =
+R"__c_cb(
+if (h-><ELEMENT_NAME>)
+ <PREFIX>_<NAME>_destroy(h-><ELEMENT_NAME>);
+)__c_cb";
- iter = g_list_next(iter);
- if (!value) {
- _W("Warning: value is NULL");
- continue;
- }
- $$
- }
-} while (0);
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_FREE[] =
+R"__c_cb(
+if (h-><ELEMENT_NAME>)
+ bundle_free(h-><ELEMENT_NAME>);
)__c_cb";
-const char CB_WRITE_ARRAY_BLOCK[] =
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_FREE[] =
R"__c_cb(
-do {
- for (int i = 0; i < $$; i++) {
-$$
- }
-} while (0);
+if (h-><ELEMENT_NAME>)
+ free(h-><ELEMENT_NAME>);
)__c_cb";
-const char CB_READ_LIST_BLOCK[] =
-R"__c_cb(do {
- int len = 0;
+/**
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ * <ELEMENT_FREE> The implementation to release the element of the structure.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * @see #CB_STRUCTURE_BASE_USER_DEFINED_FREE
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_SET[] =
+R"__c_cb(
+<PREFIX>_<NAME>_h new_value;
+int ret;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+ret = <PREFIX>_<NAME>_clone(value, &new_value);
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ return ret;
+}
+
+<ELEMENT_FREE>
- $$
- for (int i = 0; i < len; i++) {
- $$value = NULL;
+h-><ELEMENT_NAME> = new_value;
- $$
- $$ = g_list_append($$, value);
- }
-} while (0);
+return RPC_PORT_ERROR_NONE;
)__c_cb";
-const char CB_READ_ARRAY_BLOCK[] =
+/**
+ * <ELEMENT_FREE> The implementation to release the element of the structure.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * @see #CB_STRUCTURE_BASE_BUNDLE_FREE
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_SET[] =
R"__c_cb(
-do {
- $$
+bundle *new_value;
- h->## = calloc(h->##_size, sizeof(*h->##));
- if (!h->##) {
- _E("Out of memory");
- return;
- }
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
- for (int i = 0; i < h->##_size; i++) {
- $$value = $$;
+new_value = bundle_dup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
- $$
- }
-} while (0);
-)__c_cb";
+<ELEMENT_FREE>
-const char CB_READ_USER_DEFINED_BLOCK[] =
-R"__c_cb(do {
- rpc_port_$$_create(&h->##);
- if (!h->##) {
- _E("Failed to create handle");
- return;
- }
+h-><ELEMENT_NAME> = new_value;
- rpc_port_parcel_read(parcel, &h->##->parcelable, h->##);
-} while (0);
+return RPC_PORT_ERROR_NONE;
)__c_cb";
-const char CB_FINALIZE_LIST_BLOCK[] =
+/**
+ * <ELEMENT_FREE> The implementation to release the element of the structure.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * @see #CB_STRUCTURE_BASE_STRING_FREE
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_SET[] =
R"__c_cb(
-do {
- GList *iter;
-
- iter = $$;
- while (iter) {
- $$value = iter->data;
- $$
- iter = g_list_next(iter);
- }
- g_list_free($$);
-} while (0);
-)__c_cb";
+char *new_value;
-const char CB_FINALIZE_ARRAY_BLOCK[] =
-R"__c_cb(
-do {
- for (int i = 0; i < $$; i++) {
- $$
- }
- free($$);
-} while (0);
-)__c_cb";
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
-const char CB_SETTER_LIST_BLOCK[] =
-R"__c_cb(
-do {
- $$value = NULL;
+new_value = strdup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
- $$
- $$ = g_list_append($$, value);
-} while (0);
-)__c_cb";
+<ELEMENT_FREE>
-const char CB_SETTER_ARRAY_BLOCK[] =
-R"__c_cb(
-do {
- h->## = calloc(##_size, sizeof(*##));
- if (!h->##) {
- _E("Out of memory");
- return -1;
- }
- h->##_size = ##_size;
-
- for (int i = 0; i < h->##_size; i++) {
- $$
- }
-} while (0);
+h-><ELEMENT_NAME> = new_value;
+
+return RPC_PORT_ERROR_NONE;
)__c_cb";
-const char CB_GETTER_ARRAY_BLOCK[] =
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BASE_SET[] =
R"__c_cb(
-do {
- if (h->##_size == 0) {
- _W("## is empty");
- break;
- }
-
- *## = calloc(h->##_size, sizeof(*h->##));
- if (!*##) {
- _E("Out of memory");
- return -1;
- }
- *##_size = h->##_size;
-
- for (int i = 0; i < h->##_size; i++) {
- $$
- }
-} while (0);
+if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+h-><ELEMENT_NAME> = value;
+
+return RPC_PORT_ERROR_NONE;
)__c_cb";
-const char CB_ITERATOR_BLOCK[] =
+/**
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_GET[] =
R"__c_cb(
-do {
- GList *iter;
+<PREFIX>_<NAME>_h new_value;
+int ret;
- iter = $$;
- while (iter) {
- $$value = iter->data;
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
- iter = g_list_next(iter);
- if (!value) {
- _W("Warning: value is NULL");
- continue;
- }
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("<ELEMENT_NAME> is nullptr");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
- bool ret = callback($$, user_data);
- if (!ret)
- break;
- }
-} while (0);
-)__c_cb";
+ret = <PREFIX>_<NAME>_clone(h-><ELEMENT_NAME>, &new_value);
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ return ret;
+}
-const char CB_CLONER_LIST_BLOCK[] =
-R"__c_cb(
-do {
- GList *iter;
-
- iter = $$;
- while (iter) {
- $$new_value;
- $$value = iter->data;
-
- if (!value) {
- _E("Error: value is NULL");
- rpc_port_$$_destroy(handle);
- return -1;
- }
+*value = new_value;
- $$
- $$ = g_list_append($$, new_value);
- iter = g_list_next(iter);
- }
-} while (0);
+return RPC_PORT_ERROR_NONE;
)__c_cb";
-const char CB_CLONER_ARRAY_BLOCK[] =
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_GET[] =
R"__c_cb(
-do {
- if (h->##_size == 0) {
- _W("## is empty");
- break;
- }
-
- handle->## = calloc(h->##_size, sizeof(*h->##));
- if (!handle->##) {
- _E("Out of memory");
- rpc_port_$$_destroy(handle);
- return -1;
- }
- handle->##_size = h->##_size;
-
- for (int i = 0; i < h->##_size; i++) {
- $$
- }
-} while (0);
-)__c_cb";
+bundle *new_value;
-const char CB_IF_STATEMENT_WITH_BRACES[] =
-R"__c_cb(if ($$) {
- $$
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
}
-)__c_cb";
-const char CB_IF_STATEMENT[] =
-R"__c_cb(if ($$)
- $$
-)__c_cb";
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("<ELEMENT_NAME> is nullptr");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
-const char CB_DELEGATE_ENUM_FORMAT[] = "\n$$_DELEGATE_$$ = $$,";
+new_value = bundle_dup(h-><ELEMENT_NAME>);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
-const char CB_DELEGATE_ENUM[] =
-R"__c_cb(
-enum $$_delegate_e {$$
-};
-)__c_cb";
+*value = new_value;
-const char CB_METHOD_ENUM_FORMAT[] = "\n$$_METHOD_$$,";
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
-const char CB_METHOD_ENUM[] =
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_GET[] =
R"__c_cb(
-enum $$_method_e {
- $$_METHOD_Result,
- $$_METHOD_Callback,$$
-};
+char *new_value;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("<ELEMENT_NAME> is nullptr");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = strdup(h-><ELEMENT_NAME>);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+*value = new_value;
+
+return RPC_PORT_ERROR_NONE;
)__c_cb";
-const char CB_LOG_TAG[] =
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BASE_GET[] =
R"__c_cb(
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+*value = h-><ELEMENT_NAME>;
-#define LOG_TAG "$$"
+return RPC_PORT_ERROR_NONE;
)__c_cb";
-const char CB_LOG_DEF[] =
+constexpr const char CB_PRIVATE_SHARING_LIST_SET[] =
R"__c_cb(
-#ifdef _E
-#undef _E
-#endif
+static int __rpc_port_set_private_sharing_list(rpc_port_h port, GList *list)
+{
+ const char **array_file;
+ const char *value;
+ guint size;
+ GList *iter;
+ int idx = 0;
+ int ret;
+
+ size = g_list_length(list);
+ if (size == 0) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
-#ifdef _W
-#undef _W
-#endif
+ array_file = calloc(size, sizeof(const char*));
+ if (array_file == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
-#ifdef _I
-#undef _I
-#endif
+ iter = list;
+ while (iter) {
+ value = iter->data;
+ array_file[idx++] = value;
+ iter = g_list_next(iter);
+ }
-#ifdef _D
-#undef _D
-#endif
+ ret = rpc_port_set_private_sharing_array(port, array_file, idx);
+ free(array_file);
-#define _E(fmt, ...) dlog_print(DLOG_ERROR, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
-#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
-#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
-#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+ return ret;
+}
+)__c_cb";
+
+/**
+ * <PORT> The rpc port handle.
+ * <ARG> The argument.
+ */
+constexpr const char CB_LIST_FILE_SET_PRIVATE_SHARING[] =
+R"__c_cb(
+__rpc_port_set_private_sharing_list(<PORT>, <ARG>->list);
+)__c_cb";
+
+/**
+ * <PORT> The rpc port handle.
+ * <ARG> The argument.
+ */
+constexpr const char CB_ARRAY_FILE_SET_PRIVATE_SHARING[] =
+R"__c_cb(
+rpc_port_set_private_sharing_array(<PORT>, (const char **)<ARG>->value, <ARG>->size);
+)__c_cb";
+
+/**
+ * <PORT> The rpc port handle.
+ * <ARG> The argument.
+ */
+constexpr const char CB_FILE_SET_PRIVATE_SHARING[] =
+R"__c_cb(
+rpc_port_set_private_sharing(<PORT>, <ARG>);
)__c_cb";
#endif // IDLC_C_GEN_C_BODY_GEN_BASE_CB_H_
diff --git a/idlc/gen/c_body_gen_list_base_cb.h b/idlc/gen/c_body_gen_list_base_cb.h
new file mode 100644
index 0000000..d0e5ddf
--- /dev/null
+++ b/idlc/gen/c_body_gen_list_base_cb.h
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_GEN_C_BODY_GEN_LIST_BASE_CB_H_
+#define IDLC_C_GEN_C_BODY_GEN_LIST_BASE_CB_H_
+
+/**
+ * <PREFIX> The prefix of the list structure.
+ * <NAME> The name of the list structure.
+ */
+constexpr const char CB_STRUCTURE_LIST_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ GList *list;
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the list structure.
+ * <NAME> The name of the list structure.
+ * <DATA_TYPE> The type of the data of the list.
+ * <DATA_FREE> The implementation to release the data of the list.
+ * <PARAM_TYPE_IN> The type of the parameter of the add function.
+ * <PARCEL_WRITE> The implementation to write the data to parcel.
+ * <PARCEL_READ> The implementation to read the data from the parcel.
+ * <LIST_ADD> The implementation to add the data to the list.
+ * <CALLBACK_PARAM_TYPE> The type of the parameter of the callback.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+ <DATA_TYPE>value;
+ GList *iter;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ rpc_port_parcel_write_array_count(parcel, g_list_length(h->list));
+
+ iter = h->list;
+ while (iter) {
+ value = iter->data;
+ iter = g_list_next(iter);
+ <PARCEL_WRITE>
+ }
+}
+
+static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+ <DATA_TYPE>value = nullptr;
+ int ret;
+ int len = 0;
+ int i;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ ret = rpc_port_parcel_read_array_count(parcel, &len);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read array count. error(%d)", ret);
+ set_last_result(ret);
+ return;
+ }
+
+ for (i = 0; i < len; ++i) {
+ <PARCEL_READ>
+ }
+
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_from;
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ <DATA_TYPE>value;
+ GList *iter;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (h->list) {
+ iter = h->list;
+ while (iter) {
+ value = iter->data;
+ iter = g_list_next(iter);
+ <DATA_FREE>
+ }
+
+ g_list_free(h->list);
+ }
+
+ free(h);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
+{
+ <PREFIX>_<NAME>_h handle;
+ rpc_port_parcel_h parcel;
+ int ret;
+
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_create(&handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ ret = rpc_port_parcel_create(&parcel);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ rpc_port_parcel_write(parcel, &h->parcelable, h);
+ rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+ ret = get_last_result();
+ rpc_port_parcel_destroy(parcel);
+
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ *clone = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_add(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value)
+{
+ <LIST_ADD>
+}
+
+int <PREFIX>_<NAME>_foreach(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_cb callback, void *user_data)
+{
+ <DATA_TYPE>value;
+ GList *iter;
+
+ if (h == nullptr || callback == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ iter = h->list;
+ while (iter) {
+ value = iter->data;
+ iter = g_list_next(iter);
+ if (!callback(<CALLBACK_PARAM_TYPE>, user_data))
+ break;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_remove(<PREFIX>_<NAME>_h h, unsigned int nth)
+{
+ <DATA_TYPE>value;
+ GList *found;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ found = g_list_nth(h->list, nth);
+ if (found == nullptr)
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+ value = found->data;
+ h->list = g_list_remove_link(h->list, found);
+ <DATA_FREE>
+ g_list_free(found);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_length(<PREFIX>_<NAME>_h h, unsigned int *length)
+{
+ if (h == nullptr || length == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *length = g_list_length(h->list);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel, &value->parcelable, value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel, value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel, STRING_GET(value));
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel of the value.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel, *value);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user-defined type.
+ * <NAME> The name of the user-defined type.
+ */
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+ret = <PREFIX>_<NAME>_create(&value);
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ set_last_result(ret);
+ return;
+}
+
+rpc_port_parcel_read(parcel, &value->parcelable, value);
+if (get_last_result() != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", get_last_result());
+ <PREFIX>_<NAME>_destroy(value);
+ return;
+}
+
+h->list = g_list_append(h->list, value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_bundle(parcel, &value);
+if (value == nullptr) {
+ _E("Failed to read data");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+h->list = g_list_append(h->list, value);
+value = nullptr;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_string(parcel, &value);
+if (value == nullptr) {
+ _E("Failed to read data");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+h->list = g_list_append(h->list, value);
+value = nullptr;
+)__c_cb";
+
+/**
+ * <VALUE_TYPE> The type of the value.
+ * <PARCEL_TYPE> The type of the parcel of the value.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE_PARCEL_READ[] =
+R"__c_cb(
+value = calloc(1, sizeof(sizeof(<VALUE_TYPE>)));
+if (value == nullptr) {
+ _E("Out of memory");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, value);
+
+h->list = g_list_append(h->list, value);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user-defined type.
+ * <NAME> The name of the user-defined type.
+ */
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_ADD[] =
+R"__c_cb(
+<PREFIX>_<NAME>_h new_value;
+int ret;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+ret = <PREFIX>_<NAME>_clone(value, &new_value);
+if (ret != RPC_PORT_ERROR_NONE)
+ return ret;
+
+h->list = g_list_append(h->list, new_value);
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_ADD[] =
+R"__c_cb(
+bundle *new_value;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = bundle_dup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+h->list = g_list_append(h->list, new_value);
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_ADD[] =
+R"__c_cb(
+char *new_value;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = strdup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+h->list = g_list_append(h->list, new_value);
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <VALUE_TYPE> The type of the value.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE_ADD[] =
+R"__c_cb(
+<VALUE_TYPE>*new_value;
+
+if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = calloc(1, sizeof(<VALUE_TYPE>));
+if (new_value == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+*new_value = value;
+
+h->list = g_list_append(h->list, new_value);
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user-defined type.
+ * <NAME> The name of the user-defined type.
+ */
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_FREE[] =
+R"__c_cb(
+<PREFIX>_<NAME>_destroy(value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_FREE[] =
+R"__c_cb(
+bundle_free(value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_FREE[] =
+R"__c_cb(
+free(value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BASE_FREE[] =
+R"__c_cb(
+free(value);
+)__c_cb";
+
+#endif // IDLC_C_GEN_C_BODY_GEN_LIST_BASE_CB_H_
diff --git a/idlc/gen/c_gen_base.cc b/idlc/gen/c_gen_base.cc
index b3fe325..b259c6d 100644
--- a/idlc/gen/c_gen_base.cc
+++ b/idlc/gen/c_gen_base.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,102 +14,161 @@
* limitations under the License.
*/
-#include <ctime>
+#include "idlc/gen/c_gen_base.h"
+
+#include <algorithm>
#include <cassert>
-#include <vector>
+#include <ctime>
#include <sstream>
-#include <algorithm>
+#include <utility>
+#include <vector>
-#include "idlc/gen/c_gen_base.h"
+#include "idlc/gen/c_gen_base_cb.h"
+namespace tidl {
namespace {
-#include "idlc/gen/c_gen_base_cb.h"
+
+constexpr const char PREFIX_RPC_PORT_PROXY[] = "rpc_port_proxy";
+constexpr const char PREFIX_RPC_PORT_STUB[] = "rpc_port_stub";
+
+Structure* CreateStructure(std::string type_name, BaseType* key_type,
+ BaseType* value_type) {
+ if (key_type == nullptr || value_type == nullptr)
+ return nullptr;
+
+ auto* elms = new Elements();
+ if (elms == nullptr)
+ return nullptr;
+
+ elms->Add(
+ std::shared_ptr<Element>(
+ new Element(key_type->GetFullName(true), key_type, "", __LINE__)));
+ elms->Add(
+ std::shared_ptr<Element>(
+ new Element(value_type->GetFullName(true), value_type, "", __LINE__)));
+
+ auto* st = new Structure(std::move(type_name), elms, new tidl::Enums(),
+ "", __LINE__);
+ if (st == nullptr) {
+ delete elms;
+ return nullptr;
+ }
+
+ return st;
}
-namespace tidl {
+Structure* CreateStructure(std::string type_name, BaseType* elm_type) {
+ if (elm_type == nullptr)
+ return nullptr;
+
+ auto* elms = new Elements();
+ if (elms == nullptr)
+ return nullptr;
+
+ elms->Add(
+ std::shared_ptr<Element>(
+ new Element(elm_type->GetFullName(true), elm_type, "", __LINE__)));
+
+ auto* st = new Structure(
+ std::move(type_name), elms, new tidl::Enums(), "", __LINE__);
+ if (st == nullptr) {
+ delete elms;
+ return nullptr;
+ }
+
+ return st;
+}
+
+} // namespace
CGeneratorBase::CGeneratorBase(std::shared_ptr<Document> doc)
: Generator(doc) {
structures_.clear();
type_map_ = {
- {"char", "char "}, {"int", "int "}, {"short", "short "},
- {"long", "long long "}, {"bool", "bool "}, {"string", "char *"},
- {"list", "GList *"}, {"float", "float "}, {"double", "double "},
- {"bundle", "bundle *"}, {"void", "void "}, {"file", "char *"}
+ {"char", "char "},
+ {"int", "int "},
+ {"short", "short "},
+ {"long", "long long "},
+ {"bool", "bool "},
+ {"string", "char *"},
+ {"list", "GList *"},
+ {"float", "float "},
+ {"double", "double "},
+ {"bundle", "bundle *"},
+ {"void", "void "},
+ {"file", "char *"}
};
}
std::string CGeneratorBase::Tab(int cnt) {
std::string str;
-
- for (int i = 0; i < cnt; ++i) {
+ for (int i = 0; i < cnt; ++i)
str += "\t";
- }
return str;
}
std::string CGeneratorBase::NLine(int cnt) {
std::string str;
-
- for (int i = 0; i < cnt; ++i) {
+ for (int i = 0; i < cnt; ++i)
str += "\n";
- }
return str;
}
-std::string CGeneratorBase::ConvertTypeToString(
- ParameterType::Direction direction, const BaseType& type, bool bconst) {
- if (type.IsUserDefinedType()) {
- if (direction == ParameterType::Direction::IN)
- return GetHandlePrefix() + type.ToString() + "_h ";
- else
- return GetHandlePrefix() + type.ToString() + "_h *";
- }
-
- if (type.ToString() == "array") {
- if (direction == ParameterType::Direction::IN) {
- return GetReturnTypeString(*type.GetMetaType()) + "*";
- } else {
- return GetReturnTypeString(*type.GetMetaType()) + "**";
- }
- }
-
- if (type.ToString() == "string" || type.ToString() == "file") {
- if (direction == ParameterType::Direction::IN) {
- if (!bconst)
- return "char *";
- return "const char *";
- } else
- return "char **";
- }
-
- if (direction == ParameterType::Direction::IN && bconst)
- return type_map_[type.ToString()];
-
- return type_map_[type.ToString()] + "*";
+std::string CGeneratorBase::GetFullNameFromType(const BaseType& type) {
+ std::string str = type.GetFullName(true);
+ return GetEnumTypeString(str);
}
-std::string CGeneratorBase::GetFullNameFromType(const BaseType& type) {
- std::string str = type.ToString();
+std::string CGeneratorBase::GetFullNameFromType(const BaseType& type,
+ const Interface& iface) {
+ std::string str;
+ if (IsDelegateType(iface, type))
+ str += iface.GetID() + "_";
+
+ str += type.ToString();
if (type.GetMetaType() != nullptr) {
str += "_";
- str += GetFullNameFromType(*type.GetMetaType());
+ str += GetFullNameFromType(*type.GetMetaType(), iface);
+ } else if (type.GetKeyType() != nullptr) {
+ str += "_";
+ str += GetFullNameFromType(*type.GetKeyType(), iface);
+ str += "_";
+ str += GetFullNameFromType(*type.GetValueType(), iface);
}
- return str;
+ return GetEnumTypeString(str);
}
-std::string CGeneratorBase::GetParcelParamTypeString(const BaseType& type,
- bool is_pointer) {
- if (type.IsUserDefinedType())
- return GetHandlePrefix() + type.ToString() + "_h ";
+std::string CGeneratorBase::GetDataTypeString(const BaseType& type,
+ bool is_pointer,
+ const std::string& id) {
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ auto n = type.ToString().find('.');
+ if (id.empty() && n == std::string::npos) {
+ if (is_pointer) {
+ return GetEnumTypeString(ParameterType::Direction::OUT, type,
+ GetEnumBockString(type.ToString()));
+ } else {
+ return GetEnumTypeString(ParameterType::Direction::IN, type,
+ GetEnumBockString(type.ToString()));
+ }
+ }
+
+ if (is_pointer)
+ return GetEnumTypeString(ParameterType::Direction::OUT, type, id);
+ else
+ return GetEnumTypeString(ParameterType::Direction::IN, type, id);
+ }
+
+ if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetUserDefinedType() == BaseType::UserType::DELEGATE)
+ return GetHandlePrefix() + "_" + type.ToString() + "_h ";
- if (type.ToString() == "list" ||
- type.ToString() == "array")
- return GetHandlePrefix() + GetFullNameFromType(type) + "_h ";
+ if (type.GetMetaType() != nullptr || type.GetKeyType() != nullptr)
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type) + "_h ";
if (type.ToString() == "string" || type.ToString() == "file")
return "char *";
@@ -123,42 +182,96 @@ std::string CGeneratorBase::GetParcelParamTypeString(const BaseType& type,
return type_map_[type.ToString()];
}
-std::string CGeneratorBase::GetReturnTypeString(const BaseType& type) {
- if (type.IsUserDefinedType())
- return GetHandlePrefix() + type.ToString() + "_h ";
+std::string CGeneratorBase::GetReturnTypeString(const BaseType& type,
+ const std::string& id) {
+
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
+ return GetEnumTypeString(ParameterType::Direction::IN, type, id);
+ else if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetUserDefinedType() == BaseType::UserType::DELEGATE)
+ return GetHandlePrefix() + "_" + type.ToString() + "_h ";
- if (type.ToString() == "list" ||
- type.ToString() == "array")
- return GetHandlePrefix() + GetFullNameFromType(type) + "_h ";
+ if (type.GetMetaType() != nullptr || type.GetKeyType() != nullptr)
+ return GetEnumTypeString(GetHandlePrefix() + "_" +
+ GetFullNameFromType(type) + "_h ");
return type_map_[type.ToString()];
}
void CGeneratorBase::AddStructureFromType(const BaseType& type) {
- if (type.GetMetaType() == nullptr)
+ auto* meta_type = type.GetMetaType();
+ auto* key_type = type.GetKeyType();
+ if (meta_type == nullptr && key_type == nullptr)
return;
- BaseType* t = new BaseType(type);
- assert(t != nullptr);
-
+ Structure* st;
std::string type_name = GetFullNameFromType(type);
- Element* elm = new Element(type_name + "s", t, "", __LINE__);
- assert(elm != nullptr);
+ if (meta_type != nullptr) {
+ AddStructureFromType(*meta_type);
+ st = CreateStructure(type_name, new BaseType(*meta_type));
+ } else {
+ AddStructureFromType(*key_type);
+ auto* value_type = type.GetValueType();
+ AddStructureFromType(*value_type);
+ st = CreateStructure(type_name, new BaseType(*key_type),
+ new BaseType(*value_type));
+ }
+ assert(st != nullptr);
+
+ if (StructureExist(st)) {
+ delete st;
+ return;
+ }
+
+ structures_[type_name] = std::unique_ptr<Structure>(st);
+}
- Elements* elms = new Elements();
- assert(elms != nullptr);
- elms->Add(elm);
+void CGeneratorBase::AddStructureFromType(const BaseType& type,
+ const Interface& iface) {
+ auto* meta_type = type.GetMetaType();
+ auto* key_type = type.GetKeyType();
+ if (meta_type == nullptr && key_type == nullptr)
+ return;
- Structure* st = new Structure(type_name, elms, "", __LINE__);
+ Structure* st;
+ std::string type_name = GetFullNameFromType(type, iface);
+ if (meta_type != nullptr) {
+ AddStructureFromType(*meta_type, iface);
+ st = CreateStructure(type_name, new BaseType(*meta_type));
+ } else {
+ AddStructureFromType(*key_type, iface);
+ auto* value_type = type.GetValueType();
+ AddStructureFromType(*value_type);
+ st = CreateStructure(type_name, new BaseType(*key_type),
+ new BaseType(*value_type));
+ }
assert(st != nullptr);
- if (StructureExist(*st)) {
+ if (StructureExist(st)) {
delete st;
- } else {
- structures_[type_name] = std::unique_ptr<Structure>(st);
+ return;
+ }
+
+ structures_[type_name] = std::unique_ptr<Structure>(st);
+}
+
+std::string CGeneratorBase::RemoveLine(std::string lines,
+ unsigned int line_num) {
+ std::stringstream ss(lines);
+ std::string result;
+ std::string line;
+ unsigned int line_count = 0;
+
+ while (std::getline(ss, line, '\n')) {
+ line_count++;
+ if (line_num == line_count)
+ continue;
+
+ result += Trim(line);
+ result += NLine(1);
}
- AddStructureFromType(*type.GetMetaType());
+ return result;
}
std::string CGeneratorBase::SmartIndent(std::string lines) {
@@ -175,6 +288,7 @@ std::string CGeneratorBase::SmartIndent(std::string lines) {
int line_count = 0;
while (std::getline(ss, next_line, '\n')) {
+ next_line = RemoveSpaces(next_line);
line_count++;
if (line_count == 1) {
line = Trim(next_line);
@@ -184,12 +298,16 @@ std::string CGeneratorBase::SmartIndent(std::string lines) {
tab.clear();
found = line.find('}');
if (found != std::string::npos) {
- tab_size--;
+ if (line.find('{') == std::string::npos)
+ tab_size--;
}
- if (line.length() > 0) {
+ back = "__INVALID__";
+ if (line.length() > 0)
+ back = line.back();
+
+ if (back != ":" && line.length() > 0)
tab += Tab(tab_size);
- }
if (continuous && tab_size == 0 &&
found == std::string::npos) {
@@ -202,13 +320,10 @@ std::string CGeneratorBase::SmartIndent(std::string lines) {
}
continuous = false;
- back = line.back();
- if (back == ",")
+ if (back == "," || back == "\\")
continuous = true;
- if (line.empty() ||
- line.length() == 0 ||
- std::all_of(line.begin(), line.end(), isspace)) {
+ if (line.empty() || std::all_of(line.begin(), line.end(), isspace)) {
std::string n_line = Trim(next_line);
if (n_line.empty() ||
n_line.length() == 0 ||
@@ -221,19 +336,43 @@ std::string CGeneratorBase::SmartIndent(std::string lines) {
result += NLine(1);
}
} else {
- result += tab + line;
+ // for annotation && ifdef
+ if (line.compare(0, 2, " *") == 0 || line.compare(0, 1, "#") == 0)
+ result += line;
+ else
+ result += tab + line;
+
result += NLine(1);
}
found = line.find('{');
if (found != std::string::npos) {
- tab_size++;
+ if (line.find('}') == std::string::npos)
+ tab_size++;
} else {
found = line.find("if (");
if (found != std::string::npos) {
tab_size++;
if_statement = true;
}
+
+ found = line.find("else");
+ if (found != std::string::npos && line != "#else") {
+ tab_size++;
+ if_statement = true;
+ }
+
+ found = line.find("for (");
+ if (found != std::string::npos) {
+ tab_size++;
+ if_statement = true;
+ }
+
+ found = line.find("while (");
+ if (found != std::string::npos && back != ";") {
+ tab_size++;
+ if_statement = true;
+ }
}
line = Trim(next_line);
@@ -245,7 +384,35 @@ std::string CGeneratorBase::SmartIndent(std::string lines) {
return result;
}
+std::string CGeneratorBase::RemoveLastSpaces(const std::string& str) {
+ std::size_t found = str.find_last_not_of(' ');
+ if (found == std::string::npos)
+ return str;
+
+ return str.substr(0, found + 1);
+}
+
+std::string CGeneratorBase::RemoveSpaces(const std::string& str) {
+ // for annotation
+ if (str.compare(0, 3, "/**") == 0 ||
+ str.compare(0, 2, " *") == 0 ||
+ str.compare(0, 3, " */") == 0)
+ return str;
+
+ std::size_t found = str.find_first_not_of(' ');
+ if (found == std::string::npos)
+ return "";
+
+ return str.substr(found, str.size() - found);
+}
+
std::string CGeneratorBase::Trim(const std::string& str) {
+ // for annotation
+ if (str.compare(0, 3, "/**") == 0 ||
+ str.compare(0, 2, " *") == 0 ||
+ str.compare(0, 3, " */") == 0)
+ return str;
+
std::size_t first = str.find_first_not_of(" \t\r\n");
if (first == std::string::npos)
return str;
@@ -255,10 +422,7 @@ std::string CGeneratorBase::Trim(const std::string& str) {
}
void CGeneratorBase::GenVersion(std::ofstream& stream) {
- GenTemplate(CB_VERSION, stream,
- [&]()->std::string {
- return FULLVER;
- });
+ stream << ReplaceAll(CB_VERSION, "<VERSION>", FULLVER);
}
void CGeneratorBase::GenIncludeDefaultHeaders(std::ofstream& stream,
@@ -271,34 +435,84 @@ void CGeneratorBase::GenIncludeDefaultHeaders(std::ofstream& stream,
}
void CGeneratorBase::GenGNUSourceDefinition(std::ofstream& stream) {
- stream << NLine(1);
- stream << CB_GNU_SOURCE;
+ stream << SmartIndent(CB_GNU_SOURCE);
}
-bool CGeneratorBase::StructureExist(const Structure& st) {
+bool CGeneratorBase::StructureExist(const Structure* st) {
for (auto& i : GetDocument().GetBlocks()) {
if (i->GetType() != Block::TYPE_STRUCTURE)
continue;
const Structure &s = static_cast<const Structure&>(*i);
- if (s.GetID() == st.GetID())
+ if (s.GetID() == st->GetID())
return true;
}
+
return false;
}
+std::string CGeneratorBase::GetEnumTypeString(const std::string& id) {
+ std::string block_id;
+ std::string type_id;
+
+ auto n = id.find('.');
+ if (n == std::string::npos)
+ return id;
+
+ block_id = id.substr(0, n);
+ type_id = id.substr(n + 1, id.size() - (n + 1));
+ return block_id + "_" + type_id;
+}
+
+std::string CGeneratorBase::GetEnumTypeString(
+ ParameterType::Direction direction, const BaseType& type,
+ const std::string& id) {
+ std::string block_id;
+ std::string type_id;
+
+ auto n = type.ToString().find('.');
+ if (n == std::string::npos) {
+ block_id = id;
+ type_id = GetFullNameFromType(type);
+ } else {
+ block_id = type.ToString().substr(0, n);
+ type_id = type.ToString().substr(n + 1, type.ToString().size() - (n + 1));
+ }
+
+ if (direction == ParameterType::Direction::IN)
+ return GetHandlePrefix() + "_" + block_id + "_" + type_id + "_e ";
+ else
+ return GetHandlePrefix() + "_" + block_id + "_" + type_id + "_e *";
+}
+
std::string CGeneratorBase::GetParamTypeString(
- ParameterType::Direction direction, const BaseType& type) {
+ ParameterType::Direction direction, const BaseType& type,
+ const std::string& id, bool internal) {
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ auto n = type.ToString().find('.');
+ if (id.empty()&& n == std::string::npos) {
+ return GetEnumTypeString(direction, type,
+ GetEnumBockString(type.ToString()));
+ } else {
+ return GetEnumTypeString(direction, type, id);
+ }
+ }
+
if (type.IsUserDefinedType() ||
- type.ToString() == "list" ||
- type.ToString() == "array") {
+ type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ std::string postfix;
if (direction == ParameterType::Direction::IN)
- return GetHandlePrefix() + GetFullNameFromType(type) + "_h ";
+ postfix = internal ? "_t *" : "_h ";
else
- return GetHandlePrefix() + GetFullNameFromType(type) + "_h *";
+ postfix = internal ? "_t **" : "_h *";
+
+ std::string ret = GetHandlePrefix() + "_" + GetFullNameFromType(type) +
+ postfix;
+ return GetEnumTypeString(ret);
}
- if (type.ToString() == "string") {
+ if (type.ToString() == "string" || type.ToString() == "file") {
if (direction == ParameterType::Direction::IN)
return "const char *";
else
@@ -311,14 +525,69 @@ std::string CGeneratorBase::GetParamTypeString(
return type_map_[type.ToString()] + "*";
}
-std::string CGeneratorBase::GetErrorValue(const BaseType& type) {
+std::string CGeneratorBase::GetParamTypeString(
+ ParameterType::Direction direction, const BaseType& type,
+ const Interface& iface) {
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
+ return GetEnumTypeString(direction, type, iface.GetID());
+
if (type.IsUserDefinedType() ||
- type.ToString() == "list" ||
- type.ToString() == "array" ||
+ type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ if (direction == ParameterType::Direction::IN) {
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type, iface) + "_h ";
+ } else {
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type, iface) +
+ "_h *";
+ }
+ }
+
+ if (type.ToString() == "string" || type.ToString() == "file") {
+ if (direction == ParameterType::Direction::IN)
+ return "const char *";
+ else
+ return "char **";
+ }
+
+ if (direction == ParameterType::Direction::IN)
+ return type_map_[type.ToString()];
+
+ return type_map_[type.ToString()] + "*";
+}
+
+std::string CGeneratorBase::GetEnumBockString(const std::string& id) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ for (auto& e : b->GetEnums()) {
+ if (e->GetID() == id) {
+ return b->GetID();
+ }
+ }
+ }
+ return {};
+}
+
+std::string CGeneratorBase::GetArgTypeString(const BaseType& type,
+ const Interface& iface) {
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
+ return GetEnumTypeString(ParameterType::Direction::IN, type, iface.GetID());
+
+ if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.GetMetaType() != nullptr || type.GetKeyType() != nullptr)
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type, iface) + "_h ";
+
+ return type_map_[type.ToString()];
+}
+
+std::string CGeneratorBase::GetErrorValue(const BaseType& type) {
+ if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr ||
type.ToString() == "bundle" ||
type.ToString() == "string"||
type.ToString() == "file")
- return "NULL";
+ return "nullptr";
if (type.ToString() == "bool")
return "false";
if (type.ToString() == "char")
@@ -326,31 +595,18 @@ std::string CGeneratorBase::GetErrorValue(const BaseType& type) {
return "-1";
}
-std::string CGeneratorBase::GetStringFromElementType(const BaseType& type) {
- if (type.IsUserDefinedType())
- return GetHandlePrefix() + type.ToString() + "_h ";
- if (type.ToString() == "array")
- return GetReturnTypeString(*type.GetMetaType()) + "*";
-
- return type_map_[type.ToString()];
-}
-
-std::string CGeneratorBase::GetStructIdWithNamespace(const Structure& st) {
+std::string CGeneratorBase::GetHandlePrefix() {
+ std::string prefix =
+ IsProxy() ? PREFIX_RPC_PORT_PROXY : PREFIX_RPC_PORT_STUB;
if (!HasNamespace())
- return st.GetID();
- return GetFileNamespace() + "_" + st.GetID();
-}
+ return prefix;
-std::string CGeneratorBase::GetInterfaceIdWithNamespace(const Interface& inf) {
- if (!HasNamespace())
- return inf.GetID();
- return GetFileNamespace() + "_" + inf.GetID();
+ return prefix + "_" + GetFileNamespace();
}
-std::string CGeneratorBase::GetHandlePrefix() {
- if (!HasNamespace())
- return "rpc_port_";
- return "rpc_port_" + GetFileNamespace() + "_";
+const std::map<std::string, std::unique_ptr<Structure>>&
+CGeneratorBase::GetStructures() {
+ return structures_;
}
} // namespace tidl
diff --git a/idlc/gen/c_gen_base.h b/idlc/gen/c_gen_base.h
index caec145..2920242 100644
--- a/idlc/gen/c_gen_base.h
+++ b/idlc/gen/c_gen_base.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,9 +17,9 @@
#ifndef IDLC_C_GEN_C_GEN_BASE_H_
#define IDLC_C_GEN_C_GEN_BASE_H_
+#include <map>
#include <memory>
#include <string>
-#include <map>
#include "idlc/ast/type.h"
#include "idlc/ast/structure.h"
@@ -32,34 +32,45 @@ class CGeneratorBase : public Generator {
explicit CGeneratorBase(std::shared_ptr<Document> doc);
virtual ~CGeneratorBase() = default;
- std::string Trim(const std::string& str);
+ std::string RemoveLine(std::string lines, unsigned int line_num = 1);
std::string SmartIndent(std::string lines);
- std::string Tab(int cnt);
std::string NLine(int cnt);
- std::string ConvertTypeToString(ParameterType::Direction direction,
- const BaseType& type, bool bconst = true);
+
std::string GetFullNameFromType(const BaseType& type);
- std::string GetParcelParamTypeString(const BaseType& type,
- bool is_pointer = true);
- std::string GetReturnTypeString(const BaseType& type);
+ std::string GetFullNameFromType(const BaseType& type, const Interface& iface);
+
+ std::string GetDataTypeString(const BaseType& type, bool is_pointer = true,
+ const std::string& id = std::string());
+ std::string GetReturnTypeString(const BaseType& type,
+ const std::string& id = std::string());
std::string GetParamTypeString(ParameterType::Direction direction,
- const BaseType& type);
- std::string GetStringFromElementType(const BaseType& type);
+ const BaseType& type, const std::string& id = std::string(),
+ bool internal = false);
+ std::string GetParamTypeString(ParameterType::Direction direction,
+ const BaseType& type, const Interface& iface);
+ std::string GetArgTypeString(const BaseType& type, const Interface& iface);
std::string GetErrorValue(const BaseType& type);
+ std::string GetEnumTypeString(const std::string& id);
+ std::string GetEnumBockString(const std::string& id);
+
void AddStructureFromType(const BaseType& type);
- const std::map<std::string, std::unique_ptr<Structure>>& GetStructures(void) {
- return structures_;
- }
+ void AddStructureFromType(const BaseType& type, const Interface& iface);
+
+ const std::map<std::string, std::unique_ptr<Structure>>& GetStructures();
void GenVersion(std::ofstream& stream);
- void GenIncludeDefaultHeaders(std::ofstream& stream, bool body = true);
+ virtual void GenIncludeDefaultHeaders(std::ofstream& stream, bool body = true);
void GenGNUSourceDefinition(std::ofstream& stream);
- std::string GetStructIdWithNamespace(const Structure& st);
- std::string GetInterfaceIdWithNamespace(const Interface& inf);
- std::string GetHandlePrefix();
+ virtual std::string GetHandlePrefix();
+ std::string RemoveLastSpaces(const std::string& str);
private:
- bool StructureExist(const Structure& st);
+ std::string Tab(int cnt);
+ std::string Trim(const std::string& str);
+ std::string RemoveSpaces(const std::string& str);
+ std::string GetEnumTypeString(ParameterType::Direction direction,
+ const BaseType& type, const std::string& id);
+ bool StructureExist(const Structure* st);
private:
std::map<std::string, std::unique_ptr<Structure>> structures_;
diff --git a/idlc/gen/c_gen_base_cb.h b/idlc/gen/c_gen_base_cb.h
index f258cb6..739c5e5 100644
--- a/idlc/gen/c_gen_base_cb.h
+++ b/idlc/gen/c_gen_base_cb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,27 +17,33 @@
#ifndef IDLC_C_GEN_C_GEN_BASE_CB_H_
#define IDLC_C_GEN_C_GEN_BASE_CB_H_
-const char CB_VERSION[] =
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
+constexpr const char CB_VERSION[] =
R"__c_cb(/*
- * Generated by tidlc $$.
+ * Generated by tidlc <VERSION>.
*/
)__c_cb";
-const char CB_GNU_SOURCE[] =
+constexpr const char CB_GNU_SOURCE[] =
R"__c_cb(
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
)__c_cb";
-const char CB_HEADER[] =
+constexpr const char CB_HEADER[] =
R"__c_cb(
#include <stdbool.h>
#include <bundle.h>
+#include <rpc-port.h>
)__c_cb";
-const char CB_BODY_HEADER[] =
+constexpr const char CB_BODY_HEADER[] =
R"__c_cb(
+#pragma GCC diagnostic ignored "-Warray-bounds"
+
#include <pthread.h>
#include <stdio.h>
#include <string.h>
diff --git a/idlc/gen/c_group_body_gen.cc b/idlc/gen/c_group_body_gen.cc
new file mode 100644
index 0000000..69b2ff9
--- /dev/null
+++ b/idlc/gen/c_group_body_gen.cc
@@ -0,0 +1,530 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+
+#include "idlc/gen/c_group_body_gen.h"
+
+namespace {
+#include "idlc/gen/c_group_body_gen_cb.h"
+
+constexpr const char PREFIX_RPC_PORT_GROUP[] = "rpc_port_group";
+}
+
+namespace tidl {
+
+CGroupBodyGen::CGroupBodyGen(std::shared_ptr<Document> doc)
+ : CBodyGeneratorBase(doc) {
+}
+
+void CGroupBodyGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenGNUSourceDefinition(stream);
+ GenIncludeDefaultHeaders(stream, true);
+ GenIncludeHeader(stream);
+ GenLogTag(stream, std::string("RPC_PORT_GROUP"));
+ GenLogDefinition(stream);
+ GenVersionDefinition(stream);
+ GenBaseDefinition(stream);
+ GenInterfaceMethodHandlerType(stream);
+ GenInterfaceEnums(stream);
+ GenStructureDefs(stream);
+ GenInterfaceDefs(stream);
+ GenHelper(stream);
+ GenStructures(stream);
+ GenInterfaces(stream);
+}
+
+void CGroupBodyGen::OnFiniGen(std::ofstream& stream) {
+}
+
+std::string CGroupBodyGen::GetHandlePrefix() {
+ std::string prefix = PREFIX_RPC_PORT_GROUP;
+ if (!HasNamespace())
+ return prefix;
+
+ return prefix + "_" + GetFileNamespace();
+}
+
+void CGroupBodyGen::GenIncludeDefaultHeaders(std::ofstream& stream, bool body) {
+ CGeneratorBase::GenIncludeDefaultHeaders(stream, body);
+ stream << CB_INTERFACE_EXTRA_HEADER;
+}
+
+void CGroupBodyGen::GenHelper(std::ofstream& stream) {
+ stream << SmartIndent(CB_HELPER);
+}
+
+void CGroupBodyGen::GenInterfaceDefs(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterfaceDef(stream, iface);
+ }
+}
+
+void CGroupBodyGen::GenInterfaceDef(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_BASE_DEF)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+void CGroupBodyGen::GenInterfaceEnums(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceEnum(stream, iface);
+ }
+}
+
+// @see #CB_INTERFACE_METHOD_ENUM
+std::string CGroupBodyGen::GenMethodEnums(const Interface& iface) {
+ std::string method_enum(ReplaceAll(CB_INTERFACE_METHOD_ENUM, {
+ { "<UPPERCASE_PREFIX>", GetHandlePrefix() },
+ { "<UPPERCASE_NAME>", iface.GetID() },
+ { "<UPPERCASE_METHOD_NAME>", "RESULT_" }
+ }));
+
+ std::string method_enums = RemoveLine(method_enum);
+
+ method_enum = ReplaceAll(CB_INTERFACE_METHOD_ENUM, {
+ { "<UPPERCASE_PREFIX>", GetHandlePrefix() },
+ { "<UPPERCASE_NAME>", iface.GetID() },
+ { "<UPPERCASE_METHOD_NAME>", "CALLBACK_" }
+ });
+
+ method_enums += RemoveLine(method_enum);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ method_enum = ReplaceAll(CB_INTERFACE_METHOD_ENUM, {
+ { "<UPPERCASE_PREFIX>", GetHandlePrefix() },
+ { "<UPPERCASE_NAME>", iface.GetID() },
+ { "<UPPERCASE_METHOD_NAME>", d->GetID() }
+ });
+
+ method_enums += RemoveLine(method_enum);
+ }
+ std::transform(method_enums.begin(), method_enums.end(), method_enums.begin(),
+ ::toupper);
+
+ return method_enums;
+}
+
+void CGroupBodyGen::GenInterfaceEnum(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_ENUMS>", GenMethodEnums(iface) }
+ })
+ .Transform([&](std::string str){
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+void CGroupBodyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CGroupBodyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ GenInterfaceMethodHandlerBase(stream, iface, *d);
+ }
+
+ GenInterfaceMethodTable(stream, iface);
+ GenInterfaceBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ GenInterfaceMethodBase(stream, iface, *d);
+ }
+}
+
+// @see #CB_INTERFACE_METHOD_TABLE
+void CGroupBodyGen::GenInterfaceMethodTable(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_METHOD_TABLE, {
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_HANDLERS>", GenMethodHandlers(iface) }
+ })
+ .Transform([&](std::string str){
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER
+std::string CGroupBodyGen::GenMethodHandlers(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_METHOD_" + d->GetID();
+ std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
+ ::toupper);
+
+ std::string method_handler(ReplaceAll(CB_INTERFACE_METHOD_HANDLER, {
+ { "<ENUM_VALUE>", enum_value },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", d->GetID() }
+ }));
+
+ code += RemoveLine(method_handler);
+ }
+
+ return code;
+}
+
+// @see #CB_INTERFACE_BASE
+void CGroupBodyGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+ ReplaceAll(CB_INTERFACE_BASE)
+ .Change("<PREFIX>", prefix)
+ .Change("<NAME>", name)
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_TYPE
+void CGroupBodyGen::GenInterfaceMethodHandlerType(std::ofstream& stream) {
+ stream << SmartIndent(CB_INTERFACE_METHOD_HANDLER_TYPE);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_BASE
+void CGroupBodyGen::GenInterfaceMethodHandlerBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_HANDLER_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_HANDLER_ARGS_DECL>", GenMethodHandlerArgsDecl(iface, decl) },
+ { "<METHOD_HANDLER_PARCEL_READ>",
+ GenMethodHandlerParcelRead(iface, decl) },
+ { "<METHOD_HANDLER_CALLBACK_INVOKE>",
+ GenMethodHandlerCallbackInvoke(decl) },
+ { "<METHOD_HANDLER_ARGS_FREE>", GenMethodHandlerArgsFree(iface, decl) }
+ })
+ .Transform([&](std::string str){
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_INVOKE
+std::string CGroupBodyGen::GenMethodHandlerCallbackInvoke(
+ const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_INVOKE,
+ "<METHOD_NAME>", decl.GetID()));
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC)
+ code = ReplaceAll(code, "<RES_SET>", "res_ = ");
+ else
+ code = ReplaceAll(code, "<RES_SET>", "");
+
+ std::string args;
+ bool first = true;
+ for (const auto& p : decl.GetParameters()) {
+ if (!first)
+ args += ", ";
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ args += "&";
+
+ args += p->GetID();
+ first = false;
+ }
+ code = ReplaceAll(code, "<METHOD_ARGS>", args);
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_READ
+std::string CGroupBodyGen::GenMethodHandlerParcelRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ std::string parcel_read_code;
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_read_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>",
+ GetFullNameFromType(type, iface));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
+ }
+
+ code += parcel_read_code;
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CGroupBodyGen::GenMethodHandlerArgsDecl(const Interface& iface,
+ const Declaration& decl) {
+ std::string args_decl;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ args_decl += GetArgTypeString(type, iface) + p->GetID() + " = " +
+ GetErrorValue(type) + ";" + NLine(1);
+ }
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
+ args_decl += "rpc_port_parcel_h parcel_;" + NLine(1);
+ args_decl += GetArgTypeString(decl.GetType(), iface) + "res_ = " +
+ GetErrorValue(decl.GetType()) + ";" + NLine(1);
+ }
+
+ return args_decl;
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_FREE
+// @see #CB_INTERFACE_METHOD_BUNDLE_FREE
+// @see #CB_INTERFACE_METHOD_STRING_FREE
+std::string CGroupBodyGen::GenMethodHandlerArgsFree(const Interface& iface,
+ const Declaration& decl) {
+ std::string free_code;
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.ToString() == "bundle") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE,
+ "<ARG>", p->GetID());
+ } else {
+ free_code.clear();
+ }
+
+ code += free_code;
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CGroupBodyGen::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_WRITE
+std::string CGroupBodyGen::GenMethodParcelWrite(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+
+ std::string parcel_write_code;
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE, "<ARG>",
+ p->GetID());
+ std::string name = GetFullNameFromType(type, iface);
+ parcel_write_code += GetPrivateSharingString(type, iface, "h->port",
+ p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ parcel_write_code += GetPrivateSharingString(type, iface, "h->port",
+ p->GetID());
+ } else {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ARG>",
+ p->GetID());
+ }
+
+ code += parcel_write_code;
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CGroupBodyGen::GenMethodParamsCheck(const Interface& iface,
+ const Declaration& decl) {
+ std::string params_check;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array" ||
+ type.ToString() == "bundle" ||
+ type.ToString() == "string" ||
+ type.ToString() == "file")
+ params_check += " || " + p->GetID() + " == nullptr";
+ }
+
+ return params_check;
+}
+
+// @see #CB_INTERFACE_METHOD_ASYNC_BASE
+std::string CGroupBodyGen::GenMethodAsyncBase(const Interface& iface,
+ const Declaration& decl) {
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+ std::string method_name = decl.GetID();
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_ASYNC_BASE)
+ .Change("<PREFIX>", prefix)
+ .Change("<NAME>", name)
+ .Change("<METHOD_NAME>", method_name)
+ .Change("<METHOD_PARAMS>", GenMethodParams(iface, decl))
+ .Change("<METHOD_PARAMS_CHECK>", GenMethodParamsCheck(iface, decl))
+ .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
+ .ChangeToUpper("<UPPERCASE_NAME>", name)
+ .ChangeToUpper("<UPPERCASE_METHOD_NAME>", method_name)
+ .Change("<METHOD_PARCEL_WRITE>", GenMethodParcelWrite(iface, decl)));
+
+ return code;
+}
+
+std::string CGroupBodyGen::GenMethodArgs(const Interface& iface,
+ const Declaration& decl) {
+ std::string args_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ args_code += GetReturnTypeString(type) + "new_" + p->GetID() + ";";
+ args_code += NLine(1);
+ }
+
+ return args_code;
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_READ
+std::string CGroupBodyGen::GenMethodParcelReadBase(const Interface& iface,
+ const BaseType& type, const std::string& param_name) {
+ std::string parcel_read_code;
+
+ if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ,
+ "<ARG>", param_name);
+ } else if (type.ToString() == "string") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_READ,
+ "<ARG>", param_name);
+ } else {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>",
+ param_name);
+ }
+
+ return parcel_read_code;
+}
+
+// @see #CB_INTERFACE_METHOD_VALUE_SET
+std::string CGroupBodyGen::GenMethodParcelRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ std::string parcel_read_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ code += GenMethodParcelReadBase(iface, type, "new_" + p->GetID());
+ code += ReplaceAll(CB_INTERFACE_METHOD_PARAM_SET, "<PARAM>",
+ p->GetID());
+ }
+
+ // Return Value
+ auto& base_type = decl.GetType();
+ code += GenMethodParcelReadBase(iface, base_type, "ret_");
+ return RemoveLine(code);
+}
+
+void CGroupBodyGen::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code = GenMethodAsyncBase(iface, decl);
+ stream << SmartIndent(code);
+}
+
+} // namespace tidl
diff --git a/idlc/gen/c_group_body_gen.h b/idlc/gen/c_group_body_gen.h
new file mode 100644
index 0000000..18f0473
--- /dev/null
+++ b/idlc/gen/c_group_body_gen.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_C_GROUP_BODY_GEN_H_
+#define IDLC_GEN_C_GROUP_BODY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/c_body_gen_base.h"
+#include "idlc/options.h"
+
+namespace tidl {
+
+class CGroupBodyGen : public CBodyGeneratorBase {
+ public:
+ explicit CGroupBodyGen(std::shared_ptr<Document> doc);
+ virtual ~CGroupBodyGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+ std::string GetHandlePrefix() override;
+ void GenIncludeDefaultHeaders(std::ofstream& stream, bool body) override;
+
+ private:
+ void GenInterfaceDefs(std::ofstream& stream);
+ void GenInterfaceDef(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodHandlerType(std::ofstream& stream);
+ void GenInterfaceMethodHandlerBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl);
+ std::string GenMethodHandlerArgsDecl(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlerArgsFree(const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceMethodTable(std::ofstream& stream,
+ const Interface& iface);
+ std::string GenMethodHandlerCallbackInvoke(const Declaration& decl);
+ std::string GenMethodHandlerParcelRead(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlers(const Interface& iface);
+ std::string GenMethodEnums(const Interface& iface);
+ void GenInterfaceEnums(std::ofstream& stream);
+ void GenInterfaceEnum(std::ofstream& stream, const Interface& iface);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodEnumBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+
+ std::string GenMethodAsyncBase(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+ bool GenMethodParamsFileCheck(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodParcelWrite(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodArgs(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParcelReadBase(const Interface& iface,
+ const BaseType& type, const std::string& param_name);
+ std::string GenMethodParcelRead(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodParamsCheck(const Interface& iface, const Declaration& decl);
+ void GenHelper(std::ofstream& stream);
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_C_GROUP_BODY_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen/c_group_body_gen_cb.h b/idlc/gen/c_group_body_gen_cb.h
new file mode 100644
index 0000000..4bbd540
--- /dev/null
+++ b/idlc/gen/c_group_body_gen_cb.h
@@ -0,0 +1,581 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_C_GROUP_BODY_GEN_CB_H_
+#define IDLC_GEN_C_GROUP_BODY_GEN_CB_H_
+
+
+constexpr const char CB_INTERFACE_METHOD_HANDLER_TYPE[] =
+R"__c_cb(
+typedef int (*rpc_port_group_method_handler)(rpc_port_parcel_h parcel, void *data);
+)__c_cb";
+
+/**
+ * <METHOD_ENUMS> The enumeration declarations of methods.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM_BASE[] =
+R"__c_cb(
+typedef enum {
+ <METHOD_ENUMS>
+} <PREFIX>_<NAME>_method_e;
+)__c_cb";
+
+
+/**
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM[] =
+R"__c_cb(
+<UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>,
+)__c_cb";
+
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ int id;
+ int seq_id;
+ bool once;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback;
+ void *user_data;
+} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
+)__c_cb";
+
+/**
+ * <ENUM_VALUE> The enumeration value.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_TABLE_MEMBER[] =
+R"__c_cb(
+[<ENUM_VALUE>] = __<PREFIX>_<NAME>_<DELEGATE_NAME>_delegate_handler,
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ <PREFIX>_<NAME>_callback_s callback;
+ event_handler_h event_handler;
+ char *sender_appid;
+ bool is_system;
+ GRecMutex mutex;
+ void *user_data;
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_HANDLER_ARGS_DECL> The declarations for arguments of the method.
+ * <METHOD_HANDLER_PARCEL_READ> The implementation to read the parameter from the parcel.
+ * <METHOD_HANDLER_CALLBACK_INVOKE> The implementation to invoke the callback function of the method.
+ * <METHOD_HANDLER_PARCEL_WRITE> The implementation to write the result to the parcel.
+ * <METHOD_HANDLER_ARGS_FREE> The implementation to release arguments.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER_BASE[] =
+R"__c_cb(
+static int __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler(rpc_port_parcel_h parcel, void *user_data)
+{
+ <PREFIX>_<NAME>_t *h = user_data;
+ int ret_ = RPC_PORT_ERROR_NONE;
+
+ <METHOD_HANDLER_ARGS_DECL>
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ ret_ = RPC_PORT_ERROR_INVALID_PARAMETER;
+ goto out;
+ }
+ <METHOD_HANDLER_PARCEL_READ>
+ <METHOD_HANDLER_CALLBACK_INVOKE>
+
+ out:
+ <METHOD_HANDLER_ARGS_FREE>
+ return ret_;
+}
+)__c_cb";
+
+constexpr const char CB_HELPER[] =
+R"__c_cb(
+static rpc_port_parcel_h __get_parcel_from_bundle(bundle *b)
+{
+ void *raw = nullptr;
+ size_t size = 0;
+ rpc_port_parcel_h p;
+
+ int ret = bundle_get_byte(b, "TIDL_RAW", &raw, &size);
+ if (ret != BUNDLE_ERROR_NONE)
+ return nullptr;
+
+ ret = rpc_port_parcel_create_from_raw(&p, raw, (unsigned int)size);
+ if (ret != RPC_PORT_ERROR_NONE)
+ return nullptr;
+
+ return p;
+}
+
+static bundle *__get_bundle_from_parcel(rpc_port_parcel_h p, bundle* b)
+{
+ void *raw = nullptr;
+ unsigned int size = 0;
+
+ int ret = rpc_port_parcel_get_raw(p, &raw, &size);
+ if (ret != RPC_PORT_ERROR_NONE)
+ return nullptr;
+
+ ret = bundle_add_byte(b, "TIDL_RAW", raw, size);
+ if (ret != BUNDLE_ERROR_NONE)
+ return nullptr;
+
+ return b;
+}
+
+static char *__get_event_name(const char *appid, bool is_system, const char *iface_name)
+{
+ size_t size;
+ char *buf;
+
+ if (is_system) {
+ size = strlen("tizen.system.event.tidl_iface_") + strlen(iface_name) + 1;
+ buf = calloc(1, size);
+ if (!buf)
+ return nullptr;
+ snprintf(buf, size, "tizen.system.event.tidl_iface_%s", iface_name);
+ return buf;
+ }
+
+ size = strlen(appid) + strlen(iface_name) + 19;
+ buf = calloc(1, size);
+ if (!buf)
+ return nullptr;
+ snprintf(buf, size, "event.%s.tidl_iface_%s", appid, iface_name);
+ return buf;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+
+static void __<NAME>_event_system_cb(const char *event_name, bundle *event_data, void *user_data)
+{
+ <PREFIX>_<NAME>_t *handle = (<PREFIX>_<NAME>_t *)(user_data);
+ rpc_port_parcel_h p = __get_parcel_from_bundle(event_data);
+ if (p == nullptr) {
+ _E("Invalid bundle");
+ return;
+ }
+
+ rpc_port_parcel_h header;
+ int seq_num = -1;
+ int cmd;
+ rpc_port_parcel_get_header(p, &header);
+ rpc_port_parcel_header_get_seq_num(header, &seq_num);
+
+ rpc_port_parcel_read_int32(p, &cmd);
+
+ static const int table_size = ARRAY_SIZE(__<NAME>_method_table);
+ if (cmd > 1 && cmd < table_size) {
+ if (__<NAME>_method_table[cmd])
+ __<NAME>_method_table[cmd](p, handle);
+ } else {
+ _W("Invalid protocol. cmd(%d)", cmd);
+ }
+
+ rpc_port_parcel_destroy(p);
+}
+
+int <PREFIX>_<NAME>_create(const char *sender_appid, <PREFIX>_<NAME>_callback_s *callback, void *user_data, bool is_system, <PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+ int ret;
+ char *ev_name;
+
+ if (sender_appid == nullptr || callback == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ev_name = __get_event_name(sender_appid, is_system, "<NAME>");
+ if (ev_name == nullptr) {
+ free(handle);
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = event_add_event_handler(ev_name, __<NAME>_event_system_cb, handle, &handle->event_handler);
+ free(ev_name);
+
+ if (ret != EVENT_ERROR_NONE) {
+ _E("Failed to register events. result(%d)", ret);
+ free(handle);
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle->sender_appid = strdup(sender_appid);
+ if (handle->sender_appid == nullptr) {
+ _E("Out of memory");
+ event_remove_event_handler(handle->event_handler);
+ free(handle);
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ g_rec_mutex_init(&handle->mutex);
+ handle->callback = *callback;
+ handle->user_data = user_data;
+ handle->is_system = is_system;
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_create_for_sender(const char *sender_appid, bool is_system, <PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+
+ if (h == nullptr || sender_appid == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->sender_appid = strdup(sender_appid);
+ if (handle->sender_appid == nullptr) {
+ _E("Out of memory");
+ free(handle);
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ g_rec_mutex_init(&handle->mutex);
+ handle->is_system = is_system;
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ g_rec_mutex_unlock(&h->mutex);
+ g_rec_mutex_clear(&h->mutex);
+
+ if (h->event_handler)
+ event_remove_event_handler(h->event_handler);
+ if (h->sender_appid)
+ free(h->sender_appid);
+
+ free(h);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_PARAMS> The parameters of the method of the interface
+ * <METHOD_PARAMS_CHECK> The parameters check of the method.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ * <METHOD_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ */
+constexpr const char CB_INTERFACE_METHOD_ASYNC_BASE[] =
+R"__c_cb(
+void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
+{
+ rpc_port_parcel_h parcel_;
+ rpc_port_parcel_header_h header_;
+ int seq_num_ = -1;
+ int res_;
+ bundle* b;
+
+ if (h == nullptr<METHOD_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ res_ = rpc_port_parcel_create(&parcel_);
+ if (res_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", res_);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(res_);
+ return;
+ }
+
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+
+ rpc_port_parcel_write_int32(parcel_, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
+
+ <METHOD_PARCEL_WRITE>
+ b = bundle_create();
+ if (__get_bundle_from_parcel(parcel_, b) == nullptr) {
+ _E("Failed to make bundle from parcel");
+ bundle_free(b);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ int ret = event_publish_app_event(__get_event_name(h->sender_appid, h->is_system, "<NAME>"), b);
+ if (ret != EVENT_ERROR_NONE) {
+ _E("Failed to publish event. result(%d)", ret);
+ bundle_free(b);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(RPC_PORT_ERROR_IO_ERROR);
+ return;
+ }
+
+ bundle_free(b);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel_, &<ARG>->parcelable, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+<PREFIX>_<NAME>_create(&<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to create handle");
+ ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ goto out;
+}
+
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+if (get_last_result() != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data");
+ <PREFIX>_<NAME>_destroy(<ARG>);
+ <ARG> = nullptr;
+ ret_ = get_last_result();
+ goto out;
+}
+)__c_cb";
+
+
+/**
+ * <ENUM_VALUE> The enumeration value of the method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER[] =
+R"__c_cb(
+[<ENUM_VALUE>] = __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler,
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ <PREFIX>_<NAME>_destroy(<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ bundle_free(<ARG>);
+)__c_cb";
+
+/**
+ * <RES_SET> The implemention to set the result of the callback function.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <METHOD_ARGS> The arguments of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_INVOKE[] =
+R"__c_cb(
+if (h->callback.<METHOD_NAME>)
+ <RES_SET>h->callback.<METHOD_NAME>(<METHOD_ARGS>, h->user_data);
+)__c_cb";
+
+
+/**
+ * <ARG> The argument.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface
+ */
+constexpr const char CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ[] =
+R"__c_cb(
+ret_ = <PREFIX>_<NAME>_create(&<ARG>);
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret_);
+ goto out;
+}
+
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+ret_ = get_last_result();
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret_);
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ free(<ARG>);
+)__c_cb";
+
+/**
+ * <NAME> The name of the interface.
+ * <METHOD_HANDLERS> The declarations of method handlers.
+ */
+constexpr const char CB_INTERFACE_METHOD_TABLE[] =
+R"__c_cb(
+static rpc_port_group_method_handler __<NAME>_method_table[] = {
+ <METHOD_HANDLERS>
+};
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+rpc_port_parcel_read_bundle(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ goto out;
+
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+rpc_port_parcel_read_string(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &<ARG>);
+)__c_cb";
+
+/**
+ * <PARAM> The name of the parameter.
+ */
+constexpr const char CB_INTERFACE_METHOD_PARAM_SET[] =
+R"__c_cb(
+*<PARAM> = new_<PARAM>;
+)__c_cb";
+
+constexpr const char CB_INTERFACE_EXTRA_HEADER[] =
+R"__c_cb(
+#include <app_event.h>
+)__c_cb";
+
+#endif // IDLC_GEN_C_GROUP_BODY_GEN_CB_H_
diff --git a/idlc/gen/c_group_header_gen.cc b/idlc/gen/c_group_header_gen.cc
new file mode 100644
index 0000000..7af7032
--- /dev/null
+++ b/idlc/gen/c_group_header_gen.cc
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/c_group_header_gen.h"
+
+namespace {
+#include "idlc/gen/c_group_header_gen_cb.h"
+
+constexpr const char PREFIX_RPC_PORT_GROUP[] = "rpc_port_group";
+}
+
+namespace tidl {
+
+CGroupHeaderGen::CGroupHeaderGen(std::shared_ptr<Document> doc)
+ : CHeaderGeneratorBase(doc) {}
+
+void CGroupHeaderGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenPragmaOnce(stream);
+ GenIncludeDefaultHeaders(stream, false);
+ GenExplicitLinkageOpen(stream);
+ GenStructureHandles(stream);
+ GenInterfaceHandles(stream);
+ GenStructures(stream);
+ GenInterfaceCallbacks(stream);
+ GenInterfaces(stream);
+}
+
+void CGroupHeaderGen::OnFiniGen(std::ofstream& stream) {
+ GenExplicitLinkageClose(stream);
+}
+
+std::string CGroupHeaderGen::GetHandlePrefix() {
+ std::string prefix = PREFIX_RPC_PORT_GROUP;
+ if (!HasNamespace())
+ return prefix;
+
+ return prefix + "_" + GetFileNamespace();
+}
+
+void CGroupHeaderGen::GenInterfaceHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceHandle(stream, iface);
+ }
+}
+
+void CGroupHeaderGen::GenInterfaceCallbacks(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ for (const auto& d : iface.GetDeclarations()) {
+ GenInterfaceMethodCallbackBase(stream, iface, *d);
+ }
+ }
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_BASE
+void CGroupHeaderGen::GenInterfaceMethodCallbackBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_BASE, {
+ { "<RETURN_TYPE>", GetReturnTypeString(decl.GetType()) },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_PARAMS>", GenMethodParams(iface, decl) }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_HANDLE
+void CGroupHeaderGen::GenInterfaceHandle(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_HANDLE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+void CGroupHeaderGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CGroupHeaderGen::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ GenInterfaceBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations())
+ GenInterfaceMethodBase(stream, iface, *d);
+}
+
+// @see #CB_INTERFACE_BASE
+void CGroupHeaderGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID()},
+ { "<METHOD_CALLBACK_DECLS>", GenMethodCallbackDecls(iface) }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_DECL
+std::string CGroupHeaderGen::GenMethodCallbackDecls(const Interface& iface) {
+ std::string method_callback_decls;
+ for (const auto& d : iface.GetDeclarations()) {
+ std::string method_callback_decl(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_DECL, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", d->GetID() }
+ }));
+
+ method_callback_decl = RemoveLine(method_callback_decl);
+ method_callback_decls += RemoveLine(method_callback_decl, 2);
+ }
+
+ return method_callback_decls;
+}
+
+std::string CGroupHeaderGen::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ bool first = true;
+ for (const auto& p : decl.GetParameters()) {
+ if (!first)
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ first = false;
+ }
+
+ return params;
+}
+
+// @see #CB_INTERFACE_METHOD_BASE
+void CGroupHeaderGen::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_BASE, {
+ { "<RETURN_TYPE>", GetReturnTypeString(decl.GetType()) },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_PARAMS>", GenMethodParams(iface, decl) }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+} // namespace tidl
diff --git a/idlc/gen/c_group_header_gen.h b/idlc/gen/c_group_header_gen.h
new file mode 100644
index 0000000..39a846a
--- /dev/null
+++ b/idlc/gen/c_group_header_gen.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_C_GROUP_HEADER_GEN_H_
+#define IDLC_GEN_C_GROUP_HEADER_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/c_header_gen_base.h"
+
+namespace tidl {
+
+class CGroupHeaderGen : public CHeaderGeneratorBase {
+ public:
+ explicit CGroupHeaderGen(std::shared_ptr<Document> doc);
+ virtual ~CGroupHeaderGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+ std::string GetHandlePrefix() override;
+
+ private:
+ void GenInterfaceHandles(std::ofstream& stream);
+ void GenInterfaceHandle(std::ofstream& stream, const Interface& iface);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+
+ void GenInterfaceCallbacks(std::ofstream& stream);
+ void GenInterfaceMethodCallbackBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl);
+ std::string GenMethodCallbackDecls(const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_C_GROUP_HEADER_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen/c_group_header_gen_cb.h b/idlc/gen/c_group_header_gen_cb.h
new file mode 100644
index 0000000..d0211eb
--- /dev/null
+++ b/idlc/gen/c_group_header_gen_cb.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_GROUP_HEADER_GEN_CB_H_
+#define IDLC_C_GROUP_HEADER_GEN_CB_H_
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_HANDLE[] =
+R"__c_cb(
+/**
+ * @brief The <PREFIX>_<NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_s *<PREFIX>_<NAME>_h;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+/**
+ * @brief The structure type containing the set of callback functions for handling events.
+ * @details It is one of the input parameters of the <PREFIX>_<NAME>_register() function.
+ *
+ * @see <PREFIX>_<NAME>_create_cb
+ * @see <PREFIX>_<NAME>_terminate_cb
+ */
+typedef struct {
+ <METHOD_CALLBACK_DECLS>
+} <PREFIX>_<NAME>_callback_s;
+
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ * @remarks The @a h handle should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ *
+ * @param[in] sender_appid ID of app sending events
+ * @param[in] callback The set of callback functions to handle events
+ * @param[in] user_data The user data to be passed to the callback function
+ * @param[in] is_system True on system events
+ * @param[out] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RPC_PORT_ERROR_IO_ERROR IO error
+
+ * @see <PREFIX>_<NAME>_destroy()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+int <PREFIX>_<NAME>_create(const char *sender_appid, <PREFIX>_<NAME>_callback_s *callback, void *user_data, bool is_system, <PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle for sending events.
+ * @remarks The @a h handle should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ *
+ * @param[in] sender_appid ID of app sending events
+ * @param[in] is_system True on system events
+ * @param[out] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RPC_PORT_ERROR_IO_ERROR IO error
+
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_create_for_sender(const char *sender_appid, bool is_system, <PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_BASE[] =
+R"__c_cb(
+/**
+ * @brief Called when the payload is received.
+ *
+ * @param[in] ...
+ * @param[in] user_data The user data passed from the registration function
+ * @see #<PREFIX>_<NAME>_callback_s;
+ */
+typedef <RETURN_TYPE> (*<PREFIX>_<NAME>_<METHOD_NAME>_cb)(<METHOD_PARAMS>, void *user_data);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The name of the method of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_DECL[] =
+R"__c_cb(
+<PREFIX>_<NAME>_<METHOD_NAME>_cb <METHOD_NAME>; /**< This callback function is invoked when the <METHOD_NAME> request is delivered. */
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The type of the return value.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The of the interface.
+ * <METHOD_NAME> The name of the method.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE[] =
+R"__c_cb(
+/**
+ * @brief Calls the <METHOD_NAME>() method.
+ * @details The return value and args are decided by the interface declaration.
+ * You can get the result using get_last_result().
+ * Before returning the function, the function sets the result using set_last_result().
+ * @remarks The specific error code can be obtained using the get_last_result() function. Error codes are described in Exception section.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] ...
+ * @exception #RPC_PORT_ERROR_NONE Successful
+ * @exception #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @exception #RPC_PORT_ERROR_IO_ERROR I/O error
+ */
+<RETURN_TYPE><PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h, <METHOD_PARAMS>);
+)__c_cb";
+
+#endif // IDLC_C_GROUP_HEADER_GEN_CB_H_
diff --git a/idlc/gen/c_header_gen_base.cc b/idlc/gen/c_header_gen_base.cc
index f402fe0..faf62d5 100644
--- a/idlc/gen/c_header_gen_base.cc
+++ b/idlc/gen/c_header_gen_base.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <string.h>
+
#include <vector>
#include "idlc/gen/c_header_gen_base.h"
@@ -25,7 +27,33 @@ namespace {
namespace tidl {
CHeaderGeneratorBase::CHeaderGeneratorBase(std::shared_ptr<Document> doc)
- : CGeneratorBase(doc) {}
+ : CGeneratorBase(doc) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ for (const auto& e : st.GetElements()) {
+ auto& type = e->GetType();
+ AddStructureFromType(type);
+ }
+ } else {
+ auto& iface = static_cast<const Interface&>(*b);
+ for (const auto& d : iface.GetDeclarations()) {
+ for (const auto& p : d->GetParameters()) {
+ auto& type = p->GetParameterType().GetBaseType();
+ if (IsDelegateType(iface, type))
+ continue;
+
+ AddStructureFromType(type, iface);
+ }
+
+ if (d->GetMethodType() == Declaration::MethodType::SYNC) {
+ auto& type = d->GetType();
+ AddStructureFromType(type, iface);
+ }
+ }
+ }
+ }
+}
void CHeaderGeneratorBase::GenPragmaOnce(std::ofstream& stream) {
const char format[] = "#pragma once\n";
@@ -42,249 +70,124 @@ void CHeaderGeneratorBase::GenExplicitLinkageClose(std::ofstream& stream) {
stream << CB_EXPLICIT_LINKAGE_CLOSE;
}
-void CHeaderGeneratorBase::GenStructures(std::ofstream& stream) {
- for (auto& i : GetDocument().GetBlocks()) {
- if (i->GetType() == Block::TYPE_STRUCTURE) {
- const Structure &st = static_cast<const Structure&>(*i);
- GenStructure(stream, st);
- for (auto& j : st.GetElements().GetElms()) {
- auto& t = j->GetType();
- AddStructureFromType(t);
- }
- } else {
- const Interface &inf = static_cast<const Interface&>(*i);
- for (auto& d : inf.GetDeclarations().GetDecls()) {
- for (auto& p : d->GetParameters().GetParams()) {
- if (IsDelegateType(inf, p->GetParameterType().GetBaseType()))
- continue;
- AddStructureFromType(p->GetParameterType().GetBaseType());
- }
- }
+void CHeaderGeneratorBase::GenStructureHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructureHandle(stream, st);
}
}
- for (auto& p : GetStructures()) {
- const Structure& st = *p.second;
- GenStructure(stream, st);
+ for (auto& i : GetStructures()) {
+ auto& st = i.second;
+ GenStructureHandle(stream, *st);
}
}
-void CHeaderGeneratorBase::GenStructure(std::ofstream& stream,
- const Structure& st) {
- GenStructureDeclaration(stream, st);
- GenStructureConstructor(stream, st);
- GenStructureDestructor(stream, st);
- GenStructureCloner(stream, st);
- GenStructureSetter(stream, st);
- GenStructureGetter(stream, st);
- GenStructureIterator(stream, st);
- GenStructureRemover(stream, st);
- GenStructureLengthGetter(stream, st);
-}
-
-void CHeaderGeneratorBase::GenStructureDeclaration(std::ofstream& stream,
- const Structure& st) {
- GenTemplate(CB_STRUCT_DECL, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- });
-}
-
-void CHeaderGeneratorBase::GenStructureConstructor(std::ofstream& stream,
- const Structure& st) {
- GenTemplate(CB_STRUCT_CTOR, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- });
-}
-
-void CHeaderGeneratorBase::GenStructureDestructor(std::ofstream& stream,
- const Structure& st) {
- GenTemplate(CB_STRUCT_DTOR, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- });
-}
-
-void CHeaderGeneratorBase::GenStructureSetter(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- GenTemplate(CB_STRUCT_SETTER, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "list")
- return "add";
- return "set";
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().IsUserDefinedType())
- return GetParcelParamTypeString(i->GetType());
-
- if (i->GetType().ToString() == "list") {
- if (i->GetType().GetMetaType()->IsUserDefinedType() ||
- i->GetType().GetMetaType()->ToString() == "list" ||
- i->GetType().GetMetaType()->ToString() == "array") {
- return GetParcelParamTypeString(*i->GetType().GetMetaType());
- } else {
- return ConvertTypeToString(ParameterType::Direction::IN,
- *i->GetType().GetMetaType());
- }
- }
-
- if (i->GetType().ToString() == "array") {
- return GetStringFromElementType(i->GetType());
- }
-
- return ConvertTypeToString(ParameterType::Direction::IN,
- i->GetType());
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "array") {
- std::string str;
- str += i->GetID();
- str += ", ";
- str += "int " + i->GetID() + "_size";
- return str;
- }
- return i->GetID();
- });
+void CHeaderGeneratorBase::GenStructures(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructure(stream, st);
+ }
}
-}
-
-void CHeaderGeneratorBase::GenStructureGetter(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() == "list")
- continue;
- GenTemplate(CB_STRUCT_GETTER, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "array")
- return GetStringFromElementType(i->GetType()) + "*";
-
- return ConvertTypeToString(ParameterType::Direction::OUT,
- i->GetType());
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "array") {
- std::string str;
- str += i->GetID();
- str += ", ";
- str += "int *" + i->GetID() + "_size";
- return str;
- }
- return i->GetID();
- });
+ for (auto& i : GetStructures()) {
+ auto& st = i.second;
+ GenStructure(stream, *st);
}
}
-void CHeaderGeneratorBase::GenStructureIterator(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() != "list")
- continue;
-
- GenTemplate(CB_STRUCT_ITERATOR, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().GetMetaType()->IsUserDefinedType() ||
- i->GetType().GetMetaType()->ToString() == "list" ||
- i->GetType().GetMetaType()->ToString() == "array")
- return GetParcelParamTypeString(*i->GetType().GetMetaType());
-
- return ConvertTypeToString(ParameterType::Direction::IN,
- *i->GetType().GetMetaType());
- },
- [&]()->std::string {
- return i->GetID();
- });
- }
+// @see #CB_STRUCTURE_HANDLE
+void CHeaderGeneratorBase::GenStructureHandle(std::ofstream& stream,
+ const Structure& st) {
+ ReplaceAll(CB_STRUCTURE_HANDLE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", GetEnumTypeString(st.GetID()) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
}
-void CHeaderGeneratorBase::GenStructureRemover(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() != "list")
- continue;
-
- GenTemplate(CB_STRUCT_REMOVER, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- });
- }
+// @see #CB_STRUCTURE_ARRAY_BASE
+void CHeaderGeneratorBase::GenStructureArrayBase(std::ofstream& stream,
+ const Structure& st) {
+ auto& elm = *(st.GetElements().begin());
+ auto& type = elm->GetType();
+ auto param_type_in = GetParamTypeString(ParameterType::Direction::IN, type);
+ auto param_type_out = GetParamTypeString(ParameterType::Direction::OUT, type);
+
+ ReplaceAll(CB_STRUCTURE_ARRAY_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", st.GetID() },
+ { "<PARAM_TYPE_IN>", param_type_in },
+ { "<PARAM_TYPE_OUT>", param_type_out }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
}
-void CHeaderGeneratorBase::GenStructureLengthGetter(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() != "list")
- continue;
+// @see #CB_STRUCTURE_LIST_BASE
+void CHeaderGeneratorBase::GenStructureListBase(std::ofstream& stream,
+ const Structure& st) {
+ auto& elm = *(st.GetElements().begin());
+ auto& type = elm->GetType();
+ auto param_type = GetParamTypeString(ParameterType::Direction::IN, type);
+
+ ReplaceAll(CB_STRUCTURE_LIST_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", st.GetID() },
+ { "<PARAM_TYPE_IN>", param_type }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
- GenTemplate(CB_STRUCT_LENGTH_GETTER, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- });
+// @see #CB_STRUCTURE_BASE
+void CHeaderGeneratorBase::GenStructureBase(std::ofstream& stream,
+ const Structure& st) {
+ ReplaceAll(CB_STRUCTURE_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", st.GetID() }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+
+ for (const auto& e : st.GetElements()) {
+ auto& type = e->GetType();
+ auto param_type_in = GetParamTypeString(ParameterType::Direction::IN, type);
+ auto param_type_out = GetParamTypeString(ParameterType::Direction::OUT, type);
+
+ ReplaceAll(CB_STRUCTURE_BASE_SET_GET, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", st.GetID() },
+ { "<PARAM_TYPE_IN>", param_type_in },
+ { "<PARAM_TYPE_OUT>", param_type_out },
+ { "<ELEMENT_NAME>", e->GetID() }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
}
}
-void CHeaderGeneratorBase::GenStructureCloner(std::ofstream& stream,
- const Structure& st) {
- GenTemplate(CB_STRUCT_CLONER, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- });
+void CHeaderGeneratorBase::GenStructure(std::ofstream& stream,
+ const Structure& st) {
+ if (st.GetID().compare(0, strlen("array"), "array") == 0)
+ GenStructureArrayBase(stream, st);
+ else if (st.GetID().compare(0, strlen("list"), "list") == 0)
+ GenStructureListBase(stream, st);
+ else
+ GenStructureBase(stream, st);
}
} // namespace tidl
diff --git a/idlc/gen/c_header_gen_base.h b/idlc/gen/c_header_gen_base.h
index 4e2ad35..9e7e15f 100644
--- a/idlc/gen/c_header_gen_base.h
+++ b/idlc/gen/c_header_gen_base.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,21 +33,15 @@ class CHeaderGeneratorBase : public CGeneratorBase {
void GenPragmaOnce(std::ofstream& stream);
void GenExplicitLinkageOpen(std::ofstream& stream);
void GenExplicitLinkageClose(std::ofstream& stream);
- void GenStructures(std::ofstream& stream);
+ virtual void GenStructureHandles(std::ofstream& stream);
+ virtual void GenStructures(std::ofstream& stream);
private:
+ void GenStructureHandle(std::ofstream& stream, const Structure& st);
+ void GenStructureArrayBase(std::ofstream& stream, const Structure& st);
+ void GenStructureListBase(std::ofstream& stream, const Structure& st);
+ void GenStructureBase(std::ofstream& stream, const Structure& st);
void GenStructure(std::ofstream& stream, const Structure& st);
- void GenStructureDeclaration(std::ofstream& stream, const Structure& st);
- void GenStructureParcelTo(std::ofstream& stream, const Structure& st);
- void GenStructureParcelFrom(std::ofstream& stream, const Structure& st);
- void GenStructureConstructor(std::ofstream& stream, const Structure& st);
- void GenStructureDestructor(std::ofstream& stream, const Structure& st);
- void GenStructureSetter(std::ofstream& stream, const Structure& st);
- void GenStructureGetter(std::ofstream& stream, const Structure& st);
- void GenStructureIterator(std::ofstream& stream, const Structure& st);
- void GenStructureRemover(std::ofstream& stream, const Structure& st);
- void GenStructureLengthGetter(std::ofstream& stream, const Structure& st);
- void GenStructureCloner(std::ofstream& stream, const Structure& st);
};
} // namespace tidl
diff --git a/idlc/gen/c_header_gen_base_cb.h b/idlc/gen/c_header_gen_base_cb.h
index e0229f5..fe16760 100644
--- a/idlc/gen/c_header_gen_base_cb.h
+++ b/idlc/gen/c_header_gen_base_cb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,64 +17,327 @@
#ifndef IDLC_C_GEN_C_HEADER_GEN_BASE_CB_H_
#define IDLC_C_GEN_C_HEADER_GEN_BASE_CB_H_
-const char CB_EXPLICIT_LINKAGE_OPEN[] =
+constexpr const char CB_EXPLICIT_LINKAGE_OPEN[] =
R"__c_cb(
#ifdef __cplusplus
extern "C" {
#endif
)__c_cb";
-const char CB_EXPLICIT_LINKAGE_CLOSE[] =
+constexpr const char CB_EXPLICIT_LINKAGE_CLOSE[] =
R"__c_cb(
#ifdef __cplusplus
}
#endif
)__c_cb";
-const char CB_STRUCT_DECL[] =
-R"__c_cb(
-typedef struct $$_s *rpc_port_$$_h;
-)__c_cb";
-const char CB_STRUCT_CTOR[] =
+/**
+ * <PREFIX> The prefix of the handle.
+ * <NAME> The name of the handle.
+ */
+constexpr const char CB_STRUCTURE_HANDLE[] =
R"__c_cb(
-int rpc_port_$$_create(rpc_port_$$_h *h);
+/**
+ * @brief The <PREFIX>_<NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_s *<PREFIX>_<NAME>_h;
)__c_cb";
-const char CB_STRUCT_DTOR[] =
+/**
+ * <PREFIX> The prefix of the array structure.
+ * <NAME> The name of the array structure.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE[] =
R"__c_cb(
-int rpc_port_$$_destroy(rpc_port_$$_h h);
-)__c_cb";
+/**
+ * @briefs Creates a <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a h should be released using the <PREFIX>_<NAME>_destroy()
+ * if it's no longer needed.
+ * @param[out] h The <PREFIX>_<NAME> handle that is newly created
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h);
-const char CB_STRUCT_SETTER[] =
-R"__c_cb(
-int rpc_port_$$_$$_$$(rpc_port_$$_h h, $$$$);
-)__c_cb";
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
-const char CB_STRUCT_GETTER[] =
-R"__c_cb(
-int rpc_port_$$_get_$$(rpc_port_$$_h h, $$$$);
-)__c_cb";
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME> should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone);
-const char CB_STRUCT_ITERATOR[] =
-R"__c_cb(
-int rpc_port_$$_foreach_$$(rpc_port_$$_h h,
- bool (*callback)($$$$, void *user_data), void *user_data);
+/**
+ * @brief Sets the value to the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The value is internally copied and stored.
+ * You should release it if it's allocaed when it's no longer needed,
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] value The array value
+ * @param[in] size The size of the array
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_get()
+ */
+int <PREFIX>_<NAME>_set(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>*value, int size);
+
+/**
+ * @brief Gets the value from the <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created value should be released if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] value The array value
+ * @param[out] size The size of the array
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_set()
+ */
+int <PREFIX>_<NAME>_get(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>*value, int *size);
)__c_cb";
-const char CB_STRUCT_REMOVER[] =
+/**
+ * <PREFIX> The prefix of the list structure.
+ * <NAME> The name of the list structure.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE[] =
R"__c_cb(
-int rpc_port_$$_remove_$$(rpc_port_$$_h h, unsigned int nth);
+/**
+ * @brief Called to retrieve the value contained in the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a value MUST NOT be released by the application.
+ * @param[in] value The value of the list
+ * @param[in] user_data The user data passed from the foreach function
+ * @return @c true to continue with the next iteration of the loop,
+ * otherwise @c false to break out of the loop
+ * @see <PREFIX>_<NAME>_foreach()
+ */
+typedef bool (*<PREFIX>_<NAME>_cb)(<PARAM_TYPE_IN>value, void *user_data);
+
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a h handle should be released using the <PREFIX>_<NAME>_destroy()
+ * if it's no longer needed.
+ * @param[out] h The <PREFIX>_<NAME> handle that is newly created
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME> should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone);
+
+/**
+ * @brief Adds the value to the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The value is internally copied and stored.
+ * You should release it if it's allocaed when it's no longer needed,
+ * @param[in] h The <PREFIX>_<NAME> handle.
+ * @param[in] value The value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_remove()
+ */
+int <PREFIX>_<NAME>_add(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value);
+
+/**
+ * @brief Retrieves all values contained in the <PREFIX>_<NAME> handle.
+ * @details This function called <PREFIX>_<NAME>_cb once for each value contained in the <PREFIX>_<NAME> handle.
+ * If the <PREFIX>_<NAME>_cb callback function returns @c false, the iteration will be finished.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] callback The iteration callback function
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_cb()
+ */
+int <PREFIX>_<NAME>_foreach(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_cb callback, void *user_data);
+
+/**
+ * @brief Removes the element at the given position in the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] nth The position of the element
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_remove(<PREFIX>_<NAME>_h h, unsigned int nth);
+
+/**
+ * @brief Gets the number of elements in the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] length The number of elements
+ * @return @c on 0 success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_length(<PREFIX>_<NAME>_h h, unsigned int *length);
)__c_cb";
-const char CB_STRUCT_LENGTH_GETTER[] =
+/**
+ * <PREFIX> The prefix of the structure. e.g. rpc_port_proxy_ or rpc_port_stub_
+ * <NAME> The name of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE[] =
R"__c_cb(
-int rpc_port_$$_get_$$_length(rpc_port_$$_h h, unsigned int *length);
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a h handle should be released using the <PREFIX>_<NAME>_destroy()
+ * if it's no longer needed.
+ * @param[out] h The <PREFIX>_<NAME> handle that is newly created
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMTER Invaid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME> should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone);
)__c_cb";
-const char CB_STRUCT_CLONER[] =
+/**
+ * <PREFIX> The prefix of the structure. e.g. rpc_port_proxy_ or rpc_port_stub_
+ * <NAME> The name of the structure.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_SET_GET[] =
R"__c_cb(
-int rpc_port_$$_clone(rpc_port_$$_h h, rpc_port_$$_h *clone);
+/**
+ * @brief Sets the <ELEMENT_NAME> to the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The <ELEMENT_NAME> is internally copied and stored.
+ * You should release it if it's allocated when it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] value The <ELEMENT_NAME>
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_get_<ELEMENT_NAME>()
+ */
+int <PREFIX>_<NAME>_set_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value);
+
+/**
+ * @brief Gets the <ELEMENT_NAME> from the <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created value should be released if it's allocated when it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] value The <ELEMENT_NAME>
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_set_<ELEMENT_NAME>
+ */
+int <PREFIX>_<NAME>_get_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>value);
)__c_cb";
#endif // IDLC_C_GEN_C_HEADER_GEN_BASE_CB_H_
diff --git a/idlc/gen/c_proxy_body_gen.cc b/idlc/gen/c_proxy_body_gen.cc
index 7c775f5..1efe1f4 100644
--- a/idlc/gen/c_proxy_body_gen.cc
+++ b/idlc/gen/c_proxy_body_gen.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,16 +14,17 @@
* limitations under the License.
*/
-#include "idlc/gen/c_proxy_body_gen.h"
+#include <algorithm>
-namespace {
+#include "idlc/gen/c_proxy_body_gen.h"
#include "idlc/gen/c_proxy_body_gen_cb.h"
-}
namespace tidl {
-CProxyBodyGen::CProxyBodyGen(std::shared_ptr<Document> doc)
- : CBodyGeneratorBase(doc) {}
+CProxyBodyGen::CProxyBodyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options)
+ : CBodyGeneratorBase(doc), options_(std::move(options)) {
+}
void CProxyBodyGen::OnInitGen(std::ofstream& stream) {
GenVersion(stream);
@@ -32,7 +33,12 @@ void CProxyBodyGen::OnInitGen(std::ofstream& stream) {
GenIncludeHeader(stream);
GenLogTag(stream, std::string("RPC_PORT_PROXY"));
GenLogDefinition(stream);
- GenTypedefProxyDelegate(stream);
+ GenVersionDefinition(stream);
+ GenBaseDefinition(stream);
+ GenInterfaceDelegateCallback(stream);
+ GenStructureDefs(stream);
+ GenInterfaceDefs(stream);
+ GenPrivateSharingListSet(stream);
GenStructures(stream);
GenInterfaces(stream);
}
@@ -40,558 +46,564 @@ void CProxyBodyGen::OnInitGen(std::ofstream& stream) {
void CProxyBodyGen::OnFiniGen(std::ofstream& stream) {
}
-void CProxyBodyGen::GenTypedefProxyDelegate(std::ofstream& stream) {
- const char format[] =
- "typedef void (*proxy_delegate)(GList **list, rpc_port_parcel_h parcel," \
- " int seq_id, int id);\n";
- stream << NLine(1);
- stream << std::string(format);
+// @see #CB_INTERFACE_DELEGATE_CALLBACK
+void CProxyBodyGen::GenInterfaceDelegateCallback(std::ofstream& stream) {
+ stream << SmartIndent(CB_INTERFACE_DELEGATE_CALLBACK);
}
-void CProxyBodyGen::GenInterfaces(std::ofstream& stream) {
+void CProxyBodyGen::GenInterfaceDefs(std::ofstream& stream) {
for (auto& i : GetDocument().GetBlocks()) {
if (i->GetType() != Block::TYPE_INTERFACE)
continue;
- const Interface &inf = static_cast<const Interface&>(*i);
- GenInterface(stream, inf);
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterfaceDef(stream, iface);
}
}
-void CProxyBodyGen::GenInterface(std::ofstream& stream, const Interface& inf) {
- GenInterfaceFileSharing(stream, inf);
- GenInterfaceEnumerations(stream, inf);
- GenInterfaceDeclaration(stream, inf);
- GenInterfaceDelegators(stream, inf);
- GenInterfaceDelegatorTable(stream, inf);
- GenInterfaceDelegatorHandler(stream, inf);
- GenInterfaceConsumeCommand(stream, inf);
- GenInterfaceOnConnectedEventCB(stream, inf);
- GenInterfaceOnDisconnectedEventCB(stream, inf);
- GenInterfaceOnRejectedEventCB(stream, inf);
- GenInterfaceOnReceivedEventCB(stream, inf);
- GenInterfaceMethods(stream, inf);
- GenInterfaceHandleCtor(stream, inf);
- GenInterfaceHandleDtor(stream, inf);
- GenInterfaceCtor(stream, inf);
- GenInterfaceConnect(stream, inf);
- GenInterfaceDtor(stream, inf);
- GenInterfaceConnectSync(stream, inf);
-}
+void CProxyBodyGen::GenInterfaceDef(std::ofstream& stream,
+ const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
-void CProxyBodyGen::GenInterfaceFileSharing(std::ofstream& stream,
- const Interface& inf) {
-
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- for (auto& p : i->GetParameters().GetParams()) {
- if ((p->GetParameterType().GetBaseType().ToString() == "list" ||
- p->GetParameterType().GetBaseType().ToString() == "array") &&
- p->GetParameterType().GetBaseType().GetMetaType()->ToString() == "file") {
- if (p->GetParameterType().GetBaseType().ToString() == "array") {
- stream << SmartIndent(std::string(CB_FILE_ARRAY_SHARING));
- } else {
- stream << SmartIndent(std::string(CB_FILE_LIST_SHARING));
- }
- }
- }
+ GenInterfaceDelegateDef(stream, iface, *d);
}
-}
-
-void CProxyBodyGen::GenInterfaceDeclaration(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_STRUCT, "##",
- GetInterfaceIdWithNamespace(inf)));
+ GenInterfaceBaseDef(stream, iface);
}
-void CProxyBodyGen::GenInterfaceDelegators(std::ofstream& stream,
- const Interface& inf) {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
- continue;
- GenInterfaceDelegator(stream, GetInterfaceIdWithNamespace(inf), *i);
- }
+// @see #CB_INTERFACE_DELEGATE_DEF
+void CProxyBodyGen::GenInterfaceDelegateDef(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_DELEGATE_DEF, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", decl.GetID() }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
}
-void CProxyBodyGen::GenInterfaceDelegator(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- GenInterfaceDelegatorDeclaration(stream, id, decl);
- GenInterfaceDelegatorSerializer(stream, id, decl);
- GenInterfaceDelegatorDeserializer(stream, id, decl);
- GenInterfaceDelegatorConstructor(stream, id, decl);
- GenInterfaceDelegatorDestructor(stream, id, decl);
- GenInterfaceDelegatorDisposer(stream, id, decl);
- GenInterfaceDelegatorInvoker(stream, id, decl);
+// @see #CB_INTERFACE_BASE_DEF
+void CProxyBodyGen::GenInterfaceBaseDef(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_BASE_DEF, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
}
-void CProxyBodyGen::GenInterfaceDelegatorDeclaration(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << SmartIndent(ReplaceAll(
- CB_DELEGATE_STRUCT, "##", id + "_" + decl.GetID()));
-}
+void CProxyBodyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
-void CProxyBodyGen::GenInterfaceDelegatorSerializer(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << SmartIndent(
- ReplaceAll(CB_DELEGATE_SERIALIZER, "##", id + "_" + decl.GetID()));
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
}
-void CProxyBodyGen::GenInterfaceDelegatorDeserializer(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << SmartIndent(
- ReplaceAll(CB_DELEGATE_DESERIALIZER, "##", id + "_" + decl.GetID()));
-}
+void CProxyBodyGen::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ GenInterfaceDelegateEnumBase(stream, iface);
-void CProxyBodyGen::GenInterfaceDelegatorConstructor(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_DELEGATE_CTOR, "##", id + "_" + decl.GetID()),
- [&]()->std::string {
- return id;
- },
- [&]()->std::string {
- return decl.GetID();
- }));
-}
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
-void CProxyBodyGen::GenInterfaceDelegatorDisposer(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_DELEGATE_DISPOSER, "##", id + "_" + decl.GetID()),
- [&]()->std::string {
- return id;
- }));
-}
+ GenInterfaceDelegateBase(stream, iface, *d);
+ }
-void CProxyBodyGen::GenInterfaceDelegatorInvoker(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- const char parcel[] = "$$(parcel, $$);\n";
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_DELEGATE_INVOKER, "##", id + "_" + decl.GetID()),
- [&]()->std::string {
- return id;
- },
- [&]()->std::string {
- return decl.GetID();
- },
- [&]()->std::string {
- std::string str;
- int cnt = 0;
- for (auto& i : decl.GetParameters().GetParams()) {
- str += GetParcelParamTypeString(
- i->GetParameterType().GetBaseType(), false) + i->GetID();
- str += " = " + GetErrorValue(i->GetParameterType().GetBaseType());
- str += ";" + NLine(1);
- cnt++;
- }
- if (cnt > 0)
- str += NLine(1);
- for (auto& i : decl.GetParameters().GetParams()) {
- if (i->GetParameterType().GetBaseType().IsUserDefinedType() ||
- i->GetParameterType().GetBaseType().ToString() == "list" ||
- i->GetParameterType().GetBaseType().ToString() == "array") {
- str += GetConstructorString(i->GetParameterType().GetBaseType(),
- i->GetID());
- }
- str += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(
- i->GetParameterType().GetBaseType(), true);
- },
- [&]()->std::string {
- if (i->GetParameterType().GetBaseType().IsUserDefinedType() ||
- i->GetParameterType().GetBaseType()
- .ToString() == "list" ||
- i->GetParameterType().GetBaseType().ToString() == "array")
- return "&" + i->GetID() + "->parcelable, " + i->GetID();
- return "&" + i->GetID();
- });
- }
- return str;
- },
- [&]()->std::string {
- std::string str;
- str += "handle->callback(handle->user_data";
- for (auto& i : decl.GetParameters().GetParams()) {
- str += ", ";
- str += i->GetID();
- }
- str += ");" + NLine(1);
- return str;
- },
- [&]()->std::string {
- std::string str;
- for (auto& i : decl.GetParameters().GetParams()) {
- str += GetDestructorString(i->GetParameterType().GetBaseType(),
- i->GetID());
- str += NLine(1);
- }
- return str;
- }));
-}
+ GenInterfaceDelegateTable(stream, iface);
+ GenInterfaceMethodEnumBase(stream, iface);
+ GenInterfaceBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
-void CProxyBodyGen::GenInterfaceDelegatorDestructor(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << SmartIndent(ReplaceAll(
- CB_DELEGATE_DTOR, "##", id + "_" + decl.GetID()));
+ GenInterfaceMethodBase(stream, iface, *d);
+ }
}
-void CProxyBodyGen::GenInterfaceDelegatorTable(std::ofstream& stream,
- const Interface& inf) {
- const char block[] =
- "static proxy_delegate __$$_delegate_table[] = {\n" \
- "$$" \
- "};\n";
- const char delegate_format[] = "[$$] = $$,\n";
- std::string str;
- int cnt = 0;
-
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+// @see #CB_INTERFACE_BASE
+void CProxyBodyGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+
+ ReplaceAll(CB_INTERFACE_BASE)
+ .Change("<PREFIX>", prefix)
+ .Change("<NAME>", name)
+ .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
+ .ChangeToUpper("<UPPERCASE_NAME>", name)
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_DELEGATE_ENUM_BASE
+void CProxyBodyGen::GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& iface) {
+ unsigned int num = 1;
+ std::string enums;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
continue;
- str += GenTemplateString(delegate_format,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf) + "_DELEGATE_" + i->GetID();
- },
- [&]()->std::string {
- return "__" + GetInterfaceIdWithNamespace(inf) + "_delegate_"
- + i->GetID();
- });
- cnt++;
+
+ enums += GetHandlePrefix() + "_" + iface.GetID() + "_DELEGATE_" + d->GetID();
+ enums += " = " + std::to_string(num++) + ",";
+ enums += NLine(1);
}
- if (cnt == 0)
+ if (enums.empty())
return;
- stream << NLine(1);
- stream << SmartIndent(GenTemplateString(block,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return str;
- }));
-}
-
-void CProxyBodyGen::GenInterfaceDelegatorHandler(std::ofstream& stream,
- const Interface& inf) {
- std::string str;
- int cnt = 0;
-
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
- continue;
- cnt++;
+ std::transform(enums.begin(), enums.end(), enums.begin(), ::toupper);
+ ReplaceAll(CB_INTERFACE_DELEGATE_ENUM_BASE, {
+ { "<ENUMS>", enums },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+std::string CProxyBodyGen::GenDelegateArgsDecl(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ code += GetArgTypeString(type, iface) + p->GetID() + " = " +
+ GetErrorValue(param_type.GetBaseType()) + ";" + NLine(1);
}
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_PROCESS_RECEIVED_EVENT, "##",
- GetInterfaceIdWithNamespace(inf)),
- [&]()->std::string {
- if (cnt == 0)
- return str;
- return ReplaceAll(CB_PROCESS_RECEIVED_EVENT_IMPL, "##",
- GetInterfaceIdWithNamespace(inf));
- }));
-}
+ return code;
+}
+
+// @see #CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_READ
+// @see #CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_READ
+// @see #CB_INTERFACE_DELEGATE_STRING_PARCEL_READ
+// @see #CB_INTERFACE_DELEGATE_BASE_PARCEL_READ
+std::string CProxyBodyGen::GenDelegateParcelRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ std::string param_read_code;
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ param_read_code = ReplaceAll(
+ CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+
+ std::string name = GetFullNameFromType(type, iface);
+ param_read_code = ReplaceAll(param_read_code, "<NAME>", name);
+ param_read_code = ReplaceAll(param_read_code, "<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ param_read_code = ReplaceAll(CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ param_read_code = ReplaceAll(CB_INTERFACE_DELEGATE_STRING_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else {
+ param_read_code = ReplaceAll(CB_INTERFACE_DELEGATE_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ param_read_code = ReplaceAll(param_read_code, "<ARG>", p->GetID());
+ }
-void CProxyBodyGen::GenInterfaceConsumeCommand(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_CONSUME_COMMAND, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+ code += param_read_code;
+ }
-void CProxyBodyGen::GenInterfaceOnConnectedEventCB(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_ON_CONNECTED, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+ return RemoveLine(code);
+}
+
+// @see CB_INTERFACE_DELEGATE_USER_DEFINED_ARG_FREE
+// @see CB_INTERFACE_DELEGATE_BUNDLE_ARG_FREE
+// @see CB_INTERFACE_DELEGATE_STRING_ARG_FREE
+std::string CProxyBodyGen::GenDelegateArgsFree(const Interface& iface,
+ const Declaration& decl, bool& has_free) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ std::string param_free_code;
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ param_free_code = ReplaceAll(
+ CB_INTERFACE_DELEGATE_USER_DEFINED_ARG_FREE, "<PREFIX>",
+ GetHandlePrefix());
+
+ std::string name = GetFullNameFromType(type, iface);
+ param_free_code = ReplaceAll(param_free_code, "<NAME>", name);
+ param_free_code = ReplaceAll(param_free_code, "<ARG>", p->GetID());
+ has_free = true;
+ } else if (type.ToString() == "bundle") {
+ param_free_code = ReplaceAll(CB_INTERFACE_DELEGATE_BUNDLE_ARG_FREE,
+ "<ARG>", p->GetID());
+ has_free = true;
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ param_free_code = ReplaceAll(CB_INTERFACE_DELEGATE_STRING_ARG_FREE,
+ "<ARG>", p->GetID());
+ has_free = true;
+ }
-void CProxyBodyGen::GenInterfaceOnDisconnectedEventCB(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_ON_DISCONNECTED, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+ code += param_free_code;
+ }
-void CProxyBodyGen::GenInterfaceOnRejectedEventCB(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_ON_REJECTED, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+ return RemoveLine(code);
+}
+
+std::string CProxyBodyGen::GenDelegateCallbackArgs(const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters())
+ code += ", " + p->GetID();
+
+ return code;
+}
+
+// @see CB_INTERFACE_DELEGATE_BASE
+void CProxyBodyGen::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_DELEGATE_" + decl.GetID();
+ std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
+ ::toupper);
+ bool has_free = false;
+ std::string delegate_args_free = GenDelegateArgsFree(iface, decl, has_free);
+
+ ReplaceAll(CB_INTERFACE_DELEGATE_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", decl.GetID() },
+ { "<DELEGATE_ENUM_VALUE>", enum_value },
+ { "<DELEGATE_ARGS_DECL>", GenDelegateArgsDecl(iface, decl) },
+ { "<DELEGATE_PARCEL_READ>", GenDelegateParcelRead(iface, decl) },
+ { "<DELEGATE_ARGS_FREE>", delegate_args_free },
+ { "<DELEGATE_CALLBACK_ARGS>", GenDelegateCallbackArgs(decl) },
+ { "<GOTO_STATEMENT>", has_free ? "out:" + NLine(1) : "" }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_DELEGATE_TABLE
+// @see #CB_INTERFACE_DELEGATE_TABLE_MEMBER
+void CProxyBodyGen::GenInterfaceDelegateTable(std::ofstream& stream,
+ const Interface& iface) {
+ std::string delegate_handlers;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
-void CProxyBodyGen::GenInterfaceOnReceivedEventCB(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_ON_RECEIVED, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_DELEGATE_" + d->GetID();
+ std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
+ ::toupper);
+ std::string member(ReplaceAll(CB_INTERFACE_DELEGATE_TABLE_MEMBER, {
+ { "<ENUM_VALUE>", enum_value },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", d->GetID() }
+ }));
+
+ member = RemoveLine(member);
+ delegate_handlers += member;
+ }
-void CProxyBodyGen::GenInterfaceMethods(std::ofstream& stream,
- const Interface& inf) {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ if (delegate_handlers.empty())
+ delegate_handlers = "nullptr," + NLine(1);
+
+ ReplaceAll(CB_INTERFACE_DELEGATE_TABLE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_HANDLERS>", delegate_handlers }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_ENUM_BASE
+void CProxyBodyGen::GenInterfaceMethodEnumBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string enums;
+ enums += GetHandlePrefix() + "_" + iface.GetID() + "_METHOD_RESULT_,";
+ enums += NLine(1);
+ enums += GetHandlePrefix() + "_" + iface.GetID() + "_METHOD_CALLBACK_,";
+ enums += NLine(1);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_INTERFACE_METHODS, "##",
- GetInterfaceIdWithNamespace(inf)),
- [&]()->std::string {
- return GetReturnTypeString(i->GetType());
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- std::string str;
- for (auto& p : i->GetParameters().GetParams()) {
- str += ", ";
- if (IsDelegateType(inf, p->GetParameterType().GetBaseType())) {
- str += "rpc_port_" + GetInterfaceIdWithNamespace(inf) + "_" +
- p->GetParameterType().GetBaseType().ToString() +
- "_h " + p->GetID();
- } else {
- str += GetParamTypeString(p->GetParameterType().GetDirection(),
- p->GetParameterType().GetBaseType()) + p->GetID();
- }
- }
- return str;
- },
- [&]()->std::string {
- if (GetReturnTypeString(i->GetType()) != "void ")
- return GetReturnTypeString(i->GetType()) + "ret = " +
- GetErrorValue(i->GetType()) + ";";
- return "";
- },
- [&]()->std::string {
- std::string str;
- for (auto& p : i->GetParameters().GetParams()) {
- if (p->GetParameterType().GetDirection() ==
- ParameterType::Direction::OUT ||
- p->GetParameterType().GetBaseType().IsUserDefinedType() ||
- p->GetParameterType().GetBaseType().ToString() == "list" ||
- p->GetParameterType().GetBaseType().ToString() == "array" ||
- p->GetParameterType().GetBaseType().ToString() == "bundle")
- str += " || !" + p->GetID();
- }
- return str;
- },
- [&]()->std::string {
- if (GetReturnTypeString(i->GetType()) != "void ")
- return " ret";
- return "";
- },
- [&]()->std::string {
- if (GetReturnTypeString(i->GetType()) != "void ")
- return " ret";
- return "";
- },
- [&]()->std::string {
- for (auto& p : i->GetParameters().GetParams()) {
- if (p->GetParameterType().GetDirection() ==
- ParameterType::Direction::IN &&
- p->GetParameterType().GetBaseType().ToString() == "file") {
- return ReplaceAll(CB_PRIVATE_SHARING_BLOCK, "##",
- p->GetID());
- }
-
- if ((p->GetParameterType().GetBaseType().ToString() == "list" ||
- p->GetParameterType().GetBaseType().ToString() == "array") &&
- p->GetParameterType().GetBaseType().GetMetaType()->ToString() == "file") {
- if (p->GetParameterType().GetBaseType().ToString() == "array") {
-
- return ReplaceAll(CB_ARRAY_PRIVATE_SHARING_BLOCK, "##",
- p->GetID());
- } else {
- return ReplaceAll(CB_LIST_PRIVATE_SHARING_BLOCK, "##",
- p->GetID());
- }
- }
- }
- return "";
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetMethodWriteString(inf, *i);
- },
- [&]()->std::string {
- return GetMethodReadString(inf, *i);
- }));
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_METHOD_" + d->GetID() + ",";
+ enums += enum_value;
+ enums += NLine(1);
}
-}
-void CProxyBodyGen::GenInterfaceHandleCtor(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_HANDLE_CTOR, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+ std::transform(enums.begin(), enums.end(), enums.begin(), ::toupper);
+ ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE, {
+ { "<ENUMS>", enums },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+std::string CProxyBodyGen::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
-void CProxyBodyGen::GenInterfaceHandleDtor(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_HANDLE_DTOR, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+ return params;
+}
+
+std::string CProxyBodyGen::GenMethodParamsCheck(const Interface& iface,
+ const Declaration& decl) {
+ std::string params_check;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array" ||
+ type.ToString() == "bundle" ||
+ type.ToString() == "string" ||
+ type.ToString() == "file")
+ params_check += " || " + p->GetID() + " == nullptr";
+ }
-void CProxyBodyGen::GenInterfaceCtor(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_CTOR, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+ return params_check;
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_LIST_FILE_SET_PRIVATE_SHARING
+// @see #CB_INTERFACE_METHOD_ARRAY_FILE_SET_PRIVATE_SHARING
+// @see #CB_INTERFACE_METHOD_FILE_SET_PRIVATE_SHARING
+std::string CProxyBodyGen::GenMethodParcelWrite(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
-void CProxyBodyGen::GenInterfaceConnect(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_CONNECT, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+ std::string parcel_write_code;
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE, "<ARG>",
+ p->GetID());
+ std::string name = GetFullNameFromType(type, iface);
+ parcel_write_code += GetPrivateSharingString(type, iface, "h->port",
+ p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ parcel_write_code += GetPrivateSharingString(type, iface, "h->port",
+ p->GetID());
+ } else {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ARG>",
+ p->GetID());
+ }
-void CProxyBodyGen::GenInterfaceDtor(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_DTOR, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+ code += parcel_write_code;
+ }
-void CProxyBodyGen::GenInterfaceConnectSync(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_CONNECT_SYNC, "##",
- GetInterfaceIdWithNamespace(inf)));
+ return RemoveLine(code);
}
-std::string CProxyBodyGen::GetMethodWriteString(const Interface& inf,
- const Declaration& decl) {
- const char setter[] = "$$($$, $$);\n";
- const char ternary_operation[] = "## ? ## : \"\"";
- std::string str;
- for (auto& p : decl.GetParameters().GetParams()) {
- if (p->GetParameterType().GetDirection() == ParameterType::Direction::OUT)
+// @see #CB_INTERFACE_METHOD_DELEGATE_APPEND
+std::string CProxyBodyGen::GenMethodDelegateAppend(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type)) {
+ std::string delegate_append_code(ReplaceAll(
+ CB_INTERFACE_METHOD_DELEGATE_APPEND, "<ARG>", p->GetID()));
+ code += delegate_append_code;
+ }
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_ASYNC_BASE
+std::string CProxyBodyGen::GenMethodAsyncBase(const Interface& iface,
+ const Declaration& decl) {
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+ std::string method_name = decl.GetID();
+
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_ASYNC_BASE)
+ .Change("<PREFIX>", prefix)
+ .Change("<NAME>", name)
+ .Change("<METHOD_NAME>", method_name)
+ .Change("<METHOD_PARAMS>", GenMethodParams(iface, decl))
+ .Change("<METHOD_PARAMS_CHECK>", GenMethodParamsCheck(iface, decl))
+ .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
+ .ChangeToUpper("<UPPERCASE_NAME>", name)
+ .ChangeToUpper("<UPPERCASE_METHOD_NAME>", method_name)
+ .Change("<METHOD_PARCEL_WRITE>", GenMethodParcelWrite(iface, decl))
+ .Change("<METHOD_DELEGATE_APPEND>", GenMethodDelegateAppend(iface,
+ decl)));
+ return code;
+}
+
+std::string CProxyBodyGen::GenMethodArgs(const Interface& iface,
+ const Declaration& decl) {
+ std::string args_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
continue;
- if (IsDelegateType(inf, p->GetParameterType().GetBaseType())) {
- str += GenTemplateString(ReplaceAll(CB_DELEGATE_BLOCK, "##",
- GetInterfaceIdWithNamespace(inf) + "_" + p->GetParameterType()
- .GetBaseType().ToString()),
- [&]()->std::string {
- return p->GetID();
- });
+
+ auto& type = param_type.GetBaseType();
+ args_code += GetReturnTypeString(type) + "new_" + p->GetID() + ";";
+ args_code += NLine(1);
+ }
+
+ return args_code;
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_READ
+std::string CProxyBodyGen::GenMethodParcelReadBase(const Interface& iface,
+ const BaseType& type, const std::string& param_name) {
+ std::string parcel_read_code;
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_read_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ std::string name = GetFullNameFromType(type, iface);
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>", name);
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", param_name);
+ } else if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ,
+ "<ARG>", param_name);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_READ,
+ "<ARG>", param_name);
} else {
- str += GenTemplateString(setter,
- [&]()->std::string {
- return GetParcelWriteFunctionString(
- p->GetParameterType().GetBaseType(), true);
- },
- [&]()->std::string {
- return "parcel";
- },
- [&]()->std::string {
- if (p->GetParameterType().GetBaseType().IsUserDefinedType() ||
- p->GetParameterType().GetBaseType().ToString() == "list" ||
- p->GetParameterType().GetBaseType().ToString() == "array") {
- if (p->GetParameterType().GetDirection()
- == ParameterType::Direction::REF)
- return "&(*" + p->GetID() + ")->parcelable, " + "*"
- + p->GetID();
- else
- return "&" + p->GetID() + "->parcelable, " + p->GetID();
- } else if (p->GetParameterType().GetDirection()
- == ParameterType::Direction::REF) {
- if (p->GetParameterType().GetBaseType().ToString() == "string"
- || p->GetParameterType().GetBaseType().ToString() == "file")
- return ReplaceAll(ternary_operation, "##", "*" + p->GetID());
- return "*" + p->GetID();
- } else if (p->GetParameterType().GetBaseType().ToString() == "string"
- || p->GetParameterType().GetBaseType().ToString() == "file") {
- return ReplaceAll(ternary_operation, "##", p->GetID());
- }
- return p->GetID();
- });
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>",
+ param_name);
}
- }
- return str;
+
+ return parcel_read_code;
}
-std::string CProxyBodyGen::GetMethodReadString(const Interface& inf,
- const Declaration& decl) {
- const char setter[] = "$$($$, $$);\n";
- std::string str;
- if (decl.GetMethodType() != Declaration::MethodType::SYNC) {
- str += "set_last_result(r);" + NLine(1);
- return str;
- }
- str += GenTemplateString(CB_RECEIVE_BLOCK,
- [&]()->std::string {
- std::string s;
- for (auto& p : decl.GetParameters().GetParams()) {
- if (p->GetParameterType().GetDirection() !=
- ParameterType::Direction::OUT)
- continue;
- s += GetReturnTypeString(p->GetParameterType().GetBaseType()) +
- "out_" + p->GetID() + ";" + NLine(1);
- }
- return s;
- },
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- std::string s;
- for (auto& p : decl.GetParameters().GetParams()) {
- if (p->GetParameterType().GetDirection() !=
- ParameterType::Direction::OUT)
- continue;
- if (p->GetParameterType().GetBaseType().IsUserDefinedType() ||
- p->GetParameterType().GetBaseType().ToString() == "list" ||
- p->GetParameterType().GetBaseType().ToString() == "array") {
- s += GetConstructorString(p->GetParameterType().GetBaseType(),
- "out_" + p->GetID());
- }
- s += GenTemplateString(setter,
- [&]()->std::string {
- return GetParcelReadFunctionString(
- p->GetParameterType().GetBaseType(), true);
- },
- [&]()->std::string {
- return "parcel_received";
- },
- [&]()->std::string {
- auto& t = p->GetParameterType().GetBaseType();
- if (t.IsUserDefinedType() || t.ToString() == "list" ||
- t.ToString() == "array") {
- return "&out_" + p->GetID() + "->parcelable, out_"
- + p->GetID();
- }
-
- return "&out_" + p->GetID();
- });
- s += "*" + p->GetID() + " = out_" + p->GetID() + ";" + NLine(1);
- }
- if (GetReturnTypeString(decl.GetType()) != "void ") {
- if (decl.GetType().IsUserDefinedType() ||
- decl.GetType().ToString() == "list" ||
- decl.GetType().ToString() == "array") {
- s += GetConstructorString(decl.GetType(), "ret");
- }
- s += GenTemplateString(setter,
- [&]()->std::string {
- return GetParcelReadFunctionString(decl.GetType(), false);
- },
- [&]()->std::string {
- return "parcel_received";
- },
- [&]()->std::string {
- if (decl.GetType().IsUserDefinedType() ||
- decl.GetType().ToString() == "list" ||
- decl.GetType().ToString() == "array")
- return "&ret->parcelable, ret";
- return "&ret";
- });
- }
- return s;
- });
- if (GetReturnTypeString(decl.GetType()) != "void ") {
- str += "set_last_result(r);" + NLine(1);
- str += NLine(1);
- str += "return ret;";
+// @see #CB_INTERFACE_METHOD_VALUE_SET
+std::string CProxyBodyGen::GenMethodParcelRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ std::string parcel_read_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ code += GenMethodParcelReadBase(iface, type, "new_" + p->GetID());
+ code += ReplaceAll(CB_INTERFACE_METHOD_PARAM_SET, "<PARAM>",
+ p->GetID());
}
- return str;
+
+ // Return Value
+ auto& base_type = decl.GetType();
+ code += GenMethodParcelReadBase(iface, base_type, "ret_");
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_BASE
+std::string CProxyBodyGen::GenMethodBase(const Interface& iface,
+ const Declaration& decl) {
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+ std::string method_name = decl.GetID();
+
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_BASE)
+ .Change("<RETURN_TYPE>", GetReturnTypeString(decl.GetType()))
+ .Change("<PREFIX>", prefix)
+ .Change("<NAME>", name)
+ .Change("<METHOD_NAME>", method_name)
+ .Change("<METHOD_PARAMS>", GenMethodParams(iface, decl))
+ .Change("<METHOD_ARGS>", GenMethodArgs(iface, decl))
+ .Change("<ERROR_VALUE>", GetErrorValue(decl.GetType()))
+ .Change("<METHOD_PARAMS_CHECK>", GenMethodParamsCheck(iface, decl))
+ .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
+ .ChangeToUpper("<UPPERCASE_NAME>", name)
+ .ChangeToUpper("<UPPERCASE_METHOD_NAME>", method_name)
+ .Change("<METHOD_PARCEL_WRITE>", GenMethodParcelWrite(iface, decl))
+ .Change("<METHOD_PARCEL_READ>", GenMethodParcelRead(iface, decl))
+ .Change("<METHOD_DELEGATE_APPEND>", GenMethodDelegateAppend(iface,
+ decl)));
+ return code;
+}
+
+void CProxyBodyGen::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code;
+ auto method_type = decl.GetMethodType();
+ if (method_type == Declaration::MethodType::ASYNC)
+ code = GenMethodAsyncBase(iface, decl);
+ else
+ code = GenMethodBase(iface, decl);
+
+ stream << SmartIndent(code);
}
} // namespace tidl
diff --git a/idlc/gen/c_proxy_body_gen.h b/idlc/gen/c_proxy_body_gen.h
index a89c602..7f940f3 100644
--- a/idlc/gen/c_proxy_body_gen.h
+++ b/idlc/gen/c_proxy_body_gen.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,77 +21,68 @@
#include <string>
#include "idlc/gen/c_body_gen_base.h"
+#include "idlc/options.h"
namespace tidl {
class CProxyBodyGen : public CBodyGeneratorBase {
public:
- explicit CProxyBodyGen(std::shared_ptr<Document> doc);
+ explicit CProxyBodyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options);
virtual ~CProxyBodyGen() = default;
void OnInitGen(std::ofstream& stream) override;
void OnFiniGen(std::ofstream& stream) override;
private:
- void GenTypedefProxyDelegate(std::ofstream& stream);
+ void GenInterfaceDefs(std::ofstream& stream);
+ void GenInterfaceDef(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateDef(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceBaseDef(std::ofstream& stream, const Interface& iface);
+
void GenInterfaces(std::ofstream& stream);
+ void GenInterfaceDelegateCallback(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& iface);
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceDelegateTable(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodEnumBase(std::ofstream& stream,
+ const Interface& iface);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
- private:
- void GenInterface(std::ofstream& stream, const Interface& inf);
- void GenInterfaceFileSharing(std::ofstream& stream, const Interface& st);
- void GenInterfaceDeclaration(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDelegators(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDelegatorTable(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDelegatorHandler(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceConsumeCommand(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceOnConnectedEventCB(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceOnDisconnectedEventCB(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceOnRejectedEventCB(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceOnReceivedEventCB(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceMethods(std::ofstream& stream, const Interface& inf);
- void GenInterfaceHandleCtor(std::ofstream& stream, const Interface& inf);
- void GenInterfaceHandleDtor(std::ofstream& stream, const Interface& inf);
- void GenInterfaceCtor(std::ofstream& stream, const Interface& inf);
- void GenInterfaceConnect(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDtor(std::ofstream& stream, const Interface& inf);
- void GenInterfaceConnectSync(std::ofstream& stream, const Interface& inf);
+ bool HasListFile(const Interface& iface);
- private:
- void GenInterfaceDelegator(std::ofstream& stream, const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDeclaration(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorSerializer(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDeserializer(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorConstructor(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDisposer(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorInvoker(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDestructor(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
+ std::string GenDelegateArgsDecl(const Interface& iface,
+ const Declaration& decl);
+ std::string GenDelegateParcelRead(const Interface& iface,
+ const Declaration& decl);
+ std::string GenDelegateArgsFree(const Interface& iface,
+ const Declaration& decl, bool& has_free);
+ std::string GenDelegateCallbackArgs(const Declaration& decl);
- private:
- std::string GetMethodWriteString(const Interface& inf,
- const Declaration& decl);
- std::string GetMethodReadString(const Interface& inf,
- const Declaration& decl);
+ std::string GenMethodAsyncBase(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodBase(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParamsCheck(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodParcelWrite(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodDelegateAppend(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodArgs(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParcelReadBase(const Interface& iface,
+ const BaseType& type, const std::string& param_name);
+ std::string GenMethodParcelRead(const Interface& iface,
+ const Declaration& decl);
+
+ private:
+ std::shared_ptr<Options> options_;
};
} // namespace tidl
diff --git a/idlc/gen/c_proxy_body_gen_cb.h b/idlc/gen/c_proxy_body_gen_cb.h
index 0757b2d..f07b170 100644
--- a/idlc/gen/c_proxy_body_gen_cb.h
+++ b/idlc/gen/c_proxy_body_gen_cb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,568 +17,989 @@
#ifndef IDLC_C_GEN_C_PROXY_BODY_GEN_CB_H_
#define IDLC_C_GEN_C_PROXY_BODY_GEN_CB_H_
-const char CB_INTERFACE_STRUCT[] =
+constexpr const char CB_INTERFACE_DELEGATE_CALLBACK[] =
R"__c_cb(
-struct ##_s {
- char *stub_appid;
- rpc_port_proxy_h proxy;
- rpc_port_h port;
- rpc_port_h callback_port;
- rpc_port_proxy_##_callback_s callback;
- void *user_data;
- GList *delegates;
- GRecMutex mutex;
-};
+typedef void (*rpc_port_proxy_delegate_cb)(GList **delegates, rpc_port_parcel_h parcel, int id, int seq_id);
)__c_cb";
-const char CB_FILE_LIST_SHARING[] =
+/**
+ * <ENUMS> The enumeration of the interface delegate.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_ENUM_BASE[] =
R"__c_cb(
-int __file_list_set_private_sharing(rpc_port_h port, GList *list_files) {
- const char **arr = calloc(g_list_length(list_files), sizeof(char*));
- GList *iter;
- int idx = 0;
- int r = 0;
- iter = list_files;
- while (iter) {
- char *value = iter->data;
- if (!value) {
- _W("Warning: value is NULL");
- continue;
- }
- arr[idx++] = value;
- iter = g_list_next(iter);
- }
- if (idx > 0)
- r = rpc_port_set_private_sharing_array(port, arr, idx);
- return r;
-}
+typedef enum {
+ <ENUMS>
+} <PREFIX>_<NAME>_delegate_e;
)__c_cb";
-const char CB_FILE_ARRAY_SHARING[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_DEF[] =
R"__c_cb(
-int __file_array_set_private_sharing(rpc_port_h port,
- const char **files, int files_size) {
- return rpc_port_set_private_sharing_array(port, files, files_size);
-}
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ int id;
+ int seq_id;
+ bool once;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback;
+ void *user_data;
+} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
)__c_cb";
-const char CB_DELEGATE_STRUCT[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ * <DELEGATE_ENUM_VALUE> The enumeration value of the delegate.
+ * <DELEGATE_ARGS_DECL> The implementation to declares the arguments.
+ * <DELEGATE_PARCEL_READ> The implementation to read the arguments from the parcel.
+ * <DELEGATE_ARGS_FREE> The implementation to release the allocated arguments.
+ * <DELEGATE_CALLBACK_ARGS> The arguments of the delegate callback.
+ * <GOTO_STATEMENT> The statement label.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
R"__c_cb(
-struct ##_s {
- rpc_port_parcelable_t parcelable;
- int id;
- int seq_id;
- ## callback;
- bool once;
- void *user_data;
-};
-)__c_cb";
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = data;
-const char CB_DELEGATE_SERIALIZER[] =
-R"__c_cb(
-static void __##_to(rpc_port_parcel_h parcel, void *data)
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ rpc_port_parcel_write_int32(parcel, h->id);
+
+ rpc_port_parcel_write_int32(parcel, h->seq_id);
+
+ rpc_port_parcel_write_bool(parcel, h->once);
+
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+}
+
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_from(rpc_port_parcel_h parcel, void *data)
{
- struct ##_s *handle = data;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = data;
- if (!handle) {
- _E("Invalid parameter");
- return;
- }
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ rpc_port_parcel_read_int32(parcel, &h->id);
- rpc_port_parcel_write_int32(parcel, handle->id);
- rpc_port_parcel_write_int32(parcel, handle->seq_id);
- rpc_port_parcel_write_bool(parcel, handle->once);
- _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+ rpc_port_parcel_read_int32(parcel, &h->seq_id);
+
+ rpc_port_parcel_read_bool(parcel, &h->once);
+
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+ set_last_result(RPC_PORT_ERROR_NONE);
}
-)__c_cb";
-const char CB_DELEGATE_DESERIALIZER[] =
-R"__c_cb(
-static void __##_from(rpc_port_parcel_h parcel, void *data)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h)
{
- struct ##_s *handle = data;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_t *handle;
+ static int seq_num;
- if (!handle) {
- _E("Invalid parameter");
- return;
- }
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- rpc_port_parcel_read_int32(parcel, &handle->id);
- rpc_port_parcel_read_int32(parcel, &handle->seq_id);
- rpc_port_parcel_read_bool(parcel, &handle->once);
- _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_<DELEGATE_NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_<DELEGATE_NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_<DELEGATE_NAME>_from;
+ handle->id = <DELEGATE_ENUM_VALUE>;
+ handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+ _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_DELEGATE_CTOR[] =
-R"__c_cb(
-rpc_port_##_h rpc_port_##_create(## callback, bool once, void *user_data)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h)
{
- struct ##_s *handle;
- static int seq_num;
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- handle = calloc(1, sizeof(struct ##_s));
- if (!handle) {
- _E("Out of memory");
- return NULL;
- }
+ _W("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
- handle->parcelable.to = __##_to;
- handle->parcelable.from= __##_from;
- handle->id = $$_DELEGATE_$$;
- handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
- handle->callback = callback;
- handle->once = once;
- handle->user_data = user_data;
- _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+ free(h);
- return handle;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_DELEGATE_DISPOSER[] =
-R"__c_cb(
-int rpc_port_proxy_##_dispose(rpc_port_proxy_$$_h proxy, rpc_port_##_h delegate)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone)
{
- struct ##_s *handle;
- GList *iter;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h handle;
+ rpc_port_parcel_h parcel;
+ int ret;
+
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_<DELEGATE_NAME>_create(&handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ ret = rpc_port_parcel_create(&parcel);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret);
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(handle);
+ return ret;
+ }
+
+ rpc_port_parcel_write(parcel, &h->parcelable, h);
+ rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+ ret = get_last_result();
+ rpc_port_parcel_destroy(parcel);
+
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret);
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(handle);
+ return ret;
+ }
+
+ handle->callback = h->callback;
+ handle->user_data = h->user_data;
+
+ *clone = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
- if (!proxy || !delegate) {
- _E("Invalid handle %p %p", proxy, delegate);
- return -1;
- }
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_callback(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback, void *user_data)
+{
+ if (h == nullptr || callback == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- iter = proxy->delegates;
- while (iter) {
- handle = (struct ##_s *)iter->data;
- if (handle == delegate) {
- _W("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
- proxy->delegates = g_list_remove_link(proxy->delegates, iter);
- free(handle);
- g_list_free(iter);
- return 0;
- }
- iter = g_list_next(iter);
- }
+ h->callback = callback;
+ h->user_data = user_data;
- return -1;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_DELEGATE_DTOR[] =
-R"__c_cb(
-int rpc_port_##_destroy(rpc_port_##_h delegate)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool once)
{
- if (!delegate) {
- _E("Invalid parameter");
- return -1;
- }
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- free(delegate);
+ h->once = once;
- return 0;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_DELEGATE_INVOKER[] =
-R"__c_cb(
-static void __$$_delegate_$$(GList **list, rpc_port_parcel_h parcel, int seq_id, int id)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id)
{
-$$
- do {
- struct ##_s *handle;
- GList *iter;
-
- iter = *list;
- while (iter) {
- handle = (struct ##_s *)iter->data;
- if (handle->seq_id == seq_id && handle->id == id) {
- bool once = handle->once;
-
- _W("Invoke id(%d), seq_id(%d)", id, seq_id);
- $$
- if (once) {
- _W("Dispose");
- *list = g_list_remove_link(*list, iter);
- free(handle);
- g_list_free(iter);
- }
- break;
- }
- iter = g_list_next(iter);
- }
- } while (0);
-$$
+ if (h == nullptr || id == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *id = h->id;
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_PROCESS_RECEIVED_EVENT[] =
-R"__c_cb(
-static void __##_process_received_event(GList **list, rpc_port_parcel_h parcel)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id)
{
-$$
+ if (h == nullptr || seq_id == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *seq_id = h->seq_id;
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_PROCESS_RECEIVED_EVENT_IMPL[] =
-R"__c_cb(int id;
-int seq_id;
-bool once;
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once)
+{
+ if (h == nullptr || once == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
-rpc_port_parcel_read_int32(parcel, &id);
-rpc_port_parcel_read_int32(parcel, &seq_id);
-rpc_port_parcel_read_bool(parcel, &once);
-_W("id(%d), seq_id(%d)", id, seq_id);
+ *once = h->once;
-if (id > 0 && id < (sizeof(__##_delegate_table) / sizeof(__##_delegate_table[0]))) {
- if (__##_delegate_table[id])
- __##_delegate_table[id](list, parcel, seq_id, id);
-} else {
- _W("Unknown id(%d)", id);
-})__c_cb";
+ return RPC_PORT_ERROR_NONE;
+}
-const char CB_CONSUME_COMMAND[] =
-R"__c_cb(
-static rpc_port_parcel_h __##_consume_command(rpc_port_proxy_##_h h)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag)
{
- rpc_port_parcel_h parcel = NULL;
- int cmd = -1;
+ char *new_tag;
+ char buf[128];
- do {
- rpc_port_parcel_create_from_port(&parcel, h->port);
- if (!parcel)
- break;
+ if (h == nullptr || tag == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- rpc_port_parcel_read_int32(parcel, &cmd);
- if (cmd == ##_METHOD_Result)
- return parcel;
+ snprintf(buf, sizeof(buf), "%d::%d", h->id, h->seq_id);
+ new_tag = strdup(buf);
+ if (new_tag == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
- rpc_port_parcel_destroy(parcel);
- parcel = NULL;
- } while (true);
+ *tag = new_tag;
- return NULL;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_ON_CONNECTED[] =
-R"__c_cb(
-static void __##_on_connected(const char *endpoint, const char *port_name, rpc_port_h port, void *data)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose(<PREFIX>_<NAME>_h proxy, <PREFIX>_<NAME>_<DELEGATE_NAME>_h h)
{
- rpc_port_proxy_##_h handle = data;
+ GList *found;
+
+ if (proxy == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&proxy->mutex);
+ found = g_list_find(proxy->delegates, h);
+ if (found == nullptr) {
+ _E("Invalid parameter");
+ g_rec_mutex_unlock(&proxy->mutex);
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ proxy->delegates = g_list_remove_link(proxy->delegates, found);
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(h);
+ g_list_free(found);
+ g_rec_mutex_unlock(&proxy->mutex);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_delegate_handler(GList **delegates, rpc_port_parcel_h parcel, int id, int seq_id)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h handle;
+ GList *iter;
+ bool once;
+ <DELEGATE_ARGS_DECL>
+
+ <DELEGATE_PARCEL_READ>
+
+ iter = *delegates;
+ while (iter) {
+ handle = iter->data;
+ iter = g_list_next(iter);
+ if (handle->id == id && handle->seq_id == seq_id) {
+ once = handle->once;
+ _W("Invoke id(%d), seq_id(%d)", id, seq_id);
+ if (handle->callback)
+ handle->callback(handle->user_data<DELEGATE_CALLBACK_ARGS>);
+ else
+ _W("The callback function is nullptr");
+
+ if (once) {
+ *delegates = g_list_remove(*delegates, handle);
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(handle);
+ }
+
+ break;
+ }
+ }
- handle->port = port;
- rpc_port_proxy_get_port(handle->proxy, RPC_PORT_PORT_CALLBACK, &handle->callback_port);
- if (handle->callback.connected)
- handle->callback.connected(handle, handle->user_data);
- _I("[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
+<GOTO_STATEMENT>
+ <DELEGATE_ARGS_FREE>
}
)__c_cb";
-const char CB_ON_DISCONNECTED[] =
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_READ[] =
R"__c_cb(
-static void __##_on_disconnected(const char *endpoint, const char *port_name, void *data)
-{
- rpc_port_proxy_##_h handle = data;
+<PREFIX>_<NAME>_create(&<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to create handle");
+ goto out;
+}
- handle->port = NULL;
- if (handle->callback.disconnected)
- handle->callback.disconnected(handle, handle->user_data);
- _I("[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+if (get_last_result() != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data");
+ goto out;
}
)__c_cb";
-const char CB_ON_REJECTED[] =
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_READ[] =
R"__c_cb(
-static void __##_on_rejected(const char *endpoint, const char *port_name, void *data)
-{
- rpc_port_proxy_##_h handle = data;
+rpc_port_parcel_read_bundle(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ goto out;
+}
+)__c_cb";
- handle->port = NULL;
- if (handle->callback.rejected)
- handle->callback.rejected(handle, handle->user_data);
- _I("[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_STRING_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_string(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ goto out;
}
)__c_cb";
-const char CB_ON_RECEIVED[] =
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE_PARCEL_READ[] =
R"__c_cb(
-static void __##_on_received(const char *endpoint, const char *port_name, void *data)
-{
- rpc_port_proxy_##_h handle = data;
- rpc_port_parcel_h parcel_received = NULL;
- int cmd = -1;
-
- rpc_port_parcel_create_from_port(&parcel_received, handle->callback_port);
- if (!parcel_received) {
- _E("Failed to create parcel from port(%s)", port_name);
- return;
- }
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &<ARG>);
+)__c_cb";
- rpc_port_parcel_read_int32(parcel_received, &cmd);
- if (cmd != ##_METHOD_Callback) {
- _E("Invalid protocol");
- rpc_port_parcel_destroy(parcel_received);
- return;
- }
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_USER_DEFINED_ARG_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ <PREFIX>_<NAME>_destroy(<ARG>);
+)__c_cb";
- __##_process_received_event(&handle->delegates, parcel_received);
- rpc_port_parcel_destroy(parcel_received);
- _I("[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
-}
+/**
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BUNDLE_ARG_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ bundle_free(<ARG>);
)__c_cb";
-const char CB_INTERFACE_METHODS[] =
+/**
+ * <ARG> The name of the value;
+ */
+constexpr const char CB_INTERFACE_DELEGATE_STRING_ARG_FREE[] =
R"__c_cb(
-$$rpc_port_proxy_##_invoke_$$(rpc_port_proxy_##_h h$$)
-{
- rpc_port_parcel_h parcel;
- int r;
-$$
+if (<ARG>)
+ free(<ARG>);
+)__c_cb";
- if (!h$$) {
- _E("Invalid parameter");
- return$$;
- }
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_HANDLERS> The array of the delegate callbacks.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_TABLE[] =
+R"__c_cb(
+static rpc_port_proxy_delegate_cb __<PREFIX>_<NAME>_delegate_table[] = {
+ <DELEGATE_HANDLERS>
+};
+)__c_cb";
- if (!h->port) {
- _E("Not connected");
- return$$;
- }
-$$
- rpc_port_parcel_create(&parcel);
- rpc_port_parcel_write_int32(parcel, ##_METHOD_$$);
-$$
- r = rpc_port_parcel_send(parcel, h->port);
- if (r != RPC_PORT_ERROR_NONE) {
- _E("Failed to send parcel. result(%d)", r);
- r = RPC_PORT_ERROR_IO_ERROR;
- }
+/**
+ * <ENUM_VALUE> The enumeration value.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_TABLE_MEMBER[] =
+R"__c_cb(
+[<ENUM_VALUE>] = __<PREFIX>_<NAME>_<DELEGATE_NAME>_delegate_handler,
+)__c_cb";
- rpc_port_parcel_destroy(parcel);
-$$
-}
+/**
+ * <ENUMS> The enumerations of the interface method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM_BASE[] =
+R"__c_cb(
+typedef enum {
+ <ENUMS>
+} <PREFIX>_<NAME>_method_e;
)__c_cb";
-const char CB_INTERFACE_HANDLE_CTOR[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE_DEF[] =
R"__c_cb(
-static struct ##_s *__create_##(const char *stub_appid, rpc_port_proxy_##_callback_s *callback, void *user_data)
+typedef struct <PREFIX>_<NAME>_s {
+ char *stub_appid;
+ rpc_port_proxy_h proxy;
+ rpc_port_h port;
+ rpc_port_h callback_port;
+ <PREFIX>_<NAME>_callback_s callback;
+ void *user_data;
+ GList *delegates;
+ GRecMutex mutex;
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_process_received_event(GList **delegates, rpc_port_parcel_h parcel)
{
- struct ##_s *handle;
+ int id = 0;
+ int seq_id = 0;
+ bool once = false;
+ static const int table_size = ARRAY_SIZE(__<PREFIX>_<NAME>_delegate_table);
+
+ rpc_port_parcel_read_int32(parcel, &id);
+ rpc_port_parcel_read_int32(parcel, &seq_id);
+ rpc_port_parcel_read_bool(parcel, &once);
+ _W("id(%d), seq_id(%d)", id, seq_id);
+
+ if (id > 0 && id < table_size) {
+ if (__<PREFIX>_<NAME>_delegate_table[id])
+ __<PREFIX>_<NAME>_delegate_table[id](delegates, parcel, id, seq_id);
+ } else {
+ _W("Unknown ID(%d)", id);
+ }
+}
- handle = calloc(1, sizeof(struct ##_s));
- if (!handle) {
- _E("Out of memory");
- return NULL;
+static void __<PREFIX>_<NAME>_consume_command(rpc_port_h port, rpc_port_parcel_h *p)
+{
+ rpc_port_parcel_h parcel;
+ int cmd = -1;
+ int ret;
+
+ do {
+ ret = rpc_port_parcel_create_from_port(&parcel, port);
+ if (ret != RPC_PORT_ERROR_NONE)
+ break;
+
+ rpc_port_parcel_read_int32(parcel, &cmd);
+ if (cmd == <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_RESULT_) {
+ *p = parcel;
+ return;
}
- handle->stub_appid = strdup(stub_appid);
- if (!handle->stub_appid) {
- _E("Out of memory");
- free(handle);
- return NULL;
- }
+ rpc_port_parcel_destroy(parcel);
+ } while (true);
- rpc_port_proxy_create(&handle->proxy);
- if (!handle->proxy) {
- _E("Failed to create proxy");
- free(handle->stub_appid);
- free(handle);
- return NULL;
- }
+ *p = nullptr;
+}
- g_rec_mutex_init(&handle->mutex);
+static void __<PREFIX>_<NAME>_connected(const char *endpoint, const char *port_name, rpc_port_h port, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
- handle->callback = *callback;
- handle->user_data = user_data;
+ _I("endpoint(%s), port_name(%s)", endpoint, port_name);
+ h->port = port;
+ rpc_port_proxy_get_port(h->proxy, RPC_PORT_PORT_CALLBACK, &h->callback_port);
+ h->callback.connected(h, h->user_data);
+}
+
+static void __<PREFIX>_<NAME>_disconnected(const char *endpoint, const char *port_name, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+
+ _W("endpoint(%s), port_name(%s)", endpoint, port_name);
+ h->port = nullptr;
+ h->callback.disconnected(h, h->user_data);
- return handle;
}
-)__c_cb";
-const char CB_INTERFACE_HANDLE_DTOR[] =
-R"__c_cb(
-static void __destroy_##(struct ##_s *h)
+static void __<PREFIX>_<NAME>_rejected(const char *endpoint, const char *port_name, void *data)
{
- if (!h)
- return;
+ <PREFIX>_<NAME>_h h = data;
- g_rec_mutex_clear(&h->mutex);
+ _W("endpoint(%s), port_name(%s)", endpoint, port_name);
+ h->port = nullptr;
+ h->callback.rejected(h, h->user_data);
+}
+
+static void __<PREFIX>_<NAME>_received(const char *endpoint, const char *port_name, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+ rpc_port_parcel_h parcel;
+ int cmd = -1;
+ int ret;
+
+ _W("endpoint(%s), port_name(%s)", endpoint, port_name);
+ ret = rpc_port_parcel_create_from_port(&parcel, h->callback_port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle from port. error(%d)", ret);
+ return;
+ }
+
+ rpc_port_parcel_read_int32(parcel, &cmd);
+ if (cmd != <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_CALLBACK_) {
+ _E("Invalid protocol");
+ rpc_port_parcel_destroy(parcel);
+ return;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ __<PREFIX>_<NAME>_process_received_event(&h->delegates, parcel);
+ g_rec_mutex_unlock(&h->mutex);
+ rpc_port_parcel_destroy(parcel);
+}
+
+int <PREFIX>_<NAME>_create(const char *stub_appid, <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+ int ret;
+
+ if (stub_appid == nullptr || callback == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (callback->connected == nullptr || callback->disconnected == nullptr || callback->rejected == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ g_rec_mutex_init(&handle->mutex);
+
+ handle->stub_appid = strdup(stub_appid);
+ if (handle->stub_appid == nullptr) {
+ _E("Failed to duplicate stub appid");
+ <PREFIX>_<NAME>_destroy(handle);
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = rpc_port_proxy_create(&handle->proxy);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create proxy handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ handle->callback = *callback;
+ handle->user_data = user_data;
+
+ ret = rpc_port_proxy_add_connected_event_cb(handle->proxy, __<PREFIX>_<NAME>_connected, handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add connected event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = rpc_port_proxy_add_disconnected_event_cb(handle->proxy, __<PREFIX>_<NAME>_disconnected, handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add disconnected event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = rpc_port_proxy_add_rejected_event_cb(handle->proxy, __<PREFIX>_<NAME>_rejected, handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add rejected event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = rpc_port_proxy_add_received_event_cb(handle->proxy, __<PREFIX>_<NAME>_received, handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add received event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- if (h->delegates)
- g_list_free_full(h->delegates, free);
+ g_rec_mutex_lock(&h->mutex);
+ g_rec_mutex_unlock(&h->mutex);
+ g_rec_mutex_clear(&h->mutex);
- if (h->proxy)
- rpc_port_proxy_destroy(h->proxy);
+ if (h->delegates)
+ g_list_free_full(h->delegates, free);
- if (h->stub_appid)
- free(h->stub_appid);
+ if (h->proxy)
+ rpc_port_proxy_destroy(h->proxy);
- free(h);
+ if (h->stub_appid)
+ free(h->stub_appid);
+
+ free(h);
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_INTERFACE_CTOR[] =
-R"__c_cb(
-int rpc_port_proxy_##_create(const char *stub_appid, rpc_port_proxy_##_callback_s *callback, void *user_data, rpc_port_proxy_##_h *h)
+int <PREFIX>_<NAME>_connect(<PREFIX>_<NAME>_h h)
{
- struct ##_s *handle;
- int r;
+ int ret;
- if (!stub_appid || !callback || !h) {
- _E("Invalid parameter");
- return -1;
- }
+ if (h == nullptr || h->proxy == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- handle = __create_##(stub_appid, callback, user_data);
- if (!handle)
- return -1;
+ ret = rpc_port_proxy_connect(h->proxy, h->stub_appid, "<NAME>");
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to connect to stub. error(%d)", ret);
+ return ret;
+ }
- r = rpc_port_proxy_add_connected_event_cb(handle->proxy, __##_on_connected, handle);
- if (r != 0) {
- _E("Failed to add connected event cb. err = %d", r);
- __destroy_##(handle);
- return r;
- }
+ return RPC_PORT_ERROR_NONE;
+}
- r = rpc_port_proxy_add_disconnected_event_cb(handle->proxy, __##_on_disconnected, handle);
- if (r != 0) {
- _E("Failed to add disconnected event cb. err = %d", r);
- __destroy_##(handle);
- return r;
- }
+int <PREFIX>_<NAME>_connect_sync(<PREFIX>_<NAME>_h h)
+{
+ int ret;
- r = rpc_port_proxy_add_rejected_event_cb(handle->proxy, __##_on_rejected, handle);
- if (r != 0) {
- _E("Failed to add rejected event cb. err = %d", r);
- __destroy_##(handle);
- return r;
- }
+ if (h == nullptr || h->proxy == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- r = rpc_port_proxy_add_received_event_cb(handle->proxy, __##_on_received, handle);
- if (r != 0) {
- _E("Failed to add received event cb. err = %d", r);
- __destroy_##(handle);
- return r;
- }
+ ret = rpc_port_proxy_connect_sync(h->proxy, h->stub_appid, "<NAME>");
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to connect to stub. error(%d)", ret);
+ return ret;
+ }
- *h = handle;
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_disconnect(<PREFIX>_<NAME>_h h)
+{
+ int ret;
- return 0;
+ if (h == nullptr || h->proxy == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = rpc_port_disconnect(h->port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to disconnect from stub. error(%d)", ret);
+ return ret;
+ }
+
+ return RPC_PORT_ERROR_NONE;
}
)__c_cb";
-const char CB_INTERFACE_CONNECT[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_PARAMS> The parameters of the method of the interface
+ * <METHOD_PARAMS_CHECK> The parameters check of the method.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ * <METHOD_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ * <METHOD_DELEGATES_APPEND> The implementation to add the delegates to the list.
+ */
+constexpr const char CB_INTERFACE_METHOD_ASYNC_BASE[] =
R"__c_cb(
-int rpc_port_proxy_##_connect(rpc_port_proxy_##_h h)
+void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
{
- int r;
+ rpc_port_parcel_h parcel_;
+ rpc_port_parcel_header_h header_;
+ int seq_num_ = -1;
+ int res_;
+
+ if (h == nullptr<METHOD_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ if (h->port == nullptr) {
+ _E("Not connected");
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ res_ = rpc_port_parcel_create(&parcel_);
+ if (res_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", res_);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(res_);
+ return;
+ }
+
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+
+ rpc_port_parcel_write_int32(parcel_, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
+
+ <METHOD_PARCEL_WRITE>
+ <METHOD_DELEGATE_APPEND>
+
+ res_ = rpc_port_parcel_send(parcel_, h->port);
+ rpc_port_parcel_destroy(parcel_);
+ if (res_ != RPC_PORT_ERROR_NONE)
+ _E("Failed to send parcel. error(%d)", res_);
+
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(res_);
+}
+)__c_cb";
- if (!h || !h->proxy) {
- _E("Invalid parameter");
- return -1;
+/**
+ * <RETURN_TYPE> The return type of the method of the interface.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_ARGS> The value declarations for reading the data from the parcel.
+ * <ERROR_VALUE> The error value of the method.
+ * <METHOD_PARAMS> The parameters of the method of the interface.
+ * <METHOD_PARAMS_CHECK> The parameters check of the method.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ * <METHOD_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ * <METHOD_PARCEL_READ> The implementation to read results from the parcel.
+ * <METHOD_DELEGATE_APPEND> The implementation to add the delegates to the list.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE[] =
+R"__c_cb(
+<RETURN_TYPE><PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
+{
+ rpc_port_parcel_h parcel_;
+ rpc_port_parcel_header_h header_;
+ int seq_num_ = -1;
+ int recv_seq_num_ = -1;
+ char *tag_ = nullptr;
+ bool done_ = false;
+ int res_;
+ <RETURN_TYPE>ret_ = <ERROR_VALUE>;
+ <METHOD_ARGS>
+
+ if (h == nullptr<METHOD_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return ret_;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ if (h->port == nullptr) {
+ _E("Not connected");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ g_rec_mutex_unlock(&h->mutex);
+ return ret_;
+ }
+
+ res_ = rpc_port_parcel_create(&parcel_);
+ if (res_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", res_);
+ set_last_result(res_);
+ g_rec_mutex_unlock(&h->mutex);
+ return ret_;
+ }
+
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+
+ rpc_port_parcel_write_int32(parcel_, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
+
+ <METHOD_PARCEL_WRITE>
+ <METHOD_DELEGATE_APPEND>
+
+ res_ = rpc_port_parcel_send(parcel_, h->port);
+ rpc_port_parcel_destroy(parcel_);
+ if (res_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to send parcel. error(%d)", res_);
+ set_last_result(res_);
+ g_rec_mutex_unlock(&h->mutex);
+ return ret_;
+ }
+
+ do {
+ parcel_ = nullptr;
+ __<PREFIX>_<NAME>_consume_command(h->port, &parcel_);
+ if (parcel_ == nullptr) {
+ _E("Invalid protocol");
+ res_ = RPC_PORT_ERROR_IO_ERROR;
+ break;
}
- r = rpc_port_proxy_connect(h->proxy, h->stub_appid, "##");
- if (r != 0) {
- _E("Failed to connect ##(%s)", h->stub_appid);
- return r;
+ header_ = nullptr;
+ rpc_port_parcel_get_header(parcel_, &header_);
+ tag_ = nullptr;
+ rpc_port_parcel_header_get_tag(header_, &tag_);
+ if (tag_ && tag_[0] != '\0') {
+ rpc_port_parcel_header_get_seq_num(header_, &recv_seq_num_);
+ if (recv_seq_num_ != seq_num_) {
+ _E("Invalid protocol. %d", recv_seq_num_);
+ free(tag_);
+ rpc_port_parcel_destroy(parcel_);
+ continue;
+ }
}
+ done_ = true;
+ free(tag_);
- return 0;
+ <METHOD_PARCEL_READ>
+ rpc_port_parcel_destroy(parcel_);
+ } while (!done_);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(res_);
+
+ return ret_;
}
)__c_cb";
-const char CB_INTERFACE_DTOR[] =
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE[] =
R"__c_cb(
-int rpc_port_proxy_##_destroy(rpc_port_proxy_##_h h)
-{
- if (!h) {
- _E("Invalid parameter");
- return -1;
- }
+rpc_port_parcel_write(parcel_, &<ARG>->parcelable, <ARG>);
+)__c_cb";
- __destroy_##(h);
- return 0;
-}
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel_, <ARG>);
)__c_cb";
-const char CB_DELEGATE_BLOCK[] =
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_WRITE[] =
R"__c_cb(
-do {
- struct ##_s *handle = $$;
+rpc_port_parcel_write_string(parcel_, <ARG>);
+)__c_cb";
- rpc_port_parcel_write(parcel, &handle->parcelable, handle);
- h->delegates = g_list_append(h->delegates, handle);
-} while (0);
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel_, <ARG>);
)__c_cb";
-const char CB_RECEIVE_BLOCK[] =
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ[] =
R"__c_cb(
-g_rec_mutex_lock(&h->mutex);
-do {
- rpc_port_parcel_h parcel_received;
-$$
- parcel_received = __$$_consume_command(h);
- if (!parcel_received) {
- _E("Invalid protocol");
- r = RPC_PORT_ERROR_IO_ERROR;
- break;
- }
+<ARG> = nullptr;
+<PREFIX>_<NAME>_create(&<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to create handle");
+ res_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ break;
+}
-$$
- rpc_port_parcel_destroy(parcel_received);
-} while (0);
-g_rec_mutex_unlock(&h->mutex);
+rpc_port_parcel_read(parcel_, &<ARG>->parcelable, <ARG>);
+if (get_last_result() != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data");
+ <PREFIX>_<NAME>_destroy(<ARG>);
+ <ARG> = nullptr;
+ res_ = get_last_result();
+ break;
+}
)__c_cb";
-const char CB_LIST_PRIVATE_SHARING_BLOCK[] =
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ[] =
R"__c_cb(
- r = __file_list_set_private_sharing(h->port, ##->list_files);
- if (r != RPC_PORT_ERROR_NONE) {
- _E("Fail to set private sharing");
- return ret;
- }
+<ARG> = nullptr;
+rpc_port_parcel_read_bundle(parcel_, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ res_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ break;
+}
)__c_cb";
-const char CB_ARRAY_PRIVATE_SHARING_BLOCK[] =
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_READ[] =
R"__c_cb(
- r = __file_array_set_private_sharing(h->port,
- (const char **)##->array_files, ##->array_files_size);
- if (r != RPC_PORT_ERROR_NONE) {
- _E("Fail to set private sharing");
- return ret;
- }
+<ARG> = nullptr;
+rpc_port_parcel_read_string(parcel_, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ res_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ break;
+}
)__c_cb";
-const char CB_PRIVATE_SHARING_BLOCK[] =
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_READ[] =
R"__c_cb(
- r = rpc_port_set_private_sharing(h->port, ##);
- if (r != RPC_PORT_ERROR_NONE) {
- _E("Fail to set private sharing");
- return ret;
- }
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel_, &<ARG>);
)__c_cb";
-const char CB_INTERFACE_CONNECT_SYNC[] =
+/**
+ * <PARAM> The name of the parameter.
+ */
+constexpr const char CB_INTERFACE_METHOD_PARAM_SET[] =
R"__c_cb(
-int rpc_port_proxy_##_connect_sync(rpc_port_proxy_##_h h)
-{
- int r;
-
- if (!h || !h->proxy) {
- _E("Invalid parameter");
- return -1;
- }
-
- r = rpc_port_proxy_connect_sync(h->proxy, h->stub_appid, "##");
- if (r != 0) {
- _E("Failed to connect sync ##(%s)", h->stub_appid);
- return r;
- }
+*<PARAM> = new_<PARAM>;
+)__c_cb";
- return 0;
-}
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_DELEGATE_APPEND[] =
+R"__c_cb(
+h->delegates = g_list_append(h->delegates, <ARG>);
)__c_cb";
#endif // IDLC_C_GEN_C_PROXY_BODY_GEN_CB_H_
diff --git a/idlc/gen/c_proxy_header_gen.cc b/idlc/gen/c_proxy_header_gen.cc
index b5bca94..3668a44 100644
--- a/idlc/gen/c_proxy_header_gen.cc
+++ b/idlc/gen/c_proxy_header_gen.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,13 +23,16 @@ namespace {
namespace tidl {
CProxyHeaderGen::CProxyHeaderGen(std::shared_ptr<Document> doc)
- : CHeaderGeneratorBase(doc) {}
+ : CHeaderGeneratorBase(doc) {
+}
void CProxyHeaderGen::OnInitGen(std::ofstream& stream) {
GenVersion(stream);
GenPragmaOnce(stream);
GenIncludeDefaultHeaders(stream, false);
GenExplicitLinkageOpen(stream);
+ GenStructureHandles(stream);
+ GenInterfaceHandles(stream);
GenStructures(stream);
GenInterfaces(stream);
}
@@ -38,138 +41,138 @@ void CProxyHeaderGen::OnFiniGen(std::ofstream& stream) {
GenExplicitLinkageClose(stream);
}
+void CProxyHeaderGen::GenInterfaceHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceHandle(stream, iface);
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateHandle(stream, iface, *d);
+ }
+ }
+}
+
+// @see #CB_INTERFACE_HANDLE
+void CProxyHeaderGen::GenInterfaceHandle(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_HANDLE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_DELEGATE_HANDLE
+void CProxyHeaderGen::GenInterfaceDelegateHandle(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_DELEGATE_HANDLE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", decl.GetID() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
void CProxyHeaderGen::GenInterfaces(std::ofstream& stream) {
for (auto& i : GetDocument().GetBlocks()) {
if (i->GetType() != Block::TYPE_INTERFACE)
continue;
- const Interface &inf = static_cast<const Interface&>(*i);
- GenInterface(stream, inf);
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
}
}
void CProxyHeaderGen::GenInterface(std::ofstream& stream,
- const Interface& inf) {
- GenInterfaceDeclaration(stream, inf);
- GenInterfaceDelegators(stream, inf);
- GenInterfaceCtor(stream, inf);
- GenInterfaceConnect(stream, inf);
- GenInterfaceDtor(stream, inf);
- GenInterfaceMethods(stream, inf);
- GenInterfaceConnectSync(stream, inf);
-}
+ const Interface& iface) {
+ for (const auto& d: iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateBase(stream, iface, *d);
+ }
+
+ GenInterfaceBase(stream, iface);
-void CProxyHeaderGen::GenInterfaceDelegators(std::ofstream& stream,
- const Interface& inf) {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
- GenInterfaceDelegator(stream, GetInterfaceIdWithNamespace(inf), *i);
+
+ GenInterfaceMethodBase(stream, iface, *d);
}
}
-void CProxyHeaderGen::GenInterfaceDelegator(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- const char handle[] = "typedef struct $$_s *rpc_port_$$_h;";
-
- stream << NLine(1);
- stream << GenTemplateString(handle,
- [&]()->std::string {
- return id + "_" + decl.GetID();
- },
- [&]()->std::string {
- return id + "_" + decl.GetID();
- });
-
- stream << NLine(1);
- stream << GenTemplateString(CB_INTERFACE_DELEGATOR,
- [&]()->std::string {
- return GetReturnTypeString(decl.GetType());
- },
- [&]()->std::string {
- return id + "_" + decl.GetID();
- },
- [&]()->std::string {
- std::string str;
- str += "void *user_data";
- for (auto& p : decl.GetParameters().GetParams()) {
- str += ", ";
- str += GetParamTypeString(p->GetParameterType().GetDirection(),
- p->GetParameterType().GetBaseType()) + p->GetID();
- }
- return str;
- });
-
- stream << ReplaceAll(CB_DELEGATE_CTOR, "##", id + "_" + decl.GetID());
- stream << ReplaceAll(CB_DELEGATE_DTOR, "##", id + "_" + decl.GetID());
- stream << GenTemplateString(
- ReplaceAll(CB_DELEGATE_DISPOSER, "##", id + "_" + decl.GetID()),
- [&]()->std::string {
- return id;
- });
-}
+// @see #CB_INTERFACE_BASE
+void CProxyHeaderGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ }));
-void CProxyHeaderGen::GenInterfaceDeclaration(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_DECL, "##",
- GetInterfaceIdWithNamespace(inf)));
+ stream << SmartIndent(code);
}
-void CProxyHeaderGen::GenInterfaceMethods(std::ofstream& stream,
- const Interface& inf) {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
- continue;
- stream << GenTemplateString(
- ReplaceAll(CB_INTERFACE_METHODS, "##",
- GetInterfaceIdWithNamespace(inf)),
- [&]()->std::string {
- return GetReturnTypeString(i->GetType());
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- std::string str;
- for (auto& p : i->GetParameters().GetParams()) {
- str += ", ";
- if (IsDelegateType(inf, p->GetParameterType().GetBaseType())) {
- str += "rpc_port_" + GetInterfaceIdWithNamespace(inf) + "_" +
- p->GetParameterType().GetBaseType().ToString() +
- "_h " + p->GetID();
- } else {
- str += GetParamTypeString(p->GetParameterType().GetDirection(),
- p->GetParameterType().GetBaseType()) + p->GetID();
- }
- }
- return str;
- });
+std::string CProxyHeaderGen::GenDelegateParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
}
-}
-void CProxyHeaderGen::GenInterfaceCtor(std::ofstream& stream,
- const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CTOR, "##",
- GetInterfaceIdWithNamespace(inf));
+ return params;
}
-void CProxyHeaderGen::GenInterfaceConnect(std::ofstream& stream,
- const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CONNECT, "##",
- GetInterfaceIdWithNamespace(inf));
+// @see #CB_INTERFACE_DELEGATE_BASE
+void CProxyHeaderGen::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_DELEGATE_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", decl.GetID() },
+ { "<DELEGATE_PARAMS>", GenDelegateParams(iface, decl) }
+ }));
+
+ stream << SmartIndent(code);
}
-void CProxyHeaderGen::GenInterfaceDtor(std::ofstream& stream,
- const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_DTOR, "##",
- GetInterfaceIdWithNamespace(inf));
+std::string CProxyHeaderGen::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
}
-void CProxyHeaderGen::GenInterfaceConnectSync(std::ofstream& stream,
- const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CONNECT_SYNC, "##",
- GetInterfaceIdWithNamespace(inf));
+// @see #CB_INTERFACE_METHOD_BASE
+void CProxyHeaderGen::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_BASE, {
+ { "<RETURN_TYPE>", GetReturnTypeString(decl.GetType()) },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_PARAMS>", GenMethodParams(iface, decl) }
+ }));
+
+ stream << SmartIndent(code);
}
} // namespace tidl
diff --git a/idlc/gen/c_proxy_header_gen.h b/idlc/gen/c_proxy_header_gen.h
index 8dfa891..a11984e 100644
--- a/idlc/gen/c_proxy_header_gen.h
+++ b/idlc/gen/c_proxy_header_gen.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,21 +33,23 @@ class CProxyHeaderGen : public CHeaderGeneratorBase {
void OnFiniGen(std::ofstream& stream) override;
private:
+ void GenInterfaceHandles(std::ofstream& stream);
+ void GenInterfaceHandle(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateHandle(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+
void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
- private:
- void GenInterface(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDeclaration(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDelegators(std::ofstream& stream, const Interface& inf);
- void GenInterfaceMethods(std::ofstream& stream, const Interface& inf);
- void GenInterfaceCtor(std::ofstream& stream, const Interface& inf);
- void GenInterfaceConnect(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDtor(std::ofstream& stream, const Interface& inf);
- void GenInterfaceConnectSync(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& ifaceo,
+ const Declaration& decl);
- private:
- void GenInterfaceDelegator(std::ofstream& stream, const std::string& id,
- const Declaration& decl);
+ std::string GenDelegateParams(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
};
} // namespace tidl
diff --git a/idlc/gen/c_proxy_header_gen_cb.h b/idlc/gen/c_proxy_header_gen_cb.h
index e6849e1..b387f89 100644
--- a/idlc/gen/c_proxy_header_gen_cb.h
+++ b/idlc/gen/c_proxy_header_gen_cb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,62 +17,324 @@
#ifndef IDLC_C_GEN_C_PROXY_HEADER_GEN_CB_H_
#define IDLC_C_GEN_C_PROXY_HEADER_GEN_CB_H_
-const char CB_INTERFACE_DECL[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_HANDLE[] =
R"__c_cb(
-typedef struct ##_s *rpc_port_proxy_##_h;
-
-typedef struct {
- void (*connected)(rpc_port_proxy_##_h h, void *user_data);
- void (*disconnected)(rpc_port_proxy_##_h h, void *user_data);
- void (*rejected)(rpc_port_proxy_##_h h, void *user_data);
-} rpc_port_proxy_##_callback_s;
+/**
+ * @brief The <PREFIX>_<NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_s *<PREFIX>_<NAME>_h;
)__c_cb";
-const char CB_INTERFACE_CTOR[] =
+constexpr const char CB_INTERFACE_DELEGATE_HANDLE[] =
R"__c_cb(
-int rpc_port_proxy_##_create(const char *stub_appid,
- rpc_port_proxy_##_callback_s *callback, void *user_data,
- rpc_port_proxy_##_h *h);
+/**
+ * @brief The <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s *<PREFIX>_<NAME>_<DELEGATE_NAME>_h;
)__c_cb";
-const char CB_INTERFACE_CONNECT[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate.
+ * <DELEGATE_PARAMS> The parameters of the callback function.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
R"__c_cb(
-int rpc_port_proxy_##_connect(rpc_port_proxy_##_h h);
-)__c_cb";
+/**
+ * @brief Called when the event is received.
+ *
+ * @param[in] user_data The user data passed from the callback registration function
+ * @param[in] ...
+ *
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_create()
+ */
+typedef void (*<PREFIX>_<NAME>_<DELEGATE_NAME>_cb)(void *user_data<DELEGATE_PARAMS>);
-const char CB_INTERFACE_DTOR[] =
-R"__c_cb(
-int rpc_port_proxy_##_destroy(rpc_port_proxy_##_h h);
-)__c_cb";
+/**
+ * @brief Creates a <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[out] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memorya
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose()
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_set_callback()
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_set_once()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h);
-const char CB_INTERFACE_METHODS[] =
-R"__c_cb(
-$$rpc_port_proxy_##_invoke_$$(rpc_port_proxy_##_h h$$);
-)__c_cb";
+/**
+ * @brief Destroys the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_create()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h);
-const char CB_INTERFACE_DELEGATOR[] =
-R"__c_cb(
-typedef $$(*$$)($$);
-)__c_cb";
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME>_<DELEGATE_NAME> should be released using
+ * the <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME>_<DELEGATE_NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone);
-const char CB_DELEGATE_CTOR[] =
-R"__c_cb(
-rpc_port_##_h rpc_port_##_create(## callback, bool once, void *user_data);
-)__c_cb";
+/**
+ * @brief Sets the callback function to the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[in] callback The callback function
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_callback(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback, void *user_data);
-const char CB_DELEGATE_DISPOSER[] =
-R"__c_cb(
-int rpc_port_proxy_##_dispose(rpc_port_proxy_$$_h proxy, rpc_port_##_h delegate);
+/**
+ * @brief Set the once flag to the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ * @details If the once flag is 'true', the delegate handle will be deleted after invocation.
+ * If the @a h handle is not used using the method, the handle should be released using
+ * the <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy() when it's no longer needed.
+ * If you don't want the delegate callback function to be called after it's used using the method,
+ * you should release the handle using the <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose().
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[in] once The flag if it's true, the delegate will be deleted after invocation
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool once);
+
+/**
+ * @brief Gets the ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] id The ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id);
+
+/**
+ * @brief Gets the sequence ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] seq_id The Sequence ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id);
+
+/**
+ * @brief Checks whether the delegate is for one-time or not.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] once The flag, it's true, the handle is for one-time
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once);
+
+/**
+ * @brief Gets the tag from the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks The @a tag should be released using free().
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] tag The tag
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag);
+
+/**
+ * @brief Disposes the <PREFIX>_<NAME>_<DELEGATE_NAME> handle from the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] proxy The <PREFIX>_<NAME> handle
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_create()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose(<PREFIX>_<NAME>_h proxy, <PREFIX>_<NAME>_<DELEGATE_NAME>_h h);
)__c_cb";
-const char CB_DELEGATE_DTOR[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
R"__c_cb(
-int rpc_port_##_destroy(rpc_port_##_h delegate);
+/**
+ * @brief Called when the proxy is connected.
+ * @details The callback function is called when the proxy is connected to the stub.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] user_data The user data passed from the registeration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_connected_cb)(<PREFIX>_<NAME>_h h, void *user_data);
+
+/**
+ * @brief Called when the proxy is disconnected.
+ * @details The callback function is called when the proxy is disconnected from the stub.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] user_data The user data passed from the registeration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_disconnected_cb)(<PREFIX>_<NAME>_h h, void *user_data);
+
+/**
+ * @brief Called when the proxy is rejected.
+ * @details The callback function is called when the proxy is rejected to connect to the stub.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] user_data The user data passed from the registeration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_rejected_cb)(<PREFIX>_<NAME>_h h, void *user_data);
+
+/**
+ * @brief The structure type containing the set of callback functions for handling proxy events.
+ * @details It is one of the input parameters of the <PREFIX>_<NAME>_create() function.
+ *
+ * @see <PREFIX>_<NAME>_connected_cb
+ * @see <PREFIX>_<NAME>_disconnected_cb
+ * @see <PREFIX>_<NAME>_rejected_cb
+ */
+typedef struct {
+ <PREFIX>_<NAME>_connected_cb connected; /**< This callback function is called when the proxy is connected to the stub. */
+ <PREFIX>_<NAME>_disconnected_cb disconnected; /**< This callback function is called when the proxy is disconnected from the stub. */
+ <PREFIX>_<NAME>_rejected_cb rejected; /**< This callback function is called when the proxy is rejected to connect to the stub. */
+} <PREFIX>_<NAME>_callback_s;
+
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ * @remarks The @a h handle should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ *
+ * @param[in] stub_appid The application ID of the stub
+ * @param[in] callback The set of callback functions to handle proxy events
+ * @param[in] user_data The user data to be passed to the callback function
+ * @param[out] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+int <PREFIX>_<NAME>_create(const char *stub_appid, <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Connects to the stub.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_IO_ERROR I/O error
+ * @retval #RPC_PORT_ERROR_PERMISSION_DENIED Permission denied
+ */
+int <PREFIX>_<NAME>_connect(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Connects to the stub synchronously.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_IO_ERROR I/O error
+ * @retval #RPC_PORT_ERROR_PERMISSION_DENIED Permission denied
+ */
+int <PREFIX>_<NAME>_connect_sync(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Disconnects from the stub.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_disconnect(<PREFIX>_<NAME>_h h);
)__c_cb";
-const char CB_INTERFACE_CONNECT_SYNC[] =
+/**
+ * <RETURN_TYPE> The type of the return value.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The of the interface.
+ * <METHOD_NAME> The name of the method.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE[] =
R"__c_cb(
-int rpc_port_proxy_##_connect_sync(rpc_port_proxy_##_h h);
+/**
+ * @brief Calls the <METHOD_NAME>() method.
+ * @details The return value and args are decided by the interface declaration.
+ * You can get the result using get_last_result().
+ * Before returning the function, the function sets the result using set_last_result().
+ * @remarks The specific error code can be obtained using the get_last_result() function. Error codes are described in Exception section.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] ...
+ * @exception #RPC_PORT_ERROR_NONE Successful
+ * @exception #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @exception #RPC_PORT_ERROR_IO_ERROR I/O error
+ */
+<RETURN_TYPE><PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>);
)__c_cb";
#endif // IDLC_C_GEN_C_PROXY_HEADER_GEN_CB_H_
diff --git a/idlc/gen/c_stub_body_gen.cc b/idlc/gen/c_stub_body_gen.cc
index 68c4a0a..d92af42 100644
--- a/idlc/gen/c_stub_body_gen.cc
+++ b/idlc/gen/c_stub_body_gen.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-#include "idlc/gen/c_stub_body_gen.h"
+#include <algorithm>
-namespace {
+#include "idlc/gen/c_stub_body_gen.h"
#include "idlc/gen/c_stub_body_gen_cb.h"
-}
namespace tidl {
CStubBodyGen::CStubBodyGen(std::shared_ptr<Document> doc,
std::shared_ptr<Options> options)
- : CBodyGeneratorBase(doc), options_(options) {}
+ : CBodyGeneratorBase(doc), options_(options) {
+}
void CStubBodyGen::OnInitGen(std::ofstream& stream) {
GenVersion(stream);
@@ -33,601 +33,700 @@ void CStubBodyGen::OnInitGen(std::ofstream& stream) {
GenIncludeHeader(stream);
GenLogTag(stream, std::string("RPC_PORT_STUB"));
GenLogDefinition(stream);
- GenTypedefStubMethod(stream);
+ GenVersionDefinition(stream);
+ GenBaseDefinition(stream);
+ GenThreadEnableDefinition(stream);
+ GenInterfaceMethodHandlerType(stream);
+ GenInterfaceEnums(stream);
+ GenStructureDefs(stream);
+ GenInterfaceDefs(stream);
+ GenPrivateSharingListSet(stream);
GenStructures(stream);
GenInterfaces(stream);
}
-void CStubBodyGen::OnFiniGen(std::ofstream& stream) {}
+void CStubBodyGen::OnFiniGen(std::ofstream& stream) {
+}
-void CStubBodyGen::GenInterfaces(std::ofstream& stream) {
- for (auto& i : GetDocument().GetBlocks()) {
- if (i->GetType() != Block::TYPE_INTERFACE)
+// @see #CB_THREAD_ENABLE_DEF
+void CStubBodyGen::GenThreadEnableDefinition(std::ofstream& stream) {
+ if (!options_->IsThreadEnabled())
+ return;
+
+ stream << std::string(CB_THREAD_ENABLE_DEF);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_TYPE
+void CStubBodyGen::GenInterfaceMethodHandlerType(std::ofstream& stream) {
+ stream << SmartIndent(CB_INTERFACE_METHOD_HANDLER_TYPE);
+}
+
+void CStubBodyGen::GenInterfaceEnums(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
continue;
- const Interface &inf = static_cast<const Interface&>(*i);
- GenInterface(stream, inf);
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceEnum(stream, iface);
}
}
-void CStubBodyGen::GenInterface(std::ofstream& stream, const Interface& inf) {
- GenInterfaceEnumerations(stream, inf);
- GenInterfaceGlobalVariables(stream, inf);
- GenInterfaceContext(stream, inf);
- GenInterfaceDelegators(stream, inf);
- GenInterfaceMethods(stream, inf);
- GenInterfaceMethodTable(stream, inf);
- GenInterfaceOnConnectedEventCB(stream, inf);
- GenInterfaceOnDisconnectedEventCB(stream, inf);
- GenInterfaceOnReceivedEventCB(stream, inf);
- GenInterfaceAddPrivileges(stream, inf);
- GenInterfaceRegister(stream, inf);
- GenInterfaceUnregister(stream, inf);
- GenInterfaceClientNumberGetter(stream, inf);
-}
-
-void CStubBodyGen::GenInterfaceMethods(std::ofstream& stream,
- const Interface& inf) {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+void CStubBodyGen::GenInterfaceEnum(std::ofstream& stream,
+ const Interface& iface) {
+ GenInterfaceMethodEnumBase(stream, iface);
+ GenInterfaceDelegateEnumBase(stream, iface);
+}
+
+// @see #CB_INTERFACE_METHOD_ENUM
+std::string CStubBodyGen::GenMethodEnums(const Interface& iface) {
+ std::string method_enum(ReplaceAll(CB_INTERFACE_METHOD_ENUM, {
+ { "<UPPERCASE_PREFIX>", GetHandlePrefix() },
+ { "<UPPERCASE_NAME>", iface.GetID() },
+ { "<UPPERCASE_METHOD_NAME>", "RESULT_" }
+ }));
+
+ std::string method_enums = RemoveLine(method_enum);
+
+ method_enum = ReplaceAll(CB_INTERFACE_METHOD_ENUM, {
+ { "<UPPERCASE_PREFIX>", GetHandlePrefix() },
+ { "<UPPERCASE_NAME>", iface.GetID() },
+ { "<UPPERCASE_METHOD_NAME>", "CALLBACK_" }
+ });
+
+ method_enums += RemoveLine(method_enum);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
- stream << SmartIndent(GenTemplateString(CB_INTERFACE_METHOD,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return GetMethodString(inf, *i);
- }));
+ method_enum = ReplaceAll(CB_INTERFACE_METHOD_ENUM, {
+ { "<UPPERCASE_PREFIX>", GetHandlePrefix() },
+ { "<UPPERCASE_NAME>", iface.GetID() },
+ { "<UPPERCASE_METHOD_NAME>", d->GetID() }
+ });
+
+ method_enums += RemoveLine(method_enum);
}
+ std::transform(method_enums.begin(), method_enums.end(), method_enums.begin(),
+ ::toupper);
+
+ return method_enums;
}
-void CStubBodyGen::GenInterfaceMethodTable(std::ofstream& stream,
- const Interface& inf) {
- std::string str;
- int cnt = 0;
+// @see #CB_INTERFACE_METHOD_ENUM_BASE
+void CStubBodyGen::GenInterfaceMethodEnumBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_ENUMS>", GenMethodEnums(iface) }
+ }));
+
+ stream << SmartIndent(code);
+}
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+// @see #CB_INTERFACE_DELEGATE_ENUM
+std::string CStubBodyGen::GenDelegateEnums(const Interface& iface) {
+ unsigned int num = 1;
+ std::string method_enums;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
continue;
- str += GenTemplateString(CB_INTERFACE_METHOD_FORMAT,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf) + "_METHOD_" + i->GetID();
- },
- [&]()->std::string {
- return "__" + GetInterfaceIdWithNamespace(inf) + "_method_"
- + i->GetID();
- });
- cnt++;
+
+ std::string method_enum(ReplaceAll(CB_INTERFACE_DELEGATE_ENUM, {
+ { "<UPPERCASE_PREFIX>", GetHandlePrefix() },
+ { "<UPPERCASE_NAME>", iface.GetID() },
+ { "<UPPERCASE_DELEGATE_NAME>", d->GetID() },
+ { "<NUMBER>", std::to_string(num++) }
+ }));
+
+ method_enums += RemoveLine(method_enum);
}
+ std::transform(method_enums.begin(), method_enums.end(), method_enums.begin(),
+ ::toupper);
- if (cnt == 0)
+ return method_enums;
+}
+
+// @see #CB_INTERFACE_DELEGATE_ENUM_BASE
+void CStubBodyGen::GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string delegate_enums = GenDelegateEnums(iface);
+ if (delegate_enums.empty())
return;
- stream << NLine(1);
- stream << SmartIndent(GenTemplateString(CB_INTERFACE_METHOD_TABLE,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return str;
- }));
-}
-
-void CStubBodyGen::GenInterfaceOnConnectedEventCB(std::ofstream& stream,
- const Interface& inf) {
- if (options_->IsThreadEnabled()) {
- stream << SmartIndent(
- ReplaceAll(CB_INTERFACE_THREAD_METHODS, "##",
- GetInterfaceIdWithNamespace(inf)));
+ std::string code(ReplaceAll(CB_INTERFACE_DELEGATE_ENUM_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_ENUMS>", delegate_enums }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+void CStubBodyGen::GenInterfaceDefs(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceDef(stream, iface);
+ }
+}
+
+void CStubBodyGen::GenInterfaceDef(std::ofstream& stream,
+ const Interface& iface) {
+ bool has_delegate = false;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateDef(stream, iface, *d);
+ has_delegate = true;
}
- stream << SmartIndent(
- ReplaceAll(CB_INTERFACE_ON_CONNECTED, "##",
- GetInterfaceIdWithNamespace(inf)));
+ if (has_delegate)
+ GenInterfaceCallbackPortCheckDef(stream, iface);
+
+ GenInterfaceContextDef(stream, iface);
+ GenInterfaceBaseDef(stream, iface);
}
-void CStubBodyGen::GenInterfaceOnDisconnectedEventCB(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(
- ReplaceAll(CB_INTERFACE_ON_DISCONNECTED, "##",
- GetInterfaceIdWithNamespace(inf)));
+// @see #CB_INTERFACE_DELEGATE_DEF
+void CStubBodyGen::GenInterfaceDelegateDef(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_DELEGATE_DEF, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", decl.GetID() }
+ }));
+
+ stream << SmartIndent(code);
}
-void CStubBodyGen::GenInterfaceOnReceivedEventCB(std::ofstream& stream,
- const Interface& inf) {
- if (options_->IsThreadEnabled()) {
- stream << SmartIndent(
- ReplaceAll(CB_INTERFACE_THREAD_ON_RECEIVED, "##",
- GetInterfaceIdWithNamespace(inf)));
- } else {
- stream << SmartIndent(
- ReplaceAll(CB_INTERFACE_ON_RECEIVED, "##",
- GetInterfaceIdWithNamespace(inf)));
+// @see #CB_INTERFACE_CALLBACK_PORT_CHECK_DEF
+void CStubBodyGen::GenInterfaceCallbackPortCheckDef(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_CALLBACK_PORT_CHECK_DEF, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_CONTEXT_DEF
+void CStubBodyGen::GenInterfaceContextDef(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_CONTEXT_DEF, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_BASE_DEF
+void CStubBodyGen::GenInterfaceBaseDef(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_BASE_DEF, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+void CStubBodyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
}
}
-void CStubBodyGen::GenInterfaceRegister(std::ofstream& stream,
- const Interface& inf) {
- std::string r_str = ReplaceAll(CB_INTERFACE_REGISTER, "##",
- GetInterfaceIdWithNamespace(inf));
-
- stream << SmartIndent(GenTemplateString(r_str,
- [&]()->std::string {
- if (options_->IsThreadEnabled())
- return CB_INTERFACE_THREAD_CREATE;
- return "";
- }));
-}
-
-void CStubBodyGen::GenInterfaceUnregister(std::ofstream& stream,
- const Interface& inf) {
- std::string r_str = ReplaceAll(CB_INTERFACE_UNREGISTER, "##",
- GetInterfaceIdWithNamespace(inf));
-
- stream << SmartIndent(GenTemplateString(r_str,
- [&]()->std::string {
- if (options_->IsThreadEnabled())
- return "job_h job;";
- return "";
- },
- [&]()->std::string {
- if (options_->IsThreadEnabled())
- return CB_INTERFACE_THREAD_DESTROY;
- return "";
- }));
-}
-
-void CStubBodyGen::GenInterfaceGlobalVariables(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_GLOBALS, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
-
-std::string CStubBodyGen::GetMethodString(const Interface& inf,
- const Declaration& decl) {
- std::string str;
- const char port_setter[] = "rpc_port_$$_set_port($$, callback_port);\n";
- const char setter[] = "$$($$, $$);\n";
- const char do_while_block[] =
- "do {\n" \
- " rpc_port_parcel_h result;\n" \
- "\n" \
- " rpc_port_parcel_create(&result);\n" \
- " rpc_port_parcel_write_int32(result, $$_METHOD_Result);\n" \
- "$$" \
- " r = rpc_port_parcel_send(result, port);\n" \
- " rpc_port_parcel_destroy(result);\n" \
- "} while (0);\n";
- const char ternary_operation[] = "## ? ## : \"\"";
- int cnt = 0;
- for (auto& i : decl.GetParameters().GetParams()) {
- if (IsDelegateType(inf, i->GetParameterType().GetBaseType())) {
- str += "rpc_port_" + GetInterfaceIdWithNamespace(inf) + "_" +
- i->GetParameterType().GetBaseType().ToString() + "_h " +
- i->GetID() + " = NULL;" + NLine(1);
- } else if (i->GetParameterType().GetBaseType().IsUserDefinedType() ||
- i->GetParameterType().GetBaseType().ToString() == "list" ||
- i->GetParameterType().GetBaseType().ToString() == "array") {
- str += GetReturnTypeString(i->GetParameterType().GetBaseType()) +
- i->GetID() + " = NULL;" + NLine(1);
- } else {
- str += GetReturnTypeString(i->GetParameterType().GetBaseType()) +
- i->GetID() + ";" + NLine(1);
- }
- if (i->GetParameterType().GetDirection() == ParameterType::Direction::IN)
- cnt++;
+void CStubBodyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ bool has_delegate = false;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateBase(stream, iface, *d);
+ has_delegate = true;
}
- str += NLine(1);
- for (auto& i : decl.GetParameters().GetParams()) {
- if (i->GetParameterType().GetDirection() != ParameterType::Direction::IN)
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
- if (i->GetParameterType().GetBaseType().IsUserDefinedType() ||
- i->GetParameterType().GetBaseType().ToString() == "list" ||
- i->GetParameterType().GetBaseType().ToString() == "array") {
- if (IsDelegateType(inf, i->GetParameterType().GetBaseType())) {
- str += "rpc_port_" + GetInterfaceIdWithNamespace(inf) + "_" +
- i->GetParameterType().GetBaseType().ToString() +
- "_create(&" + i->GetID() + ");" + NLine(1);
- str += "\nif (!" + i->GetID() + ") {\n";
- str += " _E(\"Failed to create handle\");\n";
- str += " return -1;\n";
- str += "}\n\n";
- str += GenTemplateString(port_setter,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf) + "_" +
- i->GetParameterType().GetBaseType().ToString();
- },
- [&]()->std::string {
- return i->GetID();
- });
- } else {
- str += GetConstructorString(i->GetParameterType().GetBaseType(),
- i->GetID());
- }
- }
+ GenInterfaceMethodHandlerBase(stream, iface, *d);
+ }
+
+ GenInterfaceMethodTable(stream, iface);
+ GenInterfaceContextBase(stream, iface);
+
+ if (has_delegate)
+ GenInterfaceCallbackPortCheck(stream, iface);
+
+ GenInterfaceBase(stream, iface);
+}
+
+// @see #CB_INTERFACE_CONTEXT_BASE
+void CStubBodyGen::GenInterfaceContextBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_CONTEXT_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ }));
+
+ stream << SmartIndent(code);
+}
- str += GenTemplateString(setter,
- [&]()->std::string {
- return GetParcelReadFunctionString(
- i->GetParameterType().GetBaseType(), true);
- },
- [&]()->std::string {
- return "parcel";
- },
- [&]()->std::string {
- if (i->GetParameterType().GetBaseType().IsUserDefinedType() ||
- i->GetParameterType().GetBaseType().ToString() == "list" ||
- i->GetParameterType().GetBaseType().ToString() == "array")
- return "&" + i->GetID() + "->parcelable, " + i->GetID();
- return "&" + i->GetID();
- });
+std::string CStubBodyGen::GenDelegateParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
}
- if (cnt > 0)
- str += NLine(1);
+ return params;
+}
+
+std::string CStubBodyGen::GenDelegateParamsCheck(const Interface& iface,
+ const Declaration& decl) {
+ std::string params_check;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array" ||
+ type.ToString() == "bundle" ||
+ type.ToString() == "string" ||
+ type.ToString() == "file")
+ params_check += " || " + p->GetID() + " == nullptr";
+ }
+
+ return params_check;
+}
+
+// @see #CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_WRITE
+// @see #CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_WRITE
+// @see #CB_INTERFACE_DELEGATE_STRING_PARCEL_WRITE
+// @see #CB_INTERFACE_DELEGATE_BASE_PARCEL_WRITE
+std::string CStubBodyGen::GenDelegateParcelWrite(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ std::string parcel_write_code;
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_WRITE, "<ARG>",
+ p->GetID());
+ parcel_write_code += GetPrivateSharingString(type, iface, "h->port",
+ p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_DELEGATE_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_DELEGATE_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ parcel_write_code += GetPrivateSharingString(type, iface, "h->port",
+ p->GetID());
+ } else {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_DELEGATE_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ARG>", p->GetID());
+ }
- if (decl.GetMethodType() == Declaration::MethodType::SYNC &&
- decl.GetType().ToString() != "void") {
- str += GetReturnTypeString(decl.GetType()) + "ret = ";
+ code += parcel_write_code;
}
- str += "context->callback." + decl.GetID() + "(context";
- for (auto& i : decl.GetParameters().GetParams()) {
- str += ", ";
- if (i->GetParameterType().GetDirection() != ParameterType::Direction::IN)
- str += "&" + i->GetID();
- else
- str += i->GetID();
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_DELEGATE_BASE
+void CStubBodyGen::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_DELEGATE_" + decl.GetID();
+ std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
+ ::toupper);
+
+ std::string prefix = GetHandlePrefix();
+ std::transform(prefix.begin(), prefix.end(), prefix.begin(), ::toupper);
+
+ std::string name = iface.GetID();
+ std::transform(name.begin(), name.end(), name.begin(), ::toupper);
+
+ std::string code(ReplaceAll(CB_INTERFACE_DELEGATE_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", decl.GetID() },
+ { "<DELEGATE_PARAMS>", GenDelegateParams(iface, decl) },
+ { "<DELEGATE_PARAMS_CHECK>", GenDelegateParamsCheck(iface, decl) },
+ { "<DELEGATE_ENUM_VALUE>", enum_value },
+ { "<DELEGATE_PARCEL_WRITE>", GenDelegateParcelWrite(iface, decl) },
+ { "<UPPERCASE_PREFIX>", prefix },
+ { "<UPPERCASE_NAME>", name }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+std::string CStubBodyGen::GenMethodHandlerArgsDecl(const Interface& iface,
+ const Declaration& decl) {
+ std::string args_decl;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ args_decl += GetArgTypeString(type, iface) + p->GetID() + " = " +
+ GetErrorValue(type) + ";" + NLine(1);
}
- str += ", context->user_data);" + NLine(1);
+
if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
- str += GenTemplateString(do_while_block,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- std::string s;
- for (auto& i : decl.GetParameters().GetParams()) {
- if (i->GetParameterType().GetDirection() ==
- ParameterType::Direction::IN)
- continue;
- s += GenTemplateString(setter,
- [&]()->std::string {
- return GetParcelWriteFunctionString(
- i->GetParameterType().GetBaseType(), true);
- },
- [&]()->std::string {
- return "result";
- },
- [&]()->std::string {
- auto& t = i->GetParameterType().GetBaseType();
- if (t.IsUserDefinedType() || t.ToString() == "list" ||
- t.ToString() == "array")
- return "&" + i->GetID() + "->parcelable, " + i->GetID();
- else if (t.ToString() == "string" || t.ToString() == "file")
- return ReplaceAll(ternary_operation, "##", i->GetID());
- return i->GetID();
- });
- }
- if (decl.GetType().ToString() != "void") {
- s += GenTemplateString(setter,
- [&]()->std::string {
- return GetParcelWriteFunctionString(decl.GetType(), true);
- },
- [&]()->std::string {
- return "result";
- },
- [&]()->std::string {
- if (decl.GetType().IsUserDefinedType() ||
- decl.GetType().ToString() == "list" ||
- decl.GetType().ToString() == "array")
- return "&ret->parcelable, ret";
- else if (decl.GetType().ToString() == "string" ||
- decl.GetType().ToString() == "file")
- return ReplaceAll(ternary_operation, "##", "ret");
- return "ret";
- });
- }
- return s;
- });
- }
+ args_decl += "rpc_port_parcel_h parcel_;" + NLine(1);
+ args_decl += GetArgTypeString(decl.GetType(), iface) + "res_ = " +
+ GetErrorValue(decl.GetType()) + ";" + NLine(1);
+ }
- for (auto& i : decl.GetParameters().GetParams()) {
- str += NLine(1);
- if (IsDelegateType(inf, i->GetParameterType().GetBaseType())) {
- str += "rpc_port_" + GetInterfaceIdWithNamespace(inf) + "_" +
- i->GetParameterType().GetBaseType().ToString() +
- "_destroy(" + i->GetID() + ");";
+ return args_decl;
+}
+
+// @see #CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_READ
+std::string CStubBodyGen::GenMethodHandlerParcelRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ std::string parcel_read_code;
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type)) {
+ parcel_read_code = ReplaceAll(
+ CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>",
+ GetFullNameFromType(type, iface));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
+ } else if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_read_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>",
+ GetFullNameFromType(type, iface));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_READ,
+ "<ARG>", p->GetID());
} else {
- str += GetDestructorString(i->GetParameterType().GetBaseType(),
- i->GetID());
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
}
- }
- str += GetDestructorString(decl.GetType(), "ret");
+ code += parcel_read_code;
+ }
- return str;
+ return RemoveLine(code);
}
-std::string CStubBodyGen::GetAddPrivilegeString(const std::string& id,
- const Attribute& attr) {
- std::string str;
+// @see #CB_INTERFACE_METHOD_CALLBACK_INVOKE
+std::string CStubBodyGen::GenMethodHandlerCallbackInvoke(
+ const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_INVOKE,
+ "<METHOD_NAME>", decl.GetID()));
- str += GenTemplateString(CB_INTERFACE_PRIVILEGE_BLOCK,
- [&]()->std::string {
- return "rpc_port_stub_add_privilege(__" + id +
- "_stub, \"" + attr.GetValue() + "\")";
- },
- [&]()->std::string {
- return attr.GetValue();
- });
- return str;
-}
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC)
+ code = ReplaceAll(code, "<RES_SET>", "res_ = ");
+ else
+ code = ReplaceAll(code, "<RES_SET>", "");
-std::string CStubBodyGen::GetTrustedModeString(const std::string& id,
- const Attribute& attr) {
- std::string str;
+ std::string args;
+ for (const auto& p : decl.GetParameters()) {
+ args += ", ";
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ args += "&";
- str += GenTemplateString(CB_INTERFACE_TRUSTED_MODE_BLOCK,
- [&]()->std::string {
- return "rpc_port_stub_set_trusted(__" + id +
- "_stub, " + attr.GetValue() + ")";
- },
- [&]()->std::string {
- return attr.GetValue();
- });
- return str;
-}
+ args += p->GetID();
+ }
+ code = ReplaceAll(code, "<METHOD_ARGS>", args);
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_PARCEL_WRITE_PRE
+// @see #CB_INTERFACE_METHOD_PARCEL_WRITE_POST
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_WRITE
+std::string CStubBodyGen::GenMethodHandlerParcelWrite(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ if (decl.GetMethodType() != Declaration::MethodType::SYNC)
+ return code;
+
+ std::string prefix = GetHandlePrefix();
+ std::transform(prefix.begin(), prefix.end(), prefix.begin(), ::toupper);
+ code = ReplaceAll(CB_INTERFACE_METHOD_PARCEL_WRITE_PRE, "<UPPERCASE_PREFIX>",
+ prefix);
+
+ std::string name = iface.GetID();
+ std::transform(name.begin(), name.end(), name.begin(), ::toupper);
+ code = ReplaceAll(code, "<UPPERCASE_NAME>", name);
+
+ std::string parcel_write_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() == ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE, "<ARG>",
+ p->GetID());
+ parcel_write_code += GetPrivateSharingString(type, iface, "port",
+ p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ parcel_write_code += GetPrivateSharingString(type, iface, "port",
+ p->GetID());
+ } else {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ARG>", p->GetID());
+ }
+
+ code += parcel_write_code;
+ }
-void CStubBodyGen::GenInterfaceDelegators(std::ofstream& stream,
- const Interface& inf) {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ auto& type = decl.GetType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE, "<ARG>", "res_");
+ parcel_write_code += GetPrivateSharingString(type, iface, "port", "res_");
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE,
+ "<ARG>", "res_");
+ } else if (type.ToString() == "string") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", "res_");
+ } else if (type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", "res_");
+ parcel_write_code += GetPrivateSharingString(type, iface, "port", "res_");
+ } else {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ARG>", "res_");
+ }
+
+ code += parcel_write_code;
+ code += std::string(CB_INTERFACE_METHOD_PARCEL_WRITE_POST);
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_FREE
+// @see #CB_INTERFACE_METHOD_BUNDLE_FREE
+// @see #CB_INTERFACE_METHOD_STRING_FREE
+std::string CStubBodyGen::GenMethodHandlerArgsFree(const Interface& iface,
+ const Declaration& decl) {
+ std::string free_code;
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_FREE,
+ "<PREFIX>", GetHandlePrefix());
+ free_code = ReplaceAll(free_code, "<NAME>",
+ GetFullNameFromType(type, iface));
+ free_code = ReplaceAll(free_code, "<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE,
+ "<ARG>", p->GetID());
+ } else {
+ free_code.clear();
+ }
+
+ code += free_code;
+ }
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
+ auto& type = decl.GetType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_FREE,
+ "<PREFIX>", GetHandlePrefix());
+ free_code = ReplaceAll(free_code, "<NAME>",
+ GetFullNameFromType(type, iface));
+ free_code = ReplaceAll(free_code, "<ARG>", "res_");
+ } else if (type.ToString() == "bundle") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE,
+ "<ARG>", "res_");
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE,
+ "<ARG>", "res_");
+ } else {
+ free_code.clear();
+ }
+
+ code += free_code;
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_BASE
+void CStubBodyGen::GenInterfaceMethodHandlerBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_HANDLER_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_HANDLER_ARGS_DECL>", GenMethodHandlerArgsDecl(iface, decl) },
+ { "<METHOD_HANDLER_PARCEL_READ>",
+ GenMethodHandlerParcelRead(iface, decl) },
+ { "<METHOD_HANDLER_CALLBACK_INVOKE>",
+ GenMethodHandlerCallbackInvoke(decl) },
+ { "<METHOD_HANDLER_PARCEL_WRITE>",
+ GenMethodHandlerParcelWrite(iface, decl) },
+ { "<METHOD_HANDLER_ARGS_FREE>", GenMethodHandlerArgsFree(iface, decl) }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER
+std::string CStubBodyGen::GenMethodHandlers(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
- GenInterfaceDelegator(stream, GetInterfaceIdWithNamespace(inf), *i);
+
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_METHOD_" + d->GetID();
+ std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
+ ::toupper);
+ std::string method_handler(ReplaceAll(CB_INTERFACE_METHOD_HANDLER, {
+ { "<ENUM_VALUE>", enum_value },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", d->GetID() }
+ }));
+
+ code += RemoveLine(method_handler);
}
+
+ return code;
}
-void CStubBodyGen::GenInterfaceDelegator(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- GenInterfaceDelegatorDeclaration(stream, id, decl);
- GenInterfaceDelegatorSerializer(stream, id, decl);
- GenInterfaceDelegatorDeserializer(stream, id, decl);
- GenInterfaceDelegatorConstructor(stream, id, decl);
- GenInterfaceDelegatorDestructor(stream, id, decl);
- GenInterfaceDelegatorCloner(stream, id, decl);
- GenInterfaceDelegatorInvoker(stream, id, decl);
- GenInterfaceDelegatorPortSetter(stream, id, decl);
-}
-
-void CStubBodyGen::GenInterfaceDelegatorDeclaration(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- stream << SmartIndent(GenTemplateString(CB_INTERFACE_DELEGATOR_DECL,
- [&]()->std::string {
- return id + "_" + decl.GetID();
- }));
-}
-
-void CStubBodyGen::GenInterfaceDelegatorConstructor(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_INTERFACE_DELEGATOR_CTOR, "##", id + "_" + decl.GetID()),
- [&]()->std::string {
- return id;
- },
- [&]()->std::string {
- return decl.GetID();
- }));
-}
-
-void CStubBodyGen::GenInterfaceDelegatorDestructor(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- stream << SmartIndent(
- ReplaceAll(CB_INTERFACE_DELEGATOR_DTOR, "##", id + "_" + decl.GetID()));
-}
-
-void CStubBodyGen::GenInterfaceDelegatorSerializer(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_DELEGATOR_SERIALIZER, "##", id + "_" + decl.GetID()));
-}
-
-void CStubBodyGen::GenInterfaceDelegatorDeserializer(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_DELEGATOR_DESERIALIZER, "##", id + "_" + decl.GetID()));
-}
-
-void CStubBodyGen::GenInterfaceDelegatorCloner(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_DELEGATOR_CLONER, "##", id + "_" + decl.GetID()));
-}
-
-void CStubBodyGen::GenInterfaceDelegatorInvoker(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- const char parcel[] = "$$(parcel, $$);\n";
- const char ternary_operation[] = "## ? ## : \"\"";
- stream << SmartIndent(GenTemplateString(CB_INTERFACE_DELEGATOR_INVOKER,
- [&]()->std::string {
- return id + "_" + decl.GetID();
- },
- [&]()->std::string {
- std::string str;
- str += "rpc_port_" + id + "_" + decl.GetID() + "_h h";
- for (auto& i : decl.GetParameters().GetParams()) {
- str += ", ";
- str += GetParamTypeString(i->GetParameterType().GetDirection(),
- i->GetParameterType().GetBaseType()) + i->GetID();
- }
- return str;
- },
- [&]()->std::string {
- return id;
- },
- [&]()->std::string {
- std::string str;
- for (auto& i : decl.GetParameters().GetParams()) {
- str += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelWriteFunctionString(
- i->GetParameterType().GetBaseType(), true);
- },
- [&]()->std::string {
- auto& t = i->GetParameterType().GetBaseType();
- if (t.IsUserDefinedType() || t.ToString() == "list" ||
- t.ToString() == "array")
- return "&" + i->GetID() + "->parcelable, " + i->GetID();
- else if (t.ToString() == "string" || t.ToString() == "file")
- return ReplaceAll(ternary_operation, "##", i->GetID());
- return i->GetID();
- });
- }
- return str;
- }));
-}
-
-void CStubBodyGen::GenInterfaceDelegatorPortSetter(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_DELEGATOR_PORT_SETTER, "##", id + "_" + decl.GetID()));
-}
-
-void CStubBodyGen::GenInterfaceContext(std::ofstream& stream,
- const Interface& inf) {
- GenInterfaceContextDeclaration(stream, inf);
- GenInterfaceContextConstructor(stream, inf);
- GenInterfaceContextDestructor(stream, inf);
- GenInterfaceContextFinder(stream, inf);
- GenInterfaceContextTagSetter(stream, inf);
- GenInterfaceContextTagGetter(stream, inf);
- GenInterfaceContextSenderGetter(stream, inf);
-}
-
-void CStubBodyGen::GenInterfaceContextDeclaration(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_INTERFACE_CONTEXT_DECL, "##",
- GetInterfaceIdWithNamespace(inf)),
- [&]()->std::string {
- if (options_->IsThreadEnabled())
- return std::string(CB_INTERFACE_CONTEXT_DECL_THREAD_ELEM);
- return "";
- }));
-
- if (options_->IsThreadEnabled()) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_THREAD_FEATURE, "##", GetInterfaceIdWithNamespace(inf)));
+// @see #CB_INTERFACE_METHOD_TABLE
+void CStubBodyGen::GenInterfaceMethodTable(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_TABLE, {
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_HANDLERS>", GenMethodHandlers(iface) }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_CALLBACK_PORT_CHECK
+void CStubBodyGen::GenInterfaceCallbackPortCheck(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_CALLBACK_PORT_CHECK, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_PRIVILEGE_ADD
+// @see #CB_INTERFACE_TRUSTED_SET
+std::string CStubBodyGen::GenAccessControlSet(const Interface& iface) {
+ std::string code;
+ for (const auto& attr : iface.GetAttributes()) {
+ if (attr->GetKey() == "privilege") {
+ std::string privilege_add(ReplaceAll(CB_INTERFACE_PRIVILEGE_ADD, {
+ { "<NAME>", iface.GetID() },
+ { "<PRIVILEGE>", attr->GetValue() }
+ }));
+
+ code += privilege_add;
+ } else if (attr->GetKey() == "trusted" && attr->GetValue() == "true") {
+ std::string trusted_set(ReplaceAll(CB_INTERFACE_TRUSTED_SET,
+ "<NAME>", iface.GetID()));
+
+ code += trusted_set;
+ }
}
+
+ return RemoveLine(code);
}
-void CStubBodyGen::GenInterfaceContextConstructor(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_INTERFACE_CONTEXT_CTOR, "##",
- GetInterfaceIdWithNamespace(inf)),
- [&]()->std::string {
- if (options_->IsThreadEnabled())
- return std::string(CB_INTERFACE_CONTEXT_CTOR_THREAD_IMPL);
- return "";
- }));
-}
-
-void CStubBodyGen::GenInterfaceContextDestructor(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_INTERFACE_CONTEXT_DTOR, "##",
- GetInterfaceIdWithNamespace(inf)),
- [&]()->std::string {
- if (options_->IsThreadEnabled())
- return std::string(CB_INTERFACE_CONTEXT_DTOR_THREAD_VARS);
- return "";
- },
- [&]()->std::string {
- if (options_->IsThreadEnabled())
- return std::string(CB_INTERFACE_CONTEXT_DTOR_THREAD_IMPL);
- return "";
- }));
-}
-
-void CStubBodyGen::GenInterfaceContextFinder(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_CONTEXT_FINDER, "##", GetInterfaceIdWithNamespace(inf)));
-}
-
-void CStubBodyGen::GenInterfaceContextTagSetter(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_CONTEXT_TAG_SETTER, "##", GetInterfaceIdWithNamespace(inf)));
-}
-
-void CStubBodyGen::GenInterfaceContextTagGetter(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_CONTEXT_TAG_GETTER, "##", GetInterfaceIdWithNamespace(inf)));
-}
-
-void CStubBodyGen::GenInterfaceContextSenderGetter(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_CONTEXT_GET_SENDER, "##", GetInterfaceIdWithNamespace(inf)));
-}
-
-void CStubBodyGen::GenTypedefStubMethod(std::ofstream& stream) {
- stream << CB_STUB_METHOD_TYPE;
-}
-
-void CStubBodyGen::GenInterfaceAddPrivileges(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(GenTemplateString(CB_INTERFACE_ADD_PRIVILEGE,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- std::string str;
- for (auto& a : inf.GetAttributes().GetAttrs()) {
- if (a->GetKey() == "privilege") {
- str += GetAddPrivilegeString(
- GetInterfaceIdWithNamespace(inf), *a);
- str += NLine(1);
- } else if (a->GetKey() == "trusted" && a->GetValue() == "true") {
- str += GetTrustedModeString(GetInterfaceIdWithNamespace(inf), *a);
- str += NLine(1);
- }
- }
-
- if (!str.empty())
- str = SmartIndent("int r;\n\n") + str;
- return str;
- }));
-}
-
-void CStubBodyGen::GenInterfaceClientNumberGetter(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_CLIENT_NUMBER_GETTER, "##",
- GetInterfaceIdWithNamespace(inf)));
+// @see #CB_INTERFACE_BASE
+void CStubBodyGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<ACCESS_CONTROL_SET>", GenAccessControlSet(iface) }
+ }));
+
+ stream << SmartIndent(code);
}
} // namespace tidl
diff --git a/idlc/gen/c_stub_body_gen.h b/idlc/gen/c_stub_body_gen.h
index f787774..b8358e8 100644
--- a/idlc/gen/c_stub_body_gen.h
+++ b/idlc/gen/c_stub_body_gen.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,77 +35,57 @@ class CStubBodyGen : public CBodyGeneratorBase {
void OnFiniGen(std::ofstream& stream) override;
private:
+ void GenThreadEnableDefinition(std::ofstream& stream);
+ void GenInterfaceMethodHandlerType(std::ofstream& stream);
+ void GenInterfaceEnums(std::ofstream& stream);
+ void GenInterfaceEnum(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodEnumBase(std::ofstream& stream,
+ const Interface& iface);
+ void GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& iface);
+
+ void GenInterfaceDefs(std::ofstream& stream);
+ void GenInterfaceDef(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceContextDef(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateDef(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceCallbackPortCheckDef(std::ofstream& stream,
+ const Interface& iface);
+ void GenInterfaceBaseDef(std::ofstream& stream, const Interface& iface);
+
void GenInterfaces(std::ofstream& stream);
- void GenInterface(std::ofstream& stream, const Interface& inf);
- void GenTypedefStubMethod(std::ofstream& stream);
- void GenInterfaceMethods(std::ofstream& stream, const Interface& inf);
- void GenInterfaceMethodTable(std::ofstream& stream, const Interface& inf);
- void GenInterfaceOnConnectedEventCB(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceOnDisconnectedEventCB(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceOnReceivedEventCB(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceRegister(std::ofstream& stream, const Interface& inf);
- void GenInterfaceUnregister(std::ofstream& stream, const Interface& inf);
- void GenInterfaceGlobalVariables(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDelegators(std::ofstream& stream, const Interface& inf);
- void GenInterfaceContext(std::ofstream& stream, const Interface& inf);
- void GenInterfaceAddPrivileges(std::ofstream& stream, const Interface& inf);
- void GenInterfaceClientNumberGetter(std::ofstream& stream,
- const Interface& inf);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceContextBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceMethodHandlerBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl);
+ void GenInterfaceMethodTable(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceCallbackPortCheck(std::ofstream& stream,
+ const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
- private:
- void GenInterfaceContextDeclaration(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextConstructor(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextDestructor(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextFinder(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextTagSetter(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextTagGetter(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextSenderGetter(std::ofstream& stream,
- const Interface& inf);
+ std::string GenMethodEnums(const Interface& iface);
+ std::string GenDelegateEnums(const Interface& iface);
- private:
- void GenInterfaceDelegator(std::ofstream& stream, const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDeclaration(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorConstructor(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDestructor(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorSerializer(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDeserializer(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorCloner(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorInvoker(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorPortSetter(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
+ std::string GenDelegateParams(const Interface& iface,
+ const Declaration& decl);
+ std::string GenDelegateParamsCheck(const Interface& iface,
+ const Declaration& decl);
+ std::string GenDelegateParcelWrite(const Interface& iface,
+ const Declaration& decl);
- private:
- std::string GetMethodString(const Interface& id, const Declaration& decl);
- std::string GetAddEventCBString(const std::string& id);
- std::string GetAddPrivilegeString(const std::string& id,
- const Attribute& attr);
- std::string GetTrustedModeString(const std::string& id,
- const Attribute& attr);
+ std::string GenMethodHandlerArgsDecl(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlerParcelRead(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlerCallbackInvoke(const Declaration& decl);
+ std::string GenMethodHandlerParcelWrite(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlerArgsFree(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlers(const Interface& iface);
+ std::string GenAccessControlSet(const Interface& iface);
private:
std::shared_ptr<Options> options_;
diff --git a/idlc/gen/c_stub_body_gen_cb.h b/idlc/gen/c_stub_body_gen_cb.h
index a7ef172..c1214fc 100644
--- a/idlc/gen/c_stub_body_gen_cb.h
+++ b/idlc/gen/c_stub_body_gen_cb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,741 +17,1192 @@
#ifndef IDLC_C_GEN_C_STUB_BODY_GEN_CB_H_
#define IDLC_C_GEN_C_STUB_BODY_GEN_CB_H_
-const char CB_INTERFACE_METHOD[] =
+constexpr const char CB_THREAD_ENABLE_DEF[] =
R"__c_cb(
-static int __$$_method_$$(rpc_port_h port, rpc_port_parcel_h parcel, void *data)
-{
- rpc_port_stub_$$_context_h context = data;
- rpc_port_h callback_port;
- int r;
+#define TIDL_THREAD_ENABLE 1
+)__c_cb";
- r = rpc_port_stub_get_port(__$$_stub, RPC_PORT_PORT_CALLBACK, context->instance, &callback_port);
- if (r != 0) {
- _E("Failed to get callback port");
- return -1;
- }
+constexpr const char CB_INTERFACE_METHOD_HANDLER_TYPE[] =
+R"__c_cb(
+typedef int (*rpc_port_stub_method_handler)(rpc_port_h port, rpc_port_parcel_h parcel, void *data);
+)__c_cb";
-$$
- return r;
-}
+/**
+ * <METHOD_ENUMS> The enumeration declarations of methods.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM_BASE[] =
+R"__c_cb(
+typedef enum {
+ <METHOD_ENUMS>
+} <PREFIX>_<NAME>_method_e;
)__c_cb";
-const char CB_INTERFACE_METHOD_TABLE[] =
-R"__c_cb(static stub_method __$$_method_table[] = {$$
-};
+/**
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM[] =
+R"__c_cb(
+<UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>,
)__c_cb";
-const char CB_INTERFACE_METHOD_FORMAT[] =
+/**
+ * <DELEGATE_ENUMS> The enumeration declarations of deleagtes.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_ENUM_BASE[] =
R"__c_cb(
-[$$] = $$,)__c_cb";
+typedef enum {
+ <DELEGATE_ENUMS>
+} <PREFIX>_<NAME>_delegate_e;
+)__c_cb";
-const char CB_INTERFACE_THREAD_METHODS[] =
+/**
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_DELEGATE_NAME> The uppercase delegate name of the interface.
+ * <NUMBER> The number of the delegate.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_ENUM[] =
R"__c_cb(
-static int __run_pending_job(void)
-{
- int cmd = -1;
- job_h job;
- int r = 0;
+<UPPERCASE_PREFIX>_<UPPERCASE_NAME>_DELEGATE_<UPPERCASE_DELEGATE_NAME> = <NUMBER>,
+)__c_cb";
- if (g_queue_is_empty(__job_queue)) {
- _E("Empty queue");
- return -1;
- }
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_stub_h stub;
+ <PREFIX>_<NAME>_callback_s callback;
+ void *user_data;
+ GList* contexts;
+ GList* callback_ports;
+ GRecMutex mutex;
+} <PREFIX>_<NAME>_t;
+
+static <PREFIX>_<NAME>_t __<NAME>;
+)__c_cb";
- job = g_queue_pop_head(__job_queue);
- rpc_port_parcel_read_int32(job->parcel, &cmd);
- if (cmd > 1 && cmd < (sizeof(__##_method_table) / sizeof(__##_method_table[0]))) {
- if (__##_method_table[cmd])
- r = __##_method_table[cmd](job->port, job->parcel, job->context);
- } else {
- _E("Unknown Command(%d)", cmd);
- r = -1;
- }
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CONTEXT_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_context_s {
+ char *sender;
+ char *instance;
+ rpc_port_h port;
+ rpc_port_h callback_port;
+ void *tag;
+ <PREFIX>_<NAME>_callback_s callback;
+ void *user_data;
+#ifdef TIDL_THREAD_ENABLE
+ GThread *thread;
+ GQueue *queue;
+ GMutex mutex;
+ GCond cond;
+ bool done;
+#endif /* TIDL_THREAD_ENABLE */
+} <PREFIX>_<NAME>_context_t;
+)__c_cb";
- __destroy_job(job);
- return r;
-}
+/**
+ *
+ */
+constexpr const char CB_INTERFACE_CALLBACK_PORT_CHECK_DEF[] =
+R"__c_cb(
+static bool __<PREFIX>_<NAME>_exist_callback_port(rpc_port_h callback_port);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ rpc_port_h port;
+ int id;
+ int seq_id;
+ bool once;
+ bool valid;
+} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
)__c_cb";
-const char CB_INTERFACE_ON_CONNECTED[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CONTEXT_BASE[] =
R"__c_cb(
-static void __##_on_connected(const char *sender, const char *instance, void *data)
+static int __<PREFIX>_<NAME>_context_handle_request(<PREFIX>_<NAME>_context_h h, rpc_port_parcel_h parcel)
{
- rpc_port_stub_##_context_h context;
+ int ret = RPC_PORT_ERROR_NONE;
+ int cmd = -1;
+ static const int table_size = ARRAY_SIZE(__<NAME>_method_table);
+
+ rpc_port_parcel_read_int32(parcel, &cmd);
+ if (cmd > 1 && cmd < table_size) {
+ if (__<NAME>_method_table[cmd])
+ ret = __<NAME>_method_table[cmd](h->port, parcel, h);
+ } else {
+ _W("Invalid protocol. cmd(%d)", cmd);
+ ret = RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ return ret;
+}
- _I("[__RPC_PORT__] sender(%s), instance(%s)", sender, instance);
- context = __create_##_context(sender, instance);
- if (!context)
- return;
+#ifdef TIDL_THREAD_ENABLE
+static int __<PREFIX>_<NAME>_context_push(<PREFIX>_<NAME>_context_h h, rpc_port_parcel_h parcel)
+{
+ g_mutex_lock(&h->mutex);
+ g_queue_push_tail(h->queue, parcel);
+ g_cond_signal(&h->cond);
+ g_mutex_unlock(&h->mutex);
- if (context->callback.create)
- context->callback.create(context, context->user_data);
- __##_contexts = g_list_append(__##_contexts, context);
+ return 0;
}
-)__c_cb";
-const char CB_INTERFACE_ON_DISCONNECTED[] =
-R"__c_cb(
-static void __##_on_disconnected(const char *sender, const char *instance, void *data)
+static rpc_port_parcel_h __<PREFIX>_<NAME>_context_wait_and_pop(<PREFIX>_<NAME>_context_h h)
{
- rpc_port_stub_##_context_h context;
+ rpc_port_parcel_h parcel;
- _I("[__RPC_PORT__] sender(%s), instance(%s)", sender, instance);
- context = __find_##_context(instance);
- if (!context)
- return;
+ g_mutex_lock(&h->mutex);
+ while (g_queue_is_empty(h->queue) && !h->done)
+ g_cond_wait(&h->cond, &h->mutex);
- if (context->callback.terminate)
- context->callback.terminate(context, context->user_data);
- __##_contexts = g_list_remove(__##_contexts, context);
- __destroy_##_context(context);
+ parcel = g_queue_pop_head(h->queue);
+ g_mutex_unlock(&h->mutex);
+
+ return parcel;
}
-)__c_cb";
-const char CB_INTERFACE_ON_RECEIVED[] =
-R"__c_cb(
-static int __##_on_received(const char *sender, const char *instance, rpc_port_h port, void *data)
+static gpointer __<PREFIX>_<NAME>_context_thread_cb(gpointer user_data)
{
- rpc_port_stub_##_context_h context;
- rpc_port_parcel_h parcel;
- int cmd = -1;
- int r;
-
- _I("[__RPC_PORT__] sender(%s), instance(%s)", sender, instance);
- context = __find_##_context(instance);
- if (!context) {
- _E("Failed to find ## context(%s)", instance);
- return -1;
+ <PREFIX>_<NAME>_context_h h = user_data;
+ rpc_port_parcel_h parcel;
+
+ _W("START");
+ while (!h->done) {
+ parcel = __<PREFIX>_<NAME>_context_wait_and_pop(h);
+ if (parcel) {
+ __<PREFIX>_<NAME>_context_handle_request(h, parcel);
+ rpc_port_parcel_destroy(parcel);
}
+ }
+ _W("END");
- context->port = port;
- r = rpc_port_parcel_create_from_port(&parcel, port);
- if (r != 0) {
- _E("Failed to create parcel from port");
- return r;
- }
+ return nullptr;
+}
+#endif /* TIDL_THREAD_ENABLE */
- rpc_port_parcel_read_int32(parcel, &cmd);
- if (cmd > 1 && cmd < (sizeof(__##_method_table) / sizeof(__##_method_table[0]))) {
- if (__##_method_table[cmd])
- r = __##_method_table[cmd](port, parcel, context);
- } else {
- _E("Unknown Command(%d)", cmd);
- r = -1;
+static void __<PREFIX>_<NAME>_context_destroy(gpointer data)
+{
+ <PREFIX>_<NAME>_context_h h = data;
+#ifdef TIDL_THREAD_ENABLE
+ rpc_port_parcel_h parcel;
+#endif /* TIDL_THREAD_ENABLE */
+
+ if (h == nullptr)
+ return;
+
+#ifdef TIDL_THREAD_ENABLE
+ g_mutex_lock(&h->mutex);
+ h->done = true;
+ g_cond_signal(&h->cond);
+ g_mutex_unlock(&h->mutex);
+
+ if (h->thread) {
+ g_thread_join(h->thread);
+ g_thread_unref(h->thread);
+ }
+
+ g_mutex_clear(&h->mutex);
+ g_cond_clear(&h->cond);
+
+ if (h->queue) {
+ while (!g_queue_is_empty(h->queue)) {
+ parcel = g_queue_pop_head(h->queue);
+ rpc_port_parcel_destroy(parcel);
}
- rpc_port_parcel_destroy(parcel);
+ g_queue_free(h->queue);
+ }
+#endif /* TIDL_THREAD_ENABLE */
+
+ if (h->instance)
+ free(h->instance);
- return r;
+ if (h->sender)
+ free(h->sender);
+
+ free(h);
}
-)__c_cb";
-const char CB_INTERFACE_THREAD_ON_RECEIVED[] =
-R"__c_cb(
-static int __##_on_received(const char *sender, const char *instance, rpc_port_h port, void *data)
+static <PREFIX>_<NAME>_context_h __<PREFIX>_<NAME>_context_create(const char *sender, const char *instance, rpc_port_h callback_port)
+{
+ <PREFIX>_<NAME>_context_t *handle;
+
+ if (sender == nullptr || instance == nullptr || callback_port == nullptr) {
+ _E("Invalid parameter");
+ return nullptr;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_context_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return nullptr;
+ }
+
+ handle->sender = strdup(sender);
+ if (handle->sender == nullptr) {
+ _E("Failed to duplicate sender");
+ __<PREFIX>_<NAME>_context_destroy(handle);
+ return nullptr;
+ }
+
+ handle->instance = strdup(instance);
+ if (handle->instance == nullptr) {
+ _E("Failed to duplicate instance");
+ __<PREFIX>_<NAME>_context_destroy(handle);
+ return nullptr;
+ }
+
+#ifdef TIDL_THREAD_ENABLE
+ g_mutex_init(&handle->mutex);
+ g_cond_init(&handle->cond);
+
+ handle->queue = g_queue_new();
+ if (handle->queue == nullptr) {
+ _E("Failed to create queue");
+ __<PREFIX>_<NAME>_context_destroy(handle);
+ return nullptr;
+ }
+
+ handle->thread = g_thread_new(instance, __<PREFIX>_<NAME>_context_thread_cb, handle);
+ if (handle->thread == nullptr) {
+ _E("Failed to create thread");
+ __<PREFIX>_<NAME>_context_destroy(handle);
+ return nullptr;
+ }
+#endif /* TIDL_THREAD_ENABLE */
+
+ handle->callback_port = callback_port;
+ handle->callback = __<NAME>.callback;
+ handle->user_data = __<NAME>.user_data;
+
+ return handle;
+}
+
+int <PREFIX>_<NAME>_context_set_tag(<PREFIX>_<NAME>_context_h context, void *tag)
{
- rpc_port_stub_##_context_h context;
- int r;
+ if (context == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- _I("[__RPC_PORT__] sender(%s), instance(%s)", sender, instance);
- context = __find_##_context(instance);
- if (!context) {
- _E("Failed to find ## context(%s)", instance);
- return -1;
- }
- r = __add_thread_queue(port, context);
+ context->tag = tag;
- return r;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_INTERFACE_THREAD_CREATE[] =
-R"__c_cb(
-__job_queue = g_queue_new();
-)__c_cb";
+int <PREFIX>_<NAME>_context_get_tag(<PREFIX>_<NAME>_context_h context, void **tag)
+{
+ if (context == nullptr || tag == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
-const char CB_INTERFACE_THREAD_DESTROY[] =
-R"__c_cb(
-while (!g_queue_is_empty(__job_queue)) {
- job = g_queue_pop_head(__job_queue);
- __destroy_job(job);
+ *tag = context->tag;
+
+ return RPC_PORT_ERROR_NONE;
}
-g_queue_free(__job_queue);
-__job_queue = NULL;
-)__c_cb";
-const char CB_INTERFACE_REGISTER[] =
-R"__c_cb(
-int rpc_port_stub_##_register(rpc_port_stub_##_callback_s *callback, void *user_data)
+int <PREFIX>_<NAME>_context_get_sender(<PREFIX>_<NAME>_context_h context, char **sender)
{
- int r;
+ char *value;
- if (__##_stub) {
- _W("Already exists");
- return -1;
- }
+ if (context == nullptr || sender == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- if (!callback) {
- _E("Invalid parameter");
- return -1;
- }
+ value = strdup(context->sender);
+ if (value == nullptr) {
+ _E("Failed to duplicate sender");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
- __##_callback = *callback;
- __##_user_data = user_data;
- r = rpc_port_stub_create(&__##_stub, "##");
- if (r != 0) {
- _E("Failed to create stub handle");
- return r;
- }
-$$
-
- r = rpc_port_stub_add_received_event_cb(__##_stub, __##_on_received, NULL);
- if (r != 0) {
- _E("Failed to add received event callback");
- rpc_port_stub_destroy(__##_stub);
- __##_stub = NULL;
- return r;
- }
+ *sender = value;
- r = rpc_port_stub_add_connected_event_cb(__##_stub, __##_on_connected, NULL);
- if (r != 0) {
- _E("Failed to add connected event callback");
- rpc_port_stub_destroy(__##_stub);
- __##_stub = NULL;
- return r;
- }
+ return RPC_PORT_ERROR_NONE;
+}
- r = rpc_port_stub_add_disconnected_event_cb(__##_stub, __##_on_disconnected, NULL);
- if (r != 0) {
- _E("Failed to add disconnected event callback");
- rpc_port_stub_destroy(__##_stub);
- __##_stub = NULL;
- return r;
- }
+int <PREFIX>_<NAME>_context_get_instance(<PREFIX>_<NAME>_context_h context, char **instance)
+{
+ char *value;
- r = __##_add_privileges();
- if (r != 0) {
- _E("Failed to add privileges");
- rpc_port_stub_destroy(__##_stub);
- __##_stub = NULL;
- return r;
- }
+ if (context == nullptr || instance == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- r = rpc_port_stub_listen(__##_stub);
- if (r != 0) {
- _E("Failed to listen stub");
- rpc_port_stub_destroy(__##_stub);
- __##_stub = NULL;
- return r;
- }
+ value = strdup(context->instance);
+ if (value == nullptr) {
+ _E("Failed to duplicate instance");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
- return 0;
+ *instance = value;
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_INTERFACE_UNREGISTER[] =
-R"__c_cb(
-int rpc_port_stub_##_unregister(void)
+int <PREFIX>_<NAME>_context_disconnect(<PREFIX>_<NAME>_context_h context)
{
- int r;
-$$
+ int ret;
- if (!__##_stub)
- return -1;
+ if (context == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- if (__##_contexts) {
- g_list_free_full(__##_contexts, __destroy_##_context);
- __##_contexts = NULL;
- }
+ g_rec_mutex_lock(&__<NAME>.mutex);
- r = rpc_port_stub_destroy(__##_stub);
- __##_stub = NULL;
-$$
+ ret = rpc_port_disconnect(context->callback_port);
+ if (ret != RPC_PORT_ERROR_NONE)
+ _E("Failed to disconnect. error(%d)", ret);
- return r;
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+
+ return ret;
}
-)__c_cb";
-const char CB_INTERFACE_CLIENT_NUMBER_GETTER[] =
-R"__c_cb(
-int rpc_port_stub_##_get_client_number(unsigned int *n)
+static <PREFIX>_<NAME>_context_h __<PREFIX>_<NAME>_find_context(const char *instance)
{
- if (!n) {
- _E("Invalid parameter");
- return -1;
- }
-
- if (!__##_stub) {
- _E("## Stub is not ready");
- return -1;
+ <PREFIX>_<NAME>_context_h context;
+ GList *iter;
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ iter = __<NAME>.contexts;
+ while (iter) {
+ context = iter->data;
+ if (!strcmp(context->instance, instance)) {
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+ return context;
}
- *n = g_list_length(__##_contexts);
+ iter = g_list_next(iter);
+ }
+ g_rec_mutex_unlock(&__<NAME>.mutex);
- return 0;
+ return nullptr;
}
-)__c_cb";
-const char CB_GLOBALS[] =
-R"__c_cb(
-static rpc_port_stub_h __##_stub;
-static rpc_port_stub_##_callback_s __##_callback;
-static void *__##_user_data;
-static GList *__##_contexts;
-)__c_cb";
+static void __<PREFIX>_<NAME>_add_context(<PREFIX>_<NAME>_context_h context)
+{
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ __<NAME>.contexts = g_list_append(__<NAME>.contexts, context);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+}
-const char CB_INTERFACE_DELEGATOR_DECL[] =
-R"__c_cb(
-struct $$_s {
- rpc_port_parcelable_t parcelable;
- rpc_port_h port;
- int id;
- int seq_id;
- bool once;
- bool valid;
-};
+static void __<PREFIX>_<NAME>_remove_context(<PREFIX>_<NAME>_context_h context)
+{
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ __<NAME>.contexts = g_list_remove(__<NAME>.contexts, context);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+}
)__c_cb";
-const char CB_INTERFACE_DELEGATOR_CTOR[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ * <DELEGATE_PARAMS> The parameters of the delegate.
+ * <DELEGATE_PARAMS_CHECK> The implementation to check whether arguments are nullptr or not
+ * <DELEGATE_ENUM_VALUE> The enumeration value of the method.
+ * <DELEGATE_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
R"__c_cb(
-static int rpc_port_##_create(rpc_port_##_h *h)
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_to(rpc_port_parcel_h parcel, void *user_data)
{
- struct ##_s *handle;
- static int seq_num;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = user_data;
- if (!h) {
- _E("Invalid parameter");
- return -1;
- }
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
- handle = calloc(1, sizeof(struct ##_s));
- if (!handle) {
- _E("Out of memory");
- return -1;
- }
+ rpc_port_parcel_write_int32(parcel, h->id);
- handle->parcelable.to = __##_to;
- handle->parcelable.from = __##_from;
- handle->id = $$_DELEGATE_$$;
- handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
- handle->once = false;
- handle->valid = true;
+ rpc_port_parcel_write_int32(parcel, h->seq_id);
- *h = handle;
+ rpc_port_parcel_write_bool(parcel, h->once);
- return 0;
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
}
-)__c_cb";
-const char CB_INTERFACE_DELEGATOR_DTOR[] =
-R"__c_cb(
-int rpc_port_##_destroy(rpc_port_##_h h)
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_from(rpc_port_parcel_h parcel, void *user_data)
{
- if (!h) {
- _E("Invalid parameter");
- return -1;
- }
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = user_data;
- free(h);
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
- return 0;
-}
-)__c_cb";
+ rpc_port_parcel_read_int32(parcel, &h->id);
-const char CB_INTERFACE_DELEGATOR_SERIALIZER[] =
-R"__c_cb(
-static void __##_to(rpc_port_parcel_h parcel, void *data)
-{
- rpc_port_##_h handle = data;
+ rpc_port_parcel_read_int32(parcel, &h->seq_id);
- if (!handle) {
- _E("Invalid parameter");
- return;
- }
+ rpc_port_parcel_read_bool(parcel, &h->once);
- rpc_port_parcel_write_int32(parcel, handle->id);
- rpc_port_parcel_write_int32(parcel, handle->seq_id);
- rpc_port_parcel_write_bool(parcel, handle->once);
- _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+ set_last_result(RPC_PORT_ERROR_NONE);
}
-)__c_cb";
-const char CB_INTERFACE_DELEGATOR_DESERIALIZER[] =
-R"__c_cb(
-static void __##_from(rpc_port_parcel_h parcel, void *data)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_t *handle;
+ static int seq_num;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_<DELEGATE_NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_<DELEGATE_NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_<DELEGATE_NAME>_from;
+ handle->id = <DELEGATE_ENUM_VALUE>;
+ handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+ handle->once = false;
+ handle->valid = true;
+ _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h)
{
- rpc_port_##_h handle = data;
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- if (!handle) {
- _E("Invalid parameter");
- return;
- }
+ _W("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+
+ free(h);
- rpc_port_parcel_read_int32(parcel, &handle->id);
- rpc_port_parcel_read_int32(parcel, &handle->seq_id);
- rpc_port_parcel_read_bool(parcel, &handle->once);
- _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_INTERFACE_DELEGATOR_CLONER[] =
-R"__c_cb(
-int rpc_port_##_clone(rpc_port_##_h h, rpc_port_##_h *clone)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone)
{
- rpc_port_##_h handle;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h handle;
+ int ret;
- if (!h || !clone) {
- _E("Invalid parameter");
- return -1;
- }
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- handle = calloc(1, sizeof(struct ##_s));
- if (!handle) {
- _E("Out of memory");
- return -1;
- }
+ ret = <PREFIX>_<NAME>_<DELEGATE_NAME>_create(&handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
- handle->parcelable = h->parcelable;
- handle->port = h->port;
- handle->id = h->id;
- handle->seq_id = h->seq_id;
- handle->once = h->once;
- handle->valid = h->valid;
- _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+ handle->port = h->port;
+ handle->seq_id = h->seq_id;
+ handle->once = h->once;
+ handle->valid = h->valid;
- *clone = handle;
+ *clone = handle;
- return 0;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_INTERFACE_DELEGATOR_INVOKER[] =
-R"__c_cb(
-int rpc_port_$$_invoke($$)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id)
{
- rpc_port_parcel_h parcel = NULL;
- int r;
+ if (h == nullptr || id == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- if (!h || !h->port) {
- _E("Invalid parameter");
- return -1;
- }
+ *id = h->id;
- if (h->once && !h->valid) {
- _E("Invalid callback");
- return -1;
- }
+ return RPC_PORT_ERROR_NONE;
+}
- rpc_port_parcel_create(&parcel);
- if (!parcel) {
- _E("Failed to create parcel");
- return -1;
- }
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id)
+{
+ if (h == nullptr || seq_id == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- rpc_port_parcel_write_int32(parcel, $$_METHOD_Callback);
- rpc_port_parcel_write(parcel, &h->parcelable, h);
-$$
- r = rpc_port_parcel_send(parcel, h->port);
- rpc_port_parcel_destroy(parcel);
- h->valid = false;
+ *seq_id = h->seq_id;
- return r;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_INTERFACE_DELEGATOR_PORT_SETTER[] =
-R"__c_cb(
-int rpc_port_##_set_port(rpc_port_##_h h, rpc_port_h port)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once)
{
- if (!h || !port) {
- _E("Invalid parameter");
- return -1;
- }
+ if (h == nullptr || once == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- h->port = port;
+ *once = h->once;
- return 0;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_INTERFACE_CONTEXT_DECL[] =
-R"__c_cb(
-struct ##_context_s {
- char *sender;
- char *instance;
- rpc_port_h port;
- void *tag;
- rpc_port_stub_##_callback_s callback;
- void *user_data;
-$$
-};
-)__c_cb";
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag)
+{
+ char *value;
+ char buf[128];
-const char CB_INTERFACE_CONTEXT_DECL_THREAD_ELEM[] =
-R"__c_cb(pthread_mutex_t mutex;
-pthread_cond_t cond;
-pthread_t thread;
-bool run_wait_queue;
-)__c_cb";
+ if (h == nullptr || tag == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
-const char CB_INTERFACE_THREAD_FEATURE[] =
-R"__c_cb(
-typedef struct {
- rpc_port_parcel_h parcel;
- rpc_port_h port;
- void *context;
-} job_s;
-typedef job_s *job_h;
+ snprintf(buf, sizeof(buf), "%d::%d", h->id, h->seq_id);
+ value = strdup(buf);
+ if (value == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
-static GQueue *__job_queue;
+ *tag = value;
-static int __run_pending_job(void);
+ return RPC_PORT_ERROR_NONE;
+}
-static void *__wait_queue(void *data)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_port(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, rpc_port_h port)
{
- rpc_port_stub_##_context_h context = (rpc_port_stub_##_context_h)data;
+ if (h == nullptr || port == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- while(context->run_wait_queue) {
- pthread_mutex_lock(&context->mutex);
- pthread_cond_wait(&context->cond, &context->mutex);
- __run_pending_job();
- pthread_mutex_unlock(&context->mutex);
- }
+ h->port = port;
- return NULL;
+ return RPC_PORT_ERROR_NONE;
}
-static job_h __create_job(rpc_port_parcel_h parcel, rpc_port_h port, void *context)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_invoke(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h<DELEGATE_PARAMS>)
{
- job_h job;
+ rpc_port_parcel_h parcel_;
+ int ret_;
- job = (job_s *)calloc(1, sizeof(job_s));
- if (!job) {
- _E("Out of memory");
- return NULL;
- }
+ if (h == nullptr || h->port == nullptr<DELEGATE_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- job->parcel = parcel;
- job->port = port;
- job->context = context;
+ if (!__<PREFIX>_<NAME>_exist_callback_port(h->port)) {
+ _E("Not connected");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- return job;
-}
+ if (h->once && !h->valid) {
+ _E("The delegate handle is already used");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
-static void __destroy_job(job_h job)
-{
- rpc_port_parcel_destroy(job->parcel);
- free(job);
+ ret_ = rpc_port_parcel_create(&parcel_);
+ if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret_);
+ return ret_;
+ }
+
+ rpc_port_parcel_write_int32(parcel_, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_CALLBACK_);
+
+ rpc_port_parcel_write(parcel_, &h->parcelable, h);
+
+ <DELEGATE_PARCEL_WRITE>
+ ret_ = rpc_port_parcel_send(parcel_, h->port);
+ rpc_port_parcel_destroy(parcel_);
+ h->valid = false;
+
+ return ret_;
}
+)__c_cb";
-static int __add_thread_queue(rpc_port_h port, rpc_port_stub_##_context_h context)
-{
- rpc_port_parcel_h parcel;
- job_h job;
- int r;
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel_, &<ARG>->parcelable, <ARG>);
+)__c_cb";
- r = rpc_port_parcel_create_from_port(&parcel, port);
- if (r != 0) {
- _E("Failed to create parcel from port");
- return r;
- }
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel_, <ARG>);
+)__c_cb";
- job = __create_job(parcel, port, context);
- g_queue_push_tail(__job_queue, job);
- if (g_queue_is_empty(__job_queue)) {
- _E("Empty queue ##");
- return -1;
- }
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel_, <ARG>);
+)__c_cb";
- pthread_mutex_lock(&context->mutex);
- pthread_cond_signal(&context->cond);
- pthread_mutex_unlock(&context->mutex);
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel_, <ARG>);
+)__c_cb";
- return 0;
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_HANDLER_ARGS_DECL> The declarations for arguments of the method.
+ * <METHOD_HANDLER_PARCEL_READ> The implementation to read the parameter from the parcel.
+ * <METHOD_HANDLER_CALLBACK_INVOKE> The implementation to invoke the callback function of the method.
+ * <METHOD_HANDLER_PARCEL_WRITE> The implementation to write the result to the parcel.
+ * <METHOD_HANDLER_ARGS_FREE> The implementation to release arguments.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER_BASE[] =
+R"__c_cb(
+static int __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler(rpc_port_h port, rpc_port_parcel_h parcel, void *user_data)
+{
+ <PREFIX>_<NAME>_context_h context_ = user_data;
+ rpc_port_parcel_header_h header_;
+ int seq_num_ = -1;
+ rpc_port_h callback_port_;
+ int ret_;
+ <METHOD_HANDLER_ARGS_DECL>
+
+ ret_ = rpc_port_stub_get_port(__<NAME>.stub, RPC_PORT_PORT_CALLBACK, context_->instance, &callback_port_);
+ if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get callback port. error(%d)", ret_);
+ goto out;
+ }
+
+ rpc_port_parcel_get_header(parcel, &header_);
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+
+ <METHOD_HANDLER_PARCEL_READ>
+ <METHOD_HANDLER_CALLBACK_INVOKE>
+ <METHOD_HANDLER_PARCEL_WRITE>
+
+out:
+ <METHOD_HANDLER_ARGS_FREE>
+
+ return ret_;
}
)__c_cb";
-const char CB_INTERFACE_CONTEXT_CTOR[] =
+/**
+ * <ARG> The argument.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface
+ */
+constexpr const char CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ[] =
R"__c_cb(
-static struct ##_context_s *__create_##_context(const char *sender, const char *instance)
-{
- struct ##_context_s *handle;
+ret_ = <PREFIX>_<NAME>_create(&<ARG>);
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret_);
+ goto out;
+}
- handle = calloc(1, sizeof(struct ##_context_s));
- if (!handle) {
- _E("Out of memory");
- return NULL;
- }
+<PREFIX>_<NAME>_set_port(<ARG>, callback_port_);
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+ret_ = get_last_result();
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret_);
+ goto out;
+}
+)__c_cb";
- handle->sender = strdup(sender);
- if (!handle->sender) {
- _E("Out of memory");
- free(handle);
- return NULL;
- }
+/**
+ * <ARG> The name of the value.
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+ret_ = <PREFIX>_<NAME>_create(&<ARG>);
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret_);
+ goto out;
+}
- handle->instance = strdup(instance);
- if (!handle->instance) {
- _E("Out of memory");
- free(handle->sender);
- free(handle);
- return NULL;
- }
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+ret_ = get_last_result();
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret_);
+ goto out;
+}
+)__c_cb";
- handle->callback = __##_callback;
- handle->user_data = __##_user_data;
-$$
- return handle;
+/**
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_bundle(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ goto out;
}
)__c_cb";
-const char CB_INTERFACE_CONTEXT_CTOR_THREAD_IMPL[] =
+/**
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_READ[] =
R"__c_cb(
-pthread_mutex_init(&handle->mutex, NULL);
-pthread_cond_init(&handle->cond, NULL);
-handle->run_wait_queue = true;
-if (pthread_create(&handle->thread, NULL, &__wait_queue, (void *)handle) < 0) {
- _E("Fail to create thread");
- free(handle->instance);
- free(handle->sender);
- free(handle);
- return NULL;
+rpc_port_parcel_read_string(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ goto out;
}
)__c_cb";
-const char CB_INTERFACE_CONTEXT_DTOR[] =
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_READ[] =
R"__c_cb(
-static void __destroy_##_context(gpointer data)
-{
- struct ##_context_s *handle = data;
-$$
- if (!handle) {
- _E("Critical error!");
- return;
- }
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &<ARG>);
+)__c_cb";
+
+/**
+ * <RES_SET> The implemention to set the result of the callback function.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <METHOD_ARGS> The arguments of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_INVOKE[] =
+R"__c_cb(
+if (context_->callback.<METHOD_NAME>)
+ <RES_SET>context_->callback.<METHOD_NAME>(context_<METHOD_ARGS>, context_->user_data);
+)__c_cb";
- free(handle->instance);
- free(handle->sender);
-$$
- free(handle);
+/**
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_PARCEL_WRITE_PRE[] =
+R"__c_cb(
+ret_ = rpc_port_parcel_create(&parcel_);
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret_);
+ goto out;
}
+
+rpc_port_parcel_get_header(parcel_, &header_);
+rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+rpc_port_parcel_header_set_seq_num(header_, seq_num_);
+
+rpc_port_parcel_write_int32(parcel_, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_RESULT_);
)__c_cb";
-const char CB_INTERFACE_CONTEXT_DTOR_THREAD_VARS[] =
-R"__c_cb(void *retval = NULL;
-int ret;
+constexpr const char CB_INTERFACE_METHOD_PARCEL_WRITE_POST[] =
+R"__c_cb(
+ret_ = rpc_port_parcel_send(parcel_, port);
+rpc_port_parcel_destroy(parcel_);
)__c_cb";
-const char CB_INTERFACE_CONTEXT_DTOR_THREAD_IMPL[] =
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE[] =
R"__c_cb(
-handle->run_wait_queue = false;
-pthread_mutex_lock(&handle->mutex);
-pthread_cond_signal(&handle->cond);
-pthread_mutex_unlock(&handle->mutex);
+rpc_port_parcel_write(parcel_, &<ARG>->parcelable, <ARG>);
+)__c_cb";
-ret = pthread_join(handle->thread, &retval);
-if (ret != 0)
- _E("joining thread error [%d].", ret);
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel_, <ARG>);
+)__c_cb";
-pthread_cond_destroy(&handle->cond);
-pthread_mutex_destroy(&handle->mutex);
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel_, <ARG>);
)__c_cb";
-const char CB_INTERFACE_CONTEXT_FINDER[] =
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_WRITE[] =
R"__c_cb(
-static struct ##_context_s *__find_##_context(const char *instance)
-{
- struct ##_context_s *handle;
- GList *iter;
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel_, <ARG>);
+)__c_cb";
- iter = __##_contexts;
- while (iter) {
- handle = (struct ##_context_s *)iter->data;
- if (!strcmp(handle->instance, instance))
- return handle;
- iter = g_list_next(iter);
- }
+/**
+ * <ARG> The argument.
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ <PREFIX>_<NAME>_destroy(<ARG>);
+)__c_cb";
- return NULL;
-}
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ bundle_free(<ARG>);
)__c_cb";
-const char CB_INTERFACE_CONTEXT_TAG_SETTER[] =
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_FREE[] =
R"__c_cb(
-int rpc_port_stub_##_context_set_tag(rpc_port_stub_##_context_h ctx, void *tag)
-{
- if (!ctx) {
- _E("Invalid parameter");
- return -1;
- }
+if (<ARG>)
+ free(<ARG>);
+)__c_cb";
- ctx->tag = tag;
+/**
+ * <NAME> The name of the interface.
+ * <METHOD_HANDLERS> The declarations of method handlers.
+ */
+constexpr const char CB_INTERFACE_METHOD_TABLE[] =
+R"__c_cb(
+static rpc_port_stub_method_handler __<NAME>_method_table[] = {
+ <METHOD_HANDLERS>
+};
+)__c_cb";
- return 0;
-}
+/**
+ * <ENUM_VALUE> The enumeration value of the method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER[] =
+R"__c_cb(
+[<ENUM_VALUE>] = __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler,
)__c_cb";
-const char CB_INTERFACE_CONTEXT_TAG_GETTER[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <ACCESS_CONTROL_SET> The implmentation to set the access control the stub handle.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
R"__c_cb(
-int rpc_port_stub_##_context_get_tag(rpc_port_stub_##_context_h ctx, void **tag)
+static void __<PREFIX>_<NAME>_add_callback_port(rpc_port_h callback_port)
{
- if (!ctx || !tag) {
- _E("Invalid parameter");
- return -1;
- }
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ __<NAME>.callback_ports = g_list_append(__<NAME>.callback_ports, callback_port);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+}
- *tag = ctx->tag;
+static void __<PREFIX>_<NAME>_remove_callback_port(rpc_port_h callback_port)
+{
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ __<NAME>.callback_ports = g_list_remove(__<NAME>.callback_ports, callback_port);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+}
- return 0;
+static void __<PREFIX>_<NAME>_connected_event_cb(const char *sender, const char *instance, void *user_data)
+{
+ <PREFIX>_<NAME>_context_h context;
+ rpc_port_h callback_port = nullptr;
+ int ret;
+
+ _W("sender(%s), instance(%s)", sender, instance);
+ ret = rpc_port_stub_get_port(__<NAME>.stub, RPC_PORT_PORT_CALLBACK, instance, &callback_port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get callback port. error(%d)", ret);
+ return;
+ }
+
+ context = __<PREFIX>_<NAME>_context_create(sender, instance, callback_port);
+ if (context == nullptr)
+ return;
+
+ __<PREFIX>_<NAME>_add_context(context);
+ __<PREFIX>_<NAME>_add_callback_port(context->callback_port);
+ context->callback.create(context, context->user_data);
}
-)__c_cb";
-const char CB_INTERFACE_CONTEXT_GET_SENDER[] =
-R"__c_cb(
-int rpc_port_stub_##_context_get_sender(rpc_port_stub_##_context_h ctx, char **sender)
+static void __<PREFIX>_<NAME>_disconnected_event_cb(const char *sender, const char *instance, void *user_data)
{
- if (!ctx || !sender) {
- _E("Invalid parameter");
- return -1;
- }
+ <PREFIX>_<NAME>_context_h context;
- *sender = strdup(ctx->sender);
- if (*sender == NULL) {
- _E("Out of memory");
- return -1;
- }
- return 0;
+ _W("sender(%s), instance(%s)", sender, instance);
+ context = __<PREFIX>_<NAME>_find_context(instance);
+ if (context == nullptr)
+ return;
+
+ __<PREFIX>_<NAME>_remove_callback_port(context->callback_port);
+ context->callback.terminate(context, context->user_data);
+ __<PREFIX>_<NAME>_remove_context(context);
+ __<PREFIX>_<NAME>_context_destroy(context);
}
-)__c_cb";
-const char CB_STUB_METHOD_TYPE[] =
-R"__c_cb(
-typedef int (*stub_method)(rpc_port_h, rpc_port_parcel_h, void *data);
+static int __<PREFIX>_<NAME>_received_event_cb(const char *sender, const char *instance, rpc_port_h port, void *user_data)
+{
+ <PREFIX>_<NAME>_context_h context;
+ rpc_port_parcel_h parcel;
+ int ret;
+
+ _W("sender(%s), instance(%s)", sender, instance);
+ context = __<PREFIX>_<NAME>_find_context(instance);
+ if (context == nullptr) {
+ _E("Failed to find context. instance(%s)", instance);
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ context->port = port;
+ ret = rpc_port_parcel_create_from_port(&parcel, port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle from port. error(%d)", ret);
+ return ret;
+ }
+
+#ifdef TIDL_THREAD_ENABLE
+ ret = __<PREFIX>_<NAME>_context_push(context, parcel);
+#else
+ ret = __<PREFIX>_<NAME>_context_handle_request(context, parcel);
+ rpc_port_parcel_destroy(parcel);
+#endif /* TIDL_THREAD_ENABLE */
+
+ return ret;
+}
+
+static int __<PREFIX>_<NAME>_set_access_control(void)
+{
+ int ret = RPC_PORT_ERROR_NONE;
+
+ <ACCESS_CONTROL_SET>
+
+ return ret;
+}
+
+int <PREFIX>_<NAME>_register(<PREFIX>_<NAME>_callback_s *callback, void *user_data)
+{
+ int ret;
+
+ if (callback == nullptr || callback->create == nullptr || callback->terminate == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (__<NAME>.stub) {
+ _E("Already exists");
+ return RPC_PORT_ERROR_NONE;
+ }
+
+ g_rec_mutex_init(&__<NAME>.mutex);
+ __<NAME>.callback = *callback;
+ __<NAME>.user_data = user_data;
+
+ ret = rpc_port_stub_create(&__<NAME>.stub, "<NAME>");
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create stub handle. error(%d)", ret);
+ g_rec_mutex_clear(&__<NAME>.mutex);
+ return ret;
+ }
+
+ ret = rpc_port_stub_add_received_event_cb(__<NAME>.stub, __<PREFIX>_<NAME>_received_event_cb, &__<NAME>);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add received event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = rpc_port_stub_add_connected_event_cb(__<NAME>.stub, __<PREFIX>_<NAME>_connected_event_cb, &__<NAME>);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add connected event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = rpc_port_stub_add_disconnected_event_cb(__<NAME>.stub, __<PREFIX>_<NAME>_disconnected_event_cb, &__<NAME>);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add disconnected event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = __<PREFIX>_<NAME>_set_access_control();
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add privileges");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = rpc_port_stub_listen(__<NAME>.stub);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to listen events. error(%d)", ret);
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_unregister(void)
+{
+ if (__<NAME>.stub == nullptr)
+ return RPC_PORT_ERROR_NONE;
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+ g_rec_mutex_clear(&__<NAME>.mutex);
+
+ if (__<NAME>.contexts) {
+ g_list_free_full(__<NAME>.contexts, __<PREFIX>_<NAME>_context_destroy);
+ __<NAME>.contexts = nullptr;
+ }
+
+ if (__<NAME>.stub) {
+ rpc_port_stub_destroy(__<NAME>.stub);
+ __<NAME>.stub = nullptr;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_foreach_context(<PREFIX>_<NAME>_context_cb callback, void *user_data)
+{
+ <PREFIX>_<NAME>_context_h context;
+ GList *iter;
+
+ if (callback == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ iter = __<NAME>.contexts;
+ while (iter) {
+ context = iter->data;
+ if (!callback(context, user_data))
+ break;
+
+ iter = g_list_next(iter);
+ }
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_get_client_number(unsigned int *client_number)
+{
+ if (client_number == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (__<NAME>.stub == nullptr) {
+ _E("Invalid context");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ *client_number = g_list_length(__<NAME>.contexts);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+
+ return RPC_PORT_ERROR_NONE;
+}
)__c_cb";
-const char CB_INTERFACE_ADD_PRIVILEGE[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CALLBACK_PORT_CHECK[] =
R"__c_cb(
-static int __$$_add_privileges(void)
+static bool __<PREFIX>_<NAME>_exist_callback_port(rpc_port_h callback_port)
{
-$$
- return 0;
+ rpc_port_h port;
+ GList *iter;
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ iter = __<NAME>.callback_ports;
+ while (iter) {
+ port = iter->data;
+ if (port == callback_port) {
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+ return true;
+ }
+
+ iter = g_list_next(iter);
+ }
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+
+ return false;
}
)__c_cb";
-const char CB_INTERFACE_PRIVILEGE_BLOCK[] =
-R"__c_cb(r = $$;
-if (r != 0) {
- _E("Failed to add privilege($$)");
- return r;
+/**
+ * <NAME> The name of the interface.
+ * <PRIVILEGE> The privilege name.
+ */
+constexpr const char CB_INTERFACE_PRIVILEGE_ADD[] =
+R"__c_cb(
+ret = rpc_port_stub_add_privilege(__<NAME>.stub, "<PRIVILEGE>");
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add privilege. error(%d)", ret);
+ return ret;
}
)__c_cb";
-const char CB_INTERFACE_TRUSTED_MODE_BLOCK[] =
-R"__c_cb(r = $$;
-if (r != 0) {
- _E("Failed to set trusted mode($$)");
- return r;
+/**
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_TRUSTED_SET[] =
+R"__c_cb(
+ret = rpc_port_stub_set_trusted(__<NAME>.stub, true);
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to set trusted mode. error(%d)", ret);
+ return ret;
}
)__c_cb";
diff --git a/idlc/gen/c_stub_header_gen.cc b/idlc/gen/c_stub_header_gen.cc
index 426cd6d..3177368 100644
--- a/idlc/gen/c_stub_header_gen.cc
+++ b/idlc/gen/c_stub_header_gen.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,7 +30,10 @@ void CStubHeaderGen::OnInitGen(std::ofstream& stream) {
GenPragmaOnce(stream);
GenIncludeDefaultHeaders(stream, false);
GenExplicitLinkageOpen(stream);
+ GenStructureHandles(stream);
+ GenInterfaceHandles(stream);
GenStructures(stream);
+ GenInterfaceCallbacks(stream);
GenInterfaces(stream);
}
@@ -38,167 +41,192 @@ void CStubHeaderGen::OnFiniGen(std::ofstream& stream) {
GenExplicitLinkageClose(stream);
}
-void CStubHeaderGen::GenInterfaces(std::ofstream& stream) {
- for (auto& i : GetDocument().GetBlocks()) {
- if (i->GetType() != Block::TYPE_INTERFACE)
+void CStubHeaderGen::GenInterfaceHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
continue;
- const Interface &inf = static_cast<const Interface&>(*i);
- GenInterface(stream, inf);
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceContextHandle(stream, iface);
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateHandle(stream, iface, *d);
+ }
}
}
-void CStubHeaderGen::GenInterface(std::ofstream& stream,
- const Interface& inf) {
- GenInterfaceContext(stream, inf);
- GenInterfaceDelegators(stream, inf);
- GenInterfaceDeclaration(stream, inf);
- GenInterfaceRegister(stream, inf);
- GenInterfaceUnregister(stream, inf);
- GenInterfaceClientNumberGetter(stream, inf);
-}
-
-void CStubHeaderGen::GenInterfaceDeclaration(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(GenTemplateString(ReplaceAll(
- CB_INTERFACE_DECL, "##", GetInterfaceIdWithNamespace(inf)),
- [&]()->std::string {
- std::string str;
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
- continue;
- str += NLine(1);
- str += GenTemplateString(CB_INTERFACE_CALLBACK,
- [&]()->std::string {
- return GetReturnTypeString(i->GetType());
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- std::string s;
- for (auto& p : i->GetParameters().GetParams()) {
- if (IsDelegateType(inf, p->GetParameterType()
- .GetBaseType())) {
- s += "rpc_port_" + GetInterfaceIdWithNamespace(inf)
- + "_" + p->GetParameterType().GetBaseType().ToString()
- + "_h " + p->GetID();
- } else {
- s += GetParamTypeString(p->GetParameterType()
- .GetDirection(), p->GetParameterType().GetBaseType())
- + p->GetID();
- }
- s += ", ";
- }
- return s;
- });
- }
- return str;
- }));
+// @see #CB_INTERFACE_CONTEXT_HANDLE
+void CStubHeaderGen::GenInterfaceContextHandle(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_CONTEXT_HANDLE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ }));
+
+ stream << SmartIndent(code);
}
-void CStubHeaderGen::GenInterfaceContext(std::ofstream& stream,
- const Interface& inf) {
- GenInterfaceContextDeclaration(stream, inf);
- GenInterfaceContextTagSetter(stream, inf);
- GenInterfaceContextTagGetter(stream, inf);
- GenInterfaceContextSenderGetter(stream, inf);
+// @see #CB_INTERFACE_DELEGATE_HANDLE
+void CStubHeaderGen::GenInterfaceDelegateHandle(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_DELEGATE_HANDLE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", decl.GetID() }
+ }));
+
+ stream << SmartIndent(code);
}
-void CStubHeaderGen::GenInterfaceContextDeclaration(
- std::ofstream& stream, const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CONTEXT_DECL, "##",
- GetInterfaceIdWithNamespace(inf));
+void CStubHeaderGen::GenInterfaceCallbacks(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceCallbackBase(stream, iface);
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceMethodCallbackBase(stream, iface, *d);
+ }
+ }
}
-void CStubHeaderGen::GenInterfaceContextTagSetter(
- std::ofstream& stream, const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CONTEXT_SET_TAG, "##",
- GetInterfaceIdWithNamespace(inf));
+// @see #CB_INTERFACE_CALLBACK_BASE
+void CStubHeaderGen::GenInterfaceCallbackBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_CALLBACK_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ }));
+
+ stream << SmartIndent(code);
}
-void CStubHeaderGen::GenInterfaceContextTagGetter(
- std::ofstream& stream, const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CONTEXT_GET_TAG, "##",
- GetInterfaceIdWithNamespace(inf));
+std::string CStubHeaderGen::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
}
-void CStubHeaderGen::GenInterfaceContextSenderGetter(
- std::ofstream& stream, const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CONTEXT_GET_SENDER, "##",
- GetInterfaceIdWithNamespace(inf));
+// @see #CB_INTERFACE_METHOD_CALLBACK_BASE
+void CStubHeaderGen::GenInterfaceMethodCallbackBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_BASE, {
+ { "<RETURN_TYPE>", GetReturnTypeString(decl.GetType()) },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_PARAMS>", GenMethodParams(iface, decl) }
+ }));
+
+ stream << SmartIndent(code);
}
-void CStubHeaderGen::GenInterfaceDelegators(std::ofstream& stream,
- const Interface& inf) {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+void CStubHeaderGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
continue;
- GenInterfaceDelegator(stream, GetInterfaceIdWithNamespace(inf), *i);
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
}
}
-void CStubHeaderGen::GenInterfaceDelegator(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- GenInterfaceDelegatorDeclaration(stream, id, decl);
- GenInterfaceDelegatorDestructor(stream, id, decl);
- GenInterfaceDelegatorCloner(stream, id, decl);
- GenInterfaceDelegatorInvoker(stream, id, decl);
-}
+void CStubHeaderGen::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ GenInterfaceContextBase(stream, iface);
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
-void CStubHeaderGen::GenInterfaceDelegatorDeclaration(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << ReplaceAll(
- CB_INTERFACE_DELEGATOR_DECL, "##", id + "_" + decl.GetID());
-}
+ GenInterfaceDelegateBase(stream, iface, *d);
+ }
-void CStubHeaderGen::GenInterfaceDelegatorDestructor(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << ReplaceAll(
- CB_INTERFACE_DELEGATOR_DTOR, "##", id + "_" + decl.GetID());
+ GenInterfaceBase(stream, iface);
}
-void CStubHeaderGen::GenInterfaceDelegatorCloner(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << ReplaceAll(
- CB_INTERFACE_DELEGATOR_CLONER, "##", id + "_" + decl.GetID());
+// @see #CB_INTERFACE_CONTEXT_BASE
+void CStubHeaderGen::GenInterfaceContextBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_CONTEXT_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ }));
+
+ stream << SmartIndent(code);
}
-void CStubHeaderGen::GenInterfaceDelegatorInvoker(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << GenTemplateString(ReplaceAll(
- CB_INTERFACE_DELEGATOR_INVOKER, "##", id + "_" + decl.GetID()),
- [&]()->std::string {
- std::string str;
- for (auto& i : decl.GetParameters().GetParams()) {
- str += ", ";
- str += GetParamTypeString(i->GetParameterType().GetDirection(),
- i->GetParameterType().GetBaseType()) + i->GetID();
- }
- return str;
- });
+std::string CStubHeaderGen::GenDelegateParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
}
-void CStubHeaderGen::GenInterfaceRegister(std::ofstream& stream,
- const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_REGISTER, "##",
- GetInterfaceIdWithNamespace(inf));
+// @see #CB_INTERFACE_DELEGATE_BASE
+void CStubHeaderGen::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_DELEGATE_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", decl.GetID() },
+ { "<DELEGATE_PARAMS>", GenDelegateParams(iface, decl) }
+ }));
+
+ stream << SmartIndent(code);
}
-void CStubHeaderGen::GenInterfaceUnregister(std::ofstream& stream,
- const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_UNREGISTER, "##",
- GetInterfaceIdWithNamespace(inf));
+// @see #CB_INTERFACE_METHOD_CALLBACK_DECL
+std::string CStubHeaderGen::GenMethodCallbackDecls(const Interface& iface) {
+ std::string method_callback_decls;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string method_callback_decl(ReplaceAll(
+ CB_INTERFACE_METHOD_CALLBACK_DECL, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", d->GetID() }
+ }));
+
+ method_callback_decl = RemoveLine(method_callback_decl);
+ method_callback_decls += RemoveLine(method_callback_decl, 2);
+ }
+
+ return method_callback_decls;
}
-void CStubHeaderGen::GenInterfaceClientNumberGetter(std::ofstream& stream,
- const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CLIENT_NUMBER_GETTER, "##",
- GetInterfaceIdWithNamespace(inf));
+// @see #CB_INTERFACE_BASE
+void CStubHeaderGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_CALLBACK_DECLS>", GenMethodCallbackDecls(iface) }
+ }));
+
+ stream << SmartIndent(code);
}
} // namespace tidl
diff --git a/idlc/gen/c_stub_header_gen.h b/idlc/gen/c_stub_header_gen.h
index 43d2e53..15f7336 100644
--- a/idlc/gen/c_stub_header_gen.h
+++ b/idlc/gen/c_stub_header_gen.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,42 +33,28 @@ class CStubHeaderGen : public CHeaderGeneratorBase {
void OnFiniGen(std::ofstream& stream) override;
private:
+ void GenInterfaceHandles(std::ofstream& stream);
+ void GenInterfaceContextHandle(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateHandle(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+
+ void GenInterfaceCallbacks(std::ofstream& stream);
+ void GenInterfaceCallbackBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodCallbackBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl);
+
void GenInterfaces(std::ofstream& stream);
- void GenInterface(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDeclaration(std::ofstream& stream, const Interface& inf);
- void GenInterfaceContext(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDelegators(std::ofstream& stream, const Interface& inf);
- void GenInterfaceRegister(std::ofstream& stream, const Interface& inf);
- void GenInterfaceUnregister(std::ofstream& stream, const Interface& inf);
- void GenInterfaceClientNumberGetter(std::ofstream& stream,
- const Interface& inf);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
- private:
- void GenInterfaceContextDeclaration(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextTagSetter(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextTagGetter(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextSenderGetter(std::ofstream& stream,
- const Interface& inf);
+ void GenInterfaceContextBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
- private:
- void GenInterfaceDelegator(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDeclaration(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDestructor(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorCloner(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorInvoker(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
+ std::string GenDelegateParams(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+ std::string GenMethodCallbackDecls(const Interface& iface);
};
} // namespace tidl
diff --git a/idlc/gen/c_stub_header_gen_cb.h b/idlc/gen/c_stub_header_gen_cb.h
index 49e37f0..ee6c9b9 100644
--- a/idlc/gen/c_stub_header_gen_cb.h
+++ b/idlc/gen/c_stub_header_gen_cb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,71 +17,352 @@
#ifndef IDLC_C_GEN_C_STUB_HEADER_GEN_CB_H_
#define IDLC_C_GEN_C_STUB_HEADER_GEN_CB_H_
-const char CB_INTERFACE_DECL[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CONTEXT_HANDLE[] =
R"__c_cb(
-typedef struct {
- void (*create)(rpc_port_stub_##_context_h context, void *user_data);
- void (*terminate)(rpc_port_stub_##_context_h context, void *user_data);
-$$
-} rpc_port_stub_##_callback_s;
+/**
+ * @brief The <PREFIX>_<NAME>_context handle.
+ */
+typedef struct <PREFIX>_<NAME>_context_s *<PREFIX>_<NAME>_context_h;
)__c_cb";
-const char CB_INTERFACE_CALLBACK[] =
-R"__c_cb($$(*$$)(rpc_port_stub_$$_context_h context, $$void *user_data);)__c_cb";
-
-const char CB_INTERFACE_CONTEXT_DECL[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CONTEXT_BASE[] =
R"__c_cb(
-typedef struct ##_context_s* rpc_port_stub_##_context_h;
-)__c_cb";
+/**
+ * @brief Sets the tag to the context handle.
+ *
+ * @param[in] context The context handle
+ * @param[in] tag The tag
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_context_get_tag()
+ */
+int <PREFIX>_<NAME>_context_set_tag(<PREFIX>_<NAME>_context_h context, void *tag);
-const char CB_INTERFACE_CONTEXT_SET_TAG[] =
-R"__c_cb(
-int rpc_port_stub_##_context_set_tag(rpc_port_stub_##_context_h ctx, void *tag);
-)__c_cb";
+/**
+ * @brief Gets the tag from the context handle.
+ *
+ * @param[in] context The context handle
+ * @param[out] tag The tag
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_context_set_tag()
+ */
+int <PREFIX>_<NAME>_context_get_tag(<PREFIX>_<NAME>_context_h context, void **tag);
-const char CB_INTERFACE_CONTEXT_GET_TAG[] =
-R"__c_cb(
-int rpc_port_stub_##_context_get_tag(rpc_port_stub_##_context_h ctx, void **tag);
-)__c_cb";
+/**
+ * @brief Gets the sender ID from the context handle.
+ * @details The @a sender should be released using free().
+ *
+ * @param[in] context The context handle
+ * @param[out] sender The sender ID of the context handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <PREFIX>_<NAME>_context_get_sender(<PREFIX>_<NAME>_context_h context, char **sender);
-const char CB_INTERFACE_CONTEXT_GET_SENDER[] =
-R"__c_cb(
-int rpc_port_stub_##_context_get_sender(rpc_port_stub_##_context_h ctx, char **sender);
-)__c_cb";
+/**
+ * @brief Gets the instance ID from the context handle.
+ * @details The @a instance should be released using free().
+ *
+ * @param[in] context The context handle
+ * @param[out] instance The instance ID of the context handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <PREFIX>_<NAME>_context_get_instance(<PREFIX>_<NAME>_context_h context, char **instance);
-const char CB_INTERFACE_DELEGATOR_DECL[] =
-R"__c_cb(
-typedef struct ##_s *rpc_port_##_h;
+/**
+ * @brief Disconnects from the proxy.
+ *
+ * @param[in] context The context handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_context_disconnect(<PREFIX>_<NAME>_context_h context);
)__c_cb";
-const char CB_INTERFACE_DELEGATOR_DTOR[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_HANDLE[] =
R"__c_cb(
-int rpc_port_##_destroy(rpc_port_##_h h);
+/**
+ * @brief The <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s *<PREFIX>_<NAME>_<DELEGATE_NAME>_h;
)__c_cb";
-const char CB_INTERFACE_DELEGATOR_CLONER[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate.
+ * <DELEGATE_PARAMS> The parameters of the callback function.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
R"__c_cb(
-int rpc_port_##_clone(rpc_port_##_h h, rpc_port_##_h *clone);
+/**
+ * @brief Creates a <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[out] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_clone()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME>_<DELEGATE_NAME> should be released using
+ * the <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME>_<DELEGATE_NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone);
+
+/**
+ * @brief Gets the ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] id The ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id);
+
+/**
+ * @brief Gets the sequence ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] seq_id The Sequence ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id);
+
+/**
+ * @brief Checks whether the delegate is for one-time or not.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] once The flag, it's true, the handle is for one-time
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once);
+
+/**
+ * @brief Gets the tag from the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks The @a tag should be released using free().
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] tag The tag
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag);
+
+/**
+ * @brief Invokes the callback function of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[in] ...
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RPC_PORT_ERROR_IO_ERROR I/O error
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_invoke(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h<DELEGATE_PARAMS>);
)__c_cb";
-const char CB_INTERFACE_DELEGATOR_INVOKER[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CALLBACK_BASE[] =
R"__c_cb(
-int rpc_port_##_invoke(rpc_port_##_h h$$);
+/**
+ * @brief Called when the proxy is connected.
+ * @details The callback function is called when the proxy is connected to the stub.
+ *
+ * @param[in] context The context handle
+ * @param[in] user_data The user data passed from the registration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_create_cb)(<PREFIX>_<NAME>_context_h context, void *user_data);
+
+/**
+ * @brief Called when the proxy is disconnected.
+ * @details The callback function is called when the proxy is disconnected from the stub.
+ *
+ * @param[in] context The context handle
+ * @param[in] user_data The user data passed from the registration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_terminate_cb)(<PREFIX>_<NAME>_context_h context, void *user_data);
+
+/**
+ * @brief Called to get the proxy context once for each connected proxy.
+ *
+ * @param[in] context The context handle
+ * @param[in] user_data The user data passed from the registration function
+ * @return @c true to continue with the next iteration of the loop,
+ * otherwise @c false to break out of the loop
+ * @pre <PREFIX>_<NAME>_foreach_context() will invoke this callback.
+ * @see <PREFIX>_<NAME>_foreach_context()
+ */
+typedef bool (*<PREFIX>_<NAME>_context_cb)(<PREFIX>_<NAME>_context_h context, void *user_data);
)__c_cb";
-const char CB_INTERFACE_REGISTER[] =
+/**
+ * <RETURN_TYPE> The return type of the method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_BASE[] =
R"__c_cb(
-int rpc_port_stub_##_register(rpc_port_stub_##_callback_s *callback, void *user_data);
+/**
+ * @brief Called when the request of the proxy is delivered.
+ *
+ * @param[in] context The context handle
+ * @param[in] user_data The user data passed from the registration function
+ * @see #<PREFIX>_<NAME>_callback_s;
+ */
+typedef <RETURN_TYPE> (*<PREFIX>_<NAME>_<METHOD_NAME>_cb)(<PREFIX>_<NAME>_context_h context<METHOD_PARAMS>, void *user_data);
)__c_cb";
-const char CB_INTERFACE_UNREGISTER[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_CALLBACK_DECLS> The declarations of the method callback functions.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
R"__c_cb(
-int rpc_port_stub_##_unregister(void);
+/**
+ * @brief The structure type containing the set of callback functions for handling stub events.
+ * @details It is one of the input parameters of the <PREFIX>_<NAME>_register() function.
+ *
+ * @see <PREFIX>_<NAME>_create_cb
+ * @see <PREFIX>_<NAME>_terminate_cb
+ */
+typedef struct {
+ <PREFIX>_<NAME>_create_cb create; /**< This callback function is invoked when the proxy is connected. */
+ <PREFIX>_<NAME>_terminate_cb terminate; /**< This callback function is invoked when the proxy is disconnected. */
+ <METHOD_CALLBACK_DECLS>
+} <PREFIX>_<NAME>_callback_s;
+
+/**
+ * @brief Registers the set of the callback functions and the port.
+ * @details This function registers the set of the callback functions to handle stub events.
+ * And, the rpc_port_stub_listen() is called internally to handle events.
+ *
+ * @param[in] callback The set of callback functions to handle stub events
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RPC_PORT_ERROR_IO_ERROR I/O error
+ * @retval #RPC_PORT_ERROR_PERMISSION_DENIED Permission denied
+ * @see <PREFIX>_<NAME>_unregister()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+int <PREFIX>_<NAME>_register(<PREFIX>_<NAME>_callback_s *callback, void *user_data);
+
+/**
+ * @brief Unregisters the registered port.
+ */
+int <PREFIX>_<NAME>_unregister(void);
+
+/**
+ * @brief Retrieves the connected context handles.
+ *
+ * @param[in] callback The callback function
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_context_cb()
+ */
+int <PREFIX>_<NAME>_foreach_context(<PREFIX>_<NAME>_context_cb callback, void *user_data);
+
+/**
+ * @brief Gets the number of connected clients.
+ *
+ * @param[out] client_number The client number
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_get_client_number(unsigned int *client_number);
)__c_cb";
-const char CB_INTERFACE_CLIENT_NUMBER_GETTER[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The name of the method of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_DECL[] =
R"__c_cb(
-int rpc_port_stub_##_get_client_number(unsigned int *n);
+<PREFIX>_<NAME>_<METHOD_NAME>_cb <METHOD_NAME>; /**< This callback function is invoked when the <METHOD_NAME> request is delivered. */
)__c_cb";
#endif // IDLC_C_GEN_C_STUB_HEADER_GEN_CB_H_
diff --git a/idlc/gen/cpp_gen_base.cc b/idlc/gen/cpp_gen_base.cc
index e05aee0..9f451f4 100644
--- a/idlc/gen/cpp_gen_base.cc
+++ b/idlc/gen/cpp_gen_base.cc
@@ -26,8 +26,8 @@ namespace {
namespace tidl {
-CppGeneratorBase::CppGeneratorBase(std::shared_ptr<Document> doc)
- : Generator(doc) {
+CppGeneratorBase::CppGeneratorBase(std::shared_ptr<Document> doc,
+ bool thread_enabled) : Generator(doc), thread_enabled_(thread_enabled) {
type_map_ = {
{"char", "char"}, {"int", "int"}, {"short", "short"},
{"long", "long long"}, {"string", "std::string"}, {"bool", "bool"},
@@ -61,58 +61,51 @@ CppGeneratorBase::CppGeneratorBase(std::shared_ptr<Document> doc)
}
void CppGeneratorBase::GenStructuresForHeader(std::ofstream& stream) {
- stream << CB_BUNDLE;
- stream << CB_FILE;
+ stream << GetStructuresForHeader();
+}
+
+std::string CppGeneratorBase::GetStructuresForHeader() {
+ std::string str;
+
+ str += CB_BUNDLE;
+ str += CB_FILE;
for (auto& i : GetDocument().GetBlocks()) {
if (i->GetType() != Block::TYPE_STRUCTURE)
continue;
Structure& st = static_cast<Structure&>(*i);
- GenStructureForHeader(stream, st);
- stream << std::endl;
+ str += GetStructureForHeader(st);
}
-}
-
-void CppGeneratorBase::GenStructureForHeader(std::ofstream& stream,
- const Structure& st) {
- const char ctor[] = " $$();\n" \
- " $$($$);\n";
- const char variable[] = "$$\n";
- stream << "class " << st.GetID() << " final ";
+ return str;
+}
- GenBrace(stream, 0, [&]() {
- stream << " public:" << NLine(1);
- GenTemplate(ctor, stream,
- [&]()->std::string {
- return st.GetID();
- },
- [&]()->std::string {
- return st.GetID();
- },
- [&]()->std::string {
+std::string CppGeneratorBase::GetStructureForHeader(const Structure& st) {
+ return std::string(ReplaceAll(CB_STRUCTURE_FOR_HEADER)
+ .Change("<CLS_NAME>", st.GetID())
+ .Change("<PARAMS>", [&]() {
std::string str;
int n = 1;
- for (auto& i : st.GetElements().GetElms()) {
+ for (const auto& i : st.GetElements()) {
if (n != 1)
str += ", ";
str += ConvertTypeToString(i->GetType()) + " " + i->GetID();
n++;
}
return str;
- });
-
- stream << NLine(1);
- for (auto& i : st.GetElements().GetElms()) {
- GenSetter(stream, *i);
- GenGetter(stream, *i);
- stream << NLine(1);
- }
-
- stream << " private:";
- GenTemplate(variable, stream,
- [&]()->std::string {
+ })
+ .Change("<GETTER_SETTER>", [&]() {
+ std::string str = NLine(1);
+ for (const auto& i : st.GetElements()) {
+ str += GetSetter(*i);
+ str += NLine(1);
+ str += GetGetter(*i);
+ str += NLine(1);
+ }
+ return str;
+ })
+ .Change("<DATA_MEMBERS>", [&]() {
std::string str;
- for (auto& i : st.GetElements().GetElms()) {
+ for (const auto& i : st.GetElements()) {
str += NLine(1) + Tab(1)
+ ConvertTypeToString(i->GetType()) + " "
+ i->GetID() + "_";
@@ -125,68 +118,50 @@ void CppGeneratorBase::GenStructureForHeader(std::ofstream& stream,
}
str += NLine(1);
return str;
- });
- }, false, false);
- stream << ";" << NLine(1);
-}
-
-void CppGeneratorBase::GenSetter(std::ofstream& stream, const Element& ele) {
- const char setter[] =
- "void Set$$($$ $$) {\n" \
- " $$_ = $$;\n" \
- "}\n";
-
- GenTemplate(AddIndent(TAB_SIZE, setter, true), stream,
- [&]()->std::string {
- return ele.GetID();
- },
- [&]()->std::string {
- return ConvertTypeToString(ele.GetType());
- },
- [&]()->std::string {
- return ele.GetID();
- },
- [&]()->std::string {
- return ele.GetID();
- },
- [&]()->std::string {
- if (ele.GetType().IsUserDefinedType() ||
- ele.GetType().GetMetaType() != nullptr ||
- ele.GetType().ToString() == "string" ||
- ele.GetType().ToString() == "bundle" ||
- ele.GetType().ToString() == "file") {
- return "std::move(" + ele.GetID() + ")";
- }
+ }));
+}
+
+std::string CppGeneratorBase::GetSetter(const Element& ele) {
+ constexpr const char setter[] =
+ " void Set<NAME>(<TYPE> <NAME>) {\n" \
+ " <NAME>_ = <RVAL>;\n" \
+ " }\n";
+
+ return std::string(ReplaceAll(setter)
+ .Change("<NAME>", ele.GetID())
+ .Change("<TYPE>", ConvertTypeToString(ele.GetType()))
+ .Change("<RVAL>", [&]() {
+ if (ele.GetType().IsUserDefinedType() ||
+ ele.GetType().GetMetaType() != nullptr ||
+ ele.GetType().ToString() == "string" ||
+ ele.GetType().ToString() == "bundle" ||
+ ele.GetType().ToString() == "file") {
+ return "std::move(" + ele.GetID() + ")";
+ }
- return ele.GetID();
- });
- stream << NLine(1);
+ return ele.GetID();
+ }));
}
-void CppGeneratorBase::GenGetter(std::ofstream& stream, const Element& ele) {
- const char getter[] =
- "$$ Get$$() const {\n" \
- " return $$_;\n" \
- "}\n";
+std::string CppGeneratorBase::GetGetter(const Element& ele) {
+ constexpr const char getter[] =
+ " <RET> Get<NAME>() const {\n" \
+ " return <NAME>_;\n" \
+ " }\n";
- GenTemplate(AddIndent(TAB_SIZE, getter, true), stream,
- [&]()->std::string {
- if (ele.GetType().IsUserDefinedType() ||
- ele.GetType().GetMetaType() != nullptr ||
- ele.GetType().ToString() == "string" ||
- ele.GetType().ToString() == "bundle" ||
- ele.GetType().ToString() == "file") {
- return "const " + ConvertTypeToString(ele.GetType()) + "&";
- }
+ return std::string(ReplaceAll(getter)
+ .Change("<RET>", [&]() {
+ if (ele.GetType().IsUserDefinedType() ||
+ ele.GetType().GetMetaType() != nullptr ||
+ ele.GetType().ToString() == "string" ||
+ ele.GetType().ToString() == "bundle" ||
+ ele.GetType().ToString() == "file") {
+ return "const " + ConvertTypeToString(ele.GetType()) + "&";
+ }
- return ConvertTypeToString(ele.GetType());
- },
- [&]()->std::string {
- return ele.GetID();
- },
- [&]()->std::string {
- return ele.GetID();
- });
+ return ConvertTypeToString(ele.GetType());
+ })
+ .Change("<NAME>", ele.GetID()));
}
void CppGeneratorBase::GenStructuresForBody(std::ofstream& stream) {
@@ -202,11 +177,11 @@ void CppGeneratorBase::GenStructuresForBody(std::ofstream& stream) {
void CppGeneratorBase::GenStructureForBody(std::ofstream& stream,
const Structure& st) {
std::vector<std::pair<std::string, std::string>> v;
- const char ctor[] = "##::##() {}\n\n" \
- "##::##($$)\n" \
- " : $$ {}";
+ const char ctor[] = "<CLS_NAME>::<CLS_NAME>() {}\n\n" \
+ "<CLS_NAME>::<CLS_NAME>(<PARAMS>)\n" \
+ " : <INIT> {}";
- for (auto& i : st.GetElements().GetElms()) {
+ for (const auto& i : st.GetElements()) {
std::pair<std::string, std::string> p;
p.first = ConvertTypeToString(i->GetType());
@@ -214,27 +189,27 @@ void CppGeneratorBase::GenStructureForBody(std::ofstream& stream,
v.push_back(p);
}
- GenTemplate(ReplaceAll(ctor, "##", st.GetID()), stream,
- [&]()->std::string {
- std::string str;
- for (auto& i : v) {
- str += i.first + " " + i.second;
-
- if (i != v.back())
- str += ", ";
- }
- return str;
- },
- [&]()->std::string {
- std::string str;
- for (auto& i : v) {
- str += i.second + "_(std::move(" + i.second + "))";
-
- if (i != v.back())
- str += ", ";
- }
- return str;
- });
+ ReplaceAll(ctor)
+ .Change("<CLS_NAME>", st.GetID())
+ .Change("<PARAMS>", [&]() {
+ std::string str;
+ for (auto& i : v) {
+ str += i.first + " " + i.second;
+ if (i != v.back())
+ str += ", ";
+ }
+ return str;
+ })
+ .Change("<INIT>", [&]() {
+ std::string str;
+ for (auto& i : v) {
+ str += i.second + "_(std::move(" + i.second + "))";
+ if (i != v.back())
+ str += ", ";
+ }
+ return str;
+ })
+ .Out(stream);
stream << NLine(2);
}
@@ -262,24 +237,26 @@ void CppGeneratorBase::GenPrototype(std::ofstream& stream) {
void CppGeneratorBase::GenSerializer(std::ofstream& stream, const Structure& st,
bool proto) {
- const char parcel_str[] = "rpc_port_parcel_h";
-
- stream << parcel_str << " operator << ("
- << parcel_str << " h, const " << st.GetID() << "& param)";
if (proto) {
- stream << ";" << NLine(1);
+ ReplaceAll(CB_SERIALIZER_HEADER)
+ .Change("<TYPE>", st.GetID())
+ .Out(stream);
return;
}
- stream << " ";
- GenBrace(stream, 0, [&]() {
- for (auto& i : st.GetElements().GetElms()) {
- stream << AddIndent(TAB_SIZE,
- ConvertTypeToSerializer(i->GetType(),
+ ReplaceAll(CB_SERIALIZER_BODY)
+ .Change("<TYPE>", st.GetID())
+ .Change("<BODY>", [&]() {
+ std::string str;
+ for (const auto& i : st.GetElements()) {
+ str += AddIndent(TAB_SIZE,
+ ConvertTypeToSerializer(i->GetType(),
"param.Get" + i->GetID() + "()", "h"));
- }
- stream << Tab(1) << "return h;" << NLine(1);
- }, false);
+ }
+ str += Tab(1) + "return h;";
+ return str;
+ })
+ .Out(stream);
}
void CppGeneratorBase::GenDeSerializer(std::ofstream& stream) {
@@ -294,25 +271,38 @@ void CppGeneratorBase::GenDeSerializer(std::ofstream& stream) {
void CppGeneratorBase::GenDeSerializer(std::ofstream& stream,
const Structure& st, bool proto) {
- const char parcel_str[] = "rpc_port_parcel_h";
-
- stream << parcel_str << " operator >> ("
- << parcel_str << " h, " << st.GetID() << "& param)";
if (proto) {
- stream << ";" << NLine(1);
+ ReplaceAll(CB_DESERIALIZER_HEADER)
+ .Change("<TYPE>", st.GetID())
+ .Out(stream);
return;
}
- stream << " ";
- GenBrace(stream, 0, [&]() {
- for (auto& i : st.GetElements().GetElms()) {
- stream << AddIndent(TAB_SIZE,
- ConvertTypeToDeserializer(i->GetType(), i->GetID(), "h"));
- stream << Tab(1) << "param.Set" << i->GetID() << "(std::move("
- << i->GetID() << "));" << NLine(2);
- }
- stream << Tab(1) << "return h;" << NLine(1);
- }, false);
+ ReplaceAll(CB_DESERIALIZER_BODY)
+ .Change("<TYPE>", st.GetID())
+ .Change("<BODY>", [&]() {
+ std::string str;
+ for (const auto& i : st.GetElements()) {
+ auto& type = i->GetType();
+ str += AddIndent(TAB_SIZE,
+ ConvertTypeToDeserializer(type, i->GetID(), "h"));
+
+ str += Tab(1) + "param.Set" + i->GetID() + "(";
+ if (type.ToString() == "list" ||
+ type.ToString() == "array" ||
+ type.ToString() == "string" ||
+ type.ToString() == "bundle" ||
+ type.IsUserDefinedType())
+ str += "std::move(" + i->GetID() + ")";
+ else
+ str += i->GetID();
+
+ str += ");" + NLine(2);
+ }
+ str += Tab(1) + "return h;";
+ return str;
+ })
+ .Out(stream);
}
std::string CppGeneratorBase::ConvertTypeToString(const BaseType& type) {
@@ -351,45 +341,39 @@ void CppGeneratorBase::AddSerializerList(const BaseType& type) {
void CppGeneratorBase::GenListSerializer(std::ofstream& stream,
const BaseType& type, bool proto) {
- stream << "rpc_port_parcel_h operator << (rpc_port_parcel_h h, const "
- << ConvertTypeToString(type) << "& c)";
-
if (proto) {
- stream << ";" << NLine(1);
- stream << "rpc_port_parcel_h operator >> (rpc_port_parcel_h h, "
- << ConvertTypeToString(type) << "& c);" << NLine(1);
+ ReplaceAll(CB_SERIALIZER_HEADER)
+ .Change("<TYPE>", ConvertTypeToString(type))
+ .Out(stream);
+ ReplaceAll(CB_DESERIALIZER_HEADER)
+ .Change("<TYPE>", ConvertTypeToString(type))
+ .Out(stream);
return;
}
- stream << " ";
- GenBrace(stream, 0, [&]() {
- stream << Tab(1)
- << "rpc_port_parcel_write_array_count(h, c.size());"
- << NLine(1);
- stream << Tab(1) << "for (const auto& i : c) ";
- GenBrace(stream, TAB_SIZE, [&]() {
- auto& mt = *type.GetMetaType();
- stream << AddIndent(TAB_SIZE * 2, ConvertTypeToSerializer(mt, "i", "h"));
- }, false);
- stream << Tab(1) << "return h;" << NLine(1);
- }, false);
- stream << NLine(1);
-
- stream << "rpc_port_parcel_h operator >> (rpc_port_parcel_h h, "
- << ConvertTypeToString(type) << "& c) ";
- GenBrace(stream, 0, [&]() {
- stream << Tab(1) << "int l = 0;" << NLine(1);
- stream << Tab(1)
- << "rpc_port_parcel_read_array_count(h, &l);" << NLine(1);
- stream << Tab(1) << "for (int i = 0; i < l; i++) ";
- GenBrace(stream, TAB_SIZE, [&]() {
- auto& mt = *type.GetMetaType();
- stream << AddIndent(TAB_SIZE * 2,
- ConvertTypeToDeserializer(mt, "v", "h", true));
- stream << Tab(2) << "c.push_back(std::move(v));" << NLine(1);
- }, false);
- stream << Tab(1) << "return h;" << NLine(1);
- }, false);
+ ReplaceAll(CB_SERIALIZER_LIST_BODY)
+ .Change("<TYPE>", ConvertTypeToString(type))
+ .Change("<BODY>", [&]() {
+ auto* ptr = type.GetMetaType();
+ if (ptr == nullptr)
+ return std::string("");
+ auto& mt = *ptr;
+ return std::string(AddIndent(TAB_SIZE * 2,
+ ConvertTypeToSerializer(mt, "i", "h")));
+ })
+ .Out(stream);
+
+ ReplaceAll(CB_DESERIALIZER_LIST_BODY)
+ .Change("<TYPE>", ConvertTypeToString(type))
+ .Change("<BODY>", [&]() {
+ auto* ptr = type.GetMetaType();
+ if (ptr == nullptr)
+ return std::string("");
+ auto& mt = *ptr;
+ return std::string(AddIndent(TAB_SIZE * 2,
+ ConvertTypeToDeserializer(mt, "v", "h", true)));
+ })
+ .Out(stream);
}
void CppGeneratorBase::GenListSerializer(std::ofstream& stream, bool proto) {
@@ -397,16 +381,16 @@ void CppGeneratorBase::GenListSerializer(std::ofstream& stream, bool proto) {
for (auto& i : GetDocument().GetBlocks()) {
if (i->GetType() == Block::TYPE_STRUCTURE) {
const Structure& st = static_cast<const Structure&>(*i);
- for (auto& j : st.GetElements().GetElms()) {
+ for (const auto& j : st.GetElements()) {
auto& t = j->GetType();
AddSerializerList(t);
}
} else if (i->GetType() == Block::TYPE_INTERFACE) {
const Interface& iface = static_cast<const Interface&>(*i);
- for (auto& j : iface.GetDeclarations().GetDecls()) {
+ for (const auto& j : iface.GetDeclarations()) {
auto& t = j->GetType();
AddSerializerList(t);
- for (auto& k : j->GetParameters().GetParams()) {
+ for (const auto& k : j->GetParameters()) {
auto& t1 = k->GetParameterType().GetBaseType();
AddSerializerList(t1);
}
@@ -422,34 +406,43 @@ void CppGeneratorBase::GenListSerializer(std::ofstream& stream, bool proto) {
void CppGeneratorBase::GenMethodId(std::ofstream& stream,
const Interface& iface) {
- stream << Tab(1) << "enum class MethodId : int ";
- GenBrace(stream, TAB_SIZE, [&]() {
- int cnt = 2;
- stream << Tab(2) << "__Result = 0," << NLine(1);
- stream << Tab(2) << "__Callback = 1," << NLine(1);
- for (auto& i : iface.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
- continue;
- stream << Tab(2)
- << i->GetID() << " = " << cnt++ << "," << NLine(1);
- }
- }, false, false);
- stream << ";" << NLine(2);
+ stream << GetMethodId(iface);
+}
+
+std::string CppGeneratorBase::GetMethodId(const Interface& iface) {
+ return std::string(ReplaceAll(CB_METHOD_IDS)
+ .Change("<IDS>", [&]() {
+ std::string str;
+ int cnt = 2;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+ str += Tab(1) + i->GetID() + " = " + std::to_string(cnt++) + ","
+ + NLine(1);
+ }
+
+ return str;
+ })
+ .AddIndent(TAB_SIZE));
}
void CppGeneratorBase::GenDelegateId(std::ofstream& stream,
const Interface& iface) {
- stream << Tab(1) << "enum class DelegateId : int ";
- GenBrace(stream, TAB_SIZE, [&]() {
- int cnt = 1;
- for (auto& i : iface.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
- continue;
- stream << Tab(2)
- << i->GetID() << " = " << cnt++ << "," << NLine(1);
- }
- }, false, false);
- stream << ";" << NLine(2);
+ ReplaceAll(CB_DELEGATE_IDS)
+ .Change("<IDS>", [&]() {
+ int cnt = 1;
+ std::string str;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+ str += Tab(1) + i->GetID() + " = " + std::to_string(cnt++) + ","
+ + NLine(1);
+ }
+
+ return str;
+ })
+ .AddIndent(TAB_SIZE)
+ .Out(stream);
}
void CppGeneratorBase::GenParameters(std::ofstream& stream,
@@ -460,7 +453,7 @@ void CppGeneratorBase::GenParameters(std::ofstream& stream,
std::string CppGeneratorBase::GetParameters(const Parameters& ps) {
bool first = true;
std::string ret;
- for (auto& i : ps.GetParams()) {
+ for (const auto& i : ps) {
if (!first) {
ret += ", ";
}
@@ -480,38 +473,15 @@ std::string CppGeneratorBase::GetParameters(const Parameters& ps) {
return ret;
}
-void CppGeneratorBase::GenDeclaration(std::ofstream& stream,
- const Interface& iface,
- const Declaration& decl) {
- stream << ConvertTypeToString(decl.GetType()) << " " << iface.GetID() << "::"
- << decl.GetID() << "(";
- GenParameters(stream, decl.GetParameters());
- stream << ") ";
-}
-
std::string CppGeneratorBase::GenPrivateSharingRequest(const BaseType& type,
std::string id) {
std::string ret;
if (type.GetMetaType() != nullptr && (type.GetMetaType()->GetFullName() == "file")) {
- ret += std::string("for (const auto& i : " + id + ") {\n")
- + std::string(" std::vector<const char*> v;\n")
- + std::string(" std::string name = i.GetFileName();\n")
- + std::string(" v.push_back(name.c_str());\n")
- + std::string(" int r = rpc_port_set_private_sharing_array(port_, v.data(), v.size());\n")
- + std::string(" if (r != RPC_PORT_ERROR_NONE) {\n")
- + std::string(" _E(\"Failed to set private sharing\");\n")
- + std::string(" throw InvalidIOException();\n")
- + std::string(" }\n")
- + std::string("}\n");
+ ret = ReplaceAll(CB_PRIVATE_SHARING_REQUEST_META)
+ .Change("<ID>", id);
} else if (type.ToString() == "file") {
- ret += "std::vector<const char*> v;\n"
- + std::string("std::string name = " + id + ".GetFileName();\n")
- + std::string("v.push_back(name.c_str());\n")
- + std::string("int r = rpc_port_set_private_sharing_array(port_, v.data(), v.size());\n")
- + std::string("if (r != RPC_PORT_ERROR_NONE) {\n")
- + std::string(" _E(\"Failed to set private sharing\");\n")
- + std::string(" throw InvalidIOException();\n")
- + std::string("}\n");
+ ret = ReplaceAll(CB_PRIVATE_SHARING_REQUEST)
+ .Change("<ID>", id);
}
return ret;
}
@@ -577,8 +547,7 @@ std::string CppGeneratorBase::ConvertTypeToDeserializer(
if (make_new_type) {
ret += "Bundle " + id + "(" + id + "_raw);\n";
} else {
- ret += id + " = " + id + "_raw;\n"
- + "bundle_free(" + id + "_raw);\n";
+ ret += id + " = " + id + "_raw;\n";
}
} else if (type.GetMetaType() != nullptr || type.IsUserDefinedType()) {
std::string n;
@@ -591,8 +560,9 @@ std::string CppGeneratorBase::ConvertTypeToDeserializer(
if (make_new_type) {
ret += n + " ";
if (IsDelegateType(type)) {
- ret += id + "(new " + type.ToString()
- + "(callback_port, std::weak_ptr<ServiceBase>(b)));\n";
+ ret += id + "(new " + type.ToString() + "(callback_port" +
+ (thread_enabled_ ? "_" : "") +
+ ", std::weak_ptr<ServiceBase>(b)));\n";
} else {
ret += id + ";\n";
}
@@ -615,7 +585,7 @@ void CppGeneratorBase::GenBodyCallbacks(std::ofstream& stream,
const Interface& iface, bool is_proxy) {
stream << ReplaceAll(CB_CALLBACK_BASE, "##", iface.GetID());
- for (auto& i : iface.GetDeclarations().GetDecls()) {
+ for (const auto& i : iface.GetDeclarations()) {
if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
continue;
GenBodyCallback(stream, iface, *i, is_proxy);
@@ -625,74 +595,71 @@ void CppGeneratorBase::GenBodyCallbacks(std::ofstream& stream,
void CppGeneratorBase::GenBodyCallback(std::ofstream& stream,
const Interface& iface, const Declaration& decl, bool is_proxy) {
if (!is_proxy) {
- GenTemplate(CB_CALLBACK_INVOKE_METHOD, stream,
- [&]()->std::string {
- return iface.GetID();
- },
- [&]()->std::string {
- return decl.GetID();
- },
- [&]()->std::string {
- return GetParameters(decl.GetParameters());
- },
- [&]()->std::string {
- std::string m;
- for (auto& i : decl.GetParameters().GetParams()) {
- auto& pt = i->GetParameterType();
- m += AddIndent(TAB_SIZE,
- GenPrivateSharingRequest(pt.GetBaseType(), i->GetID()));
- m += AddIndent(TAB_SIZE,
- ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p"));
- }
- return m;
- });
+ ReplaceAll(CB_CALLBACK_INVOKE_METHOD)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Change("<CALLBACK_CLS_NAME>", decl.GetID())
+ .Change("<PARAMS>", GetParameters(decl.GetParameters()))
+ .Change("<BODY>", [&]() {
+ std::string m;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ m += AddIndent(TAB_SIZE,
+ GenPrivateSharingRequest(pt.GetBaseType(), i->GetID()));
+ m += AddIndent(TAB_SIZE,
+ ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p"));
+ }
+ return m;
+ })
+ .Out(stream);
} else {
- GenTemplate(CB_CALLBACK_ON_RECEIVED_EVENT_METHOD, stream,
- [&]()->std::string {
- return iface.GetID();
- },
- [&]()->std::string {
- return decl.GetID();
- },
- [&]()->std::string {
- int cnt = 1;
- std::string ret;
- for (auto& i : decl.GetParameters().GetParams()) {
- std::string v = "param" + std::to_string(cnt);
- std::string c = ConvertTypeToDeserializer(
- i->GetParameterType().GetBaseType(), v, "parcel");
- ret += AddIndent(TAB_SIZE, c) + NLine(1);
- cnt++;
- }
+ ReplaceAll(CB_CALLBACK_ON_RECEIVED_EVENT_METHOD)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Change("<CALLBACK_CLS_NAME>", decl.GetID())
+ .Change("<BODY>", [&]() {
+ int cnt = 1;
+ std::string ret;
+ for (const auto& i : decl.GetParameters()) {
+ std::string v = "param" + std::to_string(cnt);
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, "parcel");
+ ret += AddIndent(TAB_SIZE, c) + NLine(1);
+ cnt++;
+ }
- cnt = 1;
- ret += Tab(1) + "OnReceived(";
- for (int i = 0; i < decl.GetParameters().GetParams().size(); i++) {
- if (cnt != 1) {
- ret += ", ";
+ cnt = 1;
+ ret += Tab(1) + "OnReceived(";
+ for (auto i = decl.GetParameters().begin();
+ i != decl.GetParameters().end(); ++i) {
+ if (cnt != 1) {
+ ret += ", ";
+ }
+ ret += "std::move(param" + std::to_string(cnt) + ")";
+ cnt++;
}
- ret += "std::move(param" + std::to_string(cnt) + ")";
- cnt++;
- }
- ret += ");";
+ ret += ");";
- return ret;
- });
+ return ret;
+ })
+ .Out(stream);
}
}
void CppGeneratorBase::GenHeaderCallbacks(std::ofstream& stream,
const Interface& iface,
bool is_proxy) {
- stream << CB_CALLBACK_BASE_HEADER_FRONT;
- if (is_proxy) {
- stream << Tab(1)
- << " virtual void OnReceivedEvent(rpc_port_parcel_h port) = 0;"
- << NLine(1);
- }
- stream << CB_CALLBACK_BASE_HEADER_BACK;
+ ReplaceAll(CB_CALLBACK_BASE_HEADER)
+ .Change("<METHOD_ON_RECEIVED_EVENT>", [&]() {
+ std::string str;
+ if (is_proxy) {
+ str = Tab(2)
+ + "virtual void OnReceivedEvent(rpc_port_parcel_h port) = 0;";
+ }
- for (auto& i : iface.GetDeclarations().GetDecls()) {
+ return str;
+ })
+ .Out(stream);
+
+ for (const auto& i : iface.GetDeclarations()) {
if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
continue;
GenHeaderCallback(stream, *i, is_proxy);
@@ -702,16 +669,15 @@ void CppGeneratorBase::GenHeaderCallbacks(std::ofstream& stream,
void CppGeneratorBase::GenHeaderCallback(std::ofstream& stream,
const Declaration& decl,
bool is_proxy) {
- stream << GenTemplateString(CB_CALLBACK_CLASS,
- [&]()->std::string {
- return decl.GetID();
- },
- [&]()->std::string {
- return ReplaceAll(
- is_proxy ? CB_CALLBACK_CTOR_PROXY : CB_CALLBACK_CTOR_STUB,
- "##", decl.GetID());
- },
- [&]()->std::string {
+ ReplaceAll(CB_CALLBACK_CLASS)
+ .Select("<CTOR>",
+ { CB_CALLBACK_CTOR_PROXY, CB_CALLBACK_CTOR_STUB }, [&]() {
+ if (is_proxy)
+ return 0;
+ return 1;
+ })
+ .Change("<CLS_NAME>", decl.GetID())
+ .Change("<PUBLIC_MEMBERS>", [&]() {
std::string ret;
if (is_proxy) {
ret = Tab(2) + "virtual void OnReceived("
@@ -724,10 +690,11 @@ void CppGeneratorBase::GenHeaderCallback(std::ofstream& stream,
}
return ret;
- },
- [&]()->std::string {
+ })
+ .Change("<PRIVATE_MEMBERS>", [&]() {
return is_proxy ? CB_CALLBACK_PRIVATE_PROXY : CB_CALLBACK_PRIVATE_STUB;
- });
+ })
+ .Out(stream);
}
void CppGeneratorBase::GenVersion(std::ofstream& stream) {
@@ -748,4 +715,32 @@ void CppGeneratorBase::GenLogDefinition(std::ofstream& stream) {
stream << CB_LOG_DEF;
}
+void CppGeneratorBase::GenVersionDefinition(std::ofstream& stream) {
+ stream << ReplaceAll(CB_VERSION_DEF, "[VERSION]", FULLVER);
+}
+
+bool CppGeneratorBase::IsMovableType(const BaseType& type,
+ ParameterType::Direction dir) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+
+ if (IsDelegateType(iface, type))
+ return true;
+
+ if (dir != ParameterType::Direction::IN)
+ continue;
+
+ if (type.ToString() == "string" ||
+ type.ToString() == "file" ||
+ type.ToString() == "bundle" ||
+ type.GetMetaType() != nullptr ||
+ type.IsUserDefinedType())
+ return true;
+ }
+
+ return false;
+}
+
} // namespace tidl
diff --git a/idlc/gen/cpp_gen_base.h b/idlc/gen/cpp_gen_base.h
index fce6c56..11d75ed 100644
--- a/idlc/gen/cpp_gen_base.h
+++ b/idlc/gen/cpp_gen_base.h
@@ -21,29 +21,30 @@
#include <string>
#include <map>
-#include "idlc/ast/type.h"
#include "idlc/ast/structure.h"
+#include "idlc/ast/type.h"
#include "idlc/gen/generator.h"
namespace tidl {
class CppGeneratorBase : public Generator {
public:
- explicit CppGeneratorBase(std::shared_ptr<Document> doc);
+ explicit CppGeneratorBase(std::shared_ptr<Document> doc,
+ bool thread_enabled = false);
virtual ~CppGeneratorBase() = default;
void GenVersion(std::ofstream& stream);
void GenStructuresForHeader(std::ofstream& stream);
+ std::string GetStructuresForHeader();
void GenStructuresForBody(std::ofstream& stream);
void GenSerializer(std::ofstream& stream);
void GenDeSerializer(std::ofstream& stream);
void GenListSerializer(std::ofstream& stream, bool proto = false);
void GenPrototype(std::ofstream& stream);
void GenMethodId(std::ofstream& stream, const Interface& iface);
+ std::string GetMethodId(const Interface& iface);
void GenDelegateId(std::ofstream& stream, const Interface& iface);
void GenParameters(std::ofstream& stream, const Parameters& ps);
- void GenDeclaration(std::ofstream& stream, const Interface& iface,
- const Declaration& decl);
void GenBodyCallbacks(std::ofstream& stream, const Interface& iface,
bool is_proxy);
void GenHeaderCallbacks(std::ofstream& stream, const Interface& iface,
@@ -60,10 +61,12 @@ class CppGeneratorBase : public Generator {
std::string GetParameters(const Parameters& ps);
void GenLogTag(std::ofstream& stream, std::string id);
void GenLogDefinition(std::ofstream& stream);
+ void GenVersionDefinition(std::ofstream& stream);
+ bool IsMovableType(const BaseType& type, ParameterType::Direction dir);
private:
- void GenSetter(std::ofstream& stream, const Element& ele);
- void GenGetter(std::ofstream& stream, const Element& ele);
+ std::string GetSetter(const Element& ele);
+ std::string GetGetter(const Element& ele);
void AddSerializerList(const BaseType& type);
void GenListSerializer(std::ofstream& stream, const BaseType& type,
bool proto = false);
@@ -71,7 +74,7 @@ class CppGeneratorBase : public Generator {
bool proto = false);
void GenSerializer(std::ofstream& stream, const Structure& st,
bool proto = false);
- void GenStructureForHeader(std::ofstream& stream, const Structure& st);
+ std::string GetStructureForHeader(const Structure& st);
void GenStructureForBody(std::ofstream& stream, const Structure& st);
void GenBodyCallback(std::ofstream& stream, const Interface& iface,
const Declaration& decl, bool is_proxy);
@@ -86,6 +89,7 @@ class CppGeneratorBase : public Generator {
std::map<std::string, std::string> parcel_type_map_;
std::map<std::string, std::string> type_init_map_;
std::map<std::string, const BaseType*> serializer_list_;
+ bool thread_enabled_;
};
} // namespace tidl
diff --git a/idlc/gen/cpp_gen_base_cb.h b/idlc/gen/cpp_gen_base_cb.h
index 46f58b2..66b1e85 100644
--- a/idlc/gen/cpp_gen_base_cb.h
+++ b/idlc/gen/cpp_gen_base_cb.h
@@ -136,16 +136,13 @@ R"__cpp_cb(/*
*/
)__cpp_cb";
-const char CB_CALLBACK_BASE_HEADER_FRONT[] =
+const char CB_CALLBACK_BASE_HEADER[] =
R"__cpp_cb(
class CallbackBase {
public:
CallbackBase(int delegate_id, bool once);
virtual ~CallbackBase() = default;
-)__cpp_cb";
-
-const char CB_CALLBACK_BASE_HEADER_BACK[] =
-R"__cpp_cb(
+<METHOD_ON_RECEIVED_EVENT>
int GetId() const;
int GetSeqId() const;
bool IsOnce() const;
@@ -164,17 +161,17 @@ R"__cpp_cb(
const char CB_CALLBACK_CLASS[] =
R"__cpp_cb(
- class $$ : public CallbackBase {
- public:$$
-$$
- private:$$
+ class <CLS_NAME> : public CallbackBase {
+ public:<CTOR>
+<PUBLIC_MEMBERS>
+ private:<PRIVATE_MEMBERS>
};
)__cpp_cb";
const char CB_CALLBACK_CTOR_STUB[] =
R"__cpp_cb(
- ##(rpc_port_h port, std::weak_ptr<ServiceBase> service)
- : CallbackBase(static_cast<int>(DelegateId::##), false) {
+ <CLS_NAME>(rpc_port_h port, std::weak_ptr<ServiceBase> service)
+ : CallbackBase(static_cast<int>(DelegateId::<CLS_NAME>), false) {
port_ = port;
service_ = std::move(service);
}
@@ -182,8 +179,8 @@ R"__cpp_cb(
const char CB_CALLBACK_CTOR_PROXY[] =
R"__cpp_cb(
- ##(bool once = false)
- : CallbackBase(static_cast<int>(DelegateId::##), once) {}
+ <CLS_NAME>(bool once = false)
+ : CallbackBase(static_cast<int>(DelegateId::<CLS_NAME>), once) {}
)__cpp_cb";
const char CB_CALLBACK_PRIVATE_PROXY[] =
@@ -200,7 +197,7 @@ R"__cpp_cb(
const char CB_CALLBACK_INVOKE_METHOD[] =
R"__cpp_cb(
-void $$::$$::Invoke($$) {
+void <CLS_NAME>::<CALLBACK_CLS_NAME>::Invoke(<PARAMS>) {
if (port_ == nullptr)
throw NotConnectedSocketException();
if (service_.lock().get() == nullptr)
@@ -213,7 +210,7 @@ void $$::$$::Invoke($$) {
rpc_port_parcel_create(&p);
rpc_port_parcel_write_int32(p, static_cast<int>(MethodId::__Callback));
p << *this;
-$$
+<BODY>
// Send
set_last_result(rpc_port_parcel_send(p, port_));
rpc_port_parcel_destroy(p);
@@ -223,8 +220,8 @@ $$
const char CB_CALLBACK_ON_RECEIVED_EVENT_METHOD[] =
R"__cpp_cb(
-void $$::$$::OnReceivedEvent(rpc_port_parcel_h parcel) {
-$$
+void <CLS_NAME>::<CALLBACK_CLS_NAME>::OnReceivedEvent(rpc_port_parcel_h parcel) {
+<BODY>
}
)__cpp_cb";
@@ -261,4 +258,119 @@ R"__cpp_cb(
#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
)__cpp_cb";
+/**
+ * [VERSION] Version of TIDL Compiler.
+ */
+constexpr const char CB_VERSION_DEF[] =
+R"__cpp_cb(
+#ifndef TIDL_VERSION
+#define TIDL_VERSION "[VERSION]"
+#endif
+)__cpp_cb";
+
+constexpr const char CB_STRUCTURE_FOR_HEADER[] =
+R"__cpp_cb(
+class <CLS_NAME> final {
+ public:
+ <CLS_NAME>();
+ <CLS_NAME>(<PARAMS>);
+ <GETTER_SETTER>
+ private:<DATA_MEMBERS>
+};
+)__cpp_cb";
+
+constexpr const char CB_SERIALIZER_HEADER[] =
+R"__cpp_cb(
+rpc_port_parcel_h operator << (rpc_port_parcel_h h, const <TYPE>& param);
+)__cpp_cb";
+
+constexpr const char CB_SERIALIZER_BODY[] =
+R"__cpp_cb(
+rpc_port_parcel_h operator << (rpc_port_parcel_h h, const <TYPE>& param) {
+<BODY>
+}
+)__cpp_cb";
+
+constexpr const char CB_SERIALIZER_LIST_BODY[] =
+R"__cpp_cb(
+rpc_port_parcel_h operator << (rpc_port_parcel_h h, const <TYPE>& param) {
+ rpc_port_parcel_write_array_count(h, param.size());
+ for (const auto& i : param) {
+<BODY>
+ }
+
+ return h;
+}
+)__cpp_cb";
+
+constexpr const char CB_DESERIALIZER_HEADER[] =
+R"__cpp_cb(
+rpc_port_parcel_h operator >> (rpc_port_parcel_h h, <TYPE>& param);
+)__cpp_cb";
+
+constexpr const char CB_DESERIALIZER_BODY[] =
+R"__cpp_cb(
+rpc_port_parcel_h operator >> (rpc_port_parcel_h h, <TYPE>& param) {
+<BODY>
+}
+)__cpp_cb";
+
+constexpr const char CB_DESERIALIZER_LIST_BODY[] =
+R"__cpp_cb(
+rpc_port_parcel_h operator >> (rpc_port_parcel_h h, <TYPE>& param) {
+ int l = 0;
+ rpc_port_parcel_read_array_count(h, &l);
+
+ for (int i = 0; i < l; i++) {
+<BODY>
+ param.push_back(std::move(v));
+ }
+
+ return h;
+}
+)__cpp_cb";
+
+constexpr const char CB_METHOD_IDS[] =
+R"__cpp_cb(
+enum class MethodId : int {
+ __Result = 0,
+ __Callback = 1,
+<IDS>
+};
+)__cpp_cb";
+
+constexpr const char CB_DELEGATE_IDS[] =
+R"__cpp_cb(
+enum class DelegateId : int {
+<IDS>
+};
+)__cpp_cb";
+
+constexpr const char CB_PRIVATE_SHARING_REQUEST_META[] =
+R"__cpp_cb(
+for (const auto& i : <ID>) {
+ std::vector<const char*> v;
+ std::string name = i.GetFileName();
+ v.push_back(name.c_str());
+ int r = rpc_port_set_private_sharing_array(port_, v.data(), v.size());
+ if (r != RPC_PORT_ERROR_NONE) {
+ _E("Failed to set private sharing");
+ throw InvalidIOException();
+ }
+}
+)__cpp_cb";
+
+constexpr const char CB_PRIVATE_SHARING_REQUEST[] =
+R"__cpp_cb(
+std::vector<const char*> v;
+std::string name = <ID>.GetFileName();
+v.push_back(name.c_str());
+rpc_port_set_private_sharing_array(port_, v.data(), v.size());
+int r = rpc_port_set_private_sharing_array(port_, v.data(), v.size());
+if (r != RPC_PORT_ERROR_NONE) {
+ _E("Failed to set private sharing");
+ throw InvalidIOException();
+}
+)__cpp_cb";
+
#endif // IDLC_CPP_GEN_CPP_GEN_BASE_CB_H_
diff --git a/idlc/gen/cpp_group_body_gen.cc b/idlc/gen/cpp_group_body_gen.cc
new file mode 100644
index 0000000..4b1ce7a
--- /dev/null
+++ b/idlc/gen/cpp_group_body_gen.cc
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/cpp_group_body_gen.h"
+
+namespace {
+#include "idlc/gen/cpp_group_body_gen_cb.h"
+}
+
+namespace tidl {
+
+CppGroupBodyGen::CppGroupBodyGen(std::shared_ptr<Document> doc)
+ : CppGeneratorBase(doc) {}
+
+void CppGroupBodyGen::OnInitGen(std::ofstream& stream) {
+ std::string key(".cc");
+ std::string header_file = FileName;
+ std::size_t found = header_file.rfind(key);
+ if (found != std::string::npos)
+ header_file.replace(found, key.length(), ".h");
+
+ GenVersion(stream);
+
+ ReplaceAll(CB_HEADER)
+ .Change("<HEADER_FILE>", header_file)
+ .Out(stream);
+
+ GenLogTag(stream, "RPC_PORT_GROUP");
+ GenLogDefinition(stream);
+ GenVersionDefinition(stream);
+ stream << NLine(1);
+ GenNamespace(stream);
+}
+
+void CppGroupBodyGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void CppGroupBodyGen::GenNamespace(std::ofstream& stream) {
+ stream << "namespace rpc_port ";
+ GenBrace(stream, 0, [&]() {
+ stream << "namespace " << GetFileNamespace() << " ";
+ GenBrace(stream, 0, [&]() {
+ stream << NLine(1);
+ GenStructuresForBody(stream);
+ stream << "namespace group ";
+ GenBrace(stream, 0, [&]() {
+ GenPrototype(stream);
+ GenSerializer(stream);
+ GenDeSerializer(stream);
+ GenListSerializer(stream);
+ GenInterfaces(stream);
+ }, false, false);
+ stream << " // namespace group" + NLine(1);
+ }, false, false);
+ stream << " // namespace " + GetFileNamespace() + NLine(1);
+ }, false, false);
+ stream << " // namespace rpc_port" + NLine(1);
+}
+
+void CppGroupBodyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CppGroupBodyGen::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ GenConstructor(stream, iface);
+ GenDestructor(stream, iface);
+ GenHelperMethods(stream, iface);
+ GenMethods(stream, iface);
+}
+
+void CppGroupBodyGen::GenConstructor(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_CTOR)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Out(stream);
+}
+
+void CppGroupBodyGen::GenDestructor(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_DTOR)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Out(stream);
+}
+
+std::string CppGroupBodyGen::GetDeserializer(const Interface& iface) {
+ std::string str;
+
+ for (const auto& i : iface.GetDeclarations()) {
+ str += ReplaceAll(CB_METHOD_DISPATCHER)
+ .Change("<METHOD_ID>", i->GetID())
+ .Change("<DISPATCH>", GetDispatcher(*i));
+ }
+
+ return str;
+}
+
+std::string CppGroupBodyGen::GetDispatcher(const Declaration& decl) {
+ std::string str;
+ int cnt = 1;
+
+ // Deserialize
+ for (const auto& i : decl.GetParameters()) {
+ if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT) {
+ cnt++;
+ continue;
+ }
+
+ std::string v = "param" + std::to_string(cnt);
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, "p");
+ str += AddIndent(TAB_SIZE * 3, c);
+ cnt++;
+ }
+
+ // Invoke
+ cnt = 1;
+ std::string m;
+
+ m += "ptr->On" + decl.GetID() + "(";
+ for (const auto& i : decl.GetParameters()) {
+ (void)i;
+ if (cnt != 1) {
+ m += ", ";
+ }
+
+ m += "param" + std::to_string(cnt);
+ cnt++;
+ }
+
+ m += ");\n";
+ str += AddIndent(TAB_SIZE * 3, m);
+
+ return str;
+}
+
+void CppGroupBodyGen::GenHelperMethods(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_GROUP_HELPER_METHODS)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Change("<DESERIALIZE>", GetDeserializer(iface))
+ .Out(stream);
+}
+
+void CppGroupBodyGen::GenMethods(std::ofstream& stream,
+ const Interface& iface) {
+ auto& decls = iface.GetDeclarations();
+
+ for (const auto& i : decls) {
+ GenInvocation(stream, iface, *i);
+ }
+}
+
+void CppGroupBodyGen::GenInvocation(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INVOCATION)
+ .Change("<RET_TYPE>", ConvertTypeToString(decl.GetType()))
+ .Change("<IFACE>", iface.GetID())
+ .Change("<METHOD>", decl.GetID())
+ .Change("<PARAMS>", GetParameters(decl.GetParameters()))
+ .Change("<SERIALIZE>", [&]() {
+ std::string m;
+ std::string ret;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT)
+ continue;
+ m += GenPrivateSharingRequest(pt.GetBaseType(), i->GetID());
+ m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p");
+ }
+
+ ret = AddIndent(TAB_SIZE, m) + NLine(1);
+ return ret;
+ })
+ .Out(stream);
+}
+
+} // namespace tidl
diff --git a/idlc/gen/cpp_group_body_gen.h b/idlc/gen/cpp_group_body_gen.h
new file mode 100644
index 0000000..0174683
--- /dev/null
+++ b/idlc/gen/cpp_group_body_gen.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_GEN_CPP_GROUP_BODY_GEN_H_
+#define IDLC_CPP_GEN_CPP_GROUP_BODY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/cpp_gen_base.h"
+
+namespace tidl {
+
+class CppGroupBodyGen : public CppGeneratorBase {
+ public:
+ explicit CppGroupBodyGen(std::shared_ptr<Document> doc);
+ virtual ~CppGroupBodyGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenConstructor(std::ofstream& stream, const Interface& iface);
+ void GenDestructor(std::ofstream& stream, const Interface& iface);
+ void GenHelperMethods(std::ofstream& stream, const Interface& iface);
+ void GenMethods(std::ofstream& stream, const Interface& iface);
+ void GenInvocation(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ std::string GetDeserializer(const Interface& iface);
+ std::string GetDispatcher(const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_CPP_GEN_CPP_GROUP_BODY_GEN_H_
diff --git a/idlc/gen/cpp_group_body_gen_cb.h b/idlc/gen/cpp_group_body_gen_cb.h
new file mode 100644
index 0000000..c6f6343
--- /dev/null
+++ b/idlc/gen/cpp_group_body_gen_cb.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_GEN_CPP_GROUP_BODY_GEN_CB_H_
+#define IDLC_CPP_GEN_CPP_GROUP_BODY_GEN_CB_H_
+
+const char CB_HEADER[] =
+R"__cpp_cb(
+#include <stdlib.h>
+#include <assert.h>
+#include <dlog.h>
+
+#include "<HEADER_FILE>"
+)__cpp_cb";
+
+const char CB_INTERFACE_CTOR[] =
+R"__cpp_cb(
+<CLS_NAME>::<CLS_NAME>(std::string sender_appid, bool is_system)
+ : sender_appid_(std::move(sender_appid)), is_system_(is_system) {
+ Subscribe();
+}
+
+)__cpp_cb";
+
+const char CB_INTERFACE_DTOR[] =
+R"__cpp_cb(
+<CLS_NAME>::~<CLS_NAME>() {
+ Unsubscribe();
+}
+)__cpp_cb";
+
+const char CB_INVOCATION[] =
+R"__cpp_cb(
+<RET_TYPE> <IFACE>::<METHOD>(<PARAMS>) {
+ rpc_port_parcel_h p;
+ rpc_port_parcel_create(&p);
+ std::unique_ptr<std::remove_pointer<rpc_port_parcel_h>::type,
+ decltype(rpc_port_parcel_destroy)*> p_auto(p, rpc_port_parcel_destroy);
+ rpc_port_parcel_header_h header_;
+ rpc_port_parcel_get_header(p, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ int seq_num_ = -1;
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+ rpc_port_parcel_write_int32(p, static_cast<int>(MethodId::<METHOD>));
+<SERIALIZE>
+ // Send
+ bundle* b = bundle_create();
+ std::unique_ptr<bundle, decltype(bundle_free)*> b_auto(b, bundle_free);
+ if (GetBundleFromParcel(p, b) == nullptr) {
+ _E("Failed to make bundle from parcel");
+ throw InvalidIOException();
+ }
+
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ int ret = event_publish_app_event(GetEventName().c_str(), b);
+ if (ret != EVENT_ERROR_NONE) {
+ _E("Failed to publish event. result(%d)", ret);
+ throw InvalidIOException();
+ }
+}
+)__cpp_cb";
+
+const char CB_GROUP_HELPER_METHODS[] =
+R"__cpp_cb(
+void <CLS_NAME>::Subscribe() {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ int ret = event_add_event_handler(GetEventName().c_str(), EventCb, this, &event_handler_);
+ if (ret != EVENT_ERROR_NONE) {
+ _E("Failed to register events. result(%d)", ret);
+ throw InvalidIOException();
+ }
+}
+
+void <CLS_NAME>::Unsubscribe() {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ if (event_handler_) {
+ event_remove_event_handler(event_handler_);
+ event_handler_ = nullptr;
+ }
+}
+
+bundle* <CLS_NAME>::GetBundleFromParcel(rpc_port_parcel_h p, bundle* b) {
+ void* raw = nullptr;
+ unsigned int size = 0;
+
+ int ret = rpc_port_parcel_get_raw(p, &raw, &size);
+ if (ret != RPC_PORT_ERROR_NONE)
+ return nullptr;
+
+ ret = bundle_add_byte(b, "TIDL_RAW", raw, size);
+ if (ret != BUNDLE_ERROR_NONE)
+ return nullptr;
+
+ return b;
+}
+
+rpc_port_parcel_h <CLS_NAME>::GetParcelFromBundle(bundle* b) {
+ void* raw = nullptr;
+ size_t size = 0;
+ rpc_port_parcel_h p;
+
+ int ret = bundle_get_byte(b, "TIDL_RAW", &raw, &size);
+ if (ret != BUNDLE_ERROR_NONE)
+ return nullptr;
+
+ ret = rpc_port_parcel_create_from_raw(&p, raw,
+ static_cast<unsigned int>(size));
+ if (ret != RPC_PORT_ERROR_NONE)
+ return nullptr;
+
+ return p;
+}
+
+std::string <CLS_NAME>::GetEventName() {
+ if (is_system_)
+ return "tizen.system.event.tidl_iface_<CLS_NAME>";
+ return "event." + sender_appid_ + ".tidl_iface_<CLS_NAME>";
+}
+
+void <CLS_NAME>::EventCb(const char* event_name, bundle* event_data, void* user_data) {
+ auto* ptr = static_cast<<CLS_NAME>*>(user_data);
+ rpc_port_parcel_h p = ptr->GetParcelFromBundle(event_data);
+ if (p == nullptr) {
+ _E("Invalid bundle");
+ return;
+ }
+
+ std::unique_ptr<std::remove_pointer<rpc_port_parcel_h>::type,
+ decltype(rpc_port_parcel_destroy)*> p_auto(p, rpc_port_parcel_destroy);
+
+ rpc_port_parcel_h header;
+ int seq_num = -1;
+ int cmd;
+ rpc_port_parcel_get_header(p, &header);
+ rpc_port_parcel_header_get_seq_num(header, &seq_num);
+
+ rpc_port_parcel_read_int32(p, &cmd);
+ switch (cmd) {
+<DESERIALIZE>
+
+ default:
+ _E("Unknown command(%d)", cmd);
+ }
+}
+
+)__cpp_cb";
+
+
+const char CB_METHOD_DISPATCHER[] =
+R"__cpp_cb(
+ case static_cast<int>(MethodId::<METHOD_ID>):
+ {
+<DISPATCH>
+ }
+ break;
+
+)__cpp_cb";
+
+#endif // IDLC_CPP_GEN_CPP_GROUP_BODY_GEN_CB_H_
diff --git a/idlc/gen/cpp_group_header_gen.cc b/idlc/gen/cpp_group_header_gen.cc
new file mode 100644
index 0000000..aaa996f
--- /dev/null
+++ b/idlc/gen/cpp_group_header_gen.cc
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/cpp_group_header_gen.h"
+
+namespace {
+#include "idlc/gen/cpp_group_header_gen_cb.h"
+}
+
+namespace tidl {
+
+CppGroupHeaderGen::CppGroupHeaderGen(std::shared_ptr<Document> doc)
+ : CppGeneratorBase(doc) {}
+
+void CppGroupHeaderGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ stream << CB_HEADER;
+ GenNamespace(stream);
+}
+
+void CppGroupHeaderGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void CppGroupHeaderGen::GenNamespace(std::ofstream& stream) {
+ ReplaceAll(CB_NAMESPACE_FULL)
+ .Change("<FILE_NAMESPACE>", GetFileNamespace())
+ .Change("<STRUCTS>", GetStructuresForHeader())
+ .Change("<EXCEPTIONS>", std::string(CB_EXCEPTIONS))
+ .Change("<INTERFACES>", GetInterfaces())
+ .Out(stream);
+}
+
+std::string CppGroupHeaderGen::GetInterfaces() {
+ std::string str;
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ str += GetInterface(iface);
+ }
+
+ return str;
+}
+
+std::string CppGroupHeaderGen::GetInterface(const Interface& iface) {
+ return std::string(ReplaceAll(CB_CLASS_FULL)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Change("<PUBLIC_MEMBERS>", GetMethods(iface))
+ .Change("<PRIVATE_MEMBERS>",GetMethodId(iface)));
+}
+
+std::string CppGroupHeaderGen::GetMethods(const Interface& iface) {
+ auto& decls = iface.GetDeclarations();
+ std::string str;
+ for (const auto& i : decls) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ str += GetDeclaration(*i);
+ }
+ return str;
+}
+
+std::string CppGroupHeaderGen::GetDeclaration(const Declaration& decl) {
+ return std::string(ReplaceAll(CB_METHOD_DECL)
+ .Change("<COMMENTS>", decl.GetComments().empty() ? "" : decl.GetComments())
+ .Change("<RET_TYPE>", ConvertTypeToString(decl.GetType()))
+ .Change("<METHOD_NAME>", decl.GetID())
+ .Change("<PARAMS>", GetParameters(decl.GetParameters())));
+}
+} // namespace tidl
diff --git a/idlc/gen/cpp_group_header_gen.h b/idlc/gen/cpp_group_header_gen.h
new file mode 100644
index 0000000..2921840
--- /dev/null
+++ b/idlc/gen/cpp_group_header_gen.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_GEN_CPP_GROUP_HEADER_GEN_H_
+#define IDLC_CPP_GEN_CPP_GROUP_HEADER_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/cpp_gen_base.h"
+
+namespace tidl {
+
+class CppGroupHeaderGen : public CppGeneratorBase {
+ public:
+ explicit CppGroupHeaderGen(std::shared_ptr<Document> doc);
+ virtual ~CppGroupHeaderGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ std::string GetInterfaces();
+ std::string GetInterface(const Interface& iface);
+ std::string GetMethods(const Interface& iface);
+ std::string GetDeclaration(const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_CPP_GEN_CPP_GROUP_HEADER_GEN_H_
diff --git a/idlc/gen/cpp_group_header_gen_cb.h b/idlc/gen/cpp_group_header_gen_cb.h
new file mode 100644
index 0000000..f685077
--- /dev/null
+++ b/idlc/gen/cpp_group_header_gen_cb.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_GEN_CPP_GROUP_HEADER_GEN_CB_H_
+#define IDLC_CPP_GEN_CPP_GROUP_HEADER_GEN_CB_H_
+
+const char CB_EXCEPTIONS[] =
+R"__cpp_cb(
+class Exception {};
+class NotConnectedSocketException : public Exception {};
+class InvalidProtocolException : public Exception {};
+class InvalidIOException : public Exception {};
+class PermissionDeniedException : public Exception {};
+class InvalidIDException : public Exception {};
+)__cpp_cb";
+
+const char CB_NAMESPACE_FULL[] =
+R"__cpp_cb(
+namespace rpc_port {
+namespace <FILE_NAMESPACE> {
+
+<STRUCTS>
+namespace group {
+
+<EXCEPTIONS>
+<INTERFACES>
+} // namespace group
+} // namespace <FILE_NAMESPACE>
+} // namespace rpc_port
+)__cpp_cb";
+
+const char CB_CLASS_FULL[] =
+R"__cpp_cb(
+class <CLS_NAME> {
+ public:
+ <CLS_NAME>(std::string sender_appid, bool is_system = false);
+ virtual ~<CLS_NAME>();
+
+ <PUBLIC_MEMBERS>
+
+ private:
+<PRIVATE_MEMBERS>
+
+ bundle* GetBundleFromParcel(rpc_port_parcel_h p, bundle* b);
+ rpc_port_parcel_h GetParcelFromBundle(bundle* b);
+ std::string GetEventName();
+ void Subscribe();
+ void Unsubscribe();
+ static void EventCb(const char* event_name, bundle* event_data, void* user_data);
+
+ private:
+ event_handler_h event_handler_ = nullptr;
+ std::string sender_appid_;
+ std::recursive_mutex mutex_;
+ bool is_system_;
+};
+)__cpp_cb";
+
+const char CB_METHOD_DECL[] =
+R"__cpp_cb(
+ <COMMENTS>
+ <RET_TYPE> <METHOD_NAME>(<PARAMS>);
+
+ virtual <RET_TYPE> On<METHOD_NAME>(<PARAMS>) {}
+)__cpp_cb";
+
+const char CB_HEADER[] =
+R"__cpp_cb(
+#pragma once
+
+#include <app_event.h>
+#include <bundle.h>
+#include <rpc-port-parcel.h>
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <mutex>
+#include <list>
+#include <atomic>
+
+)__cpp_cb";
+
+#endif // IDLC_CPP_GEN_CPP_GROUP_HEADER_GEN_CB_H_
diff --git a/idlc/gen/cpp_proxy_body_gen.cc b/idlc/gen/cpp_proxy_body_gen.cc
index 06a739d..b9984f7 100644
--- a/idlc/gen/cpp_proxy_body_gen.cc
+++ b/idlc/gen/cpp_proxy_body_gen.cc
@@ -42,6 +42,7 @@ void CppProxyBodyGen::OnInitGen(std::ofstream& stream) {
<< "#include \"" << header_file << "\"" << NLine(2);
GenLogTag(stream, "RPC_PORT_PROXY");
GenLogDefinition(stream);
+ GenVersionDefinition(stream);
stream << NLine(1);
GenNamespace(stream);
}
@@ -91,24 +92,16 @@ void CppProxyBodyGen::GenInterface(std::ofstream& stream,
void CppProxyBodyGen::GenConstructor(std::ofstream& stream,
const Interface& iface) {
- GenTemplate(CB_PROXY_INTERFACE_CTOR, stream,
- [&]()->std::string {
- return iface.GetID();
- },
- [&]()->std::string {
- return iface.GetID();
- });
+ ReplaceAll(CB_PROXY_INTERFACE_CTOR)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Out(stream);
}
void CppProxyBodyGen::GenDestructor(std::ofstream& stream,
const Interface& iface) {
- GenTemplate(CB_DTOR, stream,
- [&]()->std::string {
- return iface.GetID();
- },
- [&]()->std::string {
- return iface.GetID();
- });
+ ReplaceAll(CB_DTOR)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Out(stream);
}
void CppProxyBodyGen::GenHelperMethods(std::ofstream& stream,
@@ -121,84 +114,72 @@ void CppProxyBodyGen::GenMethods(std::ofstream& stream,
const Interface& iface) {
auto& decls = iface.GetDeclarations();
- for (auto& i : decls.GetDecls()) {
+ for (const auto& i : decls) {
if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
-
- GenDeclaration(stream, iface, *i);
- GenBrace(stream, 0, [&]() {
- GenInvocation(stream, *i);
- }, false);
- stream << NLine(1);
+ GenInvocation(stream, iface, *i);
}
}
void CppProxyBodyGen::GenInvocation(std::ofstream& stream,
- const Declaration& decl) {
- stream << CB_INVOCATION_PRE;
-
- // Serialize
- stream << Tab(1)
- << "rpc_port_parcel_write_int32(p, static_cast<int>(MethodId::"
- << decl.GetID() << "));" << NLine(1);
- std::string m;
- std::string l;
- for (auto& i : decl.GetParameters().GetParams()) {
- auto& pt = i->GetParameterType();
- if (pt.GetDirection() == ParameterType::Direction::OUT)
- continue;
- m += GenPrivateSharingRequest(pt.GetBaseType(), i->GetID());
- m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p");
- if (IsDelegateType(pt.GetBaseType())) {
- l += "delegate_list_.emplace_back(" + i->GetID() + ".release());\n";
- }
- }
- stream << AddIndent(TAB_SIZE, m) << NLine(1);
-
- if (decl.GetMethodType() == Declaration::MethodType::SYNC)
- stream << Tab(1) << "rpc_port_parcel_h parcel_received;" << NLine(1);
- stream << Tab(1) << "do ";
- GenBrace(stream, TAB_SIZE, [&]() {
- stream << Tab(2) << "std::lock_guard<std::recursive_mutex> lock(mutex_);"
- << NLine(2);
- if (!l.empty())
- stream << AddIndent(TAB_SIZE * 2, l);
- stream << CB_INVOCATION_MID << NLine(1);
- if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
- stream << Tab(2) << "// Receive" << NLine(1);
- stream << Tab(2)
- << "ConsumeCommand(&parcel_received, port_);" << NLine(1);
- }
- }, false, false);
- stream << " while (false);" << NLine(1);
-
- // Deserialize
- if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
- stream << Tab(1) << "rpc_port_parcel_destroy(p);"
- << NLine(1);
- return;
- }
-
- stream << CB_INVOCATION_RECEIVE << NLine(1);
- for (auto& i : decl.GetParameters().GetParams()) {
- if (i->GetParameterType().GetDirection() == ParameterType::Direction::IN) {
- continue;
- }
-
- std::string c = ConvertTypeToDeserializer(
- i->GetParameterType().GetBaseType(),
- i->GetID(), "parcel_received", false);
- if (c != "")
- stream << AddIndent(TAB_SIZE, c);
- }
-
- if (decl.GetType().ToString() != "void") {
- stream << AddIndent(TAB_SIZE,
- ConvertTypeToDeserializer(decl.GetType(),
- "ret", "parcel_received"));
- }
-
- stream << CB_INVOCATION_END;
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INVOCATION)
+ .Select("<ASYNC_OR_SYNC>",
+ { CB_INVOCATION_ASYNC, CB_INVOCATION_SYNC }, [&]() {
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC)
+ return 0;
+ return 1;
+ })
+ .Change("<RET_TYPE>", ConvertTypeToString(decl.GetType()))
+ .Change("<IFACE>", iface.GetID())
+ .Change("<METHOD>", decl.GetID())
+ .Change("<PARAMS>", GetParameters(decl.GetParameters()))
+ .Change("<SERIALIZE>", [&]() {
+ std::string m;
+ std::string l;
+ std::string ret;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT)
+ continue;
+ m += GenPrivateSharingRequest(pt.GetBaseType(), i->GetID());
+ m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p");
+ if (IsDelegateType(pt.GetBaseType())) {
+ l += "delegate_list_.emplace_back(" + i->GetID() + ".release());\n";
+ }
+ }
+
+ ret = AddIndent(TAB_SIZE, m) + NLine(1);
+ ret += Tab(1) + "std::lock_guard<std::recursive_mutex> lock(mutex_);"
+ + NLine(1);
+
+ if (!l.empty())
+ ret += AddIndent(TAB_SIZE, l);
+ return ret;
+ })
+ .Change("<DESERIALIZE>", [&]() {
+ std::string code;
+ for (const auto& i : decl.GetParameters()) {
+ if (i->GetParameterType().GetDirection() ==
+ ParameterType::Direction::IN)
+ continue;
+
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), i->GetID(),
+ "parcel_received", false);
+ if (c != "")
+ code += AddIndent(TAB_SIZE * 2, c);
+ }
+
+ if (decl.GetType().ToString() != "void") {
+ code += AddIndent(TAB_SIZE * 2,
+ ConvertTypeToDeserializer(decl.GetType(), "ret",
+ "parcel_received", false));
+ }
+
+ return code;
+ })
+ .Out(stream);
}
} // namespace tidl
diff --git a/idlc/gen/cpp_proxy_body_gen.h b/idlc/gen/cpp_proxy_body_gen.h
index b6e7c1d..a064d0f 100644
--- a/idlc/gen/cpp_proxy_body_gen.h
+++ b/idlc/gen/cpp_proxy_body_gen.h
@@ -41,7 +41,8 @@ class CppProxyBodyGen : public CppGeneratorBase {
void GenDestructor(std::ofstream& stream, const Interface& iface);
void GenHelperMethods(std::ofstream& stream, const Interface& iface);
void GenMethods(std::ofstream& stream, const Interface& iface);
- void GenInvocation(std::ofstream& stream, const Declaration& decl);
+ void GenInvocation(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
};
} // namespace tidl
diff --git a/idlc/gen/cpp_proxy_body_gen_cb.h b/idlc/gen/cpp_proxy_body_gen_cb.h
index 83a9f08..58e870a 100644
--- a/idlc/gen/cpp_proxy_body_gen_cb.h
+++ b/idlc/gen/cpp_proxy_body_gen_cb.h
@@ -19,45 +19,79 @@
const char CB_DTOR[] =
R"__cpp_cb(
-$$::~$$() {
+<CLS_NAME>::~<CLS_NAME>() {
if (proxy_)
rpc_port_proxy_destroy(proxy_);
}
)__cpp_cb";
-const char CB_INVOCATION_PRE[] =
-R"__cpp_cb( if (port_ == nullptr) {
+const char CB_INVOCATION[] =
+R"__cpp_cb(
+<RET_TYPE> <IFACE>::<METHOD>(<PARAMS>) {
+ if (port_ == nullptr) {
_E("Not connected");
throw NotConnectedSocketException();
}
rpc_port_parcel_h p;
rpc_port_parcel_create(&p);
-)__cpp_cb";
-const char CB_INVOCATION_MID[] =
-R"__cpp_cb(
- // Send
- int r = rpc_port_parcel_send(p, port_);
- if (r != RPC_PORT_ERROR_NONE) {
- _E("Failed to send parcel. result(%d)", r);
- rpc_port_parcel_destroy(p);
- throw InvalidIOException();
- }
+ rpc_port_parcel_header_h header_;
+ rpc_port_parcel_get_header(p, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ int seq_num_ = -1;
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+ rpc_port_parcel_write_int32(p, static_cast<int>(MethodId::<METHOD>));
+<SERIALIZE>
+ // Send
+ int r = rpc_port_parcel_send(p, port_);
+ if (r != RPC_PORT_ERROR_NONE) {
+ _E("Failed to send parcel. result(%d)", r);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
+<ASYNC_OR_SYNC>
+}
)__cpp_cb";
-const char CB_INVOCATION_RECEIVE[] =
+const char CB_INVOCATION_ASYNC[] =
R"__cpp_cb(
- if (parcel_received == nullptr) {
- _E("Invalid protocol");
- throw InvalidProtocolException();
- }
+ rpc_port_parcel_destroy(p);
)__cpp_cb";
-const char CB_INVOCATION_END[] =
+const char CB_INVOCATION_SYNC[] =
R"__cpp_cb(
+ <RET_TYPE> ret;
+ bool done_ = false;
+ do {
+ rpc_port_parcel_h parcel_received = nullptr;
+ // Receive
+ ConsumeCommand(&parcel_received, port_);
+ if (parcel_received == nullptr) {
+ _E("Invalid protocol");
+ throw InvalidProtocolException();
+ }
+
+ rpc_port_parcel_get_header(parcel_received, &header_);
+ char* tag_ = nullptr;
+ rpc_port_parcel_header_get_tag(header_, &tag_);
+ std::unique_ptr<char, decltype(std::free)*> tag_auto_(tag_, std::free);
+ if (tag_ && tag_[0] != '\0') {
+ int seq_num_received_ = -1;
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_received_);
+ if (seq_num_received_ != seq_num_) {
+ _E("Invalid protocol. %d", seq_num_received_);
+ rpc_port_parcel_destroy(parcel_received);
+ continue;
+ }
+ }
+ done_ = true;
+
+<DESERIALIZE>
+ rpc_port_parcel_destroy(parcel_received);
+ } while (!done_);
+
rpc_port_parcel_destroy(p);
- rpc_port_parcel_destroy(parcel_received);
return ret;
)__cpp_cb";
@@ -85,6 +119,14 @@ void ##::Connect(bool sync) {
}
}
+void ##::Disconnect() {
+ int ret = rpc_port_disconnect(port_);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to disconnect ##");
+ throw InvalidIDException();
+ }
+}
+
void ##::DisposeCallback(const std::string& tag) {
for (auto& i : delegate_list_) {
if (i->GetTag() == tag) {
@@ -177,7 +219,7 @@ void ##::OnReceivedCB(const char *ep, const char *port_name, void *data) {
const char CB_PROXY_INTERFACE_CTOR[] =
R"__cpp_cb(
-$$::$$(IEventListener* listener, const std::string& target_appid)
+<CLS_NAME>::<CLS_NAME>(IEventListener* listener, const std::string& target_appid)
: port_(nullptr), callback_port_(nullptr), proxy_(nullptr),
listener_(listener), target_appid_(target_appid) {
int r = rpc_port_proxy_create(&proxy_);
diff --git a/idlc/gen/cpp_proxy_header_gen.cc b/idlc/gen/cpp_proxy_header_gen.cc
index 305cabc..9bd1b3f 100644
--- a/idlc/gen/cpp_proxy_header_gen.cc
+++ b/idlc/gen/cpp_proxy_header_gen.cc
@@ -39,8 +39,8 @@ void CppProxyHeaderGen::GenNamespace(std::ofstream& stream) {
GenBrace(stream, 0, [&]() {
stream << "namespace " << GetFileNamespace() << " ";
GenBrace(stream, 0, [&]() {
- stream << NLine(1);
GenStructuresForHeader(stream);
+ stream << NLine(1);
stream << "namespace proxy ";
GenBrace(stream, 0, [&]() {
GenExceptions(stream);
@@ -80,7 +80,7 @@ void CppProxyHeaderGen::GenInterface(std::ofstream& stream,
return iface.GetID();
});
GenMethods(stream, iface);
- stream << NLine(1) << " private:" << NLine(1);
+ stream << NLine(1) << " private:";
GenMethodId(stream, iface);
GenDelegateId(stream, iface);
stream << CB_PRIVATE_MEMBERS;
@@ -92,7 +92,7 @@ void CppProxyHeaderGen::GenMethods(std::ofstream& stream,
const Interface& iface) {
auto& decls = iface.GetDeclarations();
- for (auto& i : decls.GetDecls()) {
+ for (const auto& i : decls) {
if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
diff --git a/idlc/gen/cpp_proxy_header_gen_cb.h b/idlc/gen/cpp_proxy_header_gen_cb.h
index aea484f..f1d198a 100644
--- a/idlc/gen/cpp_proxy_header_gen_cb.h
+++ b/idlc/gen/cpp_proxy_header_gen_cb.h
@@ -78,6 +78,14 @@ R"__cpp_cb(
void Connect(bool sync = false);
/// <summary>
+ /// Disconnects from the service app.
+ /// </summary>
+ /// <exception cref="InvalidIDException">
+ /// Thrown when the stub port is invalid.
+ /// </exception>
+ void Disconnect();
+
+ /// <summary>
/// Disposes delegate objects in this interface
/// </summary>
/// <param name="tag">The tag string from delegate object</param>
diff --git a/idlc/gen/cpp_stub_body_gen.cc b/idlc/gen/cpp_stub_body_gen.cc
index 3c840b7..68676e1 100644
--- a/idlc/gen/cpp_stub_body_gen.cc
+++ b/idlc/gen/cpp_stub_body_gen.cc
@@ -24,7 +24,7 @@ namespace tidl {
CppStubBodyGen::CppStubBodyGen(std::shared_ptr<Document> doc,
std::shared_ptr<Options> options)
- : CppGeneratorBase(doc), options_(options) {}
+ : CppGeneratorBase(doc, options->IsThreadEnabled()), options_(options) {}
void CppStubBodyGen::OnInitGen(std::ofstream& stream) {
std::string key(".cc");
@@ -44,6 +44,7 @@ void CppStubBodyGen::OnInitGen(std::ofstream& stream) {
<< "#include \"" << header_file << "\"" << NLine(2);
GenLogTag(stream, "RPC_PORT_STUB");
GenLogDefinition(stream);
+ GenVersionDefinition(stream);
stream << NLine(1);
GenNamespace(stream);
}
@@ -96,13 +97,20 @@ void CppStubBodyGen::GenServiceBase(std::ofstream& stream,
return iface.GetID();
});
stream << NLine(1);
+ GenTemplate(CB_SERVICE_DEFAULT_METHOD, stream,
+ [&]()->std::string {
+ return iface.GetID();
+ }, [&]()->std::string {
+ return iface.GetID();
+ });
+ stream << NLine(1);
}
void CppStubBodyGen::GenConstructor(std::ofstream& stream,
const Interface& iface) {
stream << ReplaceAll(CB_CTOR_FRONT, "##", iface.GetID());
- for (auto& i : iface.GetAttributes().GetAttrs()) {
+ for (const auto& i : iface.GetAttributes()) {
if (i->GetKey() == "privilege") {
stream << Tab(1) << "rpc_port_stub_add_privilege(stub_, \""
<< i->GetValue() << "\");" << NLine(1);
@@ -132,16 +140,11 @@ void CppStubBodyGen::GenReceivedEvent(std::ofstream& stream,
return iface.GetID();
});
} else {
- GenTemplate(CB_ON_RECEIVED_CB_FRONT, stream,
- [&]()->std::string {
- return iface.GetID();
- },
- [&]()->std::string {
- return iface.GetID();
- });
+ stream << ReplaceAll(CB_ON_RECEIVED_CB_FRONT, "[NAME]",
+ iface.GetID());
}
- for (auto& i : iface.GetDeclarations().GetDecls()) {
+ for (const auto& i : iface.GetDeclarations()) {
if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
stream << Tab(2) << "case static_cast<int>(MethodId::"
@@ -155,14 +158,8 @@ void CppStubBodyGen::GenReceivedEvent(std::ofstream& stream,
if (options_->IsThreadEnabled()) {
stream << CB_RUN_PENDING_JOB_BACK << NLine(1);
-
- GenTemplate(CB_ON_RECEIVED_CB, stream,
- [&]()->std::string {
- return iface.GetID();
- },
- [&]()->std::string {
- return iface.GetID();
- });
+ stream << ReplaceAll(CB_ON_RECEIVED_CB, "[NAME]",
+ iface.GetID());
} else {
stream << CB_ON_RECEIVED_CB_BACK << NLine(1);
}
@@ -173,7 +170,7 @@ void CppStubBodyGen::GenInvocation(std::ofstream& stream,
int cnt = 1;
// Deserialize
- for (auto& i : decl.GetParameters().GetParams()) {
+ for (const auto& i : decl.GetParameters()) {
if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT) {
cnt++;
continue;
@@ -198,7 +195,7 @@ void CppStubBodyGen::GenInvocation(std::ofstream& stream,
}
m += "b->" + decl.GetID() + "(";
- for (auto& i : decl.GetParameters().GetParams()) {
+ for (const auto& i : decl.GetParameters()) {
if (cnt != 1) {
m += ", ";
}
@@ -208,7 +205,7 @@ void CppStubBodyGen::GenInvocation(std::ofstream& stream,
if (pt.GetDirection() == ParameterType::Direction::OUT) {
d += ConvertTypeToString(pt.GetBaseType()) + " " + v + ";\n";
}
- if (IsDelegateType(pt.GetBaseType())) {
+ if (IsMovableType(pt.GetBaseType(), pt.GetDirection())) {
m += "std::move(";
m += v;
m += ")";
@@ -229,7 +226,7 @@ void CppStubBodyGen::GenInvocation(std::ofstream& stream,
cnt = 0;
m = "rpc_port_parcel_write_int32(" \
"result, static_cast<int>(MethodId::__Result));\n";
- for (auto& i : decl.GetParameters().GetParams()) {
+ for (const auto& i : decl.GetParameters()) {
auto& pt = i->GetParameterType();
cnt++;
if (pt.GetDirection() == ParameterType::Direction::IN)
@@ -244,8 +241,7 @@ void CppStubBodyGen::GenInvocation(std::ofstream& stream,
m += ConvertTypeToSerializer(decl.GetType(), "retVal", "result");
}
- m += "ret = rpc_port_parcel_send(result, port);\n";
- m += "_I(\"Parcel send result(%d)\", ret);\n";
+ m += "rpc_port_parcel_send(result, port);\n";
stream << AddIndent(TAB_SIZE * 3, m);
}
diff --git a/idlc/gen/cpp_stub_body_gen_cb.h b/idlc/gen/cpp_stub_body_gen_cb.h
index 709ea4d..185248d 100644
--- a/idlc/gen/cpp_stub_body_gen_cb.h
+++ b/idlc/gen/cpp_stub_body_gen_cb.h
@@ -55,9 +55,18 @@ void ##::Listen(std::shared_ptr<##::ServiceBase::Factory> service_factory) {
}
}
-void ##::OnConnectedCB(const char* sender, const char* instance, void *data) {
+void ##::OnConnectedCB(const char* sender, const char* instance, void* data) {
##* stub = static_cast<##*>(data);
auto s = stub->service_factory_->CreateService(sender, instance);
+
+ rpc_port_h port;
+ int ret = rpc_port_stub_get_port(stub->stub_, RPC_PORT_PORT_CALLBACK, instance, &port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get the port(%d)", ret);
+ return;
+ }
+
+ s->SetPort(port);
s->OnCreate();
stub->services_.emplace_back(std::move(s));
}
@@ -73,7 +82,6 @@ void ##::OnDisconnectedCB(const char* sender, const char* instance, void *data)
}
}
}
-
)__cpp_cb";
const char CB_DEFAULT_THREAD_METHODS[] =
@@ -101,13 +109,18 @@ void ##::ServiceBase::Dispatch(rpc_port_h port,
)__cpp_cb";
+/**
+ * [NAME] The name of the interface.
+ */
const char CB_ON_RECEIVED_CB_FRONT[] =
R"__cpp_cb(
-int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void *data)
+int [NAME]::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void *data)
{
- auto* cxt = static_cast<$$*>(data);
+ auto* cxt = static_cast<[NAME]*>(data);
rpc_port_parcel_h p;
rpc_port_parcel_h result;
+ rpc_port_parcel_header_h header;
+ int seq_num = -1;
int cmd;
int ret;
std::shared_ptr<ServiceBase> b;
@@ -121,7 +134,7 @@ int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port,
}
if (b.get() == nullptr) {
- _E("Failed to find $$ context(%s)", instance);
+ _E("Failed to find [NAME] context(%s)", instance);
return -1;
}
@@ -137,7 +150,14 @@ int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port,
return ret;
}
+ rpc_port_parcel_get_header(p, &header);
+ rpc_port_parcel_header_get_seq_num(header, &seq_num);
+
rpc_port_parcel_create(&result);
+ rpc_port_parcel_get_header(result, &header);
+ rpc_port_parcel_header_set_tag(header, TIDL_VERSION);
+ rpc_port_parcel_header_set_seq_num(header, seq_num);
+
rpc_port_parcel_read_int32(p, &cmd);
switch (cmd) {
@@ -164,7 +184,6 @@ R"__cpp_cb(
void $$::PendingJob::Run() {
rpc_port_parcel_h result;
int cmd;
- int ret;
rpc_port_parcel_h p = parcel_;
std::shared_ptr<ServiceBase> b = service_;
rpc_port_h port = port_;
@@ -188,11 +207,14 @@ R"__cpp_cb( default:
}
)__cpp_cb";
+/**
+ * [NAME] The name of the interface.
+ */
const char CB_ON_RECEIVED_CB[] =
R"__cpp_cb(
-int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void *data)
+int [NAME]::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void *data)
{
- auto* cxt = static_cast<$$*>(data);
+ auto* cxt = static_cast<[NAME]*>(data);
std::shared_ptr<ServiceBase> b;
rpc_port_parcel_h parcel;
rpc_port_h callback_port;
@@ -205,7 +227,7 @@ int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port,
}
if (b.get() == nullptr) {
- _E("Failed to find $$ context(%s)", instance);
+ _E("Failed to find [NAME] context(%s)", instance);
return -1;
}
@@ -229,6 +251,23 @@ int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port,
const char CB_CTOR_SERVICE_BASE[] =
R"__cpp_cb($$::ServiceBase::ServiceBase(std::string sender, std::string instance)
: sender_(std::move(sender)), instance_(std::move(instance)),
- active_object_(new ActiveObject()) {})__cpp_cb";
+ active_object_(new ActiveObject()) {}
+)__cpp_cb";
+
+const char CB_SERVICE_DEFAULT_METHOD[] =
+R"__cpp_cb(void $$::ServiceBase::SetPort(rpc_port_h port) {
+ port_ = port;
+}
+
+void $$::ServiceBase::Disconnect() {
+ int ret = rpc_port_disconnect(port_);
+ if (ret == RPC_PORT_ERROR_NONE) {
+ _E("Failed to disconnect the port(%d)", ret);
+ return;
+ }
+
+ port_ = nullptr;
+}
+)__cpp_cb";
#endif // IDLC_CPP_GEN_CPP_STUB_BODY_GEN_CB_H_
diff --git a/idlc/gen/cpp_stub_header_gen.cc b/idlc/gen/cpp_stub_header_gen.cc
index 3e6e78f..86cc340 100644
--- a/idlc/gen/cpp_stub_header_gen.cc
+++ b/idlc/gen/cpp_stub_header_gen.cc
@@ -24,7 +24,7 @@ namespace tidl {
CppStubHeaderGen::CppStubHeaderGen(std::shared_ptr<Document> doc,
std::shared_ptr<Options> options)
- : CppGeneratorBase(doc), options_(options) {}
+ : CppGeneratorBase(doc, options->IsThreadEnabled()), options_(options) {}
void CppStubHeaderGen::OnInitGen(std::ofstream& stream) {
GenVersion(stream);
@@ -93,7 +93,7 @@ void CppStubHeaderGen::GenPublic(std::ofstream& stream,
void CppStubHeaderGen::GenPrivate(std::ofstream& stream,
const Interface& iface) {
- stream << " private:" << NLine(1);
+ stream << " private:";
GenMethodId(stream, iface);
GenDelegateId(stream, iface);
stream << CB_PRIVATE_MEMBERS;
@@ -104,7 +104,7 @@ void CppStubHeaderGen::GenServiceBase(std::ofstream& stream,
stream << CB_SERVICE_BASE_FRONT;
auto& decls = iface.GetDeclarations();
- for (auto& i : decls.GetDecls()) {
+ for (const auto& i : decls) {
if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
if (!i->GetComments().empty())
diff --git a/idlc/gen/cpp_stub_header_gen_cb.h b/idlc/gen/cpp_stub_header_gen_cb.h
index b4db8a5..49158c2 100644
--- a/idlc/gen/cpp_stub_header_gen_cb.h
+++ b/idlc/gen/cpp_stub_header_gen_cb.h
@@ -31,7 +31,7 @@ R"__cpp_cb( static void OnConnectedCB(const char* sender, const char* instance,
static void OnDisconnectedCB(const char* sender, const char* instance, void* data);
static int OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void* data);
- rpc_port_stub_h stub_;
+ rpc_port_stub_h stub_ = nullptr;
std::shared_ptr<ServiceBase::Factory> service_factory_;
std::list<std::shared_ptr<ServiceBase>> services_;
)__cpp_cb";
@@ -42,6 +42,8 @@ R"__cpp_cb(
public:
class Factory {
public:
+ virtual ~Factory() = default;
+
/// <summary>
/// The method for making service instances
/// </summary>
@@ -67,6 +69,20 @@ R"__cpp_cb(
}
/// <summary>
+ /// Sets the client app port
+ /// </summary>
+ /// <param name="port">The port of the client</param>
+ void SetPort(rpc_port_h port);
+
+ /// <summary>
+ /// Disconnects from the client app
+ /// </summary>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ void Disconnect();
+
+ /// <summary>
/// This method will be called when the client is connected
/// </summary>
virtual void OnCreate() = 0;
@@ -107,6 +123,7 @@ R"__cpp_cb(
private:
std::string sender_;
std::string instance_;
+ rpc_port_h port_ = nullptr;
std::unique_ptr<ActiveObject> active_object_;
};)__cpp_cb";
@@ -133,11 +150,11 @@ R"__cpp_cb( ##();
)__cpp_cb";
-
const char CB_JOB[] = R"__cls_job(class Job {
public:
class IEvent {
public:
+ virtual ~IEvent() = default;
virtual void Run() = 0;
};
diff --git a/idlc/gen/cs_gen_base.cc b/idlc/gen/cs_gen_base.cc
index 4266ba3..912d9d5 100644
--- a/idlc/gen/cs_gen_base.cc
+++ b/idlc/gen/cs_gen_base.cc
@@ -66,7 +66,7 @@ void CsGeneratorBase::GenStructure(std::ofstream& stream, const Structure& st) {
stream << Tab(1) <<"public sealed class " << st.GetID() << NLine(1);
GenBrace(stream, TAB_SIZE, [&]() {
- for (auto& i : st.GetElements().GetElms()) {
+ for (const auto& i : st.GetElements()) {
GenTemplate(CB_PROPERTY, stream,
[&]()->std::string {
return ConvertTypeToString(i->GetType());
@@ -95,55 +95,71 @@ void CsGeneratorBase::GenStructure(std::ofstream& stream, const Structure& st) {
void CsGeneratorBase::GenSerializer(std::ofstream& stream,
const Structure& st) {
- stream << NLine(1) << Tab(3) << "private static void Serialize(Parcel h, "
- << st.GetID() << " param)" << NLine(1);
- GenBrace(stream, TAB_SIZE * 3, [&]() {
- for (auto& i : st.GetElements().GetElms()) {
- auto& t = i->GetType();
- if (!t.IsUserDefinedType() && t.GetMetaType() == nullptr) {
- stream << Tab(4) << "h.Write"
- << ConvertTypeToParcelType(t.ToString())
- << "(param."
- << i->GetID()
- << ");" << NLine(1);
- } else {
- stream << Tab(4) << "Serialize(h, param." << i->GetID()
- << ");" << NLine(1);
- }
- }
- });
- stream << NLine(1);
+ stream << GetSerializer(st);
+}
- stream << Tab(3) << "private static void Deserialize(Parcel h, "
- << st.GetID() << " param)" << NLine(1);
- GenBrace(stream, TAB_SIZE * 3, [&]() {
- for (auto& i : st.GetElements().GetElms()) {
- auto& t = i->GetType();
- if (!t.IsUserDefinedType() && t.GetMetaType() == nullptr) {
- stream << Tab(4) << "var " << i->GetID() << " = "
- << "h.Read"
- << ConvertTypeToParcelType(t.ToString())
- << "();" << NLine(1);
- stream << Tab(4) << "param." << i->GetID() << " = " << i->GetID()
- << ";" << NLine(1);
- } else {
- stream << Tab(4) << "param." << i->GetID() << " = new "
- << ConvertTypeToString(t)
- << "();" << NLine(1);
- stream << Tab(4) << "Deserialize(h, param." << i->GetID()
- << ");" << NLine(1);
- }
- }
- });
+std::string CsGeneratorBase::GetSerializer(const Structure& st) {
+ std::string str(ReplaceAll(CB_SERIALIZER)
+ .Change("<TYPE>", st.GetID())
+ .Change("<BODY>", [&]() {
+ std::string ret;
+ for (const auto& i : st.GetElements()) {
+ auto& t = i->GetType();
+ if (!t.IsUserDefinedType() && t.GetMetaType() == nullptr) {
+ ret += Tab(4) + "h.Write"
+ + ConvertTypeToParcelType(t.ToString())
+ + "(param."
+ + i->GetID()
+ + ");" + NLine(1);
+ } else {
+ ret += Tab(4) + "Serialize(h, param." + i->GetID()
+ + ");" + NLine(1);
+ }
+ }
+
+ return ret;
+ }));
+
+ str += ReplaceAll(CB_DESERIALIZER)
+ .Change("<TYPE>", st.GetID())
+ .Change("<BODY>", [&]() {
+ std::string ret;
+ for (const auto& i : st.GetElements()) {
+ auto& t = i->GetType();
+ if (!t.IsUserDefinedType() && t.GetMetaType() == nullptr) {
+ ret += Tab(4) + "var " + i->GetID() + " = "
+ + "h.Read"
+ + ConvertTypeToParcelType(t.ToString())
+ + "();" + NLine(1);
+ ret += Tab(4) + "param." + i->GetID() + " = " + i->GetID()
+ + ";" + NLine(1);
+ } else {
+ ret += Tab(4) + "param." + i->GetID() + " = new "
+ + ConvertTypeToString(t)
+ + "();" + NLine(1);
+ ret += Tab(4) + "Deserialize(h, param." + i->GetID()
+ + ");" + NLine(1);
+ }
+ }
+ return ret;
+ });
+ return str;
}
void CsGeneratorBase::GenSerializer(std::ofstream& stream) {
+ stream << GetSerializer();
+}
+
+std::string CsGeneratorBase::GetSerializer() {
+ std::string str;
for (auto& i : GetDocument().GetBlocks()) {
if (i->GetType() == Block::TYPE_STRUCTURE) {
const Structure& st = static_cast<const Structure&>(*i);
- GenSerializer(stream, st);
+ str += GetSerializer(st);
}
}
+
+ return str;
}
void CsGeneratorBase::AddSerializerList(const BaseType& type) {
@@ -155,67 +171,78 @@ void CsGeneratorBase::AddSerializerList(const BaseType& type) {
void CsGeneratorBase::GenListSerializer(std::ofstream& stream,
const BaseType& type) {
- stream << NLine(1) << Tab(3) << "private static void Serialize(Parcel h, "
- << ConvertTypeToString(type) << " param)" << NLine(1);
- GenBrace(stream, TAB_SIZE * 3, [&]() {
- stream << Tab(4)
- << "h.WriteArrayCount(param.Count);"
- << NLine(1);
- stream << Tab(4) << "foreach (var i in param)" << NLine(1);
- GenBrace(stream, TAB_SIZE * 4, [&]() {
- auto& mt = *type.GetMetaType();
- if (!mt.IsUserDefinedType() && mt.GetMetaType() == nullptr) {
- stream << Tab(5) << "h.Write"
- << ConvertTypeToParcelType(mt.ToString())
- << "(i);" << NLine(1);
- } else {
- stream << Tab(5) << "Serialize(h, i);" << NLine(1);
- }
- });
- });
- stream << NLine(1);
+ stream << GetListSerializer(type);
+}
- stream << Tab(3) << "private static void Deserialize(Parcel h, "
- << ConvertTypeToString(type) << " param)" << NLine(1);
- GenBrace(stream, TAB_SIZE * 3, [&]() {
- stream << Tab(4)
- << "int l = h.ReadArrayCount();"
- << NLine(1);
- stream << Tab(4) << "for (int i = 0; i < l; i++)" << NLine(1);
- GenBrace(stream, TAB_SIZE * 4, [&]() {
- auto& mt = *type.GetMetaType();
- if (!mt.IsUserDefinedType() && mt.GetMetaType() == nullptr) {
- stream << Tab(5) << "var v = h.Read"
- << ConvertTypeToParcelType(mt.ToString())
- << "();" << NLine(1);
- } else {
- stream << Tab(5) << "var v = new " << ConvertTypeToString(mt)
- << "();" << NLine(1);
- stream << Tab(5) << "Deserialize(h, v);" << NLine(1);
- }
- if (type.ToString() == "list")
- stream << Tab(5) << "param.AddLast(v);" << NLine(1);
- else
- stream << Tab(5) << "param.Add(v);" << NLine(1);
- });
- });
+std::string CsGeneratorBase::GetListSerializer(const BaseType& type) {
+ std::string str(ReplaceAll(CB_LIST_SERIALIZER)
+ .Change("<TYPE>", ConvertTypeToString(type))
+ .Change("<BODY>", [&]() {
+ std::string ret;
+ auto* ptr = type.GetMetaType();
+ if (ptr == nullptr)
+ return ret;
+
+ auto& mt = *ptr;
+ if (!mt.IsUserDefinedType() && mt.GetMetaType() == nullptr) {
+ ret += Tab(5) + "h.Write"
+ + ConvertTypeToParcelType(mt.ToString())
+ + "(i);" + NLine(1);
+ } else {
+ ret += Tab(5) + "Serialize(h, i);" + NLine(1);
+ }
+ return ret;
+ }));
+
+ str += ReplaceAll(CB_DESERIALIZER)
+ .Change("<TYPE>", ConvertTypeToString(type))
+ .Change("<BODY>", [&]() {
+ std::string ret;
+ auto* ptr = type.GetMetaType();
+ if (ptr == nullptr)
+ return ret;
+
+ auto& mt = *ptr;
+ if (!mt.IsUserDefinedType() && mt.GetMetaType() == nullptr) {
+ ret += Tab(5) + "var v = h.Read"
+ + ConvertTypeToParcelType(mt.ToString())
+ + "();" + NLine(1);
+ } else {
+ ret += Tab(5) + "var v = new " + ConvertTypeToString(mt)
+ + "();" + NLine(1);
+ ret += Tab(5) + "Deserialize(h, v);" + NLine(1);
+ }
+
+ if (type.ToString() == "list")
+ ret += Tab(5) + "param.AddLast(v);" + NLine(1);
+ else
+ ret += Tab(5) + "param.Add(v);" + NLine(1);
+
+ return ret;
+ });
+
+ return str;
}
void CsGeneratorBase::GenListSerializer(std::ofstream& stream) {
+ stream << GetListSerializer();
+}
+
+std::string CsGeneratorBase::GetListSerializer() {
serializer_list_.clear();
for (auto& i : GetDocument().GetBlocks()) {
if (i->GetType() == Block::TYPE_STRUCTURE) {
const Structure& st = static_cast<const Structure&>(*i);
- for (auto& j : st.GetElements().GetElms()) {
+ for (const auto& j : st.GetElements()) {
auto& t = j->GetType();
AddSerializerList(t);
}
} else if (i->GetType() == Block::TYPE_INTERFACE) {
const Interface& iface = static_cast<const Interface&>(*i);
- for (auto& j : iface.GetDeclarations().GetDecls()) {
+ for (const auto& j : iface.GetDeclarations()) {
auto& t = j->GetType();
AddSerializerList(t);
- for (auto& k : j->GetParameters().GetParams()) {
+ for (const auto& k : j->GetParameters()) {
auto& t1 = k->GetParameterType().GetBaseType();
AddSerializerList(t1);
}
@@ -223,10 +250,13 @@ void CsGeneratorBase::GenListSerializer(std::ofstream& stream) {
}
}
+ std::string ret;
for (auto& p : serializer_list_) {
const BaseType* t = p.second;
- GenListSerializer(stream, *t);
+ ret += GetListSerializer(*t);
}
+
+ return ret;
}
std::string CsGeneratorBase::ConvertTypeToString(const BaseType& type) {
@@ -341,20 +371,22 @@ void CsGeneratorBase::GenWriteBundle(std::ofstream& stream,
});
}
-void CsGeneratorBase::GenMethodId(std::ofstream& stream,
- const Interface& iface) {
- stream << Tab(3) << "private enum MethodId : int" << NLine(1);
- GenBrace(stream, TAB_SIZE * 3, [&]() {
- int cnt = 2;
- stream << Tab(4) << "__Result = 0," << NLine(1);
- stream << Tab(4) << "__Callback = 1," << NLine(1);
- for (auto& i : iface.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
- continue;
- stream << Tab(4)
- << i->GetID() << " = " << cnt++ << "," << NLine(1);
- }
- });
+std::string CsGeneratorBase::GetMethodId(const Interface& iface) {
+ return std::string(ReplaceAll(CB_METHOD_IDS)
+ .Change("<METHOD_IDS>", [&](){
+ int cnt = 2;
+ std::string str;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+ str += Tab(4) + i->GetID() + " = " + std::to_string(cnt++) + "," + NLine(1);
+ }
+ return str;
+ }));
+}
+
+void CsGeneratorBase::GenMethodId(std::ofstream& stream, const Interface& iface) {
+ stream << GetMethodId(iface);
}
void CsGeneratorBase::GenDelegateId(std::ofstream& stream,
@@ -362,7 +394,7 @@ void CsGeneratorBase::GenDelegateId(std::ofstream& stream,
stream << Tab(3) << "private enum DelegateId : int" << NLine(1);
GenBrace(stream, TAB_SIZE * 3, [&]() {
int cnt = 1;
- for (auto& i : iface.GetDeclarations().GetDecls()) {
+ for (const auto& i : iface.GetDeclarations()) {
if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
continue;
stream << Tab(4)
@@ -373,14 +405,20 @@ void CsGeneratorBase::GenDelegateId(std::ofstream& stream,
}
void CsGeneratorBase::GenDeclaration(std::ofstream& stream,
- const Declaration& decl, bool semicol) {
- stream << ConvertTypeToString(decl.GetType()) << " "
- << decl.GetID() << "(";
- GenParameters(stream, decl.GetParameters());
+ const Declaration& decl, bool semicol) {
+ stream << GetDeclaration(decl, semicol);
+}
+
+std::string CsGeneratorBase::GetDeclaration(const Declaration& decl, bool semicol) {
+ std::string ret;
+ ret += ConvertTypeToString(decl.GetType()) + " "
+ + decl.GetID() + "(";
+ ret += GetParameters(decl.GetParameters());
if (semicol)
- stream << ");";
+ ret += ");";
else
- stream << ")";
+ ret += ")";
+ return ret;
}
void CsGeneratorBase::GenParameters(std::ofstream& stream,
@@ -391,7 +429,7 @@ void CsGeneratorBase::GenParameters(std::ofstream& stream,
std::string CsGeneratorBase::GetParameters(const Parameters& ps) {
bool first = true;
std::string ret;
- for (auto& i : ps.GetParams()) {
+ for (const auto& i : ps) {
if (!first) {
ret += ", ";
}
@@ -415,7 +453,7 @@ void CsGeneratorBase::GenCallbacks(std::ofstream& stream,
const Interface& iface, bool is_proxy) {
stream << CB_CALLBACK_BASE;
- for (auto& i : iface.GetDeclarations().GetDecls()) {
+ for (const auto& i : iface.GetDeclarations()) {
if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
continue;
GenCallback(stream, *i, iface.GetID(), is_proxy);
@@ -459,7 +497,7 @@ void CsGeneratorBase::GenReceivedEvent(std::ofstream& stream,
<< NLine(1);
GenBrace(stream, TAB_SIZE * 4, [&]() {
int cnt = 1;
- for (auto& i : decl.GetParameters().GetParams()) {
+ for (const auto& i : decl.GetParameters()) {
std::string v = "param" + std::to_string(cnt);
std::string c = ConvertTypeToDeserializer(
i->GetParameterType().GetBaseType(), v, "parcel", true, id);
@@ -469,7 +507,8 @@ void CsGeneratorBase::GenReceivedEvent(std::ofstream& stream,
cnt = 1;
stream << Tab(5) << "Received?.Invoke(";
- for (int i = 0; i < decl.GetParameters().GetParams().size(); i++) {
+ for (auto i = decl.GetParameters().begin();
+ i != decl.GetParameters().end(); ++i) {
if (cnt != 1) {
stream << ", ";
}
@@ -491,7 +530,7 @@ void CsGeneratorBase::GenInvokeMethod(std::ofstream& stream,
},
[&]()->std::string {
std::string m;
- for (auto& i : decl.GetParameters().GetParams()) {
+ for (const auto& i : decl.GetParameters()) {
auto& pt = i->GetParameterType();
m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p", id);
}
diff --git a/idlc/gen/cs_gen_base.h b/idlc/gen/cs_gen_base.h
index c7c4cdd..7400a4c 100644
--- a/idlc/gen/cs_gen_base.h
+++ b/idlc/gen/cs_gen_base.h
@@ -36,13 +36,19 @@ class CsGeneratorBase : public Generator {
void GenStructures(std::ofstream& stream);
void GenStructure(std::ofstream& stream, const Structure& st);
void GenSerializer(std::ofstream& stream);
+ std::string GetSerializer();
void GenSerializer(std::ofstream& stream, const Structure& st);
+ std::string GetSerializer(const Structure& st);
void GenListSerializer(std::ofstream& stream);
+ std::string GetListSerializer();
void GenListSerializer(std::ofstream& stream, const BaseType& type);
+ std::string GetListSerializer(const BaseType& type);
void GenMethodId(std::ofstream& stream, const Interface& iface);
+ std::string GetMethodId(const Interface& iface);
void GenDelegateId(std::ofstream& stream, const Interface& iface);
void GenDeclaration(std::ofstream& stream,
const Declaration& decl, bool semicol = true);
+ std::string GetDeclaration(const Declaration& decl, bool semicol = true);
void GenParameters(std::ofstream& stream, const Parameters& ps);
void GenCallbacks(std::ofstream& stream, const Interface& iface,
bool is_proxy);
diff --git a/idlc/gen/cs_gen_base_cb.h b/idlc/gen/cs_gen_base_cb.h
index aabc490..c349111 100644
--- a/idlc/gen/cs_gen_base_cb.h
+++ b/idlc/gen/cs_gen_base_cb.h
@@ -126,4 +126,55 @@ R"__cs_cb(
}
)__cs_cb";
+const char CB_METHOD_IDS[] =
+R"__cs_cb(
+ private enum MethodId : int
+ {
+ __Result = 0,
+ __Callback = 1,
+<METHOD_IDS>
+ }
+)__cs_cb";
+
+const char CB_SERIALIZER[] =
+R"__cs_cb(
+ private static void Serialize(Parcel h, <TYPE> param)
+ {
+<BODY>
+ }
+)__cs_cb";
+
+const char CB_DESERIALIZER[] =
+R"__cs_cb(
+ private static void Deserialize(Parcel h, <TYPE> param)
+ {
+<BODY>
+ }
+)__cs_cb";
+
+const char CB_LIST_SERIALIZER[] =
+R"__cs_cb(
+ private static void Serialize(Parcel h, <TYPE> param)
+ {
+ h.WriteArrayCount(param.Count);
+ foreach (var i in param)
+ {
+<BODY>
+ }
+ }
+)__cs_cb";
+
+const char CB_LIST_DESERIALIZER[] =
+R"__cs_cb(
+ private static void Deserialize(Parcel h, <TYPE> param)
+ {
+ int l = h.ReadArrayCount();
+ for (int i = 0; i < l; i++)
+ {
+<BODY>
+ }
+ }
+)__cs_cb";
+
+
#endif // IDLC_CS_GEN_CS_GEN_BASE_CB_H_
diff --git a/idlc/gen/cs_group_gen.cc b/idlc/gen/cs_group_gen.cc
new file mode 100644
index 0000000..b1161e5
--- /dev/null
+++ b/idlc/gen/cs_group_gen.cc
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/cs_group_gen.h"
+
+namespace {
+#include "idlc/gen/cs_group_gen_cb.h"
+}
+
+namespace tidl {
+
+CsGroupGen::CsGroupGen(std::shared_ptr<Document> doc)
+ : CsGeneratorBase(doc) {}
+
+void CsGroupGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ stream << CB_USING;
+ GenNamespace(stream);
+}
+
+void CsGroupGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void CsGroupGen::GenNamespace(std::ofstream& stream) {
+ stream << NLine(1);
+ stream << "namespace RPCPort" << NLine(1);
+ GenBrace(stream, 0, [&]() {
+ stream << "namespace " << GetFileNamespace() << NLine(1);
+ GenBrace(stream, 0, [&]() {
+ GenStructures(stream);
+ stream << Tab(1) << "namespace Group" << NLine(1);
+ GenBrace(stream, TAB_SIZE, [&]() {
+ GenInterfaces(stream);
+ });
+ });
+ });
+}
+
+void CsGroupGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ GenInterface(stream, iface);
+ stream << NLine(1);
+ }
+}
+
+void CsGroupGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_FULL)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Change("<METHOD_IDS>", GetMethodId(iface))
+ .Change("<SERIALIZER>", GetSerializer())
+ .Change("<LIST_SERIALIZER>", GetListSerializer())
+ .Change("<METHODS>", GetMethods(iface))
+ .Change("<DISPATCHERS>", GetDispatchers(iface))
+ .Out(stream);
+}
+
+std::string CsGroupGen::GetDispatchers(const Interface& iface) {
+ std::string ret;
+ for (const auto& i : iface.GetDeclarations()) {
+ ret += ReplaceAll(CB_DISPATCHER)
+ .Change("<METHOD_ID>", i->GetID())
+ .Change("<PARAM_DESERIALIZER>", GetParamDeserializer(*i))
+ .Change("<CALL_PARAMS>", GetCallParams(*i));
+ }
+
+ return ret;
+}
+
+std::string CsGroupGen::GetMethods(const Interface& iface) {
+ std::string ret;
+ auto& decls = iface.GetDeclarations();
+ for (const auto& i : decls) {
+ ret += ReplaceAll(CB_METHOD)
+ .Change("<PARAMS>", GetParameters(i->GetParameters()))
+ .Change("<COMMENTS>", i->GetComments().empty() ? "" :
+ AddIndent(TAB_SIZE * 3, i->GetComments()))
+ .Change("<DECL>", GetDeclaration(*i, false))
+ .Change("<METHOD_ID>", i->GetID())
+ .Change("<PARAM_SERIALIZER>", GetParamSerializer(*i))
+ .Change("<CLS_NAME>", iface.GetID());
+ }
+
+ return ret;
+}
+
+std::string CsGroupGen::GetParamSerializer(const Declaration& decl) {
+ std::string m;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT)
+ continue;
+ m += Tab(5) + ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p");
+ }
+
+ return m;
+}
+
+std::string CsGroupGen::GetParamDeserializer(const Declaration& decl) {
+ int cnt = 1;
+ std::string m;
+ for (const auto& i : decl.GetParameters()) {
+ if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT) {
+ cnt++;
+ continue;
+ }
+
+ std::string v = "param" + std::to_string(cnt);
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, "p");
+ m += AddIndent(TAB_SIZE * 6, c);
+ cnt++;
+ }
+
+ return m;
+}
+
+std::string CsGroupGen::GetCallParams(const Declaration& decl) {
+ int cnt = 1;
+ std::string m;
+ for (const auto& i : decl.GetParameters()) {
+ if (cnt != 1) {
+ m += ", ";
+ }
+
+ std::string v = "param" + std::to_string(cnt);
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT) {
+ m += "out " + ConvertTypeToString(pt.GetBaseType()) + " ";
+ } else if (pt.GetDirection() == ParameterType::Direction::REF) {
+ m += "ref ";
+ }
+ m += v;
+ cnt++;
+ }
+
+ return m;
+}
+
+} // namespace tidl
diff --git a/idlc/gen/cs_group_gen.h b/idlc/gen/cs_group_gen.h
new file mode 100644
index 0000000..59bb5dd
--- /dev/null
+++ b/idlc/gen/cs_group_gen.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CS_GROUP_GEN_H_
+#define IDLC_GEN_CS_GROUP_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/cs_gen_base.h"
+
+namespace tidl {
+
+class CsGroupGen : public CsGeneratorBase {
+ public:
+ explicit CsGroupGen(std::shared_ptr<Document> doc);
+ virtual ~CsGroupGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ std::string GetMethods(const Interface& iface);
+ std::string GetParamSerializer(const Declaration& decl);
+ std::string GetParamDeserializer(const Declaration& decl);
+ std::string GetDispatchers(const Interface& iface);
+ std::string GetCallParams(const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CS_GROUP_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen/cs_group_gen_cb.h b/idlc/gen/cs_group_gen_cb.h
new file mode 100644
index 0000000..caaa1fc
--- /dev/null
+++ b/idlc/gen/cs_group_gen_cb.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CS_GROUP_GEN_CB_H_
+#define IDLC_GEN_CS_GROUP_GEN_CB_H_
+
+const char CB_USING[] =
+R"__cs_cb(
+using System;
+using Tizen.Applications;
+using Tizen.Applications.EventManager;
+using Tizen.Applications.RPCPort;
+
+)__cs_cb";
+
+const char CB_INTERFACE_FULL[] =
+R"__cs_cb(
+ public class <CLS_NAME> : IDisposable
+ {
+ private EventReceiver _eventReceiver;
+ private Object _lock = new Object();
+ private bool _disposedValue = false;
+ private string _senderAppid;
+
+ private Bundle GetBundleFromParcel(Parcel p)
+ {
+ byte[] bytes = p.ToBytes();
+ Bundle b = new Bundle();
+ b.AddItem("TIDL_RAW", bytes);
+ return b;
+ }
+
+ private Parcel GetParcelFromBundle(Bundle b)
+ {
+ byte[] bytes = (byte[])b.GetItem("TIDL_RAW");
+
+ return new Parcel(bytes);
+ }
+
+ private string GetEventName(string appid, string iface_name)
+ {
+ return "event." + appid + ".tidl_iface_" + iface_name;
+ }
+
+ private void OnReceive(Parcel p)
+ {
+ int cmd = p.ReadInt();
+
+ switch ((MethodId)cmd)
+ {
+<DISPATCHERS>
+ }
+ }
+
+<METHOD_IDS>
+<SERIALIZER>
+<LIST_SERIALIZER>
+
+ public <CLS_NAME>(string senderAppid)
+ {
+ string eventName = GetEventName(senderAppid, "<CLS_NAME>");
+ _senderAppid = senderAppid;
+ _eventReceiver = new EventReceiver(eventName);
+ _eventReceiver.Received += (obj, args) =>
+ {
+ Bundle b = args.Data;
+ using (var parcel = GetParcelFromBundle(b))
+ {
+ OnReceive(parcel);
+ }
+ };
+ }
+
+ ~<CLS_NAME>()
+ {
+ Dispose(false);
+ }
+
+ protected void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ if (_eventReceiver != null)
+ {
+ _eventReceiver.Dispose();
+ _eventReceiver = null;
+ }
+ }
+
+ _disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+<METHODS>
+
+ }
+)__cs_cb";
+
+const char CB_METHOD[] =
+R"__cs_cb(
+ public delegate void <METHOD_ID>EventHandler(<PARAMS>);
+ public event <METHOD_ID>EventHandler <METHOD_ID>Event;
+<COMMENTS>
+ public <DECL>
+ {
+ using (Parcel p = new Parcel())
+ {
+ p.WriteInt((int)MethodId.<METHOD_ID>);
+<PARAM_SERIALIZER>
+ var bundle = GetBundleFromParcel(p);
+ string eventName = GetEventName(_senderAppid, "<CLS_NAME>");
+ ApplicationEventManager.Publish(eventName, bundle);
+ }
+ }
+)__cs_cb";
+
+const char CB_DISPATCHER[] =
+R"__cs_cb(
+ case MethodId.<METHOD_ID>:
+ {
+<PARAM_DESERIALIZER>
+ <METHOD_ID>Event?.Invoke(<CALL_PARAMS>);
+ break;
+ }
+)__cs_cb";
+
+
+
+#endif // IDLC_GEN_CS_GROUP_GEN_CB_H_
diff --git a/idlc/gen/cs_proxy_gen.cc b/idlc/gen/cs_proxy_gen.cc
index 3b96d03..790f520 100644
--- a/idlc/gen/cs_proxy_gen.cc
+++ b/idlc/gen/cs_proxy_gen.cc
@@ -66,7 +66,7 @@ void CsProxyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
stream << Tab(2) << "public class " << iface.GetID()
<< " : ProxyBase" << NLine(1);
GenBrace(stream, TAB_SIZE * 2, [&]() {
- stream << CB_DATA_MEMBERS;
+ stream << ReplaceAll(CB_DATA_MEMBERS, "<VERSION>", FULLVER);
GenCallbacks(stream, iface, true);
GenDelegateId(stream, iface);
GenMethodId(stream, iface);
@@ -104,7 +104,7 @@ void CsProxyGen::GenConnectMethod(std::ofstream& stream,
void CsProxyGen::GenMethods(std::ofstream& stream, const Interface& iface) {
auto& decls = iface.GetDeclarations();
- for (auto& i : decls.GetDecls()) {
+ for (const auto& i : decls) {
if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
@@ -125,7 +125,7 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
GenTemplate(CB_INVOCATION_PRE, stream,
[&]()->std::string {
std::string st;
- for (auto& i : decl.GetParameters().GetParams()) {
+ for (const auto& i : decl.GetParameters()) {
auto& pt = i->GetParameterType();
if (pt.GetDirection() == ParameterType::Direction::OUT)
continue;
@@ -135,20 +135,17 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
pt.GetBaseType().GetMetaType()->ToString() == "file")) {
st += GenTemplateString(CB_SHARE_FILE, [&]()->std::string {
std::string str = "";
- str += Tab(6) + "Port.ShareFile(myFile);";
+ str += Tab(6) + "Port.ShareFile(" + i->GetID() + ");";
return str;
});
}
- std::cout << "name : " << pt.GetBaseType().GetFullName() << std::endl;
- std::cout << "name : " << pt.GetBaseType().ToString() << std::endl;
- std::cout << "id : " << i->GetID() << std::endl;
}
st += Tab(5)
+ "p.WriteInt((int)MethodId." + decl.GetID() + ");" + NLine(1);
std::string m;
std::string l;
- for (auto& i : decl.GetParameters().GetParams()) {
+ for (const auto& i : decl.GetParameters()) {
auto& pt = i->GetParameterType();
if (pt.GetDirection() == ParameterType::Direction::OUT)
continue;
@@ -160,18 +157,12 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
st += AddIndent(TAB_SIZE * 5, m) + NLine(1);
- if (decl.GetMethodType() == Declaration::MethodType::SYNC)
- st += Tab(5) + "Parcel parcelReceived;" + NLine(1);
st += Tab(5) + "lock (_lock)" + NLine(1);
st += Tab(5) + "{" + NLine(1);
- if (!l.empty())
- st += AddIndent(TAB_SIZE * 6, l) + NLine(1);
- st += CB_INVOCATION_MID + NLine(1);
- if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
- st += Tab(6) + "// Receive" + NLine(1);
- st += Tab(6)
- + "ConsumeCommand(out parcelReceived, Port);" + NLine(1);
- }
+ if (!l.empty())
+ st += AddIndent(TAB_SIZE * 6, l) + NLine(1);
+
+ st += CB_INVOCATION_MID + NLine(1);
st += Tab(5) + "}";
// Deserialize
@@ -179,14 +170,10 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
return st;
}
- const char* receive_block =
- "if (parcelReceived == null)\n" \
- "{\n" \
- " throw new InvalidProtocolException();\n" \
- "}\n";
- st += NLine(1) + AddIndent(TAB_SIZE * 5, receive_block) + NLine(1);
+ st += NLine(1) + AddIndent(TAB_SIZE * 5, CB_INVOCATION_RECEIVE);
+ st += NLine(1);
- for (auto& i : decl.GetParameters().GetParams()) {
+ for (const auto& i : decl.GetParameters()) {
if (i->GetParameterType().GetDirection() ==
ParameterType::Direction::IN) {
continue;
diff --git a/idlc/gen/cs_proxy_gen_cb.h b/idlc/gen/cs_proxy_gen_cb.h
index 21e25b9..0c79ff8 100644
--- a/idlc/gen/cs_proxy_gen_cb.h
+++ b/idlc/gen/cs_proxy_gen_cb.h
@@ -17,11 +17,15 @@
#ifndef IDLC_CS_GEN_CS_PROXY_GEN_CB_H_
#define IDLC_CS_GEN_CS_PROXY_GEN_CB_H_
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
const char CB_DATA_MEMBERS[] =
R"__cs_cb( public event EventHandler Connected;
public event EventHandler Disconnected;
public event EventHandler Rejected;
+ private static readonly string _tidlVersion = "<VERSION>";
private bool _online = false;
private string _appId;
private Object _lock = new Object();
@@ -69,7 +73,14 @@ R"__cs_cb(
{
Parcel parcelReceived;
- parcelReceived = new Parcel(CallbackPort);
+ try
+ {
+ parcelReceived = new Parcel(CallbackPort);
+ }
+ catch (InvalidIOException)
+ {
+ return;
+ }
using (parcelReceived)
{
@@ -87,7 +98,17 @@ R"__cs_cb(
{
do
{
- var p = new Parcel(port);
+ Parcel p;
+
+ try
+ {
+ p = new Parcel(port);
+ }
+ catch (InvalidIOException)
+ {
+ parcel = null;
+ return;
+ }
int cmd = p.ReadInt();
if (cmd == (int)MethodId.__Result)
@@ -105,7 +126,7 @@ R"__cs_cb(
const char CB_CONNECT_METHOD[] =
R"__cs_cb(
/// <summary>
- /// Connects to the service app.
+ /// Connects to the stub app.
/// </summary>
/// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
/// <privilege>http://tizen.org/privilege/datasharing</privilege>
@@ -125,7 +146,18 @@ R"__cs_cb(
}
/// <summary>
- /// Connects to the service app synchronously.
+ /// Disconnects from the stub app.
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">
+ /// Thrown when an internal IO error occurrs.
+ /// </exception>
+ public void Disconnect()
+ {
+ Port?.Disconnect();
+ }
+
+ /// <summary>
+ /// Connects to the stub app synchronously.
/// </summary>
/// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
/// <privilege>http://tizen.org/privilege/datasharing</privilege>
@@ -167,6 +199,8 @@ R"__cs_cb( if (!_online)
using (Parcel p = new Parcel())
{
+ ParcelHeader header = p.GetHeader();
+ header.SetTag(_tidlVersion);
$$
}
)__cs_cb";
@@ -189,4 +223,37 @@ R"__cs_cb( // Send
p.Send(Port);
)__cs_cb";
+const char CB_INVOCATION_RECEIVE[] =
+R"__cs_cb(
+Parcel parcelReceived;
+bool done = false;
+do
+{
+ lock (_lock)
+ {
+ // Receive
+ ConsumeCommand(out parcelReceived, Port);
+ }
+
+ if (parcelReceived == null)
+ {
+ throw new InvalidProtocolException();
+ }
+
+ ParcelHeader headerReceived = parcelReceived.GetHeader();
+ if (!string.IsNullOrEmpty(headerReceived.GetTag()))
+ {
+ if (headerReceived.GetSequenceNumber() != header.GetSequenceNumber())
+ {
+ parcelReceived.Dispose();
+ parcelReceived = null;
+ }
+ }
+
+ if (parcelReceived != null)
+ done = true;
+}
+while (!done);
+)__cs_cb";
+
#endif // IDLC_CS_GEN_CS_PROXY_GEN_CB_H_
diff --git a/idlc/gen/cs_stub_gen.cc b/idlc/gen/cs_stub_gen.cc
index 04b68b3..fe57d41 100644
--- a/idlc/gen/cs_stub_gen.cc
+++ b/idlc/gen/cs_stub_gen.cc
@@ -65,7 +65,7 @@ void CsStubGen::GenInterface(std::ofstream& stream, const Interface& iface) {
stream << Tab(2) << "public sealed class " << iface.GetID()
<< " : StubBase" << NLine(1);
GenBrace(stream, TAB_SIZE * 2, [&]() {
- stream << CB_DATA_MEMBERS;
+ stream << ReplaceAll(CB_DATA_MEMBERS, "<VERSION>", FULLVER);
GenServiceBase(stream, iface);
GenCallbacks(stream, iface, false);
GenDelegateId(stream, iface);
@@ -90,7 +90,7 @@ void CsStubGen::GenServiceBase(std::ofstream& stream, const Interface& iface) {
void CsStubGen::GenDeclarations(std::ofstream& stream,
const Declarations& decls) {
- for (auto& i : decls.GetDecls()) {
+ for (const auto& i : decls) {
if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
if (!i->GetComments().empty())
@@ -104,7 +104,7 @@ void CsStubGen::GenDeclarations(std::ofstream& stream,
void CsStubGen::GenReceivedEvent(std::ofstream& stream,
const Interface& iface) {
stream << CB_ON_RECEIVED_EVENT_FRONT;
- for (auto& i : iface.GetDeclarations().GetDecls()) {
+ for (const auto& i : iface.GetDeclarations()) {
if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
stream << Tab(7) << "case MethodId." << i->GetID() << ":" << NLine(1);
@@ -120,7 +120,7 @@ void CsStubGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
int cnt = 1;
// Deserialize
- for (auto& i : decl.GetParameters().GetParams()) {
+ for (const auto& i : decl.GetParameters()) {
if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT) {
cnt++;
continue;
@@ -144,7 +144,7 @@ void CsStubGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
}
m += "b." + decl.GetID() + "(";
- for (auto& i : decl.GetParameters().GetParams()) {
+ for (const auto& i : decl.GetParameters()) {
if (cnt != 1) {
m += ", ";
}
@@ -168,8 +168,8 @@ void CsStubGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
return;
cnt = 0;
- m = "result.WriteInt((int)MethodId.__Result);\n";
- for (auto& i : decl.GetParameters().GetParams()) {
+ m = CB_INVOCATION_RESULT_PRE;
+ for (const auto& i : decl.GetParameters()) {
auto& pt = i->GetParameterType();
cnt++;
if (pt.GetDirection() == ParameterType::Direction::IN)
@@ -203,7 +203,7 @@ void CsStubGen::GenCtor(std::ofstream& stream, const Interface& iface) {
return iface.GetID();
});
- for (auto& i : iface.GetAttributes().GetAttrs()) {
+ for (const auto& i : iface.GetAttributes()) {
if (i->GetKey() == "privilege") {
stream << Tab(4) << "AddPrivilege(\""
<< i->GetValue() << "\");" << NLine(1);
diff --git a/idlc/gen/cs_stub_gen_cb.h b/idlc/gen/cs_stub_gen_cb.h
index 3be382a..bbedac3 100644
--- a/idlc/gen/cs_stub_gen_cb.h
+++ b/idlc/gen/cs_stub_gen_cb.h
@@ -17,9 +17,13 @@
#ifndef IDLC_CS_GEN_CS_STUB_GEN_CB_H_
#define IDLC_CS_GEN_CS_STUB_GEN_CB_H_
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
const char CB_DATA_MEMBERS[] =
R"__cs_cb( private List<ServiceBase> _services = new List<ServiceBase>();
private Type _serviceType;
+ private static readonly string _tidlVersion = "<VERSION>";
)__cs_cb";
const char CB_SERVICE_BASE_FRONT[] =
@@ -42,11 +46,29 @@ R"__cs_cb(
get; internal set;
}
+ public Port Port
+ {
+ get;
+ internal set;
+ }
+
protected ServiceBase()
{
}
/// <summary>
+ /// Disconnects from the proxy app
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">
+ /// Thrown when an internal IO error occurrs.
+ /// </exception>
+ public void Disconnect()
+ {
+ Port?.Disconnect();
+ Port = null;
+ }
+
+ /// <summary>
/// This method will be called when the client is connected
/// </summary>
public abstract void OnCreate();
@@ -61,7 +83,16 @@ const char CB_ON_RECEIVED_EVENT_FRONT[] =
R"__cs_cb(
protected override bool OnReceivedEvent(string sender, string instance, Port port)
{
- var p = new Parcel(port);
+ Parcel p;
+
+ try
+ {
+ p = new Parcel(port);
+ }
+ catch (InvalidIOException)
+ {
+ return false;
+ }
try
{
@@ -116,6 +147,7 @@ R"__cs_cb(
ServiceBase s = Activator.CreateInstance(_serviceType) as ServiceBase;
s.Sender = sender;
s.Instance = instance;
+ s.Port = GetPort(Port.Type.Callback, instance);
s.OnCreate();
_services.Add(s);
}
@@ -184,4 +216,13 @@ R"__cs_cb(
}
)__cs_cb";
+constexpr const char CB_INVOCATION_RESULT_PRE[] =
+R"__cs_cb(
+ParcelHeader header = p.GetHeader();
+ParcelHeader resultHeader = result.GetHeader();
+resultHeader.SetTag(_tidlVersion);
+resultHeader.SetSequenceNumber(header.GetSequenceNumber());
+result.WriteInt((int)MethodId.__Result);
+)__cs_cb";
+
#endif // IDLC_CS_GEN_CS_STUB_GEN_CB_H_
diff --git a/idlc/gen/dart_gen_base.cc b/idlc/gen/dart_gen_base.cc
new file mode 100644
index 0000000..3ba526b
--- /dev/null
+++ b/idlc/gen/dart_gen_base.cc
@@ -0,0 +1,596 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/dart_gen_base.h"
+
+#include <algorithm>
+#include <ctime>
+#include <sstream>
+#include <stack>
+#include <utility>
+#include <vector>
+
+#include "idlc/gen/dart_gen_base_cb.h"
+
+namespace tidl {
+
+DartGeneratorBase::DartGeneratorBase(std::shared_ptr<Document> doc)
+ : Generator(doc) {
+ type_map_ = {
+ {"char", "int"},
+ {"int", "int"},
+ {"short", "int"},
+ {"long", "int"},
+ {"string", "String"},
+ {"bool", "bool"},
+ {"list", "List"},
+ {"array", "List"},
+ {"double", "double"},
+ {"bundle", "Bundle"},
+ {"void", "void"},
+ {"file", "String"}
+ };
+
+ parcel_type_map_ = {
+ {"char", "Byte"},
+ {"int", "Int32"},
+ {"short", "Int16"},
+ {"long", "Int64"},
+ {"string", "String"},
+ {"bool", "Bool"},
+ {"double", "Double"},
+ {"bundle", "Bundle"},
+ {"file", "String"}
+ };
+
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ for (const auto& e : st.GetElements()) {
+ auto& type = e->GetType();
+ AddListSerializer(type);
+ }
+ } else {
+ auto& iface = static_cast<const Interface&>(*b);
+ for (const auto& d : iface.GetDeclarations()) {
+ for (const auto& p : d->GetParameters())
+ AddListSerializer(p->GetParameterType().GetBaseType());
+
+ if (d->GetMethodType() == Declaration::MethodType::SYNC)
+ AddListSerializer(d->GetType());
+ }
+ }
+ }
+}
+
+void DartGeneratorBase::AddListSerializer(const BaseType& type) {
+ if (type.ToString() != "list" && type.ToString() != "array")
+ return;
+
+ std::string type_name = ConvertTypeToString(type);
+ AddListSerializer(*type.GetMetaType());
+
+ if (list_serializer_.find(type_name) != list_serializer_.end())
+ return;
+
+ list_serializer_[std::move(type_name)] = &type;
+}
+
+void DartGeneratorBase::GenAnnotation(std::ofstream& stream) {
+ ReplaceAll(CB_ANNOTATION, "<VERSION>", FULLVER)
+ .Transform([&](std::string str) {
+ return RemoveLine(str);
+ })
+ .Out(stream);
+}
+
+void DartGeneratorBase::GenImport(std::ofstream& stream) {
+ stream << CB_IMPORT << std::endl;
+}
+
+void DartGeneratorBase::GenVersion(std::ofstream& stream) {
+ ReplaceAll(CB_VERSION_DEF, "<VERSION>", FULLVER).Out(stream);
+ stream << NLine(1);
+}
+
+void DartGeneratorBase::GenDelegateId(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code;
+ int cnt = 1;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ if (cnt != 1)
+ code += "," + NLine(1);
+
+ std::string name = i->GetID();
+ name[0] = ::tolower(name[0]);
+ code += ReplaceAll(CB_ENUM, {
+ { "<NAME>", name },
+ { "<VALUE>", std::to_string(cnt++) }
+ });
+ }
+ code += ";";
+
+ ReplaceAll(CB_DELEGATE_ID, "<DELEGATE_IDS>", code)
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+}
+
+void DartGeneratorBase::GenDelegateId(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenDelegateId(stream, iface);
+ }
+}
+
+void DartGeneratorBase::GenMethodId(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code;
+ int cnt = 2;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ if (cnt != 2)
+ code += "," + NLine(1);
+
+ std::string name = i->GetID();
+ name[0] = ::tolower(name[0]);
+ code += ReplaceAll(CB_ENUM, {
+ { "<NAME>", name },
+ { "<VALUE>", std::to_string(cnt++) }
+ });
+ }
+ code += ";";
+
+ ReplaceAll(CB_METHOD_ID, "<METHOD_IDS>", code)
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+}
+
+void DartGeneratorBase::GenMethodId(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenMethodId(stream, iface);
+ }
+}
+
+void DartGeneratorBase::GenCallbackBase(std::ofstream& stream) {
+ std::string code = IsProxy() ? CB_PROXY_CALLBACK_BASE : CB_STUB_CALLBACK_BASE;
+ stream << SmartIndent(std::move(code));
+}
+
+void DartGeneratorBase::GenStructures(std::ofstream& stream) {
+ GenListSerializer(stream);
+
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_STRUCTURE)
+ continue;
+
+ Structure& st = static_cast<Structure&>(*i);
+ GenStructure(stream, st);
+ stream << std::endl;
+ }
+}
+
+void DartGeneratorBase::GenListSerializer(std::ofstream& stream) {
+ if (list_serializer_.empty())
+ return;
+
+ ReplaceAll(CB_LIST_SERIALIZER, {
+ { "<SERIALIZE>", GenListSerializerSerialize() },
+ { "<DESERIALIZE>", GenListSerializerDeserialize() }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+std::string DartGeneratorBase::GenListSerializerSerialize() {
+ std::string code;
+ for (const auto& iter : list_serializer_) {
+ std::string parcel_write;
+ auto& type = *(iter.second);
+ if (type.GetMetaType()->IsUserDefinedType()) {
+ parcel_write = ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<NAME>", "value" },
+ { "<PARCEL>", "parcel" }
+ });
+ parcel_write += NLine(1);
+ } else if (type.GetMetaType()->ToString() == "list" ||
+ type.GetMetaType()->ToString() == "array") {
+ parcel_write = ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<NAME>", "value" },
+ { "<PARCEL>", "parcel" }
+ });
+ parcel_write += NLine(1);
+ } else {
+ parcel_write = ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>",
+ ConvertTypeToParcelType(type.GetMetaType()->ToString()) },
+ { "<NAME>", "value" }
+ });
+ parcel_write += NLine(1);
+ }
+
+ code += ReplaceAll(CB_LIST_SERIALIZER_SERIALIZE, {
+ { "<TYPE>", iter.first },
+ { "<VALUE_TYPE>", ConvertTypeToString(*type.GetMetaType()) },
+ { "<PARCEL_WRITE>", parcel_write }
+ });
+ }
+
+ return RemoveLine(code);
+}
+
+std::string DartGeneratorBase::GenListSerializerDeserialize() {
+ std::string code;
+ for (const auto& iter : list_serializer_) {
+ std::string parcel_read;
+ auto& type = *(iter.second);
+ if (type.GetMetaType()->IsUserDefinedType()) {
+ parcel_read = "final " + ConvertTypeToString(*type.GetMetaType()) +
+ " value = " + ConvertTypeToString(*type.GetMetaType()) + "();";
+ parcel_read += NLine(1);
+ parcel_read += ReplaceAll(CB_USER_DEFINED_PARCEL_READ, {
+ { "<NAME>", "value" },
+ {" <PARCEL>", "parcel" }
+ });
+ } else if (type.GetMetaType()->ToString() == "list" ||
+ type.GetMetaType()->ToString() == "array") {
+ parcel_read = "final " + ConvertTypeToString(*type.GetMetaType()) +
+ " value = [];";
+ parcel_read += NLine(1);
+ parcel_read += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<NAME>", "value" },
+ { "<PARCEL>", "parcel" }
+ });
+ } else {
+ parcel_read = "final " + ConvertTypeToString(*type.GetMetaType()) + " ";
+ parcel_read += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>",
+ ConvertTypeToParcelType(type.GetMetaType()->ToString()) },
+ { "<NAME>", "value" }
+ });
+ }
+
+ code += ReplaceAll(CB_LIST_SERIALIZER_DESERIALIZE, {
+ { "<TYPE>", iter.first },
+ { "<PARCEL_READ>", parcel_read }
+ });
+ }
+
+ return RemoveLine(code);
+}
+
+void DartGeneratorBase::GenStructure(std::ofstream& stream,
+ const Structure& st) {
+ auto& elms = st.GetElements();
+ ReplaceAll(CB_STRUCTURE_BASE, {
+ { "<NAME>", GetClassName(st.GetID()) },
+ { "<ELEMENTS>", GenBaseElements(elms) },
+ { "<PARCEL_WRITE>", GenBaseParcelWrite(elms) },
+ { "<PARCEL_READ>", GenBaseParcelRead(elms) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+std::string DartGeneratorBase::GenBaseElements(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ if (!code.empty())
+ code += NLine(1);
+
+ auto& type = elm->GetType();
+ auto param_type = ConvertTypeToString(type);
+ code += "/// The " + elm->GetID();
+ code += NLine(1);
+ code += "late " + param_type + " " + elm->GetID() + ";";
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+std::string DartGeneratorBase::GenBaseParcelWrite(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<NAME>", elm->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<NAME>", elm->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>", elm->GetID() }
+ });
+ code += NLine(1);
+ }
+
+ auto private_sharing_code = GetPrivateSharingString(
+ type, "port", elm->GetID());
+ if (!private_sharing_code.empty())
+ code += private_sharing_code + NLine(1);
+ }
+
+ return code;
+}
+
+std::string DartGeneratorBase::GenBaseParcelRead(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_READ, {
+ { "<NAME>", elm->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<NAME>", elm->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>", elm->GetID() }
+ });
+ code += NLine(1);
+ }
+ }
+
+ return code;
+}
+
+std::string DartGeneratorBase::ConvertTypeToString(const BaseType& type) {
+ if (type.IsUserDefinedType())
+ return type.ToString();
+
+ if (type.GetMetaType() != nullptr)
+ return type_map_[type.ToString()] + "<" +
+ ConvertTypeToString(*(type.GetMetaType())) + ">";
+
+ return type_map_[type.ToString()];
+}
+
+std::string DartGeneratorBase::ConvertTypeToParcelType(const std::string& key) {
+ return parcel_type_map_[key];
+}
+
+std::string DartGeneratorBase::Tab(int cnt) {
+ std::string t;
+ for (int i = 0; i < cnt; i++)
+ t += " ";
+
+ return t;
+}
+
+std::string DartGeneratorBase::NLine(int cnt) {
+ std::string t;
+ for (int i = 0; i < cnt; i++)
+ t += "\n";
+
+ return t;
+}
+
+std::string DartGeneratorBase::RemoveSpaces(const std::string& str) {
+ // for annotation
+ if (str.compare(0, 3, "/**") == 0 ||
+ str.compare(0, 2, " *") == 0 ||
+ str.compare(0, 3, " */") == 0)
+ return str;
+
+ std::size_t found = str.find_first_not_of(' ');
+ if (found == std::string::npos)
+ return "";
+
+ return str.substr(found, str.size() - found);
+}
+
+std::string DartGeneratorBase::Trim(const std::string& str) {
+ // for annotation
+ if (str.compare(0, 3, "/**") == 0 ||
+ str.compare(0, 2, " *") == 0 ||
+ str.compare(0, 3, " */") == 0)
+ return str;
+
+ std::size_t first = str.find_first_not_of(" \t\r\n");
+ if (first == std::string::npos)
+ return str;
+
+ std::size_t last = str.find_last_not_of(" \t\r\n");
+ return str.substr(first, (last - first + 1));
+}
+
+std::string DartGeneratorBase::RemoveLine(std::string lines,
+ unsigned int line_num) {
+ std::stringstream ss(lines);
+ std::string result;
+ std::string line;
+ unsigned int line_count = 0;
+
+ while (std::getline(ss, line, '\n')) {
+ line_count++;
+ if (line_num == line_count)
+ continue;
+
+ result += Trim(line);
+ result += NLine(1);
+ }
+
+ return result;
+}
+
+std::string DartGeneratorBase::SmartIndent(std::string lines) {
+ std::stringstream stream(lines);
+ std::string next_line;
+ std::string line;
+ std::string tab;
+ std::string line_back;
+ std::string code;
+ unsigned int line_count = 0;
+ int tab_size = 0;
+ std::stack<int> prev_tab_size;
+ bool tab_once = false;
+ bool continuous = false;
+ bool enum_block = false;
+
+ while (std::getline(stream, next_line, '\n')) {
+ next_line = RemoveSpaces(std::move(next_line));
+ line_count++;
+ if (line_count == 1) {
+ line = Trim(next_line);
+ continue;
+ }
+
+ tab.clear();
+ // Checks whether the brace is end or not.
+ if (line.find_first_of("}") < line.find_first_of("{"))
+ tab_size--;
+
+ // Set tab
+ if (line.length() > 0)
+ tab += Tab(tab_size);
+
+ // Set tab for if statement or for loop or while loop
+ if (tab_once) {
+ tab += Tab(1);
+ tab_once = false;
+ }
+
+ if (continuous) {
+ tab += Tab(2);
+ continuous = false;
+ }
+
+ if (line.front() == ':')
+ tab += Tab(2);
+
+ // Checks whether switch case is end or not.
+ line_back = "__INVALID__";
+ if (line.length() > 0)
+ line_back = line.back();
+
+ if (!prev_tab_size.empty() && prev_tab_size.top() == (tab_size - 1) &&
+ line_back == "}") {
+ prev_tab_size.pop();
+ tab_size--;
+ enum_block = false;
+ }
+
+ if (line.empty() || std::all_of(line.begin(), line.end(), isspace)) {
+ std::string new_line = Trim(next_line);
+ if (new_line.empty() || new_line.find('}') != std::string::npos ||
+ std::all_of(new_line.begin(), new_line.end(), isspace)) {
+ line = std::move(new_line);
+ continue;
+ }
+
+ code += tab + line + NLine(1);
+ } else {
+ if (line.compare(0, 2, " *") != 0)
+ code += tab;
+
+ code += line + NLine(1);
+ }
+
+ // Checks whether the brace is starting or not
+ if (line_back == "{" ) {
+ tab_size++;
+ if (line.find("enum ") != std::string::npos)
+ enum_block = true;
+ }
+
+ if (line_back != "{") {
+ // Checks whether if statement or for loop or while loop without braces is starting or not.
+ if (line.find("if (") != std::string::npos ||
+ line.find("for (") != std::string::npos ||
+ line.find("while (") != std::string::npos)
+ tab_once = true;
+
+ /// Checks whether switch case is starting or not.
+ if ((line.find("case ") != std::string::npos && line_back == ":") ||
+ line.find("default:") != std::string::npos) {
+ tab_size++;
+
+ prev_tab_size.push(tab_size - 1);
+ }
+
+ if (!enum_block && line_back == ",")
+ continuous = true;
+ }
+
+ line = std::move(Trim(next_line));
+ }
+
+ code += line + NLine(1);
+ return code;
+}
+
+std::string DartGeneratorBase::GetClassName(std::string name) {
+ name[0] = ::toupper(name[0]);
+ return name;
+}
+
+std::string DartGeneratorBase::GetPrivateSharingString(const BaseType& type,
+ const std::string& port, const std::string& arg) {
+ std::string code;
+ if (type.ToString() == "list" || type.ToString() == "array") {
+ if (type.GetMetaType() != nullptr &&
+ type.GetMetaType()->ToString() == "file") {
+ code = ReplaceAll(CB_LIST_FILE_SET_PRIVATE_SHARING, {
+ { "<PORT>", port },
+ { "<ARG>", arg }
+ });
+ }
+ } else if (type.ToString() == "file") {
+ code = ReplaceAll(CB_FILE_ADD, {
+ { "<PORT>", port },
+ { "<ARG>", arg }
+ });
+ }
+
+ return code;
+}
+
+} // namespace tidl
diff --git a/idlc/gen/dart_gen_base.h b/idlc/gen/dart_gen_base.h
new file mode 100644
index 0000000..018a553
--- /dev/null
+++ b/idlc/gen/dart_gen_base.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_GEN_BASE_H_
+#define IDLC_GEN_DART_GEN_BASE_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "idlc/ast/structure.h"
+#include "idlc/ast/type.h"
+#include "idlc/gen/generator.h"
+
+namespace tidl {
+
+class DartGeneratorBase : public Generator {
+ public:
+ explicit DartGeneratorBase(std::shared_ptr<Document> doc);
+ virtual ~DartGeneratorBase() = default;
+
+ void GenAnnotation(std::ofstream& stream);
+ void GenImport(std::ofstream& stream);
+ void GenVersion(std::ofstream& stream);
+ void GenDelegateId(std::ofstream& stream);
+ void GenMethodId(std::ofstream& stream);
+ void GenCallbackBase(std::ofstream& stream);
+ void GenStructures(std::ofstream& stream);
+
+ std::string ConvertTypeToParcelType(const std::string& key);
+ std::string ConvertTypeToString(const BaseType& type);
+ std::string GetClassName(std::string name);
+ std::string NLine(int cnt);
+ std::string RemoveLine(std::string lines, unsigned int line_num = 1);
+ std::string RemoveSpaces(const std::string& str);
+ std::string SmartIndent(std::string lines);
+ std::string Tab(int cnt);
+ std::string Trim(const std::string& str);
+ std::string GetPrivateSharingString(const BaseType& type,
+ const std::string& port, const std::string& arg);
+
+ private:
+ void AddListSerializer(const BaseType& type);
+ void GenListSerializer(std::ofstream& stream);
+ std::string GenListSerializerSerialize();
+ std::string GenListSerializerDeserialize();
+ void GenStructure(std::ofstream& stream, const Structure& st);
+ std::string GenBaseElements(const Elements& elms);
+ std::string GenBaseParcelWrite(const Elements& elms);
+ std::string GenBaseParcelRead(const Elements& elms);
+ void GenDelegateId(std::ofstream& stream, const Interface& iface);
+ void GenMethodId(std::ofstream& stream, const Interface& iface);
+
+ protected:
+ const int TAB_SIZE = 2;
+
+ private:
+ std::map<std::string, std::string> type_map_;
+ std::map<std::string, std::string> parcel_type_map_;
+ std::unordered_map<std::string, const BaseType*> list_serializer_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_GEN_BASE_H_
diff --git a/idlc/gen/dart_gen_base_cb.h b/idlc/gen/dart_gen_base_cb.h
new file mode 100644
index 0000000..889b94c
--- /dev/null
+++ b/idlc/gen/dart_gen_base_cb.h
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_GEN_BASE_CB_H_
+#define IDLC_GEN_DART_GEN_BASE_CB_H_
+
+namespace tidl {
+
+/**
+ * <VERSION> The TIDLC version.
+ */
+constexpr const char CB_ANNOTATION[] =
+R"__dart_cb(
+/// Generated by tidlc <VERSION>
+
+// ignore_for_file: public_member_api_docs, omit_local_variable_types
+)__dart_cb";
+
+constexpr const char CB_IMPORT[] =
+R"__dart_cb(
+import 'package:tizen_rpc_port/tizen_rpc_port.dart';
+)__dart_cb";
+
+/**
+ * <LOG_TAG> The log tag.
+ */
+constexpr const char CB_LOG_TAG[] =
+R"__dart_cb(const String _logTag = '<LOG_TAG>';)__dart_cb";
+
+/**
+ * <VERSION> The TIDLC version.
+ */
+constexpr const char CB_VERSION_DEF[] =
+R"__dart_cb(const String _tidlVersion = '<VERSION>';)__dart_cb";
+
+/**
+ * <METHOD_IDS> The method IDs.
+ */
+constexpr const char CB_METHOD_ID[] =
+R"__dart_cb(
+enum _MethodId {
+ result(0),
+ callback(1),
+ <METHOD_IDS>
+
+ const _MethodId(this.id);
+ final int id;
+}
+)__dart_cb";
+
+/**
+ * <DELEGATE_IDS> The delegate IDs.
+ */
+constexpr const char CB_DELEGATE_ID[] =
+R"__dart_cb(
+enum _DelegateId {
+ <DELEGATE_IDS>
+
+ const _DelegateId(this.id);
+ final int id;
+}
+)__dart_cb";
+
+/**
+ * <NAME> The name of the enumeration.
+ * <VALUE> The value of the enumeration.
+ */
+constexpr const char CB_ENUM[] =
+R"__dart_cb(<NAME>(<VALUE>))__dart_cb";
+
+constexpr const char CB_PROXY_CALLBACK_BASE[] =
+R"__dart_cb(
+abstract class _Delegate extends Parcelable {
+ _Delegate(this.id, this.once, this.callback) {
+ sequenceId = sequenceNum++;
+ }
+
+ int id = 0;
+ bool once = false;
+ int sequenceId = 0;
+ Function callback;
+ static int sequenceNum = 0;
+
+ Future<void> onReceivedEvent(Parcel parcel);
+
+ @override
+ void serialize(Parcel parcel) {
+ parcel.writeInt32(id);
+ parcel.writeInt32(sequenceId);
+ parcel.writeBool(once);
+ }
+
+ @override
+ void deserialize(Parcel parcel) {
+ id = parcel.readInt32();
+ sequenceId = parcel.readInt32();
+ once = parcel.readBool();
+ }
+}
+)__dart_cb";
+
+constexpr const char CB_STUB_CALLBACK_BASE[] =
+R"__dart_cb(
+abstract class _Delegate extends Parcelable {
+ _Delegate(this.id, this.once);
+
+ int id = 0;
+ bool once = false;
+ int sequenceId = 0;
+
+ @override
+ void serialize(Parcel parcel) {
+ parcel.writeInt32(id);
+ parcel.writeInt32(sequenceId);
+ parcel.writeBool(once);
+ }
+
+ @override
+ void deserialize(Parcel parcel) {
+ id = parcel.readInt32();
+ sequenceId = parcel.readInt32();
+ once = parcel.readBool();
+ }
+}
+)__dart_cb";
+
+/**
+ * <NAME> The name of the structure.
+ * <ELEMENTS> Elements of the structure.
+ * <PARCEL_WRITE> The implementation to write the data to the parcel.
+ * <PARCEL_READ> The implementation to read the data from the parcel.
+ */
+constexpr const char CB_STRUCTURE_BASE[] =
+R"__dart_cb(
+/// The [<NAME>] class.
+class <NAME> extends Parcelable {
+ /// Constructor for this class.
+ <NAME>();
+
+ /// Constructor for creating a [<NAME>] class from the parcel.
+ <NAME>.fromParcel(Parcel parcel) {
+ deserialize(parcel);
+ }
+
+ <ELEMENTS>
+
+ @override
+ void serialize(Parcel parcel) {
+ <PARCEL_WRITE>
+ }
+
+ @override
+ void deserialize(Parcel parcel) {
+ <PARCEL_READ>
+ }
+}
+)__dart_cb";
+
+/**
+ * <NAME> The variable name of the user defined type.
+ * <PARCEL> The name of the parcel instance.
+ */
+constexpr const char CB_USER_DEFINED_PARCEL_WRITE[] =
+R"__dart_cb(<NAME>.serialize(<PARCEL>);)__dart_cb";
+
+/**
+ * <PARCEL> The name of the parcel instance.
+ * <NAME> The variable name of the list type.
+ */
+constexpr const char CB_LIST_PARCEL_WRITE[] =
+R"__dart_cb(ListSerializer().serialize(<PARCEL>, <NAME>);)__dart_cb";
+
+/**
+ * <PARCEL> The name of the parcel instance.
+ * <PARCEL_TYPE> The type of the parcel of the variable.
+ * <NAME> The variable name of the base type.
+ */
+constexpr const char CB_BASE_PARCEL_WRITE[] =
+R"__dart_cb(<PARCEL>.write<PARCEL_TYPE>(<NAME>);)__dart_cb";
+
+/**
+ * <NAME> The variable name of the user defined type.
+ * <PARCEL> The name of the parcel instance.
+ */
+constexpr const char CB_USER_DEFINED_PARCEL_READ[] =
+R"__dart_cb(<NAME>.deserialize(<PARCEL>);)__dart_cb";
+
+/**
+ * <PARCEL> The name of the parcel instance.
+ * <NAME> The variable name of the list type.
+ */
+constexpr const char CB_LIST_PARCEL_READ[] =
+R"__dart_cb(ListSerializer().deserialize(<PARCEL>, <NAME>);)__dart_cb";
+
+/**
+ * <PARCEL> The name of the parcel instance.
+ * <PARCEL_TYPE> The type of the parcel of the element.
+ * <NAME> The variable name of the base type.
+ */
+constexpr const char CB_BASE_PARCEL_READ[] =
+R"__dart_cb(<NAME> = <PARCEL>.read<PARCEL_TYPE>();)__dart_cb";
+
+/**
+ * <PORT> The rpc port handle.
+ * <ARG> The argument.
+ */
+constexpr const char CB_FILE_ADD[] =
+R"__dart_cb(<PORT>.shareFile(<ARG>);)__dart_cb";
+
+/**
+ * <PORT> The rpc port handle.
+ * <ARG> The argument.
+ */
+constexpr const char CB_LIST_FILE_SET_PRIVATE_SHARING[] =
+R"__dart_cb(<PORT>.shareFiles(<ARG>);)__dart_cb";
+
+/**
+ * <SERIALIZE> The implementation to serialize the data to the parcel.
+ * <DESERIALIZE> The implementation to deserialize the data from the parcel.
+ */
+constexpr const char CB_LIST_SERIALIZER[] =
+R"__dart_cb(
+/// The [ListSerializer] class for serializing a list to the parcel.
+class ListSerializer {
+ /// Gets the instance of the [ListSerializer].
+ factory ListSerializer() {
+ return _instance;
+ }
+
+ ListSerializer._internal();
+
+ static final ListSerializer _instance = ListSerializer._internal();
+
+ /// Serailizes the parameter to the parcel.
+ void serialize(Parcel parcel, dynamic param) {
+ switch (param.runtimeType) {
+ <SERIALIZE>
+ default:
+ {
+ return;
+ }
+ }
+ }
+
+ /// Deserializes the parameter from the parcel.
+ void deserialize(Parcel parcel, dynamic param) {
+ switch (param.runtimeType) {
+ <DESERIALIZE>
+ default:
+ {
+ return;
+ }
+ }
+ }
+}
+)__dart_cb";
+
+/**
+ * <TYPE> The data type.
+ * <VALUE_TYPE> The value type of the list element.
+ * <PARCEL_WRITE> The implementation to write the data to the parcel.
+ */
+constexpr const char CB_LIST_SERIALIZER_SERIALIZE[] =
+R"__dart_cb(
+case <TYPE>:
+ {
+ parcel.writeArrayCount(param.length as int);
+ param.forEach((<VALUE_TYPE> value) {
+ <PARCEL_WRITE>
+ });
+ return;
+ }
+)__dart_cb";
+
+/**
+ * <TYPE> The data type.
+ * <PARCEL_READ> The implementation to read the data from the parcel.
+ */
+constexpr const char CB_LIST_SERIALIZER_DESERIALIZE[] =
+R"__dart_cb(
+case <TYPE>:
+ {
+ final int count = parcel.readArrayCount();
+ for (int i = 0; i < count; ++i) {
+ <PARCEL_READ>
+ param.add(value);
+ }
+ return;
+ }
+)__dart_cb";
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_GEN_BASE_CB_H_
diff --git a/idlc/gen/dart_proxy_gen.cc b/idlc/gen/dart_proxy_gen.cc
new file mode 100644
index 0000000..c793674
--- /dev/null
+++ b/idlc/gen/dart_proxy_gen.cc
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/dart_proxy_gen.h"
+
+#include <cctype>
+#include <utility>
+
+#include "idlc/gen/dart_gen_base_cb.h"
+#include "idlc/gen/dart_proxy_gen_cb.h"
+
+namespace tidl {
+
+DartProxyGen::DartProxyGen(std::shared_ptr<Document> doc)
+ : DartGeneratorBase(doc) {}
+
+void DartProxyGen::OnInitGen(std::ofstream& stream) {
+ GenAnnotation(stream);
+ GenImport(stream);
+ GenVersion(stream);
+ GenDelegateId(stream);
+ GenMethodId(stream);
+ GenStructures(stream);
+ GenInterfaces(stream);
+}
+
+void DartProxyGen::OnFiniGen(std::ofstream& stream) {}
+
+void DartProxyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*i);
+ GenCallbackBase(stream);
+ GenInterface(stream, iface);
+ }
+}
+
+void DartProxyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ GenDelegateBase(stream, *d);
+ }
+
+ GenInterfaceBase(stream, iface);
+}
+
+void DartProxyGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string name = iface.GetID();
+ name[0] = ::toupper(name[0]);
+ ReplaceAll(CB_INTERFACE_BASE, {
+ { "<INTERFACE_NAME>", name },
+ { "<METHODS>", GenInterfaceMethods(iface) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(std::move(str));
+ })
+ .Out(stream);
+}
+
+std::string DartProxyGen::GenInterfaceMethods(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string args;
+ for (auto& param : d->GetParameters())
+ args += ConvertTypeToString(param->GetParameterType().GetBaseType())
+ + ' ' + param->GetID() + ", ";
+
+ if (!args.empty()) {
+ args.pop_back();
+ args.pop_back();
+ }
+
+ std::string method_name = d->GetID();
+ method_name[0] = std::tolower(method_name[0]);
+
+ code += ReplaceAll(CB_METHOD_BASE, {
+ { "<METHOD_NAME>", d->GetID() },
+ { "<LOWER_METHOD_NAME>", std::move(method_name) },
+ { "<RETURN_TYPE>", GenReturnType(*d) },
+ { "<ARGS>", args },
+ { "<ASYNC>", GenAsync(*d) },
+ { "<METHOD_PARCEL_WRITE>", GenMethodParcelWrite(*d) },
+ { "<METHOD_PARCEL_READ>", GenMethodParcelRead(*d) },
+ });
+ }
+
+ return RemoveLine(code);
+}
+
+std::string DartProxyGen::GenReturnType(const Declaration& decl) {
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC)
+ return "Future<" + decl.GetType().ToString() + ">";
+
+ return decl.GetType().ToString();
+}
+
+std::string DartProxyGen::GenAsync(const Declaration& decl) {
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC)
+ return "async ";
+
+ return "";
+}
+
+std::string DartProxyGen::GenMethodParcelWrite(const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(type)) {
+ code += ReplaceAll(CB_METHOD_DELEGATE_WRITE, {
+ { "<DELEGATE_TYPE>", ConvertTypeToString(type) },
+ { "<DELEGATE_NAME>", p->GetID() }
+ });
+ } else if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<NAME>", p->GetID() }
+ });
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<NAME>", p->GetID() }
+ });
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>" , p->GetID() }
+ });
+ }
+
+ code += NLine(1);
+ auto private_sharing_code =
+ GetPrivateSharingString(type, "port", p->GetID());
+ if (!private_sharing_code.empty())
+ code += private_sharing_code + NLine(1);
+ }
+
+ std::string method_id = decl.GetID();
+ method_id[0] = ::tolower(method_id[0]);
+ code = ReplaceAll(CB_METHOD_PARCEL_WRITE, {{"<PARCEL_WRITE>", code},
+ {"<METHOD_NAME>", method_id}});
+ return code;
+}
+
+std::string DartProxyGen::GenMethodParcelRead(const Declaration& decl) {
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC)
+ return {};
+
+ std::string code = GenMethodResultParcelRead(decl);
+ code += GenMethodOutParamParcelRead(decl);
+ code = ReplaceAll(CB_METHOD_PARCEL_READ, "<PARCEL_READ>", code);
+ return code;
+}
+
+std::string DartProxyGen::GenMethodResultParcelRead(
+ const Declaration& decl) {
+ std::string code;
+ auto& type = decl.GetType();
+ std::string prefix = "final " + ConvertTypeToString(type) + " ret";
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_READ, {
+ { "<PARCEL>", "parcelReceived" },
+ { "<NAME>", prefix }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<PARCEL>", "parcelReceived" },
+ { "<NAME>", prefix }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcelReceived" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>" , prefix }
+ });
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+std::string DartProxyGen::GenMethodOutParamParcelRead(
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_READ, {
+ { "<PARCEL>", "parcelReceived" },
+ { "<NAME>", p->GetID() }
+ });
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<PARCEL>", "parcelReceived" },
+ { "<NAME>", p->GetID() }
+ });
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcelReceived" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>" , p->GetID() }
+ });
+ }
+ }
+
+ code += NLine(1);
+ return code;
+}
+
+std::string DartProxyGen::GenMethodArgsFree(const Declaration& decl) {
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC)
+ return {};
+
+ std::string code;
+ if (decl.GetType().ToString() == "bundle") {
+ code += "ret.dispose();";
+ code += NLine(1);
+ }
+
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.ToString() == "bundle") {
+ code += p->GetID() + ".dispose();";
+ code += NLine(1);
+ }
+ }
+
+ return code;
+}
+
+std::string DartProxyGen::GenMethodParams(const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ if (!params.empty())
+ params += ", ";
+
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += ConvertTypeToString(type) + " " + p->GetID();
+ }
+
+ return params;
+}
+
+void DartProxyGen::GenDelegateBase(std::ofstream& stream,
+ const Declaration& decl) {
+ std::string id = decl.GetID();
+ id[0] = ::tolower(id[0]);
+ ReplaceAll(CB_DELEGATE_BASE, {
+ { "<DELEGATE_NAME>", GetClassName(decl.GetID()) },
+ { "<DELEGATE_ID>", id },
+ { "<DELEGATE_PARAMS>", GenDelegateParams(decl) },
+ { "<DELEGATE_PARAM_TYPES>", GenDelegateParamTypes(decl) },
+ { "<DELEGATE_PARCEL_READ>", GenDelegateParcelRead(decl) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+std::string DartProxyGen::GenDelegateParams(const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ if (!params.empty())
+ params += ", ";
+
+ params += p->GetID();
+ }
+
+ return params;
+}
+
+std::string DartProxyGen::GenDelegateParamTypes(const Declaration& decl) {
+ std::string types;
+ for (const auto& p : decl.GetParameters()) {
+ if (!types.empty())
+ types += ", ";
+
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ types += ConvertTypeToString(type);
+ }
+
+ return types;
+}
+
+std::string DartProxyGen::GenDelegateParcelRead(const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ code += "final " + ConvertTypeToString(type) + " ";
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_READ, {
+ { "<NAME>", p->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<NAME>", p->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>", p->GetID() }
+ });
+ code += NLine(1);
+ }
+ }
+
+ return code;
+}
+
+} // namespace tidl
diff --git a/idlc/gen/dart_proxy_gen.h b/idlc/gen/dart_proxy_gen.h
new file mode 100644
index 0000000..e9a6eef
--- /dev/null
+++ b/idlc/gen/dart_proxy_gen.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_PROXY_GEN_H_
+#define IDLC_GEN_DART_PROXY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/dart_gen_base.h"
+
+namespace tidl {
+
+class DartProxyGen : public DartGeneratorBase {
+ public:
+ explicit DartProxyGen(std::shared_ptr<Document> doc);
+ virtual ~DartProxyGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenOnDisconnected(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ std::string GenInterfaceMethods(const Interface& iface);
+ std::string GenMethodParcelRead(const Declaration& decl);
+ std::string GenMethodInvoke(const Declaration& decl);
+ std::string GenReturnType(const Declaration& decl);
+ std::string GenAsync(const Declaration& decl);
+ std::string GenMethodParcelWrite(const Declaration& decl);
+ std::string GenMethodResultParcelRead(const Declaration& decl);
+ std::string GenMethodOutParamParcelRead(const Declaration& decl);
+ std::string GenMethodArgsFree(const Declaration& decl);
+ void GenServiceBase(std::ofstream& stream, const Interface& iface);
+ std::string GenServiceBaseMethodDecls(const Interface& iface);
+ std::string GenMethodParams(const Declaration& decl);
+ void GenDelegateBase(std::ofstream& stream, const Declaration& decl);
+ std::string GenDelegateParams(const Declaration& decl);
+ std::string GenDelegateParamTypes(const Declaration& decl);
+ std::string GenDelegateParcelRead(const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_PROXY_GEN_H_
diff --git a/idlc/gen/dart_proxy_gen_cb.h b/idlc/gen/dart_proxy_gen_cb.h
new file mode 100644
index 0000000..abe78a8
--- /dev/null
+++ b/idlc/gen/dart_proxy_gen_cb.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_PROXY_GEN_CB_H_
+#define IDLC_GEN_DART_PROXY_GEN_CB_H_
+
+namespace tidl {
+
+/**
+ * <DELEGATE_NAME> The name of the delegate.
+ * <DELEGATE_ID> The ID of the delegate.
+ * <DELEGATE_PARAMS> Parameters of the delegate.
+ * <DELEGATE_PARAM_TYPES> Types of Parameters of the delegate.
+ * <DELEGATE_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ */
+constexpr const char CB_DELEGATE_BASE[] =
+R"__dart_cb(
+/// Called when the <DELEGATE_NAME> event is received.
+typedef <DELEGATE_NAME> = void Function(<DELEGATE_PARAM_TYPES>);
+
+class _<DELEGATE_NAME> extends _Delegate {
+ /// Constructor for this class.
+ _<DELEGATE_NAME>(<DELEGATE_NAME> callback, {bool once = false})
+ : super(_DelegateId.<DELEGATE_ID>.id, once, callback);
+
+ @override
+ Future<void> onReceivedEvent(Parcel parcel) async {
+ <DELEGATE_PARCEL_READ>
+ (callback as <DELEGATE_NAME>)(<DELEGATE_PARAMS>);
+ }
+}
+)__dart_cb";
+
+/**
+ * <INTERFACE_NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__dart_cb(
+/// [<INTERFACE_NAME>] class for RPC.
+class <INTERFACE_NAME> extends ProxyBase {
+ /// Constructor for this class.
+ <INTERFACE_NAME>(String appid) : super(appid, '<INTERFACE_NAME>');
+
+ final List<_Delegate> _delegates = <_Delegate>[];
+
+ @override
+ @visibleForOverriding
+ @nonVirtual
+ Future<void> onReceivedEvent(Parcel parcel) async {
+ final int cmd = parcel.readInt32();
+ if (cmd != _MethodId.callback.id) {
+ return;
+ }
+
+ final int id = parcel.readInt32();
+ final int sequenceId = parcel.readInt32();
+ final bool once = parcel.readBool();
+
+ for (final _Delegate delegate in _delegates) {
+ if (delegate.id == id && delegate.sequenceId == sequenceId) {
+ await delegate.onReceivedEvent(parcel);
+ if (delegate.once && once) {
+ _delegates.remove(delegate);
+ }
+ break;
+ }
+ }
+ }
+
+ /// Disposes of registered delegate interface.
+ void disposeCallback(Function callback) {
+ _delegates
+ .removeWhere((_Delegate delegate) => delegate.callback == callback);
+ }
+
+ <METHODS>
+}
+)__dart_cb";
+
+/**
+ * <METHOD_NAME> The name of method.
+ * <RETURN_TYPE> The type of return value.
+ * <ARGS> The arguments of method.
+ * <METHOD_PARCEL_WRITE> The implementation to write to the parcel.
+ * <METHOD_PARCEL_READ> The implementation to read the arguments from the parcel.
+ * to the parcel.
+ */
+constexpr const char CB_METHOD_BASE[] =
+R"__dart_cb(
+/// This method is used to send '<METHOD_NAME>' request to the stub app.
+<RETURN_TYPE> <LOWER_METHOD_NAME>(<ARGS>) <ASYNC>{
+ <METHOD_PARCEL_WRITE>
+ <METHOD_PARCEL_READ>
+}
+)__dart_cb";
+
+/**
+ * <METHOD_NAME> The name of method.
+ * <PARCEL_WRITE> The implementation of parcel write.
+ */
+constexpr const char CB_METHOD_PARCEL_WRITE[] =
+R"__dart_cb(
+if (!isConnected) {
+ throw StateError('Must be connected first');
+}
+
+final Port port = getPort(PortType.main);
+final Parcel parcel = Parcel();
+final ParcelHeader header = parcel.header;
+header.tag = _tidlVersion;
+parcel.writeInt32(_MethodId.<METHOD_NAME>.id);
+
+<PARCEL_WRITE>
+parcel.send(port);
+)__dart_cb";
+
+/**
+ * <PARCEL_READ> The implementation of parcel read.
+ */
+constexpr const char CB_METHOD_PARCEL_READ[] =
+R"__dart_cb(
+late Parcel parcelReceived;
+while (true) {
+ parcelReceived = Parcel.fromPort(port);
+ final int cmd = parcelReceived.readInt32();
+ if (cmd != _MethodId.result.id) {
+ continue;
+ }
+ final ParcelHeader headerReceived = parcelReceived.header;
+ if (headerReceived.tag.isEmpty) {
+ break;
+ } else if (headerReceived.sequenceNumber == header.sequenceNumber) {
+ break;
+ }
+}
+
+<PARCEL_READ>
+return ret;
+)__dart_cb";
+
+/**
+ * <DELEGATE_TYPE> The name of the delegate object.
+ * <DELEGATE_NAME> The name of the delegate object.
+ */
+constexpr const char CB_METHOD_DELEGATE_WRITE[] =
+R"__dart_cb(
+{
+ final _<DELEGATE_TYPE> delegate = _<DELEGATE_TYPE>(<DELEGATE_NAME>);
+ delegate.serialize(parcel);
+ _delegates.add(delegate);
+}
+)__dart_cb";
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_PROXY_GEN_CB_H_
diff --git a/idlc/gen/dart_stub_gen.cc b/idlc/gen/dart_stub_gen.cc
new file mode 100644
index 0000000..a547621
--- /dev/null
+++ b/idlc/gen/dart_stub_gen.cc
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/dart_stub_gen.h"
+
+#include "idlc/gen/dart_gen_base_cb.h"
+#include "idlc/gen/dart_stub_gen_cb.h"
+
+namespace tidl {
+
+DartStubGen::DartStubGen(std::shared_ptr<Document> doc)
+ : DartGeneratorBase(doc) {}
+
+void DartStubGen::OnInitGen(std::ofstream& stream) {
+ GenAnnotation(stream);
+ GenImport(stream);
+ GenVersion(stream);
+ GenDelegateId(stream);
+ GenMethodId(stream);
+ GenCallbackBase(stream);
+ GenStructures(stream);
+ GenInterfaces(stream);
+}
+
+void DartStubGen::OnFiniGen(std::ofstream& stream) {}
+
+void DartStubGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void DartStubGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ GenServiceBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ GenDelegateBase(stream, *d);
+ }
+
+ GenInterfaceBase(stream, iface);
+}
+
+void DartStubGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string name = iface.GetID();
+ name[0] = ::toupper(name[0]);
+ ReplaceAll(CB_INTERFACE_BASE, {
+ { "<INTERFACE_NAME>", name },
+ { "<CTOR>", GenInterfaceCtor(iface) },
+ { "<METHOD_HANDLERS>", GenInterfaceMethodHandlers(iface) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(std::move(str));
+ })
+ .Out(stream);
+}
+
+std::string DartStubGen::GenInterfaceCtor(const Interface& iface) {
+ std::string method_handler_table;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string name = d->GetID();
+ name[0] = ::tolower(name[0]);
+ method_handler_table += ReplaceAll(CB_METHOD_HANDLER_TABLE, {
+ { "<METHOD_ID>", name },
+ { "<METHOD_NAME>", d->GetID() }
+ });
+ method_handler_table += NLine(1);
+ }
+
+ std::string attributes;
+ for (const auto& i : iface.GetAttributes()) {
+ if (i->GetKey() == "privilege") {
+ attributes += "addPrivilege('" + i->GetValue() + "');";
+ attributes += NLine(1);
+ } else if (i->GetKey() == "trusted" && i->GetValue() == "true") {
+ attributes += "setTrusted(true);";
+ attributes += NLine(1);
+ }
+ }
+
+ std::string code = std::move(method_handler_table);
+ code += NLine(1);
+ code += attributes;
+ return code;
+}
+
+std::string DartStubGen::GenInterfaceMethodHandlers(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_METHOD_HANDLER_BASE, {
+ { "<METHOD_NAME>", d->GetID() },
+ { "<METHOD_HANDLER_PARCEL_READ>", GenMethodHandlerParcelRead(*d) },
+ { "<METHOD_HANDLER_INVOKE>", GenMethodHandlerInvoke(*d) },
+ { "<METHOD_HANDLER_PARCEL_WRITE>", GenMethodHandlerParcelWrite(*d) },
+ });
+ }
+
+ return RemoveLine(code);
+}
+
+std::string DartStubGen::GenMethodHandlerParcelRead(const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType()) {
+ code += "final " + ConvertTypeToString(type) + " " + p->GetID() +
+ " = " + ConvertTypeToString(type);
+ code += IsDelegateType(type) ? "(service._port, service);" : "();";
+ code += NLine(1);
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_READ, {
+ { "<NAME>", p->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += "final " + ConvertTypeToString(type) + " " + p->GetID() +
+ " = [];";
+ code += NLine(1);
+ code += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<NAME>", p->GetID() },
+ { "<PARCEL>" , "parcel" }
+ });
+ code += NLine(1);
+ } else {
+ code += "final " + ConvertTypeToString(type) + " ";
+ code += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcel" },
+ { "<NAME>", p->GetID() },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) }
+ });
+ code += NLine(1);
+ }
+ }
+
+ return code;
+}
+
+std::string DartStubGen::GenMethodHandlerInvoke(const Declaration& decl) {
+ std::string args;
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ if (!args.empty())
+ args += ", ";
+
+ args += p->GetID();
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType()) {
+ code += "final " + ConvertTypeToString(type) + " " + p->GetID() +
+ " = " + ConvertTypeToString(type) + "();";
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += "final " + ConvertTypeToString(type) + " " + p->GetID() +
+ " = [];";
+ code += NLine(1);
+ } else {
+ code += "final " + ConvertTypeToString(type) + " " + p->GetID() + ";";
+ code += NLine(1);
+ }
+ }
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC)
+ code += "final " + ConvertTypeToString(decl.GetType()) + " ret = await ";
+
+ code += ReplaceAll(CB_METHOD_HANDLER_INVOKE, {
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<ARGS>", args }
+ });
+ return code;
+}
+
+std::string DartStubGen::GenMethodHandlerParcelWrite(const Declaration& decl) {
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC)
+ return {};
+
+ std::string code = GenMethodHandlerResultParcelWrite(decl);
+ code += GenMethodHandlerOutParamParcelWrite(decl);
+ code = ReplaceAll(CB_METHOD_HANDLER_PARCEL_WRITE, "<PARCEL_WRITE>", code);
+ return code;
+}
+
+std::string DartStubGen::GenMethodHandlerResultParcelWrite(
+ const Declaration& decl) {
+ std::string code;
+ auto& type = decl.GetType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<NAME>", "ret" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<NAME>", "ret" }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>" , "ret" }
+ });
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+std::string DartStubGen::GenMethodHandlerOutParamParcelWrite(
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<NAME>", p->GetID() }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<NAME>", p->GetID() }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>" , p->GetID() }
+ });
+ code += NLine(1);
+ }
+ }
+
+ return code;
+}
+
+void DartStubGen::GenServiceBase(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_SERVICE_BASE, "<METHOD_DECLS>",
+ GenServiceBaseMethodDecls(iface))
+ .Transform([&](std::string str) {
+ return SmartIndent(RemoveLine(std::move(str)));
+ })
+ .Out(stream);
+}
+
+std::string DartStubGen::GenServiceBaseMethodDecls(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_METHOD_DECL, {
+ { "<RETURN_TYPE>", ConvertTypeToString(d->GetType()) },
+ { "<METHOD_NAME>", d->GetID() },
+ { "<METHOD_PARAMS>", GenMethodParams(*d) }
+ });
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+std::string DartStubGen::GenMethodParams(const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ if (!params.empty())
+ params += ", ";
+
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += ConvertTypeToString(type) + " " + p->GetID();
+ }
+
+ return params;
+}
+
+void DartStubGen::GenDelegateBase(std::ofstream& stream,
+ const Declaration& decl) {
+ std::string id = decl.GetID();
+ id[0] = ::tolower(id[0]);
+ ReplaceAll(CB_DELEGATE_BASE, {
+ { "<DELEGATE_NAME>", GetClassName(decl.GetID()) },
+ { "<DELEGATE_ID>", id },
+ { "<DELEGATE_PARAMS>", GenDelegateParams(decl) },
+ { "<DELEGATE_PARCEL_WRITE>", GenDelegateParcelWrite(decl) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+std::string DartStubGen::GenDelegateParams(const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ if (!params.empty())
+ params += ", ";
+
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += ConvertTypeToString(type) + " " + p->GetID();
+ }
+
+ return params;
+}
+
+std::string DartStubGen::GenDelegateParcelWrite(const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<NAME>", p->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<NAME>", p->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>", p->GetID() }
+ });
+ code += NLine(1);
+ }
+
+ auto private_sharing_code = GetPrivateSharingString(
+ type, "_port?", p->GetID());
+ if (!private_sharing_code.empty())
+ code += private_sharing_code + NLine(1);
+ }
+
+ return code;
+}
+
+} // namespace tidl
diff --git a/idlc/gen/dart_stub_gen.h b/idlc/gen/dart_stub_gen.h
new file mode 100644
index 0000000..682881c
--- /dev/null
+++ b/idlc/gen/dart_stub_gen.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_STUB_GEN_H_
+#define IDLC_GEN_DART_STUB_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/dart_gen_base.h"
+
+namespace tidl {
+
+class DartStubGen : public DartGeneratorBase {
+ public:
+ explicit DartStubGen(std::shared_ptr<Document> doc);
+ virtual ~DartStubGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ std::string GenInterfaceCtor(const Interface& iface);
+ std::string GenInterfaceMethodHandlers(const Interface& iface);
+ std::string GenMethodHandlerParcelRead(const Declaration& decl);
+ std::string GenMethodHandlerInvoke(const Declaration& decl);
+ std::string GenMethodHandlerParcelWrite(const Declaration& decl);
+ std::string GenMethodHandlerResultParcelWrite(const Declaration& decl);
+ std::string GenMethodHandlerOutParamParcelWrite(const Declaration& decl);
+ void GenServiceBase(std::ofstream& stream, const Interface& iface);
+ std::string GenServiceBaseMethodDecls(const Interface& iface);
+ std::string GenMethodParams(const Declaration& decl);
+ void GenDelegateBase(std::ofstream& stream, const Declaration& decl);
+ std::string GenDelegateParams(const Declaration& decl);
+ std::string GenDelegateParcelWrite(const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_STUB_GEN_H_
diff --git a/idlc/gen/dart_stub_gen_cb.h b/idlc/gen/dart_stub_gen_cb.h
new file mode 100644
index 0000000..730f8a8
--- /dev/null
+++ b/idlc/gen/dart_stub_gen_cb.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_STUB_GEN_CB_H_
+#define IDLC_GEN_DART_STUB_GEN_CB_H_
+
+namespace tidl {
+
+/**
+ * <METHOD_DECLS> The declarations of methods.
+ */
+constexpr const char CB_SERVICE_BASE[] =
+R"__dart_cb(
+/// Abstract class for creating a service base class for RPC.
+abstract class ServiceBase {
+ /// Constructor for this class.
+ ServiceBase(this.sender, this.instance);
+
+ /// The client application ID.
+ final String sender;
+
+ /// The client instance ID.
+ final String instance;
+
+ /// The delegate port of the client.
+ Port? _port;
+
+ /// Disconnects with the client application.
+ void disconnect() {
+ _port?.disconnect();
+ _port = null;
+ }
+
+ /// This abstract method will be called when the client is connected.
+ Future<void> onCreate();
+
+ /// This abstract method will be called when the client is disconnected.
+ Future<void> onTerminate();
+ <METHOD_DECLS>
+}
+)__dart_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the method.
+ * <METHOD_NAME> The name of the method.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_METHOD_DECL[] =
+R"__dart_cb(
+/// This abstract method will be called when the '<METHOD_NAME>' request is delivered.
+Future<<RETURN_TYPE>> on<METHOD_NAME>(<METHOD_PARAMS>);)__dart_cb";
+
+/**
+ * <DELEGATE_NAME> The name of the delegate.
+ * <DELEGATE_ID> The ID of the delegate.
+ * <DELEGATE_PARAMS> Parameters of the delegate.
+ * <DELEGATE_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ */
+constexpr const char CB_DELEGATE_BASE[] =
+R"__dart_cb(
+/// '<DELEGATE_NAME>' class to invoke the delegate method.
+class <DELEGATE_NAME> extends _Delegate {
+ /// Constructor for this class.
+ <DELEGATE_NAME>(this._port, this.service, {bool once = false})
+ : super(_DelegateId.<DELEGATE_ID>.id, once);
+
+ final Port? _port;
+
+ /// The client service.
+ ServiceBase service;
+ bool _wasInvoked = false;
+
+ /// Invokes the delegate method of the client.
+ Future<void> invoke(<DELEGATE_PARAMS>) async {
+ if (_port == null) {
+ throw StateError('Must be connected first');
+ }
+
+ if (once && _wasInvoked) {
+ throw Exception('Can be invoked only once');
+ }
+
+ final Parcel parcel = Parcel();
+ parcel.writeInt32(_MethodId.callback.id);
+ serialize(parcel);
+
+ <DELEGATE_PARCEL_WRITE>
+
+ if (_port != null) {
+ parcel.send(_port!);
+ }
+
+ _wasInvoked = true;
+ }
+}
+)__dart_cb";
+
+/**
+ * <INTERFACE_NAME> The name of the interface.
+ * <CTOR> The implementation of the constructor of the interface.
+ * <METHOD_HANDLERS> The implementation of the method handlers of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__dart_cb(
+/// This is used when creating a service instance.
+typedef ServiceBuilder = ServiceBase Function(String sender, String instance);
+
+typedef _MethodHandler = Future<void> Function(ServiceBase, Port, Parcel);
+
+/// [<INTERFACE_NAME>] class for RPC.
+class <INTERFACE_NAME> extends StubBase {
+ /// Constructor for this class.
+ <INTERFACE_NAME>({required ServiceBuilder serviceBuilder})
+ : _serviceBuilder = serviceBuilder,
+ super('<INTERFACE_NAME>') {
+ <CTOR>
+ }
+
+ /// The indexable collection of [ServiceBase] class.
+ final List<ServiceBase> services = <ServiceBase>[];
+ final Map<int, _MethodHandler> _methodHandlers = <int, _MethodHandler>{};
+ final ServiceBuilder _serviceBuilder;
+
+ @override
+ @visibleForOverriding
+ @nonVirtual
+ Future<void> onConnectedEvent(String sender, String instance) async {
+ final ServiceBase service = _serviceBuilder(sender, instance);
+ service._port = getPort(instance, PortType.callback);
+ await service.onCreate();
+ services.add(service);
+ }
+
+ @override
+ @visibleForOverriding
+ @nonVirtual
+ Future<void> onDisconnectedEvent(String sender, String instance) async {
+ for (final ServiceBase service in services) {
+ if (service.instance == instance) {
+ await service.onTerminate();
+ services.remove(service);
+ break;
+ }
+ }
+ }
+
+ <METHOD_HANDLERS>
+
+ @override
+ @visibleForOverriding
+ @nonVirtual
+ Future<void> onReceivedEvent(String sender, String instance,
+ Parcel parcel) async {
+ ServiceBase? service;
+ for (final ServiceBase s in services) {
+ if (s.instance == instance) {
+ service = s;
+ break;
+ }
+ }
+
+ if (service == null) {
+ return;
+ }
+
+ final Port port = getPort(instance, PortType.main);
+ final int cmd = parcel.readInt32();
+ if (_methodHandlers.containsKey(cmd)) {
+ await _methodHandlers[cmd]!(service, port, parcel);
+ }
+ }
+}
+)__dart_cb";
+
+/**
+ * <METHOD_ID> The ID of the method.
+ * <METHOD_NAME> The name of the method.
+ */
+constexpr const char CB_METHOD_HANDLER_TABLE[] =
+R"__dart_cb(_methodHandlers[_MethodId.<METHOD_ID>.id] = _on<METHOD_NAME>Method;)__dart_cb";
+
+/**
+ * <METHOD_NAME> The name of the method.
+ * <METHOD_HANDLER_PARCEL_READ> The implementation to read the arguments from the parcel.
+ * <METHOD_HANDLER_INVOKE> The implementation to invoke the method handle.
+ * <METHOD_HANDLER_PARCEL_WRITE> The implementation to write the result to the parcel.
+ * <METHOD_HANDLER_ARGS_FREE> The implementation to release arguments.
+ */
+constexpr const char CB_METHOD_HANDLER_BASE[] =
+R"__dart_cb(
+Future<void> _on<METHOD_NAME>Method(ServiceBase service, Port port,
+ Parcel parcel) async {
+ <METHOD_HANDLER_PARCEL_READ>
+ <METHOD_HANDLER_INVOKE>
+ <METHOD_HANDLER_PARCEL_WRITE>
+}
+)__dart_cb";
+
+/**
+ * <METHOD_NAME> The name of the method.
+ * <ARGS> The arguments of the method.
+ */
+constexpr const char CB_METHOD_HANDLER_INVOKE[] =
+R"__dart_cb(service.on<METHOD_NAME>(<ARGS>);)__dart_cb";
+
+/**
+ * <PARCEL_WRITE> The implementation to write the result to the parcel.
+ */
+constexpr const char CB_METHOD_HANDLER_PARCEL_WRITE[] =
+R"__dart_cb(
+final Parcel result = Parcel();
+final ParcelHeader header = parcel.header;
+final ParcelHeader resultHeader = result.header;
+resultHeader.tag = _tidlVersion;
+resultHeader.sequenceNumber = header.sequenceNumber;
+
+result.writeInt32(_MethodId.result.id);
+<PARCEL_WRITE>
+
+result.send(port);
+)__dart_cb";
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_STUB_GEN_CB_H_
diff --git a/idlc/gen/generator.cc b/idlc/gen/generator.cc
index 2f04cf0..d965ba9 100644
--- a/idlc/gen/generator.cc
+++ b/idlc/gen/generator.cc
@@ -24,16 +24,29 @@
#include "idlc/ast/attribute.h"
namespace tidl {
+namespace {
+
+#if (defined(_WIN32) || defined(__WIN32__))
+constexpr const char kDelim[] = "\\";
+#else
+constexpr const char kDelim[] = "/";
+#endif
+
+} // namespace
Generator::Generator(std::shared_ptr<Document> doc) : doc_(doc) {}
-void Generator::Run(const std::string& file_name) {
+void Generator::Run(const std::string& file_name, bool divide_interface) {
FileName = file_name;
- out_file_.open(FileName);
-
- OnInitGen(out_file_);
- OnFiniGen(out_file_);
- out_file_.close();
+ if (!divide_interface) {
+ out_file_.open(FileName);
+ OnInitGen(out_file_);
+ OnFiniGen(out_file_);
+ out_file_.close();
+ } else {
+ OnInitGen(out_file_);
+ OnFiniGen(out_file_);
+ }
}
std::string Generator::AddIndent(int indent, std::string lines, bool space) {
@@ -60,7 +73,7 @@ std::string Generator::AddIndent(int indent, std::string lines, bool space) {
std::string Generator::GetFileNamespace() const {
std::string key1(".");
- std::string key2("/");
+ std::string key2(kDelim);
std::size_t p2 = FileName.rfind(key1);
std::size_t p1 = FileName.rfind(key2);
@@ -74,17 +87,6 @@ std::string Generator::GetFileNamespace() const {
return FileName.substr(p1, p2 - p1);
}
-std::string Generator::ReplaceAll(std::string str,
- const std::string& from,
- const std::string& to) {
- std::size_t pos = 0;
- while ((pos = str.find(from, pos)) != std::string::npos) {
- str.replace(pos, from.length(), to);
- pos += to.length();
- }
- return str;
-}
-
bool Generator::IsDelegateType(const BaseType& type) {
for (auto& i : GetDocument().GetBlocks()) {
if (i->GetType() != Block::TYPE_INTERFACE)
@@ -100,7 +102,7 @@ bool Generator::IsDelegateType(const BaseType& type) {
bool Generator::IsDelegateType(const Interface& inf,
const BaseType& type) {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
+ for (const auto& i : inf.GetDeclarations()) {
if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
continue;
if (i->GetID() == type.ToString())
@@ -109,4 +111,17 @@ bool Generator::IsDelegateType(const Interface& inf,
return false;
}
+std::string Generator::GetInterfaceNameFromDelegate(const BaseType& type) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*i);
+ if (IsDelegateType(iface, type))
+ return iface.GetID();
+ }
+
+ return {};
+}
+
} // namespace tidl
diff --git a/idlc/gen/generator.h b/idlc/gen/generator.h
index 249b594..9355de3 100644
--- a/idlc/gen/generator.h
+++ b/idlc/gen/generator.h
@@ -26,21 +26,27 @@
#include "idlc/ast/document.h"
#include "idlc/ast/parameter.h"
#include "idlc/ast/type.h"
+#include "idlc/gen/replace_all.h"
namespace tidl {
class Generator {
public:
+ enum ChannelType {
+ TYPE_UNKNOWN = 0,
+ TYPE_PROXY,
+ TYPE_STUB,
+ TYPE_GROUP
+ };
explicit Generator(std::shared_ptr<Document> doc);
virtual ~Generator() = default;
- void Run(const std::string& file_name);
+ void Run(const std::string& file_name, bool divide_interface = false);
std::string AddIndent(int indent, std::string lines, bool space = true);
std::string GetFileNamespace() const;
- std::string ReplaceAll(std::string str,
- const std::string& from, const std::string& to);
bool IsDelegateType(const Interface& inf, const BaseType& type);
bool IsDelegateType(const BaseType& type);
+ std::string GetInterfaceNameFromDelegate(const BaseType& type);
void EnableNamespace(bool enable) {
hasNamespace_ = enable;
@@ -50,6 +56,30 @@ class Generator {
return hasNamespace_;
}
+ void EnableProxy(bool enable) {
+ isProxy_ = enable;
+ }
+
+ bool IsProxy() const {
+ return isProxy_;
+ }
+
+ void EnableGeneratedAPI(bool enable) {
+ isGenAPI_ = enable;
+ }
+
+ bool IsGeneratedAPI() {
+ return isGenAPI_;
+ }
+
+ void SetChannelType(ChannelType type) {
+ type_ = type;
+ }
+
+ int GetChannelType() const {
+ return type_;
+ }
+
template<typename T, typename ...ARGS>
void GenTemplate(std::string templ, std::ofstream& stream,
T cb, ARGS... args) {
@@ -113,6 +143,9 @@ class Generator {
std::shared_ptr<Document> doc_;
std::ofstream out_file_;
bool hasNamespace_ = true;
+ bool isProxy_ = true;
+ bool isGenAPI_ = false;
+ ChannelType type_ = TYPE_UNKNOWN;
};
} // namespace tidl
diff --git a/idlc/gen/replace_all.cc b/idlc/gen/replace_all.cc
new file mode 100644
index 0000000..b1f3a12
--- /dev/null
+++ b/idlc/gen/replace_all.cc
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <algorithm>
+#include <sstream>
+
+#include "idlc/gen/replace_all.h"
+
+namespace tidl {
+
+ReplaceAll::ReplaceAll(std::string str) : str_(std::move(str)) {}
+
+ReplaceAll::ReplaceAll(std::string str, const std::string& from,
+ const std::string& to) : str_(std::move(str)) {
+ Change(from, to);
+}
+
+ReplaceAll::ReplaceAll(std::string str,
+ std::initializer_list<std::pair<std::string, std::string>> list)
+ : str_(std::move(str)) {
+ for (const auto& i : list)
+ Change(i.first, i.second);
+}
+
+ReplaceAll::operator const char*() const {
+ return str_.c_str();
+}
+
+ReplaceAll& ReplaceAll::Change(const std::string& from,
+ const std::string& to) {
+ std::size_t pos = 0;
+ while ((pos = str_.find(from, pos)) != std::string::npos) {
+ str_.replace(pos, from.length(), to);
+ pos += to.length();
+ }
+
+ return *this;
+}
+
+ReplaceAll& ReplaceAll::Remove(const std::string& tag, bool remove) {
+ const auto from = "<" + tag + "?>";
+ const auto to = "</" + tag + "?>";
+ auto pos1 = str_.find(from, 0);
+ auto pos2 = str_.find(to, pos1);
+
+ if (pos1 == std::string::npos || pos2 == std::string::npos)
+ return *this;
+
+ if (!remove) {
+ str_.erase(pos2, to.length());
+ str_.erase(pos1, from.length());
+ } else {
+ str_.erase(pos1, pos2 - pos1 + to.length());
+ }
+
+ return *this;
+}
+
+ReplaceAll& ReplaceAll::ChangeToUpper(const std::string& from,
+ const std::string& to) {
+ return Change(from, [to]() {
+ std::string t = to;
+ std::transform(t.begin(), t.end(), t.begin(), ::toupper);
+ return t;
+ });
+}
+
+ReplaceAll& ReplaceAll::ChangeToLower(const std::string& from,
+ const std::string& to) {
+ return Change(from, [to]() {
+ std::string t = to;
+ std::transform(t.begin(), t.end(), t.begin(), ::tolower);
+ return t;
+ });
+}
+
+ReplaceAll& ReplaceAll::Once(const std::string& from,
+ const std::string& to) {
+ std::size_t pos = 0;
+ if ((pos = str_.find(from, pos)) != std::string::npos) {
+ str_.replace(pos, from.length(), to);
+ }
+
+ return *this;
+}
+
+void ReplaceAll::Out(std::ofstream& stream) {
+ stream << str_;
+}
+
+ReplaceAll& ReplaceAll::AddIndent(int indent, bool space) {
+ std::stringstream ss(str_);
+ std::string result;
+ std::string to;
+
+ while (std::getline(ss, to, '\n')) {
+ if (to.length() > 0) {
+ for (int i = 0; i < indent; i++) {
+ if (space)
+ result += " ";
+ else
+ result += "\t";
+ }
+ }
+
+ result += to;
+ result += "\n";
+ }
+
+ str_ = result;
+ return *this;
+}
+
+} // namespace tidl
diff --git a/idlc/gen/replace_all.h b/idlc/gen/replace_all.h
new file mode 100755
index 0000000..ce0fc05
--- /dev/null
+++ b/idlc/gen/replace_all.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_REPLACE_ALL_H_
+#define IDLC_REPLACE_ALL_H_
+
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace tidl {
+
+class ReplaceAll {
+ public:
+ ReplaceAll(std::string str);
+ ReplaceAll(std::string str, const std::string& from,
+ const std::string& to);
+ ReplaceAll(std::string str,
+ std::initializer_list<std::pair<std::string, std::string>> list);
+
+ operator const char*() const;
+
+ // Deprecated. Please use 'Replace'
+ ReplaceAll& Change(const std::string& from, const std::string& to);
+
+ ReplaceAll& Remove(const std::string& tag, bool remove);
+
+ ReplaceAll& Replace(const std::string& from, const std::string& to) {
+ return Change("<" + from + ">", to);
+ }
+
+ template <class T, class F>
+ ReplaceAll& Repeat(const std::string& tag, const T& container, F fn) {
+ const auto from = "<" + tag + "*>";
+ const auto to = "</" + tag + "*>";
+ auto pos1 = str_.find(from, 0);
+ auto pos2 = str_.find(to, pos1);
+ auto pos3 = str_.rfind('\n', pos1);
+ auto space = pos1 - pos3 - 1;
+ std::string space_str(space, ' ');
+
+ if (pos1 == std::string::npos || pos2 == std::string::npos)
+ return *this;
+
+ std::string str = str_.substr(pos1 + from.length(),
+ pos2 - pos1 - from.length());
+
+ std::string ret;
+ for (const auto& i : container) {
+ ReplaceAll rep(str);
+ if (fn(&rep, i)) {
+ if (!ret.empty())
+ ret += "\n" + space_str;
+ ret += rep;
+ }
+ }
+
+ str_.replace(pos1, pos2 - pos1 + to.length(), ret);
+ return *this;
+ }
+
+ // Deprecated. Please use 'Replace'
+ template <class T>
+ ReplaceAll& Change(const std::string& from, T t) {
+ std::string str(t());
+ return Change(from, str);
+ }
+
+ template <class T>
+ ReplaceAll& Replace(const std::string& from, T t) {
+ std::string str(t());
+ return Replace(from, str);
+ }
+
+ ReplaceAll& ChangeToUpper(const std::string& from, const std::string& to);
+ ReplaceAll& ChangeToLower(const std::string& from, const std::string& to);
+ ReplaceAll& Once(const std::string& from, const std::string& to);
+
+ template <class T>
+ ReplaceAll& Once(const std::string& from, T t) {
+ std::string str(t());
+ return Once(from, str);
+ }
+
+ template <class T>
+ ReplaceAll& Select(std::string str, std::vector<std::string> strs, T t) {
+ int idx = t();
+ return Change(str, strs[idx]);
+ }
+
+ template <class T>
+ ReplaceAll& Transform(T t) {
+ std::string str(t(str_));
+ str_ = str;
+ return *this;
+ }
+
+ ReplaceAll& AddIndent(int indent, bool space = true);
+ void Out(std::ofstream& stream);
+
+ private:
+ std::string str_;
+};
+
+class Inject {
+ public:
+ template <class T>
+ explicit Inject(T t) {
+ str_ = t();
+ }
+
+ operator std::string() const {
+ return str_;
+ }
+
+ private:
+ std::string str_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_REPLACE_ALL_H_
diff --git a/idlc/gen/version2/c_body_generator_array_base_cb.hh b/idlc/gen/version2/c_body_generator_array_base_cb.hh
new file mode 100644
index 0000000..20d1e71
--- /dev/null
+++ b/idlc/gen/version2/c_body_generator_array_base_cb.hh
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_BODY_GENERATOR_ARRAY_BASE_CB_HH_
+#define IDLC_GEN_VERSION2_C_BODY_GENERATOR_ARRAY_BASE_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <PREFIX> The prefix of the array structure.
+ * <NAME> The name of the array structure.
+ * <ELEMENT_TYPE> The type of the element of the array.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ <ELEMENT_TYPE>*value;
+ int size;
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the array structure.
+ * <NAME> The name of the array structure.
+ * <UNIT_MAP_WRITE> The implementation to write the value to the unit map.
+ * <UNIT_MAP_READ> The implemention to read the value from the unit map.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ * <ELEMENT_TYPE> The type of the element of the array.
+ * <ELEMENT_TYPE_SIZE> The size of the type of the element.
+ * <ELEMENTS_FREE> The implementation to release elements.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_t *handle = data;
+ rpc_port_unit_map_h map;
+ char index[12];
+ int i;
+
+ if (parcel == nullptr || handle == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_unit_map_write_int(map, "size", handle->size);
+
+ for (i = 0; i < handle->size; ++i) {
+ snprintf(index, sizeof(index), "%d", i);
+ <UNIT_MAP_WRITE>
+ }
+
+ rpc_port_parcel_write(parcel, &map->parcelable, map);
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_t *handle = data;
+ rpc_port_unit_map_h map;
+ char index[12];
+ int i;
+
+ if (parcel == nullptr || handle == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_parcel_read(parcel, &map->parcelable, map);
+ rpc_port_unit_map_read_int(map, "size", &handle->size);
+
+ handle->value = calloc(handle->size, sizeof(<ELEMENT_TYPE_SIZE>));
+ if (handle->value == nullptr) {
+ _E("Out of memory");
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ for (i = 0; i < handle->size; ++i) {
+ snprintf(index, sizeof(index), "%d", i);
+ <UNIT_MAP_READ>
+ }
+
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_from;
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+
+ if (handle == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ <ELEMENTS_FREE>
+
+ free(handle);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ rpc_port_unit_map_h map;
+ int ret;
+
+ if (handle == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = rpc_port_unit_map_write_<NAME>(map, "clone", handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to write <NAME>. error(%d)", ret);
+ rpc_port_unit_map_destroy(map);
+ return ret;
+ }
+
+ rpc_port_unit_map_read_<NAME>(map, "clone", clone);
+ rpc_port_unit_map_destroy(map);
+
+ return ret;
+}
+
+int <PREFIX>_<NAME>_set(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>*value, int size)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ <PREFIX>_<NAME>_t *temp;
+ <PREFIX>_<NAME>_t *clone;
+ int ret;
+
+ if (handle == nullptr || value == nullptr || size <= 0) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_create((<PREFIX>_<NAME>_h *)&temp);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ temp->value = (<ELEMENT_TYPE>*)value;
+ temp->size = size;
+
+ ret = <PREFIX>_<NAME>_clone(handle, (<PREFIX>_<NAME>_h *)&clone);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ temp->value = nullptr;
+ temp->size = 0;
+ <PREFIX>_<NAME>_destroy(temp);
+ return ret;
+ }
+
+ temp->value = handle->value;
+ temp->size = handle->size;
+ <PREFIX>_<NAME>_destroy(temp);
+
+ handle->value = clone->value;
+ handle->size = clone->size;
+
+ clone->value = nullptr;
+ clone->size = 0;
+ <PREFIX>_<NAME>_destroy(clone);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_get(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>*value, int *size)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ <PREFIX>_<NAME>_t *temp;;
+ int ret;
+
+ if (handle == nullptr || value == nullptr || size == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_clone(handle, (<PREFIX>_<NAME>_h *)&temp);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ return ret;
+ }
+
+ *value = temp->value;
+ *size = temp->size;
+
+ temp->value = nullptr;
+ temp->size = 0;
+ <PREFIX>_<NAME>_destroy(temp);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the element.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_USER_DEFINED_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<TYPE_NAME>(map, index, handle->value[i]);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_ENUM_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_int(map, index, (int)handle->value[i]);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BUNDLE_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_bundle(map, index, handle->value[i]);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_STRING_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_string(map, index, STRING_GET(handle->value[i]));
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the element.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<TYPE_NAME>(map, index, handle->value[i]);
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the element.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_USER_DEFINED_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_<TYPE_NAME>(map, index, &handle->value[i]);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_ENUM_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_int(map, index, (int *)&handle->value[i]);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BUNDLE_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_bundle(map, index, &handle->value[i]);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_STRING_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_string(map, index, &handle->value[i]);
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type of the parcel of the value.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_<TYPE_NAME>(map, index, &handle->value[i]);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_USER_DEFINED_FREE[] =
+R"__c_cb(
+if (handle->value) {
+ for (int i = 0; i < handle->size; ++i) {
+ if (handle->value[i])
+ <PREFIX>_<NAME>_destroy(handle->value[i]);
+ }
+
+ free(handle->value);
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BUNDLE_FREE[] =
+R"__c_cb(
+if (handle->value) {
+ for (int i = 0; i < handle->size; ++i) {
+ if (handle->value[i])
+ bundle_free(handle->value[i]);
+ }
+
+ free(handle->value);
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_STRING_FREE[] =
+R"__c_cb(
+if (handle->value) {
+ for (int i = 0; i < handle->size; ++i) {
+ if (handle->value[i])
+ free(handle->value[i]);
+ }
+
+ free(handle->value);
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BASE_FREE[] =
+R"__c_cb(
+if (handle->value)
+ free(handle->value);
+)__c_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_BODY_GENERATOR_ARRAY_BASE_CB_HH_
diff --git a/idlc/gen/version2/c_body_generator_base.cc b/idlc/gen/version2/c_body_generator_base.cc
new file mode 100644
index 0000000..2d6fe7c
--- /dev/null
+++ b/idlc/gen/version2/c_body_generator_base.cc
@@ -0,0 +1,1511 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/c_body_generator_base.hh"
+
+#include <string.h>
+
+#include <utility>
+
+#include "idlc/gen/version2/c_body_generator_array_base_cb.hh"
+#include "idlc/gen/version2/c_body_generator_base_cb.hh"
+#include "idlc/gen/version2/c_body_generator_list_base_cb.hh"
+#include "idlc/gen/version2/c_body_generator_map_base_cb.hh"
+#include "idlc/gen/version2/c_body_generator_set_base_cb.hh"
+
+namespace tidl {
+namespace version2 {
+namespace {
+
+constexpr const char PREFIX_RPC_PORT_PROXY[] = "rpc_port_proxy";
+constexpr const char PREFIX_RPC_PORT_STUB[] = "rpc_port_stub";
+
+bool IsPtrType(const BaseType& type) {
+ if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr ||
+ type.ToString() == "string" ||
+ type.ToString() == "bundle" ||
+ type.ToString() == "file")
+ return true;
+
+ return false;
+}
+
+std::string GetBaseTypeName(const std::shared_ptr<Structure>& base) {
+ if (base->GetBase() != nullptr)
+ return GetBaseTypeName(base->GetBase()) + "::" + base->GetID();
+
+ return base->GetID();
+}
+
+void GetElementsFromStructure(Elements* elms,
+ const std::shared_ptr<Structure>& base) {
+ if (base->GetBase() != nullptr)
+ GetElementsFromStructure(elms, base->GetBase());
+
+ for (auto elm : base->GetElements())
+ elms->Add(elm);
+}
+
+Elements GetElements(const Structure& st) {
+ Elements elms;
+ if (st.GetBase() != nullptr)
+ GetElementsFromStructure(&elms, st.GetBase());
+
+ for (auto elm : st.GetElements())
+ elms.Add(elm);
+
+ return elms;
+}
+
+} // namespace
+
+CBodyGeneratorBase::CBodyGeneratorBase(std::shared_ptr<Document> doc)
+ : tidl::CBodyGeneratorBase(std::move(doc)) {
+ for (auto& iter : GetDocument().GetBlocks()) {
+ if (iter->GetType() != Block::TYPE_INTERFACE) {
+ const auto& st = static_cast<const Structure&>(*iter);
+ AddTypeName(st);
+ continue;
+ }
+
+ const auto& iface = static_cast<const Interface&>(*iter);
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() == Declaration::MethodType::DELEGATE) {
+ has_delegate_ = true;
+ break;
+ }
+ }
+ if (has_delegate_)
+ break;
+ }
+}
+
+void CBodyGeneratorBase::AddTypeName(const Structure& st) {
+ std::string name = st.GetID();
+ std::string type_name;
+ if (st.GetBase() != nullptr)
+ type_name = GetBaseTypeName(st.GetBase()) + "::" + name;
+ else
+ type_name = name;
+
+ struct_types_[std::move(name)] = std::move(type_name);
+}
+
+void CBodyGeneratorBase::GenIncludeLemHeaders(std::ofstream& stream) {
+ stream << SmartIndent(CB_LEM_HEADER);
+}
+
+void CBodyGeneratorBase::GenStructureDefinition(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructureBaseDefinition(stream, st);
+ }
+ }
+
+ for (auto& i : GetStructures()) {
+ auto& st = *i.second;
+ if (st.GetID().compare(0, strlen("array"), "array") == 0)
+ GenStructureArrayBaseDefinition(stream, st);
+ else if (st.GetID().compare(0, strlen("list"), "list") == 0)
+ GenStructureListBaseDefinition(stream, st);
+ else if (st.GetID().compare(0, strlen("map"), "map") == 0)
+ GenStructureMapBaseDefinition(stream, st);
+ else if (st.GetID().compare(0, strlen("set"), "set") == 0)
+ GenStructureSetBaseDefinition(stream, st);
+ else
+ GenStructureBaseDefinition(stream, st);
+ }
+}
+
+bool CBodyGeneratorBase::HasDelegate() {
+ return has_delegate_;
+}
+
+std::string CBodyGeneratorBase::GetHandlePrefixReverse() {
+ std::string prefix =
+ IsProxy() ? PREFIX_RPC_PORT_STUB : PREFIX_RPC_PORT_PROXY;
+ if (!HasNamespace())
+ return prefix;
+
+ return prefix + "_" + GetFileNamespace();
+}
+
+void CBodyGeneratorBase::GenStructureArrayBaseDefinition(std::ofstream& stream,
+ const Structure& st) {
+ auto& elm = *(st.GetElements().begin());
+ auto& type = elm->GetType();
+ std::string element_type = GetDataTypeString(type, false);
+
+ ReplaceAll(CB_STRUCTURE_ARRAY_DEF)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Change("<ELEMENT_TYPE>", element_type)
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CBodyGeneratorBase::GenStructureListBaseDefinition(std::ofstream& stream,
+ const Structure& st) {
+ ReplaceAll(CB_STRUCTURE_LIST_DEF)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CBodyGeneratorBase::GenStructureMapBaseDefinition(std::ofstream& stream,
+ const Structure& st) {
+ ReplaceAll(CB_STRUCTURE_MAP_DEF)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CBodyGeneratorBase::GenStructureSetBaseDefinition(std::ofstream& stream,
+ const Structure& st) {
+ ReplaceAll(CB_STRUCTURE_SET_DEF)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+std::string CBodyGeneratorBase::GenBaseElements(const Elements& elms,
+ const std::string& id) {
+ std::string code;
+ for (const auto& elm : elms) {
+ auto& type = elm->GetType();
+ auto param_type = GetDataTypeString(type, false, id);
+ code += param_type + elm->GetID() + ";";
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+void CBodyGeneratorBase::GenStructureBaseDefinition(std::ofstream& stream,
+ const Structure& st) {
+ auto elms = GetElements(st);
+ ReplaceAll(CB_STRUCTURE_BASE_DEF, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", st.GetID() },
+ { "<ELEMENTS>", GenBaseElements(elms, st.GetID()) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+void CBodyGeneratorBase::GenStructure(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructureBase(stream, st);
+ }
+ }
+
+ for (auto& i : GetStructures()) {
+ auto& st = *i.second;
+ if (st.GetID().compare(0, strlen("array"), "array") == 0)
+ GenStructureArrayBase(stream, st);
+ else if (st.GetID().compare(0, strlen("list"), "list") == 0)
+ GenStructureListBase(stream, st);
+ else if (st.GetID().compare(0, strlen("map"), "map") == 0)
+ GenStructureMapBase(stream, st);
+ else if (st.GetID().compare(0, strlen("set"), "set") == 0)
+ GenStructureSetBase(stream, st);
+ else
+ GenStructureBase(stream, st);
+ }
+}
+
+std::string CBodyGeneratorBase::GenArrayUnitMapWrite(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code = CB_STRUCTURE_ARRAY_ENUM_UNIT_MAP_WRITE;
+ } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_USER_DEFINED_UNIT_MAP_WRITE)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_ARRAY_BUNDLE_UNIT_MAP_WRITE);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_ARRAY_STRING_UNIT_MAP_WRITE);
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_BASE_UNIT_MAP_WRITE)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenArrayUnitMapRead(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code = CB_STRUCTURE_ARRAY_ENUM_UNIT_MAP_READ;
+ } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_USER_DEFINED_UNIT_MAP_READ)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_ARRAY_BUNDLE_UNIT_MAP_READ);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_ARRAY_STRING_UNIT_MAP_READ);
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_BASE_UNIT_MAP_READ)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenArrayElementsFree(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code = CB_STRUCTURE_ARRAY_BASE_FREE;
+ } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_USER_DEFINED_FREE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_ARRAY_BUNDLE_FREE);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_ARRAY_STRING_FREE);
+ } else {
+ code = std::string(CB_STRUCTURE_ARRAY_BASE_FREE);
+ }
+
+ return RemoveLine(code);
+}
+
+void CBodyGeneratorBase::GenStructureArrayBase(std::ofstream& stream,
+ const Structure& st) {
+ auto& elm = *(st.GetElements().begin());
+ auto& type = elm->GetType();
+
+ auto element_type = GetDataTypeString(type, false);
+ auto param_type_in = GetParamTypeString(ParameterType::Direction::IN, type);
+ auto param_type_out = GetParamTypeString(ParameterType::Direction::OUT, type);
+ auto element_type_size = element_type;
+
+ element_type_size = RemoveLastSpaces(element_type_size);
+
+ ReplaceAll(CB_STRUCTURE_ARRAY_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Change("<UNIT_MAP_WRITE>", GenArrayUnitMapWrite(elm))
+ .Change("<UNIT_MAP_READ>", GenArrayUnitMapRead(elm))
+ .Change("<PARAM_TYPE_IN>", param_type_in)
+ .Change("<PARAM_TYPE_OUT>", param_type_out)
+ .Change("<ELEMENT_TYPE>", element_type)
+ .Change("<ELEMENT_TYPE_SIZE>", element_type_size)
+ .Change("<ELEMENTS_FREE>", GenArrayElementsFree(elm))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+std::string CBodyGeneratorBase::GenListDataFree(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code = CB_STRUCTURE_LIST_BASE_FREE;
+ } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_FREE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_FREE);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_FREE);
+ } else {
+ code = std::string(CB_STRUCTURE_LIST_BASE_FREE);
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenListUnitMapWrite(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code = CB_STRUCTURE_LIST_ENUM_UNIT_MAP_WRITE;
+ } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_UNIT_MAP_WRITE)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_UNIT_MAP_WRITE);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_UNIT_MAP_WRITE);
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_LIST_BASE_UNIT_MAP_WRITE)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenListUnitMapRead(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code = ReplaceAll(CB_STRUCTURE_LIST_ENUM_UNIT_MAP_READ)
+ .Change("<VALUE_TYPE>",
+ RemoveLastSpaces(
+ GetParamTypeString(ParameterType::Direction::IN, type,
+ GetEnumBockString(type.ToString()))));
+ } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_UNIT_MAP_READ)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_UNIT_MAP_READ);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_UNIT_MAP_READ);
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_LIST_BASE_UNIT_MAP_READ)
+ .Change("<VALUE_TYPE>",
+ RemoveLastSpaces(
+ GetParamTypeString(ParameterType::Direction::IN, type)))
+ .Change("<TYPE_NAME>", GetFullNameFromType(type));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenListAdd(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code = ReplaceAll(CB_STRUCTURE_LIST_ENUM_ADD)
+ .Change("<VALUE_TYPE>",
+ RemoveLastSpaces(
+ GetParamTypeString(ParameterType::Direction::IN, type,
+ GetEnumBockString(type.ToString()))));
+ } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_ADD)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_ADD);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_ADD);
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_LIST_BASE_ADD)
+ .Change("<VALUE_TYPE>",
+ GetParamTypeString(ParameterType::Direction::IN, type));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenListCallbackParamType(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (IsPtrType(type))
+ code = std::string("value");
+ else
+ code = std::string("*value");
+
+ return code;
+}
+
+void CBodyGeneratorBase::GenStructureListBase(std::ofstream& stream,
+ const Structure& st) {
+ auto& elm = *(st.GetElements().begin());
+ auto& type = elm->GetType();
+ auto data_type = GetDataTypeString(type, true);
+ auto param_type = GetParamTypeString(ParameterType::Direction::IN, type);
+
+ ReplaceAll(CB_STRUCTURE_LIST_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Change("<DATA_TYPE>", data_type)
+ .Change("<DATA_FREE>", GenListDataFree(elm))
+ .Change("<PARAM_TYPE_IN>", param_type)
+ .Change("<UNIT_MAP_WRITE>", GenListUnitMapWrite(elm))
+ .Change("<UNIT_MAP_READ>", GenListUnitMapRead(elm))
+ .Change("<LIST_ADD>", GenListAdd(elm))
+ .Change("<CALLBACK_PARAM_TYPE>", GenListCallbackParamType(elm))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+std::string CBodyGeneratorBase::GenMapContains(const BaseType& key_type) {
+ std::string code;
+ if (IsPtrType(key_type))
+ code = CB_MAP_CONTAINS_KEY_PTR_TYPE;
+ else
+ code = CB_MAP_CONTAINS_KEY_BASE_TYPE;
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenMapKeyExistNullCheck(
+ const BaseType& key_type) {
+ std::string code;
+ if (IsPtrType(key_type))
+ code = CB_MAP_HANDLE_KEY_EXIST_NULL_CHECK;
+ else
+ code = CB_MAP_HANDLE_EXIST_NULL_CHECK;
+
+ return code;
+}
+
+std::string CBodyGeneratorBase::GenMapForeachVarsDefinition(
+ const BaseType& key_type, const BaseType& value_type) {
+ std::string code;
+ bool is_key_ptr = IsPtrType(key_type);
+ bool is_value_ptr = IsPtrType(value_type);
+ if (is_key_ptr && is_value_ptr)
+ code = CB_MAP_FOREACH_VARS_DEF_KEY_PTR_VALUE_PTR_TYPE;
+ else if (is_key_ptr && !is_value_ptr)
+ code = CB_MAP_FOREACH_VARS_DEF_KEY_PTR_VALUE_BASE_TYPE;
+ else if (!is_key_ptr && is_value_ptr)
+ code = CB_MAP_FOREACH_VARS_DEF_KEY_BASE_VALUE_PTR_TYPE;
+ else
+ code = CB_MAP_FOREACH_VARS_DEF_KEY_BASE_VALUE_BASE_TYPE;
+
+ code = ReplaceAll(code)
+ .Change("<KEY_TYPE>",
+ RemoveLastSpaces(GetDataTypeString(key_type, false)))
+ .Change("<VALUE_TYPE>",
+ RemoveLastSpaces(GetDataTypeString(value_type, false)));
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenMapErase(const BaseType& key_type) {
+ std::string code;
+ if (IsPtrType(key_type))
+ code = CB_MAP_ERASE_KEY_PTR_TYPE;
+ else
+ code = CB_MAP_ERASE_KEY_BASE_TYPE;
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenMapKeyNullCheck(
+ const BaseType& key_type) {
+ std::string code;
+ if (IsPtrType(key_type))
+ code = CB_MAP_HANDLE_KEY_NULL_CHECK;
+ else
+ code = CB_MAP_HANDLE_NULL_CHECK;
+
+ return code;
+}
+
+std::string CBodyGeneratorBase::GenMapLookupValueSet(
+ const BaseType& value_type) {
+ std::string code;
+ if (value_type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ value_type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ value_type.GetMetaType() != nullptr ||
+ value_type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_MAP_LOOKUP_VALUE_USER_DEFINED_SET)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", value_type.GetFullName(true));
+ } else if (value_type.ToString() == "bundle") {
+ code = CB_MAP_LOOKUP_VALUE_BUNDLE_SET;
+ } else if (value_type.ToString() == "string") {
+ code = CB_MAP_LOOKUP_VALUE_STRING_SET;
+ } else {
+ code = ReplaceAll(CB_MAP_LOOKUP_VALUE_BASE_SET)
+ .Change("<VALUE_TYPE>",
+ RemoveLastSpaces(GetDataTypeString(value_type, false)));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenMapLookup(
+ const BaseType& key_type, const BaseType& value_type) {
+ std::string code;
+ if (IsPtrType(key_type)) {
+ code = ReplaceAll(CB_MAP_LOOKUP_KEY_PTR_TYPE)
+ .Change("<MAP_LOOKUP_VALUE_SET>", GenMapLookupValueSet(value_type));
+ } else {
+ code = ReplaceAll(CB_MAP_LOOKUP_KEY_BASE_TYPE)
+ .Change("<MAP_LOOKUP_VALUE_SET>", GenMapLookupValueSet(value_type));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenMapKeyValueNullCheck(
+ const BaseType& key_type) {
+ std::string code;
+ if (IsPtrType(key_type))
+ code = CB_MAP_HANDLE_KEY_VALUE_NULL_CHECK;
+ else
+ code = CB_MAP_HANDLE_VALUE_NULL_CHECK;
+
+ return code;
+}
+
+std::string CBodyGeneratorBase::GenMapInsertNewKeyFree(
+ const BaseType& key_type) {
+ std::string code;
+ if (key_type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ key_type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ key_type.GetMetaType() != nullptr ||
+ key_type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_MAP_INSERT_NEW_KEY_USER_DEFINED_FREE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", key_type.GetFullName(true));
+ } else if (key_type.ToString() == "bundle") {
+ code = CB_MAP_INSERT_NEW_KEY_BUNDLE_FREE;
+ } else if (key_type.ToString() == "string" || key_type.ToString() == "file") {
+ code = CB_MAP_INSERT_NEW_KEY_STRING_FREE;
+ } else {
+ code = CB_MAP_INSERT_NEW_KEY_BASE_FREE;
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenMapInsertNewValueImpl(
+ const BaseType& key_type, const BaseType& value_type) {
+ std::string code;
+ if (value_type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ value_type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ value_type.GetMetaType() != nullptr ||
+ value_type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_MAP_INSERT_NEW_VALUE_USER_DEFINED_IMPL)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", value_type.GetFullName(true));
+ } else if (value_type.ToString() == "bundle") {
+ code = CB_MAP_INSERT_NEW_VALUE_BUNDLE_IMPL;
+ } else if (value_type.ToString() == "string" ||
+ value_type.ToString() == "file") {
+ code = CB_MAP_INSERT_NEW_VALUE_STRING_IMPL;
+ } else {
+ code = ReplaceAll(CB_MAP_INSERT_NEW_VALUE_BASE_IMPL)
+ .Change("<VALUE_TYPE>",
+ RemoveLastSpaces(GetDataTypeString(value_type, false)));
+ }
+
+ code = ReplaceAll(code)
+ .Change("<MAP_INSERT_NEW_KEY_FREE>", GenMapInsertNewKeyFree(key_type));
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenMapInsertNewKeyImpl(
+ const BaseType& key_type) {
+ std::string code;
+ if (key_type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ key_type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ key_type.GetMetaType() != nullptr ||
+ key_type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_MAP_INSERT_NEW_KEY_USER_DEFINED_IMPL)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", key_type.GetFullName(true));
+ } else if (key_type.ToString() == "bundle") {
+ code = CB_MAP_INSERT_NEW_KEY_BUNDLE_IMPL;
+ } else if (key_type.ToString() == "string" || key_type.ToString() == "file") {
+ code = CB_MAP_INSERT_NEW_KEY_STRING_IMPL;
+ } else {
+ code = ReplaceAll(CB_MAP_INSERT_NEW_KEY_BASE_IMPL)
+ .Change("<KEY_TYPE>",
+ RemoveLastSpaces(GetDataTypeString(key_type, false)));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenMapInsert(
+ const BaseType& key_type, const BaseType& value_type) {
+ std::string code;
+ code = ReplaceAll(CB_MAP_INSERT)
+ .Change("<MAP_INSERT_NEW_KEY_IMPL>", GenMapInsertNewKeyImpl(key_type))
+ .Change("<MAP_INSERT_NEW_VALUE_IMPL>",
+ GenMapInsertNewValueImpl(key_type, value_type));
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenMapKeyValueNullCheck(
+ const BaseType& key_type, const BaseType& value_type) {
+ std::string code;
+ bool is_key_ptr = IsPtrType(key_type);
+ bool is_value_ptr = IsPtrType(value_type);
+ if (is_key_ptr && is_value_ptr)
+ code = CB_MAP_HANDLE_KEY_VALUE_NULL_CHECK;
+ else if (is_key_ptr && !is_value_ptr)
+ code = CB_MAP_HANDLE_KEY_NULL_CHECK;
+ else if (!is_key_ptr && is_value_ptr)
+ code = CB_MAP_HANDLE_VALUE_NULL_CHECK;
+ else
+ code = CB_MAP_HANDLE_NULL_CHECK;
+
+ return code;
+}
+
+std::string CBodyGeneratorBase::GenMapFreeFunc(
+ const BaseType& type) {
+ std::string code;
+ if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_MAP_USER_DEFINED_FREE_FUNC)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", type.GetFullName(true));
+ } else if (type.ToString() == "bundle") {
+ code = CB_MAP_BUNDLE_FREE_FUNC;
+ } else {
+ code = CB_MAP_FREE_FUNC;
+ }
+
+ return code;
+}
+
+std::string CBodyGeneratorBase::GenMapCompareKeyVarsDefinition(
+ const BaseType& type) {
+ std::string code;
+ if (IsPtrType(type)) {
+ code = ReplaceAll(CB_MAP_COMPARE_KEY_VARS_DEF_PTR_TYPE)
+ .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+ } else {
+ code = ReplaceAll(CB_MAP_COMPARE_KEY_VARS_DEF_BASE_TYPE)
+ .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenMapCompareKeyVarsImpl(const BaseType& type) {
+ std::string code;
+ if (type.ToString() == "string")
+ code = CB_MAP_STRING_COMPARISION_IMPL;
+ else if (type.ToString() == "bool")
+ code = CB_MAP_BOOL_COMPARISION_IMPL;
+ else
+ code = CB_MAP_BASE_COMPARISION_IMPL;
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenMapUnitMapValueRead(
+ const BaseType& type) {
+ std::string code;
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
+ code = ReplaceAll(CB_MAP_UNIT_MAP_VALUE_ENUM_TYPE_READ)
+ .Change("<VALUE>", type.GetFullName(true));
+ else
+ code = ReplaceAll(CB_MAP_UNIT_MAP_VALUE_READ)
+ .Change("<VALUE>", type.GetFullName(true));
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenMapUnitMapKeyRead(
+ const BaseType& type) {
+ std::string code;
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
+ code = ReplaceAll(CB_MAP_UNIT_MAP_KEY_ENUM_TYPE_READ)
+ .Change("<KEY>", type.GetFullName(true));
+ else
+ code = ReplaceAll(CB_MAP_UNIT_MAP_KEY_READ)
+ .Change("<KEY>", type.GetFullName(true));
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenMapUnitMapValueWrite(
+ const BaseType& type) {
+ std::string code;
+ if (IsPtrType(type)) {
+ code = ReplaceAll(CB_MAP_UNIT_MAP_VALUE_WRITE_PTR_TYPE)
+ .Change("<VALUE>", type.GetFullName(true))
+ .Change("<VALUE_TYPE>",
+ RemoveLastSpaces(GetDataTypeString(type, false)));
+ } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code = ReplaceAll(CB_MAP_UNIT_MAP_VALUE_WRITE_ENUM_TYPE)
+ .Change("<KEY>", type.GetFullName(true));
+ } else {
+ code = ReplaceAll(CB_MAP_UNIT_MAP_VALUE_WRITE_BASE_TYPE)
+ .Change("<VALUE>", type.GetFullName(true))
+ .Change("<VALUE_TYPE>",
+ RemoveLastSpaces(GetDataTypeString(type, false)));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenMapUnitMapKeyWrite(
+ const BaseType& type) {
+ std::string code;
+ if (IsPtrType(type)) {
+ code = ReplaceAll(CB_MAP_UNIT_MAP_KEY_WRITE_PTR_TYPE)
+ .Change("<KEY>", type.GetFullName(true))
+ .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+ } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code = ReplaceAll(CB_MAP_UNIT_MAP_KEY_ENUM_BASE_TYPE)
+ .Change("<KEY>", type.GetFullName(true));
+ } else {
+ code = ReplaceAll(CB_MAP_UNIT_MAP_KEY_WRITE_BASE_TYPE)
+ .Change("<KEY>", type.GetFullName(true))
+ .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+ }
+
+ return RemoveLine(code);
+}
+
+void CBodyGeneratorBase::GenStructureMapBase(std::ofstream& stream,
+ const Structure& st) {
+ auto iter = st.GetElements().begin();
+ if (std::next(iter) == st.GetElements().end())
+ return;
+
+ auto& key_elm = *(iter);
+ auto& key_type = key_elm->GetType();
+ auto key_param_type = GetParamTypeString(ParameterType::Direction::IN,
+ key_type);
+ auto& value_elm = *(std::next(iter));
+ auto& value_type = value_elm->GetType();
+ auto value_param_type = GetParamTypeString(ParameterType::Direction::IN,
+ value_type);
+ auto value_param_type_out = GetParamTypeString(ParameterType::Direction::OUT,
+ value_type);
+
+ ReplaceAll(CB_STRUCTURE_MAP_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Change("<KEY_TYPE>", GetDataTypeString(key_type, false))
+ .Change("<VALUE_TYPE>", GetDataTypeString(value_type, false))
+ .Change("<KEY_PARAM_TYPE>", key_param_type)
+ .Change("<VALUE_PARAM_TYPE>", value_param_type)
+ .Change("<VALUE_PARAM_TYPE_OUT>", value_param_type_out)
+ .Change("<MAP_UNIT_MAP_KEY_WRITE>", GenMapUnitMapKeyWrite(key_type))
+ .Change("<MAP_UNIT_MAP_VALUE_WRITE>", GenMapUnitMapValueWrite(value_type))
+ .Change("<MAP_UNIT_MAP_KEY_READ>", GenMapUnitMapKeyRead(key_type))
+ .Change("<MAP_UNIT_MAP_VALUE_READ>", GenMapUnitMapValueRead(value_type))
+ .Change("<MAP_COMPARE_KEY_VARS_DEF>",
+ GenMapCompareKeyVarsDefinition(key_type))
+ .Change("<MAP_COMPARE_KEY_VARS_IMPL>",
+ GenMapCompareKeyVarsImpl(key_type))
+ .Change("<MAP_KEY_FREE_FUNC>", GenMapFreeFunc(key_type))
+ .Change("<MAP_VALUE_FREE_FUNC>", GenMapFreeFunc(value_type))
+ .Change("<MAP_INSERT_ARGS_NULL_CHECK>",
+ GenMapKeyValueNullCheck(key_type, value_type))
+ .Change("<MAP_INSERT>", GenMapInsert(key_type, value_type))
+ .Change("<MAP_LOOKUP_ARGS_NULL_CHECK>",
+ GenMapKeyValueNullCheck(key_type))
+ .Change("<MAP_LOOKUP>", GenMapLookup(key_type, value_type))
+ .Change("<MAP_ERASE_ARGS_NULL_CHECK>", GenMapKeyNullCheck(key_type))
+ .Change("<MAP_ERASE>", GenMapErase(key_type))
+ .Change("<MAP_REPLACE_ARGS_NULL_CHECK>",
+ GenMapKeyValueNullCheck(key_type, value_type))
+ .Change("<MAP_FOREACH_VARS_DEF>",
+ GenMapForeachVarsDefinition(key_type, value_type))
+ .Change("<MAP_CONTAINS_ARGS_NULL_CHECK>",
+ GenMapKeyExistNullCheck(key_type))
+ .Change("<MAP_CONTAINS>", GenMapContains(key_type))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+std::string CBodyGeneratorBase::GenSetContains(const BaseType& type) {
+ std::string code;
+ if (IsPtrType(type))
+ code = CB_SET_CONTAINS_KEY_PTR_TYPE;
+ else
+ code = CB_SET_CONTAINS_KEY_BASE_TYPE;
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenSetKeyExistNullCheck(
+ const BaseType& type) {
+ std::string code;
+ if (IsPtrType(type))
+ code = CB_SET_HANDLE_KEY_EXIST_NULL_CHECK;
+ else
+ code = CB_SET_HANDLE_EXIST_NULL_CHECK;
+
+ return code;
+}
+
+std::string CBodyGeneratorBase::GenSetForeachKeyVarDefinition(
+ const BaseType& type) {
+ std::string code;
+ if (IsPtrType(type)) {
+ code = ReplaceAll(CB_SET_FOREACH_VARS_DEF_KEY_PTR_TYPE)
+ .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+ } else {
+ code = ReplaceAll(CB_SET_FOREACH_VARS_DEF_KEY_BASE_TYPE)
+ .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenSetErase(const BaseType& type) {
+ std::string code;
+ if (IsPtrType(type))
+ code = CB_SET_ERASE_KEY_PTR_TYPE;
+ else
+ code = CB_SET_ERASE_KEY_BASE_TYPE;
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenSetInsert(const BaseType& type) {
+ std::string code;
+ if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_SET_INSERT_KEY_USER_DEFINED_IMPL)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", type.GetFullName(true));
+ } else if (type.ToString() == "bundle") {
+ code = CB_SET_INSERT_KEY_BUNDLE_IMPL;
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = CB_SET_INSERT_KEY_STRING_IMPL;
+ } else {
+ code = ReplaceAll(CB_SET_INSERT_KEY_BASE_IMPL)
+ .Change("<KEY_TYPE>",
+ RemoveLastSpaces(GetDataTypeString(type, false)));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenSetKeyNullCheck(const BaseType& type) {
+ std::string code;
+ if (IsPtrType(type))
+ code = CB_SET_HANDLE_KEY_NULL_CHECK;
+ else
+ code = CB_SET_HANDLE_NULL_CHECK;
+
+ return code;
+}
+
+std::string CBodyGeneratorBase::GenSetKeyFreeFunc(const BaseType& type) {
+ std::string code;
+ if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_SET_USER_DEFINED_FREE_FUNC)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", type.GetFullName(true));
+ } else if (type.ToString() == "bundle") {
+ code = CB_SET_BUNDLE_FREE_FUNC;
+ } else {
+ code = CB_SET_FREE_FUNC;
+ }
+
+ return code;
+}
+
+std::string CBodyGeneratorBase::GenSetCompareKeyVarsDefinition(
+ const BaseType& type) {
+ std::string code;
+ if (IsPtrType(type)) {
+ code = ReplaceAll(CB_SET_COMPARE_KEY_VARS_DEF_PTR_TYPE)
+ .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+ } else {
+ code = ReplaceAll(CB_SET_COMPARE_KEY_VARS_DEF_BASE_TYPE)
+ .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenSetCompareKeyVarsImpl(const BaseType& type) {
+ std::string code;
+ if (type.ToString() == "string")
+ code = CB_SET_STRING_COMPARISION_IMPL;
+ else if (type.ToString() == "bool")
+ code = CB_SET_BOOL_COMPARISION_IMPL;
+ else
+ code = CB_SET_BASE_COMPARISION_IMPL;
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenSetUnitMapKeyRead(const BaseType& type) {
+ std::string code;
+
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
+ code = CB_SET_UNIT_MAP_KEY_ENUM_TYPE_READ;
+ else
+ code = ReplaceAll(CB_SET_UNIT_MAP_KEY_READ)
+ .Change("<KEY>", type.GetFullName(true));
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenSetUnitMapKeyWrite(const BaseType& type) {
+ std::string code;
+ if (IsPtrType(type)) {
+ code = ReplaceAll(CB_SET_UNIT_MAP_KEY_WRITE_PTR_TYPE)
+ .Change("<KEY>", type.GetFullName(true))
+ .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+ } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code = CB_SET_UNIT_MAP_KEY_WRITE_ENUM_TYPE;
+ } else {
+ code = ReplaceAll(CB_SET_UNIT_MAP_KEY_WRITE_BASE_TYPE)
+ .Change("<KEY>", type.GetFullName(true))
+ .Change("<KEY_TYPE>", RemoveLastSpaces(GetDataTypeString(type, false)));
+ }
+
+ return RemoveLine(code);
+}
+
+void CBodyGeneratorBase::GenStructureSetBase(std::ofstream& stream,
+ const Structure& st) {
+ auto& key_elm = *(st.GetElements().begin());
+ auto& key_type = key_elm->GetType();
+ auto key_param_type = GetParamTypeString(ParameterType::Direction::IN,
+ key_type);
+
+ ReplaceAll(CB_STRUCTURE_SET_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Change("<KEY_TYPE>", GetDataTypeString(key_type, false))
+ .Change("<KEY_PARAM_TYPE>", key_param_type)
+ .Change("<SET_UNIT_MAP_KEY_WRITE>", GenSetUnitMapKeyWrite(key_type))
+ .Change("<SET_UNIT_MAP_KEY_READ>", GenSetUnitMapKeyRead(key_type))
+ .Change("<SET_COMPARE_KEY_VARS_DEF>",
+ GenSetCompareKeyVarsDefinition(key_type))
+ .Change("<SET_COMPARE_KEY_VARS_IMPL>",
+ GenSetCompareKeyVarsImpl(key_type))
+ .Change("<SET_KEY_FREE_FUNC>", GenSetKeyFreeFunc(key_type))
+ .Change("<SET_INSERT_ARGS_NULL_CHECK>", GenSetKeyNullCheck(key_type))
+ .Change("<SET_INSERT>", GenSetInsert(key_type))
+ .Change("<SET_ERASE_ARGS_NULL_CHECK>", GenSetKeyNullCheck(key_type))
+ .Change("<SET_ERASE>", GenSetErase(key_type))
+ .Change("<SET_FOREACH_VARS_DEF>",
+ GenSetForeachKeyVarDefinition(key_type))
+ .Change("<SET_CONTAINS_ARGS_NULL_CHECK>",
+ GenSetKeyExistNullCheck(key_type))
+ .Change("<SET_CONTAINS>", GenSetContains(key_type))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+std::string CBodyGeneratorBase::GenBaseElementFree(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_STRUCTURE_BASE_USER_DEFINED_FREE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", GetFullNameFromType(type))
+ .Change("<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "bundle") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_FREE)
+ .Change("<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_STRING_FREE)
+ .Change("<ELEMENT_NAME>", elm->GetID());
+ }
+
+ return code;
+}
+
+std::string CBodyGeneratorBase::GenBaseElementsFree(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms)
+ code += GenBaseElementFree(elm);
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenBaseUnitMapWrite(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ auto& type = elm->GetType();
+
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
+ code += ReplaceAll(CB_STRUCTURE_ENUM_UNIT_MAP_WRITE)
+ .Change("<ELEMENT_NAME>", elm->GetID());
+ else
+ code += ReplaceAll(CB_STRUCTURE_BASE_UNIT_MAP_WRITE)
+ .Change("<ELEMENT_TYPE>", GetFullNameFromType(type))
+ .Change("<ELEMENT_NAME>", elm->GetID());
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenBaseUnitMapRead(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ auto& type = elm->GetType();
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
+ code += ReplaceAll(CB_STRUCTURE_ENUM_UNIT_MAP_READ)
+ .Change("<ELEMENT_NAME>", elm->GetID());
+ else
+ code += ReplaceAll(CB_STRUCTURE_BASE_UNIT_MAP_READ)
+ .Change("<ELEMENT_TYPE>", GetFullNameFromType(type))
+ .Change("<ELEMENT_NAME>", elm->GetID());
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenBaseSet(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_STRUCTURE_BASE_USER_DEFINED_SET)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", GetFullNameFromType(type))
+ .Change("<ELEMENT_FREE>", RemoveLine(GenBaseElementFree(elm)))
+ .Change("<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "bundle") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_SET)
+ .Change("<ELEMENT_FREE>", RemoveLine(GenBaseElementFree(elm)))
+ .Change("<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_STRING_SET)
+ .Change("<ELEMENT_FREE>", RemoveLine(GenBaseElementFree(elm)))
+ .Change("<ELEMENT_NAME>", elm->GetID());
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_BASE_BASE_SET)
+ .Change("<ELEMENT_NAME>", elm->GetID());
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenBaseGet(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_STRUCTURE_BASE_USER_DEFINED_GET)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", GetFullNameFromType(type))
+ .Change("<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "bundle") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_GET)
+ .Change("<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_STRING_GET)
+ .Change("<ELEMENT_NAME>", elm->GetID());
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_BASE_BASE_GET)
+ .Change("<ELEMENT_NAME>", elm->GetID());
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CBodyGeneratorBase::GenBaseSetGet(const std::string& name,
+ const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ auto& type = elm->GetType();
+ auto param_type_in =
+ GetParamTypeString(ParameterType::Direction::IN, type, name);
+ auto param_type_out =
+ GetParamTypeString(ParameterType::Direction::OUT, type, name);
+
+ code += ReplaceAll(CB_STRUCTURE_BASE_SET_GET)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", name)
+ .Change("<ELEMENT_NAME>", elm->GetID())
+ .Change("<PARAM_TYPE_IN>", param_type_in)
+ .Change("<PARAM_TYPE_OUT>", param_type_out)
+ .Change("<BASE_SET>", GenBaseSet(elm))
+ .Change("<BASE_GET>", GenBaseGet(elm));
+ }
+
+ return RemoveLine(code);
+}
+
+void CBodyGeneratorBase::GenStructureBase(std::ofstream& stream,
+ const Structure& st) {
+ auto elms = GetElements(st);
+ ReplaceAll(CB_STRUCTURE_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Change("<ELEMENTS_FREE>", GenBaseElementsFree(elms))
+ .Change("<UNIT_MAP_WRITE>", GenBaseUnitMapWrite(elms))
+ .Change("<UNIT_MAP_READ>", GenBaseUnitMapRead(elms))
+ .Transform([&](std::string code) {
+ return SmartIndent(code + GenBaseSetGet(st.GetID(), elms));
+ })
+ .Out(stream);
+}
+
+void CBodyGeneratorBase::AddParameterType(const Interface& iface,
+ const BaseType& type, ParameterType::Direction direction) {
+ if (IsDelegateType(iface, type)) {
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType("delegate", "delegate", true),
+ ParameterType::Direction::IN));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType("delegate", "delegate", true),
+ ParameterType::Direction::OUT));
+ return;
+ } else if (type.IsUserDefinedType()) {
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(type), ParameterType::Direction::IN));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(type), ParameterType::Direction::OUT));
+ } else if (type.GetMetaType() != nullptr) {
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(type), ParameterType::Direction::IN));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(type), ParameterType::Direction::OUT));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(*type.GetMetaType()), ParameterType::Direction::IN));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(*type.GetMetaType()), ParameterType::Direction::OUT));
+ } else if (type.GetKeyType() != nullptr) {
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(type), ParameterType::Direction::IN));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(type), ParameterType::Direction::OUT));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(*type.GetKeyType()), ParameterType::Direction::IN));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(*type.GetKeyType()), ParameterType::Direction::OUT));
+ if (type.GetValueType() != nullptr) {
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(*type.GetValueType()), ParameterType::Direction::IN));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(*type.GetValueType()), ParameterType::Direction::OUT));
+ }
+ } else if (type.GetFullName() != "file") {
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(type), direction));
+ }
+}
+
+void CBodyGeneratorBase::AddParameterType(
+ std::shared_ptr<ParameterType> param_type) {
+ auto& type = param_type->GetBaseType();
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
+ return;
+
+ std::string key = param_type->GetBaseType().GetFullName(true) +
+ std::to_string(static_cast<int>(param_type->GetDirection()));
+ key = GetEnumTypeString(key);
+ if (param_types_.find(key) != param_types_.end())
+ return;
+
+ param_types_[key] = std::move(param_type);
+}
+
+void CBodyGeneratorBase::GenUnitMapDefinition(std::ofstream& stream) {
+ stream << SmartIndent(CB_UNIT_MAP_DEFS);
+}
+
+void CBodyGeneratorBase::GenParameterMap() {
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType("int", "int"), ParameterType::Direction::IN));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType("int", "int"), ParameterType::Direction::OUT));
+
+ if (HasDelegate()) {
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType("bool", "bool"), ParameterType::Direction::IN));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType("bool", "bool"), ParameterType::Direction::OUT));
+ }
+
+ if (GetChannelType() != ChannelType::TYPE_GROUP) {
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType("string", "string"), ParameterType::Direction::IN));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType("string", "string"), ParameterType::Direction::OUT));
+ }
+
+ for (auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() == Block::TYPE_INTERFACE) {
+ auto& iface = static_cast<const Interface&>(*block);
+ if (GetChannelType() != ChannelType::TYPE_GROUP) {
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType("remote_exception", "", true),
+ ParameterType::Direction::OUT));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType("remote_exception", "", true),
+ ParameterType::Direction::IN));
+ }
+
+ for (const auto& decl : iface.GetDeclarations()) {
+ for (const auto& param : decl->GetParameters()) {
+ auto& type = param->GetParameterType().GetBaseType();
+ if (decl->GetMethodType() == Declaration::MethodType::DELEGATE) {
+ AddParameterType(iface, type, ParameterType::Direction::OUT);
+ } else {
+ auto direction = param->GetParameterType().GetDirection();
+ if (direction == ParameterType::Direction::REF) {
+ AddParameterType(iface, type,
+ ParameterType::Direction::IN);
+ AddParameterType(iface, type,
+ ParameterType::Direction::OUT);
+ } else {
+ AddParameterType(iface, type,
+ param->GetParameterType().GetDirection());
+ }
+ }
+ }
+
+ auto& type = decl->GetType();
+ if (decl->GetMethodType() == Declaration::MethodType::SYNC) {
+ AddParameterType(iface, type, ParameterType::Direction::OUT);
+ } else if (decl->GetMethodType() == Declaration::MethodType::DELEGATE) {
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType("delegate", "delegate", true),
+ ParameterType::Direction::OUT));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(iface.GetID() + "_" + decl->GetID(), "", true),
+ ParameterType::Direction::IN));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(iface.GetID() + "_" + decl->GetID(), "", true),
+ ParameterType::Direction::OUT));
+ }
+ }
+ } else {
+ auto& st = static_cast<const Structure&>(*block);
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(st.GetID(), st.GetID(), true),
+ ParameterType::Direction::IN));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(st.GetID(), st.GetID(), true),
+ ParameterType::Direction::OUT));
+
+ for (auto& elm : st.GetElements()) {
+ auto& type = elm->GetType();
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(type), ParameterType::Direction::IN));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(type), ParameterType::Direction::OUT));
+ }
+ }
+ }
+
+ for (auto& i : GetStructures()) {
+ auto& st = *i.second;
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(st.GetID(), st.GetID(), true)));
+
+ for (auto& elm : st.GetElements()) {
+ auto& type = elm->GetType();
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(type), ParameterType::Direction::IN));
+ AddParameterType(
+ std::make_shared<ParameterType>(
+ new BaseType(type), ParameterType::Direction::OUT));
+ }
+ }
+}
+
+void CBodyGeneratorBase::GenUnitMapBase(std::ofstream& stream) {
+ stream << SmartIndent(CB_UNIT_MAP_BASE);
+
+ if (GetChannelType() == ChannelType::TYPE_PROXY)
+ stream << SmartIndent(CB_UNIT_MAP_CLEAR_BASE);
+
+ GenParameterMap();
+
+ std::string code;
+ for (const auto& iter : param_types_) {
+ if (!code.empty())
+ code += NLine(1);
+
+ auto& param_type = *iter.second;
+ if (param_type.GetDirection() == ParameterType::Direction::IN) {
+ if (GetChannelType() == ChannelType::TYPE_GROUP) {
+ code += GenUnitMapWrite(param_type);
+ code += GenUnitMapRead(param_type);
+ } else if (GetChannelType() == ChannelType::TYPE_PROXY) {
+ code += GenUnitMapWrite(param_type);
+ } else {
+ code += GenUnitMapRead(param_type);
+ }
+ } else {
+ if (GetChannelType() == ChannelType::TYPE_PROXY)
+ code += GenUnitMapRead(param_type);
+ else if (GetChannelType() == ChannelType::TYPE_STUB)
+ code += GenUnitMapWrite(param_type);
+ }
+ }
+
+ stream << SmartIndent(code);
+}
+
+std::string CBodyGeneratorBase::GetFullTypeNameFromType(const BaseType& type) {
+ auto found = struct_types_.find(type.GetFullName(true));
+ if (found != struct_types_.end())
+ return found->second;
+
+ return GetFullNameFromType(type);
+}
+
+std::string CBodyGeneratorBase::GenUnitMapWrite(
+ const ParameterType& param_type) {
+ std::string code;
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType() ||
+ type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ if (type.ToString() == "delegate") {
+ code = std::string(CB_UNIT_MAP_DELEGATE_WRITE);
+ } else {
+ code += ReplaceAll(CB_UNIT_MAP_USER_DEFINED_WRITE)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type))
+ .Change("<FULL_TYPE_NAME>", GetFullTypeNameFromType(type))
+ .Change("<PARAM_TYPE>",
+ GetParamTypeString(ParameterType::Direction::IN,
+ param_type.GetBaseType()))
+ .Change("<FULL_PARAM_TYPE>",
+ GetParamTypeString(ParameterType::Direction::IN,
+ param_type.GetBaseType(), "", true));
+ }
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_UNIT_MAP_BUNDLE_WRITE);
+ } else if (type.ToString() == "string") {
+ code = std::string(CB_UNIT_MAP_STRING_WRITE);
+ } else {
+ code = ReplaceAll(CB_UNIT_MAP_BASE_WRITE)
+ .Change("<TYPE_NAME>", type.ToString())
+ .Change("<PARAM_TYPE>",
+ GetParamTypeString(ParameterType::Direction::IN,
+ param_type.GetBaseType()))
+ .Change("<PARCEL_TYPE>", GetParcelType(param_type.GetBaseType()));
+ }
+
+ return code;
+}
+
+std::string CBodyGeneratorBase::GenUnitMapRead(
+ const ParameterType& param_type) {
+ std::string code;
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType() ||
+ type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ if (type.ToString() == "delegate") {
+ code = std::string(CB_UNIT_MAP_DELEGATE_READ);
+ } else {
+ std::string ctor = GetHandlePrefix() + "_" +
+ GetFullNameFromType(param_type.GetBaseType()) + "_create";
+ code = ReplaceAll(CB_UNIT_MAP_USER_DEFINED_READ)
+ .Change("<TYPE_NAME>", GetEnumTypeString(GetFullNameFromType(type)))
+ .Change("<FULL_TYPE_NAME>", GetFullTypeNameFromType(type))
+ .Change("<PARAM_TYPE_OUT>",
+ GetParamTypeString(ParameterType::Direction::OUT,
+ param_type.GetBaseType()))
+ .Change("<PARAM_TYPE_IN>",
+ GetParamTypeString(ParameterType::Direction::IN,
+ param_type.GetBaseType(), "", true))
+ .Change("<PARAM_TYPE_CTOR>", ctor);
+ }
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_UNIT_MAP_BUNDLE_READ);
+ } else if (type.ToString() == "string") {
+ code = std::string(CB_UNIT_MAP_STRING_READ);
+ } else {
+ code = ReplaceAll(CB_UNIT_MAP_BASE_READ)
+ .Change("<TYPE_NAME>", type.ToString())
+ .Change("<PARAM_TYPE>",
+ GetParamTypeString(ParameterType::Direction::OUT,
+ param_type.GetBaseType()))
+ .Change("<PARCEL_TYPE>", GetParcelType(param_type.GetBaseType()));
+ }
+
+ return code;
+}
+
+void CBodyGeneratorBase::GenRemoteExceptionDefinition(std::ofstream& stream) {
+ ReplaceAll(CB_REMOTE_EXCEPTION_DEF)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CBodyGeneratorBase::GenRemoteExceptionBase(std::ofstream& stream) {
+ ReplaceAll(CB_REMOTE_EXCEPTION_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+
+ ReplaceAll(IsProxy() ? CB_PROXY_REMOTE_EXCEPTION_BASE
+ : CB_STUB_REMOTE_EXCEPTION_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/c_body_generator_base.hh b/idlc/gen/version2/c_body_generator_base.hh
new file mode 100644
index 0000000..4444889
--- /dev/null
+++ b/idlc/gen/version2/c_body_generator_base.hh
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_BODY_GENERATOR_BASE_HH_
+#define IDLC_GEN_VERSION2_C_BODY_GENERATOR_BASE_HH_
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "idlc/gen/c_body_gen_base.h"
+
+namespace tidl {
+namespace version2 {
+
+class CBodyGeneratorBase : public tidl::CBodyGeneratorBase {
+ public:
+ explicit CBodyGeneratorBase(std::shared_ptr<Document> doc);
+ virtual ~CBodyGeneratorBase() = default;
+
+ void GenStructureDefinition(std::ofstream& stream);
+ void GenStructure(std::ofstream& stream);
+ void GenDelegateBase(std::ofstream& stream);
+ void GenUnitMapDefinition(std::ofstream& stream);
+ void GenUnitMapBase(std::ofstream& stream);
+ bool HasDelegate();
+ void GenIncludeLemHeaders(std::ofstream& stream);
+ std::string GetHandlePrefixReverse();
+ void GenRemoteExceptionDefinition(std::ofstream& stream);
+ void GenRemoteExceptionBase(std::ofstream& stream);
+
+ private:
+ void AddTypeName(const Structure& st);
+ void GenStructureArrayBaseDefinition(std::ofstream& stream,
+ const Structure& st);
+ void GenStructureListBaseDefinition(std::ofstream& stream,
+ const Structure& st);
+ void GenStructureMapBaseDefinition(std::ofstream& stream,
+ const Structure& st);
+ void GenStructureSetBaseDefinition(std::ofstream& stream,
+ const Structure& st);
+ std::string GenBaseElements(const Elements& elms, const std::string& id);
+ void GenStructureBaseDefinition(std::ofstream& stream, const Structure& st);
+
+ std::string GenArrayUnitMapWrite(const std::shared_ptr<Element>& elm);
+ std::string GenArrayUnitMapRead(const std::shared_ptr<Element>& elm);
+ std::string GenArrayElementsFree(const std::shared_ptr<Element>& elm);
+ void GenStructureArrayBase(std::ofstream& stream, const Structure& st);
+ std::string GenListDataFree(const std::shared_ptr<Element>& elm);
+ std::string GenListUnitMapWrite(const std::shared_ptr<Element>& elm);
+ std::string GenListUnitMapRead(const std::shared_ptr<Element>& elm);
+ std::string GenListAdd(const std::shared_ptr<Element>& elm);
+ std::string GenListCallbackParamType(const std::shared_ptr<Element>& elm);
+ void GenStructureListBase(std::ofstream& stream, const Structure& st);
+ std::string GenMapContains(const BaseType& key_type);
+ std::string GenMapKeyExistNullCheck(const BaseType& key_type);
+ std::string GenMapForeachVarsDefinition(const BaseType& key_type,
+ const BaseType& value_type);
+ std::string GenMapErase(const BaseType& key_type);
+ std::string GenMapKeyNullCheck(const BaseType& key_type);
+ std::string GenMapLookupValueSet(const BaseType& value_type);
+ std::string GenMapLookup(const BaseType& key_type,
+ const BaseType& value_type);
+ std::string GenMapKeyValueNullCheck(const BaseType& key_type);
+ std::string GenMapInsertNewKeyFree(const BaseType& key_type);
+ std::string GenMapInsertNewValueImpl(const BaseType& key_type,
+ const BaseType& value_type);
+ std::string GenMapInsertNewKeyImpl(const BaseType& key_type);
+ std::string GenMapInsert(const BaseType& key_type,
+ const BaseType& value_type);
+ std::string GenMapKeyValueNullCheck(const BaseType& key_type,
+ const BaseType& value_type);
+ std::string GenMapFreeFunc(const BaseType& type);
+ std::string GenMapCompareKeyVarsDefinition(const BaseType& type);
+ std::string GenMapCompareKeyVarsImpl(const BaseType& type);
+ std::string GenMapUnitMapValueRead(const BaseType& type);
+ std::string GenMapUnitMapKeyRead(const BaseType& type);
+ std::string GenMapUnitMapValueWrite(const BaseType& type);
+ std::string GenMapUnitMapKeyWrite(const BaseType& type);
+ void GenStructureMapBase(std::ofstream& stream, const Structure& st);
+ std::string GenSetContains(const BaseType& type);
+ std::string GenSetKeyExistNullCheck(const BaseType& type);
+ std::string GenSetForeachKeyVarDefinition(const BaseType& type);
+ std::string GenSetErase(const BaseType& type);
+ std::string GenSetInsert(const BaseType& type);
+ std::string GenSetKeyNullCheck(const BaseType& type);
+ std::string GenSetKeyFreeFunc(const BaseType& type);
+ std::string GenSetCompareKeyVarsDefinition(const BaseType& type);
+ std::string GenSetCompareKeyVarsImpl(const BaseType& type);
+ std::string GenSetUnitMapKeyRead(const BaseType& type);
+ std::string GenSetUnitMapKeyWrite(const BaseType& type);
+ void GenStructureSetBase(std::ofstream& stream, const Structure& st);
+ std::string GenBaseElementFree(const std::shared_ptr<Element>& elm);
+ std::string GenBaseElementsFree(const Elements& elms);
+ std::string GenBaseUnitMapWrite(const Elements& elms);
+ std::string GenBaseUnitMapRead(const Elements& elms);
+ std::string GenBaseSet(const std::shared_ptr<Element>& elm);
+ std::string GenBaseGet(const std::shared_ptr<Element>& elm);
+ std::string GenBaseSetGet(const std::string& name, const Elements& elms);
+ void GenStructureBase(std::ofstream& stream, const Structure& st);
+
+ void AddParameterType(const Interface& iface, const BaseType& type,
+ ParameterType::Direction direction);
+ void AddParameterType(std::shared_ptr<ParameterType> type);
+
+ std::string GetFullTypeNameFromType(const BaseType& type);
+ std::string GenUnitMapWrite(const ParameterType& param_type);
+ std::string GenUnitMapRead(const ParameterType& param_type);
+ void GenParameterMap();
+
+ private:
+ std::unordered_map<std::string, std::shared_ptr<ParameterType>> param_types_;
+ std::unordered_map<std::string, std::string> struct_types_;
+ bool has_delegate_ = false;
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_BODY_GENERATOR_BASE_HH_
diff --git a/idlc/gen/version2/c_body_generator_base_cb.hh b/idlc/gen/version2/c_body_generator_base_cb.hh
new file mode 100644
index 0000000..1ae929d
--- /dev/null
+++ b/idlc/gen/version2/c_body_generator_base_cb.hh
@@ -0,0 +1,1279 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_BODY_GENERATOR_BASE_CB_HH_
+#define IDLC_GEN_VERSION2_C_BODY_GENERATOR_BASE_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+constexpr const char CB_LEM_HEADER[] =
+R"__c_cb(
+#include <unistd.h>
+#include <dlfcn.h>
+#include <app_common.h>
+)__c_cb";
+
+constexpr const char CB_UNIT_MAP_DEFS[] =
+R"__c_cb(
+typedef struct rpc_port_unit_s {
+ rpc_port_parcelable_t parcelable;
+ char *name;
+ char *type;
+ rpc_port_parcel_h parcel;
+} rpc_port_unit_t;
+
+typedef rpc_port_unit_t *rpc_port_unit_h;
+
+typedef struct rpc_port_unit_map_s {
+ rpc_port_parcelable_t parcelable;
+ GHashTable *table;
+} rpc_port_unit_map_t;
+
+typedef rpc_port_unit_map_t *rpc_port_unit_map_h;
+)__c_cb";
+
+constexpr const char CB_UNIT_MAP_BASE[] =
+R"__c_cb(
+static void __rpc_port_unit_to(rpc_port_parcel_h parcel, void *user_data)
+{
+ rpc_port_unit_h unit = user_data;
+ void *raw = nullptr;
+ unsigned int size = 0;
+ int ret;
+
+ ret = rpc_port_parcel_write_string(parcel, unit->name);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ set_last_result(ret);
+ return;
+ }
+
+ ret = rpc_port_parcel_write_string(parcel, unit->type);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ set_last_result(ret);
+ return;
+ }
+
+ ret = rpc_port_parcel_get_raw(unit->parcel, &raw, &size);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ set_last_result(ret);
+ return;
+ }
+
+ ret = rpc_port_parcel_write_array_count(parcel, size & INT_MAX);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ set_last_result(ret);
+ return;
+ }
+
+ ret = rpc_port_parcel_burst_write(parcel, raw, size);
+ set_last_result(ret);
+}
+
+static void __rpc_port_unit_from(rpc_port_parcel_h parcel, void *user_data)
+{
+ rpc_port_unit_h unit = user_data;
+ unsigned char *raw;
+ int size = 0;
+
+ rpc_port_parcel_read_string(parcel, &unit->name);
+ rpc_port_parcel_read_string(parcel, &unit->type);
+ rpc_port_parcel_read_array_count(parcel, &size);
+
+ raw = malloc(size);
+ if (raw == nullptr) {
+ _E("malloc() is failed");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_parcel_burst_read(parcel, (void *)raw, size);
+ rpc_port_parcel_burst_write(unit->parcel, raw, size);
+ free(raw);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static void rpc_port_unit_destroy(gpointer user_data)
+{
+ rpc_port_unit_h unit = user_data;
+
+ if (unit == nullptr)
+ return;
+
+ if (unit->parcel)
+ rpc_port_parcel_destroy(unit->parcel);
+
+ if (unit->type)
+ free(unit->type);
+
+ if (unit->name)
+ free(unit->name);
+
+ free(unit);
+}
+
+static rpc_port_unit_h rpc_port_unit_create(const char *name, const char *type)
+{
+ rpc_port_unit_h unit;
+ int ret;
+
+ unit = calloc(1, sizeof(rpc_port_unit_t));
+ if (unit == nullptr) {
+ _E("calloc() is failed");
+ return nullptr;
+ }
+
+ if (name != nullptr) {
+ unit->name = strdup(name);
+ if (unit->name == nullptr) {
+ _E("strdup() is failed. name: %s", name);
+ rpc_port_unit_destroy(unit);
+ return nullptr;
+ }
+ }
+
+ if (type != nullptr) {
+ unit->type = strdup(type);
+ if (unit->type == nullptr) {
+ _E("strdup() is failed. type: %s", type);
+ rpc_port_unit_destroy(unit);
+ return nullptr;
+ }
+ }
+
+ ret = rpc_port_parcel_create_without_header(&unit->parcel);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("rpc_port_parcel_create_without_header() is failed. error: %d", ret);
+ rpc_port_unit_destroy(unit);
+ return nullptr;
+ }
+
+ unit->parcelable.to = __rpc_port_unit_to;
+ unit->parcelable.from = __rpc_port_unit_from;
+
+ return unit;
+}
+
+static void __rpc_port_unit_map_to(rpc_port_parcel_h parcel, void *user_data)
+{
+ rpc_port_unit_map_h unit_map = user_data;
+ rpc_port_unit_h unit;
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+
+ rpc_port_parcel_write_array_count(parcel, g_hash_table_size(unit_map->table) & INT_MAX);
+ g_hash_table_iter_init(&iter, unit_map->table);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ unit = (rpc_port_unit_h)value;
+ rpc_port_parcel_write(parcel, &unit->parcelable, unit);
+ if (get_last_result() != RPC_PORT_ERROR_NONE)
+ break;
+ }
+}
+
+static void __rpc_port_unit_map_from(rpc_port_parcel_h parcel, void *user_data)
+{
+ rpc_port_unit_map_h unit_map = user_data;
+ rpc_port_unit_h unit;
+ int size = 0;
+ int i;
+
+ rpc_port_parcel_read_array_count(parcel, &size);
+ for (i = 0; i < size; ++i) {
+ unit = rpc_port_unit_create(nullptr, nullptr);
+ if (unit == nullptr) {
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ break;
+ }
+
+ rpc_port_parcel_read(parcel, &unit->parcelable, unit);
+ if (get_last_result() != RPC_PORT_ERROR_NONE) {
+ rpc_port_unit_destroy(unit);
+ break;
+ }
+
+ g_hash_table_insert(unit_map->table, unit->name, unit);
+ }
+}
+
+static void rpc_port_unit_map_destroy(rpc_port_unit_map_h handle)
+{
+ if (handle == nullptr)
+ return;
+
+ if (handle->table)
+ g_hash_table_destroy(handle->table);
+
+ free(handle);
+}
+
+static rpc_port_unit_map_h rpc_port_unit_map_create(void)
+{
+ rpc_port_unit_map_h unit_map;
+
+ unit_map = calloc(1, sizeof(rpc_port_unit_map_t));
+ if (unit_map == nullptr) {
+ _E("calloc() is failed");
+ return nullptr;
+ }
+
+ unit_map->table = g_hash_table_new_full(g_str_hash, g_str_equal, nullptr, rpc_port_unit_destroy);
+ if (unit_map->table == nullptr) {
+ _E("g_hash_table_new_full() is failed");
+ rpc_port_unit_map_destroy(unit_map);
+ return nullptr;
+ }
+
+ unit_map->parcelable.to = __rpc_port_unit_map_to;
+ unit_map->parcelable.from = __rpc_port_unit_map_from;
+
+ return unit_map;
+}
+)__c_cb";
+
+constexpr const char CB_UNIT_MAP_CLEAR_BASE[] =
+R"__c_cb(
+static int rpc_port_unit_map_clear(rpc_port_unit_map_h map)
+{
+ if (map == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_hash_table_remove_all(map->table);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the parameter.
+ * <FULL_TYPE_NAME> The full type name of the parameter.
+ * <PARAM_TYPE> The parameter type.
+ * <FULL_PARAM_TYPE> The full name of the parameter type.
+ */
+constexpr const char CB_UNIT_MAP_USER_DEFINED_WRITE[] =
+R"__c_cb(
+static int rpc_port_unit_map_write_<TYPE_NAME>(rpc_port_unit_map_h unit_map,
+ const char *name, <PARAM_TYPE>value)
+{
+ <FULL_PARAM_TYPE>handle = value;
+ rpc_port_unit_h unit;
+
+ if (unit_map == nullptr || name == nullptr || handle == nullptr)
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+ unit = rpc_port_unit_create(name, "<FULL_TYPE_NAME>");
+ if (unit == nullptr)
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+
+ rpc_port_parcel_write(unit->parcel, &handle->parcelable, handle);
+ g_hash_table_insert(unit_map->table, unit->name, unit);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+constexpr const char CB_UNIT_MAP_DELEGATE_WRITE[] =
+R"__c_cb(
+static int rpc_port_unit_map_write_delegate(rpc_port_unit_map_h unit_map,
+ const char *name, rpc_port_delegate_h value)
+{
+ rpc_port_unit_h unit;
+
+ if (unit_map == nullptr || name == nullptr || value == nullptr)
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+ unit = rpc_port_unit_create(name, "delegate");
+ if (unit == nullptr)
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+
+ rpc_port_parcel_write(unit->parcel, &value->parcelable, value);
+ g_hash_table_insert(unit_map->table, unit->name, unit);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+constexpr const char CB_UNIT_MAP_BUNDLE_WRITE[] =
+R"__c_cb(
+static int rpc_port_unit_map_write_bundle(rpc_port_unit_map_h unit_map,
+ const char *name, bundle *value)
+{
+ rpc_port_unit_h unit;
+
+ if (unit_map == nullptr || name == nullptr || value == nullptr)
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+ unit = rpc_port_unit_create(name, "bundle");
+ if (unit == nullptr)
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+
+ rpc_port_parcel_write_bundle(unit->parcel, value);
+ g_hash_table_insert(unit_map->table, unit->name, unit);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+constexpr const char CB_UNIT_MAP_STRING_WRITE[] =
+R"__c_cb(
+static int rpc_port_unit_map_write_string(rpc_port_unit_map_h unit_map,
+ const char *name, const char *value)
+{
+ rpc_port_unit_h unit;
+
+ if (unit_map == nullptr || name == nullptr || value == nullptr)
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+ unit = rpc_port_unit_create(name, "string");
+ if (unit == nullptr)
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+
+ rpc_port_parcel_write_string(unit->parcel, value);
+ g_hash_table_insert(unit_map->table, unit->name, unit);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the parameter.
+ * <PARAM_TYPE> The type of the parameter.
+ * <PARCEL_TYPE> The type of the parcel type of the parameter.
+ */
+constexpr const char CB_UNIT_MAP_BASE_WRITE[] =
+R"__c_cb(
+static int rpc_port_unit_map_write_<TYPE_NAME>(rpc_port_unit_map_h unit_map,
+ const char *name, <PARAM_TYPE>value)
+{
+ rpc_port_unit_h unit;
+
+ if (unit_map == nullptr || name == nullptr)
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+ unit = rpc_port_unit_create(name, "<TYPE_NAME>");
+ if (unit == nullptr)
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+
+ rpc_port_parcel_write_<PARCEL_TYPE>(unit->parcel, value);
+ g_hash_table_insert(unit_map->table, unit->name, unit);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the parameter.
+ * <FULL_TYPE_NAME> The full type name of the parameter.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ * <PARAM_TYPE_CTOR> The constructor of the parameter type.
+ */
+constexpr const char CB_UNIT_MAP_USER_DEFINED_READ[] =
+R"__c_cb(
+static void rpc_port_unit_map_read_<TYPE_NAME>(rpc_port_unit_map_h unit_map,
+ const char *name, <PARAM_TYPE_OUT>value)
+{
+ rpc_port_unit_h unit;
+ <PARAM_TYPE_IN>handle;
+ int ret;
+
+ if (value == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ ret = <PARAM_TYPE_CTOR>((<PARAM_TYPE_OUT>)&handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ *value = nullptr;
+ return;
+ }
+
+ *value = handle;
+ if (unit_map == nullptr || name == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ unit = g_hash_table_lookup(unit_map->table, name);
+ if (unit == nullptr) {
+ _E("g_hash_table_lookup() is failed. name: %s", name);
+ return;
+ }
+
+ if (strncmp(unit->type, "<FULL_TYPE_NAME>", strlen("<FULL_TYPE_NAME>")) != 0) {
+ _E("type(%s) is not <FULL_TYPE_NAME>", unit->type);
+ return;
+ }
+
+ rpc_port_parcel_read(unit->parcel, &handle->parcelable, handle);
+}
+)__c_cb";
+
+constexpr const char CB_UNIT_MAP_DELEGATE_READ[] =
+R"__c_cb(
+static void rpc_port_unit_map_read_delegate(rpc_port_unit_map_h unit_map,
+ const char *name, rpc_port_delegate_h *value)
+{
+ rpc_port_unit_h unit;
+ rpc_port_delegate_h delegate;
+
+ if (value == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ delegate = rpc_port_delegate_create();
+ *value = delegate;
+
+ if (delegate == nullptr)
+ return;
+
+ if (unit_map == nullptr || name == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ unit = g_hash_table_lookup(unit_map->table, name);
+ if (unit == nullptr) {
+ _E("g_hash_table_lookup() is failed. name: %s", name);
+ return;
+ }
+
+ if (strcmp(unit->type, "delegate") != 0) {
+ _E("type(%s) is not delegate", unit->type);
+ return;
+ }
+
+ rpc_port_parcel_read(unit->parcel, &delegate->parcelable, delegate);
+}
+)__c_cb";
+
+constexpr const char CB_UNIT_MAP_BUNDLE_READ[] =
+R"__c_cb(
+static void rpc_port_unit_map_read_bundle(rpc_port_unit_map_h unit_map,
+ const char *name, bundle **value)
+{
+ rpc_port_unit_h unit;
+
+ if (value == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ if (unit_map == nullptr || name == nullptr) {
+ *value = bundle_create();
+ _E("Invalid parameter");
+ return;
+ }
+
+ unit = g_hash_table_lookup(unit_map->table, name);
+ if (unit == nullptr) {
+ _E("g_hash_table_lookup() is failed. name: %s", name);
+ *value = bundle_create();
+ return;
+ }
+
+ if (strcmp(unit->type, "bundle") != 0) {
+ _E("type(%s) is not bundle", unit->type);
+ *value = bundle_create();
+ return;
+ }
+
+ rpc_port_parcel_read_bundle(unit->parcel, value);
+}
+)__c_cb";
+
+constexpr const char CB_UNIT_MAP_STRING_READ[] =
+R"__c_cb(
+static void rpc_port_unit_map_read_string(rpc_port_unit_map_h unit_map,
+ const char *name, char **value)
+{
+ rpc_port_unit_h unit;
+
+ if (value == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ if (unit_map == nullptr || name == nullptr) {
+ *value = strdup("");
+ _E("Invalid parameter");
+ return;
+ }
+
+ unit = g_hash_table_lookup(unit_map->table, name);
+ if (unit == nullptr) {
+ _E("g_hash_table_lookup() is failed. name: %s", name);
+ *value = strdup("");
+ return;
+ }
+
+ if (strcmp(unit->type, "string") != 0) {
+ _E("type(%s) is not string", unit->type);
+ *value = strdup("");
+ return;
+ }
+
+ rpc_port_parcel_read_string(unit->parcel, value);
+}
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the parameter.
+ * <PARAM_TYPE> The type of the parameter.
+ * <PARCEL_TYPE> The parcel type of the parameter.
+ */
+constexpr const char CB_UNIT_MAP_BASE_READ[] =
+R"__c_cb(
+static void rpc_port_unit_map_read_<TYPE_NAME>(rpc_port_unit_map_h unit_map,
+ const char *name, <PARAM_TYPE>value)
+{
+ rpc_port_unit_h unit;
+
+ if (value == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ if (unit_map == nullptr || name == nullptr) {
+ *value = 0;
+ _E("Invalid parameter");
+ return;
+ }
+
+ unit = g_hash_table_lookup(unit_map->table, name);
+ if (unit == nullptr) {
+ _E("g_hash_table_lookup() is failed. name: %s", name);
+ *value = 0;
+ return;
+ }
+
+ if (strcmp(unit->type, "<TYPE_NAME>") != 0) {
+ _E("type(%s) is not <TYPE_NAME>", unit->type);
+ *value = 0;
+ return;
+ }
+
+ rpc_port_parcel_read_<PARCEL_TYPE>(unit->parcel, value);
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ELEMENTS> Elements of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ <ELEMENTS>
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ELEMENTS_FREE> The implementation to release elements of the structure.
+ * <UNIT_MAP_WRITE> The implementation to write the data to the unit map.
+ * <UNIT_MAP_READ> The implementation to read the data from the unit map.
+ */
+constexpr const char CB_STRUCTURE_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_t *handle = data;
+ rpc_port_unit_map_h map;
+
+ if (parcel == nullptr || handle == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ <UNIT_MAP_WRITE>
+
+ rpc_port_parcel_write(parcel, &map->parcelable, map);
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_t *handle = data;
+ rpc_port_unit_map_h map;
+
+ if (parcel == nullptr || handle == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_parcel_read(parcel, &map->parcelable, map);
+
+ <UNIT_MAP_READ>
+
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_from;
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+
+ if (handle == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ <ELEMENTS_FREE>
+
+ free(handle);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ rpc_port_unit_map_h map;
+ int ret;
+
+ if (handle == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = rpc_port_unit_map_write_<NAME>(map, "clone", handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to write <NAME>. error(%d)", ret);
+ rpc_port_unit_map_destroy(map);
+ return ret;
+ }
+
+ rpc_port_unit_map_read_<NAME>(map, "clone", clone);
+ rpc_port_unit_map_destroy(map);
+
+ return ret;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <PARAM_TYPE_IN> The type of the input paramter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * <BASE_SET> The implementation to set the data to the structure.
+ * <BASE_GET> The implementation to get the data from the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_SET_GET[] =
+R"__c_cb(
+int <PREFIX>_<NAME>_set_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ <BASE_SET>
+}
+
+int <PREFIX>_<NAME>_get_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>value)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ <BASE_GET>
+}
+)__c_cb";
+
+/**
+ * <ELEMENT_TYPE> The type of the element of the structure.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<ELEMENT_TYPE>(map, "<ELEMENT_NAME>", handle-><ELEMENT_NAME>);
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_ENUM_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_int(map, "<ELEMENT_NAME>", (int)handle-><ELEMENT_NAME>);
+)__c_cb";
+
+/**
+ * <ELEMENT_TYPE> The type of the element of the structure.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_<ELEMENT_TYPE>(map, "<ELEMENT_NAME>", &handle-><ELEMENT_NAME>);
+)__c_cb";
+
+/**
+ * <ELEMENT_TYPE> The type of the element of the structure.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_ENUM_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_int(map, "<ELEMENT_NAME>", (int *)&handle-><ELEMENT_NAME>);
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_FREE[] =
+R"__c_cb(
+if (handle-><ELEMENT_NAME>)
+ <PREFIX>_<NAME>_destroy(handle-><ELEMENT_NAME>);
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_FREE[] =
+R"__c_cb(
+if (handle-><ELEMENT_NAME>)
+ bundle_free(handle-><ELEMENT_NAME>);
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_FREE[] =
+R"__c_cb(
+if (handle-><ELEMENT_NAME>)
+ free(handle-><ELEMENT_NAME>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ * <ELEMENT_FREE> The implementation to release the element of the structure.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * @see #CB_STRUCTURE_BASE_USER_DEFINED_FREE
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_SET[] =
+R"__c_cb(
+<PREFIX>_<NAME>_t *new_value;
+int ret;
+
+if (handle == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+ret = <PREFIX>_<NAME>_clone(value, (<PREFIX>_<NAME>_h *)&new_value);
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ return ret;
+}
+
+<ELEMENT_FREE>
+
+handle-><ELEMENT_NAME> = new_value;
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <ELEMENT_FREE> The implementation to release the element of the structure.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * @see #CB_STRUCTURE_BASE_BUNDLE_FREE
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_SET[] =
+R"__c_cb(
+bundle *new_value;
+
+if (handle == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = bundle_dup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+<ELEMENT_FREE>
+
+handle-><ELEMENT_NAME> = new_value;
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <ELEMENT_FREE> The implementation to release the element of the structure.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * @see #CB_STRUCTURE_BASE_STRING_FREE
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_SET[] =
+R"__c_cb(
+char *new_value;
+
+if (handle == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = strdup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+<ELEMENT_FREE>
+
+handle-><ELEMENT_NAME> = new_value;
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BASE_SET[] =
+R"__c_cb(
+if (handle == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+handle-><ELEMENT_NAME> = value;
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_GET[] =
+R"__c_cb(
+<PREFIX>_<NAME>_t *new_value;
+int ret;
+
+if (handle == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+if (handle-><ELEMENT_NAME> == nullptr) {
+ _E("<ELEMENT_NAME> is nullptr");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+ret = <PREFIX>_<NAME>_clone(handle-><ELEMENT_NAME>, (<PREFIX>_<NAME>_h *)&new_value);
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ return ret;
+}
+
+*value = new_value;
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_GET[] =
+R"__c_cb(
+bundle *new_value;
+
+if (handle == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+if (handle-><ELEMENT_NAME> == nullptr) {
+ _E("<ELEMENT_NAME> is nullptr");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = bundle_dup(handle-><ELEMENT_NAME>);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+*value = new_value;
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_GET[] =
+R"__c_cb(
+char *new_value;
+if (handle == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+if (handle-><ELEMENT_NAME> == nullptr) {
+ _E("<ELEMENT_NAME> is nullptr");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = strdup(handle-><ELEMENT_NAME>);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+*value = new_value;
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BASE_GET[] =
+R"__c_cb(
+if (handle == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+*value = handle-><ELEMENT_NAME>;
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+constexpr const char CB_PRIVATE_SHARING_LIST_SET[] =
+R"__c_cb(
+static int __rpc_port_set_private_sharing_list(rpc_port_h port, GList *list)
+{
+ const char **array_file;
+ const char *value;
+ guint size;
+ GList *iter;
+ int idx = 0;
+ int ret;
+
+ size = g_list_length(list);
+ if (size == 0) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ array_file = calloc(size, sizeof(const char*));
+ if (array_file == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ iter = list;
+ while (iter) {
+ value = iter->data;
+ array_file[idx++] = value;
+ iter = g_list_next(iter);
+ }
+
+ ret = rpc_port_set_private_sharing_array(port, array_file, idx);
+ free(array_file);
+
+ return ret;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ */
+constexpr const char CB_REMOTE_EXCEPTION_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_remote_exception_s {
+ rpc_port_parcelable_t parcelable;
+ int cause;
+ char *message;
+} <PREFIX>_remote_exception_t;
+
+static __thread <PREFIX>_remote_exception_h __<PREFIX>_remote_exception;
+
+int <PREFIX>_remote_exception_create(<PREFIX>_remote_exception_h *h);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ */
+constexpr const char CB_REMOTE_EXCEPTION_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_remote_exception_to(rpc_port_parcel_h parcel, void *user_data)
+{
+ <PREFIX>_remote_exception_h h = user_data;
+ rpc_port_unit_map_h map;
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_unit_map_write_int(map, "cause", h->cause);
+ rpc_port_unit_map_write_string(map, "message", h->message);
+ rpc_port_parcel_write(parcel, &map->parcelable, map);
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static void __<PREFIX>_remote_exception_from(rpc_port_parcel_h parcel, void *user_data)
+{
+ <PREFIX>_remote_exception_h h = user_data;
+ rpc_port_unit_map_h map;
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_parcel_read(parcel, &map->parcelable, map);
+ rpc_port_unit_map_read_int(map, "cause", &h->cause);
+ rpc_port_unit_map_read_string(map, "message", &h->message);
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+int <PREFIX>_remote_exception_create(<PREFIX>_remote_exception_h *h)
+{
+ <PREFIX>_remote_exception_h exception;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ exception = calloc(1, sizeof(<PREFIX>_remote_exception_t));
+ if (exception == nullptr) {
+ _E("calloc() is failed");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ exception->parcelable.to = __<PREFIX>_remote_exception_to;
+ exception->parcelable.from = __<PREFIX>_remote_exception_from;
+
+ *h = exception;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_remote_exception_set_cause(<PREFIX>_remote_exception_h h, int cause)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ h->cause = cause;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_remote_exception_set_message(<PREFIX>_remote_exception_h h, const char *message)
+{
+ if (h == nullptr || message == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (h->message)
+ free(h->message);
+
+ h->message = strdup(message);
+ if (h->message == nullptr) {
+ _E("strdup() is failed");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_remote_exception_get_cause(<PREFIX>_remote_exception_h h, int *cause)
+{
+ if (h == nullptr || cause == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *cause = h->cause;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_remote_exception_get_message(<PREFIX>_remote_exception_h h, char **message)
+{
+ if (h == nullptr || message == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *message = strdup(h->message);
+ if (*message == nullptr) {
+ _E("strdup() is failed");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_remote_exception_destroy(<PREFIX>_remote_exception_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (h->message)
+ free(h->message);
+
+ free(h);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the proxy interface.
+ */
+constexpr const char CB_PROXY_REMOTE_EXCEPTION_BASE[] =
+R"__cpp_cb(
+int <PREFIX>_get_remote_exception(<PREFIX>_remote_exception_h *h)
+{
+ rpc_port_unit_map_h map;
+ int ret;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (__<PREFIX>_remote_exception == nullptr) {
+ _W("There is no exceptions");
+ *h = nullptr;
+ return RPC_PORT_ERROR_NONE;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = rpc_port_unit_map_write_remote_exception(map, "clone", __<PREFIX>_remote_exception);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to write remote exception. error(%d)", ret);
+ rpc_port_unit_map_destroy(map);
+ return ret;
+ }
+
+ rpc_port_unit_map_read_remote_exception(map, "clone", h);
+ rpc_port_unit_map_destroy(map);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__cpp_cb";
+
+constexpr const char CB_STUB_REMOTE_EXCEPTION_BASE[] =
+R"__cpp_cb(
+int <PREFIX>_remote_exception_throw(<PREFIX>_remote_exception_h h)
+{
+ rpc_port_unit_map_h map;
+ int ret;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = rpc_port_unit_map_write_remote_exception(map, "clone", h);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to write remote exception. error(%d)", ret);
+ rpc_port_unit_map_destroy(map);
+ return ret;
+ }
+
+ if (__<PREFIX>_remote_exception != nullptr) {
+ <PREFIX>_remote_exception_destroy(__<PREFIX>_remote_exception);
+ __<PREFIX>_remote_exception = nullptr;
+ }
+
+ rpc_port_unit_map_read_remote_exception(map, "clone", &__<PREFIX>_remote_exception);
+ rpc_port_unit_map_destroy(map);
+
+ return ret;
+}
+)__cpp_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_BODY_GENERATOR_BASE_CB_HH_
diff --git a/idlc/gen/version2/c_body_generator_list_base_cb.hh b/idlc/gen/version2/c_body_generator_list_base_cb.hh
new file mode 100644
index 0000000..c8d8de7
--- /dev/null
+++ b/idlc/gen/version2/c_body_generator_list_base_cb.hh
@@ -0,0 +1,491 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_BODY_GENERATOR_LIST_BASE_CB_HH_
+#define IDLC_GEN_VERSION2_C_BODY_GENERATOR_LIST_BASE_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <PREFIX> The prefix of the list structure.
+ * <NAME> The name of the list structure.
+ */
+constexpr const char CB_STRUCTURE_LIST_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ GList *list;
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the list structure.
+ * <NAME> The name of the list structure.
+ * <DATA_TYPE> The type of the data of the list.
+ * <DATA_FREE> The implementation to release the data of the list.
+ * <PARAM_TYPE_IN> The type of the parameter of the add function.
+ * <UNIT_MAP_WRITE> The implementation to write the data to the unit map.
+ * <UNIT_MAP_READ> The implementation to read the data from the unit map.
+ * <LIST_ADD> The implementation to add the data to the list.
+ * <CALLBACK_PARAM_TYPE> The type of the parameter of the callback.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_t *handle = data;
+ rpc_port_unit_map_h map;
+ <DATA_TYPE>value;
+ char index[12];
+ int i;
+ GList *iter;
+
+ if (parcel == nullptr || handle == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_unit_map_write_int(map, "length", g_list_length(handle->list));
+
+ i = 0;
+ iter = handle->list;
+ while (iter) {
+ value = iter->data;
+ iter = g_list_next(iter);
+ snprintf(index, sizeof(index), "%d", i++);
+ <UNIT_MAP_WRITE>
+ }
+
+ rpc_port_parcel_write(parcel, &map->parcelable, map);
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_t *handle = data;
+ <DATA_TYPE>value = nullptr;
+ rpc_port_unit_map_h map;
+ char index[12];
+ int len = 0;
+ int i;
+
+ if (parcel == nullptr || handle == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_parcel_read(parcel, &map->parcelable, map);
+
+ rpc_port_unit_map_read_int(parcel, "length", &len);
+
+ for (i = 0; i < len; ++i) {
+ snprintf(index, sizeof(index), "%d", i);
+ <UNIT_MAP_READ>
+ }
+
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_from;
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ <DATA_TYPE>value;
+ GList *iter;
+
+ if (handle == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (handle->list) {
+ iter = handle->list;
+ while (iter) {
+ value = iter->data;
+ iter = g_list_next(iter);
+ <DATA_FREE>
+ }
+
+ g_list_free(handle->list);
+ }
+
+ free(handle);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ rpc_port_unit_map_h map;
+ int ret;
+
+ if (handle == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = rpc_port_unit_map_write_<NAME>(map, "clone", handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to write <NAME>. error(%d)", ret);
+ rpc_port_unit_map_destroy(map);
+ return ret;
+ }
+
+ rpc_port_unit_map_read_<NAME>(map, "clone", clone);
+ rpc_port_unit_map_destroy(map);
+
+ return ret;
+}
+
+int <PREFIX>_<NAME>_add(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ <LIST_ADD>
+}
+
+int <PREFIX>_<NAME>_foreach(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_cb callback, void *user_data)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ <DATA_TYPE>value;
+ GList *iter;
+
+ if (handle == nullptr || callback == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ iter = handle->list;
+ while (iter) {
+ value = iter->data;
+ iter = g_list_next(iter);
+ if (!callback(<CALLBACK_PARAM_TYPE>, user_data))
+ break;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_remove(<PREFIX>_<NAME>_h h, unsigned int nth)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ <DATA_TYPE>value;
+ GList *found;
+
+ if (handle == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ found = g_list_nth(handle->list, nth);
+ if (found == nullptr)
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+ value = found->data;
+ handle->list = g_list_remove_link(handle->list, found);
+ <DATA_FREE>
+ g_list_free(found);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_length(<PREFIX>_<NAME>_h h, unsigned int *length)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+
+ if (handle == nullptr || length == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *length = g_list_length(handle->list);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the element.
+ */
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<TYPE_NAME>(map, index, value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_ENUM_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_int(map, index, (int)value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_bundle(map, index, value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_string(parcel, index, STRING_GET(value));
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the element.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<TYPE_NAME>(parcel, index, *value);
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the element.
+ */
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_UNIT_MAP_READ[] =
+R"__c_cb(
+value = nullptr;
+rpc_port_unit_map_read_<TYPE_NAME>(map, index, &value);
+handle->list = g_list_append(handle->list, value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_ENUM_UNIT_MAP_READ[] =
+R"__c_cb(
+value = calloc(1, sizeof(sizeof(<VALUE_TYPE>)));
+if (value == nullptr) {
+ _E("Out of memory");
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+rpc_port_unit_map_read_int(map, index, (int*)&value);
+handle->list = g_list_append(handle->list, value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_UNIT_MAP_READ[] =
+R"__c_cb(
+value = nullptr;
+rpc_port_unit_map_read_bundle(map, index, &value);
+handle->list = g_list_append(handle->list, value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_UNIT_MAP_READ[] =
+R"__c_cb(
+value = nullptr;
+rpc_port_unit_map_read_string(map, index, &value);
+handle->list = g_list_append(handle->list, value);
+)__c_cb";
+
+/**
+ * <VALUE_TYPE> The type of the value.
+ * <TYPE_NAME> The type name of the element.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE_UNIT_MAP_READ[] =
+R"__c_cb(
+value = calloc(1, sizeof(sizeof(<VALUE_TYPE>)));
+if (value == nullptr) {
+ _E("Out of memory");
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+rpc_port_unit_map_read_<TYPE_NAME>(map, index, value);
+handle->list = g_list_append(handle->list, value);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user-defined type.
+ * <NAME> The name of the user-defined type.
+ */
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_ADD[] =
+R"__c_cb(
+<PREFIX>_<NAME>_h new_value;
+int ret;
+
+if (handle == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+ret = <PREFIX>_<NAME>_clone(value, &new_value);
+if (ret != RPC_PORT_ERROR_NONE)
+ return ret;
+
+handle->list = g_list_append(handle->list, new_value);
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_ENUM_ADD[] =
+R"__c_cb(
+<VALUE_TYPE> *new_value;
+
+if (handle == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = calloc(1, sizeof(<VALUE_TYPE>));
+if (new_value == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+*new_value = value;
+
+handle->list = g_list_append(handle->list, new_value);
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_ADD[] =
+R"__c_cb(
+bundle *new_value;
+
+if (handle == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = bundle_dup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+handle->list = g_list_append(handle->list, new_value);
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_ADD[] =
+R"__c_cb(
+char *new_value;
+
+if (handle == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = strdup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+handle->list = g_list_append(handle->list, new_value);
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <VALUE_TYPE> The type of the value.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE_ADD[] =
+R"__c_cb(
+<VALUE_TYPE> *new_value;
+
+if (handle == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = calloc(1, sizeof(<VALUE_TYPE>));
+if (new_value == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+*new_value = value;
+
+handle->list = g_list_append(handle->list, new_value);
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user-defined type.
+ * <NAME> The name of the user-defined type.
+ */
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_FREE[] =
+R"__c_cb(
+<PREFIX>_<NAME>_destroy(value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_FREE[] =
+R"__c_cb(
+bundle_free(value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_FREE[] =
+R"__c_cb(
+free(value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BASE_FREE[] =
+R"__c_cb(
+free(value);
+)__c_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_BODY_GENERATOR_LIST_BASE_CB_HH_
diff --git a/idlc/gen/version2/c_body_generator_map_base_cb.hh b/idlc/gen/version2/c_body_generator_map_base_cb.hh
new file mode 100644
index 0000000..036cf37
--- /dev/null
+++ b/idlc/gen/version2/c_body_generator_map_base_cb.hh
@@ -0,0 +1,816 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_BODY_GENERATOR_MAP_BASE_CB_HH_
+#define IDLC_GEN_VERSION2_C_BODY_GENERATOR_MAP_BASE_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <PREFIX> The prefix of the map structure.
+ * <NAME> The name of the map structure.
+ */
+constexpr const char CB_STRUCTURE_MAP_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ GTree *node;
+ void *user_data;
+} <PREFIX>_<NAME>_t;
+
+typedef struct <PREFIX>_<NAME>_traverse_info_s {
+ rpc_port_unit_map_h map;
+ int number;
+} <PREFIX>_<NAME>_traverse_info_t;
+
+typedef struct <PREFIX>_<NAME>_foreach_info_s {
+ <PREFIX>_<NAME>_foreach_cb callback;
+ void *user_data;
+} <PREFIX>_<NAME>_foreach_info_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the map structure.
+ * <NAME> The name of the map structure.
+ * <KEY_TYPE> The type of the key of the map.
+ * <VALUE_TYPE> The type of the value of the map.
+ * <KEY_PARAM_TYPE> The parameter type of the key of the map.
+ * <VALUE_PARAM_TYPE> The parameter type of the value of the map.
+ * <VALUE_PARAM_TYPE_OUT> The output parameter type of the value of the map.
+ * <MAP_UNIT_MAP_KEY_WRITE> The implementation to write the key to the unit map.
+ * <MAP_UNIT_MAP_VALUE_WRITE> The implementation to write the value to the unit map.
+ * <MAP_UNIT_MAP_KEY_READ> The implementation to read the key from the unit map.
+ * <MAP_UNIT_MAP_VALUE_READ> The implementation to read the value from the unit map.
+ * <MAP_COMPARE_KEY_VARS_DEF> The definition of the key variables of the compare callback function.
+ * <MAP_COMPARE_KEY_VARS_IMPL> The implemenation to compare key variables.
+ * <MAP_KEY_FREE_FUNC> The implementation to free the key.
+ * <MAP_VALUE_FREE_FUNC> The implementation to free the value.
+ * <MAP_INSERT_ARGS_NULL_CHECK> The implementation to check whether the arg is nullptr or not.
+ * <MAP_INSERT> The implementation to insert the key and the value to the map.
+ * <MAP_LOOKUP_ARGS_NULL_CHECK> The implementation to check whether the arg is nullptr or not.
+ * <MAP_LOOKUP> The implementation to set the lookuped data to the output value.
+ * <MAP_ERASE_ARGS_NULL_CHECK> The implementation to check whether the arg is nullptr or not.
+ * <MAP_ERASE> The implementation to erase the element from the map.
+ * <MAP_REPLACE_ARGS_NULL_CHECK> The impementation to check whether the arg is nullptr or not.
+ * <MAP_FOREACH_KEY_VAR_DEF> The definition of the key variable of the foreach callback function.
+ * <MAP_FOREACH_VALUE_VAR_DEF> The definition of the value variable of the foreach callback function.
+ * <MAP_CONTAINS_ARGS_NULL_CHECK> The implementation to check whether the arg is nullptr or not.
+ * <MAP_CONTAINS> The implementation to check whether the key exists or not.
+ */
+constexpr const char CB_STRUCTURE_MAP_BASE[] =
+R"__c_cb(
+static gboolean __<PREFIX>_<NAME>_traverse_cb(gpointer key, gpointer value, gpointer user_data)
+{
+ <PREFIX>_<NAME>_traverse_info_t *info = user_data;
+ char name[32];
+
+ snprintf(name, sizeof(name), "key-%d", info->number);
+ <MAP_UNIT_MAP_KEY_WRITE>
+
+ snprintf(name, sizeof(name), "value-%d", info->number++);
+ <MAP_UNIT_MAP_VALUE_WRITE>
+
+ return FALSE;
+}
+
+static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_traverse_info_t info;
+ <PREFIX>_<NAME>_t *handle = data;
+ rpc_port_unit_map_h map;
+
+ if (parcel == nullptr || handle == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_unit_map_write_int(map, "size", g_tree_nnodes(handle->node));
+
+ info.map = map;
+ info.number = 0;
+ g_tree_foreach(handle->node, __<PREFIX>_<NAME>_traverse_cb, &info);
+
+ rpc_port_parcel_write(parcel, &map->parcelable, map);
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_t *handle = data;
+ <KEY_TYPE>key;
+ <VALUE_TYPE>value;
+ rpc_port_unit_map_h map;
+ char name[32];
+ int size = 0;
+ int ret;
+ int i;
+
+ if (parcel == nullptr || handle == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_parcel_read(parcel, &map->parcelable, map);
+
+ rpc_port_unit_map_read_int(map, "size", &size);
+
+ for (i = 0; i < size; ++i) {
+ snprintf(name, sizeof(name), "key-%d", i);
+ <MAP_UNIT_MAP_KEY_READ>
+ snprintf(name, sizeof(name), "value-%d", i);
+ <MAP_UNIT_MAP_VALUE_READ>
+
+ ret = <PREFIX>_<NAME>_insert(handle, key, value);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ rpc_port_unit_map_destroy(map);
+ set_last_result(ret);
+ return;
+ }
+ }
+
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static gint __<PREFIX>_<NAME>_comparison_cb(gconstpointer a, gconstpointer b, gpointer user_data)
+{
+ <MAP_COMPARE_KEY_VARS_DEF>
+
+ <MAP_COMPARE_KEY_VARS_IMPL>
+}
+
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->node = g_tree_new_full((GCompareDataFunc)__<PREFIX>_<NAME>_comparison_cb, handle, (GDestroyNotify)<MAP_KEY_FREE_FUNC>, (GDestroyNotify)<MAP_VALUE_FREE_FUNC>);
+ if (handle->node == nullptr) {
+ _E("g_tree_new_full() is failed");
+ free(handle);
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_from;
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+
+ if (handle == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (handle->node)
+ g_tree_destroy(handle->node);
+
+ free(handle);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ rpc_port_unit_map_h map;
+ int ret;
+
+ if (handle == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = rpc_port_unit_map_write_<NAME>(map, "clone", handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to write <NAME>. error(%d)", ret);
+ rpc_port_unit_map_destroy(map);
+ return ret;
+ }
+
+ rpc_port_unit_map_read_<NAME>(map, "clone", clone);
+ rpc_port_unit_map_destroy(map);
+
+ return ret;
+}
+
+int <PREFIX>_<NAME>_insert(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key, <VALUE_PARAM_TYPE>value)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ int ret;
+
+ if (<MAP_INSERT_ARGS_NULL_CHECK>) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ <MAP_INSERT>
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_lookup(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key, <VALUE_PARAM_TYPE_OUT>value)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ gpointer data;
+
+ if (<MAP_LOOKUP_ARGS_NULL_CHECK>) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ <MAP_LOOKUP>
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_erase(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+
+ if (<MAP_ERASE_ARGS_NULL_CHECK>) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ <MAP_ERASE>
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_replace(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key, <VALUE_PARAM_TYPE>value)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+
+ if (<MAP_REPLACE_ARGS_NULL_CHECK>) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ <PREFIX>_<NAME>_erase(handle, key);
+ return <PREFIX>_<NAME>_insert(handle, key, value);
+}
+
+static gboolean __<PREFIX>_<NAME>_foreach_cb(gpointer key, gpointer value, gpointer user_data)
+{
+ <PREFIX>_<NAME>_foreach_info_t *info = user_data;
+ <MAP_FOREACH_VARS_DEF>
+
+ return !info->callback(tmp_key, tmp_value, info->user_data);
+}
+
+int <PREFIX>_<NAME>_foreach(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_foreach_cb callback, void *user_data)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ <PREFIX>_<NAME>_foreach_info_t info;
+
+ if (handle == nullptr || callback == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ info.callback = callback;
+ info.user_data = user_data;
+
+ g_tree_foreach(handle->node, __<PREFIX>_<NAME>_foreach_cb, &info);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_contains(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key, bool *exist)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ gpointer data;
+
+ if (<MAP_CONTAINS_ARGS_NULL_CHECK>) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ <MAP_CONTAINS>
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_size(<PREFIX>_<NAME>_h h, size_t *size)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+
+ if (handle == nullptr || size == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *size = g_tree_nnodes(handle->node);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_clear(<PREFIX>_<NAME>_h h)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+
+ if (handle == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_tree_remove_all(handle->node);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+constexpr const char CB_MAP_STRING_COMPARISION_IMPL[] =
+R"__c_cb(
+return strcmp(key_a, key_b);
+)__c_cb";
+
+constexpr const char CB_MAP_BASE_COMPARISION_IMPL[] =
+R"__c_cb(
+if (key_a == key_b)
+ return 0;
+
+if (key_a > key_b)
+ return 1;
+
+return -1;
+)__c_cb";
+
+constexpr const char CB_MAP_BOOL_COMPARISION_IMPL[] =
+R"__c_cb(
+if (key_a == key_b)
+ return 0;
+
+return -1;
+)__c_cb";
+
+/**
+ * <KEY> The name of the key.
+ * <KEY_TYPE> The type of the key.
+ */
+constexpr const char CB_MAP_UNIT_MAP_KEY_WRITE_PTR_TYPE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<KEY>(info->map, name, (<KEY_TYPE>)key);
+)__c_cb";
+
+/**
+ * <KEY> The name of the key.
+ * <KEY_TYPE> The pointer type of the key.
+ */
+constexpr const char CB_MAP_UNIT_MAP_KEY_WRITE_BASE_TYPE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<KEY>(info->map, name, *(<KEY_TYPE> *)key);
+)__c_cb";
+
+constexpr const char CB_MAP_UNIT_MAP_KEY_ENUM_BASE_TYPE[] =
+R"__c_cb(
+rpc_port_unit_map_write_int(info->map, name, *(int *)key);
+)__c_cb";
+
+/**
+ * <VALUE> The name of the value.
+ * <VALUE_TYPE> The type of the value.
+ */
+constexpr const char CB_MAP_UNIT_MAP_VALUE_WRITE_PTR_TYPE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<VALUE>(info->map, name, (<VALUE_TYPE>)value);
+)__c_cb";
+
+constexpr const char CB_MAP_UNIT_MAP_VALUE_WRITE_ENUM_TYPE[] =
+R"__c_cb(
+rpc_port_unit_map_write_int(info->map, name, *(int *)value);
+)__c_cb";
+
+/**
+ * <VALUE> The name of the value.
+ * <VALUE_TYPE> The pointer type of the value.
+ */
+constexpr const char CB_MAP_UNIT_MAP_VALUE_WRITE_BASE_TYPE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<VALUE>(info->map, name, *(<VALUE_TYPE> *)value);
+)__c_cb";
+
+/**
+ * <KEY> The name of the key.
+ */
+constexpr const char CB_MAP_UNIT_MAP_KEY_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_<KEY>(map, name, &key);
+)__c_cb";
+
+constexpr const char CB_MAP_UNIT_MAP_KEY_ENUM_TYPE_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_int(map, name, (int *)&key);
+)__c_cb";
+
+/**
+ * <VALUE> The name of the value.
+ */
+constexpr const char CB_MAP_UNIT_MAP_VALUE_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_<VALUE>(map, name, &value);
+)__c_cb";
+
+constexpr const char CB_MAP_UNIT_MAP_VALUE_ENUM_TYPE_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_int(map, name, (int *)&value);
+)__c_cb";
+
+/**
+ * <KEY_TYPE> The type of the key.
+ */
+constexpr const char CB_MAP_COMPARE_KEY_VARS_DEF_PTR_TYPE[] =
+R"__c_cb(
+<KEY_TYPE> key_a = (<KEY_TYPE>)a;
+<KEY_TYPE> key_b = (<KEY_TYPE>)b;
+)__c_cb";
+
+/**
+ * <KEY_TYPE> The type of the key.
+ */
+constexpr const char CB_MAP_COMPARE_KEY_VARS_DEF_BASE_TYPE[] =
+R"__c_cb(
+<KEY_TYPE> key_a = *(<KEY_TYPE> *)a;
+<KEY_TYPE> key_b = *(<KEY_TYPE> *)b;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user defined type.
+ * <NAME> The name of the user defined type.
+ */
+constexpr const char CB_MAP_USER_DEFINED_FREE_FUNC[] =
+R"__c_cb(<PREFIX>_<NAME>_destroy)__c_cb";
+
+constexpr const char CB_MAP_BUNDLE_FREE_FUNC[] =
+R"__c_cb(bundle_free)__c_cb";
+
+constexpr const char CB_MAP_FREE_FUNC[] =
+R"__c_cb(free)__c_cb";
+
+constexpr const char CB_MAP_HANDLE_KEY_VALUE_NULL_CHECK[] =
+R"__c_cb(handle == nullptr || key == nullptr || value == nullptr)__c_cb";
+
+constexpr const char CB_MAP_HANDLE_KEY_NULL_CHECK[] =
+R"__c_cb(handle == nullptr || key == nullptr)__c_cb";
+
+constexpr const char CB_MAP_HANDLE_VALUE_NULL_CHECK[] =
+R"__c_cb(handle == nullptr || value == nullptr)__c_cb";
+
+constexpr const char CB_MAP_HANDLE_KEY_EXIST_NULL_CHECK[] =
+R"__c_cb(handle == nullptr || key == nullptr || exist == nullptr)__c_cb";
+
+constexpr const char CB_MAP_HANDLE_EXIST_NULL_CHECK[] =
+R"__c_cb(handle == nullptr || exist == nullptr)__c_cb";
+
+constexpr const char CB_MAP_HANDLE_NULL_CHECK[] =
+R"__c_cb(handle == nullptr)__c_cb";
+
+/**
+ * <MAP_INSERT_NEW_KEY_IMPL> The implementation to create a new varaible of the key for the map container.
+ * <MAP_INSERT_NEW_VALUE_IMPL> The implementation to create a new varaible of the value for the map container.
+ */
+constexpr const char CB_MAP_INSERT[] =
+R"__c_cb(
+<MAP_INSERT_NEW_KEY_IMPL>
+<MAP_INSERT_NEW_VALUE_IMPL>
+
+g_tree_insert(handle->node, (gpointer)new_key, (gpointer)new_value);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user defined type.
+ * <NAME> The name of the user defined type.
+ */
+constexpr const char CB_MAP_INSERT_NEW_KEY_USER_DEFINED_IMPL[] =
+R"__c_cb(
+if (g_tree_lookup(handle->node, (gpointer)key) != nullptr) {
+ _E("Already exists. Try to use replace function");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+<PREFIX>_<NAME>_t *new_key = nullptr;
+ret = <PREFIX>_<NAME>_clone(key, (<PREFIX>_<NAME>_h *)&new_key);
+if (ret != RPC_PORT_ERROR_NONE)
+ return ret;
+)__c_cb";
+
+constexpr const char CB_MAP_INSERT_NEW_KEY_BUNDLE_IMPL[] =
+R"__c_cb(
+if (g_tree_lookup(handle->node, (gpointer)key) != nullptr) {
+ _E("Already exists. Try to use replace function");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+bundle *new_key = bundle_dup(key);
+if (new_key == nullptr) {
+ ret = RPC_PORT_ERROR_INVALID_PARAMETER;
+ return ret;
+}
+)__c_cb";
+
+constexpr const char CB_MAP_INSERT_NEW_KEY_STRING_IMPL[] =
+R"__c_cb(
+if (g_tree_lookup(handle->node, (gpointer)key) != nullptr) {
+ _E("Already exists. Try to use replace function");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+char *new_key = strdup(key);
+if (new_key == nullptr) {
+ ret = RPC_PORT_ERROR_INVALID_PARAMETER;
+ return ret;
+}
+)__c_cb";
+
+/**
+ * <KEY_TYPE> The type of the key.
+ */
+constexpr const char CB_MAP_INSERT_NEW_KEY_BASE_IMPL[] =
+R"__c_cb(
+<KEY_TYPE> *new_key = malloc(sizeof(<KEY_TYPE>));
+if (new_key == nullptr) {
+ _E("malloc() is failed");
+ ret = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ return ret;
+}
+
+*new_key = key;
+if (g_tree_lookup(handle->node, (gpointer)new_key) != nullptr) {
+ _E("Already exists. Try to use replace function");
+ free(new_key);
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user defined type.
+ * <NAME> The name of the user defined type.
+ * <MAP_INSERT_NEW_KEY_FREE> The implementation to free the newly key variable.
+ */
+constexpr const char CB_MAP_INSERT_NEW_VALUE_USER_DEFINED_IMPL[] =
+R"__c_cb(
+<PREFIX>_<NAME>_t *new_value = nullptr;
+ret = <PREFIX>_<NAME>_clone(value, (<PREFIX>_<NAME>_h *)&new_value);
+if (ret != RPC_PORT_ERROR_NONE) {
+ <MAP_INSERT_NEW_KEY_FREE>
+ return ret;
+}
+)__c_cb";
+
+/**
+ * <MAP_INSERT_NEW_KEY_FREE> The implementation to free the newly key variable.
+ */
+constexpr const char CB_MAP_INSERT_NEW_VALUE_BUNDLE_IMPL[] =
+R"__c_cb(
+bundle *new_value = bundle_dup(value);
+if (new_value == nullptr) {
+ <MAP_INSERT_NEW_KEY_FREE>
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+)__c_cb";
+
+/**
+ * <MAP_INSERT_NEW_KEY_FREE> The implementation to free the newly key variable.
+ */
+constexpr const char CB_MAP_INSERT_NEW_VALUE_STRING_IMPL[] =
+R"__c_cb(
+char *new_value = strdup(value);
+if (new_value == nullptr) {
+ <MAP_INSERT_NEW_KEY_FREE>
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+)__c_cb";
+
+/**
+ * <VALUE_TYPE> The type of the value.
+ * <MAP_INSERT_NEW_KEY_FREE> The implementation to free the newly key variable.
+ */
+constexpr const char CB_MAP_INSERT_NEW_VALUE_BASE_IMPL[] =
+R"__c_cb(
+<VALUE_TYPE> *new_value = malloc(sizeof(<VALUE_TYPE>));
+if (new_value == nullptr) {
+ <MAP_INSERT_NEW_KEY_FREE>
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+*new_value = value;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user defined type.
+ * <NAME> The name of the user defined type.
+ */
+constexpr const char CB_MAP_INSERT_NEW_KEY_USER_DEFINED_FREE[] =
+R"__c_cb(
+<PREFIX>_<NAME>_destroy(new_key);
+)__c_cb";
+
+constexpr const char CB_MAP_INSERT_NEW_KEY_BUNDLE_FREE[] =
+R"__c_cb(
+bundle_free(new_key);
+)__c_cb";
+
+constexpr const char CB_MAP_INSERT_NEW_KEY_STRING_FREE[] =
+R"__c_cb(
+free(new_key);
+)__c_cb";
+
+constexpr const char CB_MAP_INSERT_NEW_KEY_BASE_FREE[] =
+R"__c_cb(
+free(new_key);
+)__c_cb";
+
+/**
+ * <MAP_LOOKUP_VALUE_SET> The implementation to set the value for the map container.
+ */
+constexpr const char CB_MAP_LOOKUP_KEY_PTR_TYPE[] =
+R"__c_cb(
+data = g_tree_lookup(handle->node, (gpointer)key);
+if (data == nullptr) {
+ _E("g_tree_lookup() is failed");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+<MAP_LOOKUP_VALUE_SET>
+)__c_cb";
+
+/**
+ * <MAP_LOOKUP_VALUE_SET> The implementation to set the value for the map container.
+ */
+constexpr const char CB_MAP_LOOKUP_KEY_BASE_TYPE[] =
+R"__c_cb(
+data = g_tree_lookup(handle->node, (gpointer)&key);
+if (data == nullptr) {
+ _E("g_tree_lookup() is failed");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+<MAP_LOOKUP_VALUE_SET>
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user defined type.
+ * <NAME> The name of the user defined type.
+ */
+constexpr const char CB_MAP_LOOKUP_VALUE_USER_DEFINED_SET[] =
+R"__c_cb(
+<PREFIX>_<NAME>_t *new_value = nullptr;
+int ret = <PREFIX>_<NAME>_clone((<PREFIX>_<NAME>_h)data, (<PREFIX>_<NAME>_h *)&new_value);
+if (ret != RPC_PORT_ERROR_NONE)
+ return ret;
+
+*value = (<PREFIX>_<NAME>_h)new_value;
+)__c_cb";
+
+constexpr const char CB_MAP_LOOKUP_VALUE_BUNDLE_SET[] =
+R"__c_cb(
+bundle *new_value = bundle_dup((bundle *)data);
+if (new_value == nullptr) {
+ _E("bundle_dup() is failed");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+*value = new_value;
+)__c_cb";
+
+constexpr const char CB_MAP_LOOKUP_VALUE_STRING_SET[] =
+R"__c_cb(
+char *new_value = strdup((char *)data);
+if (new_value == nullptr) {
+ _E("strdup() is failed");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+*value = new_value;
+)__c_cb";
+
+/**
+ * <VALUE_TYPE> The type of the value.
+ */
+constexpr const char CB_MAP_LOOKUP_VALUE_BASE_SET[] =
+R"__c_cb(
+*value = *(<VALUE_TYPE> *)data;
+)__c_cb";
+
+constexpr const char CB_MAP_ERASE_KEY_PTR_TYPE[] =
+R"__c_cb(
+if (!g_tree_remove(handle->node, (gpointer)key))
+ _W("g_tree_remove() is failed");
+)__c_cb";
+
+constexpr const char CB_MAP_ERASE_KEY_BASE_TYPE[] =
+R"__c_cb(
+if (!g_tree_remove(handle->node, (gpointer)&key))
+ _W("g_tree_remove() is failed");
+)__c_cb";
+
+/**
+ * <KEY_TYPE> The type of the key.
+ * <VALUE_TYPE> the type of the value.
+ */
+constexpr const char CB_MAP_FOREACH_VARS_DEF_KEY_PTR_VALUE_PTR_TYPE[] =
+R"__c_cb(
+<KEY_TYPE> tmp_key = (<KEY_TYPE>)key;
+<VALUE_TYPE> tmp_value = (<VALUE_TYPE>)value;
+)__c_cb";
+
+/**
+ * <KEY_TYPE> The type of the key.
+ * <VALUE_TYPE> the type of the value.
+ */
+constexpr const char CB_MAP_FOREACH_VARS_DEF_KEY_PTR_VALUE_BASE_TYPE[] =
+R"__c_cb(
+<KEY_TYPE> tmp_key = (<KEY_TYPE>)key;
+<VALUE_TYPE> tmp_value = *(<VALUE_TYPE> *)value;
+)__c_cb";
+
+/**
+ * <KEY_TYPE> The type of the key.
+ * <VALUE_TYPE> the type of the value.
+ */
+constexpr const char CB_MAP_FOREACH_VARS_DEF_KEY_BASE_VALUE_PTR_TYPE[] =
+R"__c_cb(
+<KEY_TYPE> tmp_key = *(<KEY_TYPE> *)key;
+<VALUE_TYPE> tmp_value = (<VALUE_TYPE>)value;
+)__c_cb";
+
+/**
+ * <KEY_TYPE> The type of the key.
+ * <VALUE_TYPE> the type of the value.
+ */
+constexpr const char CB_MAP_FOREACH_VARS_DEF_KEY_BASE_VALUE_BASE_TYPE[] =
+R"__c_cb(
+<KEY_TYPE> tmp_key = *(<KEY_TYPE> *)key;
+<VALUE_TYPE> tmp_value = *(<VALUE_TYPE> *)value;
+)__c_cb";
+
+constexpr const char CB_MAP_CONTAINS_KEY_PTR_TYPE[] =
+R"__c_cb(
+data = g_tree_lookup(handle->node, (gpointer)key);
+*exist = (data != nullptr) ? true : false;
+)__c_cb";
+
+constexpr const char CB_MAP_CONTAINS_KEY_BASE_TYPE[] =
+R"__c_cb(
+data = g_tree_lookup(handle->node, (gpointer)&key);
+*exist = (data != nullptr) ? true : false;
+)__c_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_BODY_GENERATOR_MAP_BASE_CB_HH_
diff --git a/idlc/gen/version2/c_body_generator_set_base_cb.hh b/idlc/gen/version2/c_body_generator_set_base_cb.hh
new file mode 100644
index 0000000..124526c
--- /dev/null
+++ b/idlc/gen/version2/c_body_generator_set_base_cb.hh
@@ -0,0 +1,528 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_BODY_GENERATOR_SET_BASE_CB_HH_
+#define IDLC_GEN_VERSION2_C_BODY_GENERATOR_SET_BASE_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <PREFIX> The prefix of the set structure.
+ * <NAME> The name of the set structure.
+ */
+constexpr const char CB_STRUCTURE_SET_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ GTree *node;
+} <PREFIX>_<NAME>_t;
+
+typedef struct <PREFIX>_<NAME>_traverse_info_s {
+ rpc_port_unit_map_h map;
+ int number;
+} <PREFIX>_<NAME>_traverse_info_t;
+
+typedef struct <PREFIX>_<NAME>_foreach_info_s {
+ <PREFIX>_<NAME>_foreach_cb callback;
+ void *user_data;
+} <PREFIX>_<NAME>_foreach_info_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the set structure.
+ * <NAME> The name of the set structure.
+ * <KEY_TYPE> The type of the key of the set.
+ * <KEY_PARAM_TYPE> The parameter type of the key of the set.
+ * <SET_UNIT_MAP_KEY_WRITE> The implementation to write the key to the unit map.
+ * <SET_UNIT_MAP_KEY_READ> The implementation to read the key from the unit map.
+ * <SET_COMPARE_KEY_VARS_DEF> The definition of the key variables of the compare callback function.
+ * <SET_COMPARE_KEY_VARS_IMPL> The implementation to compare key variables.
+ * <SET_KEY_FREE_FUNC> The implementation to free the key.
+ * <SET_INSERT_ARGS_NULL_CHECK> The implementation to check whether the arg is nullptr or not.
+ * <SET_INSERT> The implementation to insert the key and the value to the set.
+ * <SET_ERASE_ARGS_NULL_CHECK> The implementation to check whether the arg is nullptr or not.
+ * <SET_ERASE> The implementation to erase the element from the set.
+ * <SET_FOREACH_KEY_VAR_DEF> The definition of the key variable of the foreach callback function.
+ * <SET_CONTAINS_ARGS_NULL_CHECK> The implementation to check whether the arg is nullptr or not.
+ * <SET_CONTAINS> The implementation to check whether the key exists or not.
+ */
+constexpr const char CB_STRUCTURE_SET_BASE[] =
+R"__c_cb(
+static gboolean __<PREFIX>_<NAME>_traverse_cb(gpointer key, gpointer value, gpointer user_data)
+{
+ <PREFIX>_<NAME>_traverse_info_t *info = user_data;
+ char name[32];
+
+ snprintf(name, sizeof(name), "key-%d", info->number++);
+ <SET_UNIT_MAP_KEY_WRITE>
+
+ return FALSE;
+}
+
+static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_traverse_info_t info;
+ <PREFIX>_<NAME>_t *handle = data;
+ rpc_port_unit_map_h map;
+
+ if (parcel == nullptr || handle == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_unit_map_write_int(map, "size", g_tree_nnodes(handle->node));
+
+ info.map = map;
+ info.number = 0;
+ g_tree_foreach(handle->node, __<PREFIX>_<NAME>_traverse_cb, &info);
+
+ rpc_port_parcel_write(parcel, &map->parcelable, map);
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_t *handle = data;
+ <KEY_TYPE>key;
+ rpc_port_unit_map_h map;
+ char name[32];
+ int size = 0;
+ int ret;
+ int i;
+
+ if (parcel == nullptr || handle == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_parcel_read(parcel, &map->parcelable, map);
+
+ rpc_port_unit_map_read_int(map, "size", &size);
+
+ for (i = 0; i < size; ++i) {
+ snprintf(name, sizeof(name), "key-%d", i);
+ <SET_UNIT_MAP_KEY_READ>
+
+ ret = <PREFIX>_<NAME>_insert(handle, key);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ rpc_port_unit_map_destroy(map);
+ set_last_result(ret);
+ return;
+ }
+ }
+
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static gint __<PREFIX>_<NAME>_comparison_cb(gconstpointer a, gconstpointer b, gpointer user_data)
+{
+ <SET_COMPARE_KEY_VARS_DEF>
+
+ <SET_COMPARE_KEY_VARS_IMPL>
+}
+
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->node = g_tree_new_full((GCompareDataFunc)__<PREFIX>_<NAME>_comparison_cb, handle, (GDestroyNotify)<SET_KEY_FREE_FUNC>, nullptr);
+ if (handle->node == nullptr) {
+ _E("g_tree_new_full() is failed");
+ free(handle);
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_from;
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+
+ if (handle == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (handle->node)
+ g_tree_destroy(handle->node);
+
+ free(handle);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ rpc_port_unit_map_h map;
+ int ret;
+
+ if (handle == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = rpc_port_unit_map_write_<NAME>(map, "clone", handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to write <NAME>. error(%d)", ret);
+ rpc_port_unit_map_destroy(map);
+ return ret;
+ }
+
+ rpc_port_unit_map_read_<NAME>(map, "clone", clone);
+ rpc_port_unit_map_destroy(map);
+
+ return ret;
+}
+
+int <PREFIX>_<NAME>_insert(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+
+ if (<SET_INSERT_ARGS_NULL_CHECK>) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ <SET_INSERT>
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_erase(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+
+ if (<SET_ERASE_ARGS_NULL_CHECK>) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ <SET_ERASE>
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+static gboolean __<PREFIX>_<NAME>_foreach_cb(gpointer key, gpointer value, gpointer user_data)
+{
+ <PREFIX>_<NAME>_foreach_info_t *info = user_data;
+ <SET_FOREACH_VARS_DEF>
+
+ return !info->callback(tmp_key, info->user_data);
+}
+
+int <PREFIX>_<NAME>_foreach(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_foreach_cb callback, void *user_data)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ <PREFIX>_<NAME>_foreach_info_t info;
+
+ if (handle == nullptr || callback == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ info.callback = callback;
+ info.user_data = user_data;
+
+ g_tree_foreach(handle->node, __<PREFIX>_<NAME>_foreach_cb, &info);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_contains(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key, bool *exist)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+ gpointer data;
+
+ if (<SET_CONTAINS_ARGS_NULL_CHECK>) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ <SET_CONTAINS>
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_size(<PREFIX>_<NAME>_h h, size_t *size)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+
+ if (handle == nullptr || size == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *size = g_tree_nnodes(handle->node);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_clear(<PREFIX>_<NAME>_h h)
+{
+ <PREFIX>_<NAME>_t *handle = h;
+
+ if (handle == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_tree_remove_all(handle->node);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+constexpr const char CB_SET_STRING_COMPARISION_IMPL[] =
+R"__c_cb(
+return strcmp(key_a, key_b);
+)__c_cb";
+
+constexpr const char CB_SET_BASE_COMPARISION_IMPL[] =
+R"__c_cb(
+if (key_a == key_b)
+ return 0;
+
+if (key_a > key_b)
+ return 1;
+
+return -1;
+)__c_cb";
+
+constexpr const char CB_SET_BOOL_COMPARISION_IMPL[] =
+R"__c_cb(
+if (key_a == key_b)
+ return 0;
+
+return -1;
+)__c_cb";
+
+/**
+ * <KEY> The name of the key.
+ * <KEY_TYPE> The type of the key.
+ */
+constexpr const char CB_SET_UNIT_MAP_KEY_WRITE_PTR_TYPE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<KEY>(info->map, name, (<KEY_TYPE>)key);
+)__c_cb";
+
+constexpr const char CB_SET_UNIT_MAP_KEY_WRITE_ENUM_TYPE[] =
+R"__c_cb(
+rpc_port_unit_map_write_int(info->map, name, *(int *)key);
+)__c_cb";
+
+/**
+ * <KEY> The name of the key.
+ * <KEY_TYPE> The pointer type of the key.
+ */
+constexpr const char CB_SET_UNIT_MAP_KEY_WRITE_BASE_TYPE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<KEY>(info->map, name, *(<KEY_TYPE> *)key);
+)__c_cb";
+
+constexpr const char CB_SET_UNIT_MAP_KEY_ENUM_TYPE_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_int(map, name, (int *)&key);
+)__c_cb";
+
+/**
+ * <KEY> The name of the key.
+ */
+constexpr const char CB_SET_UNIT_MAP_KEY_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_<KEY>(map, name, &key);
+)__c_cb";
+
+/**
+ * <KEY_TYPE> The type of the key.
+ */
+constexpr const char CB_SET_COMPARE_KEY_VARS_DEF_PTR_TYPE[] =
+R"__c_cb(
+<KEY_TYPE> key_a = (<KEY_TYPE>)a;
+<KEY_TYPE> key_b = (<KEY_TYPE>)b;
+)__c_cb";
+
+/**
+ * <KEY_TYPE> The type of the key.
+ */
+constexpr const char CB_SET_COMPARE_KEY_VARS_DEF_BASE_TYPE[] =
+R"__c_cb(
+<KEY_TYPE> key_a = *(<KEY_TYPE> *)a;
+<KEY_TYPE> key_b = *(<KEY_TYPE> *)b;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user defined type.
+ * <NAME> The name of the user defined type.
+ */
+constexpr const char CB_SET_USER_DEFINED_FREE_FUNC[] =
+R"__c_cb(<PREFIX>_<NAME>_destroy)__c_cb";
+
+constexpr const char CB_SET_BUNDLE_FREE_FUNC[] =
+R"__c_cb(bundle_free)__c_cb";
+
+constexpr const char CB_SET_FREE_FUNC[] =
+R"__c_cb(free)__c_cb";
+
+constexpr const char CB_SET_HANDLE_KEY_NULL_CHECK[] =
+R"__c_cb(handle == nullptr || key == nullptr)__c_cb";
+
+constexpr const char CB_SET_HANDLE_KEY_EXIST_NULL_CHECK[] =
+R"__c_cb(handle == nullptr || key == nullptr || exist == nullptr)__c_cb";
+
+constexpr const char CB_SET_HANDLE_EXIST_NULL_CHECK[] =
+R"__c_cb(handle == nullptr || exist == nullptr)__c_cb";
+
+constexpr const char CB_SET_HANDLE_NULL_CHECK[] =
+R"__c_cb(handle == nullptr)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user defined type.
+ * <NAME> The name of the user defined type.
+ */
+constexpr const char CB_SET_INSERT_KEY_USER_DEFINED_IMPL[] =
+R"__c_cb(
+<PREFIX>_<NAME>_t *new_key = nullptr;
+int ret = <PREFIX>_<NAME>_clone(key, (<PREFIX>_<NAME>_h *)&new_key);
+if (ret != RPC_PORT_ERROR_NONE)
+ return ret;
+
+g_tree_replace(handle->node, (gpointer)new_key, nullptr);
+)__c_cb";
+
+constexpr const char CB_SET_INSERT_KEY_BUNDLE_IMPL[] =
+R"__c_cb(
+bundle *new_key = bundle_dup(key);
+if (new_key == nullptr) {
+ _E("bundle_dup() is failed");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+g_tree_replace(handle->node, (gpointer)new_key, nullptr);
+)__c_cb";
+
+constexpr const char CB_SET_INSERT_KEY_STRING_IMPL[] =
+R"__c_cb(
+char *new_key = strdup(key);
+if (new_key == nullptr) {
+ _E("strdup() is failed");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+g_tree_replace(handle->node, (gpointer)new_key, nullptr);
+)__c_cb";
+
+/**
+ * <KEY_TYPE The type of the key.
+ */
+constexpr const char CB_SET_INSERT_KEY_BASE_IMPL[] =
+R"__c_cb(
+<KEY_TYPE> *new_key = malloc(sizeof(<KEY_TYPE>));
+if (new_key == nullptr) {
+ _E("malloc() is failed");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+*new_key = key;
+g_tree_replace(handle->node, (gpointer)new_key, nullptr);
+)__c_cb";
+
+constexpr const char CB_SET_ERASE_KEY_PTR_TYPE[] =
+R"__c_cb(
+if (!g_tree_remove(handle->node, (gpointer)key))
+ _W("g_tree_remove() is failed");
+)__c_cb";
+
+constexpr const char CB_SET_ERASE_KEY_BASE_TYPE[] =
+R"__c_cb(
+if (!g_tree_remove(handle->node, &key))
+ _W("g_tree_remove() is failed");
+)__c_cb";
+
+/**
+ * <KEY_TYPE> The type of the key.
+ */
+constexpr const char CB_SET_FOREACH_VARS_DEF_KEY_PTR_TYPE[] =
+R"__c_cb(
+<KEY_TYPE> tmp_key = (<KEY_TYPE>)key;
+)__c_cb";
+
+/**
+ * <KEY_TYPE> The type of the key.
+ */
+constexpr const char CB_SET_FOREACH_VARS_DEF_KEY_BASE_TYPE[] =
+R"__c_cb(
+<KEY_TYPE> tmp_key = *(<KEY_TYPE> *)key;
+)__c_cb";
+
+constexpr const char CB_SET_CONTAINS_KEY_PTR_TYPE[] =
+R"__c_cb(
+data = g_tree_lookup(handle->node, (gpointer)key);
+*exist = (data != nullptr) ? true : false;
+)__c_cb";
+
+constexpr const char CB_SET_CONTAINS_KEY_BASE_TYPE[] =
+R"__c_cb(
+data = g_tree_lookup(handle->node, &key);
+*exist = (data != nullptr) ? true : false;
+)__c_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_BODY_GENERATOR_SET_BASE_CB_HH_
diff --git a/idlc/gen/version2/c_group_body_generator.cc b/idlc/gen/version2/c_group_body_generator.cc
new file mode 100644
index 0000000..e06ca31
--- /dev/null
+++ b/idlc/gen/version2/c_group_body_generator.cc
@@ -0,0 +1,516 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+
+#include "idlc/gen/version2/c_group_body_generator.hh"
+
+namespace {
+#include "idlc/gen/version2/c_group_body_generator_cb.hh"
+
+constexpr const char PREFIX_RPC_PORT_GROUP[] = "rpc_port_group";
+}
+
+namespace tidl {
+namespace version2 {
+
+CGroupBodyGenerator::CGroupBodyGenerator(std::shared_ptr<Document> doc)
+ : CBodyGeneratorBase(doc) {
+}
+
+void CGroupBodyGenerator::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenGNUSourceDefinition(stream);
+ GenIncludeDefaultHeaders(stream, true);
+ GenIncludeHeader(stream);
+ GenLogTag(stream, std::string("RPC_PORT_GROUP"));
+ GenLogDefinition(stream);
+ GenVersionDefinition(stream);
+ GenBaseDefinition(stream);
+ GenUnitMapDefinition(stream);
+ GenInterfaceMethodHandlerType(stream);
+ GenInterfaceEnums(stream);
+ GenStructureDefinition(stream);
+ GenInterfaceDefinition(stream);
+ GenUnitMapBase(stream);
+ GenHelper(stream);
+ GenStructure(stream);
+ GenInterfaces(stream);
+}
+
+void CGroupBodyGenerator::OnFiniGen(std::ofstream& stream) {
+}
+
+std::string CGroupBodyGenerator::GetHandlePrefix() {
+ std::string prefix = PREFIX_RPC_PORT_GROUP;
+ if (!HasNamespace())
+ return prefix;
+
+ return prefix + "_" + GetFileNamespace();
+}
+
+void CGroupBodyGenerator::GenIncludeDefaultHeaders(std::ofstream& stream, bool body) {
+ CGeneratorBase::GenIncludeDefaultHeaders(stream, body);
+ stream << CB_INTERFACE_EXTRA_HEADER;
+}
+
+void CGroupBodyGenerator::GenHelper(std::ofstream& stream) {
+ stream << SmartIndent(CB_HELPER);
+}
+
+void CGroupBodyGenerator::GenInterfaceDefinition(std::ofstream& stream) {
+ for (auto& iter : GetDocument().GetBlocks()) {
+ if (iter->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const auto& iface = static_cast<const Interface&>(*iter);
+ GenInterfaceBaseDefinition(stream, iface);
+ }
+}
+
+void CGroupBodyGenerator::GenInterfaceBaseDefinition(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_BASE_DEF)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+}
+
+void CGroupBodyGenerator::GenInterfaceEnums(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceEnum(stream, iface);
+ }
+}
+
+// @see #CB_INTERFACE_METHOD_ENUM
+std::string CGroupBodyGenerator::GenMethodEnums(const Interface& iface) {
+ std::string method_enums;
+
+ for (const auto& d : iface.GetDeclarations()) {
+ std::string method_enum(ReplaceAll(CB_INTERFACE_METHOD_ENUM, {
+ { "<UPPERCASE_PREFIX>", GetHandlePrefix() },
+ { "<UPPERCASE_NAME>", iface.GetID() },
+ { "<UPPERCASE_METHOD_NAME>", d->GetID() }
+ }));
+
+ method_enums += RemoveLine(method_enum);
+ }
+ std::transform(method_enums.begin(), method_enums.end(), method_enums.begin(),
+ ::toupper);
+
+ return method_enums;
+}
+
+void CGroupBodyGenerator::GenInterfaceEnum(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_ENUMS>", GenMethodEnums(iface) }
+ })
+ .Transform([&](std::string str){
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+void CGroupBodyGenerator::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CGroupBodyGenerator::GenInterface(std::ofstream& stream, const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ GenInterfaceMethodHandlerBase(stream, iface, *d);
+ }
+
+ GenInterfaceMethodTable(stream, iface);
+ GenInterfaceBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ GenInterfaceMethodBase(stream, iface, *d);
+ }
+}
+
+// @see #CB_INTERFACE_METHOD_TABLE
+void CGroupBodyGenerator::GenInterfaceMethodTable(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_METHOD_TABLE, {
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_HANDLERS>", GenMethodHandlers(iface) }
+ })
+ .Transform([&](std::string str){
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER
+std::string CGroupBodyGenerator::GenMethodHandlers(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_METHOD_" + d->GetID();
+ std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
+ ::toupper);
+
+ std::string method_handler(ReplaceAll(CB_INTERFACE_METHOD_HANDLER, {
+ { "<ENUM_VALUE>", enum_value },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", d->GetID() }
+ }));
+
+ code += RemoveLine(method_handler);
+ }
+
+ return code;
+}
+
+// @see #CB_INTERFACE_BASE
+void CGroupBodyGenerator::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+ ReplaceAll(CB_INTERFACE_BASE)
+ .Change("<PREFIX>", prefix)
+ .Change("<NAME>", name)
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_TYPE
+void CGroupBodyGenerator::GenInterfaceMethodHandlerType(std::ofstream& stream) {
+ stream << SmartIndent(CB_INTERFACE_METHOD_HANDLER_TYPE);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_BASE
+void CGroupBodyGenerator::GenInterfaceMethodHandlerBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_HANDLER_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_HANDLER_ARGS_DECL>", GenMethodHandlerArgsDecl(iface, decl) },
+ { "<METHOD_UNIT_MAP_READ>",
+ GenMethodUnitMapRead(iface, decl) },
+ { "<METHOD_HANDLER_CALLBACK_INVOKE>",
+ GenMethodHandlerCallbackInvoke(decl) },
+ { "<METHOD_HANDLER_ARGS_FREE>", GenMethodHandlerArgsFree(iface, decl) }
+ })
+ .Transform([&](std::string str){
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_INVOKE
+std::string CGroupBodyGenerator::GenMethodHandlerCallbackInvoke(
+ const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_INVOKE,
+ "<METHOD_NAME>", decl.GetID()));
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC)
+ code = ReplaceAll(code, "<RES_SET>", "res_ = ");
+ else
+ code = ReplaceAll(code, "<RES_SET>", "");
+
+ std::string args;
+ bool first = true;
+ for (const auto& p : decl.GetParameters()) {
+ if (!first)
+ args += ", ";
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ args += "&";
+
+ args += p->GetID();
+ first = false;
+ }
+ code = ReplaceAll(code, "<METHOD_ARGS>", args);
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_READ
+std::string CGroupBodyGenerator::GenMethodHandlerParcelRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ std::string parcel_read_code;
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_read_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>",
+ GetFullNameFromType(type, iface));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
+ }
+
+ code += parcel_read_code;
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CGroupBodyGenerator::GenMethodHandlerArgsDecl(const Interface& iface,
+ const Declaration& decl) {
+ std::string args_decl;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ args_decl += GetArgTypeString(type, iface) + p->GetID() + " = " +
+ GetErrorValue(type) + ";" + NLine(1);
+ }
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
+ args_decl += "rpc_port_parcel_h parcel_;" + NLine(1);
+ args_decl += GetArgTypeString(decl.GetType(), iface) + "res_ = " +
+ GetErrorValue(decl.GetType()) + ";" + NLine(1);
+ }
+
+ return args_decl;
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_FREE
+// @see #CB_INTERFACE_METHOD_BUNDLE_FREE
+// @see #CB_INTERFACE_METHOD_STRING_FREE
+std::string CGroupBodyGenerator::GenMethodHandlerArgsFree(const Interface& iface,
+ const Declaration& decl) {
+ std::string free_code;
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_FREE,
+ "<PREFIX>", GetHandlePrefix());
+ free_code = ReplaceAll(free_code, "<NAME>",
+ GetFullNameFromType(type, iface));
+ free_code = ReplaceAll(free_code, "<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE,
+ "<ARG>", p->GetID());
+ } else {
+ free_code.clear();
+ }
+
+ code += free_code;
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CGroupBodyGenerator::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+std::string CGroupBodyGenerator::GenMethodUnitMapWrite(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& param : decl.GetParameters()) {
+ auto& param_type = param->GetParameterType();
+
+ auto& type = param_type.GetBaseType();
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code += ReplaceAll(CB_INTERFACE_METHOD_ENUM_UNIT_MAP_WRITE)
+ .Change("<TYPE_NAME>", param->GetID())
+ .Change("<ARG>", param->GetID());
+ } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr) {
+ code += ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_WRITE)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG>", param->GetID());
+ code += GetPrivateSharingString(type, iface, "h->port", param->GetID());
+ } else if (type.ToString() == "bundle") {
+ code += ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_WRITE)
+ .Change("<ARG>", param->GetID());
+ } else if (type.ToString() == "string") {
+ code += ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE)
+ .Change("<ARG>", param->GetID());
+ } else if (type.ToString() == "file") {
+ code += ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE)
+ .Change("<ARG>", param->GetID());
+ code += GetPrivateSharingString(type, iface, "h->port", param->GetID());
+ } else {
+ code += ReplaceAll(CB_INTERFACE_METHOD_BASE_UNIT_MAP_WRITE)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG_NAME>", param->GetID())
+ .Change("<ARG>", param->GetID());
+ }
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CGroupBodyGenerator::GenMethodUnitMapReadBase(
+ const Interface& iface, const BaseType& type,
+ const std::string& arg_name, const std::string& arg) {
+ std::string code;
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code += ReplaceAll(CB_INTERFACE_METHOD_EMUM_UNIT_MAP_READ)
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr) {
+ code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_READ)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ } else if (type.ToString() == "bundle") {
+ code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_READ)
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_READ)
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ } else {
+ code = ReplaceAll(CB_INTERFACE_METHOD_BASE_UNIT_MAP_READ)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ }
+
+ return code;
+}
+
+std::string CGroupBodyGenerator::GenMethodUnitMapRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ std::string parcel_read_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ code += GenMethodUnitMapReadBase(iface, type, p->GetID(), p->GetID());
+ }
+
+ return RemoveLine(code);
+}
+
+
+std::string CGroupBodyGenerator::GenMethodParamsCheck(const Interface& iface,
+ const Declaration& decl) {
+ std::string params_check;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.ToString() == "list" ||
+ type.ToString() == "array" ||
+ type.ToString() == "bundle" ||
+ type.ToString() == "string" ||
+ type.ToString() == "file")
+ params_check += " || " + p->GetID() + " == nullptr";
+ }
+
+ return params_check;
+}
+
+// @see #CB_INTERFACE_METHOD_ASYNC_BASE
+std::string CGroupBodyGenerator::GenMethodAsyncBase(const Interface& iface,
+ const Declaration& decl) {
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+ std::string method_name = decl.GetID();
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_ASYNC_BASE)
+ .Change("<PREFIX>", prefix)
+ .Change("<NAME>", name)
+ .Change("<METHOD_NAME>", method_name)
+ .Change("<METHOD_PARAMS>", GenMethodParams(iface, decl))
+ .Change("<METHOD_PARAMS_CHECK>", GenMethodParamsCheck(iface, decl))
+ .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
+ .ChangeToUpper("<UPPERCASE_NAME>", name)
+ .ChangeToUpper("<UPPERCASE_METHOD_NAME>", method_name)
+ .Change("<METHOD_UNIT_MAP_WRITE>", GenMethodUnitMapWrite(iface, decl)));
+
+ return code;
+}
+
+std::string CGroupBodyGenerator::GenMethodArgs(const Interface& iface,
+ const Declaration& decl) {
+ std::string args_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ args_code += GetReturnTypeString(type) + "new_" + p->GetID() + ";";
+ args_code += NLine(1);
+ }
+
+ return args_code;
+}
+
+void CGroupBodyGenerator::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code = GenMethodAsyncBase(iface, decl);
+ stream << SmartIndent(code);
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/c_group_body_generator.hh b/idlc/gen/version2/c_group_body_generator.hh
new file mode 100644
index 0000000..113330f
--- /dev/null
+++ b/idlc/gen/version2/c_group_body_generator.hh
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_C_GROUP_BODY_GENERATOR_HH_
+#define IDLC_GEN_C_GROUP_BODY_GENERATOR_HH_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/version2/c_body_generator_base.hh"
+#include "idlc/options.h"
+
+namespace tidl {
+namespace version2 {
+
+class CGroupBodyGenerator : public CBodyGeneratorBase {
+ public:
+ explicit CGroupBodyGenerator(std::shared_ptr<Document> doc);
+ virtual ~CGroupBodyGenerator() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+ std::string GetHandlePrefix() override;
+ void GenIncludeDefaultHeaders(std::ofstream& stream, bool body) override;
+
+ private:
+ void GenInterfaceDefinition(std::ofstream& stream);
+ void GenInterfaceBaseDefinition(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodHandlerType(std::ofstream& stream);
+ void GenInterfaceMethodHandlerBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl);
+ std::string GenMethodHandlerArgsDecl(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlerArgsFree(const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceMethodTable(std::ofstream& stream,
+ const Interface& iface);
+ std::string GenMethodHandlerCallbackInvoke(const Declaration& decl);
+ std::string GenMethodHandlerParcelRead(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlers(const Interface& iface);
+ std::string GenMethodEnums(const Interface& iface);
+ void GenInterfaceEnums(std::ofstream& stream);
+ void GenInterfaceEnum(std::ofstream& stream, const Interface& iface);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodEnumBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+
+ std::string GenMethodAsyncBase(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+ std::string GenMethodUnitMapWrite(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodArgs(const Interface& iface, const Declaration& decl);
+ std::string GenMethodUnitMapRead(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodUnitMapReadBase(
+ const Interface& iface, const BaseType& type,
+ const std::string& arg_name, const std::string& arg);
+ std::string GenMethodParamsCheck(const Interface& iface, const Declaration& decl);
+ void GenHelper(std::ofstream& stream);
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_C_GROUP_BODY_GENERATOR_HH_ \ No newline at end of file
diff --git a/idlc/gen/version2/c_group_body_generator_cb.hh b/idlc/gen/version2/c_group_body_generator_cb.hh
new file mode 100644
index 0000000..a67ff11
--- /dev/null
+++ b/idlc/gen/version2/c_group_body_generator_cb.hh
@@ -0,0 +1,668 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_C_GROUP_BODY_GENERATOR_CB_HH_
+#define IDLC_GEN_C_GROUP_BODY_GENERATOR_CB_HH_
+
+
+constexpr const char CB_INTERFACE_METHOD_HANDLER_TYPE[] =
+R"__c_cb(
+typedef int (*rpc_port_group_method_handler)(rpc_port_unit_map_h map, void *data);
+)__c_cb";
+
+/**
+ * <METHOD_ENUMS> The enumeration declarations of methods.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM_BASE[] =
+R"__c_cb(
+typedef enum {
+ <METHOD_ENUMS>
+} <PREFIX>_<NAME>_method_e;
+)__c_cb";
+
+
+/**
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM[] =
+R"__c_cb(
+<UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>,
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ <PREFIX>_<NAME>_callback_s callback;
+ event_handler_h event_handler;
+ char *sender_appid;
+ bool is_system;
+ GRecMutex mutex;
+ void *user_data;
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_HANDLER_ARGS_DECL> The declarations for arguments of the method.
+ * <METHOD_HANDLER_PARCEL_READ> The implementation to read the parameter from the parcel.
+ * <METHOD_HANDLER_CALLBACK_INVOKE> The implementation to invoke the callback function of the method.
+ * <METHOD_HANDLER_PARCEL_WRITE> The implementation to write the result to the parcel.
+ * <METHOD_HANDLER_ARGS_FREE> The implementation to release arguments.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER_BASE[] =
+R"__c_cb(
+static int __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler(rpc_port_unit_map_h map_, void *user_data)
+{
+ <PREFIX>_<NAME>_t *h = user_data;
+ int ret_ = RPC_PORT_ERROR_NONE;
+
+ <METHOD_HANDLER_ARGS_DECL>
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ ret_ = RPC_PORT_ERROR_INVALID_PARAMETER;
+ goto out;
+ }
+ <METHOD_UNIT_MAP_READ>
+ <METHOD_HANDLER_CALLBACK_INVOKE>
+
+ out:
+ <METHOD_HANDLER_ARGS_FREE>
+ return ret_;
+}
+)__c_cb";
+
+constexpr const char CB_HELPER[] =
+R"__c_cb(
+static rpc_port_parcel_h __get_parcel_from_bundle(bundle *b)
+{
+ void *raw = nullptr;
+ size_t size = 0;
+ rpc_port_parcel_h p;
+
+ int ret = bundle_get_byte(b, "TIDL_RAW", &raw, &size);
+ if (ret != BUNDLE_ERROR_NONE)
+ return nullptr;
+
+ ret = rpc_port_parcel_create_from_raw(&p, raw, (unsigned int)size);
+ if (ret != RPC_PORT_ERROR_NONE)
+ return nullptr;
+
+ return p;
+}
+
+static bundle *__get_bundle_from_parcel(rpc_port_parcel_h p, bundle* b)
+{
+ void *raw = nullptr;
+ unsigned int size = 0;
+
+ int ret = rpc_port_parcel_get_raw(p, &raw, &size);
+ if (ret != RPC_PORT_ERROR_NONE)
+ return nullptr;
+
+ ret = bundle_add_byte(b, "TIDL_RAW", raw, size);
+ if (ret != BUNDLE_ERROR_NONE)
+ return nullptr;
+
+ return b;
+}
+
+static char *__get_event_name(const char *appid, bool is_system, const char *iface_name)
+{
+ size_t size;
+ char *buf;
+
+ if (is_system) {
+ size = strlen("tizen.system.event.tidl_iface_") + strlen(iface_name) + 1;
+ buf = calloc(1, size);
+ if (!buf)
+ return nullptr;
+ snprintf(buf, size, "tizen.system.event.tidl_iface_%s", iface_name);
+ return buf;
+ }
+
+ size = strlen(appid) + strlen(iface_name) + 19;
+ buf = calloc(1, size);
+ if (!buf)
+ return nullptr;
+ snprintf(buf, size, "event.%s.tidl_iface_%s", appid, iface_name);
+ return buf;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+
+static void __<NAME>_event_system_cb(const char *event_name, bundle *event_data, void *user_data)
+{
+ <PREFIX>_<NAME>_t *handle = (<PREFIX>_<NAME>_t *)(user_data);
+ rpc_port_parcel_h p = __get_parcel_from_bundle(event_data);
+ if (p == nullptr) {
+ _E("Invalid bundle");
+ return;
+ }
+
+ rpc_port_parcel_h header;
+ int seq_num = -1;
+ int cmd;
+ rpc_port_unit_map_h map;
+
+ rpc_port_parcel_get_header(p, &header);
+ rpc_port_parcel_header_get_seq_num(header, &seq_num);
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ rpc_port_parcel_destroy(p);
+ return;
+ }
+
+ rpc_port_parcel_read(p, &map->parcelable, map);
+ rpc_port_parcel_destroy(p);
+
+ rpc_port_unit_map_read_int(map, "[METHOD]", &cmd);
+
+ if (cmd >= 0 && cmd < ARRAY_SIZE(__<NAME>_method_table)) {
+ if (__<NAME>_method_table[cmd])
+ __<NAME>_method_table[cmd](map, handle);
+ } else {
+ _W("Invalid protocol. cmd(%d)", cmd);
+ }
+ rpc_port_unit_map_destroy(map);
+}
+
+int <PREFIX>_<NAME>_create(const char *sender_appid, <PREFIX>_<NAME>_callback_s *callback, void *user_data, bool is_system, <PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+ int ret;
+ char *ev_name;
+
+ if (sender_appid == nullptr || callback == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ev_name = __get_event_name(sender_appid, is_system, "<NAME>");
+ if (ev_name == nullptr) {
+ free(handle);
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = event_add_event_handler(ev_name, __<NAME>_event_system_cb, handle, &handle->event_handler);
+ free(ev_name);
+
+ if (ret != EVENT_ERROR_NONE) {
+ _E("Failed to register events. result(%d)", ret);
+ free(handle);
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle->sender_appid = strdup(sender_appid);
+ if (handle->sender_appid == nullptr) {
+ _E("Out of memory");
+ event_remove_event_handler(handle->event_handler);
+ free(handle);
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ g_rec_mutex_init(&handle->mutex);
+ handle->callback = *callback;
+ handle->user_data = user_data;
+ handle->is_system = is_system;
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_create_for_sender(const char *sender_appid, bool is_system, <PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+
+ if (h == nullptr || sender_appid == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->sender_appid = strdup(sender_appid);
+ if (handle->sender_appid == nullptr) {
+ _E("Out of memory");
+ free(handle);
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ g_rec_mutex_init(&handle->mutex);
+ handle->is_system = is_system;
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ g_rec_mutex_unlock(&h->mutex);
+ g_rec_mutex_clear(&h->mutex);
+
+ if (h->event_handler)
+ event_remove_event_handler(h->event_handler);
+ if (h->sender_appid)
+ free(h->sender_appid);
+
+ free(h);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_PARAMS> The parameters of the method of the interface
+ * <METHOD_PARAMS_CHECK> The parameters check of the method.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ * <METHOD_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ */
+constexpr const char CB_INTERFACE_METHOD_ASYNC_BASE[] =
+R"__c_cb(
+void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
+{
+ rpc_port_parcel_h parcel_;
+ rpc_port_parcel_header_h header_;
+ int seq_num_ = -1;
+ int res_;
+ bundle* b;
+ rpc_port_unit_map_h map_;
+
+ if (h == nullptr<METHOD_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ res_ = rpc_port_parcel_create(&parcel_);
+ if (res_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", res_);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(res_);
+ return;
+ }
+
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+
+ map_ = rpc_port_unit_map_create();
+ if (map_ == nullptr) {
+ _E("Failed to create unit map");
+ rpc_port_parcel_destroy(parcel_);
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_unit_map_write_int(map_, "[METHOD]", <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
+
+ <METHOD_UNIT_MAP_WRITE>
+
+ rpc_port_parcel_write(parcel_, &map_->parcelable, map_);
+ rpc_port_unit_map_destroy(map_);
+
+ b = bundle_create();
+ if (__get_bundle_from_parcel(parcel_, b) == nullptr) {
+ _E("Failed to make bundle from parcel");
+ bundle_free(b);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ int ret = event_publish_app_event(__get_event_name(h->sender_appid, h->is_system, "<NAME>"), b);
+ if (ret != EVENT_ERROR_NONE) {
+ _E("Failed to publish event. result(%d)", ret);
+ bundle_free(b);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(RPC_PORT_ERROR_IO_ERROR);
+ return;
+ }
+
+ bundle_free(b);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel_, &<ARG>->parcelable, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+<PREFIX>_<NAME>_create(&<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to create handle");
+ ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ goto out;
+}
+
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+if (get_last_result() != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data");
+ <PREFIX>_<NAME>_destroy(<ARG>);
+ <ARG> = nullptr;
+ ret_ = get_last_result();
+ goto out;
+}
+)__c_cb";
+
+
+/**
+ * <ENUM_VALUE> The enumeration value of the method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER[] =
+R"__c_cb(
+[<ENUM_VALUE>] = __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler,
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ <PREFIX>_<NAME>_destroy(<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ bundle_free(<ARG>);
+)__c_cb";
+
+/**
+ * <RES_SET> The implemention to set the result of the callback function.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <METHOD_ARGS> The arguments of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_INVOKE[] =
+R"__c_cb(
+if (h->callback.<METHOD_NAME>)
+ <RES_SET>h->callback.<METHOD_NAME>(<METHOD_ARGS>, h->user_data);
+)__c_cb";
+
+
+/**
+ * <ARG> The argument.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface
+ */
+constexpr const char CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ[] =
+R"__c_cb(
+ret_ = <PREFIX>_<NAME>_create(&<ARG>);
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret_);
+ goto out;
+}
+
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+ret_ = get_last_result();
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret_);
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ free(<ARG>);
+)__c_cb";
+
+/**
+ * <NAME> The name of the interface.
+ * <METHOD_HANDLERS> The declarations of method handlers.
+ */
+constexpr const char CB_INTERFACE_METHOD_TABLE[] =
+R"__c_cb(
+static rpc_port_group_method_handler __<NAME>_method_table[] = {
+ <METHOD_HANDLERS>
+};
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+rpc_port_parcel_read_bundle(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ goto out;
+
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+rpc_port_parcel_read_string(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG>", <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_bundle(map_, "<ARG>", <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_string(map_, "<ARG>", <ARG>);
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG>", <ARG>);
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_int(map_, "<ARG_NAME>", (int)<ARG>);
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG_NAME> The argument name.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+rpc_port_unit_map_read_<TYPE_NAME>(map_, "<ARG_NAME>", &<ARG>);
+)__c_cb";
+
+/**
+ * <ARG_NAME> The argument name.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_EMUM_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_int(map_, "<ARG_NAME>", (int *)&<ARG>);
+)__c_cb";
+
+/**
+ * <ARG_NAME> The argument name.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+rpc_port_unit_map_read_bundle(map_, "<ARG_NAME>", &<ARG>);
+)__c_cb";
+
+/**
+ * <ARG_NAME> The argument name.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_UNIT_MAP_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+= rpc_port_unit_map_read_string(map_, "<ARG_NAME>", &<ARG>);
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG_NAME> The argument name.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_<TYPE_NAME>(map_, "<ARG_NAME>", &<ARG>);
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &<ARG>);
+)__c_cb";
+
+/**
+ * <PARAM> The name of the parameter.
+ */
+constexpr const char CB_INTERFACE_METHOD_PARAM_SET[] =
+R"__c_cb(
+*<PARAM> = new_<PARAM>;
+)__c_cb";
+
+constexpr const char CB_INTERFACE_EXTRA_HEADER[] =
+R"__c_cb(
+#include <app_event.h>
+)__c_cb";
+
+#endif // IDLC_GEN_C_GROUP_BODY_GENERATOR_CB_HH_
diff --git a/idlc/gen/version2/c_group_header_generator.cc b/idlc/gen/version2/c_group_header_generator.cc
new file mode 100644
index 0000000..bbc0186
--- /dev/null
+++ b/idlc/gen/version2/c_group_header_generator.cc
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/c_group_header_generator.hh"
+
+namespace {
+#include "idlc/gen/version2/c_group_header_generator_cb.hh"
+
+constexpr const char PREFIX_RPC_PORT_GROUP[] = "rpc_port_group";
+}
+
+namespace tidl {
+namespace version2 {
+
+CGroupHeaderGenerator::CGroupHeaderGenerator(std::shared_ptr<Document> doc)
+ : CHeaderGeneratorBase(doc) {}
+
+void CGroupHeaderGenerator::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenPragmaOnce(stream);
+ GenIncludeDefaultHeaders(stream, false);
+ GenExplicitLinkageOpen(stream);
+ GenEnums(stream);
+ GenStructureHandles(stream);
+ GenInterfaceHandles(stream);
+ GenStructures(stream);
+ GenInterfaceCallbacks(stream);
+ GenInterfaces(stream);
+}
+
+void CGroupHeaderGenerator::OnFiniGen(std::ofstream& stream) {
+ GenExplicitLinkageClose(stream);
+}
+
+std::string CGroupHeaderGenerator::GetHandlePrefix() {
+ std::string prefix = PREFIX_RPC_PORT_GROUP;
+ if (!HasNamespace())
+ return prefix;
+
+ return prefix + "_" + GetFileNamespace();
+}
+
+void CGroupHeaderGenerator::GenInterfaceHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceHandle(stream, iface);
+ }
+}
+
+void CGroupHeaderGenerator::GenInterfaceCallbacks(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ for (const auto& d : iface.GetDeclarations()) {
+ GenInterfaceMethodCallbackBase(stream, iface, *d);
+ }
+ }
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_BASE
+void CGroupHeaderGenerator::GenInterfaceMethodCallbackBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_BASE, {
+ { "<RETURN_TYPE>", GetReturnTypeString(decl.GetType()) },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_PARAMS>", GenMethodParams(iface, decl) }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_HANDLE
+void CGroupHeaderGenerator::GenInterfaceHandle(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_HANDLE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+void CGroupHeaderGenerator::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CGroupHeaderGenerator::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ GenInterfaceBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations())
+ GenInterfaceMethodBase(stream, iface, *d);
+}
+
+// @see #CB_INTERFACE_BASE
+void CGroupHeaderGenerator::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID()},
+ { "<METHOD_CALLBACK_DECLS>", GenMethodCallbackDecls(iface) }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_DECL
+std::string CGroupHeaderGenerator::GenMethodCallbackDecls(const Interface& iface) {
+ std::string method_callback_decls;
+ for (const auto& d : iface.GetDeclarations()) {
+ std::string method_callback_decl(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_DECL, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", d->GetID() }
+ }));
+
+ method_callback_decl = RemoveLine(method_callback_decl);
+ method_callback_decls += RemoveLine(method_callback_decl, 2);
+ }
+
+ return method_callback_decls;
+}
+
+std::string CGroupHeaderGenerator::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ bool first = true;
+ for (const auto& p : decl.GetParameters()) {
+ if (!first)
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ first = false;
+ }
+
+ return params;
+}
+
+// @see #CB_INTERFACE_METHOD_BASE
+void CGroupHeaderGenerator::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_BASE, {
+ { "<RETURN_TYPE>", GetReturnTypeString(decl.GetType(), iface.GetID()) },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_PARAMS>", GenMethodParams(iface, decl) }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/c_group_header_generator.hh b/idlc/gen/version2/c_group_header_generator.hh
new file mode 100644
index 0000000..b067cee
--- /dev/null
+++ b/idlc/gen/version2/c_group_header_generator.hh
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_C_GROUP_HEADER_GENERATOR_HH_
+#define IDLC_GEN_C_GROUP_HEADER_GENERATOR_HH_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/version2/c_header_generator_base.hh"
+
+namespace tidl {
+namespace version2 {
+
+class CGroupHeaderGenerator : public CHeaderGeneratorBase {
+ public:
+ explicit CGroupHeaderGenerator(std::shared_ptr<Document> doc);
+ virtual ~CGroupHeaderGenerator() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+ std::string GetHandlePrefix() override;
+
+ private:
+ void GenInterfaceHandles(std::ofstream& stream);
+ void GenInterfaceHandle(std::ofstream& stream, const Interface& iface);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+
+ void GenInterfaceCallbacks(std::ofstream& stream);
+ void GenInterfaceMethodCallbackBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl);
+ std::string GenMethodCallbackDecls(const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_C_GROUP_HEADER_GENERATOR_H_ \ No newline at end of file
diff --git a/idlc/gen/version2/c_group_header_generator_cb.hh b/idlc/gen/version2/c_group_header_generator_cb.hh
new file mode 100644
index 0000000..ecbe717
--- /dev/null
+++ b/idlc/gen/version2/c_group_header_generator_cb.hh
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_GROUP_HEADER_GENERATOR_CB_HH_
+#define IDLC_C_GROUP_HEADER_GENERATOR_CB_HH_
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_HANDLE[] =
+R"__c_cb(
+/**
+ * @brief The <PREFIX>_<NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_s *<PREFIX>_<NAME>_h;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+/**
+ * @brief The structure type containing the set of callback functions for handling events.
+ * @details It is one of the input parameters of the <PREFIX>_<NAME>_register() function.
+ *
+ * @see <PREFIX>_<NAME>_create_cb
+ * @see <PREFIX>_<NAME>_terminate_cb
+ */
+typedef struct {
+ <METHOD_CALLBACK_DECLS>
+} <PREFIX>_<NAME>_callback_s;
+
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ * @remarks The @a h handle should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ *
+ * @param[in] sender_appid ID of app sending events
+ * @param[in] callback The set of callback functions to handle events
+ * @param[in] user_data The user data to be passed to the callback function
+ * @param[in] is_system True on system events
+ * @param[out] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RPC_PORT_ERROR_IO_ERROR IO error
+
+ * @see <PREFIX>_<NAME>_destroy()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+int <PREFIX>_<NAME>_create(const char *sender_appid, <PREFIX>_<NAME>_callback_s *callback, void *user_data, bool is_system, <PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle for sending events.
+ * @remarks The @a h handle should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ *
+ * @param[in] sender_appid ID of app sending events
+ * @param[in] is_system True on system events
+ * @param[out] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RPC_PORT_ERROR_IO_ERROR IO error
+
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_create_for_sender(const char *sender_appid, bool is_system, <PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_BASE[] =
+R"__c_cb(
+/**
+ * @brief Called when the payload is received.
+ *
+ * @param[in] ...
+ * @param[in] user_data The user data passed from the registration function
+ * @see #<PREFIX>_<NAME>_callback_s;
+ */
+typedef <RETURN_TYPE> (*<PREFIX>_<NAME>_<METHOD_NAME>_cb)(<METHOD_PARAMS>, void *user_data);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The name of the method of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_DECL[] =
+R"__c_cb(
+<PREFIX>_<NAME>_<METHOD_NAME>_cb <METHOD_NAME>; /**< This callback function is invoked when the <METHOD_NAME> request is delivered. */
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The type of the return value.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The of the interface.
+ * <METHOD_NAME> The name of the method.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE[] =
+R"__c_cb(
+/**
+ * @brief Calls the <METHOD_NAME>() method.
+ * @details The return value and args are decided by the interface declaration.
+ * You can get the result using get_last_result().
+ * Before returning the function, the function sets the result using set_last_result().
+ * @remarks The specific error code can be obtained using the get_last_result() function. Error codes are described in Exception section.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] ...
+ * @exception #RPC_PORT_ERROR_NONE Successful
+ * @exception #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @exception #RPC_PORT_ERROR_IO_ERROR I/O error
+ */
+<RETURN_TYPE><PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h, <METHOD_PARAMS>);
+)__c_cb";
+
+#endif // IDLC_C_GROUP_HEADER_GENERATOR_CB_HH_ \ No newline at end of file
diff --git a/idlc/gen/version2/c_header_generator_array_base_cb.hh b/idlc/gen/version2/c_header_generator_array_base_cb.hh
new file mode 100644
index 0000000..55a73bd
--- /dev/null
+++ b/idlc/gen/version2/c_header_generator_array_base_cb.hh
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_HEADER_GENERATOR_ARRAY_BASE_CB_HH_
+#define IDLC_GEN_VERSION2_C_HEADER_GENERATOR_ARRAY_BASE_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <PREFIX> The prefix of the array structure.
+ * <NAME> The name of the array structure.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE[] =
+R"__c_cb(
+/**
+ * @briefs Creates a <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a h should be released using the <PREFIX>_<NAME>_destroy()
+ * if it's no longer needed.
+ * @param[out] h The <PREFIX>_<NAME> handle that is newly created
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME> should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone);
+
+/**
+ * @brief Sets the value to the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The value is internally copied and stored.
+ * You should release it if it's allocaed when it's no longer needed,
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] value The array value
+ * @param[in] size The size of the array
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_get()
+ */
+int <PREFIX>_<NAME>_set(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>*value, int size);
+
+/**
+ * @brief Gets the value from the <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created value should be released if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] value The array value
+ * @param[out] size The size of the array
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_set()
+ */
+int <PREFIX>_<NAME>_get(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>*value, int *size);
+)__c_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_HEADER_GENERATOR_ARRAY_BASE_CB_HH_
diff --git a/idlc/gen/version2/c_header_generator_base.cc b/idlc/gen/version2/c_header_generator_base.cc
new file mode 100644
index 0000000..832441c
--- /dev/null
+++ b/idlc/gen/version2/c_header_generator_base.cc
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2022 - 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/c_header_generator_base.hh"
+
+#include <string.h>
+
+#include <string>
+#include <vector>
+
+#include "idlc/gen/version2/c_header_generator_array_base_cb.hh"
+#include "idlc/gen/version2/c_header_generator_base_cb.hh"
+#include "idlc/gen/version2/c_header_generator_list_base_cb.hh"
+#include "idlc/gen/version2/c_header_generator_map_base_cb.hh"
+#include "idlc/gen/version2/c_header_generator_set_base_cb.hh"
+
+namespace tidl {
+namespace version2 {
+namespace {
+
+void GetElementsFromStructure(Elements* elms,
+ const std::shared_ptr<Structure>& base) {
+ if (base->GetBase() != nullptr)
+ GetElementsFromStructure(elms, base->GetBase());
+
+ for (auto elm : base->GetElements())
+ elms->Add(elm);
+}
+
+Elements GetElements(const Structure& st) {
+ Elements elms;
+ if (st.GetBase() != nullptr)
+ GetElementsFromStructure(&elms, st.GetBase());
+
+ for (auto elm : st.GetElements())
+ elms.Add(elm);
+
+ return elms;
+}
+
+} // namespace
+
+CHeaderGeneratorBase::CHeaderGeneratorBase(std::shared_ptr<Document> doc)
+ : tidl::CHeaderGeneratorBase(doc) {
+}
+
+void CHeaderGeneratorBase::GenStructureHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructureHandle(stream, st);
+ }
+ }
+
+ for (auto& i : GetStructures()) {
+ auto& st = i.second;
+ GenStructureHandle(stream, *st);
+ }
+}
+
+void CHeaderGeneratorBase::GenStructureHandle(std::ofstream& stream,
+ const Structure& st) {
+ ReplaceAll(CB_STRUCTURE_HANDLE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", GetEnumTypeString(st.GetID()))
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+}
+
+void CHeaderGeneratorBase::GenStructures(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructureBase(stream, st);
+ }
+ }
+
+ for (auto& i : GetStructures()) {
+ auto& st = i.second;
+ GenStructure(stream, *st);
+ }
+}
+
+void CHeaderGeneratorBase::GenEnums(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ GenEnum(stream, *b);
+ }
+}
+
+void CHeaderGeneratorBase::GenEnum(std::ofstream& stream,
+ const Block& block) {
+ for (auto& e : block.GetEnums()) {
+ std::string enums;
+ for (auto& f : e->GetFields()) {
+ enums += GetHandlePrefix() + "_" + e->GetID() + "_" + block.GetID() + "_";
+ if (f->GetValue().empty())
+ enums += f->GetID() + "," + NLine(1);
+ else
+ enums += f->GetID() + " = " + f->GetValue() + "," + NLine(1);
+ }
+
+ ReplaceAll(CB_ENUM_BASE)
+ .ChangeToUpper("<ENUMS>", enums)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", e->GetID())
+ .Change("<OWNER_NAME>", block.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+ }
+}
+
+void CHeaderGeneratorBase::GenStructureArrayBase(std::ofstream& stream,
+ const Structure& st) {
+ auto& elm = *(st.GetElements().begin());
+ auto& type = elm->GetType();
+ std::string id;
+
+ auto pos = type.ToString().find('.');
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM &&
+ pos == std::string::npos)
+ id = GetEnumBockString(type.ToString());
+ else
+ id = st.GetID();
+
+ auto param_type_in =
+ GetParamTypeString(ParameterType::Direction::IN, type, id);
+ auto param_type_out =
+ GetParamTypeString(ParameterType::Direction::OUT, type, id);
+
+ ReplaceAll(CB_STRUCTURE_ARRAY_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", GetEnumTypeString(st.GetID()))
+ .Change("<PARAM_TYPE_IN>", param_type_in)
+ .Change("<PARAM_TYPE_OUT>", param_type_out)
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CHeaderGeneratorBase::GenStructureListBase(std::ofstream& stream,
+ const Structure& st) {
+ auto& elm = *(st.GetElements().begin());
+ auto& type = elm->GetType();
+ std::string id;
+
+ auto n = type.ToString().find('.');
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM &&
+ n == std::string::npos)
+ id = GetEnumBockString(type.ToString());
+ else
+ id = st.GetID();
+
+
+ auto param_type = GetParamTypeString(ParameterType::Direction::IN, type, id);
+
+ ReplaceAll(CB_STRUCTURE_LIST_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", GetEnumTypeString(st.GetID()))
+ .Change("<PARAM_TYPE_IN>", param_type)
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CHeaderGeneratorBase::GenStructureMapBase(std::ofstream& stream,
+ const Structure& st) {
+ auto iter = st.GetElements().begin();
+ if (std::next(iter) == st.GetElements().end())
+ return;
+
+ auto& key_elm = *iter;
+ auto& key_type = key_elm->GetType();
+ auto key_param_type = GetParamTypeString(ParameterType::Direction::IN,
+ key_type);
+ auto& value_elm = *(std::next(iter));
+ auto& value_type = value_elm->GetType();
+ auto value_param_type = GetParamTypeString(ParameterType::Direction::IN,
+ value_type);
+ auto value_param_type_out = GetParamTypeString(ParameterType::Direction::OUT,
+ value_type);
+
+ ReplaceAll(CB_STRUCTURE_MAP_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", GetEnumTypeString(st.GetID()))
+ .Change("<KEY_PARAM_TYPE>", key_param_type)
+ .Change("<VALUE_PARAM_TYPE>", value_param_type)
+ .Change("<VALUE_PARAM_TYPE_OUT>", value_param_type_out)
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CHeaderGeneratorBase::GenStructureSetBase(std::ofstream& stream,
+ const Structure& st) {
+ auto& elm = *(st.GetElements().begin());
+ auto& key_type = elm->GetType();
+ auto key_param_type = GetParamTypeString(ParameterType::Direction::IN,
+ key_type);
+
+ ReplaceAll(CB_STRUCTURE_SET_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Change("<KEY_PARAM_TYPE>", key_param_type)
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CHeaderGeneratorBase::GenStructureBase(std::ofstream& stream,
+ const Structure& st) {
+ ReplaceAll(CB_STRUCTURE_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+
+ for (const auto& e : GetElements(st)) {
+ auto& type = e->GetType();
+ auto param_type_in =
+ GetParamTypeString(ParameterType::Direction::IN, type, st.GetID());
+ auto param_type_out =
+ GetParamTypeString(ParameterType::Direction::OUT, type, st.GetID());
+
+ ReplaceAll(CB_STRUCTURE_BASE_SET_GET)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Change("<PARAM_TYPE_IN>", param_type_in)
+ .Change("<PARAM_TYPE_OUT>", param_type_out)
+ .Change("<ELEMENT_NAME>", e->GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+ }
+}
+
+void CHeaderGeneratorBase::GenStructure(std::ofstream& stream,
+ const Structure& st) {
+ if (st.GetID().compare(0, strlen("array"), "array") == 0)
+ GenStructureArrayBase(stream, st);
+ else if (st.GetID().compare(0, strlen("list"), "list") == 0)
+ GenStructureListBase(stream, st);
+ else if (st.GetID().compare(0, strlen("map"), "map") == 0)
+ GenStructureMapBase(stream, st);
+ else if (st.GetID().compare(0, strlen("set"), "set") == 0)
+ GenStructureSetBase(stream, st);
+ else
+ GenStructureBase(stream, st);
+}
+
+void CHeaderGeneratorBase::GenRemoteExceptionHandle(std::ofstream& stream) {
+ ReplaceAll(CB_REMOTE_EXCEPTION_HANDLE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CHeaderGeneratorBase::GenRemoteException(std::ofstream& stream) {
+ ReplaceAll(CB_REMOTE_EXCEPTION_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+
+ ReplaceAll(IsProxy() ? CB_PROXY_REMOTE_EXCEPTION_BASE
+ : CB_STUB_REMOTE_EXCEPTION_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/c_header_generator_base.hh b/idlc/gen/version2/c_header_generator_base.hh
new file mode 100644
index 0000000..d5171dd
--- /dev/null
+++ b/idlc/gen/version2/c_header_generator_base.hh
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2022 - 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_HEADER_GENERATOR_BASE_HH_
+#define IDLC_GEN_VERSION2_C_HEADER_GENERATOR_BASE_HH_
+
+#include <memory>
+
+#include "idlc/gen/c_header_gen_base.h"
+
+namespace tidl {
+namespace version2 {
+
+class CHeaderGeneratorBase : public tidl::CHeaderGeneratorBase {
+ public:
+ explicit CHeaderGeneratorBase(std::shared_ptr<Document> doc);
+ virtual ~CHeaderGeneratorBase() = default;
+
+ void GenStructureHandles(std::ofstream& stream) override;
+ void GenStructures(std::ofstream& stream) override;
+ void GenEnums(std::ofstream& stream);
+ void GenRemoteExceptionHandle(std::ofstream& stream);
+ void GenRemoteException(std::ofstream& stream);
+
+ private:
+ void GenStructureHandle(std::ofstream& stream, const Structure& st);
+ void GenStructureArrayBase(std::ofstream& stream, const Structure& st);
+ void GenStructureListBase(std::ofstream& stream, const Structure& st);
+ void GenStructureMapBase(std::ofstream& stream, const Structure& st);
+ void GenStructureSetBase(std::ofstream& stream, const Structure& st);
+ void GenStructureBase(std::ofstream& stream, const Structure& st);
+ void GenStructure(std::ofstream& stream, const Structure& st);
+ void GenEnum(std::ofstream& stream, const Block& block);
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_HEADER_GENERATOR_BASE_HH_
diff --git a/idlc/gen/version2/c_header_generator_base_cb.hh b/idlc/gen/version2/c_header_generator_base_cb.hh
new file mode 100644
index 0000000..a6c5992
--- /dev/null
+++ b/idlc/gen/version2/c_header_generator_base_cb.hh
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2022 - 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_HEADER_GENERATOR_BASE_CB_HH_
+#define IDLC_GEN_VERSION2_C_HEADER_GENERATOR_BASE_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <PREFIX> The prefix of the handle.
+ * <NAME> The name of the handle.
+ */
+constexpr const char CB_STRUCTURE_HANDLE[] =
+R"__c_cb(
+/**
+ * @brief The <PREFIX>_<NAME> handle.
+ */
+typedef void *<PREFIX>_<NAME>_h;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the enum.
+ * <OWNER_NAME> The name of the owner.
+ * <NAME> The name of the enum.
+ */
+constexpr const char CB_ENUM_BASE[] =
+R"__c_cb(
+/**
+ * @brief The <PREFIX>_<OWNER_NAME>_<NAME> enum.
+ */
+typedef enum {
+ <ENUMS>
+} <PREFIX>_<OWNER_NAME>_<NAME>_e;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure. e.g. rpc_port_proxy_ or rpc_port_stub_
+ * <NAME> The name of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE[] =
+R"__c_cb(
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a h handle should be released using the <PREFIX>_<NAME>_destroy()
+ * if it's no longer needed.
+ * @param[out] h The <PREFIX>_<NAME> handle that is newly created
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMTER Invaid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME> should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure. e.g. rpc_port_proxy_ or rpc_port_stub_
+ * <NAME> The name of the structure.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_SET_GET[] =
+R"__c_cb(
+/**
+ * @brief Sets the <ELEMENT_NAME> to the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The <ELEMENT_NAME> is internally copied and stored.
+ * You should release it if it's allocated when it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] value The <ELEMENT_NAME>
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_get_<ELEMENT_NAME>()
+ */
+int <PREFIX>_<NAME>_set_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value);
+
+/**
+ * @brief Gets the <ELEMENT_NAME> from the <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created value should be released if it's allocated when it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] value The <ELEMENT_NAME>
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_set_<ELEMENT_NAME>
+ */
+int <PREFIX>_<NAME>_get_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>value);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ */
+constexpr const char CB_REMOTE_EXCEPTION_HANDLE[] =
+R"__c_cb(
+/**
+ * @breif The <PREFIX> remote exception handle.
+ */
+typedef struct <PREFIX>_remote_exception_s *<PREFIX>_remote_exception_h;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ */
+constexpr const char CB_REMOTE_EXCEPTION_BASE[] =
+R"__c_cb(
+/**
+ * @brief Creates the <PREFIX> remote exception handle.
+ *
+ * @remarks The @c h handle should be released if it's no longer needed.
+ * @param[out] h The <PREFIX> remote exception handle.
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_remote_exception_destroy()
+ */
+int <PREFIX>_remote_exception_create(<PREFIX>_remote_exception_h *h);
+
+/**
+ * @brief Sets the cause of the exception.
+ *
+ * @param[in] h The <PREFIX> remote exception handle
+ * @param[in] cause The cause of the exception
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_remote_exception_set_cause(<PREFIX>_remote_exception_h h, int cause);
+
+/**
+ * @brief Sets the detail message of the exception.
+ *
+ * @param[in] h The <PREFIX> remote exception handle
+ * @param[in] message The detail message of the exception
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <PREFIX>_remote_exception_set_message(<PREFIX>_remote_exception_h h, const char *message);
+
+/**
+ * @brief Gets the cause of the exception.
+ * @param[in] h The <PREFIX> remote exception handle.
+ * @param[out] cause The cause
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_remote_exception_get_cause(<PREFIX>_remote_exception_h h, int *cause);
+
+/**
+ * @brief Gets the detail message of the exception.
+ * @remarks The @c message should be released if it's no longer needed.
+ * @param[in] h The <PREFIX> remote exception handle.
+ * @param[out] message The detail message
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <PREFIX>_remote_exception_get_message(<PREFIX>_remote_exception_h, char **message);
+
+/**
+ * @brief Destroys the remote exception handle.
+ * @param[in] h The <PREFIX> remote exception handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_remote_exception_destroy(<PREFIX>_remote_exception_h h);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the proxy interface.
+ */
+constexpr const char CB_PROXY_REMOTE_EXCEPTION_BASE[] =
+R"__cpp_cb(
+/**
+ * @brief Gets the remote exception handle.
+ * @details If the return value is nullptr, there is no exceptions.
+ * @remarks The handle should be released using <PREFIX>_remote_exception_destroy(), if it's no longer needed.
+ * @param[out] h The <PREFIX> remote exception handle.
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_remote_exception_destroy();
+ */
+int <PREFIX>_get_remote_exception(<PREFIX>_remote_exception_h *h);
+)__cpp_cb";
+
+/**
+ * <PREFIX> The prefix of the stub interface.
+ */
+constexpr const char CB_STUB_REMOTE_EXCEPTION_BASE[] =
+R"__c_cb(
+/**
+ * @brief Throws the exception to the client.
+ * @details This function throws the exception to the client in the callback function.
+ * While calling the registered callback function related the method call, this function should be called
+ * if you want to send the remote exception to the client.
+ * If this function is called outside of the registered callback function, it's meaningless.
+ * The callback function is not returned by calling this function.
+ *
+ * @param[in] h The <PREFIX> remote exception handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_remote_exception_create()
+ * @see <PREFIX>_remote_exception_destroy()
+ */
+int <PREFIX>_remote_exception_throw(<PREFIX>_remote_exception_h h);
+)__c_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_HEADER_GENERATOR_BASE_CB_HH_
diff --git a/idlc/gen/version2/c_header_generator_list_base_cb.hh b/idlc/gen/version2/c_header_generator_list_base_cb.hh
new file mode 100644
index 0000000..e8198bb
--- /dev/null
+++ b/idlc/gen/version2/c_header_generator_list_base_cb.hh
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_HEADER_GENERATOR_LIST_BASE_CB_HH_
+#define IDLC_GEN_VERSION2_C_HEADER_GENERATOR_LIST_BASE_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <PREFIX> The prefix of the list structure.
+ * <NAME> The name of the list structure.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE[] =
+R"__c_cb(
+/**
+ * @brief Called to retrieve the value contained in the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a value MUST NOT be released by the application.
+ * @param[in] value The value of the list
+ * @param[in] user_data The user data passed from the foreach function
+ * @return @c true to continue with the next iteration of the loop,
+ * otherwise @c false to break out of the loop
+ * @see <PREFIX>_<NAME>_foreach()
+ */
+typedef bool (*<PREFIX>_<NAME>_cb)(<PARAM_TYPE_IN>value, void *user_data);
+
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a h handle should be released using the <PREFIX>_<NAME>_destroy()
+ * if it's no longer needed.
+ * @param[out] h The <PREFIX>_<NAME> handle that is newly created
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME> should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone);
+
+/**
+ * @brief Adds the value to the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The value is internally copied and stored.
+ * You should release it if it's allocaed when it's no longer needed,
+ * @param[in] h The <PREFIX>_<NAME> handle.
+ * @param[in] value The value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_remove()
+ */
+int <PREFIX>_<NAME>_add(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value);
+
+/**
+ * @brief Retrieves all values contained in the <PREFIX>_<NAME> handle.
+ * @details This function called <PREFIX>_<NAME>_cb once for each value contained in the <PREFIX>_<NAME> handle.
+ * If the <PREFIX>_<NAME>_cb callback function returns @c false, the iteration will be finished.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] callback The iteration callback function
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_cb()
+ */
+int <PREFIX>_<NAME>_foreach(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_cb callback, void *user_data);
+
+/**
+ * @brief Removes the element at the given position in the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] nth The position of the element
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_remove(<PREFIX>_<NAME>_h h, unsigned int nth);
+
+/**
+ * @brief Gets the number of elements in the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] length The number of elements
+ * @return @c on 0 success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_length(<PREFIX>_<NAME>_h h, unsigned int *length);
+)__c_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_HEADER_GENERATOR_LIST_BASE_CB_HH_
diff --git a/idlc/gen/version2/c_header_generator_map_base_cb.hh b/idlc/gen/version2/c_header_generator_map_base_cb.hh
new file mode 100644
index 0000000..2281fae
--- /dev/null
+++ b/idlc/gen/version2/c_header_generator_map_base_cb.hh
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_HEADER_GENERATOR_MAP_BASE_CB_HH_
+#define IDLC_GEN_VERSION2_C_HEADER_GENERATOR_MAP_BASE_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <PREFIX> The prefix of the map structure.
+ * <NAME> The name of the map structure.
+ * <KEY_PARAM_TYPE> The parameter type of the key of the map structure.
+ * <VALUE_PARAM_TYPE> The parameter type of the value of the map structure.
+ * <VALUE_PARAM_TYPE_OUT> The output parameter type of the value of the map structure.
+ */
+constexpr const char CB_STRUCTURE_MAP_BASE[] =
+R"__c_cb(
+
+/**
+ * @brief Called to retrieve the key/value contained in the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a value MUST NOT be released by the application.
+ * @param[in] key The key of the map
+ * @param[in] value The value of the map
+ * @param[in] user_data The user data passed from the foreach function
+ * @return @c true to continue with the next iteration of the loop,
+ * otherwise @c false to break out of the loop
+ * @see <PREFIX>_<NAME>_foreach()
+ */
+typedef bool (*<PREFIX>_<NAME>_foreach_cb)(<KEY_PARAM_TYPE>key, <VALUE_PARAM_TYPE>value, void *user_data);
+
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a h handle should be released using the <PREFIX>_<NAME>_destroy()
+ * if it's no longer needed.
+ * @param[out] h The <PREFIX>_<NAME> handle that is newly created
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_NONE Internal I/O error
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_set_compare_cb()
+ * @see <PREFIX>_<NAME>_destroy()
+ * @pre <PREFIX>_<NAME>_set_compare_cb()
+ */
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME> should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone);
+
+/**
+ * @brief Inserts the key/value into the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a key and the @a value are copied internally.
+ * If you do the key data comparison based on the address, it makes a problem.
+ * @param[in] h The <PREFIX>_<NAME> handle.
+ * @param[in] key The key to insert.
+ * @param[in] value The value corresponding to the key.
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_erase()
+ */
+int <PREFIX>_<NAME>_insert(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key, <VALUE_PARAM_TYPE>value);
+
+/**
+ * @brief Gets the value corresponding to the given key.
+ *
+ * @remarks The @c value is copied internally. The data being returned is not a reference value.
+ * You should release it if it's no longer needed. The value such as integer does not need to be released.
+ * @param[in] h The <PREFIX>_<NAME> handle.
+ * @param[in] key The key to look up.
+ * @param[out] value The value correspoding to the key.
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_lookup(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key, <VALUE_PARAM_TYPE_OUT>value);
+
+/**
+ * @breif Removes the key/value pair from the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle.
+ * @param[in] key The key to remove.
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_erase(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key);
+
+/**
+ * @brief Inserts the key/value into the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a key and the @a value are copied internally.
+ * If you do the key data comparison based on the address, it makes a problem.
+ * @param[in] h The <PREFIX>_<NAME> handle.
+ * @param[in] key The key to insert.
+ * @param[in] value The value corresponding to the key.
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_insert()
+ */
+int <PREFIX>_<NAME>_replace(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key, <VALUE_PARAM_TYPE>value);
+
+/**
+ * @brief Retrieves all values contained in the <PREFIX>_<NAME> handle.
+ * @details This function called <PREFIX>_<NAME>_foreach_cb once for each the key/value contained in the <PREFIX>_<NAME> handle.
+ * If the <PREFIX>_<NAME>_cb callback function returns @c false, the iteration will be finished.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] callback The iteration callback function
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_foreach_cb()
+ */
+int <PREFIX>_<NAME>_foreach(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_foreach_cb callback, void *user_data);
+
+/**
+ * @brief Checks whether the key exists or not.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] key The key to check.
+ * @param[out] exist If it's true, the key exists.
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_contains(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key, bool *exist);
+
+/**
+ * @brief Gets the number of elements in the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] size The number of elements
+ * @return @c on 0 success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_size(<PREFIX>_<NAME>_h h, size_t *size);
+
+/**
+ * @brief Removes all elements from the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_clear(<PREFIX>_<NAME>_h h);
+)__c_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_HEADER_GENERATOR_MAP_BASE_CB_HH_
diff --git a/idlc/gen/version2/c_header_generator_set_base_cb.hh b/idlc/gen/version2/c_header_generator_set_base_cb.hh
new file mode 100644
index 0000000..9060827
--- /dev/null
+++ b/idlc/gen/version2/c_header_generator_set_base_cb.hh
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_HEADER_GENERATOR_SET_BASE_CB_HH_
+#define IDLC_GEN_VERSION2_C_HEADER_GENERATOR_SET_BASE_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <PREFIX> The prefix of the set structure.
+ * <NAME> The name of the set structure.
+ * <KEY_PARAM_TYPE> The parameter type of the key of the set structure.
+ */
+constexpr const char CB_STRUCTURE_SET_BASE[] =
+R"__c_cb(
+
+/**
+ * @brief Called to retrieve the key contained in the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a value MUST NOT be released by the application.
+ * @param[in] key The key of the map
+ * @param[in] user_data The user data passed from the foreach function
+ * @return @c true to continue with the next iteration of the loop,
+ * otherwise @c false to break out of the loop
+ * @see <PREFIX>_<NAME>_foreach()
+ */
+typedef bool (*<PREFIX>_<NAME>_foreach_cb)(<KEY_PARAM_TYPE>key, void *user_data);
+
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a h handle should be released using the <PREFIX>_<NAME>_destroy()
+ * if it's no longer needed.
+ * @param[out] h The <PREFIX>_<NAME> handle that is newly created
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_IO_ERROR Internal I/O error
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_set_compare_cb()
+ * @see <PREFIX>_<NAME>_destroy()
+ * @pre <PREFIX>_<NAME>_set_compare_cb()
+ */
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME> should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone);
+
+/**
+ * @brief Inserts the key into the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a key is copied internally.
+ * If you do the key data comparison based on the address, it makes a problem.
+ * @param[in] h The <PREFIX>_<NAME> handle.
+ * @param[in] key The key to insert.
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_erase()
+ */
+int <PREFIX>_<NAME>_insert(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key);
+
+/**
+ * @breif Removes the key from the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle.
+ * @param[in] key The key to remove.
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_erase(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key);
+
+/**
+ * @brief Retrieves all keys contained in the <PREFIX>_<NAME> handle.
+ * @details This function called <PREFIX>_<NAME>_foreach_cb once for each the key contained in the <PREFIX>_<NAME> handle.
+ * If the <PREFIX>_<NAME>_cb callback function returns @c false, the iteration will be finished.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] callback The iteration callback function
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_foreach_cb()
+ */
+int <PREFIX>_<NAME>_foreach(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_foreach_cb callback, void *user_data);
+
+/**
+ * @brief Checks whether the key exists or not.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] key The key to check.
+ * @param[out] exist If it's true, the key exists.
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_contains(<PREFIX>_<NAME>_h h, <KEY_PARAM_TYPE>key, bool *exist);
+
+/**
+ * @brief Gets the number of elements in the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] size The number of elements
+ * @return @c on 0 success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_size(<PREFIX>_<NAME>_h h, size_t *size);
+
+/**
+ * @brief Removes all elements from the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_clear(<PREFIX>_<NAME>_h h);
+)__c_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_HEADER_GENERATOR_SET_BASE_CB_HH_
diff --git a/idlc/gen/version2/c_proxy_body_generator.cc b/idlc/gen/version2/c_proxy_body_generator.cc
new file mode 100644
index 0000000..9cbbce7
--- /dev/null
+++ b/idlc/gen/version2/c_proxy_body_generator.cc
@@ -0,0 +1,638 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/c_proxy_body_generator.hh"
+
+#include <libgen.h>
+
+#include <utility>
+
+#include "idlc/gen/version2/c_proxy_body_generator_cb.hh"
+
+namespace tidl {
+namespace version2 {
+
+CProxyBodyGenerator::CProxyBodyGenerator(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options)
+ : CBodyGeneratorBase(std::move(doc)),
+ options_(std::move(options)) {
+}
+
+void CProxyBodyGenerator::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenGNUSourceDefinition(stream);
+ GenIncludeDefaultHeaders(stream);
+ GenIncludeLemHeaders(stream);
+ GenIncludeHeader(stream);
+ GenLogTag(stream, std::string("RPC_PORT_PROXY"));
+ GenLogDefinition(stream);
+ GenVersionDefinition(stream);
+ GenBaseDefinition(stream);
+ GenUnitMapDefinition(stream);
+ GenLemDefinition(stream);
+ GenDelegateDefinition(stream);
+ GenInterfaceDelegateCallback(stream);
+ GenStructureDefinition(stream);
+ GenRemoteExceptionDefinition(stream);
+ GenInterfaceDefinition(stream);
+ GenUnitMapBase(stream);
+ GenLemBase(stream);
+ GenDelegateBase(stream);
+ GenPrivateSharingListSet(stream);
+ GenStructure(stream);
+ GenRemoteExceptionBase(stream);
+ GenInterface(stream);
+ GenLemAPI(stream);
+}
+
+void CProxyBodyGenerator::OnFiniGen(std::ofstream& stream) {
+}
+
+void CProxyBodyGenerator::GenLemDefinition(std::ofstream& stream) {
+ stream << SmartIndent(CB_LEM_PROXY_BASE_DEF);
+}
+
+void CProxyBodyGenerator::GenLemBase(std::ofstream& stream) {
+ std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
+ input = input.substr(0, input.find_last_of("."));
+ ReplaceAll(CB_LEM_PROXY_BASE)
+ .Change("<INPUT_FILE>", input)
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CProxyBodyGenerator::GenLemAPI(std::ofstream& stream) {
+ std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
+ input = input.substr(0, input.find_last_of("."));
+ std::string code;
+ for (auto& iter : GetDocument().GetBlocks()) {
+ if (iter->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const auto& iface = static_cast<const Interface&>(*iter);
+ code += ReplaceAll(CB_LEM_PROXY_API)
+ .Change("<INPUT_FILE>", input)
+ .Change("<IFACE_NAME>", iface.GetID());
+ }
+
+ stream << SmartIndent(code);
+}
+
+void CProxyBodyGenerator::GenDelegateDefinition(std::ofstream& stream) {
+ if (HasDelegate())
+ stream << SmartIndent(CB_DELEGATE_DEFS);
+}
+
+void CProxyBodyGenerator::GenDelegateBase(std::ofstream& stream) {
+ if (HasDelegate())
+ stream << SmartIndent(CB_DELEGATE_BASE);
+}
+
+void CProxyBodyGenerator::GenInterfaceDelegateCallback(std::ofstream& stream) {
+ if (HasDelegate())
+ stream << SmartIndent(CB_INTERFACE_DELEGATE_CALLBACK);
+}
+
+void CProxyBodyGenerator::GenInterfaceDefinition(std::ofstream& stream) {
+ for (auto& iter : GetDocument().GetBlocks()) {
+ if (iter->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const auto& iface = static_cast<const Interface&>(*iter);
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateDefinition(stream, iface, *decl);
+ }
+
+ GenInterfaceBaseDefinition(stream, iface);
+ }
+}
+
+void CProxyBodyGenerator::GenInterfaceDelegateDefinition(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_DELEGATE_DEF)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<DELEGATE_NAME>", decl.GetID())
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+}
+
+void CProxyBodyGenerator::GenInterfaceBaseDefinition(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_BASE_DEF)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+}
+
+void CProxyBodyGenerator::GenInterface(std::ofstream& stream) {
+ for (auto& iter : GetDocument().GetBlocks()) {
+ if (iter->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const auto& iface = static_cast<const Interface&>(*iter);
+ GenInterfaceDelegateEnumBase(stream, iface);
+
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateBase(stream, iface, *decl);
+ }
+
+ GenInterfaceDelegateTable(stream, iface);
+ GenInterfaceMethodEnumBase(stream, iface);
+ GenDelegateProcess(stream, iface);
+ GenInterfaceBase(stream, iface);
+
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceMethodBase(stream, iface, *decl);
+ }
+ }
+}
+
+std::string CProxyBodyGenerator::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& param : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = param->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ param->GetID();
+ }
+
+ return params;
+}
+
+std::string CProxyBodyGenerator::GenMethodArgs(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& param : decl.GetParameters()) {
+ auto& param_type = param->GetParameterType();
+ if (param_type.GetDirection() == ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ code += GetReturnTypeString(type) + "new_" + param->GetID() + ";";
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+std::string CProxyBodyGenerator::GenMethodParamsCheck(const Interface& iface,
+ const Declaration& decl) {
+ std::string params_check;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.GetMetaType() != nullptr ||
+ type.ToString() == "bundle" ||
+ type.ToString() == "string" ||
+ type.ToString() == "file")
+ params_check += " || " + p->GetID() + " == nullptr";
+ }
+
+ return params_check;
+}
+
+std::string CProxyBodyGenerator::GenMethodUnitMapWrite(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& param : decl.GetParameters()) {
+ auto& param_type = param->GetParameterType();
+ if (param_type.GetDirection() == ParameterType::Direction::OUT)
+ continue;
+
+ std::string arg = param->GetID();
+ if (param_type.GetDirection() == ParameterType::Direction::REF)
+ arg = "*" + arg;
+
+ auto& type = param_type.GetBaseType();
+ if (type.GetUserDefinedType() == BaseType::UserType::DELEGATE) {
+ code += ReplaceAll(CB_INTERFACE_METHOD_DELEGATE_UNIT_MAP_WRITE)
+ .Change("<ARG_NAME>", param->GetID())
+ .Change("<ARG>", arg);
+ } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code += ReplaceAll(CB_INTERFACE_METHOD_ENUM_UNIT_MAP_WRITE)
+ .Change("<ARG_NAME>", param->GetID())
+ .Change("<ARG>", arg);
+ } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr) {
+ code += ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_WRITE)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG_NAME>", param->GetID())
+ .Change("<ARG>", arg);
+ code += GetPrivateSharingString(type, iface, "h->port", param->GetID());
+ } else if (type.ToString() == "bundle") {
+ code += ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_WRITE)
+ .Change("<ARG_NAME>", param->GetID())
+ .Change("<ARG>", arg);
+ } else if (type.ToString() == "string") {
+ code += ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE)
+ .Change("<ARG_NAME>", param->GetID())
+ .Change("<ARG>", arg);
+ } else if (type.ToString() == "file") {
+ code += ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE)
+ .Change("<ARG_NAME>", param->GetID())
+ .Change("<ARG>", arg);
+ code += GetPrivateSharingString(type, iface, "h->port", param->GetID());
+ } else {
+ code += ReplaceAll(CB_INTERFACE_METHOD_BASE_UNIT_MAP_WRITE)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG_NAME>", param->GetID())
+ .Change("<ARG>", arg);
+ }
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CProxyBodyGenerator::GenMethodDelegateAppend(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& param : decl.GetParameters()) {
+ auto& param_type = param->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type)) {
+ code += ReplaceAll(CB_INTERFACE_METHOD_DELEGATE_APPEND)
+ .Change("<ARG>", param->GetID());
+ }
+ }
+
+ return RemoveLine(code);
+}
+
+void CProxyBodyGenerator::GenMethodAsyncBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_ASYNC_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<METHOD_NAME>", decl.GetID())
+ .Change("<METHOD_PARAMS>", GenMethodParams(iface, decl))
+ .Change("<METHOD_PARAMS_CHECK>", GenMethodParamsCheck(iface, decl))
+ .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
+ .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
+ .ChangeToUpper("<UPPERCASE_METHOD_NAME>", decl.GetID())
+ .Change("<METHOD_UNIT_MAP_WRITE>", GenMethodUnitMapWrite(iface, decl))
+ .Change("<METHOD_DELEGATE_APPEND>", GenMethodDelegateAppend(iface, decl))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+std::string CProxyBodyGenerator::GenMethodUnitMapReadBase(
+ const Interface& iface, const BaseType& type,
+ const std::string& arg_name, const std::string& arg) {
+ std::string code;
+ if (type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_READ)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code += ReplaceAll(CB_INTERFACE_METHOD_EMUM_UNIT_MAP_READ)
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ } else if (type.ToString() == "bundle") {
+ code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_READ)
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_READ)
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ } else {
+ code = ReplaceAll(CB_INTERFACE_METHOD_BASE_UNIT_MAP_READ)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ }
+
+ return code;
+}
+
+std::string CProxyBodyGenerator::GenMethodRefFree(
+ const Interface& iface, const BaseType& type, const std::string& arg) {
+ std::string code;
+ if (type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
+ code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_REF_FREE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG>", arg);
+ } else if (type.ToString() == "bundle") {
+ code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_REF_FREE)
+ .Change("<ARG>", arg);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = ReplaceAll(CB_INTERFACE_METHOD_STRING_REF_FREE)
+ .Change("<ARG>", arg);
+ }
+
+ return code;
+}
+
+std::string CProxyBodyGenerator::GenMethodUnitMapRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ std::string parcel_read_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() == ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ code += GenMethodUnitMapReadBase(iface, type, p->GetID(),
+ "new_" + p->GetID());
+ if (param_type.GetDirection() == ParameterType::Direction::REF)
+ code += GenMethodRefFree(iface, type, p->GetID());
+
+ code += ReplaceAll(CB_INTERFACE_METHOD_PARAM_SET, "<PARAM>",
+ p->GetID());
+ }
+
+ auto& base_type = decl.GetType();
+ code += GenMethodUnitMapReadBase(iface, base_type, "[RESULT]", "ret_");
+ return RemoveLine(code);
+}
+
+void CProxyBodyGenerator::GenMethodBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_BASE)
+ .Change("<RETURN_TYPE>",
+ GetReturnTypeString(decl.GetType(), iface.GetID()))
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<METHOD_NAME>", decl.GetID())
+ .Change("<METHOD_PARAMS>", GenMethodParams(iface, decl))
+ .Change("<METHOD_ARGS>", GenMethodArgs(iface, decl))
+ .Change("<ERROR_VALUE>", GetErrorValue(decl.GetType()))
+ .Change("<METHOD_PARAMS_CHECK>", GenMethodParamsCheck(iface, decl))
+ .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
+ .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
+ .ChangeToUpper("<UPPERCASE_METHOD_NAME>", decl.GetID())
+ .Change("<METHOD_UNIT_MAP_WRITE>", GenMethodUnitMapWrite(iface, decl))
+ .Change("<METHOD_UNIT_MAP_READ>", GenMethodUnitMapRead(iface, decl))
+ .Change("<METHOD_DELEGATE_APPEND>", GenMethodDelegateAppend(iface, decl))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CProxyBodyGenerator::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code;
+ auto method_type = decl.GetMethodType();
+ if (method_type == Declaration::MethodType::ASYNC)
+ GenMethodAsyncBase(stream, iface, decl);
+ else
+ GenMethodBase(stream, iface, decl);
+}
+
+void CProxyBodyGenerator::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+ std::string event = HasDelegate() ? CB_INTERFACE_DELEGATE_REGISTER_EVENT : "";
+
+ ReplaceAll(CB_INTERFACE_BASE)
+ .Change("<DELEGATE_REGISTER_EVENT>", event)
+ .Change("<PREFIX>", prefix)
+ .Change("<NAME>", name)
+ .Change("<PREFIX_REVERSE>", GetHandlePrefixReverse())
+ .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
+ .ChangeToUpper("<UPPERCASE_NAME>", name)
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CProxyBodyGenerator::GenInterfaceMethodEnumBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string enums = GetHandlePrefix() + "_" + iface.GetID() +
+ "_METHOD_RESULT_," + NLine(1);
+ enums += GetHandlePrefix() + "_" + iface.GetID() + "_METHOD_CALLBACK_," +
+ NLine(1);
+
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ enums += GetHandlePrefix() + "_" + iface.GetID() + "_METHOD_" +
+ decl->GetID() + "," + NLine(1);
+ }
+
+ ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE)
+ .ChangeToUpper("<ENUMS>", enums)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CProxyBodyGenerator::GenDelegateProcess(std::ofstream& stream,
+ const Interface& iface) {
+ if (!HasDelegate())
+ return;
+
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+
+ ReplaceAll(CB_INTERFACE_DELEGATE_PROCESS_BASE)
+ .Change("<PREFIX>", prefix)
+ .Change("<NAME>", name)
+ .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
+ .ChangeToUpper("<UPPERCASE_NAME>", name)
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CProxyBodyGenerator::GenInterfaceDelegateTable(std::ofstream& stream,
+ const Interface& iface) {
+ if (!HasDelegate())
+ return;
+
+ std::string delegate_handlers;
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_DELEGATE_" + decl->GetID();
+ delegate_handlers += ReplaceAll(CB_INTERFACE_DELEGATE_TABLE_MEMBER)
+ .ChangeToUpper("<ENUM_VALUE>", enum_value)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<DELEGATE_NAME>", decl->GetID())
+ .Transform([&](std::string code) { return RemoveLine(code); });
+ }
+
+ if (delegate_handlers.empty())
+ delegate_handlers = "nullptr," + NLine(1);
+
+ ReplaceAll(CB_INTERFACE_DELEGATE_TABLE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<DELEGATE_HANDLERS>", delegate_handlers)
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CProxyBodyGenerator::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_DELEGATE_" + decl.GetID();
+ bool has_free = false;
+ std::string delegate_args_free = GenDelegateArgsFree(iface, decl, &has_free);
+
+ ReplaceAll(CB_INTERFACE_DELEGATE_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<DELEGATE_NAME>", decl.GetID())
+ .ChangeToUpper("<DELEGATE_ENUM_VALUE>", enum_value)
+ .Change("<DELEGATE_ARGS_DECL>", GenDelegateArgsDecl(iface, decl))
+ .Change("<DELEGATE_UNIT_MAP_READ>", GenDelegateUnitMapRead(iface, decl))
+ .Change("<DELEGATE_ARGS_FREE>", delegate_args_free)
+ .Change("<DELEGATE_CALLBACK_ARGS>", GenDelegateCallbackArgs(decl))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+std::string CProxyBodyGenerator::GenDelegateCallbackArgs(
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& param : decl.GetParameters())
+ code += ", " + param->GetID();
+
+ return code;
+}
+
+std::string CProxyBodyGenerator::GenDelegateUnitMapRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& param : decl.GetParameters()) {
+ auto& param_type = param->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code += ReplaceAll(CB_INTERFACE_DELEGATE_USER_DEFINED_UNIT_MAP_READ)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG>", param->GetID());
+
+ } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code += ReplaceAll(CB_INTERFACE_DELEGATE_ENUM_UNIT_MAP_READ)
+ .Change("<ARG_NAME>", param->GetID())
+ .Change("<ARG>", param->GetID());
+ } else if (type.ToString() == "bundle") {
+ code += ReplaceAll(CB_INTERFACE_DELEGATE_BUNDLE_UNIT_MAP_READ)
+ .Change("<ARG>", param->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code += ReplaceAll(CB_INTERFACE_DELEGATE_STRING_UNIT_MAP_READ)
+ .Change("<ARG>", param->GetID());
+ } else {
+ code += ReplaceAll(CB_INTERFACE_DELEGATE_BASE_UNIT_MAP_READ)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG_NAME>", param->GetID())
+ .Change("<ARG>", param->GetID());
+ }
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CProxyBodyGenerator::GenDelegateArgsDecl(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& param : decl.GetParameters()) {
+ auto& param_type = param->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM)
+ code += GetArgTypeString(type, iface) + param->GetID() + ";" + NLine(1);
+ else
+ code += GetArgTypeString(type, iface) + param->GetID() + " = " +
+ GetErrorValue(param_type.GetBaseType()) + ";" + NLine(1);
+ }
+
+ return code;
+}
+
+std::string CProxyBodyGenerator::GenDelegateArgsFree(const Interface& iface,
+ const Declaration& decl, bool* has_free) {
+ std::string code;
+ for (const auto& param : decl.GetParameters()) {
+ auto& param_type = param->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code += ReplaceAll(CB_INTERFACE_DELEGATE_USER_DEFINED_ARG_FREE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG>", param->GetID());
+ *has_free = true;
+ } else if (type.ToString() == "bundle") {
+ code += ReplaceAll(CB_INTERFACE_DELEGATE_BUNDLE_ARG_FREE,
+ "<ARG>", param->GetID());
+ *has_free = true;
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code += ReplaceAll(CB_INTERFACE_DELEGATE_STRING_ARG_FREE,
+ "<ARG>", param->GetID());
+ *has_free = true;
+ }
+ }
+
+ return RemoveLine(code);
+}
+
+void CProxyBodyGenerator::GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& iface) {
+ unsigned int num = 1;
+ std::string enums;
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ enums += GetHandlePrefix() + "_" + iface.GetID() + "_DELEGATE_" +
+ decl->GetID();
+ enums += " = " + std::to_string(num++) + ",";
+ enums += NLine(1);
+ }
+
+ if (enums.empty())
+ return;
+
+ ReplaceAll(CB_INTERFACE_DELEGATE_ENUM_BASE)
+ .ChangeToUpper("<ENUMS>", enums)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/c_proxy_body_generator.hh b/idlc/gen/version2/c_proxy_body_generator.hh
new file mode 100644
index 0000000..bdfbc55
--- /dev/null
+++ b/idlc/gen/version2/c_proxy_body_generator.hh
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_PROXY_BODY_GENERATOR_HH_
+#define IDLC_GEN_VERSION2_C_PROXY_BODY_GENERATOR_HH_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/version2/c_body_generator_base.hh"
+#include "idlc/options.h"
+
+namespace tidl {
+namespace version2 {
+
+class CProxyBodyGenerator : public CBodyGeneratorBase {
+ public:
+ explicit CProxyBodyGenerator(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options);
+ virtual ~CProxyBodyGenerator() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenInterfaceDelegateCallback(std::ofstream& stream);
+ void GenInterfaceDefinition(std::ofstream& stream);
+ void GenInterfaceDelegateDefinition(std::ofstream& stream,
+ const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceBaseDefinition(std::ofstream& stream,
+ const Interface& iface);
+ void GenInterface(std::ofstream& stream);
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+ std::string GenMethodArgs(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParamsCheck(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodUnitMapWrite(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodDelegateAppend(const Interface& iface,
+ const Declaration& decl);
+ void GenMethodAsyncBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodUnitMapReadBase(const Interface& iface,
+ const BaseType& type,
+ const std::string& arg_name,
+ const std::string& arg);
+ std::string GenMethodUnitMapRead(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodRefFree(const Interface& iface, const BaseType& type,
+ const std::string& arg);
+ void GenMethodBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodEnumBase(std::ofstream& stream,
+ const Interface& iface);
+ void GenInterfaceDelegateTable(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenDelegateProcess(std::ofstream& stream, const Interface& iface);
+ std::string GenDelegateCallbackArgs(const Declaration& decl);
+ std::string GenDelegateUnitMapRead(const Interface& iface,
+ const Declaration& decl);
+ std::string GenDelegateArgsDecl(const Interface& iface,
+ const Declaration& decl);
+ std::string GenDelegateArgsFree(const Interface& iface,
+ const Declaration& decl, bool* has_free);
+ void GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& iface);
+ void GenDelegateDefinition(std::ofstream& stream);
+ void GenDelegateBase(std::ofstream& stream);
+ void GenLemDefinition(std::ofstream& stream);
+ void GenLemBase(std::ofstream& stream);
+ void GenLemAPI(std::ofstream& stream);
+
+ private:
+ std::shared_ptr<Options> options_;
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_PROXY_BODY_GENERATOR_HH_
diff --git a/idlc/gen/version2/c_proxy_body_generator_cb.hh b/idlc/gen/version2/c_proxy_body_generator_cb.hh
new file mode 100644
index 0000000..40602f5
--- /dev/null
+++ b/idlc/gen/version2/c_proxy_body_generator_cb.hh
@@ -0,0 +1,1729 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_PROXY_BODY_GENERATOR_CB_HH_
+#define IDLC_GEN_VERSION2_C_PROXY_BODY_GENERATOR_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+constexpr const char CB_DELEGATE_DEFS[] =
+R"__c_cb(
+typedef struct rpc_port_delegate_s {
+ rpc_port_parcelable_t parcelable;
+ int id;
+ int seq_id;
+ bool once;
+} rpc_port_delegate_t;
+
+typedef rpc_port_delegate_t *rpc_port_delegate_h;
+
+static rpc_port_delegate_h rpc_port_delegate_create();
+)__c_cb";
+
+constexpr const char CB_DELEGATE_BASE[] =
+R"__c_cb(
+static void __rpc_port_delegate_to(rpc_port_parcel_h parcel, void *user_data)
+{
+ rpc_port_delegate_h delegate = user_data;
+ rpc_port_unit_map_h map;
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_unit_map_write_int(map, "id", delegate->id);
+ rpc_port_unit_map_write_int(map, "seq_id", delegate->seq_id);
+ rpc_port_unit_map_write_bool(map, "once", delegate->once);
+ rpc_port_parcel_write(parcel, &map->parcelable, map);
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static void __rpc_port_delegate_from(rpc_port_parcel_h parcel, void *user_data)
+{
+ rpc_port_delegate_h delegate = user_data;
+ rpc_port_unit_map_h map;
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_parcel_read(parcel, &map->parcelable, map);
+ rpc_port_unit_map_read_int(map, "id", &delegate->id);
+ rpc_port_unit_map_read_int(map, "seq_id", &delegate->seq_id);
+ rpc_port_unit_map_read_bool(map, "once", &delegate->once);
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static void rpc_port_delegate_destroy(rpc_port_delegate_h handle)
+{
+ if (handle == nullptr)
+ return;
+
+ free(handle);
+}
+
+static rpc_port_delegate_h rpc_port_delegate_create()
+{
+ rpc_port_delegate_h delegate;
+
+ delegate = calloc(1, sizeof(rpc_port_delegate_t));
+ if (delegate == nullptr) {
+ _E("malloc() is failed");
+ return nullptr;
+ }
+
+ delegate->parcelable.to = __rpc_port_delegate_to;
+ delegate->parcelable.from = __rpc_port_delegate_from;
+
+ return delegate;
+}
+)__c_cb";
+
+constexpr const char CB_INTERFACE_DELEGATE_CALLBACK[] =
+R"__c_cb(
+typedef void (*rpc_port_proxy_delegate_cb)(GList **delegates, rpc_port_unit_map_h map, rpc_port_delegate_h delegate);
+)__c_cb";
+
+/**
+ * <ENUMS> The enumeration of the interface delegate.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_ENUM_BASE[] =
+R"__c_cb(
+typedef enum {
+ <ENUMS>
+} <PREFIX>_<NAME>_delegate_e;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ int id;
+ int seq_id;
+ bool once;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback;
+ void *user_data;
+} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ * <DELEGATE_ENUM_VALUE> The enumeration value of the delegate.
+ * <DELEGATE_ARGS_DECL> The implementation to declares the arguments.
+ * <DELEGATE_PARCEL_READ> The implementation to read the arguments from the parcel.
+ * <DELEGATE_ARGS_FREE> The implementation to release the allocated arguments.
+ * <DELEGATE_CALLBACK_ARGS> The arguments of the delegate callback.
+ * <GOTO_STATEMENT> The statement label.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = data;
+ rpc_port_unit_map_h map;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_unit_map_write_int(map, "id", h->id);
+ rpc_port_unit_map_write_int(map, "seq_id", h->seq_id);
+ rpc_port_unit_map_write_bool(map, "once", h->once);
+
+ rpc_port_parcel_write(parcel, &map->parcelable, map);
+ rpc_port_unit_map_destroy(map);
+
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = data;
+ rpc_port_unit_map_h map;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_parcel_read(parcel, &map->parcelable, map);
+ rpc_port_unit_map_read_int(map, "id", &h->id);
+ rpc_port_unit_map_read_int(map, "seq_id", &h->seq_id);
+ rpc_port_unit_map_read_bool(map, "once", &h->once);
+
+ rpc_port_unit_map_destroy(map);
+
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_t *handle;
+ static int seq_num;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_<DELEGATE_NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_<DELEGATE_NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_<DELEGATE_NAME>_from;
+ handle->id = <DELEGATE_ENUM_VALUE>;
+ handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+ _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ _W("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+
+ free(h);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone)
+{
+ rpc_port_unit_map_h map;
+ int ret;
+
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = rpc_port_unit_map_write_<NAME>_<DELEGATE_NAME>(map, "clone", h);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to write <DELEGATE_NAME>. error(%d)", ret);
+ rpc_port_unit_map_destroy(map);
+ return ret;
+ }
+
+ rpc_port_unit_map_read_<NAME>_<DELEGATE_NAME>(map, "clone", clone);
+ rpc_port_unit_map_destroy(map);
+
+ return ret;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_callback(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback, void *user_data)
+{
+ if (h == nullptr || callback == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ h->callback = callback;
+ h->user_data = user_data;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool once)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ h->once = once;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id)
+{
+ if (h == nullptr || id == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *id = h->id;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id)
+{
+ if (h == nullptr || seq_id == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *seq_id = h->seq_id;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once)
+{
+ if (h == nullptr || once == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *once = h->once;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag)
+{
+ char *new_tag;
+ char buf[128];
+
+ if (h == nullptr || tag == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ snprintf(buf, sizeof(buf), "%d::%d", h->id, h->seq_id);
+ new_tag = strdup(buf);
+ if (new_tag == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ *tag = new_tag;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose(<PREFIX>_<NAME>_h proxy, <PREFIX>_<NAME>_<DELEGATE_NAME>_h h)
+{
+ GList *found;
+
+ if (proxy == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&proxy->mutex);
+ found = g_list_find(proxy->delegates, h);
+ if (found == nullptr) {
+ _E("Invalid parameter");
+ g_rec_mutex_unlock(&proxy->mutex);
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ proxy->delegates = g_list_remove_link(proxy->delegates, found);
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(h);
+ g_list_free(found);
+ g_rec_mutex_unlock(&proxy->mutex);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_delegate_handler(GList **delegates, rpc_port_unit_map_h map, rpc_port_delegate_h delegate)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h handle;
+ GList *iter;
+ bool once;
+
+ <DELEGATE_ARGS_DECL>
+
+ <DELEGATE_UNIT_MAP_READ>
+
+ iter = *delegates;
+ while (iter) {
+ handle = iter->data;
+ iter = g_list_next(iter);
+ if (handle->id == delegate->id && handle->seq_id == delegate->seq_id) {
+ once = handle->once;
+ _W("Invoke id(%d), seq_id(%d)", handle->id, handle->seq_id);
+ if (handle->callback)
+ handle->callback(handle->user_data<DELEGATE_CALLBACK_ARGS>);
+ else
+ _W("The callback function is nullptr");
+
+ if (once) {
+ *delegates = g_list_remove(*delegates, handle);
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(handle);
+ }
+
+ break;
+ }
+ }
+
+ <DELEGATE_ARGS_FREE>
+ return;
+}
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_USER_DEFINED_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_<TYPE_NAME>(map, "<ARG>", &<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BUNDLE_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_bundle(map, "<ARG>", &<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_STRING_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_string(map, "<ARG>", &<ARG>);
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_ENUM_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_int(map, "<ARG_NAME>", (int *)&<ARG>);
+)__c_cb";
+
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_<TYPE_NAME>(map, "<ARG_NAME>", &<ARG>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_USER_DEFINED_ARG_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ <PREFIX>_<NAME>_destroy(<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BUNDLE_ARG_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ bundle_free(<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The name of the value;
+ */
+constexpr const char CB_INTERFACE_DELEGATE_STRING_ARG_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ free(<ARG>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_HANDLERS> The array of the delegate callbacks.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_TABLE[] =
+R"__c_cb(
+static rpc_port_proxy_delegate_cb __<PREFIX>_<NAME>_delegate_table[] = {
+ <DELEGATE_HANDLERS>
+};
+)__c_cb";
+
+/**
+ * <ENUM_VALUE> The enumeration value.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_TABLE_MEMBER[] =
+R"__c_cb(
+[<ENUM_VALUE>] = __<PREFIX>_<NAME>_<DELEGATE_NAME>_delegate_handler,
+)__c_cb";
+
+/**
+ * <ENUMS> The enumerations of the interface method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM_BASE[] =
+R"__c_cb(
+typedef enum {
+ <ENUMS>
+} <PREFIX>_<NAME>_method_e;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ char *stub_appid;
+ rpc_port_proxy_h proxy;
+ rpc_port_h port;
+ rpc_port_h callback_port;
+ <PREFIX>_<NAME>_callback_s callback;
+ void *user_data;
+ GList *delegates;
+ GRecMutex mutex;
+ rpc_port_proxy_lem_h lem;
+} <PREFIX>_<NAME>_t;
+
+<PREFIX>_<NAME>_h __<PREFIX>_<NAME>_handle;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_PROCESS_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_process_received_event(GList **delegates, rpc_port_unit_map_h map)
+{
+ rpc_port_delegate_h delegate;
+
+ rpc_port_unit_map_read_delegate(map, "delegate", &delegate);
+
+ _W("id(%d), seq_id(%d)", delegate->id, delegate->seq_id);
+
+ if (delegate->id > 0 && delegate->id < ARRAY_SIZE(__<PREFIX>_<NAME>_delegate_table)) {
+ if (__<PREFIX>_<NAME>_delegate_table[delegate->id])
+ __<PREFIX>_<NAME>_delegate_table[delegate->id](delegates, map, delegate);
+ } else {
+ _W("Unknown ID(%d)", delegate->id);
+ }
+
+ rpc_port_delegate_destroy(delegate);
+}
+
+static void __<PREFIX>_<NAME>_lem_received(void *context, rpc_port_parcel_h parcel)
+{
+ <PREFIX>_<NAME>_t *h = context;
+ rpc_port_unit_map_h map;
+ int cmd = -1;
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ return;
+ }
+
+ rpc_port_parcel_read(parcel, &map->parcelable, map);
+
+ rpc_port_unit_map_read_int(map, "[METHOD]", &cmd);
+ if (cmd != <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_CALLBACK_) {
+ _E("Invalid protocol");
+ rpc_port_unit_map_destroy(map);
+ return;
+ }
+
+ __<PREFIX>_<NAME>_process_received_event(&h->delegates, map);
+ rpc_port_unit_map_destroy(map);
+}
+
+static void __<PREFIX>_<NAME>_received(const char *endpoint, const char *port_name, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+ rpc_port_parcel_h parcel;
+ rpc_port_unit_map_h map;
+ int cmd = -1;
+ int ret;
+
+ _W("endpoint(%s), port_name(%s)", endpoint, port_name);
+ ret = rpc_port_parcel_create_from_port(&parcel, h->callback_port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle from port. error(%d)", ret);
+ return;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ rpc_port_parcel_destroy(parcel);
+ return;
+ }
+
+ rpc_port_parcel_read(parcel, &map->parcelable, map);
+ rpc_port_parcel_destroy(parcel);
+
+ rpc_port_unit_map_read_int(map, "[METHOD]", &cmd);
+ if (cmd != <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_CALLBACK_) {
+ _E("Invalid protocol");
+ rpc_port_unit_map_destroy(map);
+ return;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ __<PREFIX>_<NAME>_process_received_event(&h->delegates, map);
+ g_rec_mutex_unlock(&h->mutex);
+ rpc_port_unit_map_destroy(map);
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_REGISTER_EVENT[] =
+R"__c_cb(
+ret = rpc_port_proxy_add_received_event_cb(handle->proxy, __<PREFIX>_<NAME>_received, handle);
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add received event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+}
+
+lem_callback.received = __<PREFIX>_<NAME>_lem_received;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_consume_command(rpc_port_h port, int seq_num, rpc_port_unit_map_h *unit_map)
+{
+ rpc_port_parcel_h parcel;
+ rpc_port_parcel_header_h header;
+ rpc_port_unit_map_h map;
+ int recv_seq_num = -1;
+ int cmd = -1;
+ int ret;
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ return;
+ }
+
+ do {
+ ret = rpc_port_parcel_create_from_port(&parcel, port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel from port. error(%d)", ret);
+ break;
+ }
+
+ rpc_port_parcel_get_header(parcel, &header);
+ rpc_port_parcel_header_get_seq_num(header, &recv_seq_num);
+ if (recv_seq_num != seq_num) {
+ _W("%d : %d", recv_seq_num, seq_num);
+ rpc_port_parcel_destroy(parcel);
+ continue;
+ }
+
+ rpc_port_parcel_read(parcel, &map->parcelable, map);
+ rpc_port_parcel_destroy(parcel);
+
+ rpc_port_unit_map_read_int(map, "[METHOD]", &cmd);
+ if (cmd == <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_RESULT_) {
+ if (__<PREFIX>_remote_exception != nullptr)
+ <PREFIX>_remote_exception_destroy(__<PREFIX>_remote_exception);
+
+ __<PREFIX>_remote_exception = nullptr;
+ rpc_port_unit_map_read_remote_exception(map, "[REMOTE_EXCEPTION]", &__<PREFIX>_remote_exception);
+
+ *unit_map = map;
+ return;
+ }
+
+ rpc_port_unit_map_clear(map);
+ } while (true);
+
+ rpc_port_unit_map_destroy(map);
+ *unit_map = nullptr;
+}
+
+static void __<PREFIX>_<NAME>_connected(const char *endpoint, const char *port_name, rpc_port_h port, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+
+ _I("endpoint(%s), port_name(%s)", endpoint, port_name);
+ h->port = port;
+ rpc_port_proxy_get_port(h->proxy, RPC_PORT_PORT_CALLBACK, &h->callback_port);
+ h->callback.connected(h, h->user_data);
+}
+
+static void __<PREFIX>_<NAME>_disconnected(const char *endpoint, const char *port_name, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+
+ _W("endpoint(%s), port_name(%s)", endpoint, port_name);
+ h->port = nullptr;
+ h->callback.disconnected(h, h->user_data);
+}
+
+static void __<PREFIX>_<NAME>_rejected(const char *endpoint, const char *port_name, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+
+ _W("endpoint(%s), port_name(%s)", endpoint, port_name);
+ h->port = nullptr;
+ h->callback.rejected(h, h->user_data);
+}
+
+static void __<PREFIX>_<NAME>_lem_connected(void *context)
+{
+ <PREFIX>_<NAME>_t *handle = context;
+
+ handle->callback.connected(handle, handle->user_data);
+}
+
+static void __<PREFIX>_<NAME>_lem_disconnected(void *context)
+{
+ <PREFIX>_<NAME>_t *handle = context;
+
+ handle->callback.disconnected(handle, handle->user_data);
+}
+
+int <PREFIX>_<NAME>_create(const char *stub_appid, <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+ int ret;
+ rpc_port_proxy_lem_event_s lem_callback = { 0, };
+ const char *appid = __get_appid();
+
+ if (stub_appid == nullptr || callback == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (callback->connected == nullptr || callback->disconnected == nullptr || callback->rejected == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ g_rec_mutex_init(&handle->mutex);
+
+ handle->stub_appid = strdup(stub_appid);
+ if (handle->stub_appid == nullptr) {
+ _E("Failed to duplicate stub appid");
+ <PREFIX>_<NAME>_destroy(handle);
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = rpc_port_proxy_create(&handle->proxy);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create proxy handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ handle->callback = *callback;
+ handle->user_data = user_data;
+
+ ret = rpc_port_proxy_add_connected_event_cb(handle->proxy, __<PREFIX>_<NAME>_connected, handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add connected event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = rpc_port_proxy_add_disconnected_event_cb(handle->proxy, __<PREFIX>_<NAME>_disconnected, handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add disconnected event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = rpc_port_proxy_add_rejected_event_cb(handle->proxy, __<PREFIX>_<NAME>_rejected, handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add rejected event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+ <DELEGATE_REGISTER_EVENT>
+ lem_callback.connected = __<PREFIX>_<NAME>_lem_connected;
+ lem_callback.disconnected = __<PREFIX>_<NAME>_lem_disconnected;
+
+ if (appid != nullptr && !strcmp(appid, stub_appid)) {
+ handle->lem = rpc_port_proxy_lem_create(handle, "<NAME>", &lem_callback);
+ if (handle->lem == nullptr) {
+ _E("Failed to create lem");
+ <PREFIX>_<NAME>_destroy(handle);
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ rpc_port_proxy_lem_load_symbols(handle->lem);
+ }
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ g_rec_mutex_unlock(&h->mutex);
+ g_rec_mutex_clear(&h->mutex);
+
+ if (h->delegates)
+ g_list_free_full(h->delegates, free);
+
+ if (h->proxy)
+ rpc_port_proxy_destroy(h->proxy);
+
+ if (h->stub_appid)
+ free(h->stub_appid);
+
+ if (h->lem) {
+ rpc_port_proxy_lem_disconnect(h->lem);
+ rpc_port_proxy_lem_destroy(h->lem);
+ }
+
+ free(h);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_connect(<PREFIX>_<NAME>_h h)
+{
+ int ret;
+
+ if (h == nullptr || h->proxy == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (h->lem != nullptr && rpc_port_proxy_lem_load_symbols(h->lem))
+ ret = rpc_port_proxy_lem_connect(h->lem, false);
+ else
+ ret = rpc_port_proxy_connect(h->proxy, h->stub_appid, "<NAME>");
+
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to connect to stub. error(%d)", ret);
+ return ret;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_connect_sync(<PREFIX>_<NAME>_h h)
+{
+ int ret;
+
+ if (h == nullptr || h->proxy == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (h->lem != nullptr && rpc_port_proxy_lem_load_symbols(h->lem))
+ ret = rpc_port_proxy_lem_connect(h->lem, true);
+ else
+ ret = rpc_port_proxy_connect_sync(h->proxy, h->stub_appid, "<NAME>");
+
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to connect to stub. error(%d)", ret);
+ return ret;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_disconnect(<PREFIX>_<NAME>_h h)
+{
+ int ret;
+
+ if (h == nullptr ) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (h->proxy == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (h->lem != nullptr && rpc_port_proxy_lem_is_connected(h->lem))
+ {
+ rpc_port_proxy_lem_disconnect(h->lem);
+ return RPC_PORT_ERROR_NONE;
+ }
+
+ ret = rpc_port_disconnect(h->port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to disconnect from stub. error(%d)", ret);
+ return ret;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_PARAMS> The parameters of the method of the interface
+ * <METHOD_PARAMS_CHECK> The parameters check of the method.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ * <METHOD_UNIT_MAP_WRITE> The implementation to write arguments to the unit map.
+ * <METHOD_DELEGATES_APPEND> The implementation to add the delegates to the list.
+ */
+constexpr const char CB_INTERFACE_METHOD_ASYNC_BASE[] =
+R"__c_cb(
+void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
+{
+ rpc_port_parcel_h parcel_;
+ rpc_port_parcel_header_h header_;
+ rpc_port_unit_map_h map_;
+ int seq_num_ = -1;
+ int res_;
+
+ if (h == nullptr<METHOD_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ if (h->port == nullptr && !rpc_port_proxy_lem_is_connected(h->lem)) {
+ _E("Not connected");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ res_ = rpc_port_parcel_create(&parcel_);
+ if (res_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", res_);
+ set_last_result(res_);
+ return;
+ }
+
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+
+ map_ = rpc_port_unit_map_create();
+ if (map_ == nullptr) {
+ _E("Failed to create unit map");
+ rpc_port_parcel_destroy(parcel_);
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_unit_map_write_int(map_, "[METHOD]", <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
+
+ <METHOD_UNIT_MAP_WRITE>
+ <METHOD_DELEGATE_APPEND>
+
+ rpc_port_parcel_write(parcel_, &map_->parcelable, map_);
+ rpc_port_unit_map_destroy(map_);
+
+ g_rec_mutex_lock(&h->mutex);
+ if (rpc_port_proxy_lem_is_connected(h->lem))
+ res_ = rpc_port_proxy_lem_send(h->lem, parcel_, nullptr);
+ else
+ res_ = rpc_port_parcel_send(parcel_, h->port);
+
+ rpc_port_parcel_destroy(parcel_);
+ if (res_ != RPC_PORT_ERROR_NONE)
+ _E("Failed to send parcel. error(%d)", res_);
+
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(res_);
+}
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the method of the interface.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_ARGS> The value declarations for reading the data from the parcel.
+ * <ERROR_VALUE> The error value of the method.
+ * <METHOD_PARAMS> The parameters of the method of the interface.
+ * <METHOD_PARAMS_CHECK> The parameters check of the method.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ * <METHOD_UNIT_MAP_WRITE> The implementation to write arguments to the unit map.
+ * <METHOD_UNIT_MAP_READ> The implementation to read results from the unit map.
+ * <METHOD_DELEGATE_APPEND> The implementation to add the delegates to the list.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE[] =
+R"__c_cb(
+<RETURN_TYPE><PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
+{
+ rpc_port_parcel_h parcel_;
+ rpc_port_parcel_header_h header_;
+ rpc_port_unit_map_h map_;
+ int seq_num_ = -1;
+ int res_;
+ <RETURN_TYPE>ret_ = <ERROR_VALUE>;
+ <METHOD_ARGS>
+
+ if (h == nullptr<METHOD_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return ret_;
+ }
+
+ if (h->port == nullptr && !rpc_port_proxy_lem_is_connected(h->lem)) {
+ _E("Not connected");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return ret_;
+ }
+
+ res_ = rpc_port_parcel_create(&parcel_);
+ if (res_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", res_);
+ set_last_result(res_);
+ return ret_;
+ }
+
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+
+ map_ = rpc_port_unit_map_create();
+ if (map_ == nullptr) {
+ _E("Failed to create unit map");
+ rpc_port_parcel_destroy(parcel_);
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return ret_;
+ }
+
+ rpc_port_unit_map_write_int(map_, "[METHOD]", <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
+
+ <METHOD_UNIT_MAP_WRITE>
+ <METHOD_DELEGATE_APPEND>
+
+ rpc_port_parcel_write(parcel_, &map_->parcelable, map_);
+ rpc_port_unit_map_destroy(map_);
+
+
+ g_rec_mutex_lock(&h->mutex);
+ rpc_port_parcel_h result_parcel_ = nullptr;
+ if (rpc_port_proxy_lem_is_connected(h->lem))
+ res_ = rpc_port_proxy_lem_send(h->lem, parcel_, &result_parcel_);
+ else
+ res_ = rpc_port_parcel_send(parcel_, h->port);
+
+ rpc_port_parcel_destroy(parcel_);
+ if (res_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to send parcel. error(%d)", res_);
+ set_last_result(res_);
+ g_rec_mutex_unlock(&h->mutex);
+ return ret_;
+ }
+
+ do {
+ map_ = nullptr;
+ if (rpc_port_proxy_lem_is_connected(h->lem)) {
+ map_ = rpc_port_unit_map_create();
+ rpc_port_parcel_read(result_parcel_, &map_->parcelable, map_);
+ rpc_port_parcel_destroy(result_parcel_);
+ } else {
+ __<PREFIX>_<NAME>_consume_command(h->port, seq_num_, &map_);
+ }
+
+ if (map_ == nullptr) {
+ _E("Invalid protocol");
+ res_ = RPC_PORT_ERROR_IO_ERROR;
+ break;
+ }
+
+ <METHOD_UNIT_MAP_READ>
+ rpc_port_unit_map_destroy(map_);
+ } while (0);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(res_);
+
+ return ret_;
+}
+)__c_cb";
+
+/**
+ * <ARG_NAME> The name of the argument.
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG_NAME>", <ARG>);
+)__c_cb";
+
+/**
+ * <ARG_NAME> The name of the argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_DELEGATE_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_delegate(map_, "<ARG_NAME>", (rpc_port_delegate_h)<ARG>);
+)__c_cb";
+
+/**
+ * <ARG_NAME> The name of the argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_bundle(map_, "<ARG_NAME>", <ARG>);
+)__c_cb";
+
+/**
+ * <ARG_NAME> The name of the argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_string(map_, "<ARG_NAME>", <ARG>);
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG_NAME> The name of the argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG_NAME>", <ARG>);
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG_NAME> The name of the argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_int(map_, "<ARG_NAME>", (int)<ARG>);
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG_NAME> The argument name.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_READ[] =
+R"__c_cb(
+ rpc_port_unit_map_read_<TYPE_NAME>(map_, "<ARG_NAME>", &<ARG>);
+)__c_cb";
+
+/**
+ * <ARG_NAME> The argument name.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_bundle(map_, "<ARG_NAME>", &<ARG>);
+)__c_cb";
+
+/**
+ * <ARG_NAME> The argument name.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_string(map_, "<ARG_NAME>", &<ARG>);
+)__c_cb";
+
+/**
+ * <ARG_NAME> The argument name.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_EMUM_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_int(map_, "<ARG_NAME>", (int *)&<ARG>);
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG_NAME> The argument name.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_<TYPE_NAME>(map_, "<ARG_NAME>", &<ARG>);
+)__c_cb";
+
+/**
+ * <PARAM> The name of the parameter.
+ */
+constexpr const char CB_INTERFACE_METHOD_PARAM_SET[] =
+R"__c_cb(
+*<PARAM> = new_<PARAM>;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the reference argument.
+ * <NAME> The name of the reference argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_REF_FREE[] =
+R"__c_cb(
+<PREFIX>_<NAME>_destroy(*<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_REF_FREE[] =
+R"__c_cb(
+bundle_free(*<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_REF_FREE[] =
+R"__c_cb(
+free(*<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_DELEGATE_APPEND[] =
+R"__c_cb(
+h->delegates = g_list_append(h->delegates, <ARG>);
+)__c_cb";
+
+constexpr const char CB_LEM_PROXY_BASE_DEF[] =
+R"__c_cb(
+typedef int (*rpc_port_stub_lem_connect_func)(void *context, const char *appid, const char *instance, bool sync);
+typedef void (*rpc_port_stub_lem_disconnect_func)(void *context, const char *appid, const char *instance);
+typedef int (*rpc_port_stub_lem_send_func)(void *context, const char *appid, const char *instance, rpc_port_parcel_h h);
+
+typedef void (*rpc_port_proxy_lem_connected_cb)(void *context);
+typedef void (*rpc_port_proxy_lem_disconnected_cb)(void* context);
+typedef void (*rpc_port_proxy_lem_received_cb)(void* context, rpc_port_parcel_h);
+
+typedef struct {
+ rpc_port_proxy_lem_connected_cb connected;
+ rpc_port_proxy_lem_disconnected_cb disconnected;
+ rpc_port_proxy_lem_received_cb received;
+} rpc_port_proxy_lem_event_s;
+
+typedef struct {
+ void *context;
+ rpc_port_proxy_lem_event_s callback;
+ char *port_name;
+ char *instance;
+ rpc_port_stub_lem_connect_func connect_func;
+ rpc_port_stub_lem_disconnect_func disconnect_func;
+ rpc_port_stub_lem_send_func send_func;
+ bool connected;
+ bool connecting;
+ bool loaded;
+ GQueue *result_queue;
+ GQueue *request_queue;
+ GRecMutex mutex;
+} rpc_port_proxy_lem_s;
+
+typedef rpc_port_proxy_lem_s *rpc_port_proxy_lem_h;
+)__c_cb";
+
+/**
+ * <INPUT_FILE> The input file name.
+ */
+constexpr const char CB_LEM_PROXY_BASE[] =
+R"__c_cb(
+static const char *__get_appid(void)
+{
+ static char *appid;
+
+ if (getuid() < 5000)
+ return appid;
+
+ if (appid == nullptr) {
+ app_get_id(&appid);
+ if (appid == nullptr)
+ _E("Failed to get appid");
+ }
+
+ return appid;
+}
+
+static rpc_port_parcel_h __rpc_port_parcel_clone(rpc_port_parcel_h parcel)
+{
+ rpc_port_parcel_h handle = nullptr;
+ void* raw = nullptr;
+ unsigned int size = 0;
+
+ if (rpc_port_parcel_get_raw(parcel, &raw, &size) != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get raw");
+ return nullptr;
+ }
+
+ rpc_port_parcel_create_from_raw(&handle, raw, size);
+ return handle;
+}
+
+static void rpc_port_proxy_lem_destroy(rpc_port_proxy_lem_h handle)
+{
+ if (handle == nullptr)
+ return;
+
+ if (g_rec_mutex_trylock(&(handle->mutex)))
+ g_rec_mutex_unlock(&handle->mutex);
+
+ g_rec_mutex_clear(&handle->mutex);
+
+ if (handle->request_queue)
+ g_queue_free_full(handle->request_queue, (GDestroyNotify)rpc_port_parcel_destroy);
+
+ if (handle->result_queue)
+ g_queue_free_full(handle->result_queue, (GDestroyNotify)rpc_port_parcel_destroy);
+
+ if (handle->instance)
+ free(handle->instance);
+
+ if (handle->port_name)
+ free(handle->port_name);
+
+ free(handle);
+}
+
+static rpc_port_proxy_lem_h rpc_port_proxy_lem_create(void *context, const char *port_name, rpc_port_proxy_lem_event_s* callback)
+{
+ static gint seq;
+ rpc_port_proxy_lem_h handle;
+ char buf[512] = { 0, };
+
+ if (context == nullptr || port_name == nullptr || callback == nullptr) {
+ _E("Invalid parameter");
+ return nullptr;
+ }
+
+ handle = calloc(1, sizeof(rpc_port_proxy_lem_s));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return nullptr;
+ }
+
+ g_rec_mutex_init(&handle->mutex);
+ handle->context = context;
+ handle->callback = *callback;
+ handle->port_name = strdup(port_name);
+ if (handle->port_name == nullptr) {
+ _E("Failed to duplicate port name(%s)", port_name);
+ rpc_port_proxy_lem_destroy(handle);
+ return nullptr;
+ }
+
+ g_atomic_int_inc(&seq);
+ snprintf(buf, sizeof(buf), "%s::%d", __get_appid(), g_atomic_int_get(&seq));
+ handle->instance = strdup(buf);
+ if (handle->instance == nullptr) {
+ _E("Failed to duplicate instance(%s)", buf);
+ rpc_port_proxy_lem_destroy(handle);
+ return nullptr;
+ }
+
+ handle->result_queue = g_queue_new();
+ if (handle->result_queue == nullptr) {
+ _E("g_queue_new() is failed");
+ rpc_port_proxy_lem_destroy(handle);
+ return nullptr;
+ }
+
+ handle->request_queue = g_queue_new();
+ if (handle->request_queue == nullptr) {
+ _E("g_queue_new() is failed");
+ rpc_port_proxy_lem_destroy(handle);
+ return nullptr;
+ }
+
+ return handle;
+}
+
+static void rpc_port_proxy_lem_result_queue_push(rpc_port_proxy_lem_h handle, rpc_port_parcel_h parcel)
+{
+ if (handle == nullptr || parcel == nullptr)
+ return;
+
+ g_rec_mutex_lock(&handle->mutex);
+ g_queue_push_tail(handle->result_queue, parcel);
+ g_rec_mutex_unlock(&handle->mutex);
+}
+
+static rpc_port_parcel_h rpc_port_proxy_lem_result_queue_pop(rpc_port_proxy_lem_h handle)
+{
+ rpc_port_parcel_h parcel;
+
+ if (handle == nullptr)
+ return nullptr;
+
+ g_rec_mutex_lock(&handle->mutex);
+ parcel = (rpc_port_parcel_h)g_queue_pop_head(handle->result_queue);
+ g_rec_mutex_unlock(&handle->mutex);
+
+ return parcel;
+}
+
+static bool rpc_port_proxy_lem_result_queue_empty(rpc_port_proxy_lem_h handle)
+{
+ bool empty;
+
+ if (handle == nullptr)
+ return true;
+
+ g_rec_mutex_lock(&handle->mutex);
+ empty = g_queue_is_empty(handle->result_queue);
+ g_rec_mutex_unlock(&handle->mutex);
+ return empty;
+}
+
+static void rpc_port_proxy_lem_request_queue_push(rpc_port_proxy_lem_h handle, rpc_port_parcel_h parcel)
+{
+ if (handle == nullptr || parcel == nullptr)
+ return;
+
+ g_rec_mutex_lock(&handle->mutex);
+ g_queue_push_tail(handle->request_queue, parcel);
+ g_rec_mutex_unlock(&handle->mutex);
+}
+
+static rpc_port_parcel_h rpc_port_proxy_lem_request_queue_pop(rpc_port_proxy_lem_h handle)
+{
+ rpc_port_parcel_h parcel;
+
+ if (handle == nullptr)
+ return nullptr;
+
+ g_rec_mutex_lock(&handle->mutex);
+ parcel = (rpc_port_parcel_h)g_queue_pop_head(handle->request_queue);
+ g_rec_mutex_unlock(&handle->mutex);
+
+ return parcel;
+}
+
+static int rpc_port_proxy_lem_connect(rpc_port_proxy_lem_h handle, bool sync)
+{
+ int ret = RPC_PORT_ERROR_NONE;
+
+ if (handle == nullptr)
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+ g_rec_mutex_lock(&handle->mutex);
+ if (handle->connecting) {
+ _E("Already connecting");
+ g_rec_mutex_unlock(&handle->mutex);
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (handle->connected) {
+ _E("Already connected");
+ g_rec_mutex_unlock(&handle->mutex);
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (handle->connect_func)
+ ret = handle->connect_func(handle, __get_appid(), handle->instance, sync);
+
+ handle->connecting = true;
+ g_rec_mutex_unlock(&handle->mutex);
+ return ret;
+}
+
+static void rpc_port_proxy_lem_disconnect(rpc_port_proxy_lem_h handle)
+{
+ if (handle == nullptr)
+ return;
+
+ g_rec_mutex_lock(&handle->mutex);
+ handle->connecting = false;
+ if (handle->disconnect_func)
+ handle->disconnect_func(handle, __get_appid(), handle->instance);
+
+ g_rec_mutex_unlock(&handle->mutex);
+}
+
+static int rpc_port_proxy_lem_send(rpc_port_proxy_lem_h handle, rpc_port_parcel_h request, rpc_port_parcel_h* result)
+{
+ int ret;
+ int count = 0;
+
+ if (handle == nullptr || request == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (handle->send_func) {
+ ret = handle->send_func(handle, __get_appid(), handle->instance, request);
+ if (result != nullptr) {
+ while (rpc_port_proxy_lem_result_queue_empty(handle) && count++ < 100)
+ usleep(100 * 1000);
+
+ if (rpc_port_proxy_lem_result_queue_empty(handle)) {
+ _E("Failed to get result from server");
+ return RPC_PORT_ERROR_IO_ERROR;
+ }
+
+ *result = rpc_port_proxy_lem_result_queue_pop(handle);
+ }
+
+ return ret;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+static bool rpc_port_proxy_lem_is_connected(rpc_port_proxy_lem_h handle)
+{
+ bool ret;
+
+ if (handle == nullptr)
+ return false;
+
+ g_rec_mutex_lock(&handle->mutex);
+ ret = handle->connected;
+ g_rec_mutex_unlock(&handle->mutex);
+
+ return ret;
+}
+
+static bool rpc_port_proxy_lem_load_symbols(rpc_port_proxy_lem_h handle)
+{
+ char symbol[1024];
+
+ if (handle == nullptr)
+ return false;
+
+ if (handle->loaded)
+ return true;
+
+ if (handle->connect_func == nullptr) {
+ snprintf(symbol, sizeof(symbol), "rpc_port_stub_<INPUT_FILE>_lem_%s_connect", handle->port_name);
+ handle->connect_func = (rpc_port_stub_lem_connect_func)dlsym(RTLD_DEFAULT, symbol);
+ if (handle->connect_func == nullptr) {
+ _E("Failed to find symbol(%s)", symbol);
+ return false;
+ }
+ }
+
+ if (handle->disconnect_func == nullptr) {
+ snprintf(symbol, sizeof(symbol), "rpc_port_stub_<INPUT_FILE>_lem_%s_disconnect", handle->port_name);
+ handle->disconnect_func = (rpc_port_stub_lem_disconnect_func)dlsym(RTLD_DEFAULT, symbol);
+ if (handle->disconnect_func == nullptr) {
+ _E("Failed to find symbol(%s)", symbol);
+ return false;
+ }
+ }
+
+ if (handle->send_func == nullptr) {
+ snprintf(symbol, sizeof(symbol), "rpc_port_stub_<INPUT_FILE>_lem_%s_send", handle->port_name);
+ handle->send_func = (rpc_port_stub_lem_send_func)dlsym(RTLD_DEFAULT, symbol);
+ if (handle->send_func == nullptr) {
+ _E("Failed to find symbol(%s)", symbol);
+ return false;
+ }
+ }
+
+ handle->loaded = true;
+ return true;
+}
+
+static gboolean rpc_port_proxy_lem_on_connected(gpointer user_data)
+{
+ rpc_port_proxy_lem_h handle = user_data;
+
+ if (handle == nullptr)
+ return G_SOURCE_REMOVE;
+
+ g_rec_mutex_lock(&handle->mutex);
+ handle->connecting = false;
+ handle->connected = true;
+ if (handle->callback.connected)
+ handle->callback.connected(handle->context);
+
+ g_rec_mutex_unlock(&handle->mutex);
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean rpc_port_proxy_lem_on_disconnected(gpointer user_data)
+{
+ rpc_port_proxy_lem_h handle = user_data;
+
+ if (handle == nullptr)
+ return G_SOURCE_REMOVE;
+
+ g_rec_mutex_lock(&handle->mutex);
+ handle->connecting = false;
+ handle->connected = false;
+ if (handle->callback.disconnected)
+ handle->callback.disconnected(handle->context);
+
+ g_rec_mutex_unlock(&handle->mutex);
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean rpc_port_proxy_lem_on_received(gpointer user_data)
+{
+ rpc_port_proxy_lem_h handle = user_data;
+ rpc_port_parcel_h request;
+
+ if (handle == nullptr)
+ return G_SOURCE_REMOVE;
+
+ request = rpc_port_proxy_lem_request_queue_pop(handle);
+ if (handle->callback.received)
+ handle->callback.received(handle->context, request);
+
+ rpc_port_parcel_destroy(request);
+ return G_SOURCE_REMOVE;
+}
+
+)__c_cb";
+
+/**
+ * <INPUT_FILE> The input file name.
+ * <IFACE_NAME> The interface name.
+ */
+constexpr const char CB_LEM_PROXY_API[] =
+R"__c_cb(
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<IFACE_NAME>_connect(void *h, bool sync)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (sync)
+ rpc_port_proxy_lem_on_connected(h);
+ else
+ g_idle_add(rpc_port_proxy_lem_on_connected, h);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<IFACE_NAME>_disconnect(void* h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_idle_add(rpc_port_proxy_lem_on_disconnected, h);
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<IFACE_NAME>_invoke_callback(void* h, rpc_port_parcel_h parcel)
+{
+ rpc_port_proxy_lem_h handle = h;
+ rpc_port_parcel_h cloned_parcel;
+
+ if (h == nullptr || parcel == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ cloned_parcel = __rpc_port_parcel_clone(parcel);
+ rpc_port_proxy_lem_request_queue_push(handle, cloned_parcel);
+ g_idle_add(rpc_port_proxy_lem_on_received, h);
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<IFACE_NAME>_send_result(void* h, rpc_port_parcel_h parcel)
+{
+ rpc_port_proxy_lem_h handle = h;
+ rpc_port_parcel_h cloned_parcel;
+
+ if (h == nullptr || parcel == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ cloned_parcel = __rpc_port_parcel_clone(parcel);
+ rpc_port_proxy_lem_result_queue_push(handle, cloned_parcel);
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_PROXY_BODY_GENERATOR_CB_HH_
diff --git a/idlc/gen/version2/c_proxy_header_generator.cc b/idlc/gen/version2/c_proxy_header_generator.cc
new file mode 100644
index 0000000..e188e79
--- /dev/null
+++ b/idlc/gen/version2/c_proxy_header_generator.cc
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/c_proxy_header_generator.hh"
+
+#include "idlc/gen/version2/c_proxy_header_generator_cb.hh"
+
+namespace tidl {
+namespace version2 {
+
+CProxyHeaderGenerator::CProxyHeaderGenerator(std::shared_ptr<Document> doc)
+ : CHeaderGeneratorBase(doc) {
+}
+
+void CProxyHeaderGenerator::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenPragmaOnce(stream);
+ GenIncludeDefaultHeaders(stream, false);
+ GenExplicitLinkageOpen(stream);
+ GenEnums(stream);
+ GenStructureHandles(stream);
+ GenRemoteExceptionHandle(stream);
+ GenInterfaceHandles(stream);
+ GenStructures(stream);
+ GenRemoteException(stream);
+ GenInterfaces(stream);
+}
+
+void CProxyHeaderGenerator::OnFiniGen(std::ofstream& stream) {
+ GenExplicitLinkageClose(stream);
+}
+
+void CProxyHeaderGenerator::GenInterfaceHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceHandle(stream, iface);
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateHandle(stream, iface, *d);
+ }
+ }
+}
+
+void CProxyHeaderGenerator::GenInterfaceHandle(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_HANDLE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CProxyHeaderGenerator::GenInterfaceDelegateHandle(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_DELEGATE_HANDLE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<DELEGATE_NAME>", decl.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CProxyHeaderGenerator::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CProxyHeaderGenerator::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateBase(stream, iface, *d);
+ }
+
+ GenInterfaceBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceMethodBase(stream, iface, *d);
+ }
+}
+
+void CProxyHeaderGenerator::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+std::string CProxyHeaderGenerator::GenDelegateParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+void CProxyHeaderGenerator::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_DELEGATE_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<DELEGATE_NAME>", decl.GetID())
+ .Change("<DELEGATE_PARAMS>", GenDelegateParams(iface, decl))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+std::string CProxyHeaderGenerator::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+void CProxyHeaderGenerator::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_BASE)
+ .Change("<RETURN_TYPE>",
+ GetReturnTypeString(decl.GetType(), iface.GetID()))
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<METHOD_NAME>", decl.GetID())
+ .Change("<METHOD_PARAMS>", GenMethodParams(iface, decl))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/c_proxy_header_generator.hh b/idlc/gen/version2/c_proxy_header_generator.hh
new file mode 100644
index 0000000..468eed6
--- /dev/null
+++ b/idlc/gen/version2/c_proxy_header_generator.hh
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_PROXY_HEADER_GENERATOR_HH_
+#define IDLC_GEN_VERSION2_C_PROXY_HEADER_GENERATOR_HH_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/version2/c_header_generator_base.hh"
+
+namespace tidl {
+namespace version2 {
+
+class CProxyHeaderGenerator : public CHeaderGeneratorBase {
+ public:
+ explicit CProxyHeaderGenerator(std::shared_ptr<Document> doc);
+ virtual ~CProxyHeaderGenerator() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenInterfaceHandles(std::ofstream& stream);
+ void GenInterfaceHandle(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateHandle(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& ifaceo,
+ const Declaration& decl);
+ std::string GenDelegateParams(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_PROXY_HEADER_GENERATOR_HH_
diff --git a/idlc/gen/version2/c_proxy_header_generator_cb.hh b/idlc/gen/version2/c_proxy_header_generator_cb.hh
new file mode 100644
index 0000000..a7e66ea
--- /dev/null
+++ b/idlc/gen/version2/c_proxy_header_generator_cb.hh
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_PROXY_HEADER_GENERATOR_CB_HH_
+#define IDLC_GEN_VERSION2_C_PROXY_HEADER_GENERATOR_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_HANDLE[] =
+R"__c_cb(
+/**
+ * @brief The <PREFIX>_<NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_s *<PREFIX>_<NAME>_h;
+)__c_cb";
+
+constexpr const char CB_INTERFACE_DELEGATE_HANDLE[] =
+R"__c_cb(
+/**
+ * @brief The <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s *<PREFIX>_<NAME>_<DELEGATE_NAME>_h;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate.
+ * <DELEGATE_PARAMS> The parameters of the callback function.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
+R"__c_cb(
+/**
+ * @brief Called when the event is received.
+ *
+ * @param[in] user_data The user data passed from the callback registration function
+ * @param[in] ...
+ *
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_create()
+ */
+typedef void (*<PREFIX>_<NAME>_<DELEGATE_NAME>_cb)(void *user_data<DELEGATE_PARAMS>);
+
+/**
+ * @brief Creates a <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[out] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memorya
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose()
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_set_callback()
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_set_once()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_create()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME>_<DELEGATE_NAME> should be released using
+ * the <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME>_<DELEGATE_NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone);
+
+/**
+ * @brief Sets the callback function to the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[in] callback The callback function
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_callback(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback, void *user_data);
+
+/**
+ * @brief Set the once flag to the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ * @details If the once flag is 'true', the delegate handle will be deleted after invocation.
+ * If the @a h handle is not used using the method, the handle should be released using
+ * the <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy() when it's no longer needed.
+ * If you don't want the delegate callback function to be called after it's used using the method,
+ * you should release the handle using the <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose().
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[in] once The flag if it's true, the delegate will be deleted after invocation
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool once);
+
+/**
+ * @brief Gets the ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] id The ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id);
+
+/**
+ * @brief Gets the sequence ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] seq_id The Sequence ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id);
+
+/**
+ * @brief Checks whether the delegate is for one-time or not.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] once The flag, it's true, the handle is for one-time
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once);
+
+/**
+ * @brief Gets the tag from the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks The @a tag should be released using free().
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] tag The tag
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag);
+
+/**
+ * @brief Disposes the <PREFIX>_<NAME>_<DELEGATE_NAME> handle from the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] proxy The <PREFIX>_<NAME> handle
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_create()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose(<PREFIX>_<NAME>_h proxy, <PREFIX>_<NAME>_<DELEGATE_NAME>_h h);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+/**
+ * @brief Called when the proxy is connected.
+ * @details The callback function is called when the proxy is connected to the stub.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] user_data The user data passed from the registeration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_connected_cb)(<PREFIX>_<NAME>_h h, void *user_data);
+
+/**
+ * @brief Called when the proxy is disconnected.
+ * @details The callback function is called when the proxy is disconnected from the stub.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] user_data The user data passed from the registeration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_disconnected_cb)(<PREFIX>_<NAME>_h h, void *user_data);
+
+/**
+ * @brief Called when the proxy is rejected.
+ * @details The callback function is called when the proxy is rejected to connect to the stub.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] user_data The user data passed from the registeration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_rejected_cb)(<PREFIX>_<NAME>_h h, void *user_data);
+
+/**
+ * @brief The structure type containing the set of callback functions for handling proxy events.
+ * @details It is one of the input parameters of the <PREFIX>_<NAME>_create() function.
+ *
+ * @see <PREFIX>_<NAME>_connected_cb
+ * @see <PREFIX>_<NAME>_disconnected_cb
+ * @see <PREFIX>_<NAME>_rejected_cb
+ */
+typedef struct {
+ <PREFIX>_<NAME>_connected_cb connected; /**< This callback function is called when the proxy is connected to the stub. */
+ <PREFIX>_<NAME>_disconnected_cb disconnected; /**< This callback function is called when the proxy is disconnected from the stub. */
+ <PREFIX>_<NAME>_rejected_cb rejected; /**< This callback function is called when the proxy is rejected to connect to the stub. */
+} <PREFIX>_<NAME>_callback_s;
+
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ * @remarks The @a h handle should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ *
+ * @param[in] stub_appid The application ID of the stub
+ * @param[in] callback The set of callback functions to handle proxy events
+ * @param[in] user_data The user data to be passed to the callback function
+ * @param[out] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+int <PREFIX>_<NAME>_create(const char *stub_appid, <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Connects to the stub.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_IO_ERROR I/O error
+ * @retval #RPC_PORT_ERROR_PERMISSION_DENIED Permission denied
+ */
+int <PREFIX>_<NAME>_connect(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Connects to the stub synchronously.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_IO_ERROR I/O error
+ * @retval #RPC_PORT_ERROR_PERMISSION_DENIED Permission denied
+ */
+int <PREFIX>_<NAME>_connect_sync(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Disconnects from the stub.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_disconnect(<PREFIX>_<NAME>_h h);
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The type of the return value.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The of the interface.
+ * <METHOD_NAME> The name of the method.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE[] =
+R"__c_cb(
+/**
+ * @brief Calls the <METHOD_NAME>() method.
+ * @details The return value and args are decided by the interface declaration.
+ * You can get the result using get_last_result().
+ * Before returning the function, the function sets the result using set_last_result().
+ * @remarks The specific error code can be obtained using the get_last_result() function. Error codes are described in Exception section.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] ...
+ * @exception #RPC_PORT_ERROR_NONE Successful
+ * @exception #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @exception #RPC_PORT_ERROR_IO_ERROR I/O error
+ */
+<RETURN_TYPE><PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>);
+)__c_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_PROXY_HEADER_GENERATOR_CB_HH_
diff --git a/idlc/gen/version2/c_stub_body_generator.cc b/idlc/gen/version2/c_stub_body_generator.cc
new file mode 100644
index 0000000..4cb231c
--- /dev/null
+++ b/idlc/gen/version2/c_stub_body_generator.cc
@@ -0,0 +1,800 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/c_stub_body_generator.hh"
+
+#include <libgen.h>
+
+#include <algorithm>
+
+#include "idlc/gen/version2/c_stub_body_generator_cb.hh"
+
+namespace tidl {
+namespace version2 {
+
+CStubBodyGenerator::CStubBodyGenerator(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options)
+ : CBodyGeneratorBase(doc), options_(options) {
+}
+
+void CStubBodyGenerator::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenGNUSourceDefinition(stream);
+ GenIncludeDefaultHeaders(stream);
+ GenIncludePrivateHeaders(stream);
+ GenIncludeLemHeaders(stream);
+ GenIncludeHeader(stream);
+ GenLogTag(stream, std::string("RPC_PORT_STUB"));
+ GenLogDefinition(stream);
+ GenVersionDefinition(stream);
+ GenBaseDefinition(stream);
+ GenThreadEnableDefinition(stream);
+ GenInterfaceEnums(stream);
+ GenUnitMapDefinition(stream);
+ GenLemDefinition(stream);
+ GenInterfaceMethodHandlerType(stream);
+ GenDelegateDefinition(stream);
+ GenStructureDefinition(stream);
+ GenRemoteExceptionDefinition(stream);
+ GenInterfaceDefs(stream);
+ GenLemBase(stream);
+ GenPrivateSharingListSet(stream);
+ GenUnitMapBase(stream);
+ GenDelegateBase(stream);
+ GenStructure(stream);
+ GenRemoteExceptionBase(stream);
+ GenInterfaces(stream);
+ GenLemAPI(stream);
+}
+
+void CStubBodyGenerator::OnFiniGen(std::ofstream& stream) {}
+
+std::string CStubBodyGenerator::GenLemContext() {
+ std::string code;
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ code += ReplaceAll(CB_LEM_CONTEXT)
+ .Change("<IFACE_NAME>", iface.GetID());
+ }
+
+ return RemoveLine(code);
+}
+
+void CStubBodyGenerator::GenLemDefinition(std::ofstream& stream) {
+ ReplaceAll(CB_LEM_BASE_DEF)
+ .Change("<LEM_CONTEXT>", GenLemContext())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CStubBodyGenerator::GenLemBase(std::ofstream& stream) {
+ std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
+ input = input.substr(0, input.find_last_of("."));
+ ReplaceAll(CB_LEM_BASE)
+ .Change("<INPUT_FILE>", input)
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CStubBodyGenerator::GenLemAPI(std::ofstream& stream) {
+ std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
+ input = input.substr(0, input.find_last_of("."));
+ std::string code;
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ code += ReplaceAll(CB_LEM_API)
+ .Change("<IFACE_NAME>", iface.GetID())
+ .Change("<INPUT_FILE>", input);
+ }
+
+ stream << SmartIndent(code);
+}
+
+void CStubBodyGenerator::GenIncludePrivateHeaders(std::ofstream& stream) {
+ stream << CB_PRIVATE_HEADERS;
+}
+
+void CStubBodyGenerator::GenDelegateDefinition(std::ofstream& stream) {
+ if (HasDelegate())
+ stream << SmartIndent(CB_DELEGATE_DEFS);
+}
+
+void CStubBodyGenerator::GenDelegateBase(std::ofstream& stream) {
+ if (HasDelegate())
+ stream << SmartIndent(CB_DELEGATE_BASE);
+}
+
+// @see #CB_THREAD_ENABLE_DEF
+void CStubBodyGenerator::GenThreadEnableDefinition(std::ofstream& stream) {
+ if (!options_->IsThreadEnabled())
+ return;
+
+ stream << std::string(CB_THREAD_ENABLE_DEF);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_TYPE
+void CStubBodyGenerator::GenInterfaceMethodHandlerType(std::ofstream& stream) {
+ stream << SmartIndent(CB_INTERFACE_METHOD_HANDLER_TYPE);
+}
+
+void CStubBodyGenerator::GenInterfaceEnums(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceEnum(stream, iface);
+ }
+}
+
+void CStubBodyGenerator::GenInterfaceEnum(std::ofstream& stream,
+ const Interface& iface) {
+ GenInterfaceMethodEnumBase(stream, iface);
+ if (HasDelegate())
+ GenInterfaceDelegateEnumBase(stream, iface);
+}
+
+// @see #CB_INTERFACE_METHOD_ENUM
+std::string CStubBodyGenerator::GenMethodEnums(const Interface& iface) {
+ std::string method_enums;
+ method_enums += RemoveLine(
+ std::string(ReplaceAll(CB_INTERFACE_METHOD_ENUM)
+ .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
+ .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
+ .ChangeToUpper("<UPPERCASE_METHOD_NAME>", "RESULT_")));
+ method_enums += RemoveLine(
+ std::string(ReplaceAll(CB_INTERFACE_METHOD_ENUM)
+ .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
+ .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
+ .ChangeToUpper("<UPPERCASE_METHOD_NAME>", "CALLBACK_")));
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ method_enums += RemoveLine(
+ std::string(ReplaceAll(CB_INTERFACE_METHOD_ENUM)
+ .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
+ .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
+ .ChangeToUpper("<UPPERCASE_METHOD_NAME>", d->GetID())));
+ }
+
+ return method_enums;
+}
+
+// @see #CB_INTERFACE_METHOD_ENUM_BASE
+void CStubBodyGenerator::GenInterfaceMethodEnumBase(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<METHOD_ENUMS>", GenMethodEnums(iface))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_DELEGATE_ENUM
+std::string CStubBodyGenerator::GenDelegateEnums(const Interface& iface) {
+ unsigned int num = 1;
+ std::string method_enums;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ method_enums += RemoveLine(
+ std::string(ReplaceAll(CB_INTERFACE_DELEGATE_ENUM)
+ .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
+ .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
+ .ChangeToUpper("<UPPERCASE_DELEGATE_NAME>", d->GetID())
+ .ChangeToUpper("<NUMBER>", std::to_string(num++))));
+ }
+
+ return method_enums;
+}
+
+// @see #CB_INTERFACE_DELEGATE_ENUM_BASE
+void CStubBodyGenerator::GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string delegate_enums = GenDelegateEnums(iface);
+ if (delegate_enums.empty())
+ return;
+
+ ReplaceAll(CB_INTERFACE_DELEGATE_ENUM_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<DELEGATE_ENUMS>", delegate_enums)
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CStubBodyGenerator::GenInterfaceDefs(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceDef(stream, iface);
+ }
+}
+
+void CStubBodyGenerator::GenInterfaceDef(std::ofstream& stream,
+ const Interface& iface) {
+ bool has_delegate = false;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateDef(stream, iface, *d);
+ has_delegate = true;
+ }
+
+ if (has_delegate)
+ GenInterfaceCallbackPortCheckDef(stream, iface);
+
+ GenInterfaceContextDef(stream, iface);
+ GenInterfaceBaseDef(stream, iface);
+}
+
+// @see #CB_INTERFACE_DELEGATE_DEF
+void CStubBodyGenerator::GenInterfaceDelegateDef(std::ofstream& stream,
+ const Interface& iface,
+ const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_DELEGATE_DEF)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<DELEGATE_NAME>", decl.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_CALLBACK_PORT_CHECK_DEF
+void CStubBodyGenerator::GenInterfaceCallbackPortCheckDef(
+ std::ofstream& stream, const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_CALLBACK_PORT_CHECK_DEF)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_CONTEXT_DEF
+void CStubBodyGenerator::GenInterfaceContextDef(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_CONTEXT_DEF)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+
+// @see #CB_INTERFACE_BASE_DEF
+void CStubBodyGenerator::GenInterfaceBaseDef(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_BASE_DEF)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CStubBodyGenerator::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CStubBodyGenerator::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ bool has_delegate = false;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateBase(stream, iface, *d);
+ has_delegate = true;
+ }
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceMethodPrivilegeCheckerBase(stream, iface, *d);
+ GenInterfaceMethodHandlerBase(stream, iface, *d);
+ }
+
+ GenInterfaceMethodPrivilegeCheckerTable(stream, iface);
+ GenInterfaceMethodTable(stream, iface);
+ GenInterfaceContextBase(stream, iface);
+
+ if (has_delegate)
+ GenInterfaceCallbackPortCheck(stream, iface);
+
+ GenInterfaceBase(stream, iface);
+}
+
+// @see #CB_INTERFACE_CONTEXT_BASE
+void CStubBodyGenerator::GenInterfaceContextBase(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_CONTEXT_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
+ .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+std::string CStubBodyGenerator::GenDelegateParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+std::string CStubBodyGenerator::GenDelegateParamsCheck(const Interface& iface,
+ const Declaration& decl) {
+ std::string params_check;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetUserDefinedType() == BaseType::UserType::DELEGATE ||
+ type.ToString() == "list" ||
+ type.ToString() == "array" ||
+ type.ToString() == "bundle" ||
+ type.ToString() == "string" ||
+ type.ToString() == "file")
+ params_check += " || " + p->GetID() + " == nullptr";
+ }
+
+ return params_check;
+}
+
+// @see #CB_INTERFACE_DELEGATE_BASE
+void CStubBodyGenerator::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_DELEGATE_" + decl.GetID();
+ ReplaceAll(CB_INTERFACE_DELEGATE_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<DELEGATE_NAME>", decl.GetID())
+ .Change("<DELEGATE_PARAMS>", GenDelegateParams(iface, decl))
+ .Change("<DELEGATE_PARAMS_CHECK>", GenDelegateParamsCheck(iface, decl))
+ .ChangeToUpper("<DELEGATE_ENUM_VALUE>", enum_value)
+ .Change("<DELEGATE_UNIT_MAP_WRITE>", GenDelegateUnitMapWrite(iface, decl))
+ .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
+ .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+std::string CStubBodyGenerator::GenMethodHandlerArgsDecl(
+ const Interface& iface, const Declaration& decl) {
+ std::string args_decl;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.IsEnumType()) {
+ args_decl += GetArgTypeString(type, iface) + p->GetID() + ";" + NLine(1);
+ } else {
+ args_decl += GetArgTypeString(type, iface) + p->GetID() + " = " +
+ GetErrorValue(type) + ";" + NLine(1);
+ }
+ }
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
+ args_decl += "rpc_port_parcel_h parcel_;" + NLine(1);
+ args_decl += "rpc_port_unit_map_h map_;" + NLine(1);
+ args_decl += GetArgTypeString(decl.GetType(), iface) +
+ "res_ = " + GetErrorValue(decl.GetType()) + ";" + NLine(1);
+ }
+
+ return args_decl;
+}
+
+// @see #CB_INTERFACE_METHOD_DELEGATE_UNIT_MAP_READ
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_READ
+// @see #CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_READ
+// @see #CB_INTERFACE_METHOD_STRING_UNIT_MAP_READ
+// @see #CB_INTERFACE_METHOD_BASE_UNIT_MAP_READ
+std::string CStubBodyGenerator::GenMethodUnitMapRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ std::string parcel_read_code;
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() == ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.GetUserDefinedType() == BaseType::UserType::DELEGATE) {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_DELEGATE_UNIT_MAP_READ)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG_NAME>", std::string("delegate"))
+ .Change("<ARG>", p->GetID());
+ } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ code += ReplaceAll(CB_INTERFACE_METHOD_EMUM_UNIT_MAP_READ)
+ .Change("<ARG_NAME>", p->GetID())
+ .Change("<ARG>", p->GetID());
+ } else if (type.GetUserDefinedType() == BaseType::UserType::STRUCTURE ||
+ type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ parcel_read_code =
+ ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_READ)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG_NAME>", p->GetID())
+ .Change("<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_READ)
+ .Change("<ARG_NAME>", p->GetID())
+ .Change("<ARG>", p->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_READ)
+ .Change("<ARG_NAME>", p->GetID())
+ .Change("<ARG>", p->GetID());
+ } else {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_UNIT_MAP_READ)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG_NAME>", p->GetID())
+ .Change("<ARG>", p->GetID());
+ }
+
+ code += parcel_read_code;
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_INVOKE
+std::string CStubBodyGenerator::GenMethodHandlerCallbackInvoke(
+ const Interface& iface, const Declaration& decl) {
+ std::string args;
+ for (const auto& p : decl.GetParameters()) {
+ args += ", ";
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ args += "&";
+
+ args += p->GetID();
+ }
+
+ std::string res_set =
+ (decl.GetMethodType() == Declaration::MethodType::SYNC) ? "res_ = " : "";
+
+ return RemoveLine(std::string(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_INVOKE)
+ .Change("<METHOD_NAME>", decl.GetID())
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<RES_SET>", res_set)
+ .Change("<METHOD_ARGS>", args)));
+}
+
+std::string CStubBodyGenerator::GenDelegateUnitMapWrite(
+ const Interface& iface, const Declaration& decl) {
+ std::string parcel_write_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ parcel_write_code += GenMethodUnitMapWriteBase(
+ iface, param_type.GetBaseType(), p->GetID(), p->GetID());
+ }
+ return RemoveLine(parcel_write_code);
+}
+
+// @see #CB_INTERFACE_METHOD_DELEGATE_UNIT_MAP_WRITE
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_WRITE
+// @see #CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_WRITE
+// @see #CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE
+// @see #CB_INTERFACE_METHOD_BASE_UNIT_MAP_WRITE
+std::string CStubBodyGenerator::GenMethodUnitMapWriteBase(
+ const Interface& iface, const BaseType& type,
+ const std::string& arg_name, const std::string& arg) {
+ std::string parcel_write_code;
+
+ if (type.GetUserDefinedType() == BaseType::UserType::DELEGATE) {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_DELEGATE_UNIT_MAP_WRITE)
+ .Change("<ARG_NAME>", std::string("delegate"))
+ .Change("<ARG>", arg);
+ } else if (type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_ENUM_UNIT_MAP_WRITE)
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ } else if (type.IsUserDefinedType() ||
+ type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ parcel_write_code =
+ ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_WRITE)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ parcel_write_code += GetPrivateSharingString(type, iface, "port", arg);
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_WRITE)
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ } else if (type.ToString() == "string") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE)
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ } else if (type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE)
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ parcel_write_code += GetPrivateSharingString(type, iface, "port", arg_name);
+ } else {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_UNIT_MAP_WRITE)
+ .Change("<TYPE_NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG_NAME>", arg_name)
+ .Change("<ARG>", arg);
+ }
+
+ return parcel_write_code;
+}
+// @see #CB_INTERFACE_METHOD_PARCEL_WRITE_PRE
+// @see #CB_INTERFACE_METHOD_PARCEL_WRITE_POST
+std::string CStubBodyGenerator::GenMethodUnitMapWrite(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ if (decl.GetMethodType() != Declaration::MethodType::SYNC)
+ return code;
+
+ code = ReplaceAll(CB_INTERFACE_METHOD_PARCEL_WRITE_PRE)
+ .ChangeToUpper("<UPPERCASE_PREFIX>", GetHandlePrefix())
+ .ChangeToUpper("<UPPERCASE_NAME>", iface.GetID());
+
+ std::string parcel_write_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() == ParameterType::Direction::IN)
+ continue;
+
+ code += GenMethodUnitMapWriteBase(iface, param_type.GetBaseType(),
+ p->GetID(), p->GetID());
+ }
+
+ code += GenMethodUnitMapWriteBase(iface, decl.GetType(), "[RESULT]", "res_");
+
+ code += ReplaceAll(CB_INTERFACE_METHOD_PARCEL_WRITE_POST)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID());
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_FREE
+// @see #CB_INTERFACE_METHOD_BUNDLE_FREE
+// @see #CB_INTERFACE_METHOD_STRING_FREE
+std::string CStubBodyGenerator::GenMethodHandlerArgsFree(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.IsStructureType() || type.IsDelegateType() ||
+ type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
+ code += ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_FREE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ code += ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE)
+ .Change("<ARG>", p->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code += ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE)
+ .Change("<ARG>", p->GetID());
+ }
+ }
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
+ std::string arg = "res_";
+ auto& type = decl.GetType();
+ if (type.IsStructureType() || type.IsDelegateType() ||
+ type.GetMetaType() != nullptr || type.GetKeyType() != nullptr) {
+ code += ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_FREE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", GetFullNameFromType(type, iface))
+ .Change("<ARG>", arg);
+ } else if (type.ToString() == "bundle") {
+ code += ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE).Change("<ARG>", arg);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code += ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE).Change("<ARG>", arg);
+ }
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CStubBodyGenerator::GenPrivileges(const Declaration& decl) {
+ std::string code;
+ for (const auto& attr : decl.GetAttributes()) {
+ if (attr->GetKey() != "privilege")
+ continue;
+
+ code += "\"" + attr->GetValue() + "\"," + NLine(1);
+ }
+
+ return code;
+}
+
+// @see #CB_INTERFACE_METHOD_PRIVILEGE_CHECKER
+std::string CStubBodyGenerator::GenMethodPrivilegeChecker(
+ const Declaration& decl) {
+ auto privileges = GenPrivileges(decl);
+ if (privileges.empty())
+ return "return RPC_PORT_ERROR_NONE;" + NLine(1);
+
+ std::string sync =
+ (decl.GetMethodType() == Declaration::MethodType::SYNC) ?
+ "true" : "false";
+ return RemoveLine(
+ std::string(ReplaceAll(CB_INTERFACE_METHOD_PRIVILEGE_CHECKER)
+ .Change("<PRIVILEGES>", privileges)
+ .Change("<SYNC_TRUE_OR_FALSE>", sync)));
+}
+
+// @see #CB_INTERFACE_METHOD_PRIVILEGE_CHECKER_BASE
+void CStubBodyGenerator::GenInterfaceMethodPrivilegeCheckerBase(
+ std::ofstream& stream, const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_PRIVILEGE_CHECKER_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<METHOD_NAME>", decl.GetID())
+ .Change("<METHOD_PRIVILEGE_CHECKER>", GenMethodPrivilegeChecker(decl))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_BASE
+void CStubBodyGenerator::GenInterfaceMethodHandlerBase(
+ std::ofstream& stream, const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_HANDLER_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<METHOD_NAME>", decl.GetID())
+ .Change("<METHOD_HANDLER_ARGS_DECL>",
+ GenMethodHandlerArgsDecl(iface, decl))
+ .Change("<METHOD_UNIT_MAP_READ>", GenMethodUnitMapRead(iface, decl))
+ .Change("<METHOD_HANDLER_CALLBACK_INVOKE>",
+ GenMethodHandlerCallbackInvoke(iface, decl))
+ .Change("<METHOD_UNIT_MAP_WRITE>", GenMethodUnitMapWrite(iface, decl))
+ .Change("<METHOD_HANDLER_ARGS_FREE>",
+ GenMethodHandlerArgsFree(iface, decl))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+// @ see #CB_INTERFACE_PRIVILEGE_CHECKER
+std::string CStubBodyGenerator::GenPrivilegeCheckers(const Interface& iface) {
+ std::string code;
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_METHOD_" + decl->GetID();
+ code += ReplaceAll(CB_INTERFACE_PRIVILEGE_CHECKER)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<METHOD_NAME>", decl->GetID())
+ .ChangeToUpper("<ENUM_VALUE>", enum_value)
+ .Transform([&](std::string str) { return RemoveLine(str); });
+ }
+
+ return code;
+}
+
+// @see #CB_INTERFACE_METHOD_PRIVIELGE_CHECKER_TABLE
+void CStubBodyGenerator::GenInterfaceMethodPrivilegeCheckerTable(
+ std::ofstream& stream, const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_METHOD_PRIVIELGE_CHECKER_TABLE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<PRIVILEGE_CHECKERS>", GenPrivilegeCheckers(iface))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER
+std::string CStubBodyGenerator::GenMethodHandlers(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_METHOD_" + d->GetID();
+ code +=
+ RemoveLine(std::string(ReplaceAll(CB_INTERFACE_METHOD_HANDLER)
+ .ChangeToUpper("<ENUM_VALUE>", enum_value)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<METHOD_NAME>", d->GetID())));
+ }
+
+ return code;
+}
+
+// @see #CB_INTERFACE_METHOD_TABLE
+void CStubBodyGenerator::GenInterfaceMethodTable(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_METHOD_TABLE)
+ .Change("<NAME>", iface.GetID())
+ .Change("<METHOD_HANDLERS>", GenMethodHandlers(iface))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_CALLBACK_PORT_CHECK
+void CStubBodyGenerator::GenInterfaceCallbackPortCheck(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_CALLBACK_PORT_CHECK)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_PRIVILEGE_ADD
+// @see #CB_INTERFACE_TRUSTED_SET
+std::string CStubBodyGenerator::GenAccessControlSet(const Interface& iface) {
+ std::string code;
+ for (const auto& attr : iface.GetAttributes()) {
+ if (attr->GetKey() == "privilege") {
+ code += ReplaceAll(CB_INTERFACE_PRIVILEGE_ADD)
+ .Change("<NAME>", iface.GetID())
+ .Change("<PRIVILEGE>", attr->GetValue());
+ } else if (attr->GetKey() == "trusted" && attr->GetValue() == "true") {
+ code += ReplaceAll(CB_INTERFACE_TRUSTED_SET)
+ .Change("<NAME>", iface.GetID());
+ }
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_BASE
+void CStubBodyGenerator::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<PREFIX_REVERSE>", GetHandlePrefixReverse())
+ .Change("<NAME>", iface.GetID())
+ .Change("<ACCESS_CONTROL_SET>", GenAccessControlSet(iface))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/c_stub_body_generator.hh b/idlc/gen/version2/c_stub_body_generator.hh
new file mode 100644
index 0000000..645bcce
--- /dev/null
+++ b/idlc/gen/version2/c_stub_body_generator.hh
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_STUB_BODY_GENERATOR_HH_
+#define IDLC_GEN_VERSION2_C_STUB_BODY_GENERATOR_HH_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/version2/c_body_generator_base.hh"
+#include "idlc/options.h"
+
+namespace tidl {
+namespace version2 {
+
+class CStubBodyGenerator : public CBodyGeneratorBase {
+ public:
+ explicit CStubBodyGenerator(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options);
+ virtual ~CStubBodyGenerator() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenIncludePrivateHeaders(std::ofstream& stream);
+ void GenThreadEnableDefinition(std::ofstream& stream);
+ void GenInterfaceMethodHandlerType(std::ofstream& stream);
+ void GenInterfaceEnums(std::ofstream& stream);
+ void GenInterfaceEnum(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodEnumBase(std::ofstream& stream,
+ const Interface& iface);
+ void GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& iface);
+
+ void GenInterfaceDefs(std::ofstream& stream);
+ void GenInterfaceDef(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceContextDef(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateDef(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceCallbackPortCheckDef(std::ofstream& stream,
+ const Interface& iface);
+ void GenInterfaceBaseDef(std::ofstream& stream, const Interface& iface);
+
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceContextBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceMethodPrivilegeCheckerBase(std::ofstream& stream,
+ const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceMethodPrivilegeCheckerTable(std::ofstream& stream,
+ const Interface& iface);
+ void GenInterfaceMethodHandlerBase(std::ofstream& stream,
+ const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceMethodTable(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceCallbackPortCheck(std::ofstream& stream,
+ const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+
+ std::string GenMethodEnums(const Interface& iface);
+ std::string GenDelegateEnums(const Interface& iface);
+
+ std::string GenDelegateParams(const Interface& iface,
+ const Declaration& decl);
+ std::string GenDelegateParamsCheck(const Interface& iface,
+ const Declaration& decl);
+ std::string GenPrivileges(const Declaration& decl);
+ std::string GenMethodPrivilegeChecker(const Declaration& decl);
+ std::string GenPrivilegeCheckers(const Interface& iface);
+ std::string GenMethodHandlerArgsDecl(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodUnitMapRead(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlerCallbackInvoke(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodUnitMapWriteBase(const Interface& iface,
+ const BaseType& type,
+ const std::string& arg_name,
+ const std::string& arg);
+ std::string GenMethodUnitMapWrite(const Interface& iface,
+ const Declaration& decl);
+ std::string GenDelegateUnitMapWrite(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlerArgsFree(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlers(const Interface& iface);
+ std::string GenAccessControlSet(const Interface& iface);
+ void GenDelegateDefinition(std::ofstream& stream);
+ void GenDelegateBase(std::ofstream& stream);
+ std::string GenLemContext();
+ void GenLemDefinition(std::ofstream& stream);
+ void GenLemBase(std::ofstream& stream);
+ void GenLemAPI(std::ofstream& stream);
+
+ private:
+ std::shared_ptr<Options> options_;
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_STUB_BODY_GENERATOR_HH_
diff --git a/idlc/gen/version2/c_stub_body_generator_cb.hh b/idlc/gen/version2/c_stub_body_generator_cb.hh
new file mode 100644
index 0000000..fafe518
--- /dev/null
+++ b/idlc/gen/version2/c_stub_body_generator_cb.hh
@@ -0,0 +1,2326 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_STUB_BODY_GENERATOR_CB_HH_
+#define IDLC_GEN_VERSION2_C_STUB_BODY_GENERATOR_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+constexpr const char CB_PRIVATE_HEADERS[] =
+R"__c_cb(
+#include <app_manager.h>
+#include <package_manager.h>
+)__c_cb";
+
+constexpr const char CB_DELEGATE_DEFS[] =
+R"__c_cb(
+#ifndef TIDL_USE_DELEGATE
+#define TIDL_USE_DELEGATE 1
+#endif
+
+typedef struct rpc_port_delegate_s {
+ rpc_port_parcelable_t parcelable;
+ rpc_port_h port;
+ int id;
+ int seq_id;
+ bool once;
+ bool valid;
+} rpc_port_delegate_t;
+
+typedef rpc_port_delegate_t *rpc_port_delegate_h;
+
+static rpc_port_delegate_h rpc_port_delegate_create();
+)__c_cb";
+
+constexpr const char CB_DELEGATE_BASE[] =
+R"__c_cb(
+static void __rpc_port_delegate_to(rpc_port_parcel_h parcel, void *user_data)
+{
+ rpc_port_delegate_h delegate = user_data;
+ rpc_port_unit_map_h map;
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_unit_map_write_int(map, "id", delegate->id);
+ rpc_port_unit_map_write_int(map, "seq_id", delegate->seq_id);
+ rpc_port_unit_map_write_bool(map, "once", delegate->once);
+ rpc_port_parcel_write(parcel, &map->parcelable, map);
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static void __rpc_port_delegate_from(rpc_port_parcel_h parcel, void *user_data)
+{
+ rpc_port_delegate_h delegate = user_data;
+ rpc_port_unit_map_h map;
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_parcel_read(parcel, &map->parcelable, map);
+ rpc_port_unit_map_read_int(map, "id", &delegate->id);
+ rpc_port_unit_map_read_int(map, "seq_id", &delegate->seq_id);
+ rpc_port_unit_map_read_bool(map, "once", &delegate->once);
+ rpc_port_unit_map_destroy(map);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static rpc_port_delegate_h rpc_port_delegate_create()
+{
+ rpc_port_delegate_h delegate;
+
+ delegate = calloc(1, sizeof(rpc_port_delegate_t));
+ if (delegate == nullptr) {
+ _E("malloc() is failed");
+ return nullptr;
+ }
+
+ delegate->parcelable.to = __rpc_port_delegate_to;
+ delegate->parcelable.from = __rpc_port_delegate_from;
+
+ return delegate;
+}
+)__c_cb";
+
+constexpr const char CB_THREAD_ENABLE_DEF[] =
+R"__c_cb(
+#define TIDL_THREAD_ENABLE 1
+)__c_cb";
+
+constexpr const char CB_INTERFACE_METHOD_HANDLER_TYPE[] =
+R"__c_cb(
+typedef int (*rpc_port_stub_method_handler)(rpc_port_h port, rpc_port_parcel_h parcel, rpc_port_unit_map_h map, void *data);
+)__c_cb";
+
+/**
+ * <METHOD_ENUMS> The enumeration declarations of methods.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM_BASE[] =
+R"__c_cb(
+typedef enum {
+ <METHOD_ENUMS>
+} <PREFIX>_<NAME>_method_e;
+)__c_cb";
+
+/**
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM[] =
+R"__c_cb(
+<UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>,
+)__c_cb";
+
+/**
+ * <DELEGATE_ENUMS> The enumeration declarations of deleagtes.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_ENUM_BASE[] =
+R"__c_cb(
+typedef enum {
+ <DELEGATE_ENUMS>
+} <PREFIX>_<NAME>_delegate_e;
+)__c_cb";
+
+/**
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_DELEGATE_NAME> The uppercase delegate name of the interface.
+ * <NUMBER> The number of the delegate.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_ENUM[] =
+R"__c_cb(
+<UPPERCASE_PREFIX>_<UPPERCASE_NAME>_DELEGATE_<UPPERCASE_DELEGATE_NAME> = <NUMBER>,
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_stub_h stub;
+ <PREFIX>_<NAME>_callback_s callback;
+ void *user_data;
+ GList* contexts;
+ GList* callback_ports;
+ GRecMutex mutex;
+} <PREFIX>_<NAME>_t;
+
+static <PREFIX>_<NAME>_t __<NAME>;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CONTEXT_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_context_s {
+ char *sender;
+ char *instance;
+ rpc_port_h port;
+ rpc_port_h callback_port;
+ void *tag;
+ <PREFIX>_<NAME>_callback_s callback;
+ void *user_data;
+ app_info_h app_info;
+ GHashTable *privileges;
+ void *lem_context;
+#ifdef TIDL_THREAD_ENABLE
+ GThread *thread;
+ GQueue *queue;
+ GMutex mutex;
+ GCond cond;
+ bool done;
+#endif /* TIDL_THREAD_ENABLE */
+} <PREFIX>_<NAME>_context_t;
+
+typedef int (*<PREFIX>_<NAME>_privilege_checker)(<PREFIX>_<NAME>_context_h h, bool *sync);
+)__c_cb";
+
+/**
+ *
+ */
+constexpr const char CB_INTERFACE_CALLBACK_PORT_CHECK_DEF[] =
+R"__c_cb(
+static bool __<PREFIX>_<NAME>_exist_callback_port(rpc_port_h callback_port);
+static <PREFIX>_<NAME>_context_h __<PREFIX>_<NAME>_find_context(const char *instance);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ rpc_port_h port;
+ int id;
+ int seq_id;
+ bool once;
+ bool valid;
+ char *lem_instance;
+} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ */
+constexpr const char CB_INTERFACE_CONTEXT_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_throw_remote_exception(rpc_port_h port, rpc_port_parcel_h parcel, int cause, const char *message)
+{
+ <PREFIX>_remote_exception_h remote_exception = nullptr;
+ rpc_port_parcel_h result_parcel = nullptr;
+ rpc_port_parcel_header_h header = nullptr;
+ rpc_port_unit_map_h map;
+ int seq_num = 0;
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ return;
+ }
+
+ rpc_port_unit_map_write_int(map, "[METHOD]", <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_RESULT_);
+
+ <PREFIX>_remote_exception_create(&remote_exception);
+ <PREFIX>_remote_exception_set_cause(remote_exception, cause);
+ <PREFIX>_remote_exception_set_message(remote_exception, message);
+ rpc_port_unit_map_write_remote_exception(map, "[REMOTE_EXCEPTION]", remote_exception);
+ <PREFIX>_remote_exception_destroy(remote_exception);
+
+ if (rpc_port_parcel_create(&result_parcel) != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle");
+ rpc_port_unit_map_destroy(map);
+ return;
+ }
+
+ rpc_port_parcel_get_header(parcel, &header);
+ rpc_port_parcel_header_get_seq_num(header, &seq_num);
+
+ header = nullptr;
+ rpc_port_parcel_get_header(result_parcel, &header);
+ rpc_port_parcel_header_set_tag(header, TIDL_VERSION);
+ rpc_port_parcel_header_set_seq_num(header, seq_num);
+
+ rpc_port_parcel_write(result_parcel, &map->parcelable, map);
+ rpc_port_unit_map_destroy(map);
+
+ if (rpc_port_parcel_send(result_parcel, port) != RPC_PORT_ERROR_NONE)
+ _E("Failed to send result");
+
+ rpc_port_parcel_destroy(result_parcel);
+}
+
+static int __<PREFIX>_<NAME>_context_handle_request(<PREFIX>_<NAME>_context_h h, rpc_port_parcel_h parcel)
+{
+ int cmd = -1;
+ rpc_port_unit_map_h map;
+ bool sync = false;
+ int ret;
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ rpc_port_parcel_read(parcel, &map->parcelable, map);
+
+ rpc_port_unit_map_read_int(map, "[METHOD]", &cmd);
+
+ if (cmd > 1 && cmd < ARRAY_SIZE(__<NAME>_method_table)) {
+ if (h->lem_context == nullptr && h->app_info && __<NAME>_privilege_checkers[cmd]) {
+ ret = __<NAME>_privilege_checkers[cmd](h, &sync);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ rpc_port_unit_map_destroy(map);
+ if (sync)
+ __<PREFIX>_<NAME>_throw_remote_exception(h->port, parcel, ret, "Permission denied");
+
+ return ret;
+ }
+ }
+
+ if (__<NAME>_method_table[cmd])
+ ret = __<NAME>_method_table[cmd](h->port, parcel, map, h);
+
+ rpc_port_unit_map_destroy(map);
+ return ret;
+ }
+
+ rpc_port_unit_map_destroy(map);
+ _W("Invalid protocol. cmd(%d)", cmd);
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+#ifdef TIDL_THREAD_ENABLE
+static int __<PREFIX>_<NAME>_context_push(<PREFIX>_<NAME>_context_h h, rpc_port_parcel_h parcel)
+{
+ g_mutex_lock(&h->mutex);
+ g_queue_push_tail(h->queue, parcel);
+ g_cond_signal(&h->cond);
+ g_mutex_unlock(&h->mutex);
+
+ return 0;
+}
+
+static rpc_port_parcel_h __<PREFIX>_<NAME>_context_wait_and_pop(<PREFIX>_<NAME>_context_h h)
+{
+ rpc_port_parcel_h parcel;
+
+ g_mutex_lock(&h->mutex);
+ while (g_queue_is_empty(h->queue) && !h->done)
+ g_cond_wait(&h->cond, &h->mutex);
+
+ parcel = g_queue_pop_head(h->queue);
+ g_mutex_unlock(&h->mutex);
+
+ return parcel;
+}
+
+static gpointer __<PREFIX>_<NAME>_context_thread_cb(gpointer user_data)
+{
+ <PREFIX>_<NAME>_context_h h = user_data;
+ rpc_port_parcel_h parcel;
+
+ _W("START");
+ while (!h->done) {
+ parcel = __<PREFIX>_<NAME>_context_wait_and_pop(h);
+ if (parcel) {
+ __<PREFIX>_<NAME>_context_handle_request(h, parcel);
+ rpc_port_parcel_destroy(parcel);
+ }
+ }
+ _W("END");
+
+ return nullptr;
+}
+#endif /* TIDL_THREAD_ENABLE */
+
+static void __<PREFIX>_<NAME>_context_destroy(gpointer data)
+{
+ <PREFIX>_<NAME>_context_h h = data;
+#ifdef TIDL_THREAD_ENABLE
+ rpc_port_parcel_h parcel;
+#endif /* TIDL_THREAD_ENABLE */
+
+ if (h == nullptr)
+ return;
+
+#ifdef TIDL_THREAD_ENABLE
+ g_mutex_lock(&h->mutex);
+ h->done = true;
+ g_cond_signal(&h->cond);
+ g_mutex_unlock(&h->mutex);
+
+ if (h->thread) {
+ g_thread_join(h->thread);
+ g_thread_unref(h->thread);
+ }
+
+ g_mutex_clear(&h->mutex);
+ g_cond_clear(&h->cond);
+
+ if (h->queue) {
+ while (!g_queue_is_empty(h->queue)) {
+ parcel = g_queue_pop_head(h->queue);
+ rpc_port_parcel_destroy(parcel);
+ }
+
+ g_queue_free(h->queue);
+ }
+#endif /* TIDL_THREAD_ENABLE */
+
+ if (h->app_info)
+ app_info_destroy(h->app_info);
+
+ if (h->privileges)
+ g_hash_table_destroy(h->privileges);
+
+ if (h->instance)
+ free(h->instance);
+
+ if (h->sender)
+ free(h->sender);
+
+ free(h);
+}
+
+static bool __<PREFIX>_<NAME>_context_privilege_info_cb(const char *privilege_name, void *user_data)
+{
+ <PREFIX>_<NAME>_context_h h = user_data;
+ char *privilege;
+
+ privilege = strdup(privilege_name);
+ if (privilege == nullptr) {
+ _E("strdup() is failed. privilege: %s", privilege_name);
+ return false;
+ }
+
+ _D("appid: %s, privilege: %s", h->sender, privilege);
+ g_hash_table_insert(h->privileges, privilege, privilege);
+
+ return true;
+}
+
+static int __<PREFIX>_<NAME>_context_load_privileges(<PREFIX>_<NAME>_context_h h)
+{
+ package_info_h package_info;
+ app_info_h app_info;
+ char *package = nullptr;
+ int ret;
+
+ ret = app_info_create(h->sender, &app_info);
+ if (ret != APP_MANAGER_ERROR_NONE) {
+ if (ret == APP_MANAGER_ERROR_NO_SUCH_APP) {
+ _W("%s is not an application", h->sender);
+ return 0;
+ }
+
+ return ret;
+ }
+
+ h->app_info = app_info;
+ ret = app_info_get_package(app_info, &package);
+ if (ret != APP_MANAGER_ERROR_NONE) {
+ _E("Failed to get package. error(%d)", ret);
+ return ret;
+ }
+
+ ret = package_info_create(package, &package_info);
+ free(package);
+ if (ret != PACKAGE_MANAGER_ERROR_NONE) {
+ _E("Failed to create package info. error(%d)", ret);
+ return ret;
+ }
+
+ ret = package_info_foreach_privilege_info(package_info, __<PREFIX>_<NAME>_context_privilege_info_cb, h);
+ package_info_destroy(package_info);
+
+ return ret;
+}
+
+static <PREFIX>_<NAME>_context_h __<PREFIX>_<NAME>_context_create(const char *sender, const char *instance, rpc_port_h callback_port, void *lem_context)
+{
+ <PREFIX>_<NAME>_context_t *handle;
+
+ if (sender == nullptr || instance == nullptr) {
+ _E("Invalid parameter");
+ return nullptr;
+ }
+
+ if (lem_context == nullptr && callback_port == nullptr) {
+ _E("Invalid parameter");
+ return nullptr;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_context_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return nullptr;
+ }
+
+ handle->sender = strdup(sender);
+ if (handle->sender == nullptr) {
+ _E("Failed to duplicate sender");
+ __<PREFIX>_<NAME>_context_destroy(handle);
+ return nullptr;
+ }
+
+ handle->instance = strdup(instance);
+ if (handle->instance == nullptr) {
+ _E("Failed to duplicate instance");
+ __<PREFIX>_<NAME>_context_destroy(handle);
+ return nullptr;
+ }
+
+ handle->privileges = g_hash_table_new_full(g_str_hash, g_str_equal, free, nullptr);
+ if (handle->privileges == nullptr) {
+ _E("Failed to create hash table for privileges");
+ __<PREFIX>_<NAME>_context_destroy(handle);
+ return nullptr;
+ }
+
+ if (__<PREFIX>_<NAME>_context_load_privileges(handle) != 0) {
+ __<PREFIX>_<NAME>_context_destroy(handle);
+ return nullptr;
+ }
+
+#ifdef TIDL_THREAD_ENABLE
+ g_mutex_init(&handle->mutex);
+ g_cond_init(&handle->cond);
+
+ handle->queue = g_queue_new();
+ if (handle->queue == nullptr) {
+ _E("Failed to create queue");
+ __<PREFIX>_<NAME>_context_destroy(handle);
+ return nullptr;
+ }
+
+ handle->thread = g_thread_new(instance, __<PREFIX>_<NAME>_context_thread_cb, handle);
+ if (handle->thread == nullptr) {
+ _E("Failed to create thread");
+ __<PREFIX>_<NAME>_context_destroy(handle);
+ return nullptr;
+ }
+#endif /* TIDL_THREAD_ENABLE */
+
+ handle->lem_context = lem_context;
+ handle->callback_port = callback_port;
+ handle->callback = __<NAME>.callback;
+ handle->user_data = __<NAME>.user_data;
+
+ return handle;
+}
+
+static <PREFIX>_<NAME>_context_h __<PREFIX>_<NAME>_find_context(const char *instance)
+{
+ <PREFIX>_<NAME>_context_h context;
+ GList *iter;
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ iter = __<NAME>.contexts;
+ while (iter) {
+ context = iter->data;
+ if (!strcmp(context->instance, instance)) {
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+ return context;
+ }
+
+ iter = g_list_next(iter);
+ }
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+
+ return nullptr;
+}
+
+static void __<PREFIX>_<NAME>_add_context(<PREFIX>_<NAME>_context_h context)
+{
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ __<NAME>.contexts = g_list_append(__<NAME>.contexts, context);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+}
+
+static void __<PREFIX>_<NAME>_remove_context(<PREFIX>_<NAME>_context_h context)
+{
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ __<NAME>.contexts = g_list_remove(__<NAME>.contexts, context);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+}
+
+static void __<PREFIX>_<NAME>_clear_context(gpointer data)
+{
+ <PREFIX>_<NAME>_context_h context = data;
+
+ if (context->lem_context) {
+ _W("[LEM] disconnect %s:<NAME>", __stub_appid);
+ rpc_port_stub_lem_disconnect(__<NAME>_context, context->lem_context);
+ __<PREFIX>_<NAME>_remove_context(context);
+ }
+ __<PREFIX>_<NAME>_context_destroy(context);
+}
+
+int <PREFIX>_<NAME>_context_set_tag(<PREFIX>_<NAME>_context_h context, void *tag)
+{
+ if (context == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ context->tag = tag;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_context_get_tag(<PREFIX>_<NAME>_context_h context, void **tag)
+{
+ if (context == nullptr || tag == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *tag = context->tag;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_context_get_sender(<PREFIX>_<NAME>_context_h context, char **sender)
+{
+ char *value;
+
+ if (context == nullptr || sender == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ value = strdup(context->sender);
+ if (value == nullptr) {
+ _E("Failed to duplicate sender");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ *sender = value;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_context_get_instance(<PREFIX>_<NAME>_context_h context, char **instance)
+{
+ char *value;
+
+ if (context == nullptr || instance == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ value = strdup(context->instance);
+ if (value == nullptr) {
+ _E("Failed to duplicate instance");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ *instance = value;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_context_disconnect(<PREFIX>_<NAME>_context_h context)
+{
+ int ret = RPC_PORT_ERROR_NONE;
+
+ if (context == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+
+ if (context->lem_context) {
+ _W("[LEM] disconnect %s:<NAME>", __stub_appid);
+ rpc_port_stub_lem_disconnect(__<NAME>_context, context->lem_context);
+ __<PREFIX>_<NAME>_remove_context(context);
+ __<PREFIX>_<NAME>_context_destroy(context);
+ } else {
+ ret = rpc_port_disconnect(context->callback_port);
+ if (ret != RPC_PORT_ERROR_NONE)
+ _E("Failed to disconnect. error(%d)", ret);
+ }
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+
+ return ret;
+}
+
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ * <DELEGATE_PARAMS> The parameters of the delegate.
+ * <DELEGATE_PARAMS_CHECK> The implementation to check whether arguments are nullptr or not
+ * <DELEGATE_ENUM_VALUE> The enumeration value of the method.
+ * <DELEGATE_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_to(rpc_port_parcel_h parcel, void *user_data)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = user_data;
+ rpc_port_unit_map_h map;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_unit_map_write_int(map, "id", h->id);
+ rpc_port_unit_map_write_int(map, "seq_id", h->seq_id);
+ rpc_port_unit_map_write_bool(map, "once", h->once);
+
+ rpc_port_parcel_write(parcel, &map->parcelable, map);
+ rpc_port_unit_map_destroy(map);
+
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_from(rpc_port_parcel_h parcel, void *user_data)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = user_data;
+ rpc_port_unit_map_h map;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ rpc_port_parcel_read(parcel, &map->parcelable, map);
+
+ rpc_port_unit_map_read_int(map, "id", &h->id);
+ rpc_port_unit_map_read_int(map, "seq_id", &h->seq_id);
+ rpc_port_unit_map_read_bool(map, "once", &h->once);
+
+ rpc_port_unit_map_destroy(map);
+
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_t *handle;
+ static int seq_num;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_<DELEGATE_NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_<DELEGATE_NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_<DELEGATE_NAME>_from;
+ handle->id = <DELEGATE_ENUM_VALUE>;
+ handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+ handle->once = false;
+ handle->valid = true;
+ _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ _W("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+
+ if (h->lem_instance)
+ free(h->lem_instance);
+
+ free(h);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone)
+{
+ rpc_port_unit_map_h map;
+ int ret;
+
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ map = rpc_port_unit_map_create();
+ if (map == nullptr) {
+ _E("Failed to create unit map");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = rpc_port_unit_map_write_<NAME>_<DELEGATE_NAME>(map, "clone", h);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to write <DELEGATE_NAME>. error(%d)", ret);
+ rpc_port_unit_map_destroy(map);
+ return ret;
+ }
+
+ rpc_port_unit_map_read_<NAME>_<DELEGATE_NAME>(map, "clone", clone);
+ rpc_port_unit_map_destroy(map);
+
+ (*clone)->port = h->port;
+
+ if (h->lem_instance) {
+ (*clone)->lem_instance = strdup(h->lem_instance);
+ if ((*clone)->lem_instance == nullptr) {
+ _E("Out of memory");
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(*clone);
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ return ret;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id)
+{
+ if (h == nullptr || id == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *id = h->id;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id)
+{
+ if (h == nullptr || seq_id == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *seq_id = h->seq_id;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once)
+{
+ if (h == nullptr || once == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *once = h->once;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag)
+{
+ char *value;
+ char buf[128];
+
+ if (h == nullptr || tag == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ snprintf(buf, sizeof(buf), "%d::%d", h->id, h->seq_id);
+ value = strdup(buf);
+ if (value == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ *tag = value;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_port(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, rpc_port_h port)
+{
+ if (h == nullptr || port == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ h->port = port;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+static int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_lem_instance(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, const char *lem_instance)
+{
+ if (h == nullptr || lem_instance == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (h->lem_instance)
+ free(h->lem_instance);
+
+ h->lem_instance = strdup(lem_instance);
+ if (h->lem_instance == nullptr) {
+ _E("strdup() is failed");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_invoke(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h<DELEGATE_PARAMS>)
+{
+ rpc_port_parcel_h parcel_;
+ int ret_;
+ rpc_port_unit_map_h map_;
+ <PREFIX>_<NAME>_context_h context = nullptr;
+
+ if (h == nullptr <DELEGATE_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (h->lem_instance) {
+ context = __<PREFIX>_<NAME>_find_context(h->lem_instance);
+ if (context == nullptr) {
+ _E("Not connected");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+ } else {
+ if (h->port == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!__<PREFIX>_<NAME>_exist_callback_port(h->port)) {
+ _E("Not connected");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+ }
+
+ if (h->once && !h->valid) {
+ _E("The delegate handle is already used");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret_ = rpc_port_parcel_create(&parcel_);
+ if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret_);
+ return ret_;
+ }
+
+ map_ = rpc_port_unit_map_create();
+ if (map_ == nullptr) {
+ _E("Failed to create unit map");
+ rpc_port_parcel_destroy(parcel_);
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return ret_;
+ }
+
+ rpc_port_unit_map_write_int(map_, "[METHOD]", <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_CALLBACK_);
+
+ rpc_port_unit_map_write_delegate(map_, "delegate", (rpc_port_delegate_h)h);
+
+ <DELEGATE_UNIT_MAP_WRITE>
+ rpc_port_parcel_write(parcel_, &map_->parcelable, map_);
+ if (context && context->lem_context) {
+ rpc_port_stub_lem_invoke_callback(__<NAME>_context, context->lem_context, parcel_);
+ ret_ = RPC_PORT_ERROR_NONE;
+ } else {
+ ret_ = rpc_port_parcel_send(parcel_, h->port);
+ }
+
+ rpc_port_unit_map_destroy(map_);
+ rpc_port_parcel_destroy(parcel_);
+ h->valid = false;
+
+ return ret_;
+}
+)__c_cb";
+
+
+/*
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_DELEGATE_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_delegate(map_, "<ARG_NAME>", (rpc_port_delegate_h)<ARG>);
+)__c_cb";
+
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_int(map_, "<ARG_NAME>", (int)<ARG>);
+)__c_cb";
+
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG_NAME>", <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_bundle(map_, "<ARG_NAME>", <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_string(map_, "<ARG_NAME>", <ARG>);
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_UNIT_MAP_WRITE[] =
+R"__c_cb(
+rpc_port_unit_map_write_<TYPE_NAME>(map_, "<ARG_NAME>", <ARG>);
+)__c_cb";
+
+/**
+ * <ARG_NAME> The argument name.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_EMUM_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_int(map, "<ARG_NAME>", (int *)&<ARG>);
+)__c_cb";
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG_NAME> The argument name.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_<TYPE_NAME>(map, "<ARG_NAME>", &<ARG>);
+)__c_cb";
+
+/**
+ * <ARG_NAME> The argument name.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_bundle(map, "<ARG_NAME>", &<ARG>);
+)__c_cb";
+
+/**
+ * <ARG_NAME> The argument name.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_string(map, "<ARG_NAME>", &<ARG>);
+)__c_cb";
+
+/*
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_DELEGATE_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_delegate(map, "<ARG>", (rpc_port_delegate_h *)&<ARG>);
+
+if (context_->lem_context)
+ <PREFIX>_<TYPE_NAME>_set_lem_instance(<ARG>, context_->instance);
+else
+ <PREFIX>_<TYPE_NAME>_set_port(<ARG>, callback_port_);
+)__c_cb";
+
+
+/**
+ * <TYPE_NAME> The type name of the argument.
+ * <ARG_NAME> The argument name.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_UNIT_MAP_READ[] =
+R"__c_cb(
+rpc_port_unit_map_read_<TYPE_NAME>(map, "<ARG_NAME>", &<ARG>);
+)__c_cb";
+
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_HANDLER_ARGS_DECL> The declarations for arguments of the method.
+ * <METHOD_HANDLER_PARCEL_READ> The implementation to read the parameter from the parcel.
+ * <METHOD_HANDLER_CALLBACK_INVOKE> The implementation to invoke the callback function of the method.
+ * <METHOD_HANDLER_PARCEL_WRITE> The implementation to write the result to the parcel.
+ * <METHOD_HANDLER_ARGS_FREE> The implementation to release arguments.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER_BASE[] =
+R"__c_cb(
+static int __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler(rpc_port_h port, rpc_port_parcel_h parcel, rpc_port_unit_map_h map, void *user_data)
+{
+ <PREFIX>_<NAME>_context_h context_ = user_data;
+ rpc_port_parcel_header_h header_;
+ int seq_num_ = -1;
+ rpc_port_h callback_port_;
+ int ret_ = RPC_PORT_ERROR_NONE;
+
+ <METHOD_HANDLER_ARGS_DECL>
+
+ if (context_->lem_context == nullptr) {
+ ret_ = rpc_port_stub_get_port(__<NAME>.stub, RPC_PORT_PORT_CALLBACK, context_->instance, &callback_port_);
+ if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get callback port. error(%d)", ret_);
+ goto out;
+ }
+ }
+
+ rpc_port_parcel_get_header(parcel, &header_);
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+
+ <METHOD_UNIT_MAP_READ>
+ <METHOD_HANDLER_CALLBACK_INVOKE>
+ <METHOD_UNIT_MAP_WRITE>
+
+out:
+ <METHOD_HANDLER_ARGS_FREE>
+ return ret_;
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface
+ */
+constexpr const char CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ[] =
+R"__c_cb(
+ret_ = <PREFIX>_<NAME>_create(&<ARG>);
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret_);
+ goto out;
+}
+
+<PREFIX>_<NAME>_set_port(<ARG>, callback_port_);
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+ret_ = get_last_result();
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret_);
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <ARG> The name of the value.
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+ret_ = <PREFIX>_<NAME>_create(&<ARG>);
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret_);
+ goto out;
+}
+
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+ret_ = get_last_result();
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret_);
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_bundle(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_string(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &<ARG>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <RES_SET> The implemention to set the result of the callback function.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <METHOD_ARGS> The arguments of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_INVOKE[] =
+R"__c_cb(
+if (__<PREFIX>_remote_exception != nullptr) {
+ <PREFIX>_remote_exception_destroy(__<PREFIX>_remote_exception);
+ __<PREFIX>_remote_exception = nullptr;
+}
+
+if (context_->callback.<METHOD_NAME>)
+ <RES_SET>context_->callback.<METHOD_NAME>(context_<METHOD_ARGS>, context_->user_data);
+)__c_cb";
+
+/**
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_PARCEL_WRITE_PRE[] =
+R"__c_cb(
+ret_ = rpc_port_parcel_create(&parcel_);
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret_);
+ goto out;
+}
+
+rpc_port_parcel_get_header(parcel_, &header_);
+rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+rpc_port_parcel_header_set_seq_num(header_, seq_num_);
+
+map_ = rpc_port_unit_map_create();
+if (map_ == nullptr) {
+ _E("Failed to create unit map");
+ rpc_port_parcel_destroy(parcel_);
+ ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ goto out;
+}
+
+rpc_port_unit_map_write_int(map_, "[METHOD]", <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_RESULT_);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_PARCEL_WRITE_POST[] =
+R"__c_cb(
+if (__<PREFIX>_remote_exception != nullptr)
+ rpc_port_unit_map_write_remote_exception(map_, "[REMOTE_EXCEPTION]", __<PREFIX>_remote_exception);
+
+rpc_port_parcel_write(parcel_, &map_->parcelable, map_);
+rpc_port_unit_map_destroy(map_);
+
+if (context_->lem_context)
+ rpc_port_stub_lem_send_result(__<NAME>_context, context_->lem_context, parcel_);
+else
+ ret_ = rpc_port_parcel_send(parcel_, port);
+
+rpc_port_parcel_destroy(parcel_);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ <PREFIX>_<NAME>_destroy(<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ bundle_free(<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ free(<ARG>);
+)__c_cb";
+
+/**
+ * <NAME> The name of the interface.
+ * <METHOD_HANDLERS> The declarations of method handlers.
+ */
+constexpr const char CB_INTERFACE_METHOD_TABLE[] =
+R"__c_cb(
+static rpc_port_stub_method_handler __<NAME>_method_table[] = {
+ <METHOD_HANDLERS>
+};
+)__c_cb";
+
+/**
+ * <ENUM_VALUE> The enumeration value of the method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER[] =
+R"__c_cb(
+[<ENUM_VALUE>] = __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler,
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <ACCESS_CONTROL_SET> The implmentation to set the access control the stub handle.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_add_callback_port(rpc_port_h callback_port)
+{
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ __<NAME>.callback_ports = g_list_append(__<NAME>.callback_ports, callback_port);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+}
+
+static void __<PREFIX>_<NAME>_remove_callback_port(rpc_port_h callback_port)
+{
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ __<NAME>.callback_ports = g_list_remove(__<NAME>.callback_ports, callback_port);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+}
+
+static void __<PREFIX>_<NAME>_connected_event_cb(const char *sender, const char *instance, void *user_data)
+{
+ <PREFIX>_<NAME>_context_h context;
+ rpc_port_h callback_port = nullptr;
+ int ret;
+
+ _W("sender(%s), instance(%s)", sender, instance);
+ ret = rpc_port_stub_get_port(__<NAME>.stub, RPC_PORT_PORT_CALLBACK, instance, &callback_port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get callback port. error(%d)", ret);
+ return;
+ }
+
+ context = __<PREFIX>_<NAME>_context_create(sender, instance, callback_port, nullptr);
+ if (context == nullptr)
+ return;
+
+ __<PREFIX>_<NAME>_add_context(context);
+ __<PREFIX>_<NAME>_add_callback_port(context->callback_port);
+ context->callback.create(context, context->user_data);
+}
+
+static void __<PREFIX>_<NAME>_disconnected_event_cb(const char *sender, const char *instance, void *user_data)
+{
+ <PREFIX>_<NAME>_context_h context;
+
+ _W("sender(%s), instance(%s)", sender, instance);
+ context = __<PREFIX>_<NAME>_find_context(instance);
+ if (context == nullptr)
+ return;
+
+ __<PREFIX>_<NAME>_remove_callback_port(context->callback_port);
+ context->callback.terminate(context, context->user_data);
+ __<PREFIX>_<NAME>_remove_context(context);
+ __<PREFIX>_<NAME>_context_destroy(context);
+}
+
+static int __<PREFIX>_<NAME>_received_event_cb(const char *sender, const char *instance, rpc_port_h port, void *user_data)
+{
+ <PREFIX>_<NAME>_context_h context;
+ rpc_port_parcel_h parcel;
+ int ret;
+
+ _W("sender(%s), instance(%s)", sender, instance);
+ context = __<PREFIX>_<NAME>_find_context(instance);
+ if (context == nullptr) {
+ _E("Failed to find context. instance(%s)", instance);
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ context->port = port;
+ ret = rpc_port_parcel_create_from_port(&parcel, port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle from port. error(%d)", ret);
+ return ret;
+ }
+
+#ifdef TIDL_THREAD_ENABLE
+ ret = __<PREFIX>_<NAME>_context_push(context, parcel);
+#else
+ ret = __<PREFIX>_<NAME>_context_handle_request(context, parcel);
+ rpc_port_parcel_destroy(parcel);
+#endif /* TIDL_THREAD_ENABLE */
+
+ return ret;
+}
+
+static int __<PREFIX>_<NAME>_set_access_control(void)
+{
+ int ret = RPC_PORT_ERROR_NONE;
+
+ <ACCESS_CONTROL_SET>
+ return ret;
+}
+
+static void __rpc_port_stub_<NAME>_lem_connected_cb(void *lem_context, const char *sender, const char* instance, bool sync)
+{
+ <PREFIX>_<NAME>_context_h context;
+
+ _W("[LEM] sender(%s), instance(%s)", sender, instance);
+ context = __<PREFIX>_<NAME>_context_create(sender, instance, nullptr, lem_context);
+ if (context == nullptr)
+ return;
+
+ __<PREFIX>_<NAME>_add_context(context);
+ context->callback.create(context, context->user_data);
+
+ rpc_port_stub_lem_connect(__<NAME>_context, lem_context, sync);
+}
+
+static void __rpc_port_stub_<NAME>_lem_disconnected_cb(void *lem_context, const char *sender, const char *instance)
+{
+ <PREFIX>_<NAME>_context_h context;
+
+ _W("[LEM] sender(%s), instance(%s)", sender, instance);
+ context = __<PREFIX>_<NAME>_find_context(instance);
+ if (context == nullptr)
+ return;
+
+ __<PREFIX>_<NAME>_remove_callback_port(context->callback_port);
+ context->callback.terminate(context, context->user_data);
+ __<PREFIX>_<NAME>_remove_context(context);
+ __<PREFIX>_<NAME>_context_destroy(context);
+
+ rpc_port_stub_lem_disconnect(__<NAME>_context, lem_context);
+}
+
+static void __rpc_port_stub_<NAME>_lem_received_cb(void *lem_context, const char *sender, const char *instance, rpc_port_parcel_h parcel)
+{
+ <PREFIX>_<NAME>_context_h context;
+
+ _W("[LEM] sender(%s), instance(%s)", sender, instance);
+ context = __<PREFIX>_<NAME>_find_context(instance);
+ if (context == nullptr) {
+ _E("Failed to find context. instance(%s)", instance);
+ return;
+ }
+
+ __<PREFIX>_<NAME>_context_handle_request(context, parcel);
+}
+
+int <PREFIX>_<NAME>_register(<PREFIX>_<NAME>_callback_s *callback, void *user_data)
+{
+ rpc_port_stub_lem_event_s lem_callback = { 0, };
+ int ret;
+
+ if (callback == nullptr || callback->create == nullptr || callback->terminate == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (__stub_appid == nullptr)
+ app_get_id(&__stub_appid);
+
+ if (__<NAME>.stub) {
+ _E("Already exists");
+ return RPC_PORT_ERROR_NONE;
+ }
+
+ g_rec_mutex_init(&__<NAME>.mutex);
+ __<NAME>.callback = *callback;
+ __<NAME>.user_data = user_data;
+
+ ret = rpc_port_stub_create(&__<NAME>.stub, "<NAME>");
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create stub handle. error(%d)", ret);
+ g_rec_mutex_clear(&__<NAME>.mutex);
+ return ret;
+ }
+
+ ret = rpc_port_stub_add_received_event_cb(__<NAME>.stub, __<PREFIX>_<NAME>_received_event_cb, &__<NAME>);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add received event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = rpc_port_stub_add_connected_event_cb(__<NAME>.stub, __<PREFIX>_<NAME>_connected_event_cb, &__<NAME>);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add connected event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = rpc_port_stub_add_disconnected_event_cb(__<NAME>.stub, __<PREFIX>_<NAME>_disconnected_event_cb, &__<NAME>);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add disconnected event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = __<PREFIX>_<NAME>_set_access_control();
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add privileges");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = rpc_port_stub_listen(__<NAME>.stub);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to listen events. error(%d)", ret);
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ lem_callback.connected = __rpc_port_stub_<NAME>_lem_connected_cb;
+ lem_callback.disconnected = __rpc_port_stub_<NAME>_lem_disconnected_cb;
+ lem_callback.received = __rpc_port_stub_<NAME>_lem_received_cb;
+
+ __<NAME>_context = rpc_port_stub_lem_create("<NAME>", &lem_callback);
+ if (__<NAME>_context == nullptr) {
+ _E("Failed to create lem context");
+ <PREFIX>_<NAME>_unregister();
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ rpc_port_stub_lem_set_listening(__<NAME>_context, true);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_unregister(void)
+{
+ if (__<NAME>.stub == nullptr)
+ return RPC_PORT_ERROR_NONE;
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+ g_rec_mutex_clear(&__<NAME>.mutex);
+
+ rpc_port_stub_lem_set_listening(__<NAME>_context, false);
+
+ if (__<NAME>.contexts) {
+ g_list_free_full(__<NAME>.contexts, __<PREFIX>_<NAME>_clear_context);
+ __<NAME>.contexts = nullptr;
+ }
+
+ if (__<NAME>.stub) {
+ rpc_port_stub_destroy(__<NAME>.stub);
+ __<NAME>.stub = nullptr;
+ }
+
+ if (__<NAME>_context) {
+ rpc_port_stub_lem_destroy(__<NAME>_context);
+ __<NAME>_context = nullptr;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_foreach_context(<PREFIX>_<NAME>_context_cb callback, void *user_data)
+{
+ <PREFIX>_<NAME>_context_h context;
+ GList *iter;
+
+ if (callback == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ iter = __<NAME>.contexts;
+ while (iter) {
+ context = iter->data;
+ if (!callback(context, user_data))
+ break;
+
+ iter = g_list_next(iter);
+ }
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_get_client_number(unsigned int *client_number)
+{
+ if (client_number == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (__<NAME>.stub == nullptr) {
+ _E("Invalid context");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ *client_number = g_list_length(__<NAME>.contexts);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CALLBACK_PORT_CHECK[] =
+R"__c_cb(
+static bool __<PREFIX>_<NAME>_exist_callback_port(rpc_port_h callback_port)
+{
+ rpc_port_h port;
+ GList *iter;
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ iter = __<NAME>.callback_ports;
+ while (iter) {
+ port = iter->data;
+ if (port == callback_port) {
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+ return true;
+ }
+
+ iter = g_list_next(iter);
+ }
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+
+ return false;
+}
+)__c_cb";
+
+/**
+ * <NAME> The name of the interface.
+ * <PRIVILEGE> The privilege name.
+ */
+constexpr const char CB_INTERFACE_PRIVILEGE_ADD[] =
+R"__c_cb(
+ret = rpc_port_stub_add_privilege(__<NAME>.stub, "<PRIVILEGE>");
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add privilege. error(%d)", ret);
+ return ret;
+}
+)__c_cb";
+
+/**
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_TRUSTED_SET[] =
+R"__c_cb(
+ret = rpc_port_stub_set_trusted(__<NAME>.stub, true);
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to set trusted mode. error(%d)", ret);
+ return ret;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interace.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <METHOD_PRIVILEGE_CHECKER> The implementation of the method privilege checker.
+ */
+constexpr const char CB_INTERFACE_METHOD_PRIVILEGE_CHECKER_BASE[] =
+R"__c_cb(
+static int __<PREFIX>_<NAME>_method_<METHOD_NAME>_privilege_checker(<PREFIX>_<NAME>_context_h h, bool *sync)
+{
+ <METHOD_PRIVILEGE_CHECKER>
+}
+)__c_cb";
+
+/**
+ * <PRIVILEGES> The privileges of the method
+ * <SYNC_TRUE_OR_FALSE> The flag if it's true, the stub should throw the remote exception.
+ */
+constexpr const char CB_INTERFACE_METHOD_PRIVILEGE_CHECKER[] =
+R"__c_cb(
+static const char *privileges[] = {
+ <PRIVILEGES>
+};
+
+*sync = <SYNC_TRUE_OR_FALSE>;
+for (size_t i = 0; i < ARRAY_SIZE(privileges); ++i) {
+ if (!g_hash_table_contains(h->privileges, privileges[i])) {
+ _E("Permission denied. %s : %s", h->sender, privileges[i]);
+ return RPC_PORT_ERROR_PERMISSION_DENIED;
+ }
+}
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <PRIVILEGE_CHECKERS> The privilege checker for each methods.
+ */
+constexpr const char CB_INTERFACE_METHOD_PRIVIELGE_CHECKER_TABLE[] =
+R"__c_cb(
+static <PREFIX>_<NAME>_privilege_checker __<NAME>_privilege_checkers[] = {
+ <PRIVILEGE_CHECKERS>
+};
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the ineterface.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <ENUM_VALUE> The enumeration value of the method of the interface.
+ */
+constexpr const char CB_INTERFACE_PRIVILEGE_CHECKER[] =
+R"__c_cb(
+[<ENUM_VALUE>] = __<PREFIX>_<NAME>_method_<METHOD_NAME>_privilege_checker,
+)__c_cb";
+
+/**
+ * <LEM_CONTEXT> The context of the local execution of the interface.
+ */
+constexpr const char CB_LEM_BASE_DEF[] =
+R"__c_cb(
+typedef int (*rpc_port_proxy_lem_connect_func)(void *context, bool sync);
+typedef int (*rpc_port_proxy_lem_disconnect_func)(void *context);
+typedef int (*rpc_port_proxy_lem_send_result_func)(void *context, rpc_port_parcel_h parcel);
+typedef int (*rpc_port_proxy_lem_invoke_callback_func)(void *context, rpc_port_parcel_h parcel);
+
+typedef void (*rpc_port_stub_lem_connected_cb)(void *context, const char *sender, const char *instance, bool sync);
+typedef void (*rpc_port_stub_lem_disconnected_cb)(void *context, const char *sender, const char *instance);
+typedef void (*rpc_port_stub_lem_received_cb)(void *context, const char *sender, const char *instance, rpc_port_parcel_h parcel);
+
+typedef struct {
+ rpc_port_stub_lem_connected_cb connected;
+ rpc_port_stub_lem_disconnected_cb disconnected;
+ rpc_port_stub_lem_received_cb received;
+} rpc_port_stub_lem_event_s;
+
+typedef struct {
+ void *context;
+ char *sender;
+ char *instance;
+ bool sync;
+ rpc_port_parcel_h parcel;
+} rpc_port_stub_lem_data_s;
+
+typedef rpc_port_stub_lem_data_s *rpc_port_stub_lem_data_h;
+
+typedef struct {
+ char *port_name;
+ rpc_port_stub_lem_event_s callback;
+ bool listening;
+ bool loaded;
+ rpc_port_proxy_lem_connect_func connect_func;
+ rpc_port_proxy_lem_disconnect_func disconnect_func;
+ rpc_port_proxy_lem_send_result_func send_result_func;
+ rpc_port_proxy_lem_invoke_callback_func invoke_callback_func;
+ GQueue *connected_queue;
+ GQueue *disconnected_queue;
+ GQueue *received_queue;
+ GRecMutex mutex;
+} rpc_port_stub_lem_s;
+
+typedef rpc_port_stub_lem_s *rpc_port_stub_lem_h;
+static char *__stub_appid;
+
+<LEM_CONTEXT>
+)__c_cb";
+
+/**
+ * <IFACE_NAME> The interface name.
+ */
+constexpr const char CB_LEM_CONTEXT[] =
+R"__c_cb(
+static rpc_port_stub_lem_h __<IFACE_NAME>_context;
+)__c_cb";
+
+/**
+ * <INPUT_FILE> The input file name.
+ */
+constexpr const char CB_LEM_BASE[] =
+R"__c_cb(
+static rpc_port_parcel_h __rpc_port_parcel_clone(rpc_port_parcel_h parcel)
+{
+ rpc_port_parcel_h handle = nullptr;
+ void* raw = nullptr;
+ unsigned int size = 0;
+
+ if (rpc_port_parcel_get_raw(parcel, &raw, &size) != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get raw");
+ return nullptr;
+ }
+
+ rpc_port_parcel_create_from_raw(&handle, raw, size);
+ return handle;
+}
+
+static void rpc_port_stub_lem_data_destroy(rpc_port_stub_lem_data_h data)
+{
+ if (data == nullptr)
+ return;
+
+ if (data->sender)
+ free(data->sender);
+
+ if (data->instance)
+ free(data->instance);
+
+ if (data->parcel)
+ rpc_port_parcel_destroy(data->parcel);
+
+ free(data);
+}
+
+static rpc_port_stub_lem_data_h rpc_port_stub_lem_data_create(void *context, const char *sender, const char *instance, bool sync)
+{
+ rpc_port_stub_lem_data_h data;
+
+ if (context == nullptr || instance == nullptr) {
+ _E("Invalid parameter");
+ return nullptr;
+ }
+
+ data = calloc(1, sizeof(rpc_port_stub_lem_data_s));
+ if (data == nullptr) {
+ _E("Out of memory");
+ return nullptr;
+ }
+
+ data->sender = strdup(sender ? sender : "");
+ if (data->sender == nullptr) {
+ _E("strdup() is failed");
+ rpc_port_stub_lem_data_destroy(data);
+ return nullptr;
+ }
+
+ data->instance = strdup(instance);
+ if (data->instance == nullptr) {
+ _E("strdup() is failed");
+ rpc_port_stub_lem_data_destroy(data);
+ return nullptr;
+ }
+
+ data->context = context;
+ data->sync = sync;
+ return data;
+}
+
+static rpc_port_stub_lem_data_h rpc_port_stub_lem_data_create_with_parcel(void *context, const char *sender, const char *instance, rpc_port_parcel_h parcel)
+{
+ rpc_port_stub_lem_data_h data;
+
+ if (context == nullptr || instance == nullptr || parcel == nullptr) {
+ _E("Invalid parameter");
+ return nullptr;
+ }
+
+ data = calloc(1, sizeof(rpc_port_stub_lem_data_s));
+ if (data == nullptr) {
+ _E("Out of memory");
+ return nullptr;
+ }
+
+ data->sender = strdup(sender ? sender : "");
+ if (data->sender == nullptr) {
+ _E("strdup() is failed");
+ rpc_port_stub_lem_data_destroy(data);
+ return nullptr;
+ }
+
+ data->instance = strdup(instance);
+ if (data->instance == nullptr) {
+ _E("strdup() is failed");
+ rpc_port_stub_lem_data_destroy(data);
+ return nullptr;
+ }
+
+ data->parcel = __rpc_port_parcel_clone(parcel);
+ if (data->parcel == nullptr) {
+ _E("Failed to clone parcel");
+ rpc_port_stub_lem_data_destroy(data);
+ return nullptr;
+ }
+
+ data->context = context;
+ return data;
+}
+
+static bool rpc_port_stub_lem_load_symbols(rpc_port_stub_lem_h handle)
+{
+ char symbol[1024];
+
+ if (handle == nullptr) {
+ _E("Invalid parameter");
+ return false;
+ }
+
+ if (handle->loaded)
+ return true;
+
+ snprintf(symbol, sizeof(symbol), "rpc_port_proxy_<INPUT_FILE>_lem_%s_connect", handle->port_name);
+ handle->connect_func = (rpc_port_proxy_lem_connect_func)dlsym(RTLD_DEFAULT, symbol);
+ if (handle->connect_func == nullptr) {
+ _E("Failed to find symbol");
+ return false;
+ }
+
+ snprintf(symbol, sizeof(symbol), "rpc_port_proxy_<INPUT_FILE>_lem_%s_disconnect", handle->port_name);
+ handle->disconnect_func = (rpc_port_proxy_lem_disconnect_func)dlsym(RTLD_DEFAULT, symbol);
+ if (handle->disconnect_func == nullptr) {
+ _E("Failed to find symbol");
+ return false;
+ }
+
+ snprintf(symbol, sizeof(symbol), "rpc_port_proxy_<INPUT_FILE>_lem_%s_send_result", handle->port_name);
+ handle->send_result_func = (rpc_port_proxy_lem_send_result_func)dlsym(RTLD_DEFAULT, symbol);
+ if (handle->send_result_func == nullptr) {
+ _E("Failed to find symbol");
+ return false;
+ }
+
+ snprintf(symbol, sizeof(symbol), "rpc_port_proxy_<INPUT_FILE>_lem_%s_invoke_callback", handle->port_name);
+ handle->invoke_callback_func = (rpc_port_proxy_lem_invoke_callback_func)dlsym(RTLD_DEFAULT, symbol);
+ if (handle->invoke_callback_func == nullptr) {
+ _E("Failed to find symbol");
+ return false;
+ }
+
+ handle->loaded = true;
+ return true;
+}
+
+static void rpc_port_stub_lem_destroy(rpc_port_stub_lem_h handle)
+{
+ if (handle == nullptr)
+ return;
+
+ if (g_rec_mutex_trylock(&handle->mutex))
+ g_rec_mutex_unlock(&handle->mutex);
+
+ g_rec_mutex_clear(&handle->mutex);
+
+ if (handle->connected_queue)
+ g_queue_free_full(handle->connected_queue, (GDestroyNotify)rpc_port_stub_lem_data_destroy);
+
+ if (handle->disconnected_queue)
+ g_queue_free_full(handle->disconnected_queue, (GDestroyNotify)rpc_port_stub_lem_data_destroy);
+
+ if (handle->received_queue)
+ g_queue_free_full(handle->received_queue, (GDestroyNotify)rpc_port_stub_lem_data_destroy);
+
+ if (handle->port_name)
+ free(handle->port_name);
+
+ free(handle);
+}
+
+static rpc_port_stub_lem_h rpc_port_stub_lem_create(const char *port_name, rpc_port_stub_lem_event_s* callback)
+{
+ rpc_port_stub_lem_h handle;
+
+ if (port_name == nullptr || callback == nullptr) {
+ _E("Invalid parameter");
+ return nullptr;
+ }
+
+ handle = (rpc_port_stub_lem_h)calloc(1, sizeof(rpc_port_stub_lem_s));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return nullptr;
+ }
+
+ g_rec_mutex_init(&handle->mutex);
+ handle->port_name = strdup(port_name);
+ if (handle->port_name == nullptr) {
+ _E("strdup() is failed");
+ rpc_port_stub_lem_destroy(handle);
+ return nullptr;
+ }
+
+ handle->connected_queue = g_queue_new();
+ if (handle->connected_queue == nullptr) {
+ _E("g_queue_new() is failed");
+ rpc_port_stub_lem_destroy(handle);
+ return nullptr;
+ }
+
+ handle->disconnected_queue = g_queue_new();
+ if (handle->disconnected_queue == nullptr) {
+ _E("g_queue_new() is failed");
+ rpc_port_stub_lem_destroy(handle);
+ return nullptr;
+ }
+
+ handle->received_queue = g_queue_new();
+ if (handle->received_queue == nullptr) {
+ _E("g_queue_new() is failed");
+ rpc_port_stub_lem_destroy(handle);
+ return nullptr;
+ }
+
+ handle->callback = *callback;
+ rpc_port_stub_lem_load_symbols(handle);
+
+ return handle;
+}
+
+static void rpc_port_stub_lem_connect(rpc_port_stub_lem_h handle, void *context, bool sync)
+{
+ if (handle == nullptr || context == nullptr)
+ return;
+
+ if (handle->connect_func)
+ handle->connect_func(context, sync);
+}
+
+static void rpc_port_stub_lem_disconnect(rpc_port_stub_lem_h handle, void *context)
+{
+ if (handle == nullptr || context == nullptr)
+ return;
+
+ if (handle->disconnect_func)
+ handle->disconnect_func(context);
+}
+
+static void rpc_port_stub_lem_send_result(rpc_port_stub_lem_h handle, void *context, rpc_port_parcel_h parcel)
+{
+ if (handle == nullptr || context == nullptr || parcel == nullptr)
+ return;
+
+ if (handle->send_result_func)
+ handle->send_result_func(context, parcel);
+}
+
+#ifdef TIDL_USE_DELEGATE
+static void rpc_port_stub_lem_invoke_callback(rpc_port_stub_lem_h handle, void *context, rpc_port_parcel_h parcel)
+{
+ if (handle == nullptr || context == nullptr || parcel == nullptr)
+ return;
+
+ if (handle->invoke_callback_func)
+ handle->invoke_callback_func(context, parcel);
+}
+#endif
+
+static void rpc_port_stub_lem_set_listening(rpc_port_stub_lem_h handle, bool listening)
+{
+ if (handle == nullptr)
+ return;
+
+ g_rec_mutex_lock(&handle->mutex);
+ handle->listening = listening;
+ g_rec_mutex_unlock(&handle->mutex);
+}
+
+static bool rpc_port_stub_lem_is_listening(rpc_port_stub_lem_h handle)
+{
+ bool ret;
+
+ if (handle == nullptr)
+ return false;
+
+ g_rec_mutex_lock(&handle->mutex);
+ ret = handle->listening;
+ g_rec_mutex_unlock(&handle->mutex);
+ return ret;
+}
+
+static void rpc_port_stub_lem_connected_data_push(rpc_port_stub_lem_h handle, rpc_port_stub_lem_data_h data)
+{
+ if (handle == nullptr || data == nullptr)
+ return;
+
+ g_rec_mutex_lock(&handle->mutex);
+ g_queue_push_tail(handle->connected_queue, data);
+ g_rec_mutex_unlock(&handle->mutex);
+}
+
+static rpc_port_stub_lem_data_h rpc_port_stub_lem_connected_data_pop(rpc_port_stub_lem_h handle)
+{
+ rpc_port_stub_lem_data_h data;
+
+ if (handle == nullptr)
+ return nullptr;
+
+ g_rec_mutex_lock(&handle->mutex);
+ data = (rpc_port_stub_lem_data_h)g_queue_pop_head(handle->connected_queue);
+ g_rec_mutex_unlock(&handle->mutex);
+
+ return data;
+}
+
+static void rpc_port_stub_lem_disconnected_data_push(rpc_port_stub_lem_h handle, rpc_port_stub_lem_data_h data)
+{
+ if (handle == nullptr || data == nullptr)
+ return;
+
+ g_rec_mutex_lock(&handle->mutex);
+ g_queue_push_tail(handle->disconnected_queue, data);
+ g_rec_mutex_unlock(&handle->mutex);
+}
+
+static rpc_port_stub_lem_data_h rpc_port_stub_lem_disconnected_data_pop(rpc_port_stub_lem_h handle)
+{
+ rpc_port_stub_lem_data_h data;
+
+ if (handle == nullptr)
+ return nullptr;
+
+ g_rec_mutex_lock(&handle->mutex);
+ data = (rpc_port_stub_lem_data_h)g_queue_pop_head(handle->disconnected_queue);
+ g_rec_mutex_unlock(&handle->mutex);
+
+ return data;
+}
+
+static void rpc_port_stub_lem_received_data_push(rpc_port_stub_lem_h handle, rpc_port_stub_lem_data_h data)
+{
+ if (handle == nullptr || data == nullptr)
+ return;
+
+ g_rec_mutex_lock(&handle->mutex);
+ g_queue_push_tail(handle->received_queue, data);
+ g_rec_mutex_unlock(&handle->mutex);
+}
+
+static rpc_port_stub_lem_data_h rpc_port_stub_lem_received_data_pop(rpc_port_stub_lem_h handle)
+{
+ rpc_port_stub_lem_data_h data;
+
+ if (handle == nullptr)
+ return nullptr;
+
+ g_rec_mutex_lock(&handle->mutex);
+ data = (rpc_port_stub_lem_data_h)g_queue_pop_head(handle->received_queue);
+ g_rec_mutex_unlock(&handle->mutex);
+
+ return data;
+}
+
+static gboolean rpc_port_stub_lem_on_connected(gpointer user_data)
+{
+ rpc_port_stub_lem_h handle = (rpc_port_stub_lem_h)user_data;
+ rpc_port_stub_lem_data_h data;
+
+ g_rec_mutex_lock(&handle->mutex);
+ data = rpc_port_stub_lem_connected_data_pop(handle);
+ if (handle->callback.connected)
+ handle->callback.connected(data->context, data->sender, data->instance, data->sync);
+
+ rpc_port_stub_lem_data_destroy(data);
+ g_rec_mutex_unlock(&handle->mutex);
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean rpc_port_stub_lem_on_disconnected(gpointer user_data)
+{
+ rpc_port_stub_lem_h handle = (rpc_port_stub_lem_h)user_data;
+ rpc_port_stub_lem_data_h data;
+
+ g_rec_mutex_lock(&handle->mutex);
+ data = rpc_port_stub_lem_disconnected_data_pop(handle);
+ if (handle->callback.disconnected)
+ handle->callback.disconnected(data->context, data->sender, data->instance);
+
+ rpc_port_stub_lem_data_destroy(data);
+ g_rec_mutex_unlock(&handle->mutex);
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean rpc_port_stub_lem_on_received(gpointer user_data)
+{
+ rpc_port_stub_lem_h handle = (rpc_port_stub_lem_h)user_data;
+ rpc_port_stub_lem_data_h data;
+
+ g_rec_mutex_lock(&handle->mutex);
+ data = rpc_port_stub_lem_received_data_pop(handle);
+ if (handle->callback.received)
+ handle->callback.received(data->context, data->sender, data->instance, data->parcel);
+
+ rpc_port_stub_lem_data_destroy(data);
+ g_rec_mutex_unlock(&handle->mutex);
+ return G_SOURCE_REMOVE;
+}
+)__c_cb";
+
+/**
+ * <INPUT_FILE> The input file name.
+ * <IFACE_NAME> The interface name.
+ */
+constexpr const char CB_LEM_API[] =
+R"__c_cb(
+EXPORT_API int rpc_port_stub_<INPUT_FILE>_lem_<IFACE_NAME>_connect(void *context, const char *sender, const char *instance, bool sync)
+{
+ rpc_port_stub_lem_h handle = __<IFACE_NAME>_context;
+ rpc_port_stub_lem_data_h data;
+
+ if (!rpc_port_stub_lem_is_listening(handle)) {
+ _E("Server is not ready");
+ return RPC_PORT_ERROR_IO_ERROR;
+ }
+
+ if (gettid() != getpid()) {
+ data = rpc_port_stub_lem_data_create(context, sender, instance, sync);
+ if (data == nullptr) {
+ _E("Ouf of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ rpc_port_stub_lem_connected_data_push(handle, data);
+ g_idle_add(rpc_port_stub_lem_on_connected, handle);
+ return RPC_PORT_ERROR_NONE;
+ }
+
+ if (handle->callback.connected)
+ handle->callback.connected(context, sender, instance, sync);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_stub_<INPUT_FILE>_lem_<IFACE_NAME>_disconnect(void *context, const char *sender, const char *instance)
+{
+ rpc_port_stub_lem_h handle = __<IFACE_NAME>_context;
+ rpc_port_stub_lem_data_h data;
+
+ if (!rpc_port_stub_lem_is_listening(handle)) {
+ _E("Server is not ready");
+ return RPC_PORT_ERROR_IO_ERROR;
+ }
+
+ if (gettid() != getpid()) {
+ data = rpc_port_stub_lem_data_create(context, sender, instance, false);
+ if (data == nullptr) {
+ _E("Ouf of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ rpc_port_stub_lem_disconnected_data_push(handle, data);
+ g_idle_add(rpc_port_stub_lem_on_disconnected, handle);
+ return RPC_PORT_ERROR_NONE;
+ }
+
+ if (handle->callback.disconnected)
+ handle->callback.disconnected(context, sender, instance);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_stub_<INPUT_FILE>_lem_<IFACE_NAME>_send(void *context, const char* sender, const char *instance, rpc_port_parcel_h parcel)
+{
+ rpc_port_stub_lem_h handle = __<IFACE_NAME>_context;
+ rpc_port_stub_lem_data_h data;
+
+ if (!rpc_port_stub_lem_is_listening(handle)) {
+ _E("Server is not ready");
+ return RPC_PORT_ERROR_IO_ERROR;
+ }
+
+ if (gettid() != getpid()) {
+ data = rpc_port_stub_lem_data_create_with_parcel(context, sender, instance, parcel);
+ if (data == nullptr) {
+ _E("Ouf of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ rpc_port_stub_lem_received_data_push(handle, data);
+ g_idle_add(rpc_port_stub_lem_on_received, handle);
+ return RPC_PORT_ERROR_NONE;
+ }
+
+ if (handle->callback.received)
+ handle->callback.received(context, sender, instance, parcel);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_STUB_BODY_GENERATOR_CB_HH_
diff --git a/idlc/gen/version2/c_stub_header_generator.cc b/idlc/gen/version2/c_stub_header_generator.cc
new file mode 100644
index 0000000..da089dc
--- /dev/null
+++ b/idlc/gen/version2/c_stub_header_generator.cc
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/c_stub_header_generator.hh"
+
+#include "idlc/gen/version2/c_stub_header_generator_cb.hh"
+
+namespace tidl {
+namespace version2 {
+
+CStubHeaderGenerator::CStubHeaderGenerator(std::shared_ptr<Document> doc)
+ : CHeaderGeneratorBase(doc) {}
+
+void CStubHeaderGenerator::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenPragmaOnce(stream);
+ GenIncludeDefaultHeaders(stream, false);
+ GenExplicitLinkageOpen(stream);
+ GenEnums(stream);
+ GenStructureHandles(stream);
+ GenRemoteExceptionHandle(stream);
+ GenInterfaceHandles(stream);
+ GenStructures(stream);
+ GenRemoteException(stream);
+ GenInterfaceCallbacks(stream);
+ GenInterfaces(stream);
+}
+
+void CStubHeaderGenerator::OnFiniGen(std::ofstream& stream) {
+ GenExplicitLinkageClose(stream);
+}
+
+void CStubHeaderGenerator::GenInterfaceHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceContextHandle(stream, iface);
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateHandle(stream, iface, *d);
+ }
+ }
+}
+
+// @see #CB_INTERFACE_CONTEXT_HANDLE
+void CStubHeaderGenerator::GenInterfaceContextHandle(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_CONTEXT_HANDLE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_DELEGATE_HANDLE
+void CStubHeaderGenerator::GenInterfaceDelegateHandle(std::ofstream& stream,
+ const Interface& iface,
+ const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_DELEGATE_HANDLE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<DELEGATE_NAME>", decl.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CStubHeaderGenerator::GenInterfaceCallbacks(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceCallbackBase(stream, iface);
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceMethodCallbackBase(stream, iface, *d);
+ }
+ }
+}
+
+// @see #CB_INTERFACE_CALLBACK_BASE
+void CStubHeaderGenerator::GenInterfaceCallbackBase(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_CALLBACK_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+std::string CStubHeaderGenerator::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_BASE
+void CStubHeaderGenerator::GenInterfaceMethodCallbackBase(
+ std::ofstream& stream, const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_BASE)
+ .Change("<RETURN_TYPE>",
+ GetReturnTypeString(decl.GetType(), iface.GetID()))
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<METHOD_NAME>", decl.GetID())
+ .Change("<METHOD_PARAMS>", GenMethodParams(iface, decl))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+void CStubHeaderGenerator::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CStubHeaderGenerator::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ GenInterfaceContextBase(stream, iface);
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateBase(stream, iface, *d);
+ }
+
+ GenInterfaceBase(stream, iface);
+}
+
+// @see #CB_INTERFACE_CONTEXT_BASE
+void CStubHeaderGenerator::GenInterfaceContextBase(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_CONTEXT_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+std::string CStubHeaderGenerator::GenDelegateParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params +=
+ GetParamTypeString(param_type.GetDirection(), type, iface) + p->GetID();
+ }
+
+ return params;
+}
+
+// @see #CB_INTERFACE_DELEGATE_BASE
+void CStubHeaderGenerator::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& iface,
+ const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_DELEGATE_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<DELEGATE_NAME>", decl.GetID())
+ .Change("<DELEGATE_PARAMS>", GenDelegateParams(iface, decl))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_DECL
+std::string CStubHeaderGenerator::GenMethodCallbackDecls(
+ const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string callback_code(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_DECL)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<METHOD_NAME>", d->GetID()));
+ code += RemoveLine(callback_code, 3);
+ }
+
+ return code;
+}
+
+// @see #CB_INTERFACE_BASE
+void CStubHeaderGenerator::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<METHOD_CALLBACK_DECLS>", GenMethodCallbackDecls(iface))
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/c_stub_header_generator.hh b/idlc/gen/version2/c_stub_header_generator.hh
new file mode 100644
index 0000000..05b57c0
--- /dev/null
+++ b/idlc/gen/version2/c_stub_header_generator.hh
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_STUB_HEADER_GENERATOR_HH_
+#define IDLC_GEN_VERSION2_C_STUB_HEADER_GENERATOR_HH_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/version2/c_header_generator_base.hh"
+
+namespace tidl {
+namespace version2 {
+
+class CStubHeaderGenerator : public CHeaderGeneratorBase {
+ public:
+ explicit CStubHeaderGenerator(std::shared_ptr<Document> doc);
+ virtual ~CStubHeaderGenerator() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenInterfaceHandles(std::ofstream& stream);
+ void GenInterfaceContextHandle(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateHandle(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+
+ void GenInterfaceCallbacks(std::ofstream& stream);
+ void GenInterfaceCallbackBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodCallbackBase(std::ofstream& stream,
+ const Interface& iface,
+ const Declaration& decl);
+
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+
+ void GenInterfaceContextBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+
+ std::string GenDelegateParams(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+ std::string GenMethodCallbackDecls(const Interface& iface);
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_STUB_HEADER_GENERATOR_HH_
diff --git a/idlc/gen/version2/c_stub_header_generator_cb.hh b/idlc/gen/version2/c_stub_header_generator_cb.hh
new file mode 100644
index 0000000..e98f2fc
--- /dev/null
+++ b/idlc/gen/version2/c_stub_header_generator_cb.hh
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_C_STUB_HEADER_GENERATOR_CB_HH_
+#define IDLC_GEN_VERSION2_C_STUB_HEADER_GENERATOR_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CONTEXT_HANDLE[] =
+R"__c_cb(
+/**
+ * @brief The <PREFIX>_<NAME>_context handle.
+ */
+typedef struct <PREFIX>_<NAME>_context_s *<PREFIX>_<NAME>_context_h;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CONTEXT_BASE[] =
+R"__c_cb(
+/**
+ * @brief Sets the tag to the context handle.
+ *
+ * @param[in] context The context handle
+ * @param[in] tag The tag
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_context_get_tag()
+ */
+int <PREFIX>_<NAME>_context_set_tag(<PREFIX>_<NAME>_context_h context, void *tag);
+
+/**
+ * @brief Gets the tag from the context handle.
+ *
+ * @param[in] context The context handle
+ * @param[out] tag The tag
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_context_set_tag()
+ */
+int <PREFIX>_<NAME>_context_get_tag(<PREFIX>_<NAME>_context_h context, void **tag);
+
+/**
+ * @brief Gets the sender ID from the context handle.
+ * @details The @a sender should be released using free().
+ *
+ * @param[in] context The context handle
+ * @param[out] sender The sender ID of the context handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <PREFIX>_<NAME>_context_get_sender(<PREFIX>_<NAME>_context_h context, char **sender);
+
+/**
+ * @brief Gets the instance ID from the context handle.
+ * @details The @a instance should be released using free().
+ *
+ * @param[in] context The context handle
+ * @param[out] instance The instance ID of the context handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <PREFIX>_<NAME>_context_get_instance(<PREFIX>_<NAME>_context_h context, char **instance);
+
+/**
+ * @brief Disconnects from the proxy.
+ *
+ * @param[in] context The context handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_context_disconnect(<PREFIX>_<NAME>_context_h context);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_HANDLE[] =
+R"__c_cb(
+/**
+ * @brief The <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s *<PREFIX>_<NAME>_<DELEGATE_NAME>_h;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate.
+ * <DELEGATE_PARAMS> The parameters of the callback function.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
+R"__c_cb(
+/**
+ * @brief Creates a <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[out] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_clone()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME>_<DELEGATE_NAME> should be released using
+ * the <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME>_<DELEGATE_NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone);
+
+/**
+ * @brief Gets the ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] id The ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id);
+
+/**
+ * @brief Gets the sequence ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] seq_id The Sequence ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id);
+
+/**
+ * @brief Checks whether the delegate is for one-time or not.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] once The flag, it's true, the handle is for one-time
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once);
+
+/**
+ * @brief Gets the tag from the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks The @a tag should be released using free().
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] tag The tag
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag);
+
+/**
+ * @brief Invokes the callback function of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[in] ...
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RPC_PORT_ERROR_IO_ERROR I/O error
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_invoke(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h<DELEGATE_PARAMS>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CALLBACK_BASE[] =
+R"__c_cb(
+/**
+ * @brief Called when the proxy is connected.
+ * @details The callback function is called when the proxy is connected to the stub.
+ *
+ * @param[in] context The context handle
+ * @param[in] user_data The user data passed from the registration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_create_cb)(<PREFIX>_<NAME>_context_h context, void *user_data);
+
+/**
+ * @brief Called when the proxy is disconnected.
+ * @details The callback function is called when the proxy is disconnected from the stub.
+ *
+ * @param[in] context The context handle
+ * @param[in] user_data The user data passed from the registration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_terminate_cb)(<PREFIX>_<NAME>_context_h context, void *user_data);
+
+/**
+ * @brief Called to get the proxy context once for each connected proxy.
+ *
+ * @param[in] context The context handle
+ * @param[in] user_data The user data passed from the registration function
+ * @return @c true to continue with the next iteration of the loop,
+ * otherwise @c false to break out of the loop
+ * @pre <PREFIX>_<NAME>_foreach_context() will invoke this callback.
+ * @see <PREFIX>_<NAME>_foreach_context()
+ */
+typedef bool (*<PREFIX>_<NAME>_context_cb)(<PREFIX>_<NAME>_context_h context, void *user_data);
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_BASE[] =
+R"__c_cb(
+/**
+ * @brief Called when the request of the proxy is delivered.
+ *
+ * @param[in] context The context handle
+ * @param[in] user_data The user data passed from the registration function
+ * @see #<PREFIX>_<NAME>_callback_s;
+ */
+typedef <RETURN_TYPE> (*<PREFIX>_<NAME>_<METHOD_NAME>_cb)(<PREFIX>_<NAME>_context_h context<METHOD_PARAMS>, void *user_data);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_CALLBACK_DECLS> The declarations of the method callback functions.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+/**
+ * @brief The structure type containing the set of callback functions for handling stub events.
+ * @details It is one of the input parameters of the <PREFIX>_<NAME>_register() function.
+ *
+ * @see <PREFIX>_<NAME>_create_cb
+ * @see <PREFIX>_<NAME>_terminate_cb
+ */
+typedef struct {
+ <PREFIX>_<NAME>_create_cb create; /**< This callback function is invoked when the proxy is connected. */
+ <PREFIX>_<NAME>_terminate_cb terminate; /**< This callback function is invoked when the proxy is disconnected. */
+ <METHOD_CALLBACK_DECLS>
+} <PREFIX>_<NAME>_callback_s;
+
+/**
+ * @brief Registers the set of the callback functions and the port.
+ * @details This function registers the set of the callback functions to handle stub events.
+ * And, the rpc_port_stub_listen() is called internally to handle events.
+ *
+ * @param[in] callback The set of callback functions to handle stub events
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RPC_PORT_ERROR_IO_ERROR I/O error
+ * @retval #RPC_PORT_ERROR_PERMISSION_DENIED Permission denied
+ * @see <PREFIX>_<NAME>_unregister()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+int <PREFIX>_<NAME>_register(<PREFIX>_<NAME>_callback_s *callback, void *user_data);
+
+/**
+ * @brief Unregisters the registered port.
+ */
+int <PREFIX>_<NAME>_unregister(void);
+
+/**
+ * @brief Retrieves the connected context handles.
+ *
+ * @param[in] callback The callback function
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_context_cb()
+ */
+int <PREFIX>_<NAME>_foreach_context(<PREFIX>_<NAME>_context_cb callback, void *user_data);
+
+/**
+ * @brief Gets the number of connected clients.
+ *
+ * @param[out] client_number The client number
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_get_client_number(unsigned int *client_number);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The name of the method of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_DECL[] =
+R"__c_cb(
+<PREFIX>_<NAME>_<METHOD_NAME>_cb <METHOD_NAME>; /**< This callback function is invoked when the <METHOD_NAME> request is delivered. */
+)__c_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_C_STUB_HEADER_GENERATOR_CB_HH_
diff --git a/idlc/gen/version2/cpp_generator_base.cc b/idlc/gen/version2/cpp_generator_base.cc
new file mode 100644
index 0000000..61f8b7a
--- /dev/null
+++ b/idlc/gen/version2/cpp_generator_base.cc
@@ -0,0 +1,1045 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/cpp_generator_base.hh"
+
+#include <sstream>
+#include <utility>
+#include <vector>
+
+#include "idlc/gen/version2/cpp_generator_base_cb.hh"
+
+namespace tidl {
+namespace version2 {
+namespace {
+
+bool IsObject(const BaseType& type) {
+ if (type.IsEnumType())
+ return false;
+
+ if (type.IsUserDefinedType() ||
+ type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr ||
+ type.ToString() == "string" ||
+ type.ToString() == "bundle" ||
+ type.ToString() == "file")
+ return true;
+
+ return false;
+}
+
+std::string GetBaseTypeName(const std::shared_ptr<Structure>& base) {
+ if (base->GetBase() != nullptr)
+ return GetBaseTypeName(base->GetBase()) + "::" + base->GetID();
+
+ return base->GetID();
+}
+
+} // namespace
+
+CppGeneratorBase::CppGeneratorBase(std::shared_ptr<Document> doc,
+ bool thread_enabled)
+ : Generator(std::move(doc)),
+ thread_enabled_(thread_enabled) {
+ type_map_ = {
+ {"char", "char"},
+ {"int", "int"},
+ {"short", "short"},
+ {"long", "long long"},
+ {"string", "std::string"},
+ {"bool", "bool"},
+ {"list", "std::list"},
+ {"float", "float"},
+ {"double", "double"},
+ {"file", "File"},
+ {"bundle", "Bundle"},
+ {"void", "void"},
+ {"array", "std::vector"},
+ {"map", "std::map"},
+ {"set", "std::set"},
+ };
+
+ parcel_type_map_ = {
+ {"char", "byte"},
+ {"int", "int32"},
+ {"short", "int16"},
+ {"long", "int64"},
+ {"string", "string"},
+ {"bool", "bool"},
+ {"float", "float"},
+ {"double", "double"},
+ {"bundle", "bundle"},
+ {"file", "string"},
+ };
+
+ type_init_map_ = {
+ {"char", "0"},
+ {"int", "0"},
+ {"short", "0"},
+ {"long", "0"},
+ {"bool", "false"},
+ {"float", "0.0f"},
+ {"double", "0.0"},
+ };
+
+ for (auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() != Block::TYPE_STRUCTURE)
+ continue;
+
+ auto& st = static_cast<const Structure&>(*block);
+ AddTypeName(st);
+ }
+}
+
+void CppGeneratorBase::AddTypeName(const Structure& st) {
+ std::string name = st.GetID();
+ std::string type_name;
+ if (st.GetBase() != nullptr)
+ type_name = GetBaseTypeName(st.GetBase()) + "::" + name;
+ else
+ type_name = name;
+
+ struct_types_[std::move(name)] = std::move(type_name);
+}
+
+void CppGeneratorBase::GenVersion(std::ofstream& stream) {
+ ReplaceAll(CB_VERSION)
+ .Change("<VERSION>", std::string(FULLVER))
+ .Transform([&](std::string code) { return RemoveLine(std::move(code)); })
+ .Out(stream);
+}
+
+void CppGeneratorBase::GenIncludeDefaultHeaders(std::ofstream& stream,
+ bool is_body) {
+ if (is_body)
+ stream << CB_BODY_HEADER;
+ else
+ stream << CB_HEADER;
+}
+
+void CppGeneratorBase::GenLogTag(std::ofstream& stream,
+ const std::string& log_tag) {
+ ReplaceAll(CB_LOG_TAG)
+ .Change("<LOG_TAG>", log_tag)
+ .Out(stream);
+}
+
+void CppGeneratorBase::GenLogDefinition(std::ofstream& stream) {
+ stream << CB_LOG_DEF;
+}
+
+void CppGeneratorBase::GenVersionDefinition(std::ofstream& stream) {
+ ReplaceAll(CB_TIDL_VERSION)
+ .Change("<VERSION>", std::string(FULLVER))
+ .Out(stream);
+ stream << NLine(1);
+}
+
+void CppGeneratorBase::GenExportAPI(std::ofstream& stream) {
+ stream << CB_EXPORT_API;
+ stream << NLine(1);
+}
+
+std::string CppGeneratorBase::GenExceptions() {
+ std::string code = CB_HEADER_UNIT_MAP_DEF;
+ code += std::string(CB_EXCEPTIONS);
+ return RemoveLine(code);
+}
+
+std::string CppGeneratorBase::GenParameters(const Elements& elms) {
+ bool first = true;
+ std::string code;
+ for (const auto& elm : elms) {
+ if (!first)
+ code += ", ";
+
+ code += ConvertTypeToString(elm->GetType()) + " " + elm->GetID();
+ first = false;
+ }
+
+ return code;
+}
+
+std::string CppGeneratorBase::GenMethodIds(const Interface& iface) {
+ int value = 2;
+ std::string code;
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_ENUM)
+ .Change("<NAME>", decl->GetID())
+ .Change("<VALUE>", std::to_string(value++));
+ code += NLine(1);
+ }
+
+ if (code.empty())
+ return code;
+
+ return RemoveLine(
+ std::string(ReplaceAll(CB_METHOD_IDS).Change("<IDS>", code)));
+}
+
+std::string CppGeneratorBase::GenDelegateIds(const Interface& iface) {
+ int value = 1;
+ std::string code;
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_ENUM)
+ .Change("<NAME>", decl->GetID())
+ .Change("<VALUE>", std::to_string(value++));
+ code += NLine(1);
+ }
+
+ if (code.empty())
+ return code;
+
+ return RemoveLine(
+ std::string(ReplaceAll(CB_DELEGATE_IDS).Change("<IDS>", code)));
+}
+
+std::string CppGeneratorBase::RemoveLine(std::string lines,
+ unsigned int line_num) {
+ std::stringstream ss(lines);
+ std::string result;
+ std::string line;
+ unsigned int line_count = 0;
+
+ while (std::getline(ss, line, '\n')) {
+ line_count++;
+ if (line_num == line_count)
+ continue;
+
+ result += Trim(line);
+ result += NLine(1);
+ }
+
+ return result;
+}
+
+std::string CppGeneratorBase::RemoveLastLine(std::string lines,
+ unsigned int line_num) {
+ std::stringstream ss(lines);
+ std::vector<std::string> tmp_lines;
+ std::string line;
+
+ while (std::getline(ss, line, '\n')) {
+ line = Trim(line);
+ line += NLine(1);
+ tmp_lines.push_back(line);
+ }
+
+ std::string result;
+ for (unsigned int i = 0; i < (tmp_lines.size() - line_num); ++i)
+ result += tmp_lines[i] + NLine(1);
+
+ return result;
+}
+
+std::string CppGeneratorBase::Tab(int cnt) {
+ return std::string(cnt * 2, ' ');
+}
+
+std::string CppGeneratorBase::NLine(int cnt) {
+ return std::string(cnt, '\n');
+}
+
+std::string CppGeneratorBase::ConvertTypeToString(const BaseType& type,
+ bool full_name) {
+ if (type.IsEnumType())
+ return GetEnumTypeString(type.ToString());
+
+ if (type.IsUserDefinedType()) {
+ if (IsDelegateType(type)) {
+ std::string name = type.ToString();
+ if (full_name)
+ name = GetInterfaceNameFromDelegate(type) + "::" + name;
+
+ return "std::unique_ptr<" + name + ">";
+ }
+
+ if (type.ToString() == "remote_exception")
+ return "RemoteException";
+
+ return type.ToString();
+ }
+
+ if (type.GetMetaType() != nullptr) {
+ return type_map_[type.ToString()] + "<" +
+ ConvertTypeToString(*(type.GetMetaType())) + ">";
+ }
+
+ if (type.GetKeyType() != nullptr && type.GetValueType() != nullptr) {
+ return type_map_[type.ToString()] + "<" +
+ ConvertTypeToString(*(type.GetKeyType())) + ", " +
+ ConvertTypeToString(*(type.GetValueType())) + ">";
+ }
+
+ return type_map_[type.ToString()];
+}
+
+std::string CppGeneratorBase::GetReturnType(const BaseType& type) {
+ if (IsObject(type))
+ return "const " + ConvertTypeToString(type) + "&";
+
+ return ConvertTypeToString(type);
+}
+
+std::string CppGeneratorBase::GetParameterType(const BaseType& type) {
+ return ConvertTypeToString(type);
+}
+
+std::string CppGeneratorBase::GetParameters(const Parameters& params) {
+ std::string code;
+ for (const auto& param : params) {
+ if (!code.empty())
+ code += ", ";
+
+ std::string ref;
+ auto direction = param->GetParameterType().GetDirection();
+ if (direction == ParameterType::Direction::OUT ||
+ direction == ParameterType::Direction::REF)
+ ref = "&";
+
+ code += ConvertTypeToString(param->GetParameterType().GetBaseType()) +
+ ref + " " + param->GetID();
+ }
+
+ return code;
+}
+
+std::string CppGeneratorBase::GenParameters(const Structure& st) {
+ std::string params;
+ if (st.GetBase() != nullptr)
+ params += GenParameters(*st.GetBase());
+
+ if (!params.empty())
+ params += ", ";
+
+ return params + GenParameters(st.GetElements());
+}
+
+std::string CppGeneratorBase::GenStructuresForHeader(bool use_file) {
+ std::string code(CB_HEADER_BUNDLE);
+ code += NLine(1);
+ if (use_file) {
+ code += CB_HEADER_FILE;
+ code += NLine(1);
+ }
+ for (auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() != Block::TYPE_STRUCTURE)
+ continue;
+
+ auto& st = static_cast<Structure&>(*block);
+ code += GenStructureForHeader(st) + NLine(1);
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppGeneratorBase::GenStructureForHeader(const Structure& st) {
+ std::string code;
+ std::string params = GenParameters(st);
+ if (params.empty()) {
+ if (st.GetBase() == nullptr) {
+ code = ReplaceAll(CB_HEADER_STRUCTURE_BASE_EMPTY)
+ .Change("<CLS_NAME>", st.GetID())
+ .Change("<ENUMS>\n", GenEnumerations(st.GetEnums()));
+ } else {
+ code = ReplaceAll(CB_HEADER_INHERITED_STRUCTURE_BASE_EMPTY)
+ .Change("<CLS_NAME>", st.GetID())
+ .Change("<BASE_CLS_NAME>", st.GetBase()->GetID())
+ .Change("<ENUMS>\n", GenEnumerations(st.GetEnums()));
+ }
+ } else {
+ if (st.GetBase() == nullptr) {
+ code = ReplaceAll(CB_HEADER_STRUCTURE_BASE)
+ .Change("<CLS_NAME>", st.GetID())
+ .Change("<PARAMS>", GenParameters(st.GetElements()))
+ .Change("<ENUMS>\n", GenEnumerations(st.GetEnums()))
+ .Change("<GETTER_SETTER>",
+ GenStructureGetterSetterForHeader(st.GetElements()))
+ .Change("<MEMBERS>\n",
+ GenStructureMembersForHeader(st.GetElements()));
+ } else {
+ code = ReplaceAll(CB_HEADER_INHERITED_STRUCTURE_BASE)
+ .Change("<CLS_NAME>", st.GetID())
+ .Change("<BASE_CLS_NAME>", st.GetBase()->GetID())
+ .Change("<PARAMS>", params)
+ .Change("<ENUMS>\n", GenEnumerations(st.GetEnums()))
+ .Change("<GETTER_SETTER>",
+ GenStructureGetterSetterForHeader(st.GetElements()))
+ .Change("<MEMBERS>\n",
+ GenStructureMembersForHeader(st.GetElements()));
+ }
+ }
+
+ return code;
+}
+
+std::string CppGeneratorBase::GenStructureGetterSetterForHeader(
+ const Elements& elms) {
+ std::string code;
+ for (auto& elm : elms) {
+ code += Tab(1);
+ code += ReplaceAll(CB_HEADER_STRUCTURE_GETTER_SETTER)
+ .Change("<RETURN_TYPE>", GetReturnType(elm->GetType()))
+ .Change("<NAME>", elm->GetID())
+ .Change("<PARAM_TYPE>", GetParameterType(elm->GetType()))
+ .Change("<PARAM_NAME>", elm->GetID());
+ }
+
+ return code;
+}
+
+std::string CppGeneratorBase::GenStructureMembersForHeader(
+ const Elements& elms) {
+ std::string code;
+ for (auto& elm : elms) {
+ code += Tab(1);
+ code += ReplaceAll(CB_HEADER_STRUCTURE_MEMBER)
+ .Change("<TYPE>", ConvertTypeToString(elm->GetType()))
+ .Change("<NAME>", elm->GetID());
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+std::string CppGeneratorBase::SmartIndent(const std::string& str) {
+ unsigned int inside_class = 0;
+ std::string indentation;
+ std::string code;
+ std::istringstream iss(str);
+ std::string line;
+ std::string previous_line;
+ bool is_access_modifier = false;
+ bool control_flow_statement_with_single_line = false;
+
+ while (std::getline(iss, line)) {
+ std::string trimmed_line = Trim(line);
+ if (trimmed_line.empty()) {
+ if (previous_line.empty() ||
+ (previous_line.find(',') != std::string::npos &&
+ previous_line.back() == ','))
+ continue;
+
+ code += trimmed_line + NLine(1);
+ previous_line = std::move(trimmed_line);
+ continue;
+ }
+
+ if (trimmed_line.find("class") != std::string::npos)
+ inside_class++;
+
+ if (previous_line.find("if (") != std::string::npos ||
+ previous_line.find("for (") != std::string::npos ||
+ previous_line.find("while (") != std::string::npos ||
+ previous_line.find("else") != std::string::npos) {
+ if (previous_line.find('{') == std::string::npos &&
+ previous_line.back() != ';')
+ control_flow_statement_with_single_line = true;
+ }
+
+ if (trimmed_line.find('{') != std::string::npos) {
+ control_flow_statement_with_single_line = false;
+ bool else_statement = false;
+ if (trimmed_line.find("} else {") != std::string::npos) {
+ else_statement = true;
+ indentation = indentation.substr(0, indentation.length() - 2);
+ }
+
+ code += indentation + trimmed_line + NLine(1);
+ if (else_statement)
+ indentation += Tab(1);
+
+ if (trimmed_line.find("namespace ") == std::string::npos &&
+ trimmed_line.find('}') == std::string::npos)
+ indentation += Tab(1);
+
+ previous_line = std::move(trimmed_line);
+ continue;
+ }
+
+ if (control_flow_statement_with_single_line)
+ indentation += Tab(1);
+
+ if (trimmed_line.find('}') != std::string::npos)
+ indentation = indentation.substr(0, indentation.length() - 2);
+
+ if (trimmed_line.find("};") != std::string::npos)
+ inside_class--;
+
+ if (inside_class != 0 &&
+ (trimmed_line.find("public:") != std::string::npos ||
+ trimmed_line.find("private:") != std::string::npos ||
+ trimmed_line.find("protected:") != std::string::npos))
+ is_access_modifier = true;
+
+ code += (is_access_modifier ?
+ indentation.substr(0, indentation.length() - 1) : indentation) +
+ trimmed_line + NLine(1);
+ is_access_modifier = false;
+ if (control_flow_statement_with_single_line) {
+ indentation = indentation.substr(0, indentation.length() - 2);
+ control_flow_statement_with_single_line = false;
+ }
+
+ previous_line = std::move(trimmed_line);
+ }
+
+ return code;
+}
+
+std::string CppGeneratorBase::Trim(std::string str) {
+ if (str.compare(0, 3, "/**") == 0 || str.compare(0, 2, " *") == 0 ||
+ str.compare(0, 3, " */") == 0 || str.compare(0, 3, "///") == 0)
+ return str;
+
+ auto first = str.find_first_not_of(" \t\r\n");
+ if (first == std::string::npos)
+ return "";
+
+ auto last = str.find_last_not_of(" \t\r\n");
+ return str.substr(first, (last - first + 1));
+}
+
+std::string CppGeneratorBase::GenStructures(bool use_file) {
+ std::string code(CB_BODY_BUNDLE);
+ if (use_file)
+ code += CB_BODY_FILE;
+
+ for (auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() == Block::Type::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*block);
+ code += GenStructure(st);
+ }
+ }
+
+ return code;
+}
+
+std::string CppGeneratorBase::GenStructure(const Structure& st) {
+ std::string params = GenParameters(st);
+ std::string code;
+ if (params.empty()) {
+ code = ReplaceAll(CB_BODY_STRUCTURE_BASE_EMPTY)
+ .Change("<CLS_NAME>", st.GetID());
+ } else {
+ if (st.GetBase() == nullptr) {
+ code =
+ ReplaceAll(CB_BODY_STRUCTURE_BASE)
+ .Change("<CLS_NAME>", st.GetID())
+ .Change("<PARAMS>", params)
+ .Change("<MEMBER_INIT>", GenStructureMemberInit(st.GetElements()))
+ .Change("<GETTER_SETTER>", GenStructureGetterSetter(st));
+ } else {
+ code =
+ ReplaceAll(CB_BODY_INHERITED_STRUCTURE_BASE)
+ .Change("<CLS_NAME>", st.GetID())
+ .Change("<BASE_CLS_NAME>", st.GetBase()->GetID())
+ .Change("<BASE_ARGS>", GenStructureBaseArgs(*st.GetBase()))
+ .Change("<PARAMS>", params)
+ .Change("<MEMBER_INIT>", GenStructureMemberInit(st.GetElements()))
+ .Change("<GETTER_SETTER>", GenStructureGetterSetter(st));
+ }
+ }
+
+ return code;
+}
+
+std::string CppGeneratorBase::GenStructureBaseArgs(const Structure& st) {
+ std::string code;
+ if (st.GetBase() != nullptr)
+ code += GenStructureBaseArgs(*st.GetBase());
+
+ if (!code.empty())
+ code += ", ";
+
+ return code + GenStructureBaseArgs(st.GetElements());
+}
+
+std::string CppGeneratorBase::GenStructureBaseArgs(const Elements& elms) {
+ std::string code;
+ for (auto& elm : elms) {
+ if (!code.empty())
+ code += ", ";
+
+ code += GetSetterValue(elm->GetType(), elm->GetID());
+ }
+
+ return code;
+}
+
+std::string CppGeneratorBase::GenStructureMemberInit(const Elements& elms) {
+ std::string code;
+ for (auto& elm : elms) {
+ if (!code.empty())
+ code += ", ";
+
+ code += ReplaceAll(CB_BODY_STRUCTURE_MEMBER_INIT)
+ .Change("<NAME>", elm->GetID())
+ .Change("<VALUE>", GetSetterValue(elm->GetType(), elm->GetID()));
+ }
+
+ return code;
+}
+
+std::string CppGeneratorBase::GenStructureGetterSetter(const Structure& st) {
+ std::string code;
+ for (auto& elm : st.GetElements()) {
+ code += ReplaceAll(CB_BODY_STRUCTURE_GETTER_SETTER)
+ .Change("<RETURN_TYPE>", GetReturnType(elm->GetType()))
+ .Change("<CLS_NAME>", st.GetID())
+ .Change("<NAME>", elm->GetID())
+ .Change("<PARAM_TYPE>", GetParameterType(elm->GetType()))
+ .Change("<PARAM_NAME>", elm->GetID())
+ .Change("<VALUE>", GetSetterValue(elm->GetType(), elm->GetID()));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppGeneratorBase::GetSetterValue(const BaseType& type,
+ const std::string& value) {
+ return IsObject(type) ? "std::move(" + value + ")" : value;
+}
+
+void CppGeneratorBase::InitUnitTypes(bool use_file) {
+ AddUnitType("int", BaseType("int", ""), "");
+ AddUnitType("bool", BaseType("bool", ""), "");
+ AddUnitType("string", BaseType("string", ""), "");
+ AddUnitType("bundle", BaseType("bundle", ""), "");
+ if (use_file)
+ AddUnitType("file", BaseType("file", ""), "");
+
+ AddUnitType("remote_exception", BaseType("remote_exception", "", true), "");
+
+ for (auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() == Block::TYPE_INTERFACE) {
+ auto& iface = static_cast<const Interface&>(*block);
+ for (const auto& e : iface.GetEnums()) {
+ std::string name = iface.GetID() + "." + e->GetID();
+ AddUnitType(name, BaseType(name, "", BaseType::UserType::ENUM),
+ iface.GetID());
+ }
+
+ for (const auto& decl : iface.GetDeclarations()) {
+ AddUnitType("delegate",
+ BaseType(iface.GetID() + "::CallbackBase", "", true),
+ iface.GetID());
+ if (decl->GetMethodType() == Declaration::MethodType::DELEGATE) {
+ AddUnitType(decl->GetID(), BaseType(decl->GetID(), "", true),
+ iface.GetID());
+ } else if (decl->GetMethodType() == Declaration::MethodType::SYNC) {
+ auto& type = decl->GetType();
+ AddUnitType(type.GetFullName(false), BaseType(type), iface.GetID());
+ }
+
+ for (const auto& param : decl->GetParameters()) {
+ auto& type = param->GetParameterType().GetBaseType();
+ if (type.IsEnumType()) continue;
+
+ AddUnitType(type.GetFullName(false), BaseType(type), iface.GetID());
+ }
+ }
+ } else if (block->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*block);
+ AddUnitType(st.GetID(), BaseType(st.GetID(), "", true), st.GetID());
+ for (const auto& e : st.GetEnums()) {
+ std::string name = st.GetID() + "." + e->GetID();
+ AddUnitType(name, BaseType(name, "", BaseType::UserType::ENUM),
+ st.GetID());
+ }
+
+ for (const auto& elm : st.GetElements()) {
+ auto& type = elm->GetType();
+ if (type.IsEnumType()) continue;
+
+ AddUnitType(type.GetFullName(false), BaseType(type), st.GetID());
+ }
+ }
+ }
+}
+
+std::string CppGeneratorBase::GetUnitTypeKey(std::string name,
+ const BaseType& type,
+ const std::string& block_id) {
+ if (type.GetMetaType() != nullptr) {
+ auto* meta_type = type.GetMetaType();
+ if (meta_type->IsEnumType() &&
+ meta_type->ToString().find('.') == std::string::npos) {
+ return type.ToString() + "<" + block_id + "." + meta_type->ToString() +
+ ">";
+ }
+ }
+
+ if (type.GetKeyType() != nullptr) {
+ std::string key = type.ToString() + "<";
+ auto* key_type = type.GetKeyType();
+ if (key_type->IsEnumType() &&
+ key_type->ToString().find('.') == std::string::npos)
+ key += block_id + "." + key_type->ToString();
+ else
+ key += key_type->ToString();
+
+ if (type.GetValueType() != nullptr) {
+ auto* value_type = type.GetValueType();
+ if (value_type->IsEnumType() &&
+ value_type->ToString().find('.') == std::string::npos)
+ key += ", " + block_id + "." + value_type->ToString();
+ else
+ key += ", " + value_type->ToString();
+ }
+
+ key += ">";
+ return key;
+ }
+
+ return name;
+}
+
+void CppGeneratorBase::AddUnitType(std::string name, BaseType type,
+ const std::string& block_id) {
+ if (type.GetMetaType() != nullptr) {
+ auto meta_type = type.GetMetaType();
+ if (!meta_type->IsEnumType()) {
+ AddUnitType(meta_type->GetFullName(false), BaseType(*meta_type),
+ block_id);
+ }
+ }
+
+ if (type.GetKeyType() != nullptr) {
+ auto key_type = type.GetKeyType();
+ if (!key_type->IsEnumType())
+ AddUnitType(key_type->GetFullName(false), BaseType(*key_type), block_id);
+
+ if (type.GetValueType() != nullptr) {
+ auto value_type = type.GetValueType();
+ if (!value_type->IsEnumType()) {
+ AddUnitType(value_type->GetFullName(false), BaseType(*value_type),
+ block_id);
+ }
+ }
+ }
+
+ name = GetUnitTypeKey(name, type, block_id);
+ unit_types_[std::move(name)] = std::move(type);
+}
+
+std::string CppGeneratorBase::GenUnitMap(bool use_file) {
+ InitUnitTypes(use_file);
+ std::string code = GenUnit();
+ code += ReplaceAll(CB_UNIT_MAP)
+ .Change("<UNIT_MAP_READ_WRITE>", GenUnitMapReadWrite());
+ code += GenUnitSerializerBodies();
+ return code;
+}
+
+std::string CppGeneratorBase::GetFullNameFromType(const BaseType& type) {
+ auto found = struct_types_.find(type.GetFullName(true));
+ if (found != struct_types_.end())
+ return found->second;
+
+ if (type.IsEnumType())
+ return "int";
+
+ if (IsDelegateType(type) ||
+ type.ToString().find("::CallbackBase") != std::string::npos)
+ return "delegate";
+
+ std::string name = type.GetFullName(true);
+ return GetEnumTypeString(name, true);
+}
+
+std::string CppGeneratorBase::GenUnitMapReadWrite() {
+ std::string code;
+ for (auto& iter : unit_types_) {
+ auto& param_type = iter.second;
+ code += ReplaceAll(CB_UNIT_MAP_READ_WRITE)
+ .Change("<TYPE>", GetFullNameFromType(param_type))
+ .Change("<PARAM_TYPE>", ConvertTypeToString(param_type, true));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppGeneratorBase::GenUnit() {
+ return std::string(
+ ReplaceAll(CB_UNIT)
+ .Change("<SERIALIZER>", GenUnitSerializerHeaders()));
+}
+
+std::string CppGeneratorBase::GenUnitSerializerHeaders() {
+ std::string code;
+ for (auto& iter : unit_types_) {
+ auto& type = iter.second;
+ code += ReplaceAll(CB_UNIT_SERIALIZER_HEADER)
+ .Change("<TYPE>", ConvertTypeToString(type, true));
+ }
+
+ return code;
+}
+
+std::string CppGeneratorBase::GenUnitSerializerBodies() {
+ std::string code;
+ for (auto& iter : unit_types_) {
+ auto& type = iter.second;
+ code += ReplaceAll(CB_UNIT_SERIALIZER_BODY)
+ .Change("<TYPE>", ConvertTypeToString(type, true))
+ .Change("<IMPL_SERIALIZER>\n", GenUnitImplSerializer(type))
+ .Change("<IMPL_DESERIALIZER>\n", GenUnitImplDeserializer(type));
+ }
+
+ return code;
+}
+
+std::string CppGeneratorBase::GenUnitImplSerializer(const BaseType& type) {
+ std::string code;
+ if (type.IsEnumType()) {
+ code = CB_UNIT_IMPL_SERIALIZER_ENUM;
+ } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ if (IsDelegateType(type)) {
+ code = CB_UNIT_IMPL_SERIALIZER_DELEGATE;
+ } else {
+ code = ReplaceAll(CB_UNIT_IMPL_SERIALIZER_USER_DEFINED)
+ .Change("<UNIT_MAP_WRITE>", GenUnitMapWrite(type));
+ }
+ } else if (type.ToString() == "string") {
+ code = CB_UNIT_IMPL_SERIALIZER_STRING;
+ } else if (type.ToString() == "bundle") {
+ code = CB_UNIT_IMPL_SERIALIZER_BUNDLE;
+ } else if (type.ToString() == "file") {
+ code = CB_UNIT_IMPL_SERIALIZER_FILE;
+ } else {
+ code = ReplaceAll(CB_UNIT_IMPL_SERIALIZER_BASE)
+ .Change("<PARCEL_TYPE>", GetParcelType(type));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppGeneratorBase::GenUnitMapBaseWrite(const Structure& st) {
+ std::string code;
+ if (st.GetBase() != nullptr)
+ code += GenUnitMapBaseWrite(*st.GetBase());
+
+ for (auto& elm : st.GetElements())
+ code += ReplaceAll(CB_UNIT_MAP_BASE_WRITE).Change("<NAME>", elm->GetID());
+
+ return code;
+}
+
+std::string CppGeneratorBase::GenUnitMapWrite(const BaseType& type) {
+ std::string code;
+ if (type.ToString().find("::CallbackBase") != std::string::npos) {
+ code = CB_UNIT_MAP_CALLBACKBASE_WRITE;
+ } else if (type.ToString() == "remote_exception") {
+ code = CB_UNIT_MAP_REMOTE_EXCEPTION_WRITE;
+ } else if (type.ToString() == "array") {
+ code = CB_UNIT_MAP_ARRAY_WRITE;
+ } else if (type.ToString() == "list") {
+ code = CB_UNIT_MAP_LIST_WRITE;
+ } else if (type.ToString() == "map") {
+ code = CB_UNIT_MAP_MAP_WRITE;
+ } else if (type.ToString() == "set") {
+ code = CB_UNIT_MAP_SET_WRITE;
+ } else {
+ for (auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*block);
+ if (st.GetID() == type.ToString()) {
+ code = GenUnitMapBaseWrite(st);
+ break;
+ }
+ }
+ }
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppGeneratorBase::GenUnitImplDeserializer(const BaseType& type) {
+ std::string code;
+ if (type.IsEnumType()) {
+ code = ReplaceAll(CB_UNIT_IMPL_DESERIALIZER_ENUM)
+ .Change("<TYPE>", ConvertTypeToString(type));
+ } else if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
+ type.GetKeyType() != nullptr) {
+ if (IsDelegateType(type)) {
+ code = ReplaceAll(CB_UNIT_IMPL_DESERIALIZER_DELEGATE)
+ .Change("<IFACE_NAME>", GetInterfaceNameFromDelegate(type));
+ } else {
+ code = ReplaceAll(CB_UNIT_IMPL_DESERIALIZER_USER_DEFINED)
+ .Change("<UNIT_MAP_READ>\n", GenUnitMapRead(type));
+ }
+ } else if (type.ToString() == "string") {
+ code = CB_UNIT_IMPL_DESERIALIZER_STRING;
+ } else if (type.ToString() == "bundle") {
+ code = CB_UNIT_IMPL_DESERIALIZER_BUNDLE;
+ } else if (type.ToString() == "file") {
+ code = CB_UNIT_IMPL_DESERIALIZER_FILE;
+ } else {
+ code = ReplaceAll(CB_UNIT_IMPL_DESERIALIZER_BASE)
+ .Change("<TYPE>", ConvertTypeToString(type))
+ .Change("<PARCEL_TYPE>", GetParcelType(type));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppGeneratorBase::GenUnitMapBaseRead(const Structure& st) {
+ std::string code;
+ if (st.GetBase() != nullptr)
+ code += GenUnitMapBaseRead(*st.GetBase());
+
+ for (auto& elm : st.GetElements()) {
+ code += ReplaceAll(CB_UNIT_MAP_BASE_READ)
+ .Change("<TYPE>", ConvertTypeToString(elm->GetType()))
+ .Change("<NAME>", elm->GetID());
+ }
+
+ return code;
+}
+
+std::string CppGeneratorBase::GenUnitMapRead(const BaseType& type) {
+ std::string code;
+ if (type.ToString().find("::CallbackBase") != std::string::npos) {
+ code = CB_UNIT_MAP_CALLBACKBASE_READ;
+ } else if (type.ToString() == "remote_exception") {
+ code = CB_UNIT_MAP_REMOTE_EXCEPTION_READ;
+ } else if (type.ToString() == "array") {
+ code = ReplaceAll(CB_UNIT_MAP_ARRAY_READ)
+ .Change("<TYPE>", ConvertTypeToString(*type.GetMetaType()));
+ } else if (type.ToString() == "list") {
+ code = ReplaceAll(CB_UNIT_MAP_LIST_READ)
+ .Change("<TYPE>", ConvertTypeToString(*type.GetMetaType()));
+ } else if (type.ToString() == "map") {
+ code = ReplaceAll(CB_UNIT_MAP_MAP_READ)
+ .Change("<KEY_TYPE>", ConvertTypeToString(*type.GetKeyType()))
+ .Change("<VALUE_TYPE>", ConvertTypeToString(*type.GetValueType()));
+ } else if (type.ToString() == "set") {
+ code = ReplaceAll(CB_UNIT_MAP_SET_READ)
+ .Change("<KEY_TYPE>", ConvertTypeToString(*type.GetMetaType()));
+ } else {
+ for (auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*block);
+ if (st.GetID() == type.ToString()) {
+ code = GenUnitMapBaseRead(st);
+ break;
+ }
+ }
+ }
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppGeneratorBase::GetParcelType(const BaseType& type) {
+ if (type.IsEnumType())
+ return "int32";
+
+ return parcel_type_map_[type.ToString()];
+}
+
+std::string CppGeneratorBase::GenPrivateSharing(const Parameter& param) {
+ std::string code;
+ auto& type = param.GetParameterType().GetBaseType();
+ if (BaseType::IsFile(&type)) {
+ if (type.GetMetaType() != nullptr) {
+ code = ReplaceAll(CB_PRIVATE_SHARING_ARRAY)
+ .Change("<NAME>", param.GetID());
+ } else {
+ code = ReplaceAll(CB_PRIVATE_SHARING)
+ .Change("<NAME>", param.GetID());
+ }
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppGeneratorBase::GetSettingInitValue(const BaseType& type) {
+ auto found = type_init_map_.find(type.ToString());
+ if (found == type_init_map_.end())
+ return {};
+
+ std::string code = " = " + found->second;
+ return code;
+}
+
+std::string CppGeneratorBase::GetClassNameFromEnumType(
+ const std::string& type) {
+ for (auto& block : GetDocument().GetBlocks()) {
+ for (const auto& e : block->GetEnums()) {
+ if (e->GetID() == type)
+ return block->GetID();
+ }
+ }
+
+ return {};
+}
+
+std::string CppGeneratorBase::GetEnumTypeString(const std::string& type,
+ bool use_underbar) {
+ std::string concatenated_char = use_underbar ? "_" : "::";
+ auto pos = type.find('.');
+ if (pos == std::string::npos) {
+ std::string cls_name = GetClassNameFromEnumType(type);
+ if (!cls_name.empty())
+ return cls_name + concatenated_char + type;
+
+ return type;
+ }
+
+ std::string block_id = type.substr(0, pos);
+ std::string type_id = type.substr(pos + 1, type.size() - (pos + 1));
+ return block_id + concatenated_char + type_id;
+}
+
+std::string CppGeneratorBase::GenEnumerations(const Enums& enums) {
+ std::string code;
+ for (const auto& e : enums) {
+ std::string enum_fields;
+ for (const auto& f : e->GetFields()) {
+ if (f->GetValue().empty())
+ enum_fields += f->GetID() + "," + NLine(1);
+ else
+ enum_fields += f->GetID() + " = " + f->GetValue() + "," + NLine(1);
+ }
+
+ code += ReplaceAll(CB_ENUM_BASE)
+ .Change("<NAME>", e->GetID())
+ .Change("<ENUMS>", enum_fields);
+ code += NLine(1);
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppGeneratorBase::GenRemoteException() {
+ return std::string(CB_BODY_REMOTE_EXCEPTION);
+}
+
+std::string CppGeneratorBase::GenRemoteExceptionForHeader() {
+ return std::string(CB_HEADER_REMOTE_EXCEPTION);
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/cpp_generator_base.hh b/idlc/gen/version2/cpp_generator_base.hh
new file mode 100644
index 0000000..4f5677a
--- /dev/null
+++ b/idlc/gen/version2/cpp_generator_base.hh
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CPP_GENERATOR_BASE_HH_
+#define IDLC_GEN_VERSION2_CPP_GENERATOR_BASE_HH_
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "idlc/ast/structure.h"
+#include "idlc/ast/type.h"
+#include "idlc/gen/generator.h"
+
+namespace tidl {
+namespace version2 {
+
+class CppGeneratorBase : public tidl::Generator {
+ public:
+ explicit CppGeneratorBase(std::shared_ptr<Document> doc,
+ bool thread_enabled = false);
+ virtual ~CppGeneratorBase() = default;
+
+ void GenVersion(std::ofstream& stream);
+ void GenIncludeDefaultHeaders(std::ofstream& stream, bool is_body = true);
+ void GenLogTag(std::ofstream& stream, const std::string& log_tag);
+ void GenLogDefinition(std::ofstream& stream);
+ void GenVersionDefinition(std::ofstream& stream);
+ void GenExportAPI(std::ofstream& stream);
+
+ std::string GenExceptions();
+ std::string GenStructuresForHeader(bool use_file = true);
+ std::string GenMethodIds(const Interface& iface);
+ std::string GenDelegateIds(const Interface& iface);
+ std::string GenParameters(const Elements& elms);
+ std::string RemoveLine(std::string lines, unsigned int line_num = 1);
+ std::string RemoveLastLine(std::string lines, unsigned int line_num = 1);
+ std::string Tab(int cnt);
+ std::string NLine(int cnt);
+ std::string Trim(std::string str);
+ std::string ConvertTypeToString(const BaseType& type, bool full_name = false);
+ std::string GetReturnType(const BaseType& type);
+ std::string GetParameterType(const BaseType& type);
+ std::string GetParameters(const Parameters& params);
+ std::string SmartIndent(const std::string& str);
+ std::string GenStructures(bool use_file = true);
+ std::string GetSetterValue(const BaseType& type, const std::string& value);
+ std::string GenUnitMap(bool use_file = true);
+ std::string GenPrivateSharing(const Parameter& param);
+ std::string GetSettingInitValue(const BaseType& type);
+ std::string GenEnumerations(const Enums& enums);
+ std::string GenRemoteException();
+ std::string GenRemoteExceptionForHeader();
+
+ private:
+ void AddTypeName(const Structure& st);
+ std::string GenParameters(const Structure& st);
+ std::string GenStructureForHeader(const Structure& st);
+ std::string GenStructureGetterSetterForHeader(const Elements& elms);
+ std::string GenStructureMembersForHeader(const Elements& elms);
+ std::string GenStructure(const Structure& st);
+ std::string GenStructureBaseArgs(const Structure& st);
+ std::string GenStructureBaseArgs(const Elements& elms);
+ std::string GenStructureMemberInit(const Elements& elms);
+ std::string GenStructureGetterSetter(const Structure& st);
+ void InitUnitTypes(bool use_file);
+ std::string GetUnitTypeKey(std::string name, const BaseType& type,
+ const std::string& block_id);
+ void AddUnitType(std::string name, BaseType type,
+ const std::string& block_id);
+ std::string GenUnitMapReadWrite();
+ std::string GenUnit();
+ std::string GenUnitSerializerHeaders();
+ std::string GenUnitSerializerBodies();
+ std::string GenUnitImplSerializer(const BaseType& type);
+ std::string GenUnitMapBaseWrite(const Structure& st);
+ std::string GenUnitMapWrite(const BaseType& type);
+ std::string GenUnitImplDeserializer(const BaseType& type);
+ std::string GenUnitMapBaseRead(const Structure& st);
+ std::string GenUnitMapRead(const BaseType& type);
+ std::string GetParcelType(const BaseType& type);
+ std::string GetFullNameFromType(const BaseType& type);
+ std::string GetClassNameFromEnumType(const std::string& type);
+ std::string GetEnumTypeString(const std::string& type,
+ bool use_underbar = false);
+
+ private:
+ bool thread_enabled_;
+ std::unordered_map<std::string, std::string> type_map_;
+ std::unordered_map<std::string, std::string> parcel_type_map_;
+ std::unordered_map<std::string, std::string> type_init_map_;
+ std::unordered_map<std::string, BaseType> unit_types_;
+ std::unordered_map<std::string, std::string> struct_types_;
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_CPP_GENERATOR_BASE_HH_
diff --git a/idlc/gen/version2/cpp_generator_base_cb.hh b/idlc/gen/version2/cpp_generator_base_cb.hh
new file mode 100644
index 0000000..aaeda07
--- /dev/null
+++ b/idlc/gen/version2/cpp_generator_base_cb.hh
@@ -0,0 +1,1040 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CPP_GENERATOR_BASE_CB_HH_
+#define IDLC_GEN_VERSION2_CPP_GENERATOR_BASE_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <VERSION> The version of TIDL compiler.
+ */
+constexpr const char CB_VERSION[] =
+R"__cpp_cb(
+/**
+ * Generated by tidlc <VERSION>.
+ */
+)__cpp_cb";
+
+constexpr const char CB_BODY_HEADER[] =
+R"__cpp_cb(
+#include <app_common.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libgen.h>
+#include <glib.h>
+#include <dlog.h>
+#include <dlfcn.h>
+#include <rpc-port.h>
+#include <rpc-port-parcel.h>
+#include <unistd.h>
+
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <stdexcept>
+#include <utility>
+#include <unordered_map>
+)__cpp_cb";
+
+constexpr const char CB_HEADER[] =
+R"__cpp_cb(
+#pragma once
+
+#include <bundle.h>
+#include <rpc-port-parcel.h>
+#include <rpc-port.h>
+
+#include <atomic>
+#include <functional>
+#include <list>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <set>
+#include <string>
+#include <vector>
+#include <unordered_map>
+#include <unordered_set>
+#include <queue>
+)__cpp_cb";
+
+/**
+ * <LOG_TAG> The log tag of dlog.
+ */
+constexpr const char CB_LOG_TAG[] =
+R"__cpp_cb(
+#undef LOG_TAG
+#define LOG_TAG "<LOG_TAG>"
+)__cpp_cb";
+
+constexpr const char CB_LOG_DEF[] =
+R"__cpp_cb(
+#undef _E
+#define _E(fmt, ...) dlog_print(DLOG_ERROR, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _W
+#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _I
+#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _D
+#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+)__cpp_cb";
+
+constexpr const char CB_TIDL_VERSION[] =
+R"__cpp_cb(
+#undef TIDL_VERSION
+#define TIDL_VERSION "<VERSION>"
+)__cpp_cb";
+
+constexpr const char CB_EXCEPTIONS[] =
+R"__cpp_cb(
+class Exception {};
+class NotConnectedSocketException : public Exception {};
+class InvalidProtocolException : public Exception {};
+class InvalidIOException : public Exception {};
+class PermissionDeniedException : public Exception {};
+class InvalidIDException : public Exception {};
+class InvalidArgumentException : public Exception {};
+class OutOfMemoryException : public Exception {};
+)__cpp_cb";
+
+constexpr const char CB_HEADER_REMOTE_EXCEPTION[] =
+R"__cpp_cb(
+class RemoteException : public Exception {
+ public:
+ RemoteException();
+ RemoteException(std::string message);
+ RemoteException(int cause, std::string message);
+
+ int GetCause() const;
+ const std::string& GetMessage() const;
+
+ private:
+ int cause_ = 0;
+ std::string message_;
+};
+)__cpp_cb";
+
+/**
+ * <FILE_NAMESPACE> The namespace of the file.
+ * <STRUCTURES> The definition of structures.
+ * <BASE_IMPL> The definition of base implementation.
+ * <INTERFACES> The definition of interfaces.
+ */
+constexpr const char CB_NAMESPACE_PROXY[] =
+R"__cpp_cb(
+namespace rpc_port {
+namespace <FILE_NAMESPACE> {
+
+<STRUCTURES>
+
+namespace proxy {
+
+<BASE_IMPL>
+<INTERFACES>
+
+} // namespace proxy
+} // namespace <FILE_NAMESPACE>
+} // namespace rpc_port
+)__cpp_cb";
+
+/**
+ * <FILE_NAMESPACE> The namespace of the file.
+ * <STRUCTURES> The definition of structures.
+ * <BASE_IMPL> The base implementation.
+ * <INTERFACES> The definition of interfaces.
+ */
+constexpr const char CB_NAMESPACE_STUB[] =
+R"__cpp_cb(
+namespace rpc_port {
+namespace <FILE_NAMESPACE> {
+
+<STRUCTURES>
+
+namespace stub {
+
+<BASE_IMPL>
+<INTERFACES>
+
+} // namespace stub
+} // namespace <FILE_NAMESPACE>
+} // namespace rpc_port
+)__cpp_cb";
+
+constexpr const char CB_HEADER_BUNDLE[] =
+R"__cpp_cb(
+class Bundle final {
+ public:
+ Bundle();
+ explicit Bundle(bundle* handle, bool copy = true, bool own = true);
+ Bundle(std::string raw);
+ ~Bundle();
+
+ Bundle(const Bundle& b);
+ Bundle& operator = (const Bundle& b);
+ Bundle(Bundle&& b) noexcept;
+ Bundle& operator = (Bundle&&) noexcept;
+
+ bundle* GetHandle() const;
+ bundle* Detach();
+
+ private:
+ bundle* handle_;
+ bool own_ = true;
+};
+)__cpp_cb";
+
+constexpr const char CB_HEADER_FILE[] =
+R"__cpp_cb(
+class File final {
+ public:
+ File(std::string filename = "");
+
+ const std::string& GetFileName() const;
+ int Share(rpc_port_h port);
+
+ private:
+ std::string filename_;
+};
+)__cpp_cb";
+
+constexpr const char CB_HEADER_UNIT_MAP_DEF[] =
+R"__cpp_cb(
+class UnitMap;
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the structure.
+ * <PARAMS> The parameters of the structure.
+ * <ENUMS> The enumerations of the structure.
+ * <GETTER_SETTER> The getters and setters.
+ * <MEMBERS> The member variables of the structure.
+ */
+constexpr const char CB_HEADER_STRUCTURE_BASE[] =
+R"__cpp_cb(
+class <CLS_NAME> {
+ public:
+ <ENUMS>
+ <CLS_NAME>();
+ <CLS_NAME>(<PARAMS>);
+ <GETTER_SETTER>
+ private:
+ <MEMBERS>
+};
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the structure.
+ * <BASE_CLS_NAME> The base class name of the structure.
+ * <PARAMS> The parameters of the structure.
+ * <ENUMS> The enumerations of the structure.
+ * <GETTER_SETTER> The getters and setters.
+ * <MEMBERS> The member variables of the structure.
+ */
+constexpr const char CB_HEADER_INHERITED_STRUCTURE_BASE[] =
+R"__cpp_cb(
+class <CLS_NAME> : public <BASE_CLS_NAME> {
+ public:
+ <ENUMS>
+ <CLS_NAME>();
+ <CLS_NAME>(<PARAMS>);
+ <GETTER_SETTER>
+ private:
+ <MEMBERS>
+};
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the structure.
+ * <ENUMS> The enumerations of the structure.
+ */
+constexpr const char CB_HEADER_STRUCTURE_BASE_EMPTY[] =
+R"__cpp_cb(
+class <CLS_NAME> {
+ public:
+ <ENUMS>
+ <CLS_NAME>();
+};
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the structure.
+ * <BASE_CLS_NAME> The base class name of the structure.
+ * <ENUMS> The enumerations of the structure.
+ */
+constexpr const char CB_HEADER_INHERITED_STRUCTURE_BASE_EMPTY[] =
+R"__cpp_cb(
+class <CLS_NAME> : public <BASE_CLS_NAME> {
+ public:
+ <ENUMS>
+ <CLS_NAME>();
+};
+)__cpp_cb";
+
+/**
+ * <NAME> The name of the enum.
+ * <ENUMS> The fields of the enumeration.
+ */
+constexpr const char CB_ENUM_BASE[] =
+R"__c_cb(
+enum class <NAME> : int {
+ <ENUMS>
+};
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the element.
+ * <NAME> The element name.
+ * <PARAM_TYPE> The parameter type of the element.
+ * <PARAM_NAME> The parameter name of the element.
+ */
+constexpr const char CB_HEADER_STRUCTURE_GETTER_SETTER[] =
+R"__cpp_cb(
+<RETURN_TYPE> Get<NAME>() const;
+void Set<NAME>(<PARAM_TYPE> <PARAM_NAME>);
+)__cpp_cb";
+
+/**
+ * <TYPE> The element type.
+ * <NAME> The element name.
+ */
+constexpr const char CB_HEADER_STRUCTURE_MEMBER[] = "<TYPE> <NAME>_;";
+
+/**
+ * <IDS> The enumeration of methods of the interface.
+ */
+constexpr const char CB_METHOD_IDS[] =
+R"__cpp_cb(
+enum class MethodId : int {
+ __Result = 0,
+ __Callback = 1,
+ <IDS>
+};
+)__cpp_cb";
+
+/**
+ * <IDS> The enumeration of delegates of the interface.
+ */
+constexpr const char CB_DELEGATE_IDS[] =
+R"__cpp_cb(
+enum class DelegateId : int {
+ <IDS>
+};
+)__cpp_cb";
+
+/**
+ * <NAME> The enumeration name.
+ * <VALUE> The enumeration value.
+ */
+constexpr const char CB_ENUM[] = "<NAME> = <VALUE>,";
+
+constexpr const char CB_BODY_BUNDLE[] =
+R"__cpp_cb(
+Bundle::Bundle() {
+ handle_ = bundle_create();
+ if (handle_ == nullptr)
+ throw new std::bad_alloc();
+}
+
+Bundle::Bundle(bundle* handle, bool copy, bool own) : handle_(handle), own_(own) {
+ if (handle == nullptr)
+ throw new std::invalid_argument("handle is nullptr");
+
+ if (copy) {
+ handle_ = bundle_dup(handle);
+ if (handle_ == nullptr)
+ throw new std::bad_alloc();
+ }
+}
+
+Bundle::Bundle(std::string raw) {
+ handle_ = bundle_decode(reinterpret_cast<const bundle_raw*>(raw.c_str()), raw.length());
+ if (handle_ == nullptr)
+ throw new std::bad_alloc();
+}
+
+Bundle::~Bundle() {
+ if (own_ && handle_)
+ bundle_free(handle_);
+}
+
+Bundle::Bundle(const Bundle& b) {
+ handle_ = bundle_dup(b.handle_);
+ if (handle_ == nullptr)
+ throw new std::bad_alloc();
+}
+
+Bundle& Bundle::operator = (const Bundle& b) {
+ if (this != &b) {
+ if (handle_ && own_)
+ bundle_free(handle_);
+
+ handle_ = bundle_dup(b.handle_);
+ if (handle_ == nullptr)
+ throw new std::bad_alloc();
+
+ own_ = true;
+ }
+
+ return *this;
+}
+
+Bundle::Bundle(Bundle&& b) noexcept {
+ handle_ = b.handle_;
+ b.handle_ = bundle_create();
+ own_ = b.own_;
+ b.own_ = true;
+}
+
+Bundle& Bundle::operator = (Bundle&& b) noexcept {
+ if (this != &b) {
+ if (handle_ && own_)
+ bundle_free(handle_);
+
+ handle_ = b.handle_;
+ b.handle_ = bundle_create();
+ own_ = b.own_;
+ }
+
+ return *this;
+}
+
+bundle* Bundle::GetHandle() const {
+ return handle_;
+}
+
+bundle* Bundle::Detach() {
+ bundle* handle = handle_;
+ handle_ = nullptr;
+ return handle;
+}
+)__cpp_cb";
+
+constexpr const char CB_BODY_FILE[] =
+R"__cpp_cb(
+File::File(std::string filename) : filename_(std::move(filename)) {}
+
+const std::string& File::GetFileName() const {
+ return filename_;
+}
+
+int File::Share(rpc_port_h port) {
+ int ret = rpc_port_set_private_sharing(port, filename_.c_str());
+ if (ret != RPC_PORT_ERROR_NONE)
+ _E("Failed to set private sharing. error(%d)", ret);
+
+ return ret;
+}
+)__cpp_cb";
+
+constexpr const char CB_BODY_REMOTE_EXCEPTION[] =
+R"__cpp_cb(
+RemoteException::RemoteException() {}
+
+RemoteException::RemoteException(std::string message) : message_(std::move(message)) {}
+
+RemoteException::RemoteException(int cause, std::string message) : cause_(cause), message_(std::move(message)) {}
+
+int RemoteException::GetCause() const {
+ return cause_;
+}
+
+const std::string& RemoteException::GetMessage() const {
+ return message_;
+}
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the structure.
+ * <PARAMS> The parameters of the structure.
+ * <GETTER_SETTER> The getters and setters.
+ * <MEMBERS> The member variables of the structure.
+ */
+constexpr const char CB_BODY_STRUCTURE_BASE[] =
+R"__cpp_cb(
+<CLS_NAME>::<CLS_NAME>() {}
+
+<CLS_NAME>::<CLS_NAME>(<PARAMS>) : <MEMBER_INIT> {}
+
+<GETTER_SETTER>
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the structure.
+ * <BASE_CLS_NAME> The base class name of the structure.
+ * <BASE_ARGS> The arguments of the base class.
+ * <PARAMS> The parameters of the structure.
+ * <GETTER_SETTER> The getters and setters.
+ * <MEMBERS> The member variables of the structure.
+ */
+constexpr const char CB_BODY_INHERITED_STRUCTURE_BASE[] =
+R"__cpp_cb(
+<CLS_NAME>::<CLS_NAME>() {}
+
+<CLS_NAME>::<CLS_NAME>(<PARAMS>) : <BASE_CLS_NAME>(<BASE_ARGS>), <MEMBER_INIT> {}
+
+<GETTER_SETTER>
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the structure.
+ */
+constexpr const char CB_BODY_STRUCTURE_BASE_EMPTY[] =
+R"__cpp_cb(
+<CLS_NAME>::<CLS_NAME>() {}
+)__cpp_cb";
+
+constexpr const char CB_BODY_STRUCTURE_MEMBER_INIT[] =
+"<NAME>_(<VALUE>)";
+
+/**
+ * <RETURN_TYPE> The return type of the element.
+ * <NAME> The element name.
+ * <PARAM_TYPE> The parameter type of the element.
+ * <PARAM_NAME> The parameter name of the element.
+ * <SET_VALUE> The setter value of the element.
+ */
+constexpr const char CB_BODY_STRUCTURE_GETTER_SETTER[] =
+R"__cpp_cb(
+<RETURN_TYPE> <CLS_NAME>::Get<NAME>() const {
+ return <NAME>_;
+}
+
+void <CLS_NAME>::Set<NAME>(<PARAM_TYPE> <PARAM_NAME>) {
+ <NAME>_ = <VALUE>;
+}
+)__cpp_cb";
+
+constexpr const char CB_UNIT[] =
+R"__cpp_cb(
+class Unit {
+ public:
+ Unit() {
+ rpc_port_parcel_create_without_header(&parcel_);
+ }
+
+ Unit(std::string name, std::string type) : name_(std::move(name)), type_(std::move(type)) {
+ rpc_port_parcel_create_without_header(&parcel_);
+ }
+
+ ~Unit() {
+ if (parcel_ != nullptr)
+ rpc_port_parcel_destroy(parcel_);
+ }
+
+ const std::string& GetName() const {
+ return name_;
+ }
+
+ void SetName(std::string name) {
+ name_ = std::move(name);
+ }
+
+ const std::string& GetType() const {
+ return type_;
+ }
+
+ void SetType(std::string type) {
+ type_ = std::move(type);
+ }
+
+ rpc_port_parcel_h GetParcel() const {
+ return parcel_;
+ }
+
+ void Serialize(rpc_port_parcel_h parcel) const {
+ rpc_port_parcel_write_string(parcel, GetName().c_str());
+ rpc_port_parcel_write_string(parcel, GetType().c_str());
+
+ void* raw = nullptr;
+ unsigned int size = 0;
+ rpc_port_parcel_get_raw(GetParcel(), &raw, &size);
+ rpc_port_parcel_write_array_count(parcel, size & INT_MAX);
+ rpc_port_parcel_burst_write(parcel, static_cast<unsigned char*>(raw), size);
+ }
+
+ void Deserialize(rpc_port_parcel_h parcel) {
+ char* name = nullptr;
+ rpc_port_parcel_read_string(parcel, &name);
+ if (name != nullptr) {
+ SetName(name);
+ free(name);
+ }
+
+ char* type = nullptr;
+ rpc_port_parcel_read_string(parcel, &type);
+ if (type != nullptr) {
+ SetType(type);
+ free(type);
+ }
+
+ int size = 0;
+ rpc_port_parcel_read_array_count(parcel, &size);
+ if (size == 0)
+ return;
+
+ unsigned char* raw = reinterpret_cast<unsigned char*>(malloc(size));
+ if (raw == nullptr) {
+ _E("malloc() is failed");
+ return;
+ }
+
+ rpc_port_parcel_burst_read(parcel, raw, size);
+ rpc_port_parcel_burst_write(GetParcel(), raw, size);
+ free(raw);
+ }
+
+ <SERIALIZER>
+
+ private:
+ std::string name_;
+ std::string type_;
+ rpc_port_parcel_h parcel_ = nullptr;
+};
+
+)__cpp_cb";
+
+/**
+ * <TYPE> The type name of the serializer.
+ */
+constexpr const char CB_UNIT_SERIALIZER_HEADER[] =
+R"__cpp_cb(
+void Write(const <TYPE>& value);
+void Read(<TYPE>& value);
+)__cpp_cb";
+
+/**
+ * <TYPE> The type name of the serializer.
+ * <IMPL_SERIALIZER> The implementation of the serializer.
+ * <IMPL_DESERIALIZER> The implementation of the deserializer.
+ */
+constexpr const char CB_UNIT_SERIALIZER_BODY[] =
+R"__cpp_cb(
+void Unit::Write(const <TYPE>& value) {
+ <IMPL_SERIALIZER>
+}
+
+void Unit::Read(<TYPE>& value) {
+ <IMPL_DESERIALIZER>
+}
+)__cpp_cb";
+
+/**
+ * <UNIT_MAP_WRITE> The implementation to write the data to the unit map.
+ */
+constexpr const char CB_UNIT_IMPL_SERIALIZER_USER_DEFINED[] =
+R"__cpp_cb(
+UnitMap unit_map;
+<UNIT_MAP_WRITE>
+unit_map.Serialize(GetParcel());
+)__cpp_cb";
+
+constexpr const char CB_UNIT_MAP_ARRAY_WRITE[] =
+R"__cpp_cb(
+unit_map.Write("size", static_cast<int>(value.size() & INT_MAX));
+
+for (size_t index = 0; index < value.size(); ++index)
+ unit_map.Write(std::to_string(index), value[index]);
+)__cpp_cb";
+
+constexpr const char CB_UNIT_MAP_LIST_WRITE[] =
+R"__cpp_cb(
+unit_map.Write("length", static_cast<int>(value.size() & INT_MAX));
+
+int index = 0;
+for (auto& data : value)
+ unit_map.Write(std::to_string(index++), data);
+)__cpp_cb";
+
+constexpr const char CB_UNIT_MAP_MAP_WRITE[] =
+R"__cpp_cb(
+unit_map.Write("size", static_cast<int>(value.size() & INT_MAX));
+
+int index = 0;
+for (auto& iter : value) {
+ auto& key = iter.first;
+ unit_map.Write("key-" + std::to_string(index), key);
+ auto& val = iter.second;
+ unit_map.Write("value-" + std::to_string(index++), val);
+}
+)__cpp_cb";
+
+constexpr const char CB_UNIT_MAP_SET_WRITE[] =
+R"__cpp_cb(
+unit_map.Write("size", static_cast<int>(value.size() & INT_MAX));
+
+int index = 0;
+for (auto& key : value)
+ unit_map.Write("key-" + std::to_string(index++), key);
+)__cpp_cb";
+
+/**
+ * <NAME> The name of the element of the value.
+ */
+constexpr const char CB_UNIT_MAP_BASE_WRITE[] =
+R"__cpp_cb(
+unit_map.Write("<NAME>", value.Get<NAME>());
+)__cpp_cb";
+
+constexpr const char CB_UNIT_MAP_CALLBACKBASE_WRITE[] =
+R"__cpp_cb(
+unit_map.Write("id", value.GetId());
+unit_map.Write("seq_id", value.GetSeqId());
+unit_map.Write("once", value.IsOnce());
+)__cpp_cb";
+
+constexpr const char CB_UNIT_MAP_REMOTE_EXCEPTION_WRITE[] =
+R"__cpp_cb(
+unit_map.Write("cause", value.GetCause());
+unit_map.Write("message", value.GetMessage());
+)__cpp_cb";
+
+constexpr const char CB_UNIT_IMPL_SERIALIZER_DELEGATE[] =
+R"__cpp_cb(
+UnitMap unit_map;
+unit_map.Write("id", value->GetId());
+unit_map.Write("seq_id", value->GetSeqId());
+unit_map.Write("once", value->IsOnce());
+unit_map.Serialize(GetParcel());
+)__cpp_cb";
+
+constexpr const char CB_UNIT_IMPL_SERIALIZER_BUNDLE[] =
+R"__cpp_cb(
+rpc_port_parcel_write_bundle(GetParcel(), value.GetHandle());
+)__cpp_cb";
+
+constexpr const char CB_UNIT_IMPL_SERIALIZER_STRING[] =
+R"__cpp_cb(
+rpc_port_parcel_write_string(GetParcel(), value.c_str());
+)__cpp_cb";
+
+constexpr const char CB_UNIT_IMPL_SERIALIZER_FILE[] =
+R"__cpp_cb(
+rpc_port_parcel_write_string(GetParcel(), value.GetFileName().c_str());
+)__cpp_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel type of the parameter.
+ */
+constexpr const char CB_UNIT_IMPL_SERIALIZER_BASE[] =
+R"__cpp_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(GetParcel(), value);
+)__cpp_cb";
+
+constexpr const char CB_UNIT_IMPL_SERIALIZER_ENUM[] =
+R"__cpp_cb(
+rpc_port_parcel_write_int32(GetParcel(), static_cast<int>(value));
+)__cpp_cb";
+
+/**
+ * <UNIT_MAP_READ> The implementation to read the data from the unit map.
+ */
+constexpr const char CB_UNIT_IMPL_DESERIALIZER_USER_DEFINED[] =
+R"__cpp_cb(
+UnitMap unit_map;
+unit_map.Deserialize(GetParcel());
+<UNIT_MAP_READ>
+)__cpp_cb";
+
+/**
+ * <TYPE> The type of the value of the array.
+ */
+constexpr const char CB_UNIT_MAP_ARRAY_READ[] =
+R"__cpp_cb(
+int tmp_size = 0;
+unit_map.Read("size", tmp_size);
+
+for (int index = 0; index < tmp_size; ++index) {
+ <TYPE> tmp_value;
+ unit_map.Read(std::to_string(index), tmp_value);
+ value.push_back(tmp_value);
+}
+)__cpp_cb";
+
+/**
+ * <TYPE> The type of the value of the list.
+ */
+constexpr const char CB_UNIT_MAP_LIST_READ[] =
+R"__cpp_cb(
+int tmp_length = 0;
+unit_map.Read("length", tmp_length);
+
+for (int index = 0; index < tmp_length; ++index) {
+ <TYPE> tmp_value;
+ unit_map.Read(std::to_string(index), tmp_value);
+ value.push_back(tmp_value);
+}
+)__cpp_cb";
+
+/**
+ * <KEY_TYPE> The type of the key of the map.
+ * <VALUE_TYPE> The type of the value of the map.
+ */
+constexpr const char CB_UNIT_MAP_MAP_READ[] =
+R"__cpp_cb(
+int tmp_size = 0;
+unit_map.Read("size", tmp_size);
+
+for (int index = 0; index < tmp_size; ++index) {
+ <KEY_TYPE> tmp_key;
+ unit_map.Read("key-" + std::to_string(index), tmp_key);
+ <VALUE_TYPE> tmp_value;
+ unit_map.Read("value-" + std::to_string(index), tmp_value);
+ value[tmp_key] = tmp_value;
+}
+)__cpp_cb";
+
+/**
+ * <KEY_TYPE> The type of the key of the map.
+ */
+constexpr const char CB_UNIT_MAP_SET_READ[] =
+R"__cpp_cb(
+int tmp_size = 0;
+unit_map.Read("size", tmp_size);
+
+for (int index = 0; index < tmp_size; ++index) {
+ <KEY_TYPE> tmp_key;
+ unit_map.Read("key-" + std::to_string(index), tmp_key);
+ value.insert(tmp_key);
+}
+)__cpp_cb";
+
+/**
+ * <NAME> The name of the element of the value.
+ */
+constexpr const char CB_UNIT_MAP_BASE_READ[] =
+R"__cpp_cb(
+<TYPE> tmp_<NAME>;
+unit_map.Read("<NAME>", tmp_<NAME>);
+value.Set<NAME>(tmp_<NAME>);
+)__cpp_cb";
+
+constexpr const char CB_UNIT_MAP_CALLBACKBASE_READ[] =
+R"__cpp_cb(
+int tmp_id = 0;
+unit_map.Read("id", tmp_id);
+value.SetId(tmp_id);
+
+int tmp_seq_id = 0;
+unit_map.Read("seq_id", tmp_seq_id);
+value.SetSeqId(tmp_seq_id);
+
+bool tmp_once = false;
+unit_map.Read("once", tmp_once);
+value.SetOnce(tmp_once);
+)__cpp_cb";
+
+constexpr const char CB_UNIT_MAP_REMOTE_EXCEPTION_READ[] =
+R"__cpp_cb(
+int tmp_cause = 0;
+unit_map.Read("cause", tmp_cause);
+
+std::string tmp_message;
+unit_map.Read("message", tmp_message);
+
+value = RemoteException(tmp_cause, std::move(tmp_message));
+)__cpp_cb";
+
+/**
+ * <IFACE_NAME> The interface name.
+ */
+constexpr const char CB_UNIT_IMPL_DESERIALIZER_DELEGATE[] =
+R"__cpp_cb(
+UnitMap unit_map;
+unit_map.Deserialize(GetParcel());
+
+int tmp_id = 0;
+unit_map.Read("id", tmp_id);
+value->SetId(tmp_id);
+
+int tmp_seq_id = 0;
+unit_map.Read("seq_id", tmp_seq_id);
+value->SetSeqId(tmp_seq_id);
+
+bool tmp_once = false;
+unit_map.Read("once", tmp_once);
+value->SetOnce(tmp_once);
+)__cpp_cb";
+
+constexpr const char CB_UNIT_IMPL_DESERIALIZER_BUNDLE[] =
+R"__cpp_cb(
+bundle* tmp_b = nullptr;
+rpc_port_parcel_read_bundle(GetParcel(), &tmp_b);
+value = Bundle(tmp_b, false, true);
+)__cpp_cb";
+
+constexpr const char CB_UNIT_IMPL_DESERIALIZER_STRING[] =
+R"__cpp_cb(
+char* tmp_str = nullptr;
+rpc_port_parcel_read_string(GetParcel(), &tmp_str);
+if (tmp_str != nullptr) {
+ value = std::string(tmp_str);
+ free(tmp_str);
+}
+)__cpp_cb";
+
+constexpr const char CB_UNIT_IMPL_DESERIALIZER_FILE[] =
+R"__cpp_cb(
+char* tmp_filename = nullptr;
+rpc_port_parcel_read_string(GetParcel(), &tmp_filename);
+if (tmp_filename != nullptr) {
+ value = File(tmp_filename);
+ free(tmp_filename);
+}
+)__cpp_cb";
+
+/**
+ * <TYPE> The type of the parameter.
+ * <PARCEL_TYPE> The type of the parcel type of the parameter.
+ */
+constexpr const char CB_UNIT_IMPL_DESERIALIZER_BASE[] =
+R"__cpp_cb(
+<TYPE> tmp_value;
+rpc_port_parcel_read_<PARCEL_TYPE>(GetParcel(), &tmp_value);
+value = tmp_value;
+)__cpp_cb";
+
+/**
+ * <TYPE> The type of the parameter.
+ */
+constexpr const char CB_UNIT_IMPL_DESERIALIZER_ENUM[] =
+R"__cpp_cb(
+int tmp_value;
+rpc_port_parcel_read_int32(GetParcel(), &tmp_value);
+value = static_cast<<TYPE>>(tmp_value);
+)__cpp_cb";
+
+/**
+ * <UNIT_MAP_READ_WRITE> The implementation of the method to read and write.
+ */
+constexpr const char CB_UNIT_MAP[] =
+R"__cpp_cb(
+class UnitMap {
+ public:
+ UnitMap() {}
+
+ void Clear() {
+ map_.clear();
+ }
+
+ size_t GetSize() const {
+ return map_.size();
+ }
+
+ void Insert(std::string name, std::shared_ptr<Unit> unit) {
+ map_[std::move(name)] = std::move(unit);
+ }
+
+ std::shared_ptr<Unit> Lookup(const std::string& name) const {
+ auto found = map_.find(name);
+ if (found == map_.end())
+ return nullptr;
+
+ return found->second;
+ }
+
+ void Serialize(rpc_port_parcel_h parcel) const {
+ rpc_port_parcel_write_array_count(parcel, GetSize() & INT_MAX);
+ for (auto& iter : map_) {
+ auto& unit = iter.second;
+ unit->Serialize(parcel);
+ }
+ }
+
+ void Deserialize(rpc_port_parcel_h parcel) {
+ int size = 0;
+ rpc_port_parcel_read_array_count(parcel, &size);
+ for (int i = 0; i < size; ++i) {
+ auto unit = std::make_shared<Unit>();
+ unit->Deserialize(parcel);
+ std::string name = unit->GetName();
+ Insert(std::move(name), std::move(unit));
+ }
+ }
+
+ <UNIT_MAP_READ_WRITE>
+
+ private:
+ std::unordered_map<std::string, std::shared_ptr<Unit>> map_;
+};
+)__cpp_cb";
+
+/**
+ * <PARAM_TYPE> The parameter type of the value.
+ * <TYPE> The type name of the value.
+ */
+constexpr const char CB_UNIT_MAP_READ_WRITE[] =
+R"__cpp_cb(
+void Read(const std::string& name, <PARAM_TYPE>& value) const {
+ auto unit = Lookup(name);
+ if (unit == nullptr) {
+ _E("Failed to find %s", name.c_str());
+ return;
+ }
+
+ if (unit->GetType().compare(0, strlen("<TYPE>"), "<TYPE>") != 0) {
+ _E("type(%s) is not <TYPE>", unit->GetType().c_str());
+ return;
+ }
+
+ unit->Read(value);
+}
+
+void Write(std::string name, const <PARAM_TYPE>& value) {
+ auto unit = std::make_shared<Unit>(name, "<TYPE>");
+ unit->Write(value);
+ Insert(std::move(name), std::move(unit));
+}
+)__cpp_cb";
+
+/**
+ * <NAME> The parameter name.
+ */
+constexpr const char CB_PRIVATE_SHARING[] =
+R"__cpp_cb(
+<NAME>.Share(port_);
+)__cpp_cb";
+
+/**
+ * <NAME> The parameter name.
+ */
+constexpr const char CB_PRIVATE_SHARING_ARRAY[] =
+R"__cpp_cb(
+{
+ std::vector<const char*> paths_;
+ for (auto& f : <NAME>)
+ paths_.push_back(f.GetFileName().c_str());
+
+ rpc_port_set_private_sharing_array(port_, paths_.data(), paths_.size());
+}
+)__cpp_cb";
+
+constexpr const char CB_EXPORT_API[] =
+R"__cpp_cb(
+#undef EXPORT_API
+#define EXPORT_API extern "C" __attribute__ ((visibility("default")))
+)__cpp_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_CPP_GENERATOR_BASE_CB_HH_
diff --git a/idlc/gen/version2/cpp_group_body_generator.cc b/idlc/gen/version2/cpp_group_body_generator.cc
new file mode 100644
index 0000000..7f1c5ab
--- /dev/null
+++ b/idlc/gen/version2/cpp_group_body_generator.cc
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/cpp_group_body_generator.hh"
+
+#include <utility>
+
+#include "idlc/gen/version2/cpp_group_body_generator_cb.hh"
+
+namespace tidl {
+namespace version2 {
+
+CppGroupBodyGenerator::CppGroupBodyGenerator(std::shared_ptr<Document> doc)
+ : CppGeneratorBase(std::move(doc)) {}
+
+void CppGroupBodyGenerator::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenHeader(stream);
+ GenLogTag(stream, "RPC_PORT_GROUP");
+ GenLogDefinition(stream);
+ GenVersionDefinition(stream);
+ GenNamespace(stream);
+}
+
+void CppGroupBodyGenerator::OnFiniGen(std::ofstream& stream) {}
+
+void CppGroupBodyGenerator::GenHeader(std::ofstream& stream) {
+ std::string key(".cc");
+ std::string header_file = FileName;
+ std::size_t found = header_file.rfind(key);
+ if (found != std::string::npos)
+ header_file.replace(found, key.length(), ".h");
+
+ ReplaceAll(CB_HEADER).Change("<HEADER_FILE>", header_file).Out(stream);
+}
+
+void CppGroupBodyGenerator::GenNamespace(std::ofstream& stream) {
+ ReplaceAll(CB_NAMESPACE)
+ .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
+ .Change("<STRUCTURES>", GenStructures(false))
+ .Change("<UNIT_MAP>", GenUnitMap(false))
+ .Change("<INTERFACES>", GenInterfaces())
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+}
+
+std::string CppGroupBodyGenerator::GenInterfaces() {
+ std::string code;
+ for (auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*block);
+ code += GenInterface(iface);
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppGroupBodyGenerator::GenInterface(const Interface& iface) {
+ return std::string(
+ ReplaceAll(CB_INTERFACE)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Change("<IMPL_DISPATCH_FUNC_INIT>\n",
+ GenInterfaceImplDispatchFuncInit(iface))
+ .Change("<IMPL_METHOD>", GenInterfaceMethod(iface))
+ .Change("<IMPL_DISPATCH_FUNC>", GenInterfaceImplDispatchFunc(iface)));
+}
+
+std::string CppGroupBodyGenerator::GenInterfaceImplDispatchFuncInit(
+ const Interface& iface) {
+ std::string code;
+ for (auto& decl : iface.GetDeclarations()) {
+ code += ReplaceAll(CB_INTERFACE_IMPL_DISPATCH_FUNC_INIT)
+ .Change("<NAME>", decl->GetID())
+ .Change("<CLS_NAME>", iface.GetID());
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppGroupBodyGenerator::GenInterfaceImplDispatchFunc(
+ const Interface& iface) {
+ std::string code;
+ for (auto& decl : iface.GetDeclarations()) {
+ code += ReplaceAll(CB_INTERFACE_DISPATCH_FUNC)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Change("<DESERIALIZE>", GenInterfaceImplDispatchFuncDeserialize(*decl))
+ .Change("<NAME>", decl->GetID())
+ .Change("<PARAMS>", GenInterfaceImplDispatchFuncParams(*decl));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppGroupBodyGenerator::GenInterfaceImplDispatchFuncDeserialize(
+ const Declaration& decl) {
+ std::string code;
+ for (auto& param : decl.GetParameters()) {
+ auto& type = param->GetParameterType().GetBaseType();
+ std::string str = std::string(
+ ReplaceAll(CB_INTERFACE_DISPATCH_FUNC_UNIT_MAP_READ)
+ .Change("<TYPE>", ConvertTypeToString(type))
+ .Change("<NAME>", param->GetID()));
+ code += RemoveLine(str);
+ }
+
+ return code;
+}
+
+std::string CppGroupBodyGenerator::GenInterfaceImplDispatchFuncParams(
+ const Declaration& decl) {
+ std::string code;
+ for (auto& param : decl.GetParameters()) {
+ if (!code.empty())
+ code += ", ";
+
+ code += param->GetID();
+ }
+
+ return code;
+}
+
+std::string CppGroupBodyGenerator::GenInterfaceMethod(const Interface& iface) {
+ std::string code;
+ for (auto& decl : iface.GetDeclarations()) {
+ code += ReplaceAll(CB_INTERFACE_METHOD)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Change("<NAME>", decl->GetID())
+ .Change("<PARAMS>", GetParameters(decl->GetParameters()))
+ .Change("<SERIALIZE>", GenInterfaceMethodSerialize(*decl));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppGroupBodyGenerator::GenInterfaceMethodSerialize(
+ const Declaration& decl) {
+ std::string code;
+ for (auto& param : decl.GetParameters()) {
+ code += ReplaceAll(CB_INTERFACE_METHOD_UNIT_MAP_WRITE)
+ .Change("<NAME>", param->GetID());
+ }
+
+ return RemoveLine(code);
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/cpp_group_body_generator.hh b/idlc/gen/version2/cpp_group_body_generator.hh
new file mode 100644
index 0000000..86a38c4
--- /dev/null
+++ b/idlc/gen/version2/cpp_group_body_generator.hh
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CPP_GROUP_BODY_GENERATOR_HH_
+#define IDLC_GEN_VERSION2_CPP_GROUP_BODY_GENERATOR_HH_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/version2/cpp_generator_base.hh"
+
+namespace tidl {
+namespace version2 {
+
+class CppGroupBodyGenerator : public CppGeneratorBase {
+ public:
+ explicit CppGroupBodyGenerator(std::shared_ptr<Document> doc);
+ virtual ~CppGroupBodyGenerator() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenHeader(std::ofstream& stream);
+ void GenNamespace(std::ofstream& stream);
+ std::string GenInterfaces();
+ std::string GenInterface(const Interface& iface);
+ std::string GenInterfaceImplDispatchFuncInit(const Interface& iface);
+ std::string GenInterfaceImplDispatchFunc(const Interface& iface);
+ std::string GenInterfaceImplDispatchFuncDeserialize(const Declaration& iface);
+ std::string GenInterfaceImplDispatchFuncParams(const Declaration& iface);
+ std::string GenInterfaceMethod(const Interface& iface);
+ std::string GenInterfaceMethodSerialize(const Declaration& decl);
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_CPP_GROUP_BODY_GENERATOR_HH_
diff --git a/idlc/gen/version2/cpp_group_body_generator_cb.hh b/idlc/gen/version2/cpp_group_body_generator_cb.hh
new file mode 100644
index 0000000..bd39a1b
--- /dev/null
+++ b/idlc/gen/version2/cpp_group_body_generator_cb.hh
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CPP_GROUP_BODY_GENERATOR_CB_HH_
+#define IDLC_GEN_VERSION2_CPP_GROUP_BODY_GENERATOR_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <HEADER_FILE> The header file name.
+ */
+constexpr const char CB_HEADER[] =
+R"__cpp_cb(
+#include "<HEADER_FILE>"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <dlog.h>
+
+#include <climits>
+)__cpp_cb";
+
+/**
+ * <FILE_NAMESPACE> The namespace of the file.
+ * <STRCUTURES> The implementation of structures.
+ * <UNIT_MAP> The implementation of unit map.
+ * <INTERFACES> The implementation of interfaces.
+ */
+constexpr const char CB_NAMESPACE[] =
+R"__cpp_cb(
+namespace rpc_port {
+namespace <FILE_NAMESPACE> {
+
+<STRUCTURES>
+namespace group {
+
+<UNIT_MAP>
+<INTERFACES>
+} // namespace group
+} // namespace <FILE_NAMESPACE>
+} // namespace rpc_port
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The interface name.
+ * <IMPL_DISPATCH_FUNC_INIT> The implementation of the initialization of dispatch funcs.
+ * <IMPL_DISPATCH_FUNC> The implementation of dispatch funcs of methods.
+ * <IMPL_METHOD> The implementation of methods.
+ */
+constexpr const char CB_INTERFACE[] =
+R"__cpp_cb(
+<CLS_NAME>::<CLS_NAME>(std::string sender_appid, bool is_system) : sender_appid_(std::move(sender_appid)), is_system_(is_system) {
+ dispatch_funcs_ = {
+ <IMPL_DISPATCH_FUNC_INIT>
+ };
+
+ Subscribe();
+}
+
+<CLS_NAME>::~<CLS_NAME>() { Unsubscribe(); }
+
+void <CLS_NAME>::Subscribe() {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ int ret = event_add_event_handler(GetEventName().c_str(), EventCb, this, &event_handler_);
+ if (ret != EVENT_ERROR_NONE) {
+ _E("Failed to register events. error(%d)", ret);
+ throw InvalidIOException();
+ }
+}
+
+void <CLS_NAME>::Unsubscribe() {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ if (event_handler_) {
+ event_remove_event_handler(event_handler_);
+ event_handler_ = nullptr;
+ }
+}
+
+bundle* <CLS_NAME>::GetBundleFromParcel(rpc_port_parcel_h parcel) {
+ void* raw = nullptr;
+ unsigned int size = 0;
+ int ret = rpc_port_parcel_get_raw(parcel, &raw, &size);
+ if (ret != RPC_PORT_ERROR_NONE)
+ return nullptr;
+
+ bundle* b = bundle_create();
+ if (b == nullptr)
+ return nullptr;
+
+ ret = bundle_add_byte(b, "TIDL_RAW", raw, size);
+ if (ret != BUNDLE_ERROR_NONE)
+ return nullptr;
+
+ return b;
+}
+
+rpc_port_parcel_h <CLS_NAME>::GetParcelFromBundle(bundle* b) {
+ void* raw = nullptr;
+ size_t size = 0;
+ int ret = bundle_get_byte(b, "TIDL_RAW", &raw, &size);
+ if (ret != BUNDLE_ERROR_NONE)
+ return nullptr;
+
+ rpc_port_parcel_h parcel;
+ ret = rpc_port_parcel_create_from_raw(&parcel, raw, static_cast<unsigned int>(size));
+ if (ret != RPC_PORT_ERROR_NONE)
+ return nullptr;
+
+ return parcel;
+}
+
+std::string <CLS_NAME>::GetEventName() {
+ if (is_system_)
+ return "tizen.system.event.tidl_iface_<CLS_NAME>";
+
+ return "event." + sender_appid_ + ".tidl_iface_<CLS_NAME>";
+}
+
+void <CLS_NAME>::EventCb(const char* event_name, bundle* event_data, void* user_data) {
+ auto* handle = static_cast<<CLS_NAME>*>(user_data);
+ rpc_port_parcel_h parcel = handle->GetParcelFromBundle(event_data);
+ if (parcel == nullptr) {
+ _E("Invalid bundle");
+ return;
+ }
+
+ UnitMap unit_map;
+ unit_map.Deserialize(parcel);
+ rpc_port_parcel_destroy(parcel);
+
+ int cmd = -1;
+ unit_map.Read("[METHOD]", cmd);
+
+ auto found = handle->dispatch_funcs_.find(cmd);
+ if (found == handle->dispatch_funcs_.end()) {
+ _E("Unknown command(%d)", cmd);
+ return;
+ }
+
+ auto& func = found->second;
+ func(unit_map);
+}
+
+<IMPL_METHOD>
+<IMPL_DISPATCH_FUNC>
+)__cpp_cb";
+
+/**
+ * <NAME> The method name of the interface.
+ * <CLS_NAME> The interface name.
+ */
+constexpr const char CB_INTERFACE_IMPL_DISPATCH_FUNC_INIT[] =
+R"__cpp_cb(
+{ static_cast<int>(MethodId::<NAME>), std::bind(&<CLS_NAME>::Dispatch<NAME>, this, std::placeholders::_1) },
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The interface name.
+ * <NAME> The method name.
+ * <DESERIALIZE> The deserialize parameters of the method.
+ * <PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_DISPATCH_FUNC[] =
+R"__cpp_cb(
+void <CLS_NAME>::Dispatch<NAME>(const UnitMap& unit_map) {
+ <DESERIALIZE>
+ On<NAME>(<PARAMS>);
+}
+)__cpp_cb";
+
+/**
+ * <TYPE> The parameter type.
+ * <NAME> The parameter name.
+ */
+constexpr const char CB_INTERFACE_DISPATCH_FUNC_UNIT_MAP_READ[] =
+R"__cpp_cb(
+<TYPE> <NAME>;
+unit_map.Read("<NAME>", <NAME>);
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The interface name.
+ * <NAME> The method name of the interface.
+ * <PARAMS> The parameters of the method.
+ * <SERIALIZE> The implmenetation of the serialization of parameters.
+ */
+constexpr const char CB_INTERFACE_METHOD[] =
+R"__cpp_cb(
+void <CLS_NAME>::<NAME>(<PARAMS>) {
+ UnitMap unit_map;
+ unit_map.Write("[METHOD]", static_cast<int>(MethodId::<NAME>));
+ <SERIALIZE>
+ rpc_port_parcel_h parcel = nullptr;
+ rpc_port_parcel_create(&parcel);
+ unit_map.Serialize(parcel);
+ bundle* b = GetBundleFromParcel(parcel);
+ rpc_port_parcel_destroy(parcel);
+ if (b == nullptr) {
+ _E("Failed to make bundle from parcel");
+ throw InvalidIOException();
+ }
+
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ int ret = event_publish_app_event(GetEventName().c_str(), b);
+ bundle_free(b);
+ if (ret != EVENT_ERROR_NONE) {
+ _E("Failed to publish event. error(%d)", ret);
+ throw InvalidIOException();
+ }
+}
+)__cpp_cb";
+
+/**
+ * <NAME> The parameter name.
+ */
+constexpr const char CB_INTERFACE_METHOD_UNIT_MAP_WRITE[] =
+R"__cpp_cb(
+unit_map.Write("<NAME>", <NAME>);
+)__cpp_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_CPP_GROUP_BODY_GENERATOR_CB_HH_
diff --git a/idlc/gen/version2/cpp_group_header_generator.cc b/idlc/gen/version2/cpp_group_header_generator.cc
new file mode 100644
index 0000000..b3798c0
--- /dev/null
+++ b/idlc/gen/version2/cpp_group_header_generator.cc
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/cpp_group_header_generator.hh"
+
+#include <utility>
+
+#include "idlc/gen/version2/cpp_group_header_generator_cb.hh"
+
+namespace tidl {
+namespace version2 {
+
+CppGroupHeaderGenerator::CppGroupHeaderGenerator(std::shared_ptr<Document> doc)
+ : CppGeneratorBase(std::move(doc)) {}
+
+void CppGroupHeaderGenerator::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ stream << CB_HEADER;
+ GenNamespace(stream);
+}
+
+void CppGroupHeaderGenerator::OnFiniGen(std::ofstream& stream) {}
+
+void CppGroupHeaderGenerator::GenNamespace(std::ofstream& stream) {
+ ReplaceAll(CB_NAMESPACE)
+ .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
+ .Change("<STRUCTURES>", GenStructuresForHeader(false))
+ .Change("<EXCEPTIONS>", GenExceptions())
+ .Change("<INTERFACES>", GenInterfaces())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+std::string CppGroupHeaderGenerator::GenInterfaces() {
+ std::string code;
+ for (auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() != Block::Type::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*block);
+ code += GenInterface(iface);
+ code += NLine(1);
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppGroupHeaderGenerator::GenInterface(const Interface& iface) {
+ return std::string(
+ ReplaceAll(CB_INTERFACE)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Change("<ENUMS>", GenEnumerations(iface.GetEnums()))
+ .Change("<PUBLIC_MEMBERS>", GenInterfacePublicMembers(iface))
+ .Change("<PRIVATE_MEMBERS>", GenInterfacePrivateMembers(iface)));
+}
+
+std::string CppGroupHeaderGenerator::GenInterfacePublicMembers(
+ const Interface& iface) {
+ std::string code;
+ for (auto& decl : iface.GetDeclarations()) {
+ code += ReplaceAll(CB_METHOD)
+ .Change("<NAME>", decl->GetID())
+ .Change("<PARAMS>", GetParameters(decl->GetParameters()));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppGroupHeaderGenerator::GenInterfacePrivateMembers(
+ const Interface& iface) {
+ std::string code = GenMethodIds(iface);
+ for (auto& decl : iface.GetDeclarations()) {
+ code += ReplaceAll(CB_DISPATCH_FUNC)
+ .Change("<NAME>", decl->GetID());
+ }
+
+ return code;
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/cpp_group_header_generator.hh b/idlc/gen/version2/cpp_group_header_generator.hh
new file mode 100644
index 0000000..4469f8f
--- /dev/null
+++ b/idlc/gen/version2/cpp_group_header_generator.hh
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CPP_GROUP_HEADER_GENERATOR_HH_
+#define IDLC_GEN_VERSION2_CPP_GROUP_HEADER_GENERATOR_HH_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/version2/cpp_generator_base.hh"
+
+namespace tidl {
+namespace version2 {
+
+class CppGroupHeaderGenerator : public CppGeneratorBase {
+ public:
+ explicit CppGroupHeaderGenerator(std::shared_ptr<Document> doc);
+ virtual ~CppGroupHeaderGenerator() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ std::string GenInterfaces();
+ std::string GenInterface(const Interface& iface);
+ std::string GenInterfacePublicMembers(const Interface& iface);
+ std::string GenInterfacePrivateMembers(const Interface& iface);
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_CPP_GROUP_HEADER_GENERATOR_HH_
diff --git a/idlc/gen/version2/cpp_group_header_generator_cb.hh b/idlc/gen/version2/cpp_group_header_generator_cb.hh
new file mode 100644
index 0000000..1312cc3
--- /dev/null
+++ b/idlc/gen/version2/cpp_group_header_generator_cb.hh
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CPP_GROUP_HEADER_GENERATOR_CB_HH_
+#define IDLC_GEN_VERSION2_CPP_GROUP_HEADER_GENERATOR_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+constexpr const char CB_HEADER[] =
+R"__cpp_cb(
+#pragma once
+
+#include <app_event.h>
+#include <bundle.h>
+#include <rpc-port-parcel.h>
+
+#include <atomic>
+#include <list>
+#include <functional>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <vector>
+#include <unordered_map>
+)__cpp_cb";
+
+/**
+ * <FILE_NAMESPACE> The namespace of the file.
+ * <STRCUTURES> The structure definitions.
+ * <EXCEPTIONS> The exceptions.
+ * <INTERFACES> The interface definitions.
+ */
+constexpr const char CB_NAMESPACE[] =
+R"__cpp_cb(
+namespace rpc_port {
+namespace <FILE_NAMESPACE> {
+
+<STRUCTURES>
+namespace group {
+
+<EXCEPTIONS>
+<INTERFACES>
+} // namespace group
+} // namespace <FILE_NAMESPACE>
+} // namespace rpc_port
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the interface.
+ * <PUBLIC_MEMBERS> The implementation of public members of the interface.
+ * <PRIVATE_MEMBERS> The implementation of private members of the interface.
+ */
+constexpr const char CB_INTERFACE[] =
+R"__cpp_cb(
+class <CLS_NAME> {
+ public:
+ <CLS_NAME>(std::string sender_appid, bool is_system = false);
+ virtual ~<CLS_NAME>();
+ <ENUMS>
+
+ <PUBLIC_MEMBERS>
+
+ private:
+ using DispatchFunc = std::function<void(const UnitMap& unit_map)>;
+
+ <PRIVATE_MEMBERS>
+
+ bundle* GetBundleFromParcel(rpc_port_parcel_h parcel);
+ rpc_port_parcel_h GetParcelFromBundle(bundle* b);
+ std::string GetEventName();
+ void Subscribe();
+ void Unsubscribe();
+ static void EventCb(const char* event_name, bundle* event_data, void* user_data);
+
+ private:
+ event_handler_h event_handler_ = nullptr;
+ std::string sender_appid_;
+ std::recursive_mutex mutex_;
+ bool is_system_;
+ std::unordered_map<int, DispatchFunc> dispatch_funcs_;
+};
+)__cpp_cb";
+
+/**
+ * <NAME> The method name.
+ * <PARAMS> The parameters of the method.
+ */
+constexpr const char CB_METHOD[] =
+R"__cpp_cb(
+void <NAME>(<PARAMS>);
+virtual void On<NAME>(<PARAMS>) {}
+)__cpp_cb";
+
+/**
+ * <NAME> The method name.
+ */
+constexpr const char CB_DISPATCH_FUNC[] =
+R"__cpp_cb(
+void Dispatch<NAME>(const UnitMap& unit_map);
+)__cpp_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_CPP_GROUP_HEADER_GENERATOR_CB_HH_
diff --git a/idlc/gen/version2/cpp_proxy_body_generator.cc b/idlc/gen/version2/cpp_proxy_body_generator.cc
new file mode 100644
index 0000000..ec24631
--- /dev/null
+++ b/idlc/gen/version2/cpp_proxy_body_generator.cc
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/cpp_proxy_body_generator.hh"
+
+#include <libgen.h>
+
+#include <utility>
+
+#include "idlc/gen/version2/cpp_generator_base_cb.hh"
+#include "idlc/gen/version2/cpp_proxy_body_generator_cb.hh"
+
+namespace tidl {
+namespace version2 {
+
+CppProxyBodyGenerator::CppProxyBodyGenerator(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options)
+ : CppGeneratorBase(std::move(doc)), options_(std::move(options)) {}
+
+void CppProxyBodyGenerator::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenIncludeProxyBodyHeader(stream);
+ GenIncludeDefaultHeaders(stream);
+ GenLogTag(stream, "RPC_PORT_PROXY");
+ GenLogDefinition(stream);
+ GenVersionDefinition(stream);
+ GenExportAPI(stream);
+ GenLemAnonymousNamespace(stream);
+ GenNamespace(stream);
+ GenLemAPI(stream);
+}
+
+void CppProxyBodyGenerator::OnFiniGen(std::ofstream& stream) {}
+
+void CppProxyBodyGenerator::GenIncludeProxyBodyHeader(std::ofstream& stream) {
+ std::string key(".cc");
+ std::string header_file = FileName;
+
+ auto found = header_file.rfind(key);
+ if (found != std::string::npos)
+ header_file.replace(found, key.length(), ".h");
+
+ ReplaceAll(CB_PROXY_BODY_HEADER)
+ .Change("<FILENAME>", header_file)
+ .Out(stream);
+}
+
+void CppProxyBodyGenerator::GenNamespace(std::ofstream& stream) {
+ ReplaceAll(CB_NAMESPACE_PROXY)
+ .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
+ .Change("<STRUCTURES>", GenLemBaseWithStructures())
+ .Change("<BASE_IMPL>", GenBaseImpl())
+ .Change("<INTERFACES>", GenInterfaces())
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+ stream << NLine(1);
+}
+
+void CppProxyBodyGenerator::GenLemAnonymousNamespace(std::ofstream& stream) {
+ stream << SmartIndent(CB_LEM_ANONYMOUS_NAMESPACE);
+ stream << NLine(1);
+}
+
+void CppProxyBodyGenerator::GenLemAPI(std::ofstream& stream) {
+ std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
+ input = input.substr(0, input.find_last_of("."));
+ std::string code = NLine(1);
+ for (const auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<Interface&>(*block);
+ code += ReplaceAll(CB_LEM_API)
+ .Change("<CLS_NAME>", iface.GetID())
+ .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
+ .ChangeToLower("<INPUT_FILE>", input);
+ code += NLine(1);
+ }
+
+ stream << SmartIndent(code);
+}
+
+std::string CppProxyBodyGenerator::GenLemBaseWithStructures() {
+ std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
+ input = input.substr(0, input.find_last_of("."));
+ std::string code;
+ code += ReplaceAll(CB_LEM_BASE).ChangeToLower("<INPUT_FILE>", input);
+ code += NLine(1);
+ code += GenStructures();
+ return code;
+}
+
+std::string CppProxyBodyGenerator::GenBaseImpl() {
+ std::string code = GenRemoteException();
+ code += GenUnitMap();
+ return code;
+}
+
+std::string CppProxyBodyGenerator::GenInterfaces() {
+ std::string code;
+ for (const auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<Interface&>(*block);
+ code += GenInterface(iface) + NLine(1);
+ }
+
+ return code;
+}
+
+std::string CppProxyBodyGenerator::GenInterface(const Interface& iface) {
+ return std::string(
+ ReplaceAll(CB_INTERFACE_BASE)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Change("<ENUMS>", GenEnumerations(iface.GetEnums()))
+ .Change("<CALLBACKS>", GenInterfaceCallbacks(iface))
+ .Change("<METHODS>", GenInterfaceMethods(iface)));
+}
+
+std::string CppProxyBodyGenerator::GenInterfaceCallbacks(
+ const Interface& iface) {
+ std::string code;
+ code += ReplaceAll(CB_INTERFACE_CALKBACBASE_BASE)
+ .Change("<IFACE_NAME>", iface.GetID());
+ code += NLine(1);
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_INTERFACE_CALLBACK)
+ .Change("<IFACE_NAME>", iface.GetID())
+ .Change("<CLS_NAME>", decl->GetID())
+ .Change("<PARAMS>", GetParameters(decl->GetParameters()))
+ .Change("<IMPL_RECEIVED_EVENT>\n",
+ GenInterfaceCallbackReceivedEvent(decl->GetParameters()));
+ code += NLine(1);
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppProxyBodyGenerator::GenInterfaceCallbackReceivedEvent(
+ const Parameters& params) {
+ std::string callback_params;
+ std::string code;
+ for (auto& param : params) {
+ auto& type = param->GetParameterType().GetBaseType();
+ code += ReplaceAll(CB_INTERFACE_CALLBACK_UNIT_MAP_READ)
+ .Change("<TYPE>", ConvertTypeToString(type))
+ .Change("<NAME>", param->GetID());
+
+ if (!callback_params.empty())
+ callback_params += ", ";
+
+ callback_params += param->GetID() + "_";
+ }
+
+ code += ReplaceAll(CB_INTERFACE_CALLBACK_INVOKE)
+ .Change("<PARAMS>", callback_params);
+
+ return RemoveLine(code);
+}
+
+std::string CppProxyBodyGenerator::GenInterfaceMethods(const Interface& iface) {
+ std::string code;
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() == Declaration::MethodType::DELEGATE) continue;
+
+ code += GenInterfaceMethod(iface, *decl);
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppProxyBodyGenerator::GenInterfaceMethod(const Interface& iface,
+ const Declaration& decl) {
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
+ return std::string(
+ ReplaceAll(CB_INTERFACE_METHOD_ASYNC_BASE)
+ .Change("<IFACE_NAME>", iface.GetID())
+ .Change("<NAME>", decl.GetID())
+ .Change("<PARAMS>", GetParameters(decl.GetParameters()))
+ .Change("<SERIALIZE>", GenInterfaceMethodSerialize(decl)));
+ }
+
+ return std::string(
+ ReplaceAll(CB_INTERFACE_METHOD_BASE)
+ .Change("<RETURN_TYPE>", ConvertTypeToString(decl.GetType()))
+ .Change("<SET_INIT_VALUE>", GetSettingInitValue(decl.GetType()))
+ .Change("<IFACE_NAME>", iface.GetID())
+ .Change("<NAME>", decl.GetID())
+ .Change("<PARAMS>", GetParameters(decl.GetParameters()))
+ .Change("<SERIALIZE>", GenInterfaceMethodSerialize(decl))
+ .Change("<DESERIALIZE>", GenInterfaceMethodDeserialize(decl)));
+}
+
+std::string CppProxyBodyGenerator::GenInterfaceMethodSerialize(
+ const Declaration& decl) {
+ std::string code;
+ for (auto& param : decl.GetParameters()) {
+ if (param->GetParameterType().GetDirection() !=
+ ParameterType::Direction::IN)
+ continue;
+
+ code += ReplaceAll(CB_INTERFACE_METHOD_UNIT_MAP_WRITE)
+ .Change("<NAME>", param->GetID());
+ if (IsDelegateType(param->GetParameterType().GetBaseType())) {
+ code += ReplaceAll(CB_INTERFACE_METHOD_DELEGATE_INSERT)
+ .Change("<NAME>", param->GetID());
+ } else {
+ code += GenPrivateSharing(*param);
+ }
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppProxyBodyGenerator::GenInterfaceMethodDeserialize(
+ const Declaration& decl) {
+ std::string code;
+ for (auto& param : decl.GetParameters()) {
+ if (param->GetParameterType().GetDirection() ==
+ ParameterType::Direction::IN)
+ continue;
+
+ code += ReplaceAll(CB_INTERFACE_METHOD_UNIT_MAP_READ)
+ .Change("<NAME>", param->GetID());
+ }
+
+ return RemoveLine(code);
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/cpp_proxy_body_generator.hh b/idlc/gen/version2/cpp_proxy_body_generator.hh
new file mode 100644
index 0000000..d4c2099
--- /dev/null
+++ b/idlc/gen/version2/cpp_proxy_body_generator.hh
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CPP_PROXY_BODY_GENERATOR_HH_
+#define IDLC_GEN_VERSION2_CPP_PROXY_BODY_GENERATOR_HH_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/version2/cpp_generator_base.hh"
+#include "idlc/options.h"
+
+namespace tidl {
+namespace version2 {
+
+class CppProxyBodyGenerator : public CppGeneratorBase {
+ public:
+ explicit CppProxyBodyGenerator(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options);
+ virtual ~CppProxyBodyGenerator() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenIncludeProxyBodyHeader(std::ofstream& stream);
+ void GenNamespace(std::ofstream& stream);
+ void GenLemAnonymousNamespace(std::ofstream& stream);
+ void GenLemAPI(std::ofstream& stream);
+ std::string GenLemBaseWithStructures();
+ std::string GenBaseImpl();
+ std::string GenInterfaces();
+ std::string GenInterface(const Interface& iface);
+ std::string GenInterfaceCallbacks(const Interface& iface);
+ std::string GenInterfaceCallbackReceivedEvent(const Parameters& params);
+ std::string GenInterfaceMethods(const Interface& iface);
+ std::string GenInterfaceMethod(const Interface& iface,
+ const Declaration& decl);
+ std::string GenInterfaceMethodSerialize(const Declaration& decl);
+ std::string GenInterfaceMethodDeserialize(const Declaration& decl);
+
+ private:
+ std::shared_ptr<Options> options_;
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_CPP_PROXY_BODY_GENERATOR_HH_
diff --git a/idlc/gen/version2/cpp_proxy_body_generator_cb.hh b/idlc/gen/version2/cpp_proxy_body_generator_cb.hh
new file mode 100644
index 0000000..7e3028d
--- /dev/null
+++ b/idlc/gen/version2/cpp_proxy_body_generator_cb.hh
@@ -0,0 +1,718 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CPP_PROXY_BODY_GENERATOR_CB_HH_
+#define IDLC_GEN_VERSION2_CPP_PROXY_BODY_GENERATOR_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <FILENAME> The filename of the proxy.
+ */
+constexpr const char CB_PROXY_BODY_HEADER[] =
+R"__cpp_cb(
+#include "<FILENAME>"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <dlog.h>
+)__cpp_cb";
+
+/**
+ * <IFACE_NAME> The interface name of the callback base class.
+ */
+constexpr const char CB_INTERFACE_CALKBACBASE_BASE[] =
+R"__cpp_cb(
+std::atomic<int> <IFACE_NAME>::CallbackBase::seq_num_ { 0 };
+
+<IFACE_NAME>::CallbackBase::CallbackBase(int delegate_id, bool once) : id_(delegate_id), once_(once) {
+ seq_id_ = seq_num_++;
+}
+
+void <IFACE_NAME>::CallbackBase::OnReceivedEvent(const UnitMap& unit_map) {}
+
+int <IFACE_NAME>::CallbackBase::GetId() const {
+ return id_;
+}
+
+void <IFACE_NAME>::CallbackBase::SetId(int id) {
+ id_ = id;
+}
+
+int <IFACE_NAME>::CallbackBase::GetSeqId() const {
+ return seq_id_;
+}
+
+void <IFACE_NAME>::CallbackBase::SetSeqId(int seq_id) {
+ seq_id_ = seq_id;
+}
+
+bool <IFACE_NAME>::CallbackBase::IsOnce() const {
+ return once_;
+}
+
+void <IFACE_NAME>::CallbackBase::SetOnce(bool once) {
+ once_ = once;
+}
+
+std::string <IFACE_NAME>::CallbackBase::GetTag() const {
+ return std::to_string(id_) + "::" + std::to_string(seq_id_);
+}
+)__cpp_cb";
+
+/**
+ * <IFACE_NAME> The interface name of the callback.
+ * <CLS_NAME> The class name of the callback.
+ * <IMPL_RECEIVED_EVENT> The implmenetation of the OnReceivedEvent() of the callback.
+ */
+constexpr const char CB_INTERFACE_CALLBACK[] =
+R"__cpp_cb(
+<IFACE_NAME>::<CLS_NAME>::<CLS_NAME>(bool once) : CallbackBase(static_cast<int>(DelegateId::<CLS_NAME>), once) {}
+
+void <IFACE_NAME>::<CLS_NAME>::OnReceived(<PARAMS>) {}
+
+void <IFACE_NAME>::<CLS_NAME>::OnReceivedEvent(const UnitMap& unit_map) {
+ <IMPL_RECEIVED_EVENT>
+}
+)__cpp_cb";
+
+/**
+ * <NAME> The name of the parameter of the callback.
+ */
+constexpr const char CB_INTERFACE_CALLBACK_UNIT_MAP_READ[] =
+R"__cpp_cb(
+<TYPE> <NAME>_;
+unit_map.Read("<NAME>", <NAME>_);
+)__cpp_cb";
+
+/**
+ * <PARAMS> The parameters of the callback.
+ */
+constexpr const char CB_INTERFACE_CALLBACK_INVOKE[] =
+R"__cpp_cb(
+OnReceived(<PARAMS>);
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the interface.
+ * <CALLBACKS> The callbacks of the interface.
+ * <METHODS> The methods of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__cpp_cb(
+<CALLBACKS>
+<CLS_NAME>::<CLS_NAME>(<CLS_NAME>::IEventListener* listener, std::string target_appid) : listener_(listener), target_appid_(std::move(target_appid)) {
+ _W("<CLS_NAME> ctor");
+ int ret = rpc_port_proxy_create(&proxy_);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create proxy. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ rpc_port_proxy_add_connected_event_cb(proxy_, OnConnectedCb, this);
+ rpc_port_proxy_add_disconnected_event_cb(proxy_, OnDisconnectedCb, this);
+ rpc_port_proxy_add_rejected_event_cb(proxy_, OnRejectedCb, this);
+ rpc_port_proxy_add_received_event_cb(proxy_, OnReceivedCb, this);
+
+ if (GetAppId() == target_appid_) {
+ local_execution_ = std::make_unique<LocalExecution>("<CLS_NAME>", this);
+ local_execution_->LoadSymbols();
+ }
+}
+
+<CLS_NAME>::~<CLS_NAME>() {
+ _W("<CLS_NAME> dtor");
+ if (proxy_ != nullptr)
+ rpc_port_proxy_destroy(proxy_);
+}
+
+void <CLS_NAME>::Connect(bool sync) {
+ int ret;
+ if (local_execution_.get() != nullptr && local_execution_->LoadSymbols()) {
+ ret = local_execution_->Connect(sync);
+ } else {
+ if (sync)
+ ret = rpc_port_proxy_connect_sync(proxy_, target_appid_.c_str(), "<CLS_NAME>");
+ else
+ ret = rpc_port_proxy_connect(proxy_, target_appid_.c_str(), "<CLS_NAME>");
+ }
+
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to connect to <CLS_NAME>. error(%d)", ret);
+ switch (ret) {
+ case RPC_PORT_ERROR_INVALID_PARAMETER: {
+ throw InvalidIDException();
+ }
+ case RPC_PORT_ERROR_IO_ERROR: {
+ throw InvalidIOException();
+ }
+ case RPC_PORT_ERROR_PERMISSION_DENIED: {
+ throw PermissionDeniedException();
+ }
+ }
+ }
+}
+
+void <CLS_NAME>::Disconnect() {
+ if (local_execution_.get() != nullptr && local_execution_->IsConnected()) {
+ local_execution_->Disconnect();
+ return;
+ }
+
+ int ret = rpc_port_disconnect(port_);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to disconnect from <CLS_NAME>. error(%d)", ret);
+ throw InvalidIDException();
+ }
+}
+
+void <CLS_NAME>::DisposeCallback(const std::string& tag) {
+ auto iter = delegate_list_.begin();
+ while (iter != delegate_list_.end()) {
+ if ((*iter)->GetTag() == tag) {
+ iter = delegate_list_.erase(iter);
+ break;
+ }
+
+ iter++;
+ }
+}
+
+<METHODS>
+
+void <CLS_NAME>::OnLocalConnected() {
+ listener_->OnConnected();
+}
+
+void <CLS_NAME>::OnLocalDisconnected() {
+ listener_->OnDisconnected();
+}
+
+void <CLS_NAME>::OnLocalReceived(rpc_port_parcel_h parcel) {
+ UnitMap map;
+ map.Deserialize(parcel);
+ ProcessReceivedEvent(map);
+}
+
+void <CLS_NAME>::ProcessReceivedEvent(const UnitMap& unit_map) {
+ CallbackBase callback;
+ unit_map.Read("delegate", callback);
+
+ auto iter = delegate_list_.begin();
+ while (iter != delegate_list_.end()) {
+ auto& delegate = *iter;
+ if (delegate->GetId() == callback.GetId() && delegate->GetSeqId() == callback.GetSeqId()) {
+ delegate->OnReceivedEvent(unit_map);
+ if (delegate->IsOnce())
+ iter = delegate_list_.erase(iter);
+
+ break;
+ }
+
+ iter++;
+ }
+}
+
+void <CLS_NAME>::ConsumeCommand(rpc_port_h port, int seq_num, UnitMap& unit_map) {
+ do {
+ rpc_port_parcel_h parcel;
+ int ret = rpc_port_parcel_create_from_port(&parcel, port);
+ if (ret != RPC_PORT_ERROR_NONE)
+ break;
+
+ rpc_port_parcel_header_h header;
+ ret = rpc_port_parcel_get_header(parcel, &header);
+ if (ret != RPC_PORT_ERROR_NONE)
+ break;
+
+ int received_seq_num = -1;
+ rpc_port_parcel_header_get_seq_num(header, &received_seq_num);
+ if (received_seq_num != seq_num) {
+ _W("%d : %d", received_seq_num, seq_num);
+ rpc_port_parcel_destroy(parcel);
+ continue;
+ }
+
+ unit_map.Deserialize(parcel);
+ rpc_port_parcel_destroy(parcel);
+
+ int cmd = -1;
+ unit_map.Read("[METHOD]", cmd);
+ if (cmd == static_cast<int>(MethodId::__Result))
+ return;
+
+ unit_map.Clear();
+ } while (true);
+}
+
+void <CLS_NAME>::OnConnectedCb(const char* endpoint, const char* port_name, rpc_port_h port, void* user_data) {
+ auto* handle = static_cast<<CLS_NAME>*>(user_data);
+ handle->port_ = port;
+ rpc_port_h cb_port = nullptr;
+ rpc_port_proxy_get_port(handle->proxy_, RPC_PORT_PORT_CALLBACK, &cb_port);
+ handle->callback_port_ = cb_port;
+ handle->listener_->OnConnected();
+}
+
+void <CLS_NAME>::OnDisconnectedCb(const char* endpoint, const char* port_name, void* user_data) {
+ auto* handle = static_cast<<CLS_NAME>*>(user_data);
+ handle->delegate_list_.clear();
+ handle->listener_->OnDisconnected();
+}
+
+void <CLS_NAME>::OnRejectedCb(const char* endpoint, const char* port_name, void* user_data) {
+ auto* handle = static_cast<<CLS_NAME>*>(user_data);
+ handle->listener_->OnRejected();
+}
+
+void <CLS_NAME>::OnReceivedCb(const char* endpoint, const char* port_name, void* user_data) {
+ auto* handle = static_cast<<CLS_NAME>*>(user_data);
+ rpc_port_parcel_h parcel;
+ int ret = rpc_port_parcel_create_from_port(&parcel, handle->callback_port_);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel from port. error(%d)", ret);
+ return;
+ }
+
+ UnitMap unit_map;
+ unit_map.Deserialize(parcel);
+ rpc_port_parcel_destroy(parcel);
+
+ int cmd = -1;
+ unit_map.Read("[METHOD]", cmd);
+ if (cmd != static_cast<int>(MethodId::__Callback)) {
+ _E("Invalid procotol");
+ return;
+ }
+
+ handle->ProcessReceivedEvent(unit_map);
+}
+)__cpp_cb";
+
+/**
+ * <IFACE_NAME> The interface name.
+ * <NAME> The method name of the interface.
+ * <PARAMS> The parameters of the method.
+ * <SERIALIZE> The implementation of serialization of the input parameter.
+ */
+constexpr const char CB_INTERFACE_METHOD_ASYNC_BASE[] =
+R"__cpp_cb(
+void <IFACE_NAME>::<NAME>(<PARAMS>) {
+ if (port_ == nullptr && (local_execution_.get() == nullptr || !local_execution_->IsConnected())) {
+ _E("Not connected");
+ throw NotConnectedSocketException();
+ }
+
+ rpc_port_parcel_h parcel_;
+ rpc_port_parcel_create(&parcel_);
+
+ rpc_port_parcel_header_h header_;
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+
+ UnitMap map_;
+ map_.Write("[METHOD]", static_cast<int>(MethodId::<NAME>));
+ <SERIALIZE>
+ map_.Serialize(parcel_);;
+
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ int ret_;
+ if (local_execution_.get() != nullptr && local_execution_->IsConnected())
+ ret_ = local_execution_->Send(parcel_, nullptr);
+ else
+ ret_ = rpc_port_parcel_send(parcel_, port_);
+
+ rpc_port_parcel_destroy(parcel_);
+ if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to send parcel. error(%d)", ret_);
+ throw InvalidIOException();
+ }
+}
+)__cpp_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the method of the interface.
+ * <SET_INIT_VALUE> The setting initialization value.
+ * <IFACE_NAME> The interface name.
+ * <NAME> The method name of the interface.
+ * <PARAMS> The parameters of the method.
+ * <SERIALIZE> The implementation of serialization of the input parameter.
+ * <DESERIALIZE> The implementation of deserialization of the output parameter.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE[] =
+R"__cpp_cb(
+<RETURN_TYPE> <IFACE_NAME>::<NAME>(<PARAMS>) {
+ if (port_ == nullptr && (local_execution_.get() == nullptr || !local_execution_->IsConnected())) {
+ _E("Not connected");
+ throw NotConnectedSocketException();
+ }
+
+ rpc_port_parcel_h parcel_;
+ rpc_port_parcel_create(&parcel_);
+
+ rpc_port_parcel_header_h header_;
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+
+ int seq_num_ = -1;
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+
+ UnitMap map_;
+ map_.Write("[METHOD]", static_cast<int>(MethodId::<NAME>));
+ <SERIALIZE>
+ map_.Serialize(parcel_);
+
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ int ret_;
+ rpc_port_parcel_h result_parcel_ = nullptr;
+ if (local_execution_.get() != nullptr && local_execution_->IsConnected())
+ ret_ = local_execution_->Send(parcel_, &result_parcel_);
+ else
+ ret_ = rpc_port_parcel_send(parcel_, port_);
+
+ rpc_port_parcel_destroy(parcel_);
+ if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to send parcel. error(%d)", ret_);
+ throw InvalidIOException();
+ }
+
+ <RETURN_TYPE> result_<SET_INIT_VALUE>;
+ UnitMap received_map_;
+ if (local_execution_.get() != nullptr && local_execution_->IsConnected()) {
+ received_map_.Deserialize(result_parcel_);
+ rpc_port_parcel_destroy(result_parcel_);
+ } else {
+ ConsumeCommand(port_, seq_num_, received_map_);
+ }
+
+ if (received_map_.GetSize() == 0) {
+ _E("received map size is zero");
+ }
+
+ auto unit_ = received_map_.Lookup("[REMOTE_EXCEPTION]");
+ if (unit_ != nullptr) {
+ RemoteException remote_except;
+ unit_->Read(remote_except);
+ throw remote_except;
+ }
+
+ <DESERIALIZE>
+ received_map_.Read("[RESULT]", result_);
+ return result_;
+}
+)__cpp_cb";
+
+/**
+ * <NAME> The name of the parameter.
+ */
+constexpr const char CB_INTERFACE_METHOD_UNIT_MAP_WRITE[] =
+R"__cpp_cb(
+map_.Write("<NAME>", <NAME>);
+)__cpp_cb";
+
+/**
+ * <NAME> The name of the parameter.
+ */
+constexpr const char CB_INTERFACE_METHOD_DELEGATE_INSERT[] =
+R"__cpp_cb(
+delegate_list_.push_back(std::move(<NAME>));
+)__cpp_cb";
+
+/**
+ * <NAME> The name of the parameter.
+ */
+constexpr const char CB_INTERFACE_METHOD_UNIT_MAP_READ[] =
+R"__cpp_cb(
+received_map_.Read("<NAME>", <NAME>);
+)__cpp_cb";
+
+constexpr const char CB_LEM_ANONYMOUS_NAMESPACE[] =
+R"__cpp_cb(
+namespace {
+
+std::atomic<unsigned int> seq_ { 0 };
+std::string appid_;
+
+const std::string& GetAppId() {
+ if (getuid() < 5000)
+ return appid_;
+
+ if (appid_.empty()) {
+ char* id = nullptr;
+ app_get_id(&id);
+ if (id == nullptr) {
+ _E("Failed to get app id");
+ return appid_;
+ }
+
+ appid_ = std::string(id);
+ free(id);
+ }
+
+ return appid_;
+}
+
+rpc_port_parcel_h Clone(rpc_port_parcel_h parcel) {
+ void* raw = nullptr;
+ unsigned int size = 0;
+ if (rpc_port_parcel_get_raw(parcel, &raw, &size) != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get raw");
+ return nullptr;
+ }
+
+ rpc_port_parcel_h handle = nullptr;
+ rpc_port_parcel_create_from_raw(&handle, raw, size);
+ return handle;
+}
+
+} // namespace
+)__cpp_cb";
+
+/**
+ * <INPUT_FILE> The input file name.
+ */
+constexpr const char CB_LEM_BASE[] =
+R"__cpp_cb(
+LocalExecution::LocalExecution(std::string port_name, LocalExecution::IEvent* listener) : port_name_(std::move(port_name)), listener_(listener) {
+ instance_ = GetAppId() + "::" + std::to_string(seq_++);
+}
+
+LocalExecution::~LocalExecution() {
+ while (!result_queue_.empty()) {
+ auto parcel = result_queue_.front();
+ result_queue_.pop();
+ rpc_port_parcel_destroy(parcel);
+ }
+
+ while (!request_queue_.empty()) {
+ auto parcel = request_queue_.front();
+ request_queue_.pop();
+ rpc_port_parcel_destroy(parcel);
+ }
+}
+
+int LocalExecution::Connect(bool sync) {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ if (connecting_) {
+ _E("Already connecting");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (connected_) {
+ _E("Already connected");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (connect_func_) {
+ int ret = connect_func_(this, GetAppId().c_str(), instance_.c_str(), sync);
+ if (ret != RPC_PORT_ERROR_NONE)
+ return ret;
+ }
+
+ connecting_ = true;
+ return RPC_PORT_ERROR_NONE;
+}
+
+void LocalExecution::Disconnect() {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ connecting_ = false;
+ if (disconnect_func_)
+ disconnect_func_(this, GetAppId().c_str(), instance_.c_str());
+}
+
+int LocalExecution::Send(rpc_port_parcel_h request, rpc_port_parcel_h* result) {
+ if (send_func_) {
+ int ret = send_func_(this, request);
+ if (result != nullptr) {
+ int count = 0;
+ while (ResultQueueEmpty() && count++ < 100)
+ usleep(100 * 1000);
+
+ if (ResultQueueEmpty()) {
+ _E("Failed to get result from server");
+ return RPC_PORT_ERROR_IO_ERROR;
+ }
+
+ *result = ResultQueuePop();
+ }
+
+ return ret;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+void LocalExecution::OnConnected() {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ connecting_ = false;
+ connected_ = true;
+ if (listener_ != nullptr)
+ listener_->OnLocalConnected();
+}
+
+void LocalExecution::OnDisconnected() {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ connecting_ = false;
+ connected_ = false;
+ if (listener_ != nullptr)
+ listener_->OnLocalDisconnected();
+}
+
+void LocalExecution::OnReceived(rpc_port_parcel_h parcel) {
+ if (listener_ != nullptr)
+ listener_->OnLocalReceived(parcel);
+}
+
+bool LocalExecution::LoadSymbols() {
+ if (loaded_)
+ return true;
+
+ if (connect_func_ == nullptr) {
+ std::string symbol = "rpc_port_stub_<INPUT_FILE>_lem_" + port_name_ + "_connect";
+ connect_func_ = reinterpret_cast<StubConnectFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+ if (connect_func_ == nullptr) {
+ _E("Failed to find symbol(%s)", symbol.c_str());
+ return false;
+ }
+ }
+
+ if (disconnect_func_ == nullptr) {
+ std::string symbol = "rpc_port_stub_<INPUT_FILE>_lem_" + port_name_ + "_disconnect";
+ disconnect_func_ = reinterpret_cast<StubDisconnectFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+ if (disconnect_func_ == nullptr) {
+ _E("Failed to find symbol(%s)", symbol.c_str());
+ return false;
+ }
+ }
+
+ if (send_func_ == nullptr) {
+ std::string symbol = "rpc_port_stub_<INPUT_FILE>_lem_" + port_name_ + "_send";
+ send_func_ = reinterpret_cast<StubSendFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+ if (send_func_ == nullptr) {
+ _E("Failed to find symbol(%s)", symbol.c_str());
+ return false;
+ }
+ }
+
+ loaded_ = true;
+ return true;
+}
+
+void LocalExecution::ResultQueuePush(rpc_port_parcel_h parcel) {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ result_queue_.push(parcel);
+}
+
+rpc_port_parcel_h LocalExecution::ResultQueuePop() {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ auto parcel = result_queue_.front();
+ result_queue_.pop();
+ return parcel;
+}
+
+bool LocalExecution::ResultQueueEmpty() const {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ return result_queue_.empty();
+}
+
+void LocalExecution::RequestQueuePush(rpc_port_parcel_h parcel) {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ request_queue_.push(parcel);
+}
+
+rpc_port_parcel_h LocalExecution::RequestQueuePop() {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ auto parcel = request_queue_.front();
+ request_queue_.pop();
+ return parcel;
+}
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The interface name.
+ * <INPUT_FILE> The input file name.
+ * <FILE_NAMESPACE> The file namespace.
+ */
+constexpr const char CB_LEM_API[] =
+R"__cpp_cb(
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<CLS_NAME>_connect(void* h, bool sync) {
+ auto* handle = static_cast<rpc_port::<FILE_NAMESPACE>::LocalExecution*>(h);
+ if (sync) {
+ handle->OnConnected();
+ return RPC_PORT_ERROR_NONE;
+ }
+
+ auto* ptr = new std::weak_ptr<rpc_port::<FILE_NAMESPACE>::LocalExecution>(handle->shared_from_this());
+ g_idle_add([](gpointer user_data) {
+ auto* wp = static_cast<std::weak_ptr<rpc_port::<FILE_NAMESPACE>::LocalExecution>*>(user_data);
+ auto p = wp->lock();
+ if (p != nullptr)
+ p->OnConnected();
+
+ delete wp;
+ return G_SOURCE_REMOVE;
+ }, ptr);
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<CLS_NAME>_disconnect(void* h) {
+ auto* handle = static_cast<rpc_port::<FILE_NAMESPACE>::LocalExecution*>(h);
+ auto* ptr = new std::weak_ptr<rpc_port::<FILE_NAMESPACE>::LocalExecution>(handle->shared_from_this());
+ g_idle_add([](gpointer user_data) {
+ auto* wp = static_cast<std::weak_ptr<rpc_port::<FILE_NAMESPACE>::LocalExecution>*>(user_data);
+ auto p = wp->lock();
+ if (p != nullptr)
+ p->OnDisconnected();
+
+ delete wp;
+ return G_SOURCE_REMOVE;
+ }, ptr);
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<CLS_NAME>_invoke_callback(void* h, rpc_port_parcel_h parcel) {
+ auto* handle = static_cast<rpc_port::<FILE_NAMESPACE>::LocalExecution*>(h);
+ auto* ptr = new std::weak_ptr<rpc_port::<FILE_NAMESPACE>::LocalExecution>(handle->shared_from_this());
+ rpc_port_parcel_h cloned_parcel = ::Clone(parcel);
+ handle->RequestQueuePush(cloned_parcel);
+ g_idle_add([](gpointer user_data) {
+ auto* wp = static_cast<std::weak_ptr<rpc_port::<FILE_NAMESPACE>::LocalExecution>*>(user_data);
+ auto p = wp->lock();
+ if (p != nullptr) {
+ rpc_port_parcel_h request = p->RequestQueuePop();
+ p->OnReceived(request);
+ rpc_port_parcel_destroy(request);
+ }
+
+ delete wp;
+ return G_SOURCE_REMOVE;
+ }, ptr);
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<CLS_NAME>_send_result(void* h, rpc_port_parcel_h parcel) {
+ auto* handle = static_cast<rpc_port::<FILE_NAMESPACE>::LocalExecution*>(h);
+ rpc_port_parcel_h cloned_parcel = ::Clone(parcel);
+ handle->ResultQueuePush(cloned_parcel);
+ return RPC_PORT_ERROR_NONE;
+}
+)__cpp_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_CPP_PROXY_BODY_GENERATOR_CB_HH_
diff --git a/idlc/gen/version2/cpp_proxy_header_generator.cc b/idlc/gen/version2/cpp_proxy_header_generator.cc
new file mode 100644
index 0000000..ce81dac
--- /dev/null
+++ b/idlc/gen/version2/cpp_proxy_header_generator.cc
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/cpp_proxy_header_generator.hh"
+
+#include <utility>
+
+#include "idlc/gen/version2/cpp_generator_base_cb.hh"
+#include "idlc/gen/version2/cpp_proxy_header_generator_cb.hh"
+
+namespace tidl {
+namespace version2 {
+
+CppProxyHeaderGenerator::CppProxyHeaderGenerator(
+ std::shared_ptr<Document> doc, std::shared_ptr<Options> options)
+ : CppGeneratorBase(std::move(doc)), options_(std::move(options)) {}
+
+void CppProxyHeaderGenerator::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenIncludeDefaultHeaders(stream, false);
+ GenNamespace(stream);
+}
+
+void CppProxyHeaderGenerator::OnFiniGen(std::ofstream& stream) {}
+
+void CppProxyHeaderGenerator::GenNamespace(std::ofstream& stream) {
+ ReplaceAll(CB_NAMESPACE_PROXY)
+ .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
+ .Change("<STRUCTURES>", GenLemBaseWithStructures())
+ .Change("<BASE_IMPL>", GenBaseImpl())
+ .Change("<INTERFACES>", GenInterfaces())
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+}
+
+std::string CppProxyHeaderGenerator::GenLemBaseWithStructures() {
+ std::string code = CB_LEM_BASE;
+ code += NLine(1);
+ code += GenStructuresForHeader();
+ return code;
+}
+
+std::string CppProxyHeaderGenerator::GenBaseImpl() {
+ std::string code = GenExceptions();
+ code += GenRemoteExceptionForHeader();
+ return code;
+}
+
+std::string CppProxyHeaderGenerator::GenInterfaces() {
+ std::string code;
+ for (auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<Interface&>(*block);
+ code += GenInterface(iface) + NLine(1);
+ }
+
+ return code;
+}
+
+std::string CppProxyHeaderGenerator::GenInterface(const Interface& iface) {
+ return std::string(
+ ReplaceAll(CB_INTERFACE_BASE)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Change("<ENUMS>", GenEnumerations(iface.GetEnums()))
+ .Change("<CALLBACKS>", GenInterfaceCallbacks(iface))
+ .Change("<METHODS>", GenInterfaceMethods(iface))
+ .Change("<METHOD_IDS>", GenMethodIds(iface))
+ .Change("<DELEGATE_IDS>", GenDelegateIds(iface)));
+}
+
+std::string CppProxyHeaderGenerator::GenInterfaceCallbacks(
+ const Interface& iface) {
+ std::string code;
+ code += ReplaceAll(CB_INTERFACE_CALLBACK_BASE)
+ .Change("<IFACE_NAME>", iface.GetID());
+ code += NLine(1);
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_INTERFACE_CALLBACK)
+ .Change("<CLS_NAME>", decl->GetID())
+ .Change("<PARAMS>", GetParameters(decl->GetParameters()));
+ code += NLine(1);
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppProxyHeaderGenerator::GenInterfaceMethods(
+ const Interface& iface) {
+ std::string code;
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_INTERFACE_METHOD)
+ .Change("<RETURN_TYPE>", ConvertTypeToString(decl->GetType()))
+ .Change("<NAME>", decl->GetID())
+ .Change("<PARAMS>", GetParameters(decl->GetParameters()));
+ }
+
+ return RemoveLine(code);
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/cpp_proxy_header_generator.hh b/idlc/gen/version2/cpp_proxy_header_generator.hh
new file mode 100644
index 0000000..13b147e
--- /dev/null
+++ b/idlc/gen/version2/cpp_proxy_header_generator.hh
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CPP_PROXY_HEADER_GENERATOR_HH_
+#define IDLC_GEN_VERSION2_CPP_PROXY_HEADER_GENERATOR_HH_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/version2/cpp_generator_base.hh"
+#include "idlc/options.h"
+
+namespace tidl {
+namespace version2 {
+
+class CppProxyHeaderGenerator : public CppGeneratorBase {
+ public:
+ explicit CppProxyHeaderGenerator(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options);
+ virtual ~CppProxyHeaderGenerator() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ std::string GenLemBaseWithStructures();
+ std::string GenBaseImpl();
+ std::string GenInterfaces();
+ std::string GenInterface(const Interface& iface);
+ std::string GenInterfaceCallbacks(const Interface& iface);
+ std::string GenInterfaceMethods(const Interface& iface);
+
+ private:
+ std::shared_ptr<Options> options_;
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_CPP_PROXY_HEADER_GENERATOR_HH_
diff --git a/idlc/gen/version2/cpp_proxy_header_generator_cb.hh b/idlc/gen/version2/cpp_proxy_header_generator_cb.hh
new file mode 100644
index 0000000..098431f
--- /dev/null
+++ b/idlc/gen/version2/cpp_proxy_header_generator_cb.hh
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CPP_PROXY_HEADER_GENERATOR_CB_HH_
+#define IDLC_GEN_VERSION2_CPP_PROXY_HEADER_GENERATOR_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <IFACE_NAME> The interface name.
+ */
+constexpr const char CB_INTERFACE_CALLBACK_BASE[] =
+R"__cpp_cb(
+class CallbackBase {
+ public:
+ CallbackBase() = default;
+ CallbackBase(int delegate_id, bool once);
+ virtual ~CallbackBase() = default;
+
+ virtual void OnReceivedEvent(const UnitMap& unit_map);
+ int GetId() const;
+ void SetId(int id);
+
+ int GetSeqId() const;
+ void SetSeqId(int seq_id);
+
+ bool IsOnce() const;
+ void SetOnce(bool once);
+
+ std::string GetTag() const;
+
+ private:
+ static std::atomic<int> seq_num_;
+ int id_ = 0;
+ int seq_id_ = 0;
+ bool once_ = false;
+};
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the callback.
+ * <PARAMS> The parameters of the callback.
+ */
+constexpr const char CB_INTERFACE_CALLBACK[] =
+R"__cpp_cb(
+class <CLS_NAME> : public CallbackBase {
+ public:
+ <CLS_NAME>(bool once = false);
+
+ virtual void OnReceived(<PARAMS>);
+
+ private:
+ void OnReceivedEvent(const UnitMap& unit_map) override;
+};
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the interface.
+ * <CALLBACKS> The callbacks of the interface.
+ * <METHODS> The methods of the interface.
+ * <METHOD_IDS> The enumeration of methods of the interface.
+ * <DELEGATE_IDS> The enumeration of delegates(callbacks) of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__cpp_cb(
+class <CLS_NAME> : public LocalExecution::IEvent {
+ public:
+ <ENUMS>
+ <CALLBACKS>
+ class IEventListener {
+ public:
+ /// <summary>
+ /// This method will be invoked when the client app is connected to the servicece app.
+ /// </summary>
+ virtual void OnConnected() = 0;
+
+ /// <summary>
+ /// This method will be invoked after the client app was disconnected from the servicece app.
+ /// </summary>
+ virtual void OnDisconnected() = 0;
+
+ /// <summary>
+ /// This method will be invoked when the service app rejects the client app.
+ /// </summary>
+ virtual void OnRejected() = 0;
+ };
+
+ /// <summary>
+ /// Constructor for this class
+ /// </summary>
+ /// <param name="listener">The listener for events</param>
+ /// <param name="target_appid">The service app ID to connect</param>
+ <CLS_NAME>(IEventListener* listener, std::string target_appid);
+
+ /// <summary>
+ /// Destructor for this class
+ /// </summary>
+ virtual ~<CLS_NAME>();
+
+ /// <summary>
+ /// Connects to the service app.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ // <param name="sync">if true, connects to the service app synchornously</param>
+ /// <exception cref="InvalidIDException">
+ /// Thrown when the appid to connect is invalid.
+ /// </exception>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ /// <exception cref="PermissionDeniedException">
+ /// Thrown when the permission is denied.
+ /// </exception>
+ /// <remark> If you want to use this method, you must add privileges.</remark>
+ void Connect(bool sync = false);
+
+ /// <summary>
+ /// Disconnects from the service app.
+ /// </summary>
+ /// <exception cref="InvalidIDException">
+ /// Thrown when the stub port is invalid.
+ /// </exception>
+ void Disconnect();
+
+ /// <summary>
+ /// Disposes delegate objects in this interface
+ /// </summary>
+ /// <param name="tag">The tag string from delegate object</param>
+ void DisposeCallback(const std::string& tag);
+
+ <METHODS>
+ private:
+ <METHOD_IDS>
+ <DELEGATE_IDS>
+
+ void ProcessReceivedEvent(const UnitMap& unit_map);
+ void ConsumeCommand(rpc_port_h port, int seq_num, UnitMap& unit_map);
+ static void OnConnectedCb(const char* endpoint, const char* port_name, rpc_port_h port, void* user_data);
+ static void OnDisconnectedCb(const char* endpoint, const char* port_name, void* user_data);
+ static void OnRejectedCb(const char* endpoint, const char* port_name, void* user_data);
+ static void OnReceivedCb(const char* endpoint, const char* port_name, void* user_data);
+
+ void OnLocalConnected() override;
+ void OnLocalDisconnected() override;
+ void OnLocalReceived(rpc_port_parcel_h parcel) override;
+
+ private:
+ rpc_port_h port_ = nullptr;
+ rpc_port_h callback_port_ = nullptr;
+ rpc_port_proxy_h proxy_ = nullptr;
+ IEventListener* listener_ = nullptr;
+ std::recursive_mutex mutex_;
+ std::list<std::unique_ptr<CallbackBase>> delegate_list_;
+ std::string target_appid_;
+ std::shared_ptr<LocalExecution> local_execution_;
+};
+)__cpp_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the method of the interface.
+ * <NAME> The method name of the interface.
+ * <PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD[] =
+R"__cpp_cb(
+<RETURN_TYPE> <NAME>(<PARAMS>);
+)__cpp_cb";
+
+constexpr const char CB_LEM_BASE[] =
+R"__cpp_cb(
+class LocalExecution : public std::enable_shared_from_this<LocalExecution> {
+ public:
+ class IEvent {
+ public:
+ virtual ~IEvent() = default;
+ virtual void OnLocalConnected() = 0;
+ virtual void OnLocalDisconnected() = 0;
+ virtual void OnLocalReceived(rpc_port_parcel_h parcel) = 0;
+ };
+
+ LocalExecution(std::string port_name, IEvent* listener);
+ virtual ~LocalExecution();
+
+ int Connect(bool sync);
+ void Disconnect();
+ int Send(rpc_port_parcel_h request, rpc_port_parcel_h* result);
+
+ bool IsConnected() const { return connected_; }
+
+ void OnConnected();
+ void OnDisconnected();
+ void OnReceived(rpc_port_parcel_h parcel);
+
+ bool LoadSymbols();
+
+ void ResultQueuePush(rpc_port_parcel_h parcel);
+ rpc_port_parcel_h ResultQueuePop();
+ bool ResultQueueEmpty() const;
+
+ void RequestQueuePush(rpc_port_parcel_h parcel);
+ rpc_port_parcel_h RequestQueuePop();
+
+
+ private:
+ using StubConnectFunc = int (*)(void*, const char*, const char*, bool);
+ using StubDisconnectFunc = void (*)(void*, const char*, const char*);
+ using StubSendFunc = int (*)(void*, rpc_port_parcel_h);
+
+ private:
+ std::string port_name_;
+ IEvent* listener_;
+ std::string instance_;
+ bool connected_ = false;
+ bool connecting_ = false;
+ bool loaded_ = false;
+ StubConnectFunc connect_func_ = nullptr;
+ StubDisconnectFunc disconnect_func_ = nullptr;
+ StubSendFunc send_func_ = nullptr;
+ std::queue<rpc_port_parcel_h> result_queue_;
+ std::queue<rpc_port_parcel_h> request_queue_;
+ mutable std::recursive_mutex mutex_;
+};
+)__cpp_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_CPP_PROXY_HEADER_GENERATOR_CB_HH_
diff --git a/idlc/gen/version2/cpp_stub_body_generator.cc b/idlc/gen/version2/cpp_stub_body_generator.cc
new file mode 100644
index 0000000..793d54d
--- /dev/null
+++ b/idlc/gen/version2/cpp_stub_body_generator.cc
@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/cpp_stub_body_generator.hh"
+
+#include <libgen.h>
+
+#include <utility>
+
+#include "idlc/gen/version2/cpp_generator_base_cb.hh"
+#include "idlc/gen/version2/cpp_stub_body_generator_cb.hh"
+
+namespace tidl {
+namespace version2 {
+
+CppStubBodyGenerator::CppStubBodyGenerator(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options)
+ : CppGeneratorBase(std::move(doc)), options_(std::move(options)) {}
+
+void CppStubBodyGenerator::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenIncludeStubBodyHeader(stream);
+ GenIncludeDefaultHeaders(stream);
+ GenLogTag(stream, "RPC_PORT_STUB");
+ GenLogDefinition(stream);
+ GenVersionDefinition(stream);
+ GenExportAPI(stream);
+ GenLemAnonymousNamespace(stream);
+ GenNamespace(stream);
+ GenLemAPI(stream);
+}
+
+void CppStubBodyGenerator::OnFiniGen(std::ofstream& stream) {}
+
+void CppStubBodyGenerator::GenIncludeStubBodyHeader(std::ofstream& stream) {
+ std::string key(".cc");
+ std::string header_file = FileName;
+
+ auto found = header_file.rfind(key);
+ if (found != std::string::npos)
+ header_file.replace(found, key.length(), ".h");
+
+ ReplaceAll(CB_STUB_BODY_HEADER)
+ .Change("<FILENAME>", header_file)
+ .Out(stream);
+}
+
+void CppStubBodyGenerator::GenNamespace(std::ofstream& stream) {
+ ReplaceAll(CB_NAMESPACE_STUB)
+ .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
+ .Change("<STRUCTURES>", GenLemBaseWithStructures())
+ .Change("<BASE_IMPL>", GenBaseImpl())
+ .Change("<INTERFACES>", GenInterfaces())
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+ stream << NLine(1);
+}
+
+void CppStubBodyGenerator::GenLemAnonymousNamespace(std::ofstream& stream) {
+ ReplaceAll(CB_LEM_ANONYMOUS_NAMESPACE)
+ .Change("<LEM_CONTEXT>", GenLemContext())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+ stream << NLine(1);
+}
+
+std::string CppStubBodyGenerator::GenLemContext() {
+ std::string code;
+ for (const auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<Interface&>(*block);
+ code += ReplaceAll(CB_LEM_CONTEXT)
+ .Change("<IFACE_NAME>", iface.GetID())
+ .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace());
+ }
+
+ return RemoveLine(code);
+}
+
+void CppStubBodyGenerator::GenLemAPI(std::ofstream& stream) {
+ std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
+ input = input.substr(0, input.find_last_of("."));
+ std::string code = NLine(1);
+ for (const auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<Interface&>(*block);
+ code += ReplaceAll(CB_LEM_API)
+ .Change("<CLS_NAME>", iface.GetID())
+ .ChangeToLower("<INPUT_FILE>", input);
+ code += NLine(1);
+ }
+
+ stream << SmartIndent(code);
+}
+
+std::string CppStubBodyGenerator::GenLemBaseWithStructures() {
+ std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
+ input = input.substr(0, input.find_last_of("."));
+ std::string code;
+ code += ReplaceAll(CB_LEM_BASE).ChangeToLower("<INPUT_FILE>", input);
+ code += NLine(1);
+ code += GenStructures();
+ return code;
+}
+
+std::string CppStubBodyGenerator::GenBaseImpl() {
+ std::string code = GenRemoteException();
+ code += GenUnitMap();
+ return code;
+}
+
+std::string CppStubBodyGenerator::GenInterfaces() {
+ std::string code;
+ for (const auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<Interface&>(*block);
+ code += GenInterface(iface) + NLine(1);
+ }
+
+ return code;
+}
+
+std::string CppStubBodyGenerator::GenInterface(const Interface& iface) {
+ return std::string(
+ ReplaceAll(CB_INTERFACE_BASE)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Change("<CALLBACKS>", GenInterfaceCallbacks(iface))
+ .Change("<IMPL_SERVICE_BASE_THREAD_MEMBER_INIT>",
+ GenInterfaceImplServiceBaseThreadMemberInit())
+ .Change("<IMPL_SERVICE_BASE_DISPATCH_FUNC_INIT>",
+ GenInterfaceImplServiceBaseDispatchFuncInit(iface))
+ .Change("<IMPL_SERVICE_BASE_DISPATCH>",
+ GenInterfaceImplServiceBaseDispatch())
+ .Change("<IMPL_SERVICE_BASE_DISPATCH_FUNCS>",
+ GenInterfaceImplServiceBaseDispatchFuncs(iface))
+ .Change("<IMPL_SERVICE_BASE_SET_PRIVILEGE_MAP>",
+ GenInterfaceImplServiceBaseSetPrivilegeMap(iface)));
+}
+
+std::string CppStubBodyGenerator::GenInterfaceCallbacks(
+ const Interface& iface) {
+ std::string code;
+ code += ReplaceAll(CB_INTERFACE_CALKBACBASE_BASE)
+ .Change("<IFACE_NAME>", iface.GetID());
+ code += NLine(1);
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_INTERFACE_CALLBACK)
+ .Change("<IFACE_NAME>", iface.GetID())
+ .Change("<CLS_NAME>", decl->GetID())
+ .Change("<PARAMS>", GetParameters(decl->GetParameters()))
+ .Change("<SERIALIZE>",
+ GenInterfaceCallbackSerialize(decl->GetParameters()));
+ code += NLine(1);
+ }
+
+ if (options_->IsThreadEnabled()) {
+ code += ReplaceAll(CB_INTERFACE_PENDING_JOB)
+ .Change("<IFACE_NAME>", iface.GetID());
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppStubBodyGenerator::GenInterfaceCallbackSerialize(
+ const Parameters& params) {
+ std::string code;
+ for (auto& param : params) {
+ code += ReplaceAll(CB_INTERFACE_CALLBACK_UNIT_MAP_WRITE)
+ .Change("<NAME>", param->GetID());
+ code += GenPrivateSharing(*param);
+ }
+
+ return RemoveLine(code);
+}
+
+std::string
+CppStubBodyGenerator::GenInterfaceImplServiceBaseThreadMemberInit() {
+ if (options_->IsThreadEnabled()) {
+ return RemoveLine(
+ std::string(CB_INTERFACE_IMPL_SERVICE_BASE_THREAD_MEMBER_INIT));
+ }
+
+ return "";
+}
+
+std::string CppStubBodyGenerator::GenInterfaceImplServiceBaseDispatchFuncInit(
+ const Interface& iface) {
+ std::string code;
+ for (auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_INTERFACE_IMPL_SERVICE_BASE_DISPATCH_FUNC_INIT)
+ .Change("<NAME>", decl->GetID())
+ .Change("<IFACE_NAME>", iface.GetID());
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppStubBodyGenerator::GenInterfaceImplServiceBaseDispatch() {
+ std::string code;
+ if (options_->IsThreadEnabled())
+ code = CB_INTERFACE_SERVICE_BASE_DISPATCH_BASE_WITH_THREAD;
+ else
+ code = CB_INTERFACE_SERVICE_BASE_DISPATCH_BASE;
+
+ return RemoveLine(code);
+}
+
+std::string CppStubBodyGenerator::GenInterfaceImplServiceBaseDispatchFuncs(
+ const Interface& iface) {
+ std::string code;
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += GenInterfaceImplServiceBaseDispatchFunc(iface, *decl);
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppStubBodyGenerator::GenInterfaceImplServiceBaseDispatchFunc(
+ const Interface& iface, const Declaration& decl) {
+ std::string params;
+ for (auto& param : decl.GetParameters()) {
+ if (!params.empty())
+ params += ", ";
+
+ auto& type = param->GetParameterType().GetBaseType();
+ if (IsDelegateType(type))
+ params += "std::move(" + param->GetID() + ")";
+ else
+ params += param->GetID();
+ }
+
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
+ return std::string(
+ ReplaceAll(CB_INTERFACE_SERVICE_BASE_DISPATCH_FUNC_ASYNC)
+ .Change("<IFACE_NAME>", iface.GetID())
+ .Change("<NAME>", decl.GetID())
+ .Change("<PARAMS>", params)
+ .Change("<DESERIALIZE>", GenInterfaceServiceBaseDeserialize(decl)));
+ }
+
+ return std::string(
+ ReplaceAll(CB_INTERFACE_SERVICE_BASE_DISPATCH_FUNC)
+ .Change("<IFACE_NAME>", iface.GetID())
+ .Change("<NAME>", decl.GetID())
+ .Change("<PARAMS>", params)
+ .Change("<SERIALIZE>", GenInterfaceServiceBaseSerialize(decl))
+ .Change("<DESERIALIZE>", GenInterfaceServiceBaseDeserialize(decl)));
+}
+
+std::string CppStubBodyGenerator::GenInterfaceServiceBaseDeserialize(
+ const Declaration& decl) {
+ std::string code;
+ for (auto& param : decl.GetParameters()) {
+ auto& type = param->GetParameterType().GetBaseType();
+ if (IsDelegateType(type)) {
+ code += ReplaceAll(CB_INTERFACE_SERVICE_BASE_PARAM_DELEGATE)
+ .Change("<TYPE>", ConvertTypeToString(type))
+ .Change("<TYPE_NAME>", type.ToString())
+ .Change("<NAME>", param->GetID());
+ } else {
+ code += ReplaceAll(CB_INTERFACE_SERVICE_BASE_PARAM_BASE)
+ .Change("<TYPE>", ConvertTypeToString(type))
+ .Change("<NAME>", param->GetID());
+ }
+
+ if (param->GetParameterType().GetDirection() !=
+ ParameterType::Direction::IN)
+ continue;
+
+ code += RemoveLine(
+ std::string(
+ ReplaceAll(CB_INTERFACE_SERVICE_BASE_UNIT_MAP_READ)
+ .Change("<TYPE>", ConvertTypeToString(type))
+ .Change("<NAME>", param->GetID())));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppStubBodyGenerator::GenInterfaceServiceBaseSerialize(
+ const Declaration& decl) {
+ std::string code;
+ for (auto& param : decl.GetParameters()) {
+ if (param->GetParameterType().GetDirection() ==
+ ParameterType::Direction::IN)
+ continue;
+
+ code += ReplaceAll(CB_INTERFACE_SERVICE_BASE_UNIT_MAP_WRITE)
+ .Change("<NAME>", param->GetID());
+ code += GenPrivateSharing(*param);
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppStubBodyGenerator::GenInterfaceImplServiceBaseSetPrivilegeMap(
+ const Interface& iface) {
+ std::string code;
+ for (auto& decl : iface.GetDeclarations()) {
+ std::string privileges;
+ for (auto& attr : decl->GetAttributes()) {
+ if (attr->GetKey() != "privilege")
+ continue;
+
+ privileges += "\"" + attr->GetValue() + "\"," + NLine(1);
+ }
+
+ if (privileges.empty())
+ continue;
+
+ code += ReplaceAll(CB_INTERFACE_SERVICE_BASE_SET_PRIVILEGE_MAP)
+ .Change("<PRIVILEGES>", privileges)
+ .Change("<METHOD>", decl->GetID());
+ }
+
+ return RemoveLine(code);
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/cpp_stub_body_generator.hh b/idlc/gen/version2/cpp_stub_body_generator.hh
new file mode 100644
index 0000000..90a7353
--- /dev/null
+++ b/idlc/gen/version2/cpp_stub_body_generator.hh
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CPP_STUB_BODY_GENERATOR_HH_
+#define IDLC_GEN_VERSION2_CPP_STUB_BODY_GENERATOR_HH_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/version2/cpp_generator_base.hh"
+#include "idlc/options.h"
+
+namespace tidl {
+namespace version2 {
+
+class CppStubBodyGenerator : public CppGeneratorBase {
+ public:
+ explicit CppStubBodyGenerator(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options);
+ virtual ~CppStubBodyGenerator() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenIncludeStubBodyHeader(std::ofstream& stream);
+ void GenLemAnonymousNamespace(std::ofstream& stream);
+ std::string GenLemContext();
+ void GenLemAPI(std::ofstream& stream);
+ void GenNamespace(std::ofstream& stream);
+ std::string GenLemBaseWithStructures();
+ std::string GenBaseImpl();
+ std::string GenInterfaces();
+ std::string GenInterface(const Interface& iface);
+ std::string GenInterfaceCallbacks(const Interface& iface);
+ std::string GenInterfaceCallbackSerialize(const Parameters& params);
+ std::string GenInterfaceImplServiceBaseThreadMemberInit();
+ std::string GenInterfaceImplServiceBaseDispatchFuncInit(
+ const Interface& iface);
+ std::string GenInterfaceImplServiceBaseDispatch();
+ std::string GenInterfaceImplServiceBaseDispatchFuncs(const Interface& iface);
+ std::string GenInterfaceImplServiceBaseDispatchFunc(const Interface& iface,
+ const Declaration& decl);
+ std::string GenInterfaceServiceBaseDeserialize(const Declaration& decl);
+ std::string GenInterfaceServiceBaseSerialize(const Declaration& decl);
+ std::string GenInterfaceImplServiceBaseSetPrivilegeMap(
+ const Interface& iface);
+
+ private:
+ std::shared_ptr<Options> options_;
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_CPP_STUB_BODY_GENERATOR_HH_
diff --git a/idlc/gen/version2/cpp_stub_body_generator_cb.hh b/idlc/gen/version2/cpp_stub_body_generator_cb.hh
new file mode 100644
index 0000000..5cf1a7d
--- /dev/null
+++ b/idlc/gen/version2/cpp_stub_body_generator_cb.hh
@@ -0,0 +1,757 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CPP_STUB_BODY_GENERATOR_CB_HH_
+#define IDLC_GEN_VERSION2_CPP_STUB_BODY_GENERATOR_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+/**
+ * <FILENAME> The filename of the stub.
+ */
+constexpr const char CB_STUB_BODY_HEADER[] =
+R"__cpp_cb(
+#include "<FILENAME>"
+
+#include <app_manager.h>
+#include <assert.h>
+#include <dlog.h>
+#include <package_manager.h>
+#include <stdlib.h>
+)__cpp_cb";
+
+/**
+ * <IFACE_NAME> The interface name of the callback base class.
+ */
+constexpr const char CB_INTERFACE_CALKBACBASE_BASE[] =
+R"__cpp_cb(
+std::atomic<int> <IFACE_NAME>::CallbackBase::seq_num_ { 0 };
+
+<IFACE_NAME>::CallbackBase::CallbackBase(int delegate_id, bool once) : id_(delegate_id), once_(once) {
+ seq_id_ = seq_num_++;
+}
+
+int <IFACE_NAME>::CallbackBase::GetId() const {
+ return id_;
+}
+
+void <IFACE_NAME>::CallbackBase::SetId(int id) {
+ id_ = id;
+}
+
+int <IFACE_NAME>::CallbackBase::GetSeqId() const {
+ return seq_id_;
+}
+
+void <IFACE_NAME>::CallbackBase::SetSeqId(int seq_id) {
+ seq_id_ = seq_id;
+}
+
+bool <IFACE_NAME>::CallbackBase::IsOnce() const {
+ return once_;
+}
+
+void <IFACE_NAME>::CallbackBase::SetOnce(bool once) {
+ once_ = once;
+}
+
+std::string <IFACE_NAME>::CallbackBase::GetTag() const {
+ return std::to_string(id_) + "::" + std::to_string(seq_id_);
+}
+
+void <IFACE_NAME>::CallbackBase::SetContext(void* context) {
+ context_ = context;
+}
+
+void* <IFACE_NAME>::CallbackBase::GetContext() const {
+ return context_;
+}
+)__cpp_cb";
+
+/**
+ * <IFACE_NAME> The interface name of the callback.
+ * <CLS_NAME> The class name of the callback.
+ * <SERILAIZE> The implementation of serialization of the input parameter.
+ */
+constexpr const char CB_INTERFACE_CALLBACK[] =
+R"__cpp_cb(
+void <IFACE_NAME>::<CLS_NAME>::Invoke(<PARAMS>) {
+ if (callback_port_ == nullptr && GetContext() == nullptr)
+ throw NotConnectedSocketException();
+
+ if (service_.lock().get() == nullptr)
+ throw NotConnectedSocketException();
+
+ if (IsOnce() && !valid_)
+ throw InvalidArgumentException();
+
+ UnitMap unit_map_;
+ unit_map_.Write("[METHOD]", static_cast<int>(MethodId::__Callback));
+ unit_map_.Write("delegate", *this);
+ <SERIALIZE>
+
+ rpc_port_parcel_h parcel_;
+ rpc_port_parcel_create(&parcel_);
+ unit_map_.Serialize(parcel_);
+
+ if (GetContext() != nullptr) {
+ <IFACE_NAME>_context_->InvokeCallback(GetContext(), parcel_);
+ set_last_result(RPC_PORT_ERROR_NONE);
+ } else {
+ set_last_result(rpc_port_parcel_send(parcel_, callback_port_));
+ }
+
+ rpc_port_parcel_destroy(parcel_);
+ valid_ = false;
+}
+)__cpp_cb";
+
+/**
+ * <NAME> The name of the parameter of the callback.
+ */
+constexpr const char CB_INTERFACE_CALLBACK_UNIT_MAP_WRITE[] =
+R"__cpp_cb(
+unit_map_.Write("<NAME>", <NAME>);
+)__cpp_cb";
+
+/**
+ * <IFACE_NAME> The interface name.
+ */
+constexpr const char CB_INTERFACE_PENDING_JOB[] =
+R"__cpp_cb(
+<IFACE_NAME>::PendingJob::PendingJob(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel, std::shared_ptr<ServiceBase> service) : port_(port), callback_port_(callback_port), parcel_(parcel), service_(std::move(service)) {}
+
+<IFACE_NAME>::PendingJob::~PendingJob() {
+ if (parcel_ != nullptr)
+ rpc_port_parcel_destroy(parcel_);
+}
+
+void <IFACE_NAME>::PendingJob::OnRun() {
+ service_->Dispatch(port_, callback_port_, parcel_);
+ parcel_ = nullptr;
+}
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the interface.
+ * <CALLBACKS> The callbacks of the interface.
+ * <IMPL_SERVICE_BASE_DISPATCH_FUNC_INIT> The implementation of the initialization of dispatch funcs of the service base.
+ * <IMPL_SERVICE_BASE_THREAD_MEMBER_INIT> The implementation of the initialization of thread member variable of the service base.
+ * <IMPL_SERVICE_BASE_DISPATCH> The implementation of the dispatch method of the service base.
+ * <IMPL_SERVICE_BASE_DISPATCH_FUNCS> The implementation of the dispatch functions of the service base.
+ * <IMPL_SERVICE_BASE_SET_PRIVILEGE_MAP> The implementation of setting privilege map of the service base.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__cpp_cb(
+<CALLBACKS>
+
+<CLS_NAME>::ServiceBase::ServiceBase(std::string sender, std::string instance) : sender_(std::move(sender)), instance_(std::move(instance)) {
+ LoadPrivileges();
+ SetPrivilegeMap();
+ <IMPL_SERVICE_BASE_THREAD_MEMBER_INIT>
+ dispatch_funcs_ = {
+ <IMPL_SERVICE_BASE_DISPATCH_FUNC_INIT>
+ };
+}
+
+void <CLS_NAME>::ServiceBase::SetPort(rpc_port_h port) {
+ port_ = port;
+}
+
+void <CLS_NAME>::ServiceBase::Disconnect() {
+ int ret = rpc_port_disconnect(port_);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to disconnect the port. error(%d)", ret);
+ return;
+ }
+
+ port_ = nullptr;
+}
+
+void <CLS_NAME>::ServiceBase::Dispatch(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel, std::shared_ptr<ServiceBase> service) {
+ <IMPL_SERVICE_BASE_DISPATCH>
+}
+
+void <CLS_NAME>::ServiceBase::Dispatch(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel) {
+ rpc_port_parcel_header_h header;
+ rpc_port_parcel_get_header(parcel, &header);
+
+ int seq_num = -1;
+ rpc_port_parcel_header_get_seq_num(header, &seq_num);
+
+ UnitMap unit_map_;
+ unit_map_.Deserialize(parcel);
+ rpc_port_parcel_destroy(parcel);
+
+ int cmd_ = -1;
+ unit_map_.Read("[METHOD]", cmd_);
+
+ auto found = dispatch_funcs_.find(cmd_);
+ if (found == dispatch_funcs_.end()) {
+ _E("Unknown command(%d)", cmd_);
+ return;
+ }
+
+ auto& func = found->second;
+ func(port, callback_port, seq_num, unit_map_);
+}
+
+bool <CLS_NAME>::ServiceBase::PrivilegeInfoCb(const char* privilege_name, void *user_data) {
+ auto* service_base = static_cast<<CLS_NAME>::ServiceBase*>(user_data);
+ _D("appid: %s, privilege: %s", service_base->GetSender().c_str(), privilege_name);
+ service_base->privileges_.insert(privilege_name);
+ return true;
+}
+
+void <CLS_NAME>::ServiceBase::LoadPrivileges() {
+ app_info_h app_info = nullptr;
+ int ret = app_info_create(GetSender().c_str(), &app_info);
+ if (ret != APP_MANAGER_ERROR_NONE) {
+ if (ret == APP_MANAGER_ERROR_NO_SUCH_APP)
+ _W("%s is not an application", GetSender().c_str());
+
+ return;
+ }
+
+ char* package = nullptr;
+ ret = app_info_get_package(app_info, &package);
+ app_info_destroy(app_info);
+ if (ret != APP_MANAGER_ERROR_NONE) {
+ _E("Failed to get package. error(%d)", ret);
+ return;
+ }
+
+ package_info_h package_info = nullptr;
+ ret = package_info_create(package, &package_info);
+ free(package);
+ if (ret != PACKAGE_MANAGER_ERROR_NONE) {
+ _E("Failed to create package info. error(%d)", ret);
+ return;
+ }
+
+ package_info_foreach_privilege_info(package_info, PrivilegeInfoCb, this);
+ package_info_destroy(package_info);
+}
+
+void <CLS_NAME>::ServiceBase::SetPrivilegeMap() {
+ <IMPL_SERVICE_BASE_SET_PRIVILEGE_MAP>
+}
+
+bool <CLS_NAME>::ServiceBase::CheckPrivileges(int method_id) {
+ auto found = privilege_map_.find(method_id);
+ if (found == privilege_map_.end())
+ return true;
+
+ for (const auto& privilege : found->second) {
+ if (privileges_.find(privilege) == privileges_.end()) {
+ _E("%s does not exist", privilege.c_str());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+<IMPL_SERVICE_BASE_DISPATCH_FUNCS>
+
+void <CLS_NAME>::ServiceBase::SetContext(void* context) {
+ context_ = context;
+}
+
+void* <CLS_NAME>::ServiceBase::GetContext() const {
+ return context_;
+}
+
+<CLS_NAME>::<CLS_NAME>() {
+ _W("<CLS_NAME> ctor");
+ int ret = rpc_port_stub_create(&stub_, "<CLS_NAME>");
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create stub. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ rpc_port_stub_add_connected_event_cb(stub_, OnConnectedCb, this);
+ rpc_port_stub_add_disconnected_event_cb(stub_, OnDisconnectedCb, this);
+ rpc_port_stub_add_received_event_cb(stub_, OnReceivedCb, this);
+
+ <CLS_NAME>_context_ = std::make_unique<LocalExecution>("<CLS_NAME>", this);
+}
+
+<CLS_NAME>::~<CLS_NAME>() {
+ _W("<CLS_NAME> dtor");
+ <CLS_NAME>_context_.reset();
+ for (auto& service : services_)
+ service->OnTerminate();
+
+ if (stub_ != nullptr)
+ rpc_port_stub_destroy(stub_);
+}
+
+void <CLS_NAME>::Listen(std::shared_ptr<<CLS_NAME>::ServiceBase::Factory> service_factory) {
+ service_factory_ = std::move(service_factory);
+ int ret = rpc_port_stub_listen(stub_);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to listen stub. error(%d)", ret);
+ if (ret == RPC_PORT_ERROR_INVALID_PARAMETER || ret == RPC_PORT_ERROR_IO_ERROR)
+ throw InvalidIOException();
+ }
+
+ <CLS_NAME>_context_->SetListening(true);
+}
+
+void <CLS_NAME>::OnConnectedCb(const char* sender, const char* instance, void* user_data) {
+ auto* handle = static_cast<<CLS_NAME>*>(user_data);
+ auto service = handle->service_factory_->CreateService(sender, instance);
+
+ rpc_port_h port;
+ int ret = rpc_port_stub_get_port(handle->stub_, RPC_PORT_PORT_CALLBACK, instance, &port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get port. error(%d)", ret);
+ return;
+ }
+
+ service->SetPort(port);
+ service->OnCreate();
+ handle->services_.emplace_back(std::move(service));
+}
+
+void <CLS_NAME>::OnDisconnectedCb(const char* sender, const char* instance, void* user_data) {
+ auto* handle = static_cast<<CLS_NAME>*>(user_data);
+ auto iter = handle->services_.begin();
+ while (iter != handle->services_.end()) {
+ if ((*iter)->GetInstance() == instance) {
+ (*iter)->OnTerminate();
+ iter = handle->services_.erase(iter);
+ break;
+ }
+
+ iter++;
+ }
+}
+
+int <CLS_NAME>::OnReceivedCb(const char* sender, const char* instance, rpc_port_h port, void* user_data) {
+ auto* handle = static_cast<<CLS_NAME>*>(user_data);
+ std::shared_ptr<ServiceBase> service;
+ for (auto& iter : handle->services_) {
+ if (iter->GetInstance() == instance) {
+ service = iter;
+ break;
+ }
+ }
+
+ if (service.get() == nullptr) {
+ _E("Failed to find <CLS_NAME> context. instance(%s)", instance);
+ return -1;
+ }
+
+ rpc_port_h callback_port;
+ int ret = rpc_port_stub_get_port(handle->stub_, RPC_PORT_PORT_CALLBACK, instance, &callback_port);
+ if (ret != 0) {
+ _E("Failed to get callback port. error(%d)", ret);
+ return -1;
+ }
+
+ rpc_port_parcel_h parcel;
+ ret = rpc_port_parcel_create_from_port(&parcel, port);
+ if (ret != 0) {
+ _E("Failed to create parcel from port. error(%d)", ret);
+ return ret;
+ }
+
+ service->Dispatch(port, callback_port, parcel, service);
+ return ret;
+}
+
+void <CLS_NAME>::OnLocalConnected(void* context, const std::string& sender, const std::string& instance, bool sync) {
+ auto service = service_factory_->CreateService(sender, instance);
+ service->SetContext(context);
+ service->OnCreate();
+ services_.emplace_back(std::move(service));
+ <CLS_NAME>_context_->Connect(context, sync);
+}
+
+void <CLS_NAME>::OnLocalDisconnected(void* context, const std::string& sender, const std::string& instance) {
+ auto iter = services_.begin();
+ while (iter != services_.end()) {
+ if ((*iter)->GetInstance() == instance) {
+ (*iter)->OnTerminate();
+ iter = services_.erase(iter);
+ break;
+ }
+
+ iter++;
+ }
+
+ <CLS_NAME>_context_->Disconnect(context);
+}
+
+void <CLS_NAME>::OnLocalReceived(void* context, rpc_port_parcel_h parcel) {
+ std::shared_ptr<ServiceBase> service;
+ for (auto& iter : services_) {
+ if (iter->GetContext() == context) {
+ service = iter;
+ break;
+ }
+ }
+
+ if (service.get() == nullptr) {
+ _E("Failed to find <CLS_NAME> context. context(%p)", context);
+ return;
+ }
+
+ service->Dispatch(nullptr, nullptr, parcel, service);
+}
+)__cpp_cb";
+
+/**
+ * <NAME> The method name of the interface.
+ * <IFACE_NAME> The interface name.
+ */
+constexpr const char CB_INTERFACE_IMPL_SERVICE_BASE_DISPATCH_FUNC_INIT[] =
+R"__cpp_cb(
+{ static_cast<int>(MethodId::<NAME>), std::bind(&<IFACE_NAME>::ServiceBase::Dispatch<NAME>, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4) },
+)__cpp_cb";
+
+constexpr const char CB_INTERFACE_IMPL_SERVICE_BASE_THREAD_MEMBER_INIT[] =
+R"__cpp_cb(
+active_object_ = std::unique_ptr<ActiveObject>(new ActiveObject());
+)__cpp_cb";
+
+constexpr const char CB_INTERFACE_SERVICE_BASE_DISPATCH_BASE[] =
+R"__cpp_cb(
+Dispatch(port, callback_port, parcel);
+)__cpp_cb";
+
+constexpr const char CB_INTERFACE_SERVICE_BASE_DISPATCH_BASE_WITH_THREAD[] =
+R"__cpp_cb(
+active_object_->Send(std::make_shared<Job>(port, callback_port, parcel, std::move(service)));
+)__cpp_cb";
+
+/**
+ * <IFACE_NAME> The interface name.
+ * <NAME> The method name of the interface.
+ * <PARAMS> The parameters of the method.
+ * <SERIALIZE> The implementation of serialization of the output parameter.
+ * <DESERIALIZE> The implementation of deserialization of the input parameter.
+ */
+constexpr const char CB_INTERFACE_SERVICE_BASE_DISPATCH_FUNC_ASYNC[] =
+R"__cpp_cb(
+void <IFACE_NAME>::ServiceBase::Dispatch<NAME>(rpc_port_h port, rpc_port_h callback_port, int seq_num, const UnitMap& unit_map) {
+ if (!CheckPrivileges(static_cast<int>(MethodId::<NAME>))) {
+ _E("Permission denied");
+ return;
+ }
+
+ <DESERIALIZE>
+ <NAME>(<PARAMS>);
+}
+)__cpp_cb";
+
+/**
+ * <IFACE_NAME> The interface name.
+ * <NAME> The method name of the interface.
+ * <PARAMS> The parameters of the method.
+ * <SERIALIZE> The implementation of serialization of the output parameter.
+ * <DESERIALIZE> The implementation of deserialization of the input parameter.
+ */
+constexpr const char CB_INTERFACE_SERVICE_BASE_DISPATCH_FUNC[] =
+R"__cpp_cb(
+void <IFACE_NAME>::ServiceBase::Dispatch<NAME>(rpc_port_h port, rpc_port_h callback_port, int seq_num, const UnitMap& unit_map) {
+ UnitMap map_;
+ if (!CheckPrivileges(static_cast<int>(MethodId::<NAME>))) {
+ _E("Permission denied");
+ RemoteException remote_except(RPC_PORT_ERROR_PERMISSION_DENIED, "Permission denied");
+ map_.Write("[REMOTE_EXCEPTION]", remote_except);
+ } else {
+ <DESERIALIZE>
+ try {
+ auto ret_ = <NAME>(<PARAMS>);
+ map_.Write("[RESULT]", ret_);
+ <SERIALIZE>
+ } catch (const RemoteException& e) {
+ _E("Exception occurs. cause(%d), message(%s)", e.GetCause(), e.GetMessage().c_str());
+ map_.Write("[REMOTE_EXCEPTION]", e);
+ }
+ }
+
+ map_.Write("[METHOD]", static_cast<int>(MethodId::__Result));
+
+ rpc_port_parcel_h parcel_;
+ rpc_port_parcel_create(&parcel_);
+
+ rpc_port_parcel_header_h header_;
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_set_seq_num(header_, seq_num);
+
+ map_.Serialize(parcel_);
+ if (GetContext() != nullptr)
+ <IFACE_NAME>_context_->SendResult(GetContext(), parcel_);
+ else
+ rpc_port_parcel_send(parcel_, port);
+ rpc_port_parcel_destroy(parcel_);
+}
+)__cpp_cb";
+
+/**
+ * <NAME> The name of the parameter.
+ */
+constexpr const char CB_INTERFACE_SERVICE_BASE_UNIT_MAP_WRITE[] =
+R"__cpp_cb(
+map_.Write("<NAME>", <NAME>);
+)__cpp_cb";
+
+/**
+ * <TYPE> The type of the parameter.
+ * <NAME> The name of the parameter.
+ */
+constexpr const char CB_INTERFACE_SERVICE_BASE_PARAM_BASE[] =
+R"__cpp_cb(
+<TYPE> <NAME>;
+)__cpp_cb";
+
+/**
+ * <TYPE> The type of the parameter.
+ * <TYPE_NAME> The type name of the parameter.
+ * <NAME> The name of the parameter.
+ */
+constexpr const char CB_INTERFACE_SERVICE_BASE_PARAM_DELEGATE[] =
+R"__cpp_cb(
+<TYPE> <NAME>(new <TYPE_NAME>(callback_port, std::weak_ptr<ServiceBase>(this->shared_from_this())));
+<NAME>->SetContext(GetContext());
+)__cpp_cb";
+
+/**
+ * <NAME> The name of the parameter.
+ */
+constexpr const char CB_INTERFACE_SERVICE_BASE_UNIT_MAP_READ[] =
+R"__cpp_cb(
+unit_map.Read("<NAME>", <NAME>);
+)__cpp_cb";
+
+/**
+ * <PRIVILEGES> The privileges of the method.
+ * <METHOD> The method name.
+ */
+constexpr const char CB_INTERFACE_SERVICE_BASE_SET_PRIVILEGE_MAP[] =
+R"__cpp_cb(
+{
+ std::vector<std::string> privileges = {
+ <PRIVILEGES>
+ };
+ privilege_map_[static_cast<int>(MethodId::<METHOD>)] = std::move(privileges);
+}
+)__cpp_cb";
+
+/**
+ * <LEM_CONTEXT> The context of the local execution of the interface.
+ */
+constexpr const char CB_LEM_ANONYMOUS_NAMESPACE[] =
+R"__cpp_cb(
+namespace {
+
+rpc_port_parcel_h Clone(rpc_port_parcel_h parcel) {
+ void* raw = nullptr;
+ unsigned int size = 0;
+ rpc_port_parcel_get_raw(parcel, &raw, &size);
+
+ rpc_port_parcel_h handle = nullptr;
+ rpc_port_parcel_create_from_raw(&handle, raw, size);
+ return handle;
+}
+
+void IdleAddOnce(std::function<void()>* func) {
+ g_idle_add([](gpointer user_data) {
+ auto* cb = static_cast<std::function<void()>*>(user_data);
+ (*cb)();
+ delete cb;
+ return G_SOURCE_REMOVE;
+ }, func);
+}
+
+<LEM_CONTEXT>
+
+} // namespace
+)__cpp_cb";
+
+/**
+ * <FILE_NAMESPACE> The file namespace.
+ * <IFACE_NAME> The interface name.
+ */
+constexpr const char CB_LEM_CONTEXT[] =
+R"__cpp_cb(
+std::shared_ptr<rpc_port::<FILE_NAMESPACE>::LocalExecution> <IFACE_NAME>_context_;
+)__cpp_cb";
+
+/**
+ * <INPUT_FILE> The file namespace.
+ */
+constexpr const char CB_LEM_BASE[] =
+R"__cpp_cb(
+LocalExecution::LocalExecution(std::string port_name, LocalExecution::IEvent* listener) : port_name_(std::move(port_name)), listener_(listener) {
+ LoadSymbols();
+}
+
+void LocalExecution::Connect(void* context, bool sync) {
+ if (connect_func_ != nullptr)
+ connect_func_(context, sync);
+}
+
+void LocalExecution::Disconnect(void* context) {
+ if (disconnect_func_ != nullptr)
+ disconnect_func_(context);
+}
+
+void LocalExecution::SendResult(void* context, rpc_port_parcel_h parcel) {
+ if (send_result_func_ != nullptr)
+ send_result_func_(context, parcel);
+}
+
+void LocalExecution::InvokeCallback(void* context, rpc_port_parcel_h parcel) {
+ if (invoke_callback_func_ != nullptr)
+ invoke_callback_func_(context, parcel);
+}
+
+void LocalExecution::OnConnected(void* context, const std::string& sender, const std::string& instance, bool sync) {
+ if (listener_ != nullptr)
+ listener_->OnLocalConnected(context, sender, instance, sync);
+}
+
+void LocalExecution::OnDisconnected(void* context, const std::string& sender, const std::string& instance) {
+ if (listener_ != nullptr)
+ listener_->OnLocalDisconnected(context, sender, instance);
+}
+
+void LocalExecution::OnReceived(void* context, rpc_port_parcel_h parcel) {
+ if (listener_ != nullptr)
+ listener_->OnLocalReceived(context, parcel);
+}
+
+bool LocalExecution::LoadSymbols() {
+ if (loaded_)
+ return true;
+
+ std::string symbol = "rpc_port_proxy_<INPUT_FILE>_lem_" + port_name_ + "_connect";
+ connect_func_ = reinterpret_cast<ProxyConnectFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+ if (connect_func_ == nullptr) {
+ _E("Failed to find symbol");
+ return false;
+ }
+
+ symbol = "rpc_port_proxy_<INPUT_FILE>_lem_" + port_name_ + "_disconnect";
+ disconnect_func_ = reinterpret_cast<ProxyDisconnectFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+ if (disconnect_func_ == nullptr) {
+ _E("Failed to find symbol");
+ return false;
+ }
+
+ symbol = "rpc_port_proxy_<INPUT_FILE>_lem_" + port_name_ + "_send_result";
+ send_result_func_ = reinterpret_cast<ProxySendResultFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+ if (send_result_func_ == nullptr) {
+ _E("Failed to find symbol");
+ return false;
+ }
+
+ symbol = "rpc_port_proxy_<INPUT_FILE>_lem_" + port_name_ + "_invoke_callback";
+ invoke_callback_func_ = reinterpret_cast<ProxyInvokeCallbackFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+ if (invoke_callback_func_ == nullptr) {
+ _E("Failed to find symbol");
+ return false;
+ }
+
+ loaded_ = true;
+ return true;
+}
+
+void LocalExecution::SetListening(bool listening) {
+ listening_ = listening;
+}
+
+bool LocalExecution::IsListening() const {
+ return listening_;
+}
+)__cpp_cb";
+
+/**
+ * <INPUT_FILE> The input file name.
+ * <CLS_NAME> The interface name.
+ */
+constexpr const char CB_LEM_API[] =
+R"__cpp_cb(
+EXPORT_API int rpc_port_stub_<INPUT_FILE>_lem_<CLS_NAME>_connect(void* context, const char* sender, const char* instance, bool sync) {
+ if (<CLS_NAME>_context_.get() == nullptr || !<CLS_NAME>_context_->IsListening()) {
+ _E("Server is not ready");
+ return RPC_PORT_ERROR_IO_ERROR;
+ }
+
+ if (gettid() != getpid()) {
+ std::string sender_str(sender);
+ std::string instance_str(instance);
+ auto* func = new std::function<void()>([context, sender_str, instance_str, sync] {
+ <CLS_NAME>_context_->OnConnected(context, sender_str, instance_str, sync);
+ });
+ IdleAddOnce(func);
+ } else {
+ <CLS_NAME>_context_->OnConnected(context, sender, instance, sync);
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_stub_<INPUT_FILE>_lem_<CLS_NAME>_disconnect(void* context, const char* sender, const char* instance) {
+ if (<CLS_NAME>_context_.get() == nullptr || !<CLS_NAME>_context_->IsListening()) {
+ _E("Server is not ready");
+ return RPC_PORT_ERROR_IO_ERROR;
+ }
+
+ if (gettid() != getpid()) {
+ std::string sender_str(sender);
+ std::string instance_str(instance);
+ auto* func = new std::function<void()>([context, sender_str, instance_str] {
+ <CLS_NAME>_context_->OnDisconnected(context, sender_str, instance_str);
+ });
+ IdleAddOnce(func);
+ } else {
+ <CLS_NAME>_context_->OnDisconnected(context, sender, instance);
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_stub_<INPUT_FILE>_lem_<CLS_NAME>_send(void* context, rpc_port_parcel_h parcel) {
+ if (<CLS_NAME>_context_.get() == nullptr || !<CLS_NAME>_context_->IsListening()) {
+ _E("Server is not ready");
+ return RPC_PORT_ERROR_IO_ERROR;
+ }
+
+ rpc_port_parcel_h cloned_parcel = Clone(parcel);
+ if (getpid() != getpid()) {
+ auto* func = new std::function<void()>([context, cloned_parcel] {
+ <CLS_NAME>_context_->OnReceived(context, cloned_parcel);
+ });
+ IdleAddOnce(func);
+ } else {
+ <CLS_NAME>_context_->OnReceived(context, cloned_parcel);
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__cpp_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_CPP_STUB_BODY_GENERATOR_CB_HH_
diff --git a/idlc/gen/version2/cpp_stub_header_generator.cc b/idlc/gen/version2/cpp_stub_header_generator.cc
new file mode 100644
index 0000000..9453b42
--- /dev/null
+++ b/idlc/gen/version2/cpp_stub_header_generator.cc
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/cpp_stub_header_generator.hh"
+
+#include <utility>
+
+#include "idlc/gen/version2/cpp_generator_base_cb.hh"
+#include "idlc/gen/version2/cpp_stub_header_generator_cb.hh"
+
+namespace tidl {
+namespace version2 {
+
+CppStubHeaderGenerator::CppStubHeaderGenerator(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options)
+ : CppGeneratorBase(std::move(doc)), options_(std::move(options)) {}
+
+void CppStubHeaderGenerator::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenIncludeDefaultHeaders(stream, false);
+ GenNamespace(stream);
+}
+
+void CppStubHeaderGenerator::OnFiniGen(std::ofstream& stream) {}
+
+void CppStubHeaderGenerator::GenNamespace(std::ofstream& stream) {
+ ReplaceAll(CB_NAMESPACE_STUB)
+ .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
+ .Change("<STRUCTURES>", GenLemBaseWithStructures())
+ .Change("<BASE_IMPL>", GenBaseImpl())
+ .Change("<INTERFACES>", GenInterfaces())
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+}
+
+std::string CppStubHeaderGenerator::GenLemBaseWithStructures() {
+ std::string code = CB_LEM_BASE;
+ code += NLine(1);
+ code += GenStructuresForHeader();
+ return code;
+}
+
+std::string CppStubHeaderGenerator::GenBaseImpl() {
+ std::string code = GenExceptions();
+ code += GenRemoteExceptionForHeader();
+ if (options_->IsThreadEnabled())
+ code += CB_THREAD_BASE;
+
+ return code;
+}
+
+std::string CppStubHeaderGenerator::GenInterfaces() {
+ std::string code;
+ for (auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<Interface&>(*block);
+ code += GenInterface(iface) + NLine(1);
+ }
+
+ return code;
+}
+
+std::string CppStubHeaderGenerator::GenInterface(const Interface& iface) {
+ return std::string(
+ ReplaceAll(CB_INTERFACE_BASE)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Change("<CALLBACKS>", GenInterfaceCallbacks(iface))
+ .Change("<ENUMS>", GenEnumerations(iface.GetEnums()))
+ .Change("<SERVICE_BASE_METHODS>",
+ GenInterfaceServiceBaseMethods(iface))
+ .Change("<SERVICE_BASE_DISPATCH_FUNCS>",
+ GenInterfaceServiceBaseDispatchFuncs(iface))
+ .Change("<SERVICE_BASE_IMPL_THREAD_MEMBER>",
+ GenInterfaceServiceBaseImplThreadMember())
+ .Change("<METHOD_IDS>", GenMethodIds(iface))
+ .Change("<DELEGATE_IDS>", GenDelegateIds(iface)));
+}
+
+std::string CppStubHeaderGenerator::GenInterfaceCallbacks(
+ const Interface& iface) {
+ std::string code;
+ code += ReplaceAll(CB_INTERFACE_CALLBACK_BASE)
+ .Change("<IFACE_NAME>", iface.GetID());
+ code += NLine(1);
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_INTERFACE_CALLBACK)
+ .Change("<CLS_NAME>", decl->GetID())
+ .Change("<PARAMS>", GetParameters(decl->GetParameters()));
+ code += NLine(1);
+ }
+
+ if (options_->IsThreadEnabled())
+ code += CB_INTERFACE_PENDING_JOB;
+
+ return RemoveLine(code);
+}
+
+std::string CppStubHeaderGenerator::GenInterfaceServiceBaseMethods(
+ const Interface& iface) {
+ std::string code;
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_INTERFACE_SERVICE_BASE_METHOD)
+ .Change("<RETURN_TYPE>", ConvertTypeToString(decl->GetType()))
+ .Change("<NAME>", decl->GetID())
+ .Change("<PARAMS>", GetParameters(decl->GetParameters()));
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppStubHeaderGenerator::GenInterfaceServiceBaseDispatchFuncs(
+ const Interface& iface) {
+ std::string code;
+ for (const auto& decl : iface.GetDeclarations()) {
+ if (decl->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_INTERFACE_SERVICE_BASE_DISPATCH_FUNC)
+ .Change("<NAME>", decl->GetID());
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CppStubHeaderGenerator::GenInterfaceServiceBaseImplThreadMember() {
+ if (options_->IsThreadEnabled())
+ return std::string(CB_INTERFACE_SERVICE_BASE_IMPL_THREAD_MEMBER);
+
+ return "";
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/cpp_stub_header_generator.hh b/idlc/gen/version2/cpp_stub_header_generator.hh
new file mode 100644
index 0000000..e124fc7
--- /dev/null
+++ b/idlc/gen/version2/cpp_stub_header_generator.hh
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CPP_STUB_HEADER_GENERATOR_HH_
+#define IDLC_GEN_VERSION2_CPP_STUB_HEADER_GENERATOR_HH_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/version2/cpp_generator_base.hh"
+#include "idlc/options.h"
+
+namespace tidl {
+namespace version2 {
+
+class CppStubHeaderGenerator : public CppGeneratorBase {
+ public:
+ explicit CppStubHeaderGenerator(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options);
+ virtual ~CppStubHeaderGenerator() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ std::string GenLemBaseWithStructures();
+ std::string GenBaseImpl();
+ std::string GenInterfaces();
+ std::string GenInterface(const Interface& iface);
+ std::string GenInterfaceCallbacks(const Interface& iface);
+ std::string GenInterfaceServiceBaseMethods(const Interface& iface);
+ std::string GenInterfaceServiceBaseDispatchFuncs(const Interface& iface);
+ std::string GenInterfaceServiceBaseImplThreadMember();
+
+ private:
+ std::shared_ptr<Options> options_;
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_CPP_STUB_HEADER_GENERATOR_HH_
diff --git a/idlc/gen/version2/cpp_stub_header_generator_cb.hh b/idlc/gen/version2/cpp_stub_header_generator_cb.hh
new file mode 100644
index 0000000..562491a
--- /dev/null
+++ b/idlc/gen/version2/cpp_stub_header_generator_cb.hh
@@ -0,0 +1,448 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CPP_STUB_HEADER_GENERATOR_CB_HH_
+#define IDLC_GEN_VERSION2_CPP_STUB_HEADER_GENERATOR_CB_HH_
+
+namespace tidl {
+namespace version2 {
+
+constexpr const char CB_THREAD_BASE[] =
+R"__cpp_cb(
+class Job {
+ public:
+ class IEvent {
+ public:
+ virtual ~IEvent() = default;
+ virtual void OnRun() = 0;
+ };
+
+ Job(IEvent* listener) : listener_(listener) {}
+ Job() = default;
+ virtual ~Job() = default;
+
+ Job(const Job& job) {
+ listener_ = job.listener_;
+ }
+
+ Job& operator = (const Job& job) {
+ if (this != &job)
+ listener_ = job.listener_;
+
+ return *this;
+ }
+
+ Job(Job&& job) noexcept {
+ listener_ = job.listener_;
+ job.listener_ = nullptr;
+ }
+
+ Job& operator = (Job&& job) noexcept {
+ if (this != &job) {
+ listener_ = job.listener_;
+ job.listener_ = nullptr;
+ }
+
+ return *this;
+ }
+
+ void Do() {
+ if (listener_ != nullptr)
+ listener_->OnRun();
+ }
+
+ private:
+ IEvent* listener_ = nullptr;
+};
+
+template <class T>
+class SharedQueue {
+ public:
+ SharedQueue() = default;
+ virtual ~SharedQueue() = default;
+
+ void Push(T item) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ queue_.push_back(item);
+ cond_var_.notify_one();
+ }
+
+ void PushFront(T item) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ queue_.push_front(item);
+ cond_var_.notify_one();
+ }
+
+ bool TryAndPop(T& item) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ if (queue_.empty())
+ return false;
+
+ item = queue_.front();
+ queue_.pop_front();
+
+ return true;
+ }
+
+ void WaitAndPop(T& item) {
+ std::unique_lock<std::mutex> lock(mutex_);
+ while (queue_.empty())
+ cond_var_.wait(lock);
+
+ item = queue_.front();
+ queue_.pop_front();
+ }
+
+ bool Empty() {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return queue_.empty();
+ }
+
+ int Size() {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return queue_.size();
+ }
+
+ private:
+ std::deque<T> queue_;
+ mutable std::mutex mutex_;
+ std::condition_variable cond_var_;
+};
+
+class ActiveObject : public Job::IEvent {
+ public:
+ ActiveObject() {
+ thread_ = std::thread([&]() -> void { RunThread(); });
+ }
+
+ virtual ~ActiveObject() {
+ Quit();
+ thread_.join();
+ }
+
+ void Send(std::shared_ptr<Job> job) {
+ queue_.Push(std::move(job));
+ }
+
+ private:
+ void Quit() {
+ Send(std::make_shared<Job>(new Job(this)));
+ }
+
+ void OnRun() override {
+ done_ = true;
+ }
+
+ void RunThread() {
+ do {
+ std::shared_ptr<Job> item;
+ queue_.WaitAndPop(item);
+ item->Do();
+ } while (!done_);
+ }
+
+ private:
+ std::thread thread_;
+ bool done_ = false;
+ SharedQueue<std::shared_ptr<Job>> queue_;
+};
+)__cpp_cb";
+
+/**
+ * <IFACE_NAME> The interface name.
+ */
+constexpr const char CB_INTERFACE_CALLBACK_BASE[] =
+R"__cpp_cb(
+class ServiceBase;
+
+class CallbackBase {
+ public:
+ CallbackBase(int delegate_id, bool once);
+ CallbackBase() = default;
+ virtual ~CallbackBase() = default;
+
+ int GetId() const;
+ void SetId(int id);
+ int GetSeqId() const;
+ void SetSeqId(int seq_id);
+ bool IsOnce() const;
+ void SetOnce(bool once);
+
+ std::string GetTag() const;
+
+ void SetContext(void* context);
+ void* GetContext() const;
+
+ private:
+ static std::atomic<int> seq_num_;
+ int id_ = 0;
+ int seq_id_ = 0;
+ bool once_ = false;
+ void* context_ = nullptr;
+};
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the callback.
+ * <PARAMS> The parameters of the callback.
+ */
+constexpr const char CB_INTERFACE_CALLBACK[] =
+R"__cpp_cb(
+class <CLS_NAME> : public CallbackBase {
+ public:
+ <CLS_NAME>(rpc_port_h callback_port, std::weak_ptr<ServiceBase> service) : CallbackBase(static_cast<int>(DelegateId::<CLS_NAME>), false), callback_port_(callback_port), service_(std::move(service)) {}
+
+ void Invoke(<PARAMS>);
+
+ private:
+ rpc_port_h callback_port_;
+ std::weak_ptr<ServiceBase> service_;
+ bool valid_ = true;
+};
+)__cpp_cb";
+
+constexpr const char CB_INTERFACE_PENDING_JOB[] =
+R"__cpp_cb(
+class PendingJob : public Job, Job::IEvent {
+ public:
+ PendingJob(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel, std::shared_ptr<ServiceBase> service);
+
+ virtual ~PendingJob();
+
+ private:
+ void OnRun() override;
+
+ private:
+ rpc_port_h port_;
+ rpc_port_h callback_port_;
+ rpc_port_parcel_h parcel_;
+ std::shared_ptr<ServiceBase> service_;
+};
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The class name of the interface.
+ * <CALLBACKS> The callbacks of the interface.
+ * <SERVICE_BASE_METHODS> The methods of service base of the interface.
+ * <SERVICE_BASE_DISPATCH_FUNCS> The dispatch function of service base of the interface.
+ * <SERVICE_BASE_IMPL_THREAD_MEMBER> The member variable of the thread of service base.
+ * <METHOD_IDS> The enumeration of methods of the interface.
+ * <DELEGATE_IDS> The enumeration of delegates(callbacks) of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__cpp_cb(
+class <CLS_NAME> : public LocalExecution::IEvent {
+ public:
+ <ENUMS>
+ <CALLBACKS>
+ class ServiceBase : public std::enable_shared_from_this<ServiceBase> {
+ public:
+ class Factory {
+ public:
+ virtual ~Factory() = default;
+
+ /// <summary>
+ /// The method for making service instances
+ /// </summary>
+ /// <param name="sender">The client app ID</param>
+ /// <param name="instance">The client instance ID</param>
+ virtual std::unique_ptr<ServiceBase> CreateService(std::string sender, std::string instance) = 0;
+ };
+
+ virtual ~ServiceBase() = default;
+
+ /// <summary>
+ /// Gets client app ID
+ /// </summary>
+ const std::string& GetSender() const {
+ return sender_;
+ }
+
+ /// <summary>
+ /// Gets client instance ID
+ /// </summary>
+ const std::string& GetInstance() const {
+ return instance_;
+ }
+
+ /// <summary>
+ /// Sets the client app port
+ /// </summary>
+ /// <param name="port">The port of the client</param>
+ void SetPort(rpc_port_h port);
+
+ /// <summary>
+ /// Disconnects from the client app
+ /// </summary>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ void Disconnect();
+
+ /// <summary>
+ /// This method will be called when the client is connected
+ /// </summary>
+ virtual void OnCreate() = 0;
+
+ /// <summary>
+ /// This method will be called when the client is disconnected
+ /// </summary>
+ virtual void OnTerminate() = 0;
+
+ void SetContext(void* context);
+ void* GetContext() const;
+ void Dispatch(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel, std::shared_ptr<ServiceBase> service);
+ void Dispatch(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel);
+
+ <SERVICE_BASE_METHODS>
+
+ protected:
+ ServiceBase(std::string sender, std::string instance);
+
+ private:
+ using DispatchFunc = std::function<void(rpc_port_h, rpc_port_h, int, const UnitMap&)>;
+
+ static bool PrivilegeInfoCb(const char* privilege_name, void* user_data);
+ void LoadPrivileges();
+ void SetPrivilegeMap();
+ bool CheckPrivileges(int method_id);
+ <SERVICE_BASE_DISPATCH_FUNCS>
+
+ <SERVICE_BASE_IMPL_THREAD_MEMBER>
+
+ private:
+ std::string sender_;
+ std::string instance_;
+ rpc_port_h port_ = nullptr;
+ std::unordered_map<int, DispatchFunc> dispatch_funcs_;
+ std::unordered_map<int, std::vector<std::string>> privilege_map_;
+ std::unordered_set<std::string> privileges_;
+ void* context_ = nullptr;
+ };
+
+ <CLS_NAME>();
+ ~<CLS_NAME>();
+
+ /// <summary>
+ /// Listens to client apps
+ /// </summary>
+ /// <param name="service_factory">The factory object for making service instances</param>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ void Listen(std::shared_ptr<ServiceBase::Factory> service_factory);
+
+ /// <summary>
+ /// Gets service objects which are connected
+ /// </summary>
+ /// <returns>The list of service objects which are connected</returns>
+ const std::list<std::shared_ptr<ServiceBase>>& GetServices() const {
+ return services_;
+ }
+
+ private:
+ <METHOD_IDS>
+ <DELEGATE_IDS>
+
+ static void OnConnectedCb(const char* sender, const char* instance, void* user_data);
+ static void OnDisconnectedCb(const char* sender, const char* instance, void* user_data);
+ static int OnReceivedCb(const char* sender, const char* instance, rpc_port_h port, void* user_data);
+
+ void OnLocalConnected(void* context, const std::string& sender, const std::string& instance, bool sync) override;
+ void OnLocalDisconnected(void* context, const std::string& sender, const std::string& instance) override;
+ void OnLocalReceived(void* context, rpc_port_parcel_h parcel) override;
+
+ private:
+ rpc_port_stub_h stub_ = nullptr;
+ std::shared_ptr<ServiceBase::Factory> service_factory_;
+ std::list<std::shared_ptr<ServiceBase>> services_;
+};
+)__cpp_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the method of the interface.
+ * <NAME> The method name of the interface.
+ * <PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_SERVICE_BASE_METHOD[] =
+R"__cpp_cb(
+virtual <RETURN_TYPE> <NAME>(<PARAMS>) = 0;
+)__cpp_cb";
+
+/**
+ * <NAME> The method name of the interface.
+ */
+constexpr const char CB_INTERFACE_SERVICE_BASE_DISPATCH_FUNC[] =
+R"__cpp_cb(
+void Dispatch<NAME>(rpc_port_h port, rpc_port_h callback_port, int seq_num, const UnitMap& unit_map);
+)__cpp_cb";
+
+constexpr const char CB_INTERFACE_SERVICE_BASE_IMPL_THREAD_MEMBER[] =
+R"__cpp_cb(
+std::unique_ptr<ActiveObject> active_object_;
+)__cpp_cb";
+
+constexpr const char CB_LEM_BASE[] =
+R"__cpp_cb(
+class LocalExecution {
+ public:
+ class IEvent {
+ public:
+ virtual ~IEvent() = default;
+ virtual void OnLocalConnected(void* context, const std::string& sender, const std::string& instance, bool sync) = 0;
+ virtual void OnLocalDisconnected(void* context, const std::string& sender, const std::string& instance) = 0;
+ virtual void OnLocalReceived(void* context, rpc_port_parcel_h parcel) = 0;
+ };
+
+ LocalExecution(std::string port_name, IEvent* listener);
+ virtual ~LocalExecution() = default;
+
+ void Connect(void* context, bool sync);
+ void Disconnect(void* context);
+ void SendResult(void* context, rpc_port_parcel_h parcel);
+ void InvokeCallback(void* context, rpc_port_parcel_h parcel);
+
+ void OnConnected(void* context, const std::string& sender, const std::string& instance, bool sync);
+ void OnDisconnected(void* context, const std::string& sender, const std::string& instance);
+ void OnReceived(void* context, rpc_port_parcel_h parcel);
+
+ void SetListening(bool listening);
+ bool IsListening() const;
+
+ bool LoadSymbols();
+
+ private:
+ using ProxyConnectFunc = int (*)(void*, bool);
+ using ProxyDisconnectFunc = int (*)(void*);
+ using ProxySendResultFunc = int (*)(void*, rpc_port_parcel_h);
+ using ProxyInvokeCallbackFunc = int (*)(void*, rpc_port_parcel_h);
+
+ private:
+ std::string port_name_;
+ IEvent* listener_;
+ bool listening_ = false;
+ bool loaded_ = false;
+ ProxyConnectFunc connect_func_ = nullptr;
+ ProxyDisconnectFunc disconnect_func_ = nullptr;
+ ProxySendResultFunc send_result_func_ = nullptr;
+ ProxyInvokeCallbackFunc invoke_callback_func_ = nullptr;
+};
+)__cpp_cb";
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_CPP_STUB_HEADER_GENERATOR_CB_HH_
diff --git a/idlc/gen/version2/cs_generator_base.cc b/idlc/gen/version2/cs_generator_base.cc
new file mode 100644
index 0000000..8c7aa5d
--- /dev/null
+++ b/idlc/gen/version2/cs_generator_base.cc
@@ -0,0 +1,867 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/cs_generator_base.h"
+
+#include <ctime>
+#include <unordered_map>
+#include <vector>
+
+namespace {
+#include "idlc/gen/cs_cb_version.h"
+#include "idlc/gen/version2/cs_generator_base_cb.h"
+} // namespace
+
+namespace tidl {
+namespace version2 {
+
+CsGeneratorBase::CsGeneratorBase(std::shared_ptr<Document> doc)
+ : Generator(doc) {
+ type_map_ = {
+ {"char", "byte"}, {"int", "int"}, {"short", "short"},
+ {"long", "long"}, {"string", "string"}, {"bool", "bool"},
+ {"list", "LinkedList"}, {"array", "List"}, {"float", "float"},
+ {"double", "double"}, {"bundle", "Bundle"}, {"void", "void"},
+ {"file", "string"}, {"set", "HashSet"}, {"map", "Dictionary"}};
+
+ parcel_type_map_ = {{"char", "Byte"}, {"int", "Int"},
+ {"short", "Short"}, {"long", "Long"},
+ {"string", "String"}, {"bool", "Bool"},
+ {"float", "Float"}, {"double", "Double"},
+ {"bundle", "Bundle"}, {"file", "String"}};
+}
+
+void CsGeneratorBase::GenStructures(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_STRUCTURE) continue;
+ Structure& st = static_cast<Structure&>(*i);
+ GenStructure(stream, st);
+ stream << std::endl;
+ }
+}
+
+void CsGeneratorBase::GenRemoteException(std::ofstream& stream) {
+ stream << CB_REMOTE_EXCEPTION_BASE;
+}
+
+void CsGeneratorBase::GenUsingNamespace(std::ofstream& stream) {
+ stream << CB_USING_NAMESPACE;
+}
+
+std::string CsGeneratorBase::GenEnum(const Block& block, int tab_size) {
+ std::string str;
+ for (const auto& e : block.GetEnums()) {
+ str += Tab(tab_size) + "public enum " + e->GetID() + " {" + NLine(1);
+ for (auto& f : e->GetFields()) {
+ if (f->GetValue().empty()) {
+ str += Tab(tab_size + 1) + f->GetID() + "," + NLine(1);
+ } else {
+ str += Tab(tab_size + 1) + f->GetID() + " = " + f->GetValue() + "," +
+ NLine(1);
+ }
+ }
+ str += Tab(tab_size) + "}" + NLine(1);
+ }
+ return str;
+}
+
+void CsGeneratorBase::GenEnum(std::ofstream& stream, const Block& block,
+ int tab_size) {
+ stream << GenEnum(block, tab_size);
+}
+
+void CsGeneratorBase::GenStructure(std::ofstream& stream, const Structure& st) {
+ std::vector<std::string> v;
+
+ stream << Tab(1) << "public class " << st.GetID();
+
+ if (st.GetBase() == nullptr) {
+ stream << NLine(1);
+ } else {
+ stream << " : " << st.GetBase()->GetID() << NLine(1);
+ }
+
+ GenBrace(stream, TAB_SIZE, [&]() {
+ GenEnum(stream, st, 2);
+ for (const auto& i : st.GetElements()) {
+ GenTemplate(
+ CB_PROPERTY, stream,
+ [&]() -> std::string { return ConvertTypeToString(i->GetType()); },
+ [&]() -> std::string { return i->GetID(); });
+ if (i->GetType().ToString() == "bundle" ||
+ i->GetType().ToString() == "map" ||
+ i->GetType().ToString() == "set") {
+ v.push_back(i->GetID() + " = " + "new " +
+ ConvertTypeToString(i->GetType()) + "()");
+ }
+ }
+
+ GenTemplate(
+ CB_CTOR, stream, [&]() -> std::string { return st.GetID(); },
+ [&]() -> std::string {
+ std::string str;
+ for (auto& i : v) {
+ str += " " + i + ";\n";
+ }
+ return str;
+ });
+ });
+}
+
+void CsGeneratorBase::GenSerializer(std::ofstream& stream,
+ const Structure& st) {
+ stream << GetSerializer(st);
+}
+
+std::string CsGeneratorBase::GetStructureSerialize(const Structure& st) {
+ std::string code;
+ std::string type_str;
+
+ for (const auto& i : st.GetElements()) {
+ code += Tab(4) + "map.Write(\"" + i->GetID() + "\", param." +
+ i->GetID() + ");" + NLine(1);
+ }
+
+ if (st.GetBase() != nullptr)
+ code += GetStructureSerialize(*st.GetBase());
+
+ return code;
+}
+
+std::string CsGeneratorBase::GetStructureDeserialize(const Structure& st) {
+ std::string code;
+ std::string type_str;
+
+ for (const auto& i : st.GetElements()) {
+ auto& t = i->GetType();
+ if (t.IsEnumType())
+ type_str = "int";
+ else
+ type_str = GetTypeString(t);
+
+ code += Tab(4) + "map.Read(\"" + i->GetID() + "\", out param." +
+ i->GetID() + ");" + NLine(1);
+ }
+
+ if (st.GetBase() != nullptr)
+ code += GetStructureDeserialize(*st.GetBase());
+
+ return code;
+}
+
+std::string CsGeneratorBase::GetSerializer(const Structure& st) {
+ std::string str(ReplaceAll(CB_SERIALIZER)
+ .Change("<TYPE>", st.GetID())
+ .Change("<BODY>", GetStructureSerialize(st)));
+
+ str += ReplaceAll(CB_DESERIALIZER)
+ .Change("<TYPE>", st.GetID())
+ .Change("<BODY>", GetStructureDeserialize(st));
+ return str;
+}
+
+void CsGeneratorBase::GenSerializer(std::ofstream& stream) {
+ stream << GetSerializer();
+
+ if (GetChannelType() != ChannelType::TYPE_GROUP)
+ stream << CB_REMOTE_EXCEPTION_SERIALIZE;
+}
+
+std::string CsGeneratorBase::GetSerializer() {
+ std::string str;
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() == Block::TYPE_STRUCTURE) {
+ const Structure& st = static_cast<const Structure&>(*i);
+ str += GetSerializer(st);
+ }
+ }
+
+ return str;
+}
+
+void CsGeneratorBase::AddSerializerList(const BaseType& type,
+ const std::string& st_id) {
+ if (type.GetMetaType() != nullptr) {
+ if (type.GetMetaType()->GetUserDefinedType() == BaseType::UserType::ENUM &&
+ !st_id.empty()) {
+ BaseType new_type(type.ToString(), "", type.GetUserDefinedType());
+ BaseType* new_meta =
+ new BaseType(st_id + "." + type.GetMetaType()->ToString(), "",
+ BaseType::UserType::ENUM);
+ new_type.SetMetaType(new_meta);
+ serializer_list_[ConvertTypeToString(type, st_id)] = new_type;
+ return;
+ }
+
+ serializer_list_[ConvertTypeToString(type, st_id)] = type;
+ AddSerializerList(*type.GetMetaType(), st_id);
+ } else if (type.GetKeyType() != nullptr && type.GetValueType() != nullptr) {
+ if (type.GetValueType()->IsEnumType() && !st_id.empty()) {
+ BaseType new_type(type.ToString(), "", type.GetUserDefinedType());
+ BaseType* new_key = new BaseType(*(type.GetKeyType()));
+ BaseType* new_value =
+ new BaseType(st_id + "." + type.GetValueType()->ToString(), "",
+ BaseType::UserType::ENUM);
+
+ new_type.SetKeyType(new_key);
+ new_type.SetValueType(new_value);
+ serializer_list_[ConvertTypeToString(type, st_id)] = new_type;
+ return;
+ }
+ serializer_list_[ConvertTypeToString(type, st_id)] = type;
+ }
+}
+
+std::string CsGeneratorBase::GenListWrite(const BaseType& type,
+ const std::string& type_str) {
+ std::string ret;
+
+ if (type.ToString() == "map") {
+ ret = CB_LIST_MAP_WRITE;
+ } else if (type.ToString() == "set") {
+ ret = CB_LIST_SET_WRITE;
+ } else {
+ ret = CB_LIST_WRITE;
+ }
+
+ return ret;
+}
+
+std::string CsGeneratorBase::GenListRead(const BaseType& type,
+ const std::string& type_str) {
+ std::string ret;
+
+ if (type.ToString() == "map") {
+ if (type.GetValueType()->IsEnumType()) {
+ ret = ReplaceAll(CB_LIST_MAP_READ)
+ .Change("<KEY_TYPE>", ConvertTypeToString(*type.GetKeyType()))
+ .Change("<VALUE_TYPE>", type.GetValueType()->ToString());
+ } else {
+ ret =
+ ReplaceAll(CB_LIST_MAP_READ)
+ .Change("<KEY_TYPE>", ConvertTypeToString(*type.GetKeyType()))
+ .Change("<VALUE_TYPE>",
+ ConvertTypeToString(*type.GetValueType()));
+ }
+ } else if (type.ToString() == "set") {
+ ret = ReplaceAll(CB_LIST_SET_READ)
+ .Change("<VALUE_TYPE>", ConvertTypeToString(*type.GetMetaType()));
+ } else if (type.GetMetaType()->IsEnumType()) {
+ std::string list_method;
+ if (type.ToString() == "list")
+ list_method = "Last";
+
+ ret = ReplaceAll(CB_LIST_READ)
+ .Change("<LIST_METHOD>", list_method)
+ .Change("<VALUE_TYPE>", type.GetMetaType()->ToString());
+ } else {
+ std::string list_method;
+ if (type.ToString() == "list")
+ list_method = "Last";
+
+ ret = ReplaceAll(CB_LIST_READ)
+ .Change("<LIST_METHOD>", list_method)
+ .Change("<VALUE_TYPE>", ConvertTypeToString(*type.GetMetaType()));
+ }
+
+ return ret;
+}
+
+std::string CsGeneratorBase::GetLengthName(const BaseType& type) {
+ if (type.ToString() == "list") {
+ return "length";
+ } else {
+ return "size";
+ }
+}
+std::string CsGeneratorBase::GetListSerializer(const BaseType& type,
+ const std::string& type_str) {
+ std::string code;
+ code = ReplaceAll(CB_LIST_SERIALIZER)
+ .Change("<TYPE>", type_str)
+ .Change("<LENGTH_NAME>", GetLengthName(type))
+ .Change("<WRITE_LIST>", GenListWrite(type, type_str));
+
+ code += ReplaceAll(CB_LIST_DESERIALIZER)
+ .Change("<TYPE>", type_str)
+ .Change("<LENGTH_NAME>", GetLengthName(type))
+ .Change("<READ_LIST>", GenListRead(type, type_str));
+
+ return code;
+}
+
+void CsGeneratorBase::GenListSerializer(std::ofstream& stream) {
+ stream << GetListSerializer();
+}
+
+std::string CsGeneratorBase::GetListSerializer() {
+ serializer_list_.clear();
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() == Block::TYPE_STRUCTURE) {
+ const Structure& st = static_cast<const Structure&>(*i);
+ for (const auto& j : st.GetElements()) {
+ auto& t = j->GetType();
+ AddSerializerList(t, st.GetID());
+ }
+ } else if (i->GetType() == Block::TYPE_INTERFACE) {
+ const Interface& iface = static_cast<const Interface&>(*i);
+ for (const auto& j : iface.GetDeclarations()) {
+ auto& t = j->GetType();
+ AddSerializerList(t);
+ for (const auto& k : j->GetParameters()) {
+ auto& t1 = k->GetParameterType().GetBaseType();
+ AddSerializerList(t1);
+ }
+ }
+ }
+ }
+
+ std::string ret;
+ for (auto& p : serializer_list_) {
+ auto& type_str = p.first;
+ auto& t = p.second;
+ ret += GetListSerializer(t, type_str);
+ }
+
+ return ret;
+}
+
+std::string CsGeneratorBase::ConvertTypeToString(const BaseType& type,
+ const std::string& st_id) {
+ if (type.GetUserDefinedType() == BaseType::UserType::ENUM && !st_id.empty()) {
+ return st_id + "." + type.ToString();
+ }
+
+ if (type.IsUserDefinedType())
+ return type.ToString();
+
+ if (type.GetMetaType() != nullptr)
+ return type_map_[type.ToString()] + "<" +
+ ConvertTypeToString(*(type.GetMetaType()), st_id) + ">";
+
+ if (type.GetKeyType() != nullptr && type.GetValueType() != nullptr) {
+ return type_map_[type.ToString()] + "<" +
+ ConvertTypeToString(*(type.GetKeyType()), st_id) + ", " +
+ ConvertTypeToString(*(type.GetValueType()), st_id) + ">";
+ }
+
+ return type_map_[type.ToString()];
+}
+
+std::string CsGeneratorBase::ConvertTypeToParcelType(const std::string& key) {
+ return parcel_type_map_[key];
+}
+
+std::string CsGeneratorBase::ConvertTypeToDeserializer(
+ const BaseType& type, std::string gen_id, std::string param_id,
+ std::string map, bool make_new_type, std::string iface_id) {
+ std::string ret;
+ std::string new_type = "";
+
+ if (make_new_type) {
+ if (type.IsUserDefinedType() || type.GetMetaType() != nullptr) {
+ if (type.GetMetaType() != nullptr)
+ new_type = ConvertTypeToString(type);
+ else
+ new_type = type.ToString();
+ } else {
+ new_type = ConvertTypeToString(type);
+ }
+ }
+
+ ret += map + ".Read(" + "\"" + param_id + "\", out ";
+ if (IsDelegateType(type)) {
+ ret += "CallbackBase del_" + gen_id + ");\n";
+ ret += ReplaceAll(CB_DLELGATGE_CREATE)
+ .Change("<TYPE>", new_type)
+ .Change("<GEN_ID>", gen_id);
+ } else {
+ if (make_new_type) {
+ ret += new_type + " " + gen_id + ");\n";
+ } else {
+ ret += gen_id + ");\n";
+ }
+ }
+
+ return ret;
+}
+
+std::string CsGeneratorBase::ConvertTypeToSerializer(std::string gen_id,
+ std::string param_id,
+ std::string map) {
+
+ return map + ".Write(\"" + param_id + "\", " + gen_id + ");\n";
+}
+
+std::string CsGeneratorBase::Tab(int cnt) {
+ std::string t;
+
+ for (int i = 0; i < cnt; i++) {
+ t += " ";
+ }
+
+ return t;
+}
+
+std::string CsGeneratorBase::NLine(int cnt) {
+ std::string t;
+
+ for (int i = 0; i < cnt; i++) {
+ t += "\n";
+ }
+
+ return t;
+}
+
+void CsGeneratorBase::GenWriteBundle(std::ofstream& stream,
+ const std::string& id) {
+ GenTemplate(
+ CB_WRITE_BUNDLE, stream, [&]() -> std::string { return id; },
+ [&]() -> std::string { return id; });
+}
+
+std::string CsGeneratorBase::GetMethodId(const Interface& iface) {
+ return std::string(ReplaceAll(CB_METHOD_IDS).Change("<METHOD_IDS>", [&]() {
+ int cnt = 2;
+ std::string str;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE) continue;
+ str +=
+ Tab(4) + i->GetID() + " = " + std::to_string(cnt++) + "," + NLine(1);
+ }
+ return str;
+ }));
+}
+
+void CsGeneratorBase::GenMethodId(std::ofstream& stream,
+ const Interface& iface) {
+ stream << GetMethodId(iface);
+}
+
+void CsGeneratorBase::GenDelegateId(std::ofstream& stream,
+ const Interface& iface) {
+ if (HasDelegate(iface) == false)
+ return;
+
+ stream << Tab(3) << "private enum DelegateId : int" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 3, [&]() {
+ int cnt = 1;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE) continue;
+ stream << Tab(4) << i->GetID() << " = " << cnt++ << "," << NLine(1);
+ }
+ });
+ stream << NLine(1);
+}
+
+void CsGeneratorBase::GenDeclaration(std::ofstream& stream,
+ const Declaration& decl, bool semicol) {
+ stream << GetDeclaration(decl, semicol);
+}
+
+std::string CsGeneratorBase::GetDeclaration(const Declaration& decl,
+ bool semicol) {
+ std::string ret;
+ ret += ConvertTypeToString(decl.GetType()) + " " + decl.GetID() + "(";
+ ret += GetParameters(decl.GetParameters());
+ if (semicol)
+ ret += ");";
+ else
+ ret += ")";
+ return ret;
+}
+
+void CsGeneratorBase::GenParameters(std::ofstream& stream,
+ const Parameters& ps) {
+ stream << GetParameters(ps);
+}
+
+bool CsGeneratorBase::HasDelegate(const Interface& iface) {
+ bool found = false;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE) {
+ found = true;
+ break;
+ }
+ }
+ return found;
+}
+
+std::string CsGeneratorBase::GetParameters(const Parameters& ps) {
+ bool first = true;
+ std::string ret;
+ for (const auto& i : ps) {
+ if (!first) {
+ ret += ", ";
+ }
+
+ auto dir = i->GetParameterType().GetDirection();
+ if (dir == ParameterType::Direction::OUT) {
+ ret += "out ";
+ } else if (dir == ParameterType::Direction::REF) {
+ ret += "ref ";
+ }
+
+ ret += ConvertTypeToString(i->GetParameterType().GetBaseType()) + " " +
+ i->GetID();
+ first = false;
+ }
+
+ return ret;
+}
+
+std::string CsGeneratorBase::GenUnitMapParamType(const BaseType& base_type,
+ const std::string& type_str) {
+ std::string ret;
+ if (base_type.GetUserDefinedType() == BaseType::UserType::DELEGATE)
+ ret = "CallbackBase";
+ else if (base_type.GetFullName() == "[REMOTE_EXCEPTION]")
+ ret = "RemoteException";
+ else
+ ret = type_str;
+
+ return ret;
+}
+
+std::string CsGeneratorBase::GenUnitMapParamInit(const Interface& iface,
+ const BaseType& base_type,
+ const std::string& type_str) {
+ std::string ret;
+
+ if (base_type.GetUserDefinedType() == BaseType::UserType::DELEGATE) {
+ ret = "value = new CallbackBase(1, false);";
+ } else if (type_str == "string") {
+ ret = "value = new string(\"\");";
+ } else if (type_str == "[REMOTE_EXCEPTION]") {
+ ret = "value = new RemoteException();";
+ } else {
+ ret = "value = new " + type_str + "();";
+ }
+
+ return ret;
+}
+
+std::string CsGeneratorBase::GetEnumTypeString(const BaseType& base_type) {
+ std::string ret = base_type.GetFullName(true);
+ auto pos = ret.find('.');
+ if (pos == std::string::npos)
+ return ret;
+
+ std::string block_id = ret.substr(0, pos);
+ std::string type_id = ret.substr(pos + 1, ret.size() - (pos + 1));
+ return block_id + "_" + type_id;
+}
+
+std::string CsGeneratorBase::GetStructTypeString(const Structure& st) {
+ std::string str;
+
+ if (st.GetBase() != nullptr) {
+ str += GetStructTypeString(*st.GetBase()) + "::";
+ }
+ str += st.GetID();
+
+ return str;
+}
+
+std::string CsGeneratorBase::GetStructTypeString(const BaseType& base_type) {
+ std::string str;
+
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() == Block::TYPE_STRUCTURE) {
+ const Structure& st = static_cast<const Structure&>(*i);
+ if (st.GetID() == base_type.GetFullName()) {
+ str = GetStructTypeString(st);
+ break;
+ }
+ }
+ }
+
+ return str;
+}
+
+std::string CsGeneratorBase::GetTypeString(const BaseType& base_type) {
+ std::string ret;
+
+ if (!base_type.IsUserDefinedType() && base_type.GetMetaType() == nullptr &&
+ base_type.GetKeyType() == nullptr) {
+ if (base_type.ToString() == "file")
+ ret = base_type.ToString();
+ else
+ ret = ConvertTypeToString(base_type);
+ } else if (base_type.GetUserDefinedType() == BaseType::UserType::DELEGATE) {
+ ret = "delegate";
+ } else if (base_type.GetUserDefinedType() == BaseType::UserType::STRUCTURE) {
+ ret = GetStructTypeString(base_type);
+ } else if (base_type.IsUserDefinedType()) {
+ ret = ConvertTypeToString(base_type);
+ } else {
+ ret = GetEnumTypeString(base_type);
+ }
+
+ return ret;
+}
+
+std::string CsGeneratorBase::GenUnitMaUintWrite(const Interface& iface,
+ const BaseType& base_type) {
+ std::string ret;
+
+ if (!base_type.IsUserDefinedType() && base_type.GetMetaType() == nullptr &&
+ base_type.GetKeyType() == nullptr) {
+ ret = "unit.parcel.Write" + ConvertTypeToParcelType(base_type.ToString()) +
+ "(value);";
+ } else if (base_type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ ret = "unit.parcel.WriteInt((int)value);";
+ } else if (base_type.GetUserDefinedType() == BaseType::UserType::DELEGATE) {
+ ret = "CallbackBase.Serialize(unit.parcel, value);";
+ } else {
+ ret = iface.GetID() + ".Serialize(unit.parcel, value);";
+ }
+
+ return ret;
+}
+
+std::string CsGeneratorBase::GenUnitMaUintRead(const Interface& iface,
+ const BaseType& base_type,
+ const std::string& type_str) {
+ std::string ret;
+
+ if (!base_type.IsUserDefinedType() && base_type.GetMetaType() == nullptr &&
+ base_type.GetKeyType() == nullptr) {
+ ret = "value = unit.parcel.Read" +
+ ConvertTypeToParcelType(base_type.ToString()) + "();";
+ } else if (base_type.GetUserDefinedType() == BaseType::UserType::ENUM) {
+ ret = "int enum_int = unit.parcel.ReadInt();" + NLine(1) + Tab(1) +
+ "value = (" + type_str + ")enum_int;";
+ } else if (base_type.GetUserDefinedType() == BaseType::UserType::DELEGATE) {
+ ret = "CallbackBase.Deserialize(unit.parcel, value);";
+ } else {
+ ret = iface.GetID() + ".Deserialize(unit.parcel, value);";
+ }
+
+ return ret;
+}
+
+void CsGeneratorBase::AddTypeMap(
+ std::unordered_map<std::string, BaseType>& types, const BaseType& base_type,
+ const std::string& st_id) {
+ types[ConvertTypeToString(base_type, st_id)] = base_type;
+
+ if (base_type.GetMetaType() != nullptr) {
+ AddTypeMap(types, *base_type.GetMetaType(), st_id);
+ }
+
+ if (base_type.GetKeyType() != nullptr) {
+ AddTypeMap(types, *base_type.GetKeyType(), st_id);
+
+ if (base_type.GetValueType() != nullptr) {
+ AddTypeMap(types, *base_type.GetValueType(), st_id);
+ }
+ }
+}
+
+std::string CsGeneratorBase::GenUnitMapReadWrite(const Interface& iface) {
+ std::unordered_map<std::string, BaseType> types;
+ BaseType bI("int", "int");
+ BaseType bS("string", "string");
+ BaseType bB("bool", "bool");
+
+ if (GetChannelType() != ChannelType::TYPE_GROUP) {
+ BaseType bE("[REMOTE_EXCEPTION]", "", BaseType::UserType::STRUCTURE);
+ types[bE.GetFullName()] = bE;
+ }
+
+ types[bI.GetFullName()] = bI;
+ types[bS.GetFullName()] = bS;
+ types[bB.GetFullName()] = bB;
+
+ for (const auto& i : iface.GetDeclarations()) {
+ types[ConvertTypeToString(i->GetType())] = i->GetType();
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE) {
+ BaseType del(i->GetID(), "", BaseType::UserType::DELEGATE);
+ AddTypeMap(types, del);
+ }
+
+ for (const auto& j : i->GetParameters()) {
+ auto& type = j->GetParameterType().GetBaseType();
+ AddTypeMap(types, type);
+ }
+ }
+
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() == Block::TYPE_STRUCTURE) {
+ const Structure& st = static_cast<const Structure&>(*i);
+ for (const auto& i : st.GetElements()) {
+ auto& type = i->GetType();
+
+ std::string name = type.GetFullName();
+ std::size_t pos = name.find('.');
+
+ if (pos == std::string::npos) {
+ AddTypeMap(types, type, st.GetID());
+ } else {
+ std::string st_id = name.substr(0, pos);
+ std::string enum_id = name.substr(pos + 1, name.size() - (pos + 1));
+ BaseType enum_type(enum_id, "", BaseType::UserType::ENUM);
+ AddTypeMap(types, enum_type, st_id);
+ }
+ }
+ }
+ }
+
+ types.erase("void");
+
+ std::string code = "";
+ for (const auto& iter : types) {
+ auto& type_str = iter.first;
+ auto& base_type = iter.second;
+
+ std::string unit_type;
+ if (base_type.IsEnumType())
+ unit_type = "int";
+ else
+ unit_type = GetTypeString(base_type);
+
+ code +=
+ ReplaceAll(CB_UNITMAP_READ_READ_BASE)
+ .Change("<PARAM_TYPE>", GenUnitMapParamType(base_type, type_str))
+ .Change("<PARAM_INIT>",
+ GenUnitMapParamInit(iface, base_type, type_str))
+ .Change("<UNIT_TYPE>", unit_type)
+ .Change("<UINT_READ>",
+ GenUnitMaUintRead(iface, base_type, type_str));
+ code +=
+ ReplaceAll(CB_UNITMAP_READ_WRITE_BASE)
+ .Change("<PARAM_TYPE>", GenUnitMapParamType(base_type, type_str))
+ .Change("<UNIT_TYPE>", unit_type)
+ .Change("<UINT_WRITE>", GenUnitMaUintWrite(iface, base_type));
+ }
+
+ return AddIndent(TAB_SIZE, code);
+}
+
+void CsGeneratorBase::GenUnitMap(std::ofstream& stream, const Interface& iface,
+ int tabSize) {
+ stream << GetUnitMap(iface, tabSize);
+}
+
+std::string CsGeneratorBase::GetUnitMap(const Interface& iface, int tabSize) {
+ std::string ret_string(CB_UNIT_BASE);
+ ret_string += ReplaceAll(CB_UNITMAP_BASE)
+ .Change("<PARAM_READ_WRITE>", GenUnitMapReadWrite(iface));
+ return AddIndent(TAB_SIZE * tabSize, ret_string);
+}
+
+void CsGeneratorBase::GenCallbacks(std::ofstream& stream,
+ const Interface& iface, bool is_proxy) {
+ if (HasDelegate(iface) == false)
+ return;
+ stream << CB_CALLBACK_BASE;
+
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+ GenCallback(stream, *i, iface.GetID(), is_proxy);
+ }
+}
+
+void CsGeneratorBase::GenCallback(std::ofstream& stream,
+ const Declaration& decl,
+ const std::string& id, bool is_proxy) {
+ stream << Tab(3) << "public sealed class " << decl.GetID()
+ << " : CallbackBase" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 3, [&]() {
+ if (is_proxy) {
+ GenTemplate(
+ CB_CALLBACK_CTOR_PROXY, stream,
+ [&]() -> std::string { return decl.GetID(); },
+ [&]() -> std::string { return decl.GetID(); });
+ } else {
+ GenTemplate(
+ CB_CALLBACK_CTOR_STUB, stream,
+ [&]() -> std::string { return decl.GetID(); },
+ [&]() -> std::string { return decl.GetID(); },
+ [&]() -> std::string { return decl.GetID(); });
+ }
+ stream << NLine(1);
+
+ if (is_proxy) {
+ stream << Tab(4) << "public delegate void Callback(";
+ GenParameters(stream, decl.GetParameters());
+ stream << ");" << NLine(1);
+ stream << Tab(4) << "public event Callback Received;" << NLine(2);
+ GenReceivedEvent(stream, decl, id);
+ } else {
+ stream << CB_CALLBACK_STUB_MEMBERS;
+ GenInvokeMethod(stream, decl, id);
+ }
+ });
+ stream << NLine(1);
+}
+
+void CsGeneratorBase::GenReceivedEvent(std::ofstream& stream,
+ const Declaration& decl,
+ const std::string& id) {
+ stream << Tab(4) << "internal override void OnReceivedEvent(UnitMap map)"
+ << NLine(1);
+ GenBrace(stream, TAB_SIZE * 4, [&]() {
+ int cnt = 1;
+ for (const auto& i : decl.GetParameters()) {
+ std::string v = "param" + std::to_string(cnt);
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, i->GetID(), "map", true, id);
+ stream << AddIndent(TAB_SIZE * 5, c);
+ cnt++;
+ }
+
+ cnt = 1;
+ stream << NLine(1) << Tab(5) << "Received?.Invoke(";
+ for (auto i = decl.GetParameters().begin(); i != decl.GetParameters().end();
+ ++i) {
+ if (cnt != 1) {
+ stream << ", ";
+ }
+ std::string v = "param" + std::to_string(cnt);
+ stream << v;
+ cnt++;
+ }
+ stream << ");" << NLine(1);
+ });
+ stream << NLine(1);
+}
+
+void CsGeneratorBase::GenInvokeMethod(std::ofstream& stream,
+ const Declaration& decl,
+ const std::string& id) {
+ GenTemplate(
+ CB_CALLBACK_INVOKE_METHOD, stream,
+ [&]() -> std::string { return GetParameters(decl.GetParameters()); },
+ [&]() -> std::string {
+ std::string m;
+ for (const auto& i : decl.GetParameters()) {
+ m += ConvertTypeToSerializer(i->GetID(), i->GetID(), "map");
+ }
+ return AddIndent(TAB_SIZE * 5, m);
+ });
+}
+
+void CsGeneratorBase::GenVersion(std::ofstream& stream) {
+ GenTemplate(::cs_cb_version, stream,
+ [&]() -> std::string { return FULLVER; });
+ stream << NLine(1);
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/cs_generator_base.h b/idlc/gen/version2/cs_generator_base.h
new file mode 100644
index 0000000..39ffa75
--- /dev/null
+++ b/idlc/gen/version2/cs_generator_base.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_GEN_VERSION2_CS_GENRATOR_BASE_H_
+#define IDLC_CS_GEN_VERSION2_CS_GENRATOR_BASE_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "idlc/ast/structure.h"
+#include "idlc/ast/type.h"
+#include "idlc/gen/generator.h"
+
+namespace tidl {
+namespace version2 {
+
+class CsGeneratorBase : public Generator {
+ public:
+ explicit CsGeneratorBase(std::shared_ptr<Document> doc);
+ virtual ~CsGeneratorBase() = default;
+
+ void GenVersion(std::ofstream& stream);
+ void GenStructures(std::ofstream& stream);
+ void GenStructure(std::ofstream& stream, const Structure& st);
+ void GenSerializer(std::ofstream& stream);
+ std::string GetSerializer();
+ void GenSerializer(std::ofstream& stream, const Structure& st);
+ std::string GetSerializer(const Structure& st);
+ void GenListSerializer(std::ofstream& stream);
+ std::string GetListSerializer();
+ std::string GetListSerializer(const BaseType& type,
+ const std::string& st_id = "");
+ void GenMethodId(std::ofstream& stream, const Interface& iface);
+ std::string GetMethodId(const Interface& iface);
+ void GenDelegateId(std::ofstream& stream, const Interface& iface);
+ void GenDeclaration(std::ofstream& stream, const Declaration& decl,
+ bool semicol = true);
+ std::string GetDeclaration(const Declaration& decl, bool semicol = true);
+ void GenParameters(std::ofstream& stream, const Parameters& ps);
+ void GenCallbacks(std::ofstream& stream, const Interface& iface,
+ bool is_proxy);
+
+ std::string ConvertTypeToString(const BaseType& type,
+ const std::string& st_id = "");
+ std::string ConvertTypeToDeserializer(const BaseType& type,
+ std::string gen_id,
+ std::string parma_id, std::string map,
+ bool make_new_type = true,
+ const std::string iface_id = "");
+ std::string ConvertTypeToSerializer(std::string gen_id, std::string param_id,
+ std::string map);
+ std::string ConvertTypeToParcelType(const std::string& key);
+ std::string GetParameters(const Parameters& ps);
+ std::string Tab(int cnt);
+ std::string NLine(int cnt);
+ void GenUnitMap(std::ofstream& stream, const Interface& iface, int tabSize);
+ std::string GetUnitMap(const Interface& iface, int tabSize);
+ std::string GetTypeString(const BaseType& base_type);
+ void GenUsingNamespace(std::ofstream& stream);
+ void GenEnum(std::ofstream& stream, const Block& block, int tab);
+ std::string GenEnum(const Block& block, int tab_size);
+ bool HasDelegate(const Interface& iface);
+ void GenRemoteException(std::ofstream& stream);
+
+ protected:
+ const int TAB_SIZE = 4;
+
+ private:
+ std::string GetEnumTypeString(const BaseType& base_type);
+ void AddTypeMap(std::unordered_map<std::string, BaseType>& types,
+ const BaseType& base_type, const std::string& st_id = "");
+ void GenWriteBundle(std::ofstream& stream, const std::string& id);
+ void AddSerializerList(const BaseType& type, const std::string& st_id = "");
+ void GenCallback(std::ofstream& stream, const Declaration& decl,
+ const std::string& id, bool is_proxy);
+ void GenReceivedEvent(std::ofstream& stream, const Declaration& decl,
+ const std::string& id);
+ void GenInvokeMethod(std::ofstream& stream, const Declaration& decl,
+ const std::string& id);
+ std::string GenUnitMapReadWrite(const Interface& iface);
+ std::string GenUnitMapParamType(const BaseType& base_type,
+ const std::string& type_str);
+ std::string GenUnitMaUintRead(const Interface& iface,
+ const BaseType& base_type,
+ const std::string& type_str);
+ std::string GenUnitMaUintWrite(const Interface& iface,
+ const BaseType& base_type);
+ std::string GenListWrite(const BaseType& type, const std::string& type_str);
+ std::string GenListRead(const BaseType& type, const std::string& type_str);
+ std::string GetLengthName(const BaseType& type);
+ std::string GenUnitMapParamInit(const Interface& iface,
+ const BaseType& base_type,
+ const std::string& type_str);
+ std::string GetStructureSerialize(const Structure& st);
+ std::string GetStructureDeserialize(const Structure& st);
+ std::string GetStructTypeString(const BaseType& base_type);
+ std::string GetStructTypeString(const Structure& st);
+
+ private:
+ std::map<std::string, std::string> type_map_;
+ std::map<std::string, std::string> parcel_type_map_;
+ std::map<std::string, BaseType> serializer_list_;
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_CS_GEN_VERSION2_CS_GENRATOR_BASE_H_ \ No newline at end of file
diff --git a/idlc/gen/version2/cs_generator_base_cb.h b/idlc/gen/version2/cs_generator_base_cb.h
new file mode 100644
index 0000000..60aae64
--- /dev/null
+++ b/idlc/gen/version2/cs_generator_base_cb.h
@@ -0,0 +1,416 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_GEN_VERSION2_CS_GENRATOR_BASE_CB_H_
+#define IDLC_CS_GEN_VERSION2_CS_GENRATOR_BASE_CB_H_
+
+const char CB_USING_NAMESPACE[] =
+R"__cs_cb(
+using System;
+using System.Collections.Generic;
+using System.Collections.Concurrent;
+using System.Threading;
+using System.Reflection;
+using Tizen.Applications;
+using Tizen.Applications.RPCPort;
+
+)__cs_cb";
+
+const char CB_REMOTE_EXCEPTION_BASE[] =
+R"__cs_cb(
+ public class RemoteException : Exception
+ {
+ public RemoteException()
+ {
+ }
+
+ public RemoteException(string message)
+ {
+ this.Message = message;
+ }
+
+ public RemoteException(string message, int cause)
+ {
+ this.Message = message;
+ this.Cause = cause;
+ }
+
+ public new string Message { get; set; }
+ public int Cause { get; set; }
+ }
+
+)__cs_cb";
+
+const char CB_REMOTE_EXCEPTION_SERIALIZE[] =
+R"__cs_cb(
+ private static void Serialize(Parcel h, RemoteException param)
+ {
+ UnitMap map = new UnitMap();
+ map.Write("cause", param.Cause);
+ map.Write("message", param.Message);
+
+ map.Serialize(h);
+ }
+
+ private static void Deserialize(Parcel h, RemoteException param)
+ {
+ UnitMap map = new UnitMap();
+ map.Deserialize(h);
+ map.Read("cause", out int cause);
+ param.Cause = cause;
+ map.Read("message", out string message);
+ param.Message = message;
+ }
+)__cs_cb";
+
+
+const char CB_UNIT_BASE[] =
+R"__cs_cb(
+internal class Unit
+{
+ internal string name;
+ internal string type;
+ internal Parcel parcel;
+ internal Unit()
+ {
+ parcel = new Parcel(false);
+ }
+
+ internal void Serialize(Parcel h)
+ {
+ h.WriteString(name);
+ h.WriteString(type);
+
+ byte[] raw = parcel.ToBytes();
+ h.WriteArrayCount(raw.Length & int.MaxValue);
+ h.Write(raw);
+ }
+
+ internal void Deserialize(Parcel h)
+ {
+ name = h.ReadString();
+ type = h.ReadString();
+
+ int size = h.ReadArrayCount();
+ byte[] raw = h.Read(size);
+ parcel.Write(raw);
+ }
+}
+)__cs_cb";
+
+
+const char CB_UNITMAP_READ_READ_BASE[] =
+R"__cs_cb(
+internal void Read(string name, out <PARAM_TYPE> value)
+{
+ <PARAM_INIT>
+ if (map.ContainsKey(name) == false)
+ {
+ Tizen.Log.Error("RPC_PORT", "Not exist key " + name);
+ return;
+ }
+
+ Unit unit = map[name];
+ if (unit.type != "<UNIT_TYPE>")
+ {
+ Tizen.Log.Error("RPC_PORT", "type is not <UNIT_TYPE> : " + unit.type);
+ return;
+ }
+ <UINT_READ>
+}
+)__cs_cb";
+
+const char CB_UNITMAP_READ_WRITE_BASE[] =
+R"__cs_cb(
+internal void Write(string name, <PARAM_TYPE> value)
+{
+ Unit unit = new Unit();
+ unit.name = name;
+ unit.type = "<UNIT_TYPE>";
+ <UINT_WRITE>
+ map[name] = unit;
+}
+)__cs_cb";
+
+const char CB_UNITMAP_BASE[] =
+R"__cs_cb(
+internal class UnitMap
+{
+ internal Dictionary<string, Unit> map;
+ internal UnitMap()
+ {
+ map = new Dictionary<string, Unit>();
+ }
+
+ internal void Serialize(Parcel parcel)
+ {
+ parcel.WriteArrayCount(map.Count & int.MaxValue);
+ foreach (Unit unit in map.Values) {
+ unit.Serialize(parcel);
+ }
+ }
+
+ internal void Deserialize(Parcel parcel)
+ {
+ int size = parcel.ReadArrayCount();
+
+ for (int i = 0; i < size; i++) {
+ Unit unit = new Unit();
+ unit.Deserialize(parcel);
+
+ map[unit.name] = unit;
+ }
+ }
+
+ internal bool ContainsName(string name)
+ {
+ return map.ContainsKey(name);
+ }
+ <PARAM_READ_WRITE>
+}
+)__cs_cb";
+
+const char CB_CALLBACK_BASE[] =
+R"__cs_cb(
+ public class CallbackBase
+ {
+ internal int Id;
+ internal int SeqId;
+ internal bool Once;
+ private static volatile int _seqNum = 0;
+
+ public string Tag
+ {
+ get
+ {
+ return Id.ToString() + "::" + SeqId.ToString();
+ }
+ }
+
+ public CallbackBase(int delegateId, bool once)
+ {
+ Id = delegateId;
+ SeqId = _seqNum++;
+ Once = once;
+ }
+
+ internal virtual void OnReceivedEvent(UnitMap map) {}
+
+ internal static void Serialize(Parcel h, CallbackBase param)
+ {
+ UnitMap map = new UnitMap();
+ map.Write("id", param.Id);
+ map.Write("seq_id", param.SeqId);
+ map.Write("once", param.Once);
+ map.Serialize(h);
+ }
+
+ internal static void Deserialize(Parcel h, CallbackBase param)
+ {
+ UnitMap map = new UnitMap();
+ map.Deserialize(h);
+ map.Read("id", out param.Id);
+ map.Read("seq_id", out param.SeqId);
+ map.Read("once", out param.Once);
+ }
+ }
+
+)__cs_cb";
+
+const char CB_CALLBACK_CTOR_PROXY[] =
+R"__cs_cb( public $$(bool once = false) : base((int)DelegateId.$$, once)
+ {
+ }
+)__cs_cb";
+
+const char CB_CALLBACK_CTOR_STUB[] =
+R"__cs_cb( internal $$(Port port, WeakReference service) : base((int)DelegateId.$$, false)
+ {
+ _port = port;
+ _service = service;
+ }
+
+ internal $$(Port port, WeakReference service, CallbackBase cb) : base(cb.Id, cb.Once)
+ {
+ _port = port;
+ _service = service;
+ SeqId = cb.SeqId;
+ }
+)__cs_cb";
+
+const char CB_CALLBACK_STUB_MEMBERS[] =
+R"__cs_cb( private Port _port;
+ private WeakReference _service;
+ private bool _valid = true;
+ internal LocalExecution _lem;
+)__cs_cb";
+
+const char CB_CALLBACK_INVOKE_METHOD[] =
+R"__cs_cb(
+ public void Invoke($$)
+ {
+ if (_port == null && _lem == null)
+ throw new NotConnectedSocketException();
+ if (!_service.IsAlive)
+ throw new InvalidProtocolException();
+ if (Once && !_valid)
+ throw new InvalidCallbackException();
+ if (_lem != null && _lem._online == false)
+ throw new NotConnectedSocketException();
+
+ var p = new Parcel();
+ UnitMap map = new UnitMap();
+
+ map.Write("[METHOD]", (int)MethodId.__Callback);
+ map.Write("delegate", this);
+
+$$
+ map.Serialize(p);
+
+ if (_lem != null)
+ {
+ _lem.SendRequest(p);
+ } else
+ {
+ // Send
+ p.Send(_port);
+ }
+ _valid = false;
+ }
+)__cs_cb";
+
+const char CB_PROPERTY[] = R"__cs_cb( public $$ $$;
+)__cs_cb";
+
+const char CB_CTOR[] = R"__cs_cb(
+ public $$()
+ {
+$$
+ }
+)__cs_cb";
+
+const char CB_DLELGATGE_CREATE[] =
+R"__cs_cb(
+Port cb_port;
+if (b._lem != null)
+ cb_port = null;
+else
+ cb_port = GetPort(Port.Type.Callback, instance);
+
+<TYPE> <GEN_ID> = new <TYPE>(cb_port, new WeakReference(b), del_<GEN_ID>);
+
+if (b._lem != null)
+ param3._lem = b._lem;
+)__cs_cb";
+
+
+const char CB_WRITE_BUNDLE[] =
+R"__cs_cb(
+ if (param.$$ != null)
+ {
+ h.WriteBundle(param.$$);
+ }
+ else
+ {
+ h.WriteBundle(new Bundle());
+ }
+)__cs_cb";
+
+const char CB_METHOD_IDS[] =
+R"__cs_cb(
+ private enum MethodId : int
+ {
+ __Result = 0,
+ __Callback = 1,
+<METHOD_IDS>
+ }
+)__cs_cb";
+
+const char CB_SERIALIZER[] =
+R"__cs_cb(
+ private static void Serialize(Parcel h, <TYPE> param)
+ {
+ UnitMap map = new UnitMap();
+<BODY>
+ map.Serialize(h);
+ }
+)__cs_cb";
+
+const char CB_DESERIALIZER[] =
+R"__cs_cb(
+ private static void Deserialize(Parcel h, <TYPE> param)
+ {
+ UnitMap map = new UnitMap();
+ map.Deserialize(h);
+<BODY>
+ }
+)__cs_cb";
+
+constexpr const char CB_LIST_MAP_WRITE[] =
+R"__cs_cb( map.Write("key-" + index.ToString(), i.Key);
+ map.Write("value-" + index.ToString(), i.Value);)__cs_cb";
+
+constexpr const char CB_LIST_SET_WRITE[] =
+R"__cs_cb( map.Write("key-" + index.ToString(), i);)__cs_cb";
+
+constexpr const char CB_LIST_WRITE[] =
+R"__cs_cb( map.Write(index.ToString(), i);)__cs_cb";
+
+constexpr const char CB_LIST_MAP_READ[] =
+R"__cs_cb( map.Read("key-" + index.ToString(), out <KEY_TYPE> key);
+ map.Read("value-" + index.ToString(), out <VALUE_TYPE> value);
+ param[key] = value;)__cs_cb";
+
+constexpr const char CB_LIST_SET_READ[] =
+R"__cs_cb( map.Read("key-" + index.ToString(), out <VALUE_TYPE> value);
+ param.Add(value);)__cs_cb";
+
+constexpr const char CB_LIST_READ[] =
+R"__cs_cb( map.Read("key-" + index.ToString(), out <VALUE_TYPE> value);
+ param.Add<LIST_METHOD>(value);)__cs_cb";
+
+const char CB_LIST_SERIALIZER[] =
+R"__cs_cb(
+ private static void Serialize(Parcel h, <TYPE> param)
+ {
+ UnitMap map = new UnitMap();
+ map.Write("<LENGTH_NAME>", param.Count & int.MaxValue);
+ int index = 0;
+ foreach (var i in param)
+ {
+<WRITE_LIST>
+ index++;
+ }
+ map.Serialize(h);
+ }
+)__cs_cb";
+
+const char CB_LIST_DESERIALIZER[] =
+R"__cs_cb(
+ private static void Deserialize(Parcel h, <TYPE> param)
+ {
+ UnitMap map = new UnitMap();
+ map.Deserialize(h);
+ map.Read("<LENGTH_NAME>", out int length);
+ for (int index = 0; index < length; index++)
+ {
+<READ_LIST>
+ }
+ }
+)__cs_cb";
+
+
+#endif // IDLC_CS_GEN_VERSION2_CS_GENRATOR_BASE_CB_H_
diff --git a/idlc/gen/version2/cs_group_generator.cc b/idlc/gen/version2/cs_group_generator.cc
new file mode 100644
index 0000000..747062c
--- /dev/null
+++ b/idlc/gen/version2/cs_group_generator.cc
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/cs_group_generator.h"
+
+namespace {
+#include "idlc/gen/version2/cs_group_generator_cb.h"
+}
+
+namespace tidl {
+namespace version2 {
+
+CsGroupGen::CsGroupGen(std::shared_ptr<Document> doc) : CsGeneratorBase(doc) {}
+
+void CsGroupGen::OnInitGen(std::ofstream& stream) {
+ SetChannelType(Generator::ChannelType::TYPE_GROUP);
+ GenVersion(stream);
+
+ GenUsingNamespace(stream);
+ stream << CB_USING_NAMESPACE_GROUP;
+
+ GenNamespace(stream);
+}
+
+void CsGroupGen::OnFiniGen(std::ofstream& stream) {}
+
+void CsGroupGen::GenNamespace(std::ofstream& stream) {
+ stream << NLine(1);
+ stream << "namespace RPCPort" << NLine(1);
+ GenBrace(stream, 0, [&]() {
+ stream << "namespace " << GetFileNamespace() << NLine(1);
+ GenBrace(stream, 0, [&]() {
+ GenStructures(stream);
+ stream << Tab(1) << "namespace Group" << NLine(1);
+ GenBrace(stream, TAB_SIZE, [&]() {
+ GenInterfaces(stream);
+ });
+ });
+ });
+}
+
+void CsGroupGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE) continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ GenInterface(stream, iface);
+ stream << NLine(1);
+ }
+}
+
+void CsGroupGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_FULL)
+ .Change("<CLS_NAME>", iface.GetID())
+ .Change("<ENUMS>", GenEnum(iface, 3))
+ .Change("<UNITMAP>", GetUnitMap(iface, 3))
+ .Change("<METHOD_IDS>", GetMethodId(iface))
+ .Change("<SERIALIZER>", GetSerializer())
+ .Change("<LIST_SERIALIZER>", GetListSerializer())
+ .Change("<METHODS>", GetMethods(iface))
+ .Change("<DISPATCHERS>", GetDispatchers(iface))
+ .Out(stream);
+}
+
+std::string CsGroupGen::GetDispatchers(const Interface& iface) {
+ std::string ret;
+ for (const auto& i : iface.GetDeclarations()) {
+ ret += ReplaceAll(CB_DISPATCHER)
+ .Change("<METHOD_ID>", i->GetID())
+ .Change("<PARAM_DESERIALIZER>", GetParamDeserializer(*i))
+ .Change("<CALL_PARAMS>", GetCallParams(*i));
+ }
+
+ return ret;
+}
+
+std::string CsGroupGen::GetMethods(const Interface& iface) {
+ std::string ret;
+ auto& decls = iface.GetDeclarations();
+ for (const auto& i : decls) {
+ ret += ReplaceAll(CB_METHOD)
+ .Change("<PARAMS>", GetParameters(i->GetParameters()))
+ .Change("<COMMENTS>",
+ i->GetComments().empty()
+ ? ""
+ : AddIndent(TAB_SIZE * 3, i->GetComments()))
+ .Change("<DECL>", GetDeclaration(*i, false))
+ .Change("<METHOD_ID>", i->GetID())
+ .Change("<PARAM_SERIALIZER>", GetParamSerializer(*i))
+ .Change("<CLS_NAME>", iface.GetID());
+ }
+
+ return ret;
+}
+
+std::string CsGroupGen::GetParamSerializer(const Declaration& decl) {
+ std::string m;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT)
+ continue;
+ m += Tab(5) + ConvertTypeToSerializer(i->GetID(), i->GetID(), "map");
+ }
+
+ return m;
+}
+
+std::string CsGroupGen::GetParamDeserializer(const Declaration& decl) {
+ int cnt = 1;
+ std::string m;
+ for (const auto& i : decl.GetParameters()) {
+ if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT) {
+ cnt++;
+ continue;
+ }
+
+ std::string v = "param" + std::to_string(cnt);
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, i->GetID(), "map");
+ m += AddIndent(TAB_SIZE * 6, c);
+
+ cnt++;
+ }
+
+ return m;
+}
+
+std::string CsGroupGen::GetCallParams(const Declaration& decl) {
+ int cnt = 1;
+ std::string m;
+ for (const auto& i : decl.GetParameters()) {
+ if (cnt != 1) {
+ m += ", ";
+ }
+
+ std::string v = "param" + std::to_string(cnt);
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT) {
+ m += "out " + ConvertTypeToString(pt.GetBaseType()) + " ";
+ } else if (pt.GetDirection() == ParameterType::Direction::REF) {
+ m += "ref ";
+ }
+ m += v;
+ cnt++;
+ }
+
+ return m;
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/cs_group_generator.h b/idlc/gen/version2/cs_group_generator.h
new file mode 100644
index 0000000..19d2c1e
--- /dev/null
+++ b/idlc/gen/version2/cs_group_generator.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CS_GROUP_GENRATOR_H_
+#define IDLC_GEN_VERSION2_CS_GROUP_GENRATOR_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/version2/cs_generator_base.h"
+
+namespace tidl {
+namespace version2 {
+
+class CsGroupGen : public CsGeneratorBase {
+ public:
+ explicit CsGroupGen(std::shared_ptr<Document> doc);
+ virtual ~CsGroupGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ std::string GetMethods(const Interface& iface);
+ std::string GetParamSerializer(const Declaration& decl);
+ std::string GetParamDeserializer(const Declaration& decl);
+ std::string GetDispatchers(const Interface& iface);
+ std::string GetCallParams(const Declaration& decl);
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_GEN_VERSION2_CS_GROUP_GENRATOR_H_ \ No newline at end of file
diff --git a/idlc/gen/version2/cs_group_generator_cb.h b/idlc/gen/version2/cs_group_generator_cb.h
new file mode 100644
index 0000000..074ebe6
--- /dev/null
+++ b/idlc/gen/version2/cs_group_generator_cb.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_VERSION2_CS_GROUP_GENRATOR_CB_H_
+#define IDLC_GEN_VERSION2_CS_GROUP_GENRATOR_CB_H_
+
+const char CB_USING_NAMESPACE_GROUP[] =
+R"__cs_cb(using Tizen.Applications.EventManager;
+
+)__cs_cb";
+
+const char CB_INTERFACE_FULL[] =
+R"__cs_cb(
+ public class <CLS_NAME> : IDisposable
+ {
+<ENUMS>
+ private EventReceiver _eventReceiver;
+ private Object _lock = new Object();
+ private bool _disposedValue = false;
+ private string _senderAppid;
+<UNITMAP>
+ private Bundle GetBundleFromParcel(Parcel p)
+ {
+ byte[] bytes = p.ToBytes();
+ Bundle b = new Bundle();
+ b.AddItem("TIDL_RAW", bytes);
+ return b;
+ }
+
+ private Parcel GetParcelFromBundle(Bundle b)
+ {
+ byte[] bytes = (byte[])b.GetItem("TIDL_RAW");
+
+ return new Parcel(bytes);
+ }
+
+ private string GetEventName(string appid, string iface_name)
+ {
+ return "event." + appid + ".tidl_iface_" + iface_name;
+ }
+
+ private void OnReceive(Parcel p)
+ {
+ UnitMap map = new UnitMap();
+ map.Deserialize(p);
+
+ map.Read("[METHOD]", "int", out int cmd);
+
+ switch ((MethodId)cmd)
+ {
+<DISPATCHERS>
+ }
+ }
+
+<METHOD_IDS>
+<SERIALIZER>
+<LIST_SERIALIZER>
+
+ public <CLS_NAME>(string senderAppid)
+ {
+ string eventName = GetEventName(senderAppid, "<CLS_NAME>");
+ _senderAppid = senderAppid;
+ _eventReceiver = new EventReceiver(eventName);
+ _eventReceiver.Received += (obj, args) =>
+ {
+ Bundle b = args.Data;
+ using (var parcel = GetParcelFromBundle(b))
+ {
+ OnReceive(parcel);
+ }
+ };
+ }
+
+ ~<CLS_NAME>()
+ {
+ Dispose(false);
+ }
+
+ protected void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ if (_eventReceiver != null)
+ {
+ _eventReceiver.Dispose();
+ _eventReceiver = null;
+ }
+ }
+
+ _disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+<METHODS>
+
+ }
+)__cs_cb";
+
+const char CB_METHOD[] =
+R"__cs_cb(
+ public delegate void <METHOD_ID>EventHandler(<PARAMS>);
+ public event <METHOD_ID>EventHandler <METHOD_ID>Event;
+<COMMENTS>
+ public <DECL>
+ {
+ using (Parcel p = new Parcel())
+ {
+ UnitMap map = new UnitMap();
+ map.Write("[METHOD]", "int", (int)MethodId.<METHOD_ID>);
+<PARAM_SERIALIZER>
+ map.Serialize(p);
+
+ var bundle = GetBundleFromParcel(p);
+ string eventName = GetEventName(_senderAppid, "<CLS_NAME>");
+ ApplicationEventManager.Publish(eventName, bundle);
+ }
+ }
+)__cs_cb";
+
+const char CB_DISPATCHER[] =
+R"__cs_cb(
+ case MethodId.<METHOD_ID>:
+ {
+<PARAM_DESERIALIZER>
+ <METHOD_ID>Event?.Invoke(<CALL_PARAMS>);
+ break;
+ }
+)__cs_cb";
+
+
+
+#endif // IDLC_GEN_VERSION2_CS_GROUP_GENRATOR_CB_H_ \ No newline at end of file
diff --git a/idlc/gen/version2/cs_proxy_generator.cc b/idlc/gen/version2/cs_proxy_generator.cc
new file mode 100644
index 0000000..8218a32
--- /dev/null
+++ b/idlc/gen/version2/cs_proxy_generator.cc
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/cs_proxy_generator.h"
+
+namespace {
+#include "idlc/gen/version2/cs_proxy_generator_cb.h"
+}
+
+namespace tidl {
+namespace version2 {
+
+CsProxyGen::CsProxyGen(std::shared_ptr<Document> doc) : CsGeneratorBase(doc) {}
+
+void CsProxyGen::OnInitGen(std::ofstream& stream) {
+ SetChannelType(Generator::ChannelType::TYPE_PROXY);
+ GenVersion(stream);
+ GenUsingNamespace(stream);
+ GenNamespace(stream);
+}
+
+void CsProxyGen::OnFiniGen(std::ofstream& stream) {}
+
+void CsProxyGen::GenNamespace(std::ofstream& stream) {
+ stream << "namespace RPCPort" << NLine(1);
+ GenBrace(stream, 0, [&]() {
+ stream << "namespace " << GetFileNamespace() << NLine(1);
+ GenBrace(stream, 0, [&]() {
+ GenLemBase(stream);
+ GenRemoteException(stream);
+ GenStructures(stream);
+ stream << Tab(1) << "namespace Proxy" << NLine(1);
+ GenBrace(stream, TAB_SIZE, [&]() {
+ GenInterfaces(stream);
+ });
+ });
+ });
+}
+
+void CsProxyGen::GenLemBase(std::ofstream& stream) {
+ stream << CB_LEM_BASE;
+}
+
+void CsProxyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE) continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ GenInterface(stream, iface);
+ stream << NLine(1);
+ }
+}
+
+void CsProxyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ stream << Tab(2) << "public class " << iface.GetID() << " : ProxyBase"
+ << NLine(1);
+ GenBrace(stream, TAB_SIZE * 2, [&]() {
+ GenEnum(stream, iface, 3);
+ GenMemberData(stream, iface);
+ GenUnitMap(stream, iface, 3);
+ GenCallbacks(stream, iface, true);
+ GenDelegateId(stream, iface);
+ GenMethodId(stream, iface);
+ GenEventMethod(stream, iface);
+ GenSerializer(stream);
+ GenListSerializer(stream);
+ GenCtor(stream, iface);
+ GenConnectMethod(stream, iface);
+ GenMethods(stream, iface);
+ });
+}
+
+void CsProxyGen::GenMemberData(std::ofstream& stream, const Interface& iface) {
+ ReplaceAll(CB_DATA_MEMBERS)
+ .Change("<VERSION>", std::string(FULLVER))
+ .Change("<CALLBACK_LIST>",
+ HasDelegate(iface) ? CB_DATA_CALLBACK_LIST : std::string(""))
+ .Out(stream);
+}
+
+void CsProxyGen::GenEventMethod(std::ofstream& stream, const Interface& iface) {
+ bool found = HasDelegate(iface);
+
+ ReplaceAll(CB_EVENT_METHODS)
+ .Change("<PROCESS_EVENT_BASE>",
+ found ? CB_EVENT_PROCESS_EVENT_BASE : std::string(""))
+ .Change("<RECEIVE_EVENT_BASE>",
+ found ? CB_EVENT_RECEIVE_EVENT_BASE : std::string(""))
+ .Out(stream);
+}
+
+void CsProxyGen::GenCtor(std::ofstream& stream, const Interface& iface) {
+ ReplaceAll(CB_CONSTRUCTOR_METHOD)
+ .Change("<NAME>", iface.GetID())
+ .Out(stream);
+}
+
+void CsProxyGen::GenConnectMethod(std::ofstream& stream,
+ const Interface& iface) {
+ GenTemplate(
+ CB_CONNECT_METHOD, stream,
+ [&]() -> std::string { return iface.GetID(); },
+ [&]() -> std::string { return iface.GetID(); });
+
+ if (HasDelegate(iface)) {
+ stream << CB_DISPOSE_CALLBACK_METHOD;
+ }
+
+ stream << NLine(1);
+}
+
+void CsProxyGen::GenMethods(std::ofstream& stream, const Interface& iface) {
+ auto& decls = iface.GetDeclarations();
+
+ for (const auto& i : decls) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE) continue;
+
+ if (!i->GetComments().empty())
+ stream << AddIndent(TAB_SIZE * 3, i->GetComments());
+
+ stream << Tab(3) << "public ";
+ GenDeclaration(stream, *i, false);
+ stream << NLine(1);
+ GenBrace(stream, TAB_SIZE * 3, [&]() { GenInvocation(stream, *i); });
+ stream << NLine(1);
+ }
+}
+
+void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
+ GenTemplate(CB_INVOCATION_PRE, stream, [&]() -> std::string {
+ std::string st;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT) continue;
+
+ if (pt.GetBaseType().ToString() == "file" ||
+ (pt.GetBaseType().GetMetaType() != nullptr &&
+ pt.GetBaseType().GetMetaType()->ToString() == "file")) {
+ st += GenTemplateString(CB_SHARE_FILE, [&]() -> std::string {
+ std::string str = "";
+ str += Tab(6) + "Port.ShareFile(" + i->GetID() + ");";
+ return str;
+ });
+ }
+ }
+
+ std::string m;
+ std::string l;
+
+ m += Tab(5) + NLine(1) + "UnitMap map = new UnitMap();" + NLine(1);
+ m += ConvertTypeToSerializer("(int)MethodId." + decl.GetID(), "[METHOD]",
+ "map");
+
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT)
+ continue;
+
+ m += ConvertTypeToSerializer(i->GetID(), i->GetID(), "map");
+
+ if (IsDelegateType(pt.GetBaseType())) {
+ l += "_delegateList.Add(" + i->GetID() + ");\n";
+ }
+ }
+ m += NLine(1) + "map.Serialize(p);" + NLine(1);
+
+ st += AddIndent(TAB_SIZE * 5, m) + NLine(1);
+
+ st += Tab(5) + "lock (_lock)" + NLine(1);
+ st += Tab(5) + "{" + NLine(1);
+ if (!l.empty()) st += AddIndent(TAB_SIZE * 6, l) + NLine(1);
+
+
+
+ // Deserialize
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
+ st += CB_INVOCATION_ASYNC_MID + NLine(1);
+ st += Tab(5) + "}";
+ return st;
+ } else {
+ st += CB_INVOCATION_SYNC_MID + NLine(1);
+ }
+
+ st += NLine(1) + AddIndent(TAB_SIZE * 5, CB_INVOCATION_RECEIVE);
+ st += NLine(1);
+
+ for (const auto& i : decl.GetParameters()) {
+ if (i->GetParameterType().GetDirection() ==
+ ParameterType::Direction::IN) {
+ continue;
+ }
+
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), i->GetID(), i->GetID(),
+ "mapReceived", false);
+ if (c != "") st += AddIndent(TAB_SIZE * 5, c);
+ }
+
+ if (decl.GetType().ToString() != "void") {
+ st += AddIndent(TAB_SIZE * 5, CB_INVOCATION_REMOTE_EXCEPTION);
+ st += AddIndent(TAB_SIZE * 6, NLine(1) + ConvertTypeToDeserializer(
+ decl.GetType(), "ret",
+ "[RESULT]", "mapReceived"));
+ st += AddIndent(TAB_SIZE * 6, NLine(1) + "return ret;");
+ }
+ st += AddIndent(TAB_SIZE * 5, NLine(1) + "}");
+
+ return st;
+ });
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/cs_proxy_generator.h b/idlc/gen/version2/cs_proxy_generator.h
new file mode 100644
index 0000000..a929041
--- /dev/null
+++ b/idlc/gen/version2/cs_proxy_generator.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_GEN_VERSION2_CS_PROXY_GENRATOR_H_
+#define IDLC_CS_GEN_VERSION2_CS_PROXY_GENRATOR_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/version2/cs_generator_base.h"
+
+namespace tidl {
+namespace version2 {
+
+class CsProxyGen : public CsGeneratorBase {
+ public:
+ explicit CsProxyGen(std::shared_ptr<Document> doc);
+ virtual ~CsProxyGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenCtor(std::ofstream& stream, const Interface& iface);
+ void GenConnectMethod(std::ofstream& stream, const Interface& iface);
+ void GenMethods(std::ofstream& stream, const Interface& iface);
+ void GenInvocation(std::ofstream& stream, const Declaration& decl);
+ void GenEventMethod(std::ofstream& stream, const Interface& iface);
+ void GenMemberData(std::ofstream& stream, const Interface& iface);
+ void GenLemBase(std::ofstream& stream);
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_CS_GEN_VERSION2_CS_PROXY_GENRATOR_H_ \ No newline at end of file
diff --git a/idlc/gen/version2/cs_proxy_generator_cb.h b/idlc/gen/version2/cs_proxy_generator_cb.h
new file mode 100644
index 0000000..4901392
--- /dev/null
+++ b/idlc/gen/version2/cs_proxy_generator_cb.h
@@ -0,0 +1,497 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_GEN_VERSION2_CS_PROXY_GENRATOR_CB_H_
+#define IDLC_CS_GEN_VERSION2_CS_PROXY_GENRATOR_CB_H_
+
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
+const char CB_DATA_MEMBERS[] =
+R"__cs_cb( public event EventHandler Connected;
+ public event EventHandler Disconnected;
+ public event EventHandler Rejected;
+
+ private static readonly string _tidlVersion = "<VERSION>";
+ private bool _online = false;
+ private string _appId;
+ private Object _lock = new Object();
+ private bool _connecting = false;
+ private LocalExecution _lem;
+ private SynchronizationContext _async_context = TizenSynchronizationContext.Current;
+<CALLBACK_LIST>
+)__cs_cb";
+
+
+const char CB_LEM_BASE[] =
+R"__cs_cb( internal class LocalExecution
+ {
+ internal bool IsListen = false;
+ object _instance = null;
+ string _instance_id = null;
+ string _appId = null;
+ static int _seq = 0;
+ MethodInfo _send = null;
+ MethodInfo _connect = null;
+ MethodInfo _disconnect = null;
+ ConcurrentQueue<Parcel> _result = new ConcurrentQueue<Parcel>();
+
+ internal LocalExecution(string appId, string interfaceName)
+ {
+ string current_appid = Application.Current.ApplicationInfo.ApplicationId;
+
+ if (current_appid != appId)
+ return;
+
+ _seq++;
+ _instance_id = appId + "::" + _seq.ToString();
+ _appId = appId;
+
+ Assembly assembly = Assembly.GetExecutingAssembly();
+ Type type = null;
+
+ foreach (Type t in assembly.GetTypes())
+ {
+ if (t.Name != interfaceName)
+ continue;
+
+ string[] name = t.FullName?.Split('.');
+
+ if (name == null || name.Length != 4)
+ continue;
+
+ if (name[0] == "RPCPort" && name[2] == "Stub")
+ {
+ if (type == null)
+ {
+ type = t;
+ }
+ else
+ {
+ type = null;
+ break;
+ }
+ }
+ }
+
+ if (type == null)
+ return;
+
+ MethodInfo getInstance = type.GetMethod("GetInstance", BindingFlags.Static | BindingFlags.NonPublic);
+ if (getInstance == null) { return; }
+
+ _instance = getInstance.Invoke(null, null);
+ if (_instance == null) { return; }
+
+ _send = type.GetMethod("OnLemReceivedEvent", BindingFlags.NonPublic | BindingFlags.Instance);
+ if (_send == null) { return; }
+
+ _connect = type.GetMethod("OnLemConnectedEvent", BindingFlags.NonPublic | BindingFlags.Instance);
+ if (_connect == null) { return; }
+
+ _disconnect = type.GetMethod("OnLemDisconnectedEvent", BindingFlags.NonPublic | BindingFlags.Instance);
+ if (_disconnect == null) { return; }
+
+ MethodInfo getListen = type.GetMethod("GetListenStatus", BindingFlags.NonPublic | BindingFlags.Instance);
+ if (getListen == null) { return; }
+
+ object ret = getListen.Invoke(_instance, null);
+ if (ret == null) { return; }
+ IsListen = (bool)ret;
+ }
+
+ internal void Connect(object proxy_instance)
+ {
+ _connect.Invoke(_instance, new object[] { proxy_instance, _appId, _instance_id });
+ }
+
+ internal void Disconnect()
+ {
+ _disconnect.Invoke(_instance, new object[] { _appId, _instance_id });
+ }
+
+ internal void Send(Parcel p)
+ {
+ _send.Invoke(_instance, new object[] { _instance_id, p});
+ }
+
+ internal void Send(Parcel p, ref Parcel resutl)
+ {
+ Send(p);
+
+ int count = 0;
+ while (_result.IsEmpty && count++ < 100)
+ Thread.Sleep(100);
+
+ if (ResultQueuePop(out resutl))
+ {
+ Tizen.Log.Error("RPC_PORT", "ResultQueuePop");
+ return;
+ }
+
+ Tizen.Log.Error("RPC_PORT_PROXY", "Failed to get result from server");
+ throw new InvalidIOException();
+ }
+
+ internal void ResultQueuePush(Parcel p)
+ {
+ _result.Enqueue(p);
+ }
+
+ internal bool ResultQueuePop(out Parcel p)
+ {
+ return _result.TryDequeue(out p);
+ }
+ }
+)__cs_cb";
+
+const char CB_DATA_CALLBACK_LIST[] =
+R"__cs_cb(
+ private List<CallbackBase> _delegateList = new List<CallbackBase>();
+)__cs_cb";
+const char CB_EVENT_PROCESS_EVENT_BASE[] =
+R"__cs_cb(
+ private void ProcessReceivedEvent(Parcel parcelReceived)
+ {
+ UnitMap map = new UnitMap();
+ map.Deserialize(parcelReceived);
+
+ int cmd;
+ map.Read("[METHOD]", out cmd);
+
+ if (cmd != (int)MethodId.__Callback)
+ {
+ return;
+ }
+
+ CallbackBase cb;
+ map.Read("delegate", out cb);
+
+ foreach (var i in _delegateList)
+ {
+ if ((int)i.Id == cb.Id && i.SeqId == cb.SeqId)
+ {
+ i.OnReceivedEvent(map);
+ if (i.Once)
+ _delegateList.Remove(i);
+ break;
+ }
+ }
+ }
+
+ internal void OnLemReceivedEvent(Parcel parcelReceived)
+ {
+ _async_context.Post((data) =>
+ {
+ ProcessReceivedEvent(parcelReceived);
+
+ }, null);
+ }
+
+)__cs_cb";
+
+const char CB_EVENT_RECEIVE_EVENT_BASE[] =
+R"__cs_cb( Parcel parcelReceived;
+
+ try
+ {
+ parcelReceived = new Parcel(CallbackPort);
+ }
+ catch (InvalidIOException)
+ {
+ return;
+ }
+
+ using (parcelReceived)
+ {
+ ProcessReceivedEvent(parcelReceived);
+ }
+)__cs_cb";
+
+const char CB_EVENT_METHODS[] =
+R"__cs_cb(
+ protected override void OnConnectedEvent(string endPoint, string portName, Port port)
+ {
+ _online = true;
+ _connecting = false;
+ Connected?.Invoke(this, null);
+ }
+
+ protected override void OnDisconnectedEvent(string endPoint, string portName)
+ {
+ _online = false;
+ Disconnected?.Invoke(this, null);
+ }
+
+ internal void OnLemDisconnectedEvent()
+ {
+ _async_context.Post((data) =>
+ {
+ OnDisconnectedEvent(null, null);
+
+ }, null);
+
+ }
+
+ internal void OnLemResultEvent(Parcel result)
+ {
+ _lem.ResultQueuePush(result);
+ }
+
+ protected override void OnRejectedEvent(string endPoint, string portName)
+ {
+ _connecting = false;
+ Rejected?.Invoke(this, null);
+ }
+<PROCESS_EVENT_BASE>
+ protected override void OnReceivedEvent(string endPoint, string portName)
+ {
+<RECEIVE_EVENT_BASE>
+ }
+
+ private void ConsumeCommand(out UnitMap unitMap, Port port, ParcelHeader header)
+ {
+ do
+ {
+ Parcel p;
+
+ try
+ {
+ p = new Parcel(port);
+ }
+ catch (InvalidIOException)
+ {
+ unitMap = null;
+ return;
+ }
+
+ ParcelHeader headerReceived = p.GetHeader();
+ if (!string.IsNullOrEmpty(headerReceived.GetTag()))
+ {
+ if (headerReceived.GetSequenceNumber() != header.GetSequenceNumber())
+ {
+ Tizen.Log.Error("RPC_PORT_PROXY", headerReceived.GetSequenceNumber().ToString() + " - " + headerReceived.GetTag() + " : " + header.GetSequenceNumber().ToString() + " - " + header.GetTag());
+ continue;
+ }
+ }
+
+ UnitMap map = new UnitMap();
+ map.Deserialize(p);
+
+ unitMap = map;
+ return;
+ } while (true);
+ }
+)__cs_cb";
+
+const char CB_DISPOSE_CALLBACK_METHOD[] =
+R"__cs_cb(
+ /// <summary>
+ /// Disposes delegate objects in this interface
+ /// </summary>
+ /// <param name="tag">The tag string from delegate object</param>
+ void DisposeCallback(string tag)
+ {
+ foreach (var i in _delegateList)
+ {
+ if (i.Tag.Equals(tag))
+ {
+ _delegateList.Remove(i);
+ return;
+ }
+ }
+ }
+)__cs_cb";
+
+const char CB_CONSTRUCTOR_METHOD[] =
+R"__cs_cb(
+ public <NAME>(string appId)
+ {
+ _appId = appId;
+ _lem = new LocalExecution(appId, "<NAME>");
+ }
+)__cs_cb";
+
+const char CB_CONNECT_METHOD[] =
+R"__cs_cb(
+ /// <summary>
+ /// Connects to the stub app.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <exception cref="InvalidIDException">
+ /// Thrown when the appid to connect is invalid.
+ /// </exception>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ /// <exception cref="PermissionDeniedException">
+ /// Thrown when the permission is denied.
+ /// </exception>
+ /// <remark> If you want to use this method, you must add privileges.</remark>
+ public void Connect()
+ {
+ if (_lem.IsListen)
+ {
+ if (_online || _connecting)
+ throw new InvalidIDException();
+
+ _connecting = true;
+ _lem.Connect(this);
+
+ _async_context.Post((data) =>
+ {
+ OnConnectedEvent(null, null, null);
+ }, null);
+ }
+ else
+ {
+ Connect(_appId, "$$");
+ }
+ }
+
+ /// <summary>
+ /// Disconnects from the stub app.
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">
+ /// Thrown when an internal IO error occurrs.
+ /// </exception>
+ public void Disconnect()
+ {
+ if (_lem.IsListen)
+ {
+ if (_online)
+ _lem.Disconnect();
+ }
+ else
+ {
+ Port?.Disconnect();
+ }
+ _online = false;
+ }
+
+ /// <summary>
+ /// Connects to the stub app synchronously.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ /// <exception cref="InvalidIDException">
+ /// Thrown when the appid to connect is invalid.
+ /// </exception>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ /// <exception cref="PermissionDeniedException">
+ /// Thrown when the permission is denied.
+ /// </exception>
+ /// <remark> If you want to use this method, you must add privileges.</remark>
+ public void ConnectSync()
+ {
+ if (_lem.IsListen)
+ {
+ if (_online || _connecting)
+ throw new InvalidIDException();
+
+ _connecting = true;
+ _lem.Connect(this);
+ OnConnectedEvent(null, null, null);
+ }
+ else
+ {
+ ConnectSync(_appId, "$$");
+ }
+ }
+)__cs_cb";
+
+const char CB_INVOCATION_PRE[] =
+R"__cs_cb( if (!_online)
+ throw new NotConnectedSocketException();
+
+ using (Parcel p = new Parcel())
+ {
+ ParcelHeader header = p.GetHeader();
+ header.SetTag(_tidlVersion);
+$$
+ }
+)__cs_cb";
+
+
+const char CB_SHARE_FILE[] =
+R"__cs_cb(
+ try
+ {
+$$
+ }
+ catch (InvalidIOException)
+ {
+ throw new InvalidIOException();
+ }
+)__cs_cb";
+
+const char CB_INVOCATION_ASYNC_MID[] =
+R"__cs_cb( // Send
+ if (_lem.IsListen)
+ {
+ _lem.Send(p);
+ }
+ else
+ {
+ p.Send(Port);
+ }
+)__cs_cb";
+
+const char CB_INVOCATION_SYNC_MID[] =
+R"__cs_cb( // Send
+ Parcel ret_parcel = new Parcel();
+ // Send
+ if (_lem.IsListen)
+ {
+ _lem.Send(p, ref ret_parcel);
+ }
+ else
+ {
+ p.Send(Port);
+ }
+)__cs_cb";
+
+const char CB_INVOCATION_RECEIVE[] =
+R"__cs_cb( UnitMap mapReceived;
+ if (_lem.IsListen)
+ {
+ mapReceived = new UnitMap();
+ mapReceived.Deserialize(ret_parcel);
+ }
+ else
+ {
+ // Receive
+ ConsumeCommand(out mapReceived, Port, header);
+ }
+
+ if (mapReceived == null)
+ {
+ throw new InvalidProtocolException();
+ }
+)__cs_cb";
+
+const char CB_INVOCATION_REMOTE_EXCEPTION[] =
+R"__cs_cb( if (mapReceived.ContainsName("[REMOTE_EXCEPTION]"))
+ {
+ mapReceived.Read("[REMOTE_EXCEPTION]", out RemoteException exception);
+ throw exception;
+ }
+)__cs_cb";
+
+#endif // IDLC_CS_GEN_VERSION2_CS_PROXY_GENRATOR_CB_H_ \ No newline at end of file
diff --git a/idlc/gen/version2/cs_stub_generator.cc b/idlc/gen/version2/cs_stub_generator.cc
new file mode 100644
index 0000000..a74d651
--- /dev/null
+++ b/idlc/gen/version2/cs_stub_generator.cc
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/version2/cs_stub_generator.h"
+
+namespace {
+#include "idlc/gen/version2/cs_stub_generator_cb.h"
+}
+
+namespace tidl {
+namespace version2 {
+
+CsStubGen::CsStubGen(std::shared_ptr<Document> doc) : CsGeneratorBase(doc) {}
+
+void CsStubGen::OnInitGen(std::ofstream& stream) {
+ SetChannelType(Generator::ChannelType::TYPE_STUB);
+ GenVersion(stream);
+ GenUsingNamespace(stream);
+ GenNamespace(stream);
+}
+
+void CsStubGen::OnFiniGen(std::ofstream& stream) {}
+
+void CsStubGen::GenNamespace(std::ofstream& stream) {
+ stream << "namespace RPCPort" << NLine(1);
+ GenBrace(stream, 0, [&]() {
+ stream << "namespace " << GetFileNamespace() << NLine(1);
+ GenBrace(stream, 0, [&]() {
+ GenLemBase(stream);
+ GenRemoteException(stream);
+ GenStructures(stream);
+ stream << Tab(1) << "namespace Stub" << NLine(1);
+ GenBrace(stream, TAB_SIZE, [&]() { GenInterfaces(stream); });
+ });
+ });
+}
+
+void CsStubGen::GenLemBase(std::ofstream& stream) {
+ stream << CB_LEM_BASE;
+}
+
+void CsStubGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE) continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ GenInterface(stream, iface);
+ stream << std::endl;
+ }
+}
+
+void CsStubGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ stream << Tab(2) << "public sealed class " << iface.GetID() << " : StubBase"
+ << NLine(1);
+ GenBrace(stream, TAB_SIZE * 2, [&]() {
+ GenEnum(stream, iface, 3);
+ stream << ReplaceAll(CB_DATA_MEMBERS, "<VERSION>", FULLVER);
+ GenServiceBase(stream, iface);
+ GenUnitMap(stream, iface, 3);
+ GenCallbacks(stream, iface, false);
+ GenDelegateId(stream, iface);
+ GenMethodId(stream, iface);
+ GenSerializer(stream);
+ GenListSerializer(stream);
+ GenCheckPrivilege(stream);
+ GenReceivedEvent(stream, iface);
+ GenConnectedEvent(stream);
+ GenDisconnectedEvent(stream);
+ GenCtor(stream, iface);
+ GenCommonMethods(stream);
+ GenDisposable(stream, iface);
+ });
+}
+
+void CsStubGen::GenServiceBase(std::ofstream& stream, const Interface& iface) {
+ stream << CB_SERVICE_BASE_FRONT;
+ GenDeclarations(stream, iface.GetDeclarations());
+ stream << NLine(1);
+ stream << AddIndent(TAB_SIZE * 3, "}\n");
+}
+
+void CsStubGen::GenDeclarations(std::ofstream& stream,
+ const Declarations& decls) {
+ for (const auto& i : decls) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE) continue;
+ if (!i->GetComments().empty())
+ stream << NLine(1) << AddIndent(TAB_SIZE * 4, i->GetComments());
+ stream << Tab(4) << "public abstract ";
+ GenDeclaration(stream, *i);
+ stream << NLine(1);
+ }
+}
+
+void CsStubGen::GenCheckPrivilege(std::ofstream& stream) {
+ stream << CB_CHECK_PRIVILEGE_METHOD;
+}
+
+void CsStubGen::GenReceivedEvent(std::ofstream& stream,
+ const Interface& iface) {
+ stream << CB_ON_RECEIVED_EVENT_FRONT;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE) continue;
+ stream << Tab(6) << "case MethodId." << i->GetID() << ":" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 7, [&]() {
+ GenInvocation(stream, *i);
+ stream << Tab(8) << "break;" << NLine(1);
+ });
+ }
+ stream << CB_ON_RECEIVED_EVENT_BACK;
+}
+
+
+std::string CsStubGen::GetWriteOutParam(const Declaration& decl) {
+ int cnt = 0;
+ std::string code;
+
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ cnt++;
+ if (pt.GetDirection() == ParameterType::Direction::IN)
+ continue;
+
+ code += ConvertTypeToSerializer("param" + std::to_string(cnt),
+ i->GetID(), "result_map");
+ }
+
+ return code;
+}
+
+std::string CsStubGen::GetInvocationMethod(const Declaration& decl) {
+ std::string code;
+ if (decl.GetType().ToString() != "void") {
+ code =
+ ReplaceAll(CB_INVOCATION_REMOTE_EXCEPTION)
+ .Change("<SYNC_INVOCATION>", GetInvocationMethodParam(decl, true))
+ .Change("<WRITE_RESULT>", ConvertTypeToSerializer(
+ "retVal", "[RESULT]", "result_map"))
+ .Change("<WRITE_OUT_PARAM>", GetWriteOutParam(decl));
+ } else {
+ code = NLine(1) + GetInvocationMethodParam(decl, false);
+ }
+
+ return code;
+}
+
+std::string CsStubGen::GetInvocationMethodParam(const Declaration& decl,
+ bool hasRet) {
+ int cnt = 1;
+ std::string code;
+
+ if (hasRet)
+ code = "var retVal = ";
+
+ code += "b." + decl.GetID() + "(";
+ for (const auto& i : decl.GetParameters()) {
+ if (cnt != 1) {
+ code += ", ";
+ }
+
+ std::string v = "param" + std::to_string(cnt);
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT) {
+ code += "out " + ConvertTypeToString(pt.GetBaseType()) + " ";
+ } else if (pt.GetDirection() == ParameterType::Direction::REF) {
+ code += "ref ";
+ }
+ code += v;
+ cnt++;
+ }
+
+ code += ");\n";
+
+ return code;
+}
+void CsStubGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
+ int cnt = 1;
+
+ // Deserialize
+ for (const auto& i : decl.GetParameters()) {
+ if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT) {
+ cnt++;
+ continue;
+ }
+
+ std::string v = "param" + std::to_string(cnt);
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, i->GetID(), "map");
+ stream << AddIndent(TAB_SIZE * 8, c);
+ cnt++;
+ }
+
+ // Invoke
+ std::string m;
+
+ m += NLine(1) + "UnitMap result_map = new UnitMap();";
+
+ m += ReplaceAll(CB_INVOCATION_CHECK_PRIVILEGE)
+ .Change("<INVOCATION>",
+ AddIndent(TAB_SIZE, GetInvocationMethod(decl)));
+
+ stream << AddIndent(TAB_SIZE * 8, m);
+
+ // Serialize
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC)
+ return;
+
+ cnt = 0;
+ m = CB_INVOCATION_RESULT;
+ stream << AddIndent(TAB_SIZE * 8, m);
+}
+
+void CsStubGen::GenConnectedEvent(std::ofstream& stream) {
+ stream << CB_ON_CONNECTED_EVENT;
+}
+
+void CsStubGen::GenDisconnectedEvent(std::ofstream& stream) {
+ stream << CB_ON_DISCONNECTED_EVENT;
+}
+
+std::string CsStubGen::GenPrivileges(const Declaration& decl,
+ const std::string& id) {
+ std::string code;
+ for (const auto& attr : decl.GetAttributes()) {
+ if (attr->GetKey() != "privilege")
+ continue;
+
+ code +=
+ Tab(4) + "list" + id + ".Add(\"" + attr->GetValue() + "\");" + NLine(1);
+ }
+
+ return code;
+}
+
+void CsStubGen::GenCtor(std::ofstream& stream, const Interface& iface) {
+ GenTemplate(
+ CB_CTOR_FRONT, stream,
+ [&]() -> std::string { return iface.GetID(); },
+ [&]() -> std::string { return iface.GetID(); });
+
+ for (const auto& i : iface.GetAttributes()) {
+ if (i->GetKey() == "privilege") {
+ stream << Tab(4) << "AddPrivilege(\"" << i->GetValue() << "\");"
+ << NLine(1);
+ } else if (i->GetKey() == "trusted" && i->GetValue() == "true") {
+ stream << Tab(4) << "SetTrusted(" << i->GetValue() << ");" << NLine(1);
+ }
+ }
+
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string code = GenPrivileges(*i, i->GetID());
+ if (code.empty())
+ continue;
+
+ ReplaceAll(CB_PRIVILEGE_MAP_BASE)
+ .Change("<METHOD_ID>", i->GetID())
+ .Change("<PRIVILEGE_LIST>", code)
+ .Out(stream);
+ }
+
+ stream << Tab(3) << "}" << NLine(1);
+}
+
+void CsStubGen::GenCommonMethods(std::ofstream& stream) {
+ stream << CB_COMMON_METHODS;
+}
+
+void CsStubGen::GenDisposable(std::ofstream& stream, const Interface& iface) {
+ stream << CB_DISPOSABLE;
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/gen/version2/cs_stub_generator.h b/idlc/gen/version2/cs_stub_generator.h
new file mode 100644
index 0000000..a4e09ea
--- /dev/null
+++ b/idlc/gen/version2/cs_stub_generator.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_GEN_VERSION2_CS_STUB_GENRATOR_H_
+#define IDLC_CS_GEN_VERSION2_CS_STUB_GENRATOR_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/version2/cs_generator_base.h"
+
+namespace tidl {
+namespace version2 {
+
+class CsStubGen : public CsGeneratorBase {
+ public:
+ explicit CsStubGen(std::shared_ptr<Document> doc);
+ virtual ~CsStubGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenServiceBase(std::ofstream& stream, const Interface& iface);
+ void GenReceivedEvent(std::ofstream& stream, const Interface& iface);
+ void GenConnectedEvent(std::ofstream& stream);
+ void GenCheckPrivilege(std::ofstream& stream);
+ std::string GenPrivileges(const Declaration& decl, const std::string& id);
+ void GenDisconnectedEvent(std::ofstream& stream);
+ void GenCtor(std::ofstream& stream, const Interface& iface);
+ void GenCommonMethods(std::ofstream& stream);
+ void GenDeclarations(std::ofstream& stream, const Declarations& decls);
+ void GenInvocation(std::ofstream& stream, const Declaration& decl);
+ void GenDisposable(std::ofstream& stream, const Interface& iface);
+ std::string GetInvocationMethodParam(const Declaration& decl, bool hasRet);
+ std::string GetInvocationMethod(const Declaration& decl);
+ std::string GetWriteOutParam(const Declaration& decl);
+ void GenLemBase(std::ofstream& stream);
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_CS_GEN_VERSION2_CS_STUB_GENRATOR_H_ \ No newline at end of file
diff --git a/idlc/gen/version2/cs_stub_generator_cb.h b/idlc/gen/version2/cs_stub_generator_cb.h
new file mode 100644
index 0000000..23866a7
--- /dev/null
+++ b/idlc/gen/version2/cs_stub_generator_cb.h
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_GEN_VERSION2_CS_STUB_GENRATOR_CB_H_
+#define IDLC_CS_GEN_VERSION2_CS_STUB_GENRATOR_CB_H_
+
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
+const char CB_DATA_MEMBERS[] =
+R"__cs_cb( private List<ServiceBase> _services = new List<ServiceBase>();
+ private Type _serviceType;
+ private static readonly string _tidlVersion = "<VERSION>";
+ private Dictionary<MethodId, List<string>> _privilege_map = new Dictionary<MethodId, List<string>>();
+ private static Message _instance;
+ private bool _isListen = false;
+ private SynchronizationContext _async_context = TizenSynchronizationContext.Current;
+)__cs_cb";
+
+const char CB_LEM_BASE[] =
+R"__cs_cb( internal class LocalExecution
+ {
+ object _instance = null;
+ MethodInfo _send_result = null;
+ MethodInfo _send_request = null;
+ MethodInfo _disconnect = null;
+
+ internal bool _online = false;
+
+ internal LocalExecution (object instance)
+ {
+ Type type = instance.GetType();
+
+ if (type == null)
+ return;
+
+ _send_result = type.GetMethod("OnLemResultEvent", BindingFlags.NonPublic | BindingFlags.Instance);
+ if (_send_result == null) { return; }
+
+ _send_request = type.GetMethod("OnLemReceivedEvent", BindingFlags.NonPublic | BindingFlags.Instance);
+
+ _disconnect = type.GetMethod("OnLemDisconnectedEvent", BindingFlags.NonPublic | BindingFlags.Instance);
+ if (_disconnect == null) { return; }
+
+ _instance = instance;
+ _online = true;
+
+ }
+
+ internal void SendResult(Parcel result)
+ {
+ _send_result.Invoke(_instance, new object[] {result});
+ }
+
+ internal void SendRequest(Parcel result)
+ {
+ if (_send_request != null)
+ _send_request.Invoke(_instance, new object[] { result });
+ }
+
+ internal void Disconnect()
+ {
+ if (_online)
+ _disconnect.Invoke(_instance, null);
+ _online = false;
+ }
+ }
+)__cs_cb";
+
+const char CB_SERVICE_BASE_FRONT[] =
+R"__cs_cb(
+ public abstract class ServiceBase
+ {
+ internal bool _is_app = true;
+ internal List<string> _privileges;
+ internal LocalExecution _lem;
+
+ /// <summary>
+ /// The client app ID
+ /// </summary>
+ public string Sender
+ {
+ get; internal set;
+ }
+
+ /// <summary>
+ /// The client instance ID
+ /// </summary>
+ public string Instance
+ {
+ get; internal set;
+ }
+
+ public Port Port
+ {
+ get;
+ internal set;
+ }
+
+ protected ServiceBase()
+ {
+ }
+
+ internal void LoadPrivilege()
+ {
+ ApplicationInfo info = new ApplicationInfo(Sender);
+ if (info.PackageId == string.Empty)
+ {
+ _is_app = false;
+ return;
+ }
+
+ Package pkg = PackageManager.GetPackage(info.PackageId);
+ _privileges = new List<string>(pkg.Privileges);
+ }
+
+ /// <summary>
+ /// Disconnects from the proxy app
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">
+ /// Thrown when an internal IO error occurrs.
+ /// </exception>
+ public void Disconnect()
+ {
+ if(_lem != null)
+ {
+ _lem.Disconnect();
+ }
+ else
+ {
+ Port?.Disconnect();
+ Port = null;
+ }
+ }
+
+ /// <summary>
+ /// This method will be called when the client is connected
+ /// </summary>
+ public abstract void OnCreate();
+
+ /// <summary>
+ /// This method will be called when the client is disconnected
+ /// </summary>
+ public abstract void OnTerminate();
+)__cs_cb";
+
+
+const char CB_CHECK_PRIVILEGE_METHOD[] =
+R"__cs_cb(
+ private bool CheckPrivilege(MethodId id, ServiceBase b)
+ {
+ if (_privilege_map.ContainsKey(id) == false)
+ return true;
+
+ foreach (var item in _privilege_map[id])
+ {
+ if (b._privileges.Contains(item) == false) {
+ Tizen.Log.Error("RPC_PORT", "Permission denied. " + b.Sender + " : " + item);
+ return false;
+ }
+ }
+
+ return true;
+ }
+)__cs_cb";
+
+const char CB_PRIVILEGE_MAP_BASE[] =
+R"__cs_cb(
+ List<string> list<METHOD_ID> = new List<string>();
+<PRIVILEGE_LIST>
+ _privilege_map[MethodId.<METHOD_ID>] = list<METHOD_ID>;
+)__cs_cb";
+
+
+const char CB_ON_RECEIVED_EVENT_FRONT[] =
+R"__cs_cb(
+ protected override bool OnReceivedEvent(string sender, string instance, Port port)
+ {
+ Parcel p;
+
+ try
+ {
+ p = new Parcel(port);
+ }
+ catch (InvalidIOException)
+ {
+ return false;
+ }
+
+ return OnReceivedEvent(instance, port, p);
+ }
+
+ internal void OnLemReceivedEvent(string instance, Parcel p)
+ {
+ if (Thread.CurrentThread.ManagedThreadId != 1)
+ {
+ _async_context.Post((data) =>
+ {
+ ((Message)data).OnReceivedEvent(instance, null, p);
+ }, this);
+ }
+ else
+ {
+ OnReceivedEvent(instance, null, p);
+ }
+ }
+
+ internal bool OnReceivedEvent(string instance, Port port, Parcel p)
+ {
+ try
+ {
+ ServiceBase b = null;
+
+ foreach (var i in _services)
+ {
+ if (i.Instance.Equals(instance))
+ {
+ b = i;
+ break;
+ }
+ }
+
+ if (b == null)
+ {
+ return false;
+ }
+
+ var result = new Parcel();
+
+ int cmd;
+ UnitMap map = new UnitMap();
+ map.Deserialize(p);
+
+ map.Read("[METHOD]", out cmd);
+
+ switch ((MethodId)cmd)
+ {
+)__cs_cb";
+
+const char CB_ON_RECEIVED_EVENT_BACK[] =
+R"__cs_cb(
+ default:
+ return false;
+ }
+
+ return true;
+ }
+ catch (InvalidIOException)
+ {
+ return false;
+ }
+ finally
+ {
+ p.Dispose();
+ }
+ }
+)__cs_cb";
+
+const char CB_ON_CONNECTED_EVENT[] =
+R"__cs_cb(
+ protected override void OnConnectedEvent(string sender, string instance)
+ {
+ ServiceBase s = Activator.CreateInstance(_serviceType) as ServiceBase;
+ s.Sender = sender;
+ s.LoadPrivilege();
+ s.Instance = instance;
+ s.Port = GetPort(Port.Type.Callback, instance);
+ _services.Add(s);
+ s.OnCreate();
+ }
+
+ internal void OnLemConnectedEvent(object proxy_instance, string sender, string instance)
+ {
+ ServiceBase s = Activator.CreateInstance(_serviceType) as ServiceBase;
+ s.Sender = sender;
+ s.LoadPrivilege();
+ s.Instance = instance;
+ s._lem = new LocalExecution(proxy_instance);
+ _services.Add(s);
+ if (Thread.CurrentThread.ManagedThreadId != 1)
+ {
+ _async_context.Post((data) =>
+ {
+ ((ServiceBase)data).OnCreate();
+ }, s);
+ }
+ else
+ {
+ s.OnCreate();
+ }
+ }
+)__cs_cb";
+
+const char CB_ON_DISCONNECTED_EVENT[] =
+R"__cs_cb(
+ protected override void OnDisconnectedEvent(string sender, string instance)
+ {
+ foreach (var i in _services)
+ {
+ if (i.Instance.Equals(instance))
+ {
+ if (i._lem != null)
+ i._lem._online = false;
+
+ i.OnTerminate();
+ _services.Remove(i);
+ break;
+ }
+ }
+ }
+
+ internal void OnLemDisconnectedEvent(string sender, string instance)
+ {
+ if (Thread.CurrentThread.ManagedThreadId != 1)
+ {
+ _async_context.Post((data) =>
+ {
+ ((Message)data).OnDisconnectedEvent(sender, instance);
+ }, this);
+ }
+ else
+ {
+ OnDisconnectedEvent(sender, instance);
+ }
+ }
+)__cs_cb";
+
+const char CB_CTOR_FRONT[] =
+R"__cs_cb(
+ internal static Message GetInstance()
+ {
+ return _instance;
+ }
+
+ internal bool GetListenStatus()
+ {
+ return _isListen;
+ }
+
+ public $$() : base("$$")
+ {
+ _instance = this;
+)__cs_cb";
+
+const char CB_COMMON_METHODS[] =
+R"__cs_cb(
+ /// <summary>
+ /// Listens to client apps
+ /// </summary>
+ /// <param name="serviceType">The type object for making service instances</param>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// Thrown when serviceType is invalid.
+ /// </exception>
+ public void Listen(Type serviceType)
+ {
+ if (!typeof(ServiceBase).IsAssignableFrom(serviceType))
+ throw new ArgumentException("Invalid type");
+ _serviceType = serviceType;
+ Listen();
+ _isListen = true;
+ }
+
+ /// <summary>
+ /// Gets service objects which are connected
+ /// </summary>
+ /// <returns>The enumerable service objects which are connected</returns>
+ public IEnumerable<ServiceBase> GetServices()
+ {
+ return _services;
+ }
+)__cs_cb";
+
+const char CB_DISPOSABLE[] =
+R"__cs_cb(
+ protected override void OnTerminatedEvent()
+ {
+ foreach (var i in _services)
+ {
+ if (i._lem != null)
+ i._lem._online = false;
+ i.OnTerminate();
+ }
+ }
+)__cs_cb";
+
+constexpr const char CB_INVOCATION_CHECK_PRIVILEGE[] =
+R"__cs_cb(
+if (b._is_app && CheckPrivilege((MethodId)cmd, b) == false)
+{
+ RemoteException ex = new RemoteException("Permission denied", (int)Tizen.Internals.Errors.ErrorCode.PermissionDenied);
+ result_map.Write("[REMOTE_EXCEPTION]", ex);
+} else {
+ <INVOCATION>
+}
+)__cs_cb";
+
+constexpr const char CB_INVOCATION_REMOTE_EXCEPTION[] =
+R"__cs_cb(try
+{
+ <SYNC_INVOCATION>
+ <WRITE_RESULT>
+ <WRITE_OUT_PARAM>
+} catch (RemoteException ex)
+{
+ result_map.Write("[REMOTE_EXCEPTION]", ex);
+})__cs_cb";
+
+constexpr const char CB_INVOCATION_RESULT[] =
+R"__cs_cb(
+ParcelHeader header = p.GetHeader();
+ParcelHeader resultHeader = result.GetHeader();
+resultHeader.SetTag(_tidlVersion);
+resultHeader.SetSequenceNumber(header.GetSequenceNumber());
+result_map.Write("[METHOD]", (int)MethodId.__Result);
+result_map.Serialize(result);
+
+if (b._lem != null)
+ b._lem.SendResult(result);
+else
+ result.Send(port);
+
+)__cs_cb";
+
+#endif // IDLC_CS_GEN_VERSION2_CS_STUB_GENRATOR_CB_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/c_cion_body_gen_array_base_cb.h b/idlc/gen_cion/c_cion_body_gen_array_base_cb.h
new file mode 100644
index 0000000..481a241
--- /dev/null
+++ b/idlc/gen_cion/c_cion_body_gen_array_base_cb.h
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_BODY_GEN_ARRAY_BASE_CB_H_
+#define IDLC_C_CION_GEN_C_BODY_GEN_ARRAY_BASE_CB_H_
+
+/**
+ * <PREFIX> The prefix of the array structure.
+ * <NAME> The name of the array structure.
+ * <ELEMENT_TYPE> The type of the element of the array.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ <ELEMENT_TYPE>*value;
+ int size;
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the array structure.
+ * <NAME> The name of the array structure.
+ * <PARCEL_WRITE> The implementation to write the value to the parcel.
+ * <PARCEL_READ> The implemention to read the value from the parcel.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ * <ELEMENT_TYPE> The type of the element of the array.
+ * <ELEMENT_TYPE_SIZE> The size of the type of the element.
+ * <ELEMENTS_FREE> The implementation to release elements.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+ int i;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ rpc_port_parcel_write_array_count(parcel, h->size);
+
+ for (i = 0; i < h->size; ++i)
+ <PARCEL_WRITE>
+}
+
+static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+ <ELEMENT_TYPE>value;
+ int ret;
+ int i;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(<ERROR_PREFIX>_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ ret = rpc_port_parcel_read_array_count(parcel, &h->size);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read array count. error(%d)", ret);
+ set_last_result(<ERROR_PREFIX>_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ h->value = calloc(h->size, sizeof(<ELEMENT_TYPE_SIZE>));
+ if (h->value == nullptr) {
+ _E("Out of memory");
+ set_last_result(<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ for (i = 0; i < h->size; ++i) {
+ <PARCEL_READ>
+ }
+
+ set_last_result(<ERROR_PREFIX>_ERROR_NONE);
+}
+
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_from;
+
+ *h = handle;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ <ELEMENTS_FREE>
+
+ free(h);
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
+{
+ <PREFIX>_<NAME>_h handle;
+ rpc_port_parcel_h parcel;
+ int ret;
+
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_create(&handle);
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ ret = rpc_port_parcel_create(&parcel);
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ rpc_port_parcel_write(parcel, &h->parcelable, h);
+ rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+ ret = get_last_result();
+ rpc_port_parcel_destroy(parcel);
+
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ *clone = handle;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_set(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>*value, int size)
+{
+ <PREFIX>_<NAME>_h handle;
+ <PREFIX>_<NAME>_h clone;
+ int ret;
+
+ if (h == nullptr || value == nullptr || size <= 0) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_create(&handle);
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ handle->value = (<ELEMENT_TYPE>*)value;
+ handle->size = size;
+
+ ret = <PREFIX>_<NAME>_clone(handle, &clone);
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ handle->value = nullptr;
+ handle->size = 0;
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ handle->value = h->value;
+ handle->size = h->size;
+ <PREFIX>_<NAME>_destroy(handle);
+
+ h->value = clone->value;
+ h->size = clone->size;
+
+ clone->value = nullptr;
+ clone->size = 0;
+ <PREFIX>_<NAME>_destroy(clone);
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_get(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>*value, int *size)
+{
+ <PREFIX>_<NAME>_h handle;
+ int ret;
+
+ if (h == nullptr || value == nullptr || size == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_clone(h, &handle);
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ return ret;
+ }
+
+ *value = handle->value;
+ *size = handle->size;
+
+ handle->value = nullptr;
+ handle->size = 0;
+ <PREFIX>_<NAME>_destroy(handle);
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel, &h->value[i]->parcelable, h->value[i]);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel, h->value[i]);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel, STRING_GET(h->value[i]));
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel of the value.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel, h->value[i]);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user-defined type.
+ * <NAME> The name of the user-defined type.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+ret = <PREFIX>_<NAME>_create(&value);
+if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ set_last_result(ret);
+ return;
+}
+
+rpc_port_parcel_read(parcel, &value->parcelable, value);
+if (get_last_result() != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", get_last_result());
+ <PREFIX>_<NAME>_destroy(value);
+ return;
+}
+
+h->value[i] = value;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+value = nullptr;
+rpc_port_parcel_read_bundle(parcel, &value);
+if (value == nullptr) {
+ _E("Failed to read data");
+ set_last_result(<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+h->value[i] = value;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_STRING_PARCEL_READ[] =
+R"__c_cb(
+value = nullptr;
+rpc_port_parcel_read_string(parcel, &value);
+if (value == nullptr) {
+ _E("Failed to read data");
+ set_last_result(<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+h->value[i] = value;
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel of the value.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &value);
+h->value[i] = value;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_USER_DEFINED_FREE[] =
+R"__c_cb(
+if (h->value) {
+ for (int i = 0; i < h->size; ++i) {
+ if (h->value[i])
+ <PREFIX>_<NAME>_destroy(h->value[i]);
+ }
+
+ free(h->value);
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BUNDLE_FREE[] =
+R"__c_cb(
+if (h->value) {
+ for (int i = 0; i < h->size; ++i) {
+ if (h->value[i])
+ bundle_free(h->value[i]);
+ }
+
+ free(h->value);
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_STRING_FREE[] =
+R"__c_cb(
+if (h->value) {
+ for (int i = 0; i < h->size; ++i) {
+ if (h->value[i])
+ free(h->value[i]);
+ }
+
+ free(h->value);
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BASE_FREE[] =
+R"__c_cb(
+if (h->value)
+ free(h->value);
+)__c_cb";
+
+#endif // IDLC_C_CION_GEN_C_BODY_GEN_ARRAY_BASE_CB_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/c_cion_body_gen_base.cc b/idlc/gen_cion/c_cion_body_gen_base.cc
new file mode 100644
index 0000000..35ce625
--- /dev/null
+++ b/idlc/gen_cion/c_cion_body_gen_base.cc
@@ -0,0 +1,917 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <cstring>
+#include <vector>
+
+#include "idlc/gen_cion/c_cion_body_gen_array_base_cb.h"
+#include "idlc/gen_cion/c_cion_body_gen_base.h"
+#include "idlc/gen_cion/c_cion_body_gen_base_cb.h"
+#include "idlc/gen_cion/c_cion_body_gen_list_base_cb.h"
+
+namespace tidl {
+
+CCionBodyGeneratorBase::CCionBodyGeneratorBase(
+ std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : CCionGeneratorBase(doc, trans) {
+ parcel_type_map_ = {
+ {"none", ""},
+ {"char", "byte"},
+ {"int", "int32"},
+ {"short", "int16"},
+ {"long", "int64"},
+ {"string", "string"},
+ {"bool", "bool"},
+ {"float", "float"},
+ {"double", "double"},
+ {"bundle", "bundle"},
+ {"file", "string"},
+ };
+
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ for (const auto& e : st.GetElements()) {
+ auto& type = e->GetType();
+ AddStructureFromType(type);
+ }
+ } else {
+ auto& iface = static_cast<const Interface&>(*b);
+ for (const auto& d : iface.GetDeclarations()) {
+ for (const auto& p : d->GetParameters()) {
+ auto& type = p->GetParameterType().GetBaseType();
+ if (IsDelegateType(iface, type))
+ continue;
+
+ AddStructureFromType(type, iface);
+ }
+
+ if (d->GetMethodType() == Declaration::MethodType::SYNC) {
+ auto& type = d->GetType();
+ AddStructureFromType(type, iface);
+ }
+ }
+ }
+ }
+}
+
+void CCionBodyGeneratorBase::GenIncludeHeader(std::ofstream& stream) {
+ std::string code;
+ code += "#include \"";
+ code += FileName.substr(0, FileName.length() - 2);
+ code += ".h\"";
+ stream << NLine(1);
+ stream << code;
+ stream << NLine(1);
+}
+
+void CCionBodyGeneratorBase::GenLogTag(std::ofstream& stream,
+ const std::string& log_tag) {
+ std::string tag = log_tag;
+ std::transform(tag.begin(), tag.end(), tag.begin(), ::toupper);
+ std::string code(ReplaceAll(CB_LOG_TAG, "<LOG_TAG>", tag));
+ stream << code;
+}
+
+void CCionBodyGeneratorBase::GenLogDefinition(std::ofstream& stream) {
+ stream << SmartIndent(CB_LOG_DEF);
+}
+
+void CCionBodyGeneratorBase::GenBaseDefinition(std::ofstream& stream) {
+ stream << SmartIndent(CB_BASE_DEF);
+}
+
+void CCionBodyGeneratorBase::GenStructureDefs(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructureDef(stream, st);
+ }
+ }
+
+ for (auto& i : GetStructures()) {
+ auto& st = i.second;
+ GenStructureDef(stream, *st);
+ }
+}
+
+void CCionBodyGeneratorBase::GenStructureDef(std::ofstream& stream,
+ const Structure& st) {
+ if (st.GetID().compare(0, strlen("array"), "array") == 0)
+ GenStructureArrayDef(stream, st);
+ else if (st.GetID().compare(0, strlen("list"), "list") == 0)
+ GenStructureListDef(stream, st);
+ else
+ GenStructureBaseDef(stream, st);
+}
+
+// @see #CB_STRUCTURE_ARRAY_DEF
+void CCionBodyGeneratorBase::GenStructureArrayDef(std::ofstream& stream,
+ const Structure& st) {
+ std::string code(ReplaceAll(CB_STRUCTURE_ARRAY_DEF, "<PREFIX>",
+ GetHandlePrefix()));
+ code = ReplaceAll(code, "<NAME>", st.GetID());
+
+ auto& elm = *(st.GetElements().begin());
+ auto& type = elm->GetType();
+ auto element_type = GetDataTypeString(type, false);
+ code = ReplaceAll(code, "<ELEMENT_TYPE>", element_type);
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_STRUCTURE_LIST_DEF
+void CCionBodyGeneratorBase::GenStructureListDef(std::ofstream& stream,
+ const Structure& st) {
+ std::string code(ReplaceAll(CB_STRUCTURE_LIST_DEF, "<PREFIX>",
+ GetHandlePrefix()));
+ code = ReplaceAll(code, "<NAME>", st.GetID());
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_STRUCTURE_BASE_DEF
+void CCionBodyGeneratorBase::GenStructureBaseDef(std::ofstream& stream,
+ const Structure& st) {
+ std::string code(ReplaceAll(CB_STRUCTURE_BASE_DEF, "<PREFIX>",
+ GetHandlePrefix()));
+ code = ReplaceAll(code, "<NAME>", st.GetID());
+
+ auto& elms = st.GetElements();
+ code = ReplaceAll(code, "<ELEMENTS>", GenBaseElements(elms));
+
+ stream << SmartIndent(code);
+}
+
+void CCionBodyGeneratorBase::GenStructures(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructure(stream, st);
+ }
+ }
+
+ for (auto& i : GetStructures()) {
+ auto& st = i.second;
+ GenStructure(stream, *st);
+ }
+}
+
+void CCionBodyGeneratorBase::GenStructure(std::ofstream& stream,
+ const Structure& st) {
+ if (st.GetID().compare(0, strlen("array"), "array") == 0)
+ GenStructureArrayBase(stream, st);
+ else if (st.GetID().compare(0, strlen("list"), "list") == 0)
+ GenStructureListBase(stream, st);
+ else
+ GenStructureBase(stream, st);
+}
+
+// @see #CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_WRITE
+// @see #CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_WRITE
+// @see #CB_STRUCTURE_ARRAY_STRING_PARCEL_WRITE
+// @see #CB_STRUCTURE_ARRAY_BASE_PARCEL_WRITE
+std::string CCionBodyGeneratorBase::GenArrayParcelWrite(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = std::string(CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_WRITE);
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_WRITE);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_ARRAY_STRING_PARCEL_WRITE);
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_BASE_PARCEL_WRITE, "<PARCEL_TYPE>",
+ GetParcelType(type));
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_READ
+// @see #CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_READ
+// @see #CB_STRUCTURE_ARRAY_STRING_PARCEL_READ
+// @see #CB_STRUCTURE_ARRAY_BASE_PARCEL_READ
+std::string CCionBodyGeneratorBase::GenArrayParcelRead(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_READ,
+ "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_STRING_PARCEL_READ,
+ "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix());
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_BASE_PARCEL_READ, "<PARCEL_TYPE>",
+ GetParcelType(type));
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_STRUCTURE_ARRAY_USER_DEFINED_FREE
+// @see #CB_STRUCTURE_ARRAY_BUNDLE_FREE
+// @see #CB_STRUCTURE_ARRAY_STRING_FREE
+// @see #CB_STRUCTURE_ARRAY_BASE_FREE
+std::string CCionBodyGeneratorBase::GenArrayElementsFree(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_USER_DEFINED_FREE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_ARRAY_BUNDLE_FREE);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_ARRAY_STRING_FREE);
+ } else {
+ code = std::string(CB_STRUCTURE_ARRAY_BASE_FREE);
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_STRUCTURE_ARRAY_BASE
+void CCionBodyGeneratorBase::GenStructureArrayBase(std::ofstream& stream,
+ const Structure& st) {
+ auto& elm = *(st.GetElements().begin());
+ auto& type = elm->GetType();
+
+ ReplaceAll(CB_STRUCTURE_ARRAY_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Change("<PARCEL_WRITE>", GenArrayParcelWrite(elm))
+ .Change("<PARCEL_READ>", GenArrayParcelRead(elm))
+ .Change("<PARAM_TYPE_IN>", GetParamTypeString(
+ ParameterType::Direction::IN, type))
+ .Change("<PARAM_TYPE_OUT>", GetParamTypeString(
+ ParameterType::Direction::OUT, type))
+ .Change("<ELEMENT_TYPE>", GetDataTypeString(type, false))
+ .Change("<ELEMENT_TYPE_SIZE>", RemoveLastSpaces(
+ GetDataTypeString(type, false)))
+ .Change("<ELEMENTS_FREE>", GenArrayElementsFree(elm))
+ .Change("<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix())
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_STRUCTURE_LIST_USER_DEFINED_FREE
+// @see #CB_STRUCTURE_LIST_BUNDLE_FREE
+// @see #CB_STRUCTURE_LIST_STRING_FREE
+// @see #CB_STRUCTURE_LIST_BASE_FREE
+std::string CCionBodyGeneratorBase::GenListDataFree(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_FREE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_FREE);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_FREE);
+ } else {
+ code = std::string(CB_STRUCTURE_LIST_BASE_FREE);
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_WRITE
+// @see #CB_STRUCTURE_LIST_BUNDLE_PARCEL_WRITE
+// @see #CB_STRUCTURE_LIST_STRING_PARCEL_WRITE
+// @see #CB_STRUCTURE_LIST_BASE_PARCEL_WRITE
+std::string CCionBodyGeneratorBase::GenListParcelWrite(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = std::string(CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_WRITE);
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_PARCEL_WRITE);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_PARCEL_WRITE);
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_LIST_BASE_PARCEL_WRITE, "<PARCEL_TYPE>",
+ GetParcelType(type));
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_READ
+// @see #CB_STRUCTURE_LIST_BUNDLE_PARCEL_READ
+// @see #CB_STRUCTURE_LIST_STRING_PARCEL_READ
+// @see #CB_STRUCTURE_LIST_BASE_PARCEL_READ
+std::string CCionBodyGeneratorBase::GenListParcelRead(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_PARCEL_READ);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_PARCEL_READ);
+ } else {
+ auto value_type = GetParamTypeString(ParameterType::Direction::IN, type);
+ value_type = RemoveLastSpaces(value_type);
+ code = ReplaceAll(CB_STRUCTURE_LIST_BASE_PARCEL_READ, "<VALUE_TYPE>",
+ value_type);
+ code = ReplaceAll(code, "<PARCEL_TYPE>", GetParcelType(type));
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_STRUCTURE_LIST_USER_DEFINED_ADD
+// @see #CB_STRUCTURE_LIST_BUNDLE_ADD
+// @see #CB_STRUCTURE_LIST_STRING_ADD
+// @see #CB_STRUCTURE_LIST_BASE_ADD
+std::string CCionBodyGeneratorBase::GenListAdd(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_ADD, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_ADD);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_ADD);
+ } else {
+ auto value_type = GetParamTypeString(ParameterType::Direction::IN, type);
+ code = ReplaceAll(CB_STRUCTURE_LIST_BASE_ADD, "<VALUE_TYPE>",
+ value_type);
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CCionBodyGeneratorBase::GenListCallbackParamType(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array"||
+ type.ToString() == "bundle" ||
+ type.ToString() == "string" ||
+ type.ToString() == "file")
+ code = std::string("value");
+ else
+ code = std::string ("*value");
+
+ return code;
+}
+
+// @see #CB_STRUCTURE_LIST_BASE
+void CCionBodyGeneratorBase::GenStructureListBase(std::ofstream& stream,
+ const Structure& st) {
+
+ auto& elm = *(st.GetElements().begin());
+ auto& type = elm->GetType();
+ ReplaceAll(CB_STRUCTURE_LIST_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Change("<DATA_TYPE>", GetDataTypeString(type, true))
+ .Change("<DATA_FREE>", GenListDataFree(elm))
+ .Change("<PARAM_TYPE_IN>", GetParamTypeString(
+ ParameterType::Direction::IN, type))
+ .Change("<PARCEL_WRITE>", GenListParcelWrite(elm))
+ .Change("<PARCEL_READ>", GenListParcelRead(elm))
+ .Change("<LIST_ADD>", GenListAdd(elm))
+ .Change("<CALLBACK_PARAM_TYPE>", GenListCallbackParamType(elm))
+ .Change("<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix())
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+std::string CCionBodyGeneratorBase::GenBaseElements(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ auto& type = elm->GetType();
+ auto param_type = GetDataTypeString(type, false);
+ code += param_type + elm->GetID() + ";";
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+void CCionBodyGeneratorBase::GenCommonFuntions(std::ofstream& stream) {
+ std::string code = GetTransportable().C().GenBodyPeerInfoBase();
+ if(GetChannelType() != ChannelType::TYPE_GROUP) {
+ code += GetTransportable().C().GenBodyConnectionBase();
+ code += GetTransportable().C().GenBodyPayloadBase();
+ }
+
+ ReplaceAll(code,"<PREFIX>", GetHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Change("<INTERNAL_PREFIX>", GetInternalHandlePrefix())
+ .Out(stream);
+}
+
+// @see #CB_STRUCTURE_BASE_USER_DEFINED_FREE
+// @see #CB_STRUCTURE_BASE_BUNDLE_FREE
+// @see #CB_STRUCTURE_BASE_STRING_FREE
+std::string CCionBodyGeneratorBase::GenBaseElementFree(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_USER_DEFINED_FREE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+ code = ReplaceAll(code, "<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "bundle") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_FREE, "<ELEMENT_NAME>",
+ elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_STRING_FREE, "<ELEMENT_NAME>",
+ elm->GetID());
+ }
+
+ return code;
+}
+
+std::string CCionBodyGeneratorBase::GenBaseElementsFree(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms)
+ code += GenBaseElementFree(elm);
+
+ return RemoveLine(code);
+}
+
+// @see #CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_WRITE
+// @see #CB_STRUCTURE_BASE_BUNDLE_PARCEL_WRITE
+// @see #CB_STRUCTURE_BASE_STRING_PARCEL_WRITE
+// @see #CB_STRUCTURE_BASE_BASE_PARCEL_WRITE
+std::string CCionBodyGeneratorBase::GenBaseParcelWrite(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ std::string parcel_write_code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_WRITE, "<ELEMENT_NAME>",
+ elm->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_PARCEL_WRITE,
+ "<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_STRUCTURE_BASE_STRING_PARCEL_WRITE,
+ "<ELEMENT_NAME>", elm->GetID());
+ } else {
+ parcel_write_code = ReplaceAll(CB_STRUCTURE_BASE_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ELEMENT_NAME>",
+ elm->GetID());
+ }
+
+ code += parcel_write_code;
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_READ
+// @see #CB_STRUCTURE_BASE_BUNDLE_PARCEL_READ
+// @see #CB_STRUCTURE_BASE_STRING_PARCEL_READ
+// @see #CB_STRUCTURE_BASE_BASE_PARCEL_READ
+std::string CCionBodyGeneratorBase::GenBaseParcelRead(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ std::string parcel_read_code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_read_code = ReplaceAll(
+ CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>",
+ GetFullNameFromType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ELEMENT_NAME>",
+ elm->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_PARCEL_READ,
+ "<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ parcel_read_code = ReplaceAll(CB_STRUCTURE_BASE_STRING_PARCEL_READ,
+ "<ELEMENT_NAME>", elm->GetID());
+ } else {
+ parcel_read_code = ReplaceAll(CB_STRUCTURE_BASE_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ELEMENT_NAME>",
+ elm->GetID());
+ }
+
+ code += parcel_read_code;
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_STRUCTURE_BASE_USER_DEFINED_SET
+// @see #CB_STRUCTURE_BASE_BUNDLE_SET
+// @see #CB_STRUCTURE_BASE_STRING_SET
+// @see #CB_STRUCTURE_BASE_BASE_SET
+std::string CCionBodyGeneratorBase::GenBaseSet(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_USER_DEFINED_SET, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+
+ auto element_free_code = RemoveLine(GenBaseElementFree(elm));
+ code = ReplaceAll(code, "<ELEMENT_FREE>", element_free_code);
+ code = ReplaceAll(code, "<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "bundle") {
+ auto element_free_code = RemoveLine(GenBaseElementFree(elm));
+ code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_SET, "<ELEMENT_FREE>",
+ element_free_code);
+ code = ReplaceAll(code, "<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ auto element_free_code = RemoveLine(GenBaseElementFree(elm));
+ code = ReplaceAll(CB_STRUCTURE_BASE_STRING_SET, "<ELEMENT_FREE>",
+ element_free_code);
+ code = ReplaceAll(code, "<ELEMENT_NAME>", elm->GetID());
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_BASE_BASE_SET, "<ELEMENT_NAME>",
+ elm->GetID());
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_STRUCTURE_BASE_USER_DEFINED_GET
+// @see #CB_STRUCTURE_BASE_BUNDLE_GET
+// @see #CB_STRUCTURE_BASE_STRING_GET
+// @see #CB_STRUCTURE_BASE_BASE_GET
+std::string CCionBodyGeneratorBase::GenBaseGet(
+ const std::shared_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_USER_DEFINED_GET, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+ code = ReplaceAll(code, "<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "bundle") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_GET, "<ELEMENT_NAME>",
+ elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_STRING_GET, "<ELEMENT_NAME>",
+ elm->GetID());
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_BASE_BASE_GET, "<ELEMENT_NAME>",
+ elm->GetID());
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_STRUCTURE_BASE_SET_GET
+std::string CCionBodyGeneratorBase::GenBaseSetGet(const std::string& name,
+ const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ std::string set_get_code(ReplaceAll(CB_STRUCTURE_BASE_SET_GET,
+ "<PREFIX>", GetHandlePrefix()));
+ set_get_code = ReplaceAll(set_get_code, "<NAME>", name);
+ set_get_code = ReplaceAll(set_get_code, "<ELEMENT_NAME>", elm->GetID());
+
+ auto& type = elm->GetType();
+ auto param_type_in = GetParamTypeString(ParameterType::Direction::IN, type);
+ set_get_code = ReplaceAll(set_get_code, "<PARAM_TYPE_IN>", param_type_in);
+ auto param_type_out = GetParamTypeString(ParameterType::Direction::OUT,
+ type);
+ set_get_code = ReplaceAll(set_get_code, "<PARAM_TYPE_OUT>", param_type_out);
+
+ set_get_code = ReplaceAll(set_get_code, "<BASE_SET>", GenBaseSet(elm));
+ set_get_code = ReplaceAll(set_get_code, "<BASE_GET>", GenBaseGet(elm));
+
+ code += set_get_code;
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_STRUCTURE_BASE
+void CCionBodyGeneratorBase::GenStructureBase(std::ofstream& stream,
+ const Structure& st) {
+ std::string code(ReplaceAll(CB_STRUCTURE_BASE, "<PREFIX>",
+ GetHandlePrefix()));
+ code = ReplaceAll(code, "<NAME>", st.GetID());
+
+ auto& elms = st.GetElements();
+ code = ReplaceAll(code, "<ELEMENTS_FREE>", GenBaseElementsFree(elms));
+
+ code = ReplaceAll(code, "<PARCEL_WRITE>", GenBaseParcelWrite(elms));
+ code = ReplaceAll(code, "<PARCEL_READ>", GenBaseParcelRead(elms));
+
+ code += GenBaseSetGet(st.GetID(), elms);
+
+ code = ReplaceAll(code, "<ERROR_PREFIX>",
+ GetTransportable().C().GenErrorPrefix());
+
+ stream << SmartIndent(code);
+}
+
+const std::string& CCionBodyGeneratorBase::GetParcelType(const BaseType& type) {
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array")
+ return parcel_type_map_["none"];
+
+ return parcel_type_map_[type.ToString()];
+}
+
+
+bool CCionBodyGeneratorBase::HasListFile(const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ if (IsProxy() && d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ for (const auto& p : d->GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ auto name = GetFullNameFromType(type, iface);
+ if (name == "list_file")
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool CCionBodyGeneratorBase::HasFile(const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ for (const auto& p : d->GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ auto name = GetFullNameFromType(type, iface);
+ if (name == "file" || name == "list_file" || name == "array_file")
+ return true;
+ }
+ }
+
+ return false;
+}
+
+CCionBodyGeneratorBase::FileParamType CCionBodyGeneratorBase::HasFile(const Interface& iface, const BaseType& type) {
+ if (type.ToString() == "list" || type.ToString() == "array") {
+ std::string name = GetFullNameFromType(type, iface);
+ if (name == "array_file")
+ return ArrayFile;
+ else if (name == "list_file" || name == "file")
+ return File;
+ } else if (type.ToString() == "file") {
+ return File;
+ }
+
+ return NotExist;
+}
+
+CCionBodyGeneratorBase::FileParamType CCionBodyGeneratorBase::HasFile(const Interface& iface, const Declaration& decl, bool is_proxy) {
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (is_proxy) {
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+ } else if (decl.GetMethodType() == Declaration::MethodType::DELEGATE) {
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+ } else {
+ if (param_type.GetDirection() == ParameterType::Direction::IN)
+ continue;
+ }
+
+ auto result = HasFile(iface, param_type.GetBaseType());
+ if (result != NotExist)
+ return result;
+
+ }
+
+ if (is_proxy)
+ return NotExist;
+
+ return HasFile(iface, decl.GetType());
+}
+
+void CCionBodyGeneratorBase::GenFilePayloadSend(std::ofstream& stream, bool is_proxy) {
+ CCionBodyGeneratorBase::FileParamType param_type = NotExist;
+
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*i);
+ for (const auto& d : iface.GetDeclarations()) {
+ param_type = HasFile(iface, *d, is_proxy);
+ if (param_type != NotExist)
+ break;
+ }
+ if (param_type != NotExist)
+ break;
+ }
+
+ if (param_type == NotExist)
+ return;
+
+ std::string code = CB_INTERFACE_METHOD_FILE_PAYLOAD_SENDER_DEF;
+ if (is_proxy) {
+ std::string def(
+ ReplaceAll(CB_INTERFACE_METHOD_FILE_PAYLOAD_SENDER_CLIENT_DEF,
+ "<CLIENT_T>", GetTransportable().C().GenClientType()));
+ code = ReplaceAll(code, "<FILE_PAYLOAD_SENDER_DEF>", def);
+ code = ReplaceAll(code, "<FILE_PAYLOAD_SEND>",
+ GetTransportable().C().GenClientFileSend("value", "client"));
+ code = ReplaceAll(code, "<PREFIX>", GetHandlePrefix());
+
+ } else {
+ std::string def(
+ ReplaceAll(CB_INTERFACE_METHOD_FILE_PAYLOAD_SENDER_SERVER_DEF,
+ "<SERVER_T>", GetTransportable().C().GenServerType()));
+ def = ReplaceAll(def, "<PEER_T>", GetTransportable().C().GenPeerInfoType());
+ code = ReplaceAll(code, "<FILE_PAYLOAD_SENDER_DEF>", def);
+ code = ReplaceAll(code, "<FILE_PAYLOAD_SEND>",
+ GetTransportable().C().GenServerFileSend("value",
+ "server", "peer_info"));
+ code = ReplaceAll(code, "<PREFIX>", GetHandlePrefix());
+ }
+
+ code = ReplaceAll(code)
+ .Change("<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix())
+ .Change("<INTERNAL_PREFIX>", GetInternalHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix());
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_PRIVATE_SHARING_LIST_SET
+void CCionBodyGeneratorBase::GenPrivateSharingListSet(std::ofstream& stream) {
+ bool has_list_file = false;
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*i);
+ has_list_file = HasListFile(iface);
+ if (has_list_file)
+ break;
+ }
+
+ if (!has_list_file)
+ return;
+
+ std::string code(ReplaceAll(CB_PRIVATE_SHARING_LIST_SET,
+ "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix()));
+
+ stream << SmartIndent(code);
+ }
+
+// @see #CB_LIST_FILE_SET_PAYLOAD
+// @see #CB_ARRAY_FILE_SET_PRIVATE_SHARING
+// @see #CB_FILE_SET_PAYLOAD
+std::string CCionBodyGeneratorBase::GetPrivateSharingString(const BaseType& type,
+ const Interface& iface, std::string port, const std::string& arg) {
+ std::string code;
+ std::string name = GetFullNameFromType(type, iface);
+ if (name == "list_file") {
+ code = ReplaceAll(CB_LIST_FILE_SET_PAYLOAD, "<ARG>", arg);
+ } else if (name == "array_file") {
+ code = ReplaceAll(CB_ARRAY_FILE_SET_PAYLOAD, "<ARG>", arg);
+ } else if (name == "file") {
+ code = ReplaceAll(CB_FILE_SET_PAYLOAD, "<ARG>", arg);
+ }
+
+ return code;
+}
+
+std::string CCionBodyGeneratorBase::GetFilePayloadString(const BaseType& type,
+ const Interface& iface, const std::string& arg) {
+ std::string code;
+ std::string name = GetFullNameFromType(type, iface);
+ if (name == "list_file") {
+ code = ReplaceAll(CB_LIST_FILE_SET_PAYLOAD, "<ARG>", arg);
+ } else if (name == "array_file") {
+ code = ReplaceAll(CB_ARRAY_FILE_SET_PAYLOAD, "<ARG>", arg);
+ } else if (name == "file") {
+ code = ReplaceAll(CB_FILE_SET_PAYLOAD, "<ARG>", arg);
+ }
+
+ return code;
+}
+std::string CCionBodyGeneratorBase::GetFilePayloadDefString(const Interface& iface,
+ const Declaration& decl, bool is_proxy) {
+ FileParamType file_type = HasFile(iface, decl, is_proxy);
+
+ if (file_type == File)
+ return CB_FILE_PAYLOAD_DEF;
+ else if (file_type == ArrayFile)
+ return CB_FILE_ARRAY_PAYLOAD_DEF;
+
+ return {};
+}
+
+std::string CCionBodyGeneratorBase::GetFilePayloadFreeString(const Interface& iface,
+ const Declaration& decl) {
+ if (HasFile(iface, decl) != NotExist)
+ return CB_FILE_PAYLOAD_FREE;
+
+ return {};
+}
+
+std::string CCionBodyGeneratorBase::GetFilePayloadSendString(const Interface& iface,
+ const Declaration& decl, bool is_proxy) {
+ if (HasFile(iface, decl, is_proxy) != NotExist) {
+ std::string code;
+ if (is_proxy)
+ code = ReplaceAll(CB_FILE_PAYLOAD_SEND_CLIENT,
+ "<MODULE_PREFIX>", GetMoudlePrefix());
+ else
+ code = ReplaceAll(CB_FILE_PAYLOAD_SEND_SERVER,
+ "<MODULE_PREFIX>", GetMoudlePrefix());
+
+ return code;
+ }
+
+ return {};
+}
+
+std::string CCionBodyGeneratorBase::GenSecurityString(const Interface& iface) {
+ std::string security_path;
+
+ for (const auto& attr : iface.GetAttributes()) {
+ if (attr->GetKey() == "ca_path")
+ security_path +=
+ GetTransportable().C().GenSetSecurityCA(attr->GetValue());
+ else if (attr->GetKey() == "cert_path")
+ security_path +=
+ GetTransportable().C().GenSetSecurityCert(attr->GetValue());
+ else if (attr->GetKey() == "private_key")
+ security_path +=
+ GetTransportable().C().GenSetSecurityPrivateKey(attr->GetValue());
+ }
+
+ return RemoveLine(security_path);
+}
+
+
+
+} // namespace tidl
diff --git a/idlc/gen_cion/c_cion_body_gen_base.h b/idlc/gen_cion/c_cion_body_gen_base.h
new file mode 100644
index 0000000..f97862a
--- /dev/null
+++ b/idlc/gen_cion/c_cion_body_gen_base.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_BODY_GEN_BASE_H_
+#define IDLC_C_CION_GEN_C_BODY_GEN_BASE_H_
+
+#include <memory>
+#include <string>
+#include <map>
+
+#include "idlc/gen_cion/c_cion_gen_base.h"
+
+namespace tidl {
+
+class CCionBodyGeneratorBase : public CCionGeneratorBase {
+ public:
+ enum FileParamType {
+ NotExist,
+ File,
+ ArrayFile
+ };
+ explicit CCionBodyGeneratorBase(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CCionBodyGeneratorBase() = default;
+
+ void GenStructureDefs(std::ofstream& stream);
+ void GenStructures(std::ofstream& stream);
+ void GenIncludeHeader(std::ofstream& stream);
+ void GenLogTag(std::ofstream& stream, const std::string& log_tag);
+ void GenLogDefinition(std::ofstream& stream);
+ void GenBaseDefinition(std::ofstream& stream);
+ const std::string& GetParcelType(const BaseType& type);
+ void GenFilePayloadSend(std::ofstream& stream, bool is_proxy);
+ std::string GetFilePayloadString(const BaseType& type,
+ const Interface& iface, const std::string& arg);
+ void GenPrivateSharingListSet(std::ofstream& stream);
+ std::string GetPrivateSharingString(const BaseType& type,
+ const Interface& iface, std::string port, const std::string& arg);
+ std::string GetFilePayloadDefString(const Interface& iface,
+ const Declaration& decl, bool is_proxy = true);
+ std::string GetFilePayloadFreeString(const Interface& iface,
+ const Declaration& decl);
+ std::string GetFilePayloadSendString(const Interface& iface,
+ const Declaration& decl, bool is_proxy);
+ std::string GenSecurityString(const Interface& iface);
+ void GenCommonFuntions(std::ofstream& stream);
+ void GenFilePayloadFuntions(std::ofstream& stream);
+
+ private:
+ void GenStructureDef(std::ofstream& stream, const Structure& st);
+ void GenStructureBaseDef(std::ofstream& stream, const Structure& st);
+ void GenStructureArrayDef(std::ofstream& stream, const Structure& st);
+ void GenStructureListDef(std::ofstream& stream, const Structure& st);
+
+ void GenStructure(std::ofstream& stream, const Structure& st);
+ void GenStructureBase(std::ofstream& stream, const Structure& st);
+ void GenStructureArrayBase(std::ofstream& stream, const Structure& st);
+ void GenStructureListBase(std::ofstream& stream, const Structure& st);
+
+ std::string GenArrayParcelWrite(const std::shared_ptr<Element>& elm);
+ std::string GenArrayParcelRead(const std::shared_ptr<Element>& elm);
+ std::string GenArrayElementsFree(const std::shared_ptr<Element>& elm);
+
+ std::string GenListDataFree(const std::shared_ptr<Element>& elm);
+ std::string GenListParcelWrite(const std::shared_ptr<Element>& elm);
+ std::string GenListParcelRead(const std::shared_ptr<Element>& elm);
+ std::string GenListAdd(const std::shared_ptr<Element>& elm);
+ std::string GenListCallbackParamType(const std::shared_ptr<Element>& elm);
+
+ std::string GenBaseElements(const Elements& elms);
+ std::string GenBaseElementFree(const std::shared_ptr<Element>& elm);
+ std::string GenBaseElementsFree(const Elements& elms);
+ std::string GenBaseParcelWrite(const Elements& elms);
+ std::string GenBaseParcelRead(const Elements& elms);
+ std::string GenBaseSetGet(const std::string& name, const Elements& elms);
+ std::string GenBaseSet(const std::shared_ptr<Element>& elm);
+ std::string GenBaseGet(const std::shared_ptr<Element>& elm);
+
+ bool HasListFile(const Interface& iface);
+ bool HasFile(const Interface& iface);
+ FileParamType HasFile(const Interface& iface, const BaseType& type);
+ FileParamType HasFile(const Interface& iface, const Declaration& decl, bool is_proxy = true);
+ private:
+ std::map<std::string, std::string> parcel_type_map_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_C_CION_GEN_C_BODY_GEN_BASE_H_
diff --git a/idlc/gen_cion/c_cion_body_gen_base_cb.h b/idlc/gen_cion/c_cion_body_gen_base_cb.h
new file mode 100644
index 0000000..ecd9bc5
--- /dev/null
+++ b/idlc/gen_cion/c_cion_body_gen_base_cb.h
@@ -0,0 +1,678 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_BODY_GEN_BASE_CB_H_
+#define IDLC_C_CION_GEN_C_BODY_GEN_BASE_CB_H_
+
+/**
+ * <LOG_TAG> The log tag.
+ */
+constexpr const char CB_LOG_TAG[] =
+R"__c_cb(
+#undef LOG_TAG
+#define LOG_TAG "<LOG_TAG>"
+)__c_cb";
+
+constexpr const char CB_LOG_DEF[] =
+R"__c_cb(
+#undef _E
+#define _E(fmt, ...) dlog_print(DLOG_ERROR, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _W
+#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _I
+#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _D
+#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+)__c_cb";
+
+constexpr const char CB_BASE_DEF[] =
+R"__c_cb(
+#ifndef nullptr
+#define nullptr NULL
+#endif
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
+#ifndef STRING_GET
+#define STRING_GET(x) ((x) ? x : "")
+#endif
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ELEMENTS> Elements of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ <ELEMENTS>
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ELEMENTS_FREE> The implementation to release elements of the structure.
+ * <PARCEL_WRITE> The implementation to write the data to the parcel.
+ * <PARCEL_READ> The implementation to read the data from the parcel.
+ */
+constexpr const char CB_STRUCTURE_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ <PARCEL_WRITE>
+}
+
+static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(<ERROR_PREFIX>_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ <PARCEL_READ>
+
+ set_last_result(<ERROR_PREFIX>_ERROR_NONE);
+}
+
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_from;
+
+ *h = handle;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ <ELEMENTS_FREE>
+
+ free(h);
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
+{
+ <PREFIX>_<NAME>_h handle;
+ rpc_port_parcel_h parcel;
+ int ret;
+
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_create(&handle);
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ ret = rpc_port_parcel_create(&parcel);
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ rpc_port_parcel_write(parcel, &h->parcelable, h);
+ rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+ ret = get_last_result();
+ rpc_port_parcel_destroy(parcel);
+
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ *clone = handle;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <PARAM_TYPE_IN> The type of the input paramter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * <BASE_SET> The implementation to set the data to the structure.
+ * <BASE_GET> The implementation to get the data from the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_SET_GET[] =
+R"__c_cb(
+int <PREFIX>_<NAME>_set_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value)
+{
+ <BASE_SET>
+}
+
+int <PREFIX>_<NAME>_get_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>value)
+{
+ <BASE_GET>
+}
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel, &h-><ELEMENT_NAME>->parcelable, h-><ELEMENT_NAME>);
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel, h-><ELEMENT_NAME>);
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel, STRING_GET(h-><ELEMENT_NAME>));
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel of the element.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel, h-><ELEMENT_NAME>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+<PREFIX>_<NAME>_create(&h-><ELEMENT_NAME>);
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("Failed to create handle");
+ set_last_result(<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+rpc_port_parcel_read(parcel, &h-><ELEMENT_NAME>->parcelable, h-><ELEMENT_NAME>);
+if (get_last_result() != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to read data");
+ return;
+}
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_bundle(parcel, &h-><ELEMENT_NAME>);
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("Failed to read data");
+ set_last_result(<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY);
+ return;
+}
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_string(parcel, &h-><ELEMENT_NAME>);
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("Failed to read data");
+ set_last_result(<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY);
+ return;
+}
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel of the element.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BASE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &h-><ELEMENT_NAME>);
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_FREE[] =
+R"__c_cb(
+if (h-><ELEMENT_NAME>)
+ <PREFIX>_<NAME>_destroy(h-><ELEMENT_NAME>);
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_FREE[] =
+R"__c_cb(
+if (h-><ELEMENT_NAME>)
+ bundle_free(h-><ELEMENT_NAME>);
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_FREE[] =
+R"__c_cb(
+if (h-><ELEMENT_NAME>)
+ free(h-><ELEMENT_NAME>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ * <ELEMENT_FREE> The implementation to release the element of the structure.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * @see #CB_STRUCTURE_BASE_USER_DEFINED_FREE
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_SET[] =
+R"__c_cb(
+<PREFIX>_<NAME>_h new_value;
+int ret;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+}
+
+ret = <PREFIX>_<NAME>_clone(value, &new_value);
+if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ return ret;
+}
+
+<ELEMENT_FREE>
+
+h-><ELEMENT_NAME> = new_value;
+
+return <ERROR_PREFIX>_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <ELEMENT_FREE> The implementation to release the element of the structure.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * @see #CB_STRUCTURE_BASE_BUNDLE_FREE
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_SET[] =
+R"__c_cb(
+bundle *new_value;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+}
+
+new_value = bundle_dup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+}
+
+<ELEMENT_FREE>
+
+h-><ELEMENT_NAME> = new_value;
+
+return <ERROR_PREFIX>_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <ELEMENT_FREE> The implementation to release the element of the structure.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * @see #CB_STRUCTURE_BASE_STRING_FREE
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_SET[] =
+R"__c_cb(
+char *new_value;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+}
+
+new_value = strdup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+}
+
+<ELEMENT_FREE>
+
+h-><ELEMENT_NAME> = new_value;
+
+return <ERROR_PREFIX>_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BASE_SET[] =
+R"__c_cb(
+if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+}
+
+h-><ELEMENT_NAME> = value;
+
+return <ERROR_PREFIX>_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_GET[] =
+R"__c_cb(
+<PREFIX>_<NAME>_h new_value;
+int ret;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+}
+
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("<ELEMENT_NAME> is nullptr");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+}
+
+ret = <PREFIX>_<NAME>_clone(h-><ELEMENT_NAME>, &new_value);
+if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ return ret;
+}
+
+*value = new_value;
+
+return <ERROR_PREFIX>_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_GET[] =
+R"__c_cb(
+bundle *new_value;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+}
+
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("<ELEMENT_NAME> is nullptr");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+}
+
+new_value = bundle_dup(h-><ELEMENT_NAME>);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+}
+
+*value = new_value;
+
+return <ERROR_PREFIX>_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_GET[] =
+R"__c_cb(
+char *new_value;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+}
+
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("<ELEMENT_NAME> is nullptr");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+}
+
+new_value = strdup(h-><ELEMENT_NAME>);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+}
+
+*value = new_value;
+
+return <ERROR_PREFIX>_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BASE_GET[] =
+R"__c_cb(
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+}
+
+*value = h-><ELEMENT_NAME>;
+
+return <ERROR_PREFIX>_ERROR_NONE;
+)__c_cb";
+
+
+constexpr const char CB_INTERFACE_METHOD_FILE_PAYLOAD_SENDER_CLIENT_DEF[] =
+R"__c_cb(static int __<MODULE_PREFIX>_file_payload_send(<CLIENT_T> client, GList *list))__c_cb";
+
+constexpr const char CB_INTERFACE_METHOD_FILE_PAYLOAD_SENDER_SERVER_DEF[] =
+R"__c_cb(static int __<MODULE_PREFIX>_file_payload_send(<SERVER_T> server, const <PEER_T> peer_info, GList *list))__c_cb";
+
+constexpr const char CB_INTERFACE_METHOD_FILE_PAYLOAD_SENDER_DEF[] =
+R"__c_cb(<FILE_PAYLOAD_SENDER_DEF>
+{
+ const char *value;
+ GList *iter;
+ int ret = <ERROR_PREFIX>_ERROR_NONE;
+
+ if (g_list_length(list) == 0) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ iter = list;
+ while (iter) {
+ value = iter->data;
+<FILE_PAYLOAD_SEND>
+ iter = g_list_next(iter);
+ }
+
+ return ret;
+}
+)__c_cb";
+
+constexpr const char CB_PRIVATE_SHARING_LIST_SET[] =
+R"__c_cb(
+static int __rpc_port_set_private_sharing_list(rpc_port_h port, GList *list)
+{
+ const char **array_file;
+ const char *value;
+ guint size;
+ GList *iter;
+ int idx = 0;
+ int ret;
+
+ size = g_list_length(list);
+ if (size == 0) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ array_file = calloc(size, sizeof(const char*));
+ if (array_file == nullptr) {
+ _E("Out of memory");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ }
+
+ iter = list;
+ while (iter) {
+ value = iter->data;
+ array_file[idx++] = value;
+ iter = g_list_next(iter);
+ }
+
+ ret = rpc_port_set_private_sharing_array(port, array_file, idx);
+ free(array_file);
+
+ return ret;
+}
+)__c_cb";
+
+/**
+ * <PORT> The rpc port handle.
+ * <ARG> The argument.
+ */
+constexpr const char CB_LIST_FILE_SET_PRIVATE_SHARING[] =
+R"__c_cb(
+__rpc_port_set_private_sharing_list(<PORT>, <ARG>->list);
+)__c_cb";
+
+/**
+ * <PORT> The rpc port handle.
+ * <ARG> The argument.
+ */
+constexpr const char CB_ARRAY_FILE_SET_PRIVATE_SHARING[] =
+R"__c_cb(
+rpc_port_set_private_sharing_array(<PORT>, (const char **)<ARG>->value, <ARG>->size);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_FILE_SET_PRIVATE_SHARING[] =
+R"__c_cb(
+h->delegates = g_list_append(h->delegates, cb);
+rpc_port_set_private_sharing(<PORT>, <ARG>);
+)__c_cb";
+
+constexpr const char CB_FILE_PAYLOAD_DEF[] =
+R"__c_cb(GList *payload_files_ = nullptr;
+)__c_cb";
+
+constexpr const char CB_FILE_ARRAY_PAYLOAD_DEF[] =
+R"__c_cb(GList *payload_files_ = nullptr;
+int idx_;)__c_cb";
+
+constexpr const char CB_FILE_PAYLOAD_FREE[] =
+R"__c_cb(g_list_free(payload_files_);)__c_cb";
+
+constexpr const char CB_FILE_PAYLOAD_SEND_CLIENT[] =
+R"__c_cb(
+res_ = __<MODULE_PREFIX>_file_payload_send(h->client, payload_files_);
+if (res_ != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to __<MODULE_PREFIX>_file_payload_send : %d", res_);
+ goto out;
+}
+)__c_cb";
+
+constexpr const char CB_FILE_PAYLOAD_SEND_SERVER[] =
+R"__c_cb(
+__<MODULE_PREFIX>_file_payload_send(__<NAME>.stub, peer_info, payload_files_);
+)__c_cb";
+
+
+/**
+ * <PORT> The rpc port handle.
+ * <ARG> The argument.
+ */
+constexpr const char CB_ARRAY_FILE_SET_PAYLOAD[] =
+R"__c_cb(
+for (idx_ = 0; idx_ < <ARG>->size ; idx_++)
+ payload_files_ = g_list_append(payload_files_, <ARG>->value[idx_]);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_LIST_FILE_SET_PAYLOAD[] =
+R"__c_cb(
+GList *iter;
+iter = <ARG>->list;
+while (iter) {
+ payload_files_ = g_list_prepend(payload_files_, iter->data);
+ iter = g_list_next(iter);
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_FILE_SET_PAYLOAD[] =
+R"__c_cb(
+payload_files_ = g_list_append(payload_files_, (void *)<ARG>);
+)__c_cb";
+
+#endif // IDLC_C_CION_GEN_C_BODY_GEN_BASE_CB_H_
diff --git a/idlc/gen_cion/c_cion_body_gen_list_base_cb.h b/idlc/gen_cion/c_cion_body_gen_list_base_cb.h
new file mode 100644
index 0000000..e52f1d8
--- /dev/null
+++ b/idlc/gen_cion/c_cion_body_gen_list_base_cb.h
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_BODY_GEN_LIST_BASE_CB_H_
+#define IDLC_C_CION_GEN_C_BODY_GEN_LIST_BASE_CB_H_
+
+/**
+ * <PREFIX> The prefix of the list structure.
+ * <NAME> The name of the list structure.
+ */
+constexpr const char CB_STRUCTURE_LIST_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ GList *list;
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the list structure.
+ * <NAME> The name of the list structure.
+ * <DATA_TYPE> The type of the data of the list.
+ * <DATA_FREE> The implementation to release the data of the list.
+ * <PARAM_TYPE_IN> The type of the parameter of the add function.
+ * <PARCEL_WRITE> The implementation to write the data to parcel.
+ * <PARCEL_READ> The implementation to read the data from the parcel.
+ * <LIST_ADD> The implementation to add the data to the list.
+ * <CALLBACK_PARAM_TYPE> The type of the parameter of the callback.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+ <DATA_TYPE>value;
+ GList *iter;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ rpc_port_parcel_write_array_count(parcel, g_list_length(h->list));
+
+ iter = h->list;
+ while (iter) {
+ value = iter->data;
+ iter = g_list_next(iter);
+ <PARCEL_WRITE>
+ }
+}
+
+static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+ <DATA_TYPE>value = nullptr;
+ int ret;
+ int len = 0;
+ int i;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(<ERROR_PREFIX>_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ ret = rpc_port_parcel_read_array_count(parcel, &len);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read array count. error(%d)", ret);
+ set_last_result(<ERROR_PREFIX>_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ for (i = 0; i < len; ++i) {
+ <PARCEL_READ>
+ }
+
+ set_last_result(<ERROR_PREFIX>_ERROR_NONE);
+}
+
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_from;
+
+ *h = handle;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ <DATA_TYPE>value;
+ GList *iter;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ if (h->list) {
+ iter = h->list;
+ while (iter) {
+ value = iter->data;
+ iter = g_list_next(iter);
+ <DATA_FREE>
+ }
+
+ g_list_free(h->list);
+ }
+
+ free(h);
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
+{
+ <PREFIX>_<NAME>_h handle;
+ rpc_port_parcel_h parcel;
+ int ret;
+
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_create(&handle);
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ ret = rpc_port_parcel_create(&parcel);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ }
+
+ rpc_port_parcel_write(parcel, &h->parcelable, h);
+ rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+ ret = get_last_result();
+ rpc_port_parcel_destroy(parcel);
+
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ *clone = handle;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_add(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value)
+{
+ <LIST_ADD>
+}
+
+int <PREFIX>_<NAME>_foreach(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_cb callback, void *user_data)
+{
+ <DATA_TYPE>value;
+ GList *iter;
+
+ if (h == nullptr || callback == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ iter = h->list;
+ while (iter) {
+ value = iter->data;
+ iter = g_list_next(iter);
+ if (!callback(<CALLBACK_PARAM_TYPE>, user_data))
+ break;
+ }
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_remove(<PREFIX>_<NAME>_h h, unsigned int nth)
+{
+ <DATA_TYPE>value;
+ GList *found;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ found = g_list_nth(h->list, nth);
+ if (found == nullptr)
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+
+ value = found->data;
+ h->list = g_list_remove_link(h->list, found);
+ <DATA_FREE>
+ g_list_free(found);
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_length(<PREFIX>_<NAME>_h h, unsigned int *length)
+{
+ if (h == nullptr || length == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ *length = g_list_length(h->list);
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel, &value->parcelable, value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel, value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel, STRING_GET(value));
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel of the value.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel, *value);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user-defined type.
+ * <NAME> The name of the user-defined type.
+ */
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+ret = <PREFIX>_<NAME>_create(&value);
+if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ set_last_result(ret);
+ return;
+}
+
+rpc_port_parcel_read(parcel, &value->parcelable, value);
+if (get_last_result() != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", get_last_result());
+ <PREFIX>_<NAME>_destroy(value);
+ return;
+}
+
+h->list = g_list_append(h->list, value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_bundle(parcel, &value);
+if (value == nullptr) {
+ _E("Failed to read data");
+ set_last_result(<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+h->list = g_list_append(h->list, value);
+value = nullptr;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_string(parcel, &value);
+if (value == nullptr) {
+ _E("Failed to read data");
+ set_last_result(<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+h->list = g_list_append(h->list, value);
+value = nullptr;
+)__c_cb";
+
+/**
+ * <VALUE_TYPE> The type of the value.
+ * <PARCEL_TYPE> The type of the parcel of the value.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE_PARCEL_READ[] =
+R"__c_cb(
+value = calloc(1, sizeof(sizeof(<VALUE_TYPE>)));
+if (value == nullptr) {
+ _E("Out of memory");
+ set_last_result(<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, value);
+
+h->list = g_list_append(h->list, value);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user-defined type.
+ * <NAME> The name of the user-defined type.
+ */
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_ADD[] =
+R"__c_cb(
+<PREFIX>_<NAME>_h new_value;
+int ret;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+}
+
+ret = <PREFIX>_<NAME>_clone(value, &new_value);
+if (ret != <ERROR_PREFIX>_ERROR_NONE)
+ return ret;
+
+h->list = g_list_append(h->list, new_value);
+
+return <ERROR_PREFIX>_ERROR_NONE;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_ADD[] =
+R"__c_cb(
+bundle *new_value;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+}
+
+new_value = bundle_dup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+}
+
+h->list = g_list_append(h->list, new_value);
+
+return <ERROR_PREFIX>_ERROR_NONE;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_ADD[] =
+R"__c_cb(
+char *new_value;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+}
+
+new_value = strdup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+}
+
+h->list = g_list_append(h->list, new_value);
+
+return <ERROR_PREFIX>_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <VALUE_TYPE> The type of the value.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE_ADD[] =
+R"__c_cb(
+<VALUE_TYPE>*new_value;
+
+if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+}
+
+new_value = calloc(1, sizeof(<VALUE_TYPE>));
+if (new_value == nullptr) {
+ _E("Out of memory");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+}
+
+*new_value = value;
+
+h->list = g_list_append(h->list, new_value);
+
+return <ERROR_PREFIX>_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user-defined type.
+ * <NAME> The name of the user-defined type.
+ */
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_FREE[] =
+R"__c_cb(
+<PREFIX>_<NAME>_destroy(value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_FREE[] =
+R"__c_cb(
+bundle_free(value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_FREE[] =
+R"__c_cb(
+free(value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BASE_FREE[] =
+R"__c_cb(
+free(value);
+)__c_cb";
+
+#endif // IDLC_C_CION_GEN_C_BODY_GEN_LIST_BASE_CB_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/c_cion_gen_base.cc b/idlc/gen_cion/c_cion_gen_base.cc
new file mode 100644
index 0000000..8184708
--- /dev/null
+++ b/idlc/gen_cion/c_cion_gen_base.cc
@@ -0,0 +1,509 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ctime>
+#include <cassert>
+#include <vector>
+#include <sstream>
+#include <algorithm>
+
+#include "idlc/options.h"
+#include "idlc/gen_cion/c_cion_gen_base.h"
+
+namespace {
+#include "idlc/gen_cion/c_cion_gen_base_cb.h"
+} // namespace
+
+namespace tidl {
+
+CCionGeneratorBase::CCionGeneratorBase(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : CionPluginBase(std::move(doc), trans) {
+ structures_.clear();
+ type_map_ = {
+ {"char", "char "},
+ {"int", "int "},
+ {"short", "short "},
+ {"long", "long long "},
+ {"bool", "bool "},
+ {"string", "char *"},
+ {"list", "GList *"},
+ {"float", "float "},
+ {"double", "double "},
+ {"bundle", "bundle *"},
+ {"void", "void "},
+ {"file", "char *"}
+ };
+}
+
+std::string CCionGeneratorBase::Tab(int cnt) {
+ std::string str;
+ for (int i = 0; i < cnt; ++i)
+ str += "\t";
+
+ return str;
+}
+
+std::string CCionGeneratorBase::NLine(int cnt) {
+ std::string str;
+ for (int i = 0; i < cnt; ++i)
+ str += "\n";
+
+ return str;
+}
+
+std::string CCionGeneratorBase::GetFullNameFromType(const BaseType& type) {
+ std::string str = type.ToString();
+
+ if (type.GetMetaType() != nullptr) {
+ str += "_";
+ str += GetFullNameFromType(*type.GetMetaType());
+ }
+
+ return str;
+}
+
+std::string CCionGeneratorBase::GetFullNameFromType(const BaseType& type,
+ const Interface& iface) {
+ std::string str;
+ if (IsDelegateType(iface, type))
+ str += iface.GetID() + "_";
+
+ str += type.ToString();
+
+ if (type.GetMetaType() != nullptr) {
+ str += "_";
+ str += GetFullNameFromType(*type.GetMetaType(), iface);
+ }
+
+ return str;
+}
+
+std::string CCionGeneratorBase::GetDataTypeString(const BaseType& type,
+ bool is_pointer) {
+ if (type.IsUserDefinedType())
+ return GetHandlePrefix() + "_" + type.ToString() + "_h ";
+
+ if (type.ToString() == "list" ||
+ type.ToString() == "array")
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type) + "_h ";
+
+ if (type.ToString() == "string" || type.ToString() == "file")
+ return "char *";
+
+ if (type.ToString() == "bundle")
+ return "bundle *";
+
+ if (is_pointer)
+ return type_map_[type.ToString()] + "*";
+
+ return type_map_[type.ToString()];
+}
+
+std::string CCionGeneratorBase::GetReturnTypeString(const BaseType& type) {
+ if (type.IsUserDefinedType())
+ return GetHandlePrefix() + "_" + type.ToString() + "_h ";
+
+ if (type.ToString() == "list" ||
+ type.ToString() == "array")
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type) + "_h ";
+
+ return type_map_[type.ToString()];
+}
+
+void CCionGeneratorBase::AddStructureFromType(const BaseType& type) {
+ if (type.GetMetaType() == nullptr)
+ return;
+
+ BaseType* t = new BaseType(*type.GetMetaType());
+ assert(t != nullptr);
+
+ std::string type_name = GetFullNameFromType(type);
+ auto elm = std::shared_ptr<Element>(new Element(type_name, t, "", __LINE__));
+ assert(elm != nullptr);
+
+ Elements* elms = new Elements();
+ assert(elms != nullptr);
+ elms->Add(std::move(elm));
+
+ auto* st = new Structure(type_name, elms, new tidl::Enums(), "", __LINE__);
+ assert(st != nullptr);
+
+ AddStructureFromType(*type.GetMetaType());
+
+ if (StructureExist(st)) {
+ delete st;
+ return;
+ }
+
+ structures_[type_name] = std::unique_ptr<Structure>(st);
+}
+
+void CCionGeneratorBase::AddStructureFromType(const BaseType& type,
+ const Interface& iface) {
+ if (type.GetMetaType() == nullptr)
+ return;
+
+ BaseType* t = nullptr;
+ if (IsDelegateType(iface, *type.GetMetaType()))
+ t = new BaseType(GetFullNameFromType(*type.GetMetaType(), iface), "", true);
+ else
+ t = new BaseType(*type.GetMetaType());
+
+ assert(t != nullptr);
+
+ std::string type_name = GetFullNameFromType(type, iface);
+ auto elm = std::shared_ptr<Element>(new Element(type_name, t, "", __LINE__));
+ assert(elm != nullptr);
+
+ Elements* elms = new Elements();
+ assert(elms != nullptr);
+ elms->Add(std::move(elm));
+
+ auto* st = new Structure(type_name, elms, new tidl::Enums(), "", __LINE__);
+ assert(st != nullptr);
+
+ AddStructureFromType(*type.GetMetaType(), iface);
+
+ if (StructureExist(st)) {
+ delete st;
+ return;
+ }
+
+ structures_[type_name] = std::unique_ptr<Structure>(st);
+}
+
+std::string CCionGeneratorBase::RemoveLine(std::string lines,
+ unsigned int line_num) {
+ std::stringstream ss(lines);
+ std::string result;
+ std::string line;
+ unsigned int line_count = 0;
+
+ while (std::getline(ss, line, '\n')) {
+ line_count++;
+ if (line_num == line_count)
+ continue;
+
+ result += Trim(line);
+ result += NLine(1);
+ }
+
+ return result;
+}
+
+std::string CCionGeneratorBase::SmartIndent(std::string lines) {
+ std::stringstream ss(lines);
+ std::string result;
+ std::string line;
+ std::string next_line;
+ std::string tab;
+ std::string back;
+ std::size_t found;
+ bool if_statement = false;
+ bool continuous = false;
+ int tab_size = 0;
+ int line_count = 0;
+
+ while (std::getline(ss, next_line, '\n')) {
+ next_line = RemoveSpaces(next_line);
+ line_count++;
+ if (line_count == 1) {
+ line = Trim(next_line);
+ continue;
+ }
+
+ tab.clear();
+ found = line.find('}');
+ if (found != std::string::npos) {
+ tab_size--;
+ }
+
+ back = "__INVALID__";
+ if (line.length() > 0)
+ back = line.back();
+
+ if (back != ":" && line.length() > 0)
+ tab += Tab(tab_size);
+
+ if (continuous && tab_size == 0 &&
+ found == std::string::npos) {
+ tab += Tab(2);
+ }
+
+ if (found == std::string::npos && if_statement) {
+ tab_size--;
+ if_statement = false;
+ }
+
+ continuous = false;
+ if (back == "," || back == "\\")
+ continuous = true;
+
+ if (line.empty() || std::all_of(line.begin(), line.end(), isspace)) {
+ std::string n_line = Trim(next_line);
+ if (n_line.empty() ||
+ n_line.length() == 0 ||
+ n_line.find('}') != std::string::npos ||
+ std::all_of(n_line.begin(), n_line.end(), isspace)) {
+ line = n_line;
+ continue;
+ } else {
+ result += tab + line;
+ result += NLine(1);
+ }
+ } else {
+ // for annotation && ifdef
+ if (line.compare(0, 2, " *") == 0 || line.compare(0, 1, "#") == 0)
+ result += line;
+ else
+ result += tab + line;
+
+ result += NLine(1);
+ }
+
+ found = line.find('{');
+ if (found != std::string::npos) {
+ tab_size++;
+ } else {
+ found = line.find("if (");
+ if (found != std::string::npos) {
+ tab_size++;
+ if_statement = true;
+ }
+
+ found = line.find("else");
+ if (found != std::string::npos && line != "#else") {
+ tab_size++;
+ if_statement = true;
+ }
+
+ found = line.find("for (");
+ if (found != std::string::npos) {
+ tab_size++;
+ if_statement = true;
+ }
+
+ found = line.find("while (");
+ if (found != std::string::npos && back != ";") {
+ tab_size++;
+ if_statement = true;
+ }
+ }
+
+ line = Trim(next_line);
+ }
+
+ result += line;
+ result += NLine(1);
+
+ return result;
+}
+
+std::string CCionGeneratorBase::RemoveLastSpaces(const std::string& str) {
+ std::size_t found = str.find_last_not_of(' ');
+ if (found == std::string::npos)
+ return str;
+
+ return str.substr(0, found + 1);
+}
+
+std::string CCionGeneratorBase::RemoveSpaces(const std::string& str) {
+ // for annotation
+ if (str.compare(0, 3, "/**") == 0 ||
+ str.compare(0, 2, " *") == 0 ||
+ str.compare(0, 3, " */") == 0)
+ return str;
+
+ std::size_t found = str.find_first_not_of(' ');
+ if (found == std::string::npos)
+ return "";
+
+ return str.substr(found, str.size() - found);
+}
+
+std::string CCionGeneratorBase::Trim(const std::string& str) {
+ // for annotation
+ if (str.compare(0, 3, "/**") == 0 ||
+ str.compare(0, 2, " *") == 0 ||
+ str.compare(0, 3, " */") == 0)
+ return str;
+
+ std::size_t first = str.find_first_not_of(" \t\r\n");
+ if (first == std::string::npos)
+ return str;
+
+ std::size_t last = str.find_last_not_of(" \t\r\n");
+ return str.substr(first, (last - first + 1));
+}
+
+void CCionGeneratorBase::GenVersion(std::ofstream& stream) {
+ stream << ReplaceAll(CB_VERSION, "<VERSION>", FULLVER);
+}
+
+void CCionGeneratorBase::GenIncludeDefaultHeaders(std::ofstream& stream,
+ bool body) {
+ std::string str;
+ if (body) {
+ str = CB_BODY_HEADER;
+ } else {
+ str = CB_HEADER;
+ }
+
+ str = ReplaceAll(str, "<INCLUDE>",
+ GetTransportable().C().GenInclude(
+ body, static_cast<int>(GetChannelType())));
+ str = ReplaceAll(str, "<PREFIX>", GetHandlePrefix());
+ str = ReplaceAll(str, "<FILENAME>", GetFileNamespace());
+ stream << str;
+}
+
+void CCionGeneratorBase::GenGNUSourceDefinition(std::ofstream& stream) {
+ stream << SmartIndent(CB_GNU_SOURCE);
+}
+
+bool CCionGeneratorBase::StructureExist(const Structure* st) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_STRUCTURE)
+ continue;
+
+ const Structure &s = static_cast<const Structure&>(*i);
+ if (s.GetID() == st->GetID())
+ return true;
+ }
+
+ return false;
+}
+
+std::string CCionGeneratorBase::GetParamTypeString(
+ ParameterType::Direction direction, const BaseType& type) {
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ if (direction == ParameterType::Direction::IN)
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type) + "_h ";
+ else
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type) + "_h *";
+ }
+
+ if (type.ToString() == "string" || type.ToString() == "file") {
+ if (direction == ParameterType::Direction::IN)
+ return "const char *";
+ else
+ return "char **";
+ }
+
+ if (direction == ParameterType::Direction::IN)
+ return type_map_[type.ToString()];
+
+ return type_map_[type.ToString()] + "*";
+}
+
+std::string CCionGeneratorBase::GetParamTypeString(
+ ParameterType::Direction direction, const BaseType& type,
+ const Interface& iface) {
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ if (direction == ParameterType::Direction::IN)
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type, iface) + "_h ";
+ else
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type, iface) + "_h *";
+ }
+
+ if (type.ToString() == "string" || type.ToString() == "file") {
+ if (direction == ParameterType::Direction::IN)
+ return "const char *";
+ else
+ return "char **";
+ }
+
+ if (direction == ParameterType::Direction::IN)
+ return type_map_[type.ToString()];
+
+ return type_map_[type.ToString()] + "*";
+}
+
+std::string CCionGeneratorBase::GetArgTypeString(const BaseType& type,
+ const Interface& iface) {
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array")
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type, iface) + "_h ";
+
+ return type_map_[type.ToString()];
+}
+
+std::string CCionGeneratorBase::GetErrorValue(const BaseType& type) {
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array" ||
+ type.ToString() == "bundle" ||
+ type.ToString() == "string"||
+ type.ToString() == "file")
+ return "nullptr";
+ if (type.ToString() == "bool")
+ return "false";
+ if (type.ToString() == "char")
+ return "0";
+ return "-1";
+}
+
+std::string CCionGeneratorBase::GetMoudlePrefix() {
+ std::string prefix = GetTransportable().C().GenModulePrefix();
+
+ if (!HasNamespace()|| !IsGeneratedAPI())
+ return prefix;
+
+ return prefix + "_" + GetFileNamespace();
+}
+
+std::string CCionGeneratorBase::GetInternalHandlePrefix() {
+ std::string prefix = GetHandlePrefix();
+
+ if (!HasNamespace())
+ return prefix;
+
+ return prefix + "_internal";
+}
+
+std::string CCionGeneratorBase::GetHandlePrefix() {
+ std::string prefix;
+ switch(GetChannelType()) {
+ case ChannelType::TYPE_STUB:
+ prefix = GetTransportable().C().GenStubPrefix();
+ break;
+ case ChannelType::TYPE_PROXY:
+ prefix = GetTransportable().C().GenProxyPrefix();
+ break;
+ case ChannelType::TYPE_GROUP:
+ prefix = GetTransportable().C().GenGroupPrefix();
+ break;
+ default:
+ break;
+ }
+
+ if (!HasNamespace())
+ return prefix;
+
+ return prefix + "_" + GetFileNamespace();
+}
+
+const std::map<std::string, std::unique_ptr<Structure>>&
+CCionGeneratorBase::GetStructures() {
+ return structures_;
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/c_cion_gen_base.h b/idlc/gen_cion/c_cion_gen_base.h
new file mode 100644
index 0000000..abb9c2c
--- /dev/null
+++ b/idlc/gen_cion/c_cion_gen_base.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_GEN_BASE_H_
+#define IDLC_C_CION_GEN_C_GEN_BASE_H_
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include "idlc/ast/type.h"
+#include "idlc/ast/structure.h"
+#include "idlc/gen_cion/cion_plugin_base.h"
+
+namespace tidl {
+
+class CCionGeneratorBase : public CionPluginBase {
+ public:
+ explicit CCionGeneratorBase(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CCionGeneratorBase() = default;
+
+ std::string RemoveLine(std::string lines, unsigned int line_num = 1);
+ std::string SmartIndent(std::string lines);
+ std::string NLine(int cnt);
+
+ std::string GetFullNameFromType(const BaseType& type);
+ std::string GetFullNameFromType(const BaseType& type, const Interface& iface);
+
+ std::string GetDataTypeString(const BaseType& type, bool is_pointer = true);
+ std::string GetReturnTypeString(const BaseType& type);
+ std::string GetParamTypeString(ParameterType::Direction direction,
+ const BaseType& type);
+ std::string GetParamTypeString(ParameterType::Direction direction,
+ const BaseType& type, const Interface& iface);
+ std::string GetArgTypeString(const BaseType& type, const Interface& iface);
+ std::string GetErrorValue(const BaseType& type);
+
+ void AddStructureFromType(const BaseType& type);
+ void AddStructureFromType(const BaseType& type, const Interface& iface);
+
+ const std::map<std::string, std::unique_ptr<Structure>>& GetStructures();
+
+ void GenVersion(std::ofstream& stream);
+ void GenIncludeDefaultHeaders(std::ofstream& stream, bool body = true);
+ void GenGNUSourceDefinition(std::ofstream& stream);
+ std::string GetHandlePrefix();
+ std::string GetMoudlePrefix();
+ std::string GetInternalHandlePrefix();
+ std::string RemoveLastSpaces(const std::string& str);
+
+ private:
+ std::string Tab(int cnt);
+ std::string Trim(const std::string& str);
+ std::string RemoveSpaces(const std::string& str);
+ bool StructureExist(const Structure* st);
+
+ private:
+ std::map<std::string, std::unique_ptr<Structure>> structures_;
+ std::map<std::string, std::string> type_map_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_C_CION_GEN_C_GEN_BASE_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/c_cion_gen_base_cb.h b/idlc/gen_cion/c_cion_gen_base_cb.h
new file mode 100644
index 0000000..3a9048a
--- /dev/null
+++ b/idlc/gen_cion/c_cion_gen_base_cb.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_GEN_BASE_CB_H_
+#define IDLC_C_CION_GEN_C_GEN_BASE_CB_H_
+
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
+constexpr const char CB_VERSION[] =
+R"__c_cb(/*
+ * Generated by tidlc <VERSION>.
+ */
+)__c_cb";
+
+constexpr const char CB_GNU_SOURCE[] =
+R"__c_cb(
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+)__c_cb";
+
+constexpr const char CB_HEADER[] =
+R"__c_cb(
+#include <stdbool.h>
+#include <bundle.h>
+<INCLUDE>
+)__c_cb";
+
+constexpr const char CB_BODY_HEADER[] =
+R"__c_cb(
+#pragma GCC diagnostic ignored "-Warray-bounds"
+
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libgen.h>
+#include <glib.h>
+#include <dlog.h>
+#include <rpc-port-parcel.h>
+<INCLUDE>
+)__c_cb";
+
+#endif // IDLC_C_CION_GEN_C_GEN_BASE_CB_H_
diff --git a/idlc/gen_cion/c_cion_group_body_gen.cc b/idlc/gen_cion/c_cion_group_body_gen.cc
new file mode 100644
index 0000000..ea20722
--- /dev/null
+++ b/idlc/gen_cion/c_cion_group_body_gen.cc
@@ -0,0 +1,552 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+
+#include "idlc/gen_cion/c_cion_group_body_gen.h"
+#include "idlc/gen_cion/c_cion_group_body_gen_cb.h"
+
+namespace tidl {
+
+CCionGroupBodyGen::CCionGroupBodyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options, std::shared_ptr<tidl::Transportable> trans)
+ : CCionBodyGeneratorBase(doc, trans), options_(std::move(options)) {
+}
+
+void CCionGroupBodyGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenGNUSourceDefinition(stream);
+ GenIncludeDefaultHeaders(stream);
+ GenIncludeHeader(stream);
+ GenLogTag(stream, GetTransportable().C().GenGroupPrefix());
+ GenLogDefinition(stream);
+ GenBaseDefinition(stream);
+ GenInterfaceMethodHandlerType(stream);
+ GenInterfaceEnums(stream);
+ GenStructureDefs(stream);
+ GenInterfaceDefs(stream);
+ GenStructures(stream);
+ GenCommonFuntions(stream);
+ GenInterfaces(stream);
+}
+
+void CCionGroupBodyGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void CCionGroupBodyGen::GenInterfaceDefs(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterfaceDef(stream, iface);
+ }
+}
+
+void CCionGroupBodyGen::GenInterfaceDef(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_BASE_DEF)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<SECURITY_T>", GetTransportable().C().GenSecurityType())
+ .Change("<GROUP_T>", GetTransportable().C().GenGroupType())
+ .Change("<INTERNAL_PREFIX>", GetInternalHandlePrefix())
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+void CCionGroupBodyGen::GenInterfaceEnums(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceEnum(stream, iface);
+ }
+}
+
+// @see #CB_INTERFACE_METHOD_ENUM
+std::string CCionGroupBodyGen::GenMethodEnums(const Interface& iface) {
+ std::string method_enums, method_enum;
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ method_enum = ReplaceAll(CB_INTERFACE_METHOD_ENUM, {
+ { "<UPPERCASE_PREFIX>", GetHandlePrefix() },
+ { "<UPPERCASE_NAME>", iface.GetID() },
+ { "<UPPERCASE_METHOD_NAME>", d->GetID() }
+ });
+
+ method_enums += RemoveLine(method_enum);
+ }
+ std::transform(method_enums.begin(), method_enums.end(), method_enums.begin(),
+ ::toupper);
+
+ return method_enums;
+}
+
+void CCionGroupBodyGen::GenInterfaceEnum(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_ENUMS>", GenMethodEnums(iface) }
+ })
+ .Transform([&](std::string str){
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_TYPE
+void CCionGroupBodyGen::GenInterfaceMethodHandlerType(std::ofstream& stream) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_HANDLER_TYPE,
+ "<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType()));
+ code = ReplaceAll(code, "<MODULE_PREFIX>", GetMoudlePrefix());
+
+ stream << SmartIndent(code);
+}
+
+void CCionGroupBodyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CCionGroupBodyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceMethodHandlerBase(stream, iface, *d);
+ }
+
+ GenInterfaceMethodTable(stream, iface);
+
+ GenInterfaceBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::ASYNC)
+ continue;
+
+ GenInterfaceMethodBase(stream, iface, *d);
+ }
+}
+
+// @see #CB_INTERFACE_METHOD_TABLE
+void CCionGroupBodyGen::GenInterfaceMethodTable(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_METHOD_TABLE, {
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_HANDLERS>", GenMethodHandlers(iface) }
+ })
+ .Transform([&](std::string str){
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER
+std::string CCionGroupBodyGen::GenMethodHandlers(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_METHOD_" + d->GetID();
+ std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
+ ::toupper);
+
+ std::string method_handler(ReplaceAll(CB_INTERFACE_METHOD_HANDLER, {
+ { "<ENUM_VALUE>", enum_value },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", d->GetID() }
+ }));
+
+ code += RemoveLine(method_handler);
+ }
+
+ return code;
+}
+
+// @see #CB_INTERFACE_BASE
+void CCionGroupBodyGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+ ReplaceAll(CB_INTERFACE_BASE)
+ .Change("<EXTRA>", GetTransportable().C().GenGroupExtra())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Change("<GROUP_CREATE>", GetTransportable().C().GenGroupCreate())
+ .Change("<NAME>", name)
+ .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
+ .ChangeToUpper("<UPPERCASE_NAME>", name)
+ .Change("<SET_SECURITY>", GenSecurityString(iface))
+ .Change("<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType())
+ .Change("<SECURITY_T>", GetTransportable().C().GenSecurityType())
+ .Change("<PAYLOAD_T>", GetTransportable().C().GenPayloadType(true))
+ .Change("<PAYLOAD_TYPE_E>", GetTransportable().C().GenPayloadTypeEnum())
+ .Change("<PAYLOAD_GET_TYPE>", GetTransportable().C().GenPayloadGetType())
+ .Change("<ERROR_NONE>", GetTransportable().C().GenErrorNone())
+ .Change("<PAYLOAD_TYPE_DATA>", GetTransportable().C().GenPayloadTypeData())
+ .Change("<PAYLOAD_GET_DATA>", GetTransportable().C().GenPayloadGetData())
+ .Change("<GROUP_DESTROY>", GetTransportable().C().GenGroupDestroy())
+ .Change("<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Change("<INTERNAL_PREFIX>", GetInternalHandlePrefix())
+ .Change("<PREFIX>", prefix)
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_BASE
+void CCionGroupBodyGen::GenInterfaceMethodHandlerBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_HANDLER_BASE, {
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_HANDLER_ARGS_DECL>", GenMethodHandlerArgsDecl(iface, decl) },
+ { "<METHOD_HANDLER_PARCEL_READ>",
+ GenMethodHandlerParcelRead(iface, decl) },
+ { "<METHOD_HANDLER_CALLBACK_INVOKE>",
+ GenMethodHandlerCallbackInvoke(decl) },
+ { "<METHOD_HANDLER_ARGS_FREE>", GenMethodHandlerArgsFree(iface, decl) },
+ { "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix() },
+ { "<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<PREFIX>", GetHandlePrefix() }
+ })
+ .Transform([&](std::string str){
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_INVOKE
+std::string CCionGroupBodyGen::GenMethodHandlerCallbackInvoke(
+ const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_INVOKE,
+ "<METHOD_NAME>", decl.GetID()));
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC)
+ code = ReplaceAll(code, "<RES_SET>", "res_ = ");
+ else
+ code = ReplaceAll(code, "<RES_SET>", "");
+
+ std::string args;
+ for (const auto& p : decl.GetParameters()) {
+ args += ", ";
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ args += "&";
+
+ args += p->GetID();
+ }
+ code = ReplaceAll(code, "<METHOD_ARGS>", args);
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_READ
+std::string CCionGroupBodyGen::GenMethodHandlerParcelRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ std::string parcel_read_code;
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type)) {
+ parcel_read_code = ReplaceAll(
+ CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>",
+ GetFullNameFromType(type, iface));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
+ } else if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_read_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>",
+ GetFullNameFromType(type, iface));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
+ }
+
+ code += parcel_read_code;
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CCionGroupBodyGen::GenMethodHandlerArgsDecl(const Interface& iface,
+ const Declaration& decl) {
+ std::string args_decl;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ args_decl += GetArgTypeString(type, iface) + p->GetID() + " = " +
+ GetErrorValue(type) + ";" + NLine(1);
+ }
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
+ args_decl += "rpc_port_parcel_h parcel_;" + NLine(1);
+ args_decl += GetArgTypeString(decl.GetType(), iface) + "res_ = " +
+ GetErrorValue(decl.GetType()) + ";" + NLine(1);
+ }
+
+ return args_decl;
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_FREE
+// @see #CB_INTERFACE_METHOD_BUNDLE_FREE
+// @see #CB_INTERFACE_METHOD_STRING_FREE
+std::string CCionGroupBodyGen::GenMethodHandlerArgsFree(const Interface& iface,
+ const Declaration& decl) {
+ std::string free_code;
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_FREE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", GetFullNameFromType(type, iface) },
+ { "<ARG>", p->GetID() }
+ });
+ } else if (type.ToString() == "bundle") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE,
+ "<ARG>", p->GetID());
+ } else {
+ free_code.clear();
+ }
+
+ code += free_code;
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CCionGroupBodyGen::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+std::string CCionGroupBodyGen::GenMethodParamsCheck(const Interface& iface,
+ const Declaration& decl) {
+ std::string params_check;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array" ||
+ type.ToString() == "bundle" ||
+ type.ToString() == "string")
+ params_check += " || " + p->GetID() + " == nullptr";
+ }
+
+ return params_check;
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_WRITE
+std::string CCionGroupBodyGen::GenMethodParcelWrite(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+
+ std::string parcel_write_code;
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE, "<ARG>",
+ p->GetID());
+ std::string name = GetFullNameFromType(type, iface);
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ARG>",
+ p->GetID());
+ }
+
+ code += parcel_write_code;
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_ASYNC_BASE
+std::string CCionGroupBodyGen::GenMethodAsyncBase(const Interface& iface,
+ const Declaration& decl) {
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+ std::string method_name = decl.GetID();
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_ASYNC_BASE)
+ .Change("<PREFIX>", prefix)
+ .Change("<NAME>", name)
+ .Change("<METHOD_NAME>", method_name)
+ .Change("<METHOD_PARAMS>", GenMethodParams(iface, decl))
+ .Change("<METHOD_PARAMS_CHECK>", GenMethodParamsCheck(iface, decl))
+ .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
+ .ChangeToUpper("<UPPERCASE_NAME>", name)
+ .ChangeToUpper("<UPPERCASE_METHOD_NAME>", method_name)
+ .Change("<METHOD_PARCEL_WRITE>", GenMethodParcelWrite(iface, decl))
+ .Change("<PAYLOAD_T>", GetTransportable().C().GenPayloadType(true))
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Change("<GROUP_PUBLISH>", GetTransportable().C().GenGroupPublish())
+ .Change("<INTERNAL_PREFIX>", GetInternalHandlePrefix())
+ .Change("<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix()));
+ return code;
+}
+
+std::string CCionGroupBodyGen::GenMethodArgs(const Interface& iface,
+ const Declaration& decl) {
+ std::string args_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ args_code += GetReturnTypeString(type) + "new_" + p->GetID() + ";";
+ args_code += NLine(1);
+ }
+
+ return args_code;
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_READ
+std::string CCionGroupBodyGen::GenMethodParcelReadBase(const Interface& iface,
+ const BaseType& type, const std::string& param_name) {
+ std::string parcel_read_code;
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_read_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ std::string name = GetFullNameFromType(type, iface);
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>", name);
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", param_name);
+ } else if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ,
+ "<ARG>", param_name);
+ } else if (type.ToString() == "string") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_READ,
+ "<ARG>", param_name);
+ } else {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>",
+ param_name);
+ }
+
+ return parcel_read_code;
+}
+
+// @see #CB_INTERFACE_METHOD_VALUE_SET
+std::string CCionGroupBodyGen::GenMethodParcelRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ std::string parcel_read_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ code += GenMethodParcelReadBase(iface, type, "new_" + p->GetID());
+ code += ReplaceAll(CB_INTERFACE_METHOD_PARAM_SET, "<PARAM>",
+ p->GetID());
+ }
+
+ // Return Value
+ auto& base_type = decl.GetType();
+ code += GenMethodParcelReadBase(iface, base_type, "ret_");
+ return RemoveLine(code);
+}
+
+void CCionGroupBodyGen::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code = GenMethodAsyncBase(iface, decl);
+ stream << SmartIndent(code);
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/c_cion_group_body_gen.h b/idlc/gen_cion/c_cion_group_body_gen.h
new file mode 100644
index 0000000..bf1922b
--- /dev/null
+++ b/idlc/gen_cion/c_cion_group_body_gen.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_GROUP_BODY_GEN_H_
+#define IDLC_C_CION_GEN_C_GROUP_BODY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/c_cion_body_gen_base.h"
+#include "idlc/options.h"
+
+namespace tidl {
+
+class CCionGroupBodyGen : public CCionBodyGeneratorBase {
+ public:
+ explicit CCionGroupBodyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CCionGroupBodyGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenInterfaceDefs(std::ofstream& stream);
+ void GenInterfaceDef(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodHandlerType(std::ofstream& stream);
+ void GenInterfaceMethodHandlerBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl);
+ std::string GenMethodHandlerArgsDecl(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlerArgsFree(const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceMethodTable(std::ofstream& stream,
+ const Interface& iface);
+ std::string GenMethodHandlerCallbackInvoke(const Declaration& decl);
+ std::string GenMethodHandlerParcelRead(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlers(const Interface& iface);
+ std::string GenMethodEnums(const Interface& iface);
+ void GenInterfaceEnums(std::ofstream& stream);
+ void GenInterfaceEnum(std::ofstream& stream, const Interface& iface);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodEnumBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+
+ std::string GenMethodAsyncBase(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParamsCheck(const Interface& iface,
+ const Declaration& decl);
+ bool GenMethodParamsFileCheck(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodParcelWrite(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodArgs(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParcelReadBase(const Interface& iface,
+ const BaseType& type, const std::string& param_name);
+ std::string GenMethodParcelRead(const Interface& iface,
+ const Declaration& decl);
+
+ private:
+ std::shared_ptr<Options> options_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_C_CION_GEN_C_GROUP_BODY_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/c_cion_group_body_gen_cb.h b/idlc/gen_cion/c_cion_group_body_gen_cb.h
new file mode 100644
index 0000000..f3aeb90
--- /dev/null
+++ b/idlc/gen_cion/c_cion_group_body_gen_cb.h
@@ -0,0 +1,516 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_GROUP_BODY_GEN_CB_H_
+#define IDLC_C_CION_GEN_C_GROUP_BODY_GEN_CB_H_
+
+
+constexpr const char CB_INTERFACE_METHOD_HANDLER_TYPE[] =
+R"__c_cb(
+typedef int (*_group_method_handler)(const <PEER_INFO_T> peer_info, rpc_port_parcel_h parcel, void *data);
+)__c_cb";
+
+/**
+ * <METHOD_ENUMS> The enumeration declarations of methods.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM_BASE[] =
+R"__c_cb(
+typedef enum {
+ <METHOD_ENUMS>
+} <PREFIX>_<NAME>_method_e;
+)__c_cb";
+
+
+/**
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM[] =
+R"__c_cb(
+<UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>,
+)__c_cb";
+
+
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ int id;
+ int seq_id;
+ bool once;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback;
+ void *user_data;
+} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
+)__c_cb";
+
+/**
+ * <ENUM_VALUE> The enumeration value.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_TABLE_MEMBER[] =
+R"__c_cb(
+[<ENUM_VALUE>] = __<PREFIX>_<NAME>_<DELEGATE_NAME>_delegate_handler,
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ char *topic_name;
+ <GROUP_T> group;
+ <SECURITY_T>
+ <PREFIX>_<NAME>_callback_s callback;
+ GRecMutex mutex;
+ void *user_data;
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_HANDLER_ARGS_DECL> The declarations for arguments of the method.
+ * <METHOD_HANDLER_PARCEL_READ> The implementation to read the parameter from the parcel.
+ * <METHOD_HANDLER_CALLBACK_INVOKE> The implementation to invoke the callback function of the method.
+ * <METHOD_HANDLER_PARCEL_WRITE> The implementation to write the result to the parcel.
+ * <METHOD_HANDLER_ARGS_FREE> The implementation to release arguments.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER_BASE[] =
+R"__c_cb(
+static int __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler(const <PEER_INFO_T> peer_info, rpc_port_parcel_h parcel, void *user_data)
+{
+ <PREFIX>_<NAME>_t *h = user_data;
+ int ret_ = <ERROR_PREFIX>_ERROR_NONE;
+
+ <METHOD_HANDLER_ARGS_DECL>
+ if (h == nullptr || h->group == nullptr) {
+ _E("Invalid parameter");
+ ret_ = <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ goto out;
+ }
+ <METHOD_HANDLER_PARCEL_READ>
+ <METHOD_HANDLER_CALLBACK_INVOKE>
+
+ out:
+ <METHOD_HANDLER_ARGS_FREE>
+ return ret_;
+}
+)__c_cb";
+
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+static int __<PREFIX>_<NAME>_process_received_event(<PREFIX>_<NAME>_t *h, const <PEER_INFO_T> peer_info, rpc_port_parcel_h parcel)
+{
+ int ret = <ERROR_PREFIX>_ERROR_NONE;
+ int cmd = -1;
+ static const int table_size = ARRAY_SIZE(__<NAME>_method_table);
+
+ rpc_port_parcel_read_int32(parcel, &cmd);
+ if (cmd >= 0 && cmd < table_size) {
+ if (__<NAME>_method_table[cmd])
+ ret = __<NAME>_method_table[cmd](peer_info, parcel, h);
+ } else {
+ _W("Invalid protocol. cmd(%d)", cmd);
+ ret = <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ return ret;
+}
+
+static void __<PREFIX>_<NAME>_joined_cb(const char *topic_name,
+ const <PEER_INFO_T> peer_info, void *user_data)
+{
+ <PREFIX>_<NAME>_h h = user_data;
+
+ _I("topic_name(%s)", topic_name);
+ h->callback.joined(h, peer_info, h->user_data);
+}
+
+static void __<PREFIX>_<NAME>_left_cb(const char *topic_name,
+ const <PEER_INFO_T> peer_info, void *user_data)
+{
+ <PREFIX>_<NAME>_h h = user_data;
+
+ _W("topic_name(%s)", topic_name);
+ h->callback.left(h, peer_info, h->user_data);
+
+}
+
+static void __<PREFIX>_<NAME>_received(const char *topic_name,
+ const <PEER_INFO_T> peer_info, <PAYLOAD_T> payload, void *user_data)
+{
+ <PREFIX>_<NAME>_h h = user_data;
+ rpc_port_parcel_h parcel;
+ unsigned char *data;
+ <PAYLOAD_TYPE_E> type;
+ int ret;
+ unsigned int data_len;
+
+ _W("topic_name(%s)", topic_name);
+
+ <PAYLOAD_GET_TYPE>
+ if (ret != <ERROR_NONE> || type != <PAYLOAD_TYPE_DATA>) {
+ _E("Faled to <MODULE_PREFIX>_payload_get_type : [%d][%d]", ret, type);
+ return;
+ }
+
+ <PAYLOAD_GET_DATA>
+ if (ret != <ERROR_NONE>) {
+ _E("Faled to <MODULE_PREFIX>_payload_get_data : %d", ret);
+ return;
+ }
+
+ ret = rpc_port_parcel_create_from_raw(&parcel, data, data_len);
+ free(data);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle from data. error(%d)", ret);
+ return;
+ }
+
+ __<PREFIX>_<NAME>_process_received_event(h, peer_info, parcel);
+ rpc_port_parcel_destroy(parcel);
+
+}
+
+<EXTRA> {
+ <PREFIX>_<NAME>_t *handle;
+ int ret;
+ <SECURITY_T>
+
+ if (topic_name == nullptr || callback == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ if (callback->joined == nullptr || callback->left == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ }
+
+ g_rec_mutex_init(&handle->mutex);
+
+ handle->topic_name = strdup(topic_name);
+ if (handle->topic_name == nullptr) {
+ _E("Failed to duplicate topic name");
+ <PREFIX>_<NAME>_destroy(handle);
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ }
+ <GROUP_CREATE>
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ g_rec_mutex_unlock(&h->mutex);
+ g_rec_mutex_clear(&h->mutex);
+
+ <GROUP_DESTROY>
+
+ if (h->topic_name)
+ free(h->topic_name);
+
+ free(h);
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_PARAMS> The parameters of the method of the interface
+ * <METHOD_PARAMS_CHECK> The parameters check of the method.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ * <METHOD_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ * <METHOD_DELEGATES_APPEND> The implementation to add the delegates to the list.
+ */
+constexpr const char CB_INTERFACE_METHOD_ASYNC_BASE[] =
+R"__c_cb(
+void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
+{
+ rpc_port_parcel_h parcel_ = nullptr;
+ int res_;
+ unsigned int data_size_;
+ unsigned char *data_;
+ <PAYLOAD_T> pl_ = nullptr;
+
+ if (h == nullptr<METHOD_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ set_last_result(<ERROR_PREFIX>_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ if (h->group == nullptr) {
+ _E("Not connected");
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(<ERROR_PREFIX>_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ res_ = rpc_port_parcel_create(&parcel_);
+ if (res_ != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", res_);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(res_);
+ return;
+ }
+
+ rpc_port_parcel_write_int32(parcel_, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
+
+ <METHOD_PARCEL_WRITE>
+
+ res_ = rpc_port_parcel_get_raw(parcel_, (void **)&data_, &data_size_);
+ if (res_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get raw. error(%d)", res_);
+ goto out;
+ }
+ <GROUP_PUBLISH>
+out:
+ set_last_result(res_);
+ g_rec_mutex_unlock(&h->mutex);
+
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel_, &<ARG>->parcelable, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+<PREFIX>_<NAME>_create(&<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to create handle");
+ ret_ = <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ goto out;
+}
+
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+if (get_last_result() != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to read data");
+ <PREFIX>_<NAME>_destroy(<ARG>);
+ <ARG> = nullptr;
+ ret_ = get_last_result();
+ goto out;
+}
+)__c_cb";
+
+
+/**
+ * <ENUM_VALUE> The enumeration value of the method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER[] =
+R"__c_cb(
+[<ENUM_VALUE>] = __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler,
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ <PREFIX>_<NAME>_destroy(<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ bundle_free(<ARG>);
+)__c_cb";
+
+/**
+ * <RES_SET> The implemention to set the result of the callback function.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <METHOD_ARGS> The arguments of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_INVOKE[] =
+R"__c_cb(
+if (h->callback.<METHOD_NAME>)
+ <RES_SET>h->callback.<METHOD_NAME>(peer_info<METHOD_ARGS>, h->user_data);
+)__c_cb";
+
+
+/**
+ * <ARG> The argument.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface
+ */
+constexpr const char CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ[] =
+R"__c_cb(
+ret_ = <PREFIX>_<NAME>_create(&<ARG>);
+if (ret_ != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret_);
+ goto out;
+}
+
+__<PREFIX>_<NAME>_set_peerInfo(<ARG>, peer_info);
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+ret_ = get_last_result();
+if (ret_ != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret_);
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ free(<ARG>);
+)__c_cb";
+
+/**
+ * <NAME> The name of the interface.
+ * <METHOD_HANDLERS> The declarations of method handlers.
+ */
+constexpr const char CB_INTERFACE_METHOD_TABLE[] =
+R"__c_cb(
+static _group_method_handler __<NAME>_method_table[] = {
+ <METHOD_HANDLERS>
+};
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+rpc_port_parcel_read_bundle(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ ret_ = <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ goto out;
+
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+rpc_port_parcel_read_string(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ ret_ = <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &<ARG>);
+)__c_cb";
+
+/**
+ * <PARAM> The name of the parameter.
+ */
+constexpr const char CB_INTERFACE_METHOD_PARAM_SET[] =
+R"__c_cb(
+*<PARAM> = new_<PARAM>;
+)__c_cb";
+
+#endif // IDLC_C_CION_GEN_C_GROUP_BODY_GEN_CB_H_
diff --git a/idlc/gen_cion/c_cion_group_header_gen.cc b/idlc/gen_cion/c_cion_group_header_gen.cc
new file mode 100644
index 0000000..75d346d
--- /dev/null
+++ b/idlc/gen_cion/c_cion_group_header_gen.cc
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/c_cion_group_header_gen.h"
+
+namespace {
+#include "idlc/gen_cion/c_cion_group_header_gen_cb.h"
+}
+
+namespace tidl {
+
+CCionGroupHeaderGen::CCionGroupHeaderGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans)
+ : CCionHeaderGeneratorBase(doc, trans) {
+}
+
+void CCionGroupHeaderGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenPragmaOnce(stream);
+ GenIncludeDefaultHeaders(stream, false);
+ GenExplicitLinkageOpen(stream);
+ GenCommonHandles(stream);
+ GenStructureHandles(stream);
+ GenInterfaceHandles(stream);
+ GenStructures(stream);
+ GenCommonBase(stream);
+ GenInterfaceCallbacks(stream);
+ GenInterfaces(stream);
+}
+
+void CCionGroupHeaderGen::OnFiniGen(std::ofstream& stream) {
+ GenExplicitLinkageClose(stream);
+}
+
+void CCionGroupHeaderGen::GenInterfaceHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceHandle(stream, iface);
+ }
+}
+
+void CCionGroupHeaderGen::GenInterfaceCallbacks(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceCallbackBase(stream, iface);
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceMethodCallbackBase(stream, iface, *d);
+ }
+ }
+}
+
+void CCionGroupHeaderGen::GenInterfaceCallbackBase(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_CALLBACK_BASE)
+ .Change("<NAME>", iface.GetID())
+ .Change("<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_BASE
+void CCionGroupHeaderGen::GenInterfaceMethodCallbackBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_BASE, {
+ { "<RETURN_TYPE>", GetReturnTypeString(decl.GetType()) },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_PARAMS>", GenMethodParams(iface, decl) },
+ { "<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<PREFIX>", GetHandlePrefix() },
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_HANDLE
+void CCionGroupHeaderGen::GenInterfaceHandle(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_HANDLE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+void CCionGroupHeaderGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CCionGroupHeaderGen::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+
+ GenInterfaceBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceMethodBase(stream, iface, *d);
+ }
+}
+
+// @see #CB_INTERFACE_BASE
+void CCionGroupHeaderGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_BASE, {
+ { "<EXTRA>", GetTransportable().C().GenGroupExtra(false) },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID()},
+ { "<METHOD_CALLBACK_DECLS>", GenMethodCallbackDecls(iface) },
+ { "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix() }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_DECL
+std::string CCionGroupHeaderGen::GenMethodCallbackDecls(const Interface& iface) {
+ std::string method_callback_decls;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string method_callback_decl(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_DECL, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", d->GetID() }
+ }));
+
+ method_callback_decl = RemoveLine(method_callback_decl);
+ method_callback_decls += RemoveLine(method_callback_decl, 2);
+ }
+
+ return method_callback_decls;
+}
+
+std::string CCionGroupHeaderGen::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+// @see #CB_INTERFACE_METHOD_BASE
+void CCionGroupHeaderGen::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_BASE, {
+ { "<RETURN_TYPE>", GetReturnTypeString(decl.GetType()) },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_PARAMS>", GenMethodParams(iface, decl) },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix() }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/c_cion_group_header_gen.h b/idlc/gen_cion/c_cion_group_header_gen.h
new file mode 100644
index 0000000..b12132d
--- /dev/null
+++ b/idlc/gen_cion/c_cion_group_header_gen.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_GROUP_HEADER_GEN_H_
+#define IDLC_C_CION_GEN_C_GROUP_HEADER_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/c_cion_header_gen_base.h"
+
+namespace tidl {
+
+class CCionGroupHeaderGen : public CCionHeaderGeneratorBase {
+ public:
+ explicit CCionGroupHeaderGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CCionGroupHeaderGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenInterfaceHandles(std::ofstream& stream);
+ void GenInterfaceHandle(std::ofstream& stream, const Interface& iface);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+
+ void GenInterfaceCallbacks(std::ofstream& stream);
+ void GenInterfaceCallbackBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodCallbackBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl);
+ std::string GenMethodCallbackDecls(const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& ifaceo,
+ const Declaration& decl);
+
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_C_CION_GEN_C_GROUP_HEADER_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/c_cion_group_header_gen_cb.h b/idlc/gen_cion/c_cion_group_header_gen_cb.h
new file mode 100644
index 0000000..4b31a8d
--- /dev/null
+++ b/idlc/gen_cion/c_cion_group_header_gen_cb.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_GROUP_HEADER_GEN_CB_H_
+#define IDLC_C_CION_GEN_C_GROUP_HEADER_GEN_CB_H_
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_HANDLE[] =
+R"__c_cb(
+/**
+ * @brief The <PREFIX>_<NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_s *<PREFIX>_<NAME>_h;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CALLBACK_BASE[] =
+R"__c_cb(
+/**
+ * @brief Called when a peer joins a topic.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] peer_info The <MODULE_PREFIX> peer information handle \n
+ * The @a peer_info can be used only in the callback. To use outside, make a copy.
+ * @param[in] user_data The user data
+ * @see <MODULE_PREFIX>_peer_info_clone()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_joined_cb)(<PREFIX>_<NAME>_h h,
+ const <PEER_INFO_T> peer_info, void *user_data);
+
+/**
+ * @brief Called when a peer leaves a topic.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] peer_info The <MODULE_PREFIX> peer information handle \n
+ * The @a peer_info can be used only in the callback. To use outside, make a copy.
+ * @param[in] user_data The user data
+ * @see <MODULE_PREFIX>_peer_info_clone()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_left_cb)(<PREFIX>_<NAME>_h h,
+ const <PEER_INFO_T> peer_info, void *user_data);
+
+)__c_cb";
+
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+/**
+ * @brief The structure type containing the set of callback functions for handling events.
+ * @details It is one of the input parameters of the <PREFIX>_<NAME>_register() function.
+ *
+ * @see <PREFIX>_<NAME>_create_cb
+ * @see <PREFIX>_<NAME>_terminate_cb
+ */
+typedef struct {
+ <PREFIX>_<NAME>_joined_cb joined;/**< This callback function is invoked when a peer joins a topic. */
+ <PREFIX>_<NAME>_left_cb left;/**< This callback function is invoked when when a peer leaves a topic. */
+ <METHOD_CALLBACK_DECLS>
+} <PREFIX>_<NAME>_callback_s;
+
+<EXTRA>
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_BASE[] =
+R"__c_cb(
+/**
+ * @brief Called when the payload is received.
+ *
+ * @param[in] peer_info The <MODULE_PREFIX> peer information handle \n
+ * The @a peer_info can be used only in the callback. To use outside, make a copy.
+ * @param[in] ...
+ * @param[in] user_data The user data passed from the registration function
+ * @see <MODULE_PREFIX>_peer_info_clone()
+ * @see #<PREFIX>_<NAME>_callback_s;
+ */
+typedef <RETURN_TYPE> (*<PREFIX>_<NAME>_<METHOD_NAME>_cb)(const <PEER_INFO_T> peer_info<METHOD_PARAMS>, void *user_data);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The name of the method of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_DECL[] =
+R"__c_cb(
+<PREFIX>_<NAME>_<METHOD_NAME>_cb <METHOD_NAME>; /**< This callback function is invoked when the <METHOD_NAME> request is delivered. */
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The type of the return value.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The of the interface.
+ * <METHOD_NAME> The name of the method.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE[] =
+R"__c_cb(
+/**
+ * @brief Calls the <METHOD_NAME>() method.
+ * @details The return value and args are decided by the interface declaration.
+ * You can get the result using get_last_result().
+ * Before returning the function, the function sets the result using set_last_result().
+ * @remarks The specific error code can be obtained using the get_last_result() function. Error codes are described in Exception section.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] ...
+ * @exception #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @exception #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @exception #<ERROR_PREFIX>_ERROR_IO_ERROR I/O error
+ */
+<RETURN_TYPE><PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>);
+)__c_cb";
+
+#endif // IDLC_C_CION_GEN_C_GROUP_HEADER_GEN_CB_H_
diff --git a/idlc/gen_cion/c_cion_header_gen_base.cc b/idlc/gen_cion/c_cion_header_gen_base.cc
new file mode 100644
index 0000000..23fa609
--- /dev/null
+++ b/idlc/gen_cion/c_cion_header_gen_base.cc
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+
+#include <vector>
+
+#include "idlc/gen_cion/c_cion_header_gen_base.h"
+
+namespace {
+#include "idlc/gen_cion/c_cion_header_gen_base_cb.h"
+}
+
+namespace tidl {
+
+CCionHeaderGeneratorBase::CCionHeaderGeneratorBase(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : CCionGeneratorBase(doc, trans) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ for (const auto& e : st.GetElements()) {
+ auto& type = e->GetType();
+ AddStructureFromType(type);
+ }
+ } else {
+ auto& iface = static_cast<const Interface&>(*b);
+ for (const auto& d : iface.GetDeclarations()) {
+ for (const auto& p : d->GetParameters()) {
+ auto& type = p->GetParameterType().GetBaseType();
+ if (IsDelegateType(iface, type))
+ continue;
+
+ AddStructureFromType(type, iface);
+ }
+
+ if (d->GetMethodType() == Declaration::MethodType::SYNC) {
+ auto& type = d->GetType();
+ AddStructureFromType(type, iface);
+ }
+ }
+ }
+ }
+}
+
+void CCionHeaderGeneratorBase::GenPragmaOnce(std::ofstream& stream) {
+ const char format[] = "#pragma once\n";
+
+ stream << NLine(1);
+ stream << std::string(format);
+}
+
+void CCionHeaderGeneratorBase::GenExplicitLinkageOpen(std::ofstream& stream) {
+ stream << CB_EXPLICIT_LINKAGE_OPEN;
+}
+
+void CCionHeaderGeneratorBase::GenExplicitLinkageClose(std::ofstream& stream) {
+ stream << CB_EXPLICIT_LINKAGE_CLOSE;
+}
+
+void CCionHeaderGeneratorBase::GenCommonHandles(std::ofstream& stream) {
+ ReplaceAll(GetTransportable().C().GenHeaderCommonHandle())
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CCionHeaderGeneratorBase::GenFileHandle(std::ofstream& stream) {
+ ReplaceAll(GetTransportable().C().GenHeaderPayloadHandle())
+ .Change("<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix())
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CCionHeaderGeneratorBase::GenFileBase(std::ofstream& stream) {
+ ReplaceAll(GetTransportable().C().GenHeaderPayloadBase())
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CCionHeaderGeneratorBase::GenConnectionHandle(std::ofstream& stream) {
+ ReplaceAll(GetTransportable().C().GenHeaderConnectionHandle())
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CCionHeaderGeneratorBase::GenConnectionBase(std::ofstream& stream) {
+ ReplaceAll(GetTransportable().C().GenHeaderConnectionBase())
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CCionHeaderGeneratorBase::GenCommonBase(std::ofstream& stream) {
+ ReplaceAll(GetTransportable().C().GenHeaderBase())
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CCionHeaderGeneratorBase::GenStructureHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructureHandle(stream, st);
+ }
+ }
+
+ for (auto& i : GetStructures()) {
+ auto& st = i.second;
+ GenStructureHandle(stream, *st);
+ }
+}
+
+void CCionHeaderGeneratorBase::GenStructures(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructure(stream, st);
+ }
+ }
+
+ for (auto& i : GetStructures()) {
+ auto& st = i.second;
+ GenStructure(stream, *st);
+ }
+}
+
+// @see #CB_STRUCTURE_HANDLE
+void CCionHeaderGeneratorBase::GenStructureHandle(std::ofstream& stream,
+ const Structure& st) {
+ ReplaceAll(CB_STRUCTURE_HANDLE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_STRUCTURE_ARRAY_BASE
+void CCionHeaderGeneratorBase::GenStructureArrayBase(std::ofstream& stream,
+ const Structure& st) {
+ auto& elm = *(st.GetElements().begin());
+ auto& type = elm->GetType();
+
+ ReplaceAll(CB_STRUCTURE_ARRAY_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Change("<PARAM_TYPE_IN>",
+ GetParamTypeString(ParameterType::Direction::IN, type))
+ .Change("<PARAM_TYPE_OUT>",
+ GetParamTypeString(ParameterType::Direction::OUT, type))
+ .Change("<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix())
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_STRUCTURE_LIST_BASE
+void CCionHeaderGeneratorBase::GenStructureListBase(std::ofstream& stream,
+ const Structure& st) {
+ auto& elm = *(st.GetElements().begin());
+ auto& type = elm->GetType();
+
+ ReplaceAll(CB_STRUCTURE_LIST_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Change("<PARAM_TYPE_IN>",
+ GetParamTypeString(ParameterType::Direction::IN, type))
+ .Change("<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix())
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_STRUCTURE_BASE
+void CCionHeaderGeneratorBase::GenStructureBase(std::ofstream& stream,
+ const Structure& st) {
+ ReplaceAll(CB_STRUCTURE_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Change("<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix())
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+
+ for (const auto& e : st.GetElements()) {
+ auto& type = e->GetType();
+
+ ReplaceAll(CB_STRUCTURE_BASE_SET_GET)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", st.GetID())
+ .Change("<PARAM_TYPE_IN>",
+ GetParamTypeString(ParameterType::Direction::IN, type))
+ .Change("<PARAM_TYPE_OUT>",
+ GetParamTypeString(ParameterType::Direction::OUT, type))
+ .Change("<ELEMENT_NAME>", e->GetID())
+ .Change("<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix())
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+ }
+}
+
+void CCionHeaderGeneratorBase::GenStructure(std::ofstream& stream,
+ const Structure& st) {
+ if (st.GetID().compare(0, strlen("array"), "array") == 0)
+ GenStructureArrayBase(stream, st);
+ else if (st.GetID().compare(0, strlen("list"), "list") == 0)
+ GenStructureListBase(stream, st);
+ else
+ GenStructureBase(stream, st);
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/c_cion_header_gen_base.h b/idlc/gen_cion/c_cion_header_gen_base.h
new file mode 100644
index 0000000..0bdef42
--- /dev/null
+++ b/idlc/gen_cion/c_cion_header_gen_base.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_HEADER_GEN_BASE_H_
+#define IDLC_C_CION_GEN_C_HEADER_GEN_BASE_H_
+
+#include <memory>
+#include <string>
+#include <map>
+
+#include "idlc/gen_cion/c_cion_gen_base.h"
+
+namespace tidl {
+
+class CCionHeaderGeneratorBase : public CCionGeneratorBase {
+ public:
+ explicit CCionHeaderGeneratorBase(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CCionHeaderGeneratorBase() = default;
+
+ void GenPragmaOnce(std::ofstream& stream);
+ void GenExplicitLinkageOpen(std::ofstream& stream);
+ void GenExplicitLinkageClose(std::ofstream& stream);
+ void GenStructureHandles(std::ofstream& stream);
+ void GenStructures(std::ofstream& stream);
+ void GenCommonHandles(std::ofstream& stream);
+ void GenCommonBase(std::ofstream& stream);
+ void GenFileHandle(std::ofstream& stream);
+ void GenFileBase(std::ofstream& stream);
+ void GenConnectionHandle(std::ofstream& stream);
+ void GenConnectionBase(std::ofstream& stream);
+
+ private:
+ void GenStructureHandle(std::ofstream& stream, const Structure& st);
+ void GenStructureArrayBase(std::ofstream& stream, const Structure& st);
+ void GenStructureListBase(std::ofstream& stream, const Structure& st);
+ void GenStructureBase(std::ofstream& stream, const Structure& st);
+ void GenStructure(std::ofstream& stream, const Structure& st);
+};
+
+} // namespace tidl
+
+#endif // IDLC_C_CION_GEN_C_HEADER_GEN_BASE_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/c_cion_header_gen_base_cb.h b/idlc/gen_cion/c_cion_header_gen_base_cb.h
new file mode 100644
index 0000000..1c1cd82
--- /dev/null
+++ b/idlc/gen_cion/c_cion_header_gen_base_cb.h
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_HEADER_GEN_BASE_CB_H_
+#define IDLC_C_CION_GEN_C_HEADER_GEN_BASE_CB_H_
+
+constexpr const char CB_EXPLICIT_LINKAGE_OPEN[] =
+R"__c_cb(
+#ifdef __cplusplus
+extern "C" {
+#endif
+)__c_cb";
+
+constexpr const char CB_EXPLICIT_LINKAGE_CLOSE[] =
+R"__c_cb(
+#ifdef __cplusplus
+}
+#endif
+)__c_cb";
+
+
+/**
+ * <PREFIX> The prefix of the handle.
+ * <NAME> The name of the handle.
+ */
+constexpr const char CB_STRUCTURE_HANDLE[] =
+R"__c_cb(
+/**
+ * @brief The <PREFIX>_<NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_s *<PREFIX>_<NAME>_h;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the array structure.
+ * <NAME> The name of the array structure.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE[] =
+R"__c_cb(
+/**
+ * @briefs Creates a <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a h should be released using the <PREFIX>_<NAME>_destroy()
+ * if it's no longer needed.
+ * @param[out] h The <PREFIX>_<NAME> handle that is newly created
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME> should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone);
+
+/**
+ * @brief Sets the value to the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The value is internally copied and stored.
+ * You should release it if it's allocaed when it's no longer needed,
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] value The array value
+ * @param[in] size The size of the array
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_get()
+ */
+int <PREFIX>_<NAME>_set(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>*value, int size);
+
+/**
+ * @brief Gets the value from the <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created value should be released if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] value The array value
+ * @param[out] size The size of the array
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_set()
+ */
+int <PREFIX>_<NAME>_get(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>*value, int *size);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the list structure.
+ * <NAME> The name of the list structure.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE[] =
+R"__c_cb(
+/**
+ * @brief Called to retrieve the value contained in the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a value MUST NOT be released by the application.
+ * @param[in] value The value of the list
+ * @param[in] user_data The user data passed from the foreach function
+ * @return @c true to continue with the next iteration of the loop,
+ * otherwise @c false to break out of the loop
+ * @see <PREFIX>_<NAME>_foreach()
+ */
+typedef bool (*<PREFIX>_<NAME>_cb)(<PARAM_TYPE_IN>value, void *user_data);
+
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a h handle should be released using the <PREFIX>_<NAME>_destroy()
+ * if it's no longer needed.
+ * @param[out] h The <PREFIX>_<NAME> handle that is newly created
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME> should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone);
+
+/**
+ * @brief Adds the value to the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The value is internally copied and stored.
+ * You should release it if it's allocaed when it's no longer needed,
+ * @param[in] h The <PREFIX>_<NAME> handle.
+ * @param[in] value The value
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_remove()
+ */
+int <PREFIX>_<NAME>_add(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value);
+
+/**
+ * @brief Retrieves all values contained in the <PREFIX>_<NAME> handle.
+ * @details This function called <PREFIX>_<NAME>_cb once for each value contained in the <PREFIX>_<NAME> handle.
+ * If the <PREFIX>_<NAME>_cb callback function returns @c false, the iteration will be finished.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] callback The iteration callback function
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_cb()
+ */
+int <PREFIX>_<NAME>_foreach(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_cb callback, void *user_data);
+
+/**
+ * @brief Removes the element at the given position in the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] nth The position of the element
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_remove(<PREFIX>_<NAME>_h h, unsigned int nth);
+
+/**
+ * @brief Gets the number of elements in the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] length The number of elements
+ * @return @c on 0 success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_length(<PREFIX>_<NAME>_h h, unsigned int *length);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure. e.g. rpc_port_proxy_ or rpc_port_stub_
+ * <NAME> The name of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE[] =
+R"__c_cb(
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a h handle should be released using the <PREFIX>_<NAME>_destroy()
+ * if it's no longer needed.
+ * @param[out] h The <PREFIX>_<NAME> handle that is newly created
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMTER Invaid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME> should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure. e.g. rpc_port_proxy_ or rpc_port_stub_
+ * <NAME> The name of the structure.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_SET_GET[] =
+R"__c_cb(
+/**
+ * @brief Sets the <ELEMENT_NAME> to the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The <ELEMENT_NAME> is internally copied and stored.
+ * You should release it if it's allocated when it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] value The <ELEMENT_NAME>
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_get_<ELEMENT_NAME>()
+ */
+int <PREFIX>_<NAME>_set_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value);
+
+/**
+ * @brief Gets the <ELEMENT_NAME> from the <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created value should be released if it's allocated when it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] value The <ELEMENT_NAME>
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_set_<ELEMENT_NAME>
+ */
+int <PREFIX>_<NAME>_get_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>value);
+)__c_cb";
+
+#endif // IDLC_C_CION_GEN_C_HEADER_GEN_BASE_CB_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/c_cion_proxy_body_gen.cc b/idlc/gen_cion/c_cion_proxy_body_gen.cc
new file mode 100644
index 0000000..4153fa4
--- /dev/null
+++ b/idlc/gen_cion/c_cion_proxy_body_gen.cc
@@ -0,0 +1,658 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+
+#include "idlc/gen_cion/c_cion_proxy_body_gen.h"
+#include "idlc/gen_cion/c_cion_proxy_body_gen_cb.h"
+
+namespace tidl {
+
+CCionProxyBodyGen::CCionProxyBodyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options, std::shared_ptr<tidl::Transportable> trans)
+ : CCionBodyGeneratorBase(doc, trans), options_(std::move(options)) {
+}
+
+void CCionProxyBodyGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenGNUSourceDefinition(stream);
+ GenIncludeDefaultHeaders(stream);
+ GenIncludeHeader(stream);
+ GenLogTag(stream, GetTransportable().C().GenProxyPrefix());
+ GenLogDefinition(stream);
+ GenBaseDefinition(stream);
+ GenInterfaceDelegateCallback(stream);
+ GenStructureDefs(stream);
+ GenInterfaceDefs(stream);
+ GenFilePayloadSend(stream, true);
+ GenStructures(stream);
+ GenCommonFuntions(stream);
+ GenInterfaces(stream);
+}
+
+void CCionProxyBodyGen::OnFiniGen(std::ofstream& stream) {
+}
+
+
+// @see #CB_INTERFACE_DELEGATE_CALLBACK
+void CCionProxyBodyGen::GenInterfaceDelegateCallback(std::ofstream& stream) {
+ stream << SmartIndent(CB_INTERFACE_DELEGATE_CALLBACK);
+}
+
+void CCionProxyBodyGen::GenInterfaceDefs(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterfaceDef(stream, iface);
+ }
+}
+
+void CCionProxyBodyGen::GenInterfaceDef(std::ofstream& stream,
+ const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateDef(stream, iface, *d);
+ }
+
+ GenInterfaceBaseDef(stream, iface);
+}
+
+// @see #CB_INTERFACE_DELEGATE_DEF
+void CCionProxyBodyGen::GenInterfaceDelegateDef(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_DELEGATE_DEF, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", decl.GetID() }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_BASE_DEF
+void CCionProxyBodyGen::GenInterfaceBaseDef(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_BASE_DEF, {
+ { "<NAME>", iface.GetID() },
+ { "<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType() },
+ { "<CLIENT_T>", GetTransportable().C().GenClientType() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<SECURITY_T>", GetTransportable().C().GenSecurityType() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() },
+ { "<PREFIX>", GetHandlePrefix() }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+void CCionProxyBodyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CCionProxyBodyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ GenInterfaceDelegateEnumBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateBase(stream, iface, *d);
+ }
+
+ GenInterfaceDelegateTable(stream, iface);
+ GenInterfaceMethodEnumBase(stream, iface);
+ GenInterfaceBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceMethodBase(stream, iface, *d);
+ }
+}
+
+// @see #CB_INTERFACE_BASE
+void CCionProxyBodyGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+
+ ReplaceAll(CB_INTERFACE_BASE)
+ .Change("<CLIENT_TRY_CONNECT>",
+ GetTransportable().C().GenClientTryConnect("h->client", "peer_info"))
+ .Change("<CLIENT_DISCONNECT>",
+ GetTransportable().C().GenClientDisconnect("h->client"))
+ .Change("<CLIENT_TRY_DISCOVERY>",
+ GetTransportable().C().GenClientTryDiscovery("h->client"))
+ .Change("<CLIENT_STOP_DISCOVERY>",
+ GetTransportable().C().GenClientStopDiscovery("h->client"))
+ .Change("<CLIENT_CREATE>", GetTransportable().C().GenClientCreate())
+ .Change("<EXTRA>", GetTransportable().C().GenClientExtra())
+ .Change("<NAME>", name)
+ .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
+ .ChangeToUpper("<UPPERCASE_NAME>", name)
+ .Change("<SET_SECURITY>", GenSecurityString(iface))
+ .Change("<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType())
+ .Change("<PAYLOAD_T>", GetTransportable().C().GenPayloadType())
+ .Change("<PAYLOAD_TRANSFER_STATUS_T>",
+ GetTransportable().C().GenPayloadTransferStatusType(true))
+ .Change("<SECURITY_T>", GetTransportable().C().GenSecurityType())
+ .Change("<PAYLOAD_TYPE_E>", GetTransportable().C().GenPayloadTypeEnum())
+ .Change("<PAYLOAD_GET_TYPE>", GetTransportable().C().GenPayloadGetType())
+ .Change("<ERROR_NONE>", GetTransportable().C().GenErrorNone())
+ .Change("<PAYLOAD_TYPE_DATA>", GetTransportable().C().GenPayloadTypeData())
+ .Change("<PAYLOAD_TYPE_FILE>", GetTransportable().C().GenPayloadTypeFile())
+ .Change("<PAYLOAD_GET_DATA>", GetTransportable().C().GenPayloadGetData())
+ .Change("<CLIENT_DESTROY>", GetTransportable().C().GenClientDestroy())
+ .Change("<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix())
+ .Change("<INTERNAL_PREFIX>", GetInternalHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Change("<PREFIX>", prefix)
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_DELEGATE_ENUM_BASE
+void CCionProxyBodyGen::GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& iface) {
+ unsigned int num = 1;
+ std::string enums;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ enums += GetHandlePrefix() + "_" + iface.GetID() + "_DELEGATE_" + d->GetID();
+ enums += " = " + std::to_string(num++) + ",";
+ enums += NLine(1);
+ }
+
+ if (enums.empty())
+ return;
+
+ std::transform(enums.begin(), enums.end(), enums.begin(), ::toupper);
+ ReplaceAll(CB_INTERFACE_DELEGATE_ENUM_BASE, {
+ { "<ENUMS>", enums },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+std::string CCionProxyBodyGen::GenDelegateArgsDecl(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ code += GetArgTypeString(type, iface) + p->GetID() + " = " +
+ GetErrorValue(param_type.GetBaseType()) + ";" + NLine(1);
+ }
+
+ return code;
+}
+
+// @see #CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_READ
+// @see #CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_READ
+// @see #CB_INTERFACE_DELEGATE_STRING_PARCEL_READ
+// @see #CB_INTERFACE_DELEGATE_BASE_PARCEL_READ
+std::string CCionProxyBodyGen::GenDelegateParcelRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ std::string param_read_code;
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ param_read_code = ReplaceAll(
+ CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+
+ std::string name = GetFullNameFromType(type, iface);
+ param_read_code = ReplaceAll(param_read_code, "<NAME>", name);
+ param_read_code = ReplaceAll(param_read_code, "<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ param_read_code = ReplaceAll(CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ param_read_code = ReplaceAll(CB_INTERFACE_DELEGATE_STRING_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else {
+ param_read_code = ReplaceAll(CB_INTERFACE_DELEGATE_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ param_read_code = ReplaceAll(param_read_code, "<ARG>", p->GetID());
+ }
+
+ code += param_read_code;
+ }
+
+ return RemoveLine(code);
+}
+
+// @see CB_INTERFACE_DELEGATE_USER_DEFINED_ARG_FREE
+// @see CB_INTERFACE_DELEGATE_BUNDLE_ARG_FREE
+// @see CB_INTERFACE_DELEGATE_STRING_ARG_FREE
+std::string CCionProxyBodyGen::GenDelegateArgsFree(const Interface& iface,
+ const Declaration& decl, bool& has_free) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ std::string param_free_code;
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ param_free_code = ReplaceAll(
+ CB_INTERFACE_DELEGATE_USER_DEFINED_ARG_FREE, "<PREFIX>",
+ GetHandlePrefix());
+
+ std::string name = GetFullNameFromType(type, iface);
+ param_free_code = ReplaceAll(param_free_code, "<NAME>", name);
+ param_free_code = ReplaceAll(param_free_code, "<ARG>", p->GetID());
+ has_free = true;
+ } else if (type.ToString() == "bundle") {
+ param_free_code = ReplaceAll(CB_INTERFACE_DELEGATE_BUNDLE_ARG_FREE,
+ "<ARG>", p->GetID());
+ has_free = true;
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ param_free_code = ReplaceAll(CB_INTERFACE_DELEGATE_STRING_ARG_FREE,
+ "<ARG>", p->GetID());
+ has_free = true;
+ }
+
+ code += param_free_code;
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CCionProxyBodyGen::GenDelegateCallbackArgs(const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters())
+ code += ", " + p->GetID();
+
+ return code;
+}
+
+// @see CB_INTERFACE_DELEGATE_BASE
+void CCionProxyBodyGen::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_DELEGATE_" + decl.GetID();
+ std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
+ ::toupper);
+ bool has_free = false;
+ std::string delegate_args_free = GenDelegateArgsFree(iface, decl, has_free);
+
+ ReplaceAll(CB_INTERFACE_DELEGATE_BASE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Change("<DELEGATE_NAME>", decl.GetID())
+ .Change("<DELEGATE_ENUM_VALUE>", enum_value)
+ .Change("<DELEGATE_ARGS_DECL>", GenDelegateArgsDecl(iface, decl))
+ .Change("<DELEGATE_PARCEL_READ>", GenDelegateParcelRead(iface, decl))
+ .Change("<DELEGATE_ARGS_FREE>", delegate_args_free)
+ .Change("<DELEGATE_CALLBACK_ARGS>", GenDelegateCallbackArgs(decl))
+ .Change("<GOTO_STATEMENT>", has_free ? "out:" + NLine(1) : "")
+ .Change("<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix())
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_DELEGATE_TABLE
+// @see #CB_INTERFACE_DELEGATE_TABLE_MEMBER
+void CCionProxyBodyGen::GenInterfaceDelegateTable(std::ofstream& stream,
+ const Interface& iface) {
+ std::string delegate_handlers;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_DELEGATE_" + d->GetID();
+ std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
+ ::toupper);
+ std::string member(ReplaceAll(CB_INTERFACE_DELEGATE_TABLE_MEMBER, {
+ { "<ENUM_VALUE>", enum_value },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", d->GetID() }
+ }));
+
+ member = RemoveLine(member);
+ delegate_handlers += member;
+ }
+
+ if (delegate_handlers.empty())
+ delegate_handlers = "nullptr," + NLine(1);
+
+ ReplaceAll(CB_INTERFACE_DELEGATE_TABLE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_HANDLERS>", delegate_handlers }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_ENUM_BASE
+void CCionProxyBodyGen::GenInterfaceMethodEnumBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string enums;
+ enums += GetHandlePrefix() + "_" + iface.GetID() + "_METHOD_RESULT_,";
+ enums += NLine(1);
+ enums += GetHandlePrefix() + "_" + iface.GetID() + "_METHOD_CALLBACK_,";
+ enums += NLine(1);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_METHOD_" + d->GetID() + ",";
+ enums += enum_value;
+ enums += NLine(1);
+ }
+
+ std::transform(enums.begin(), enums.end(), enums.begin(), ::toupper);
+ ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE, {
+ { "<ENUMS>", enums },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+std::string CCionProxyBodyGen::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+std::string CCionProxyBodyGen::GenMethodParamsCheck(const Interface& iface,
+ const Declaration& decl) {
+ std::string params_check;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array" ||
+ type.ToString() == "bundle" ||
+ type.ToString() == "string" ||
+ type.ToString() == "file")
+ params_check += " || " + p->GetID() + " == nullptr";
+ }
+
+ return params_check;
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_LIST_FILE_SET_PRIVATE_SHARING
+// @see #CB_INTERFACE_METHOD_ARRAY_FILE_SET_PRIVATE_SHARING
+// @see #CB_INTERFACE_METHOD_FILE_SET_PRIVATE_SHARING
+std::string CCionProxyBodyGen::GenMethodParcelWrite(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+
+ std::string parcel_write_code;
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE, "<ARG>",
+ p->GetID());
+ std::string name = GetFullNameFromType(type, iface);
+ parcel_write_code += GetFilePayloadString(type, iface, p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ parcel_write_code += GetFilePayloadString(type, iface, p->GetID());
+ } else {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ARG>",
+ p->GetID());
+ }
+
+ code += parcel_write_code;
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_DELEGATE_APPEND
+std::string CCionProxyBodyGen::GenMethodDelegateAppend(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type)) {
+ std::string delegate_append_code(ReplaceAll(
+ CB_INTERFACE_METHOD_DELEGATE_APPEND, "<ARG>", p->GetID()));
+ code += delegate_append_code;
+ }
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_ASYNC_BASE
+std::string CCionProxyBodyGen::GenMethodAsyncBase(const Interface& iface,
+ const Declaration& decl) {
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+ std::string method_name = decl.GetID();
+
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_ASYNC_BASE)
+ .Change("<NAME>", name)
+ .Change("<METHOD_NAME>", method_name)
+ .Change("<METHOD_PARAMS>", GenMethodParams(iface, decl))
+ .Change("<METHOD_PARAMS_CHECK>", GenMethodParamsCheck(iface, decl))
+ .Change("<FILE_LIST_DEF>", GetFilePayloadDefString(iface, decl))
+ .Change("<FILE_LIST_SEND>", GetFilePayloadSendString(iface, decl, true))
+ .Change("<FILE_LIST_FREE>", GetFilePayloadFreeString(iface, decl))
+ .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
+ .ChangeToUpper("<UPPERCASE_NAME>", name)
+ .ChangeToUpper("<UPPERCASE_METHOD_NAME>", method_name)
+ .Change("<METHOD_PARCEL_WRITE>", GenMethodParcelWrite(iface, decl))
+ .Change("<METHOD_DELEGATE_APPEND>", GenMethodDelegateAppend(iface,
+ decl))
+ .Change("<PAYLOAD_T>", GetTransportable().C().GenPayloadType())
+ .Change("<CLIENT_SEND_ASYNC>",
+ GetTransportable().C().GenClientSendAsync(
+ "h->client", "pl_", "data_size_"))
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Change("<INTERNAL_PREFIX>", GetInternalHandlePrefix())
+ .Change("<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix())
+ .Change("<PREFIX>", prefix));
+
+ return code;
+}
+
+std::string CCionProxyBodyGen::GenMethodArgs(const Interface& iface,
+ const Declaration& decl) {
+ std::string args_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ args_code += GetReturnTypeString(type) + "new_" + p->GetID() + ";";
+ args_code += NLine(1);
+ }
+
+ return args_code;
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_READ
+std::string CCionProxyBodyGen::GenMethodParcelReadBase(const Interface& iface,
+ const BaseType& type, const std::string& param_name) {
+ std::string parcel_read_code;
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_read_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ std::string name = GetFullNameFromType(type, iface);
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>", name);
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", param_name);
+ } else if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ,
+ "<ARG>", param_name);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_READ,
+ "<ARG>", param_name);
+ } else {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>",
+ param_name);
+ }
+
+ return parcel_read_code;
+}
+
+// @see #CB_INTERFACE_METHOD_VALUE_SET
+std::string CCionProxyBodyGen::GenMethodParcelRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ std::string parcel_read_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ code += GenMethodParcelReadBase(iface, type, "new_" + p->GetID());
+ code += ReplaceAll(CB_INTERFACE_METHOD_PARAM_SET, "<PARAM>",
+ p->GetID());
+ }
+
+ // Return Value
+ auto& base_type = decl.GetType();
+ code += GenMethodParcelReadBase(iface, base_type, "ret_");
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_BASE
+std::string CCionProxyBodyGen::GenMethodBase(const Interface& iface,
+ const Declaration& decl) {
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+ std::string method_name = decl.GetID();
+
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_BASE)
+ .Change("<RETURN_TYPE>", GetReturnTypeString(decl.GetType()))
+ .Change("<NAME>", name)
+ .Change("<METHOD_NAME>", method_name)
+ .Change("<METHOD_PARAMS>", GenMethodParams(iface, decl))
+ .Change("<METHOD_ARGS>", GenMethodArgs(iface, decl))
+ .Change("<ERROR_VALUE>", GetErrorValue(decl.GetType()))
+ .Change("<METHOD_PARAMS_CHECK>", GenMethodParamsCheck(iface, decl))
+ .Change("<FILE_LIST_DEF>", GetFilePayloadDefString(iface, decl))
+ .Change("<FILE_LIST_SEND>", GetFilePayloadSendString(iface, decl, true))
+ .Change("<FILE_LIST_FREE>", GetFilePayloadFreeString(iface, decl))
+ .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
+ .ChangeToUpper("<UPPERCASE_NAME>", name)
+ .ChangeToUpper("<UPPERCASE_METHOD_NAME>", method_name)
+ .Change("<METHOD_PARCEL_WRITE>", GenMethodParcelWrite(iface, decl))
+ .Change("<METHOD_PARCEL_READ>", GenMethodParcelRead(iface, decl))
+ .Change("<METHOD_DELEGATE_APPEND>", GenMethodDelegateAppend(iface,
+ decl))
+ .Change("<CLIENT_SEND>", GetTransportable().C().GenClientSend(
+ "h->client", "data_", "data_size_",
+ "return_data_", "return_data_size_"))
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Change("<INTERNAL_PREFIX>", GetInternalHandlePrefix())
+ .Change("<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix())
+ .Change("<PREFIX>", prefix));
+ return code;
+}
+
+void CCionProxyBodyGen::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code;
+ auto method_type = decl.GetMethodType();
+ if (method_type == Declaration::MethodType::ASYNC)
+ code = GenMethodAsyncBase(iface, decl);
+ else
+ code = GenMethodBase(iface, decl);
+
+ stream << SmartIndent(code);
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/c_cion_proxy_body_gen.h b/idlc/gen_cion/c_cion_proxy_body_gen.h
new file mode 100644
index 0000000..c70a4cc
--- /dev/null
+++ b/idlc/gen_cion/c_cion_proxy_body_gen.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_PROXY_BODY_GEN_H_
+#define IDLC_C_CION_GEN_C_PROXY_BODY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/c_cion_body_gen_base.h"
+#include "idlc/options.h"
+
+namespace tidl {
+
+class CCionProxyBodyGen : public CCionBodyGeneratorBase {
+ public:
+ explicit CCionProxyBodyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CCionProxyBodyGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenInterfaceDefs(std::ofstream& stream);
+ void GenInterfaceDef(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateDef(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceBaseDef(std::ofstream& stream, const Interface& iface);
+
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterfaceDelegateCallback(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& iface);
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceDelegateTable(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodEnumBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+
+ std::string GenDelegateArgsDecl(const Interface& iface,
+ const Declaration& decl);
+ std::string GenDelegateParcelRead(const Interface& iface,
+ const Declaration& decl);
+ std::string GenDelegateArgsFree(const Interface& iface,
+ const Declaration& decl, bool& has_free);
+ std::string GenDelegateCallbackArgs(const Declaration& decl);
+
+ std::string GenMethodAsyncBase(const Interface& iface, const Declaration& decl);
+ std::string GenMethodBase(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParamsCheck(const Interface& iface,
+ const Declaration& decl);
+ bool GenMethodParamsFileCheck(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodParcelWrite(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodDelegateAppend(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodArgs(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParcelReadBase(const Interface& iface,
+ const BaseType& type, const std::string& param_name);
+ std::string GenMethodParcelRead(const Interface& iface,
+ const Declaration& decl);
+
+ private:
+ std::shared_ptr<Options> options_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_C_CION_GEN_C_PROXY_BODY_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/c_cion_proxy_body_gen_cb.h b/idlc/gen_cion/c_cion_proxy_body_gen_cb.h
new file mode 100644
index 0000000..c3dd444
--- /dev/null
+++ b/idlc/gen_cion/c_cion_proxy_body_gen_cb.h
@@ -0,0 +1,981 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_PROXY_BODY_GEN_CB_H_
+#define IDLC_C_CION_GEN_C_PROXY_BODY_GEN_CB_H_
+
+constexpr const char CB_INTERFACE_DELEGATE_CALLBACK[] =
+R"__c_cb(
+typedef void (*_proxy_delegate_cb)(GList **delegates, rpc_port_parcel_h parcel, int id, int seq_id);
+)__c_cb";
+
+/**
+ * <ENUMS> The enumeration of the interface delegate.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_ENUM_BASE[] =
+R"__c_cb(
+typedef enum {
+ <ENUMS>
+} <PREFIX>_<NAME>_delegate_e;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ int id;
+ int seq_id;
+ bool once;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback;
+ void *user_data;
+} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ * <DELEGATE_ENUM_VALUE> The enumeration value of the delegate.
+ * <DELEGATE_ARGS_DECL> The implementation to declares the arguments.
+ * <DELEGATE_PARCEL_READ> The implementation to read the arguments from the parcel.
+ * <DELEGATE_ARGS_FREE> The implementation to release the allocated arguments.
+ * <DELEGATE_CALLBACK_ARGS> The arguments of the delegate callback.
+ * <GOTO_STATEMENT> The statement label.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = data;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ rpc_port_parcel_write_int32(parcel, h->id);
+
+ rpc_port_parcel_write_int32(parcel, h->seq_id);
+
+ rpc_port_parcel_write_bool(parcel, h->once);
+
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+}
+
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = data;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(<ERROR_PREFIX>_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ rpc_port_parcel_read_int32(parcel, &h->id);
+
+ rpc_port_parcel_read_int32(parcel, &h->seq_id);
+
+ rpc_port_parcel_read_bool(parcel, &h->once);
+
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+ set_last_result(<ERROR_PREFIX>_ERROR_NONE);
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_t *handle;
+ static int seq_num;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_<DELEGATE_NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_<DELEGATE_NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_<DELEGATE_NAME>_from;
+ handle->id = <DELEGATE_ENUM_VALUE>;
+ handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+ _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+
+ *h = handle;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ _W("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+
+ free(h);
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h handle;
+ rpc_port_parcel_h parcel;
+ int ret;
+
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_<DELEGATE_NAME>_create(&handle);
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ ret = rpc_port_parcel_create(&parcel);
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret);
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(handle);
+ return ret;
+ }
+
+ rpc_port_parcel_write(parcel, &h->parcelable, h);
+ rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+ ret = get_last_result();
+ rpc_port_parcel_destroy(parcel);
+
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret);
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(handle);
+ return ret;
+ }
+
+ handle->callback = h->callback;
+ handle->user_data = h->user_data;
+
+ *clone = handle;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_callback(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback, void *user_data)
+{
+ if (h == nullptr || callback == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ h->callback = callback;
+ h->user_data = user_data;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool once)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ h->once = once;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id)
+{
+ if (h == nullptr || id == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ *id = h->id;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id)
+{
+ if (h == nullptr || seq_id == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ *seq_id = h->seq_id;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once)
+{
+ if (h == nullptr || once == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ *once = h->once;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag)
+{
+ char *new_tag;
+ char buf[128];
+
+ if (h == nullptr || tag == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ snprintf(buf, sizeof(buf), "%d::%d", h->id, h->seq_id);
+ new_tag = strdup(buf);
+ if (new_tag == nullptr) {
+ _E("Out of memory");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ }
+
+ *tag = new_tag;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose(<PREFIX>_<NAME>_h proxy, <PREFIX>_<NAME>_<DELEGATE_NAME>_h h)
+{
+ GList *found;
+
+ if (proxy == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ found = g_list_find(proxy->delegates, h);
+ if (found == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ proxy->delegates = g_list_remove_link(proxy->delegates, found);
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(h);
+ g_list_free(found);
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_delegate_handler(GList **delegates, rpc_port_parcel_h parcel, int id, int seq_id)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h handle;
+ GList *iter;
+ bool once;
+ <DELEGATE_ARGS_DECL>
+
+ <DELEGATE_PARCEL_READ>
+
+ iter = *delegates;
+ while (iter) {
+ handle = iter->data;
+ iter = g_list_next(iter);
+ if (handle->id == id && handle->seq_id == seq_id) {
+ once = handle->once;
+ _W("Invoke id(%d), seq_id(%d)", id, seq_id);
+ if (handle->callback)
+ handle->callback(handle->user_data<DELEGATE_CALLBACK_ARGS>);
+ else
+ _W("The callback function is nullptr");
+
+ if (once) {
+ *delegates = g_list_remove(*delegates, handle);
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(handle);
+ }
+
+ break;
+ }
+ }
+
+<GOTO_STATEMENT>
+ <DELEGATE_ARGS_FREE>
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+<PREFIX>_<NAME>_create(&<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to create handle");
+ goto out;
+}
+
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+if (get_last_result() != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to read data");
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_bundle(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_STRING_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_string(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &<ARG>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_USER_DEFINED_ARG_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ <PREFIX>_<NAME>_destroy(<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BUNDLE_ARG_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ bundle_free(<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The name of the value;
+ */
+constexpr const char CB_INTERFACE_DELEGATE_STRING_ARG_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ free(<ARG>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_HANDLERS> The array of the delegate callbacks.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_TABLE[] =
+R"__c_cb(
+static _proxy_delegate_cb __<PREFIX>_<NAME>_delegate_table[] = {
+ <DELEGATE_HANDLERS>
+};
+)__c_cb";
+
+/**
+ * <ENUM_VALUE> The enumeration value.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_TABLE_MEMBER[] =
+R"__c_cb(
+[<ENUM_VALUE>] = __<PREFIX>_<NAME>_<DELEGATE_NAME>_delegate_handler,
+)__c_cb";
+
+/**
+ * <ENUMS> The enumerations of the interface method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM_BASE[] =
+R"__c_cb(
+typedef enum {
+ <ENUMS>
+} <PREFIX>_<NAME>_method_e;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ char *service_name;
+ <CLIENT_T> client;
+ <SECURITY_T>
+ <PREFIX>_<NAME>_callback_s callback;
+ void *user_data;
+ GList *delegates;
+ GRecMutex mutex;
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_process_received_event(GList **delegates, rpc_port_parcel_h parcel)
+{
+ int id = 0;
+ int seq_id = 0;
+ bool once = false;
+ static const int table_size = ARRAY_SIZE(__<PREFIX>_<NAME>_delegate_table);
+
+ rpc_port_parcel_read_int32(parcel, &id);
+ rpc_port_parcel_read_int32(parcel, &seq_id);
+ rpc_port_parcel_read_bool(parcel, &once);
+ _W("id(%d), seq_id(%d)", id, seq_id);
+
+ if (id > 0 && id < table_size) {
+ if (__<PREFIX>_<NAME>_delegate_table[id])
+ __<PREFIX>_<NAME>_delegate_table[id](delegates, parcel, id, seq_id);
+ } else {
+ _W("Unknown ID(%d)", id);
+ }
+}
+
+
+static void __<PREFIX>_<NAME>_consume_command(unsigned char *data, unsigned int size, rpc_port_parcel_h *p)
+{
+ rpc_port_parcel_h parcel;
+ int cmd = -1;
+ int ret;
+
+ do {
+ ret = rpc_port_parcel_create_from_raw(&parcel, data, size);
+ if (ret != RPC_PORT_ERROR_NONE)
+ break;
+
+ rpc_port_parcel_read_int32(parcel, &cmd);
+ if (cmd == <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_RESULT_) {
+ *p = parcel;
+ return;
+ }
+
+ rpc_port_parcel_destroy(parcel);
+ } while (0);
+
+ *p = nullptr;
+}
+
+static void __<PREFIX>_<NAME>_connection_result(const char *service_name, const <PEER_INFO_T> peer_info,
+ const <MODULE_PREFIX>_connection_result_h result, void *user_data)
+{
+ <PREFIX>_<NAME>_h h = user_data;
+
+ _I("service_name(%s)", service_name);
+ h->callback.connection_result(h, result, h->user_data);
+}
+
+static void __<PREFIX>_<NAME>_disconnected(const char *service_name,
+ const <PEER_INFO_T> peer_info, void *user_data)
+{
+ <PREFIX>_<NAME>_h h = user_data;
+
+ _W("service_name(%s)", service_name);
+ h->callback.disconnected(h, h->user_data);
+
+}
+
+static void __<PREFIX>_<NAME>_discovered(const char *service_name,
+ const <PEER_INFO_T> peer_info, void *user_data)
+{
+ <PREFIX>_<NAME>_h h = user_data;
+
+ _W("service_name(%s)", service_name);
+ h->callback.discovered(peer_info, h->user_data);
+}
+
+static void __<PREFIX>_<NAME>_received(const char *service_name,
+ const <PEER_INFO_T> peer_info, const <PAYLOAD_T> payload,
+ <PAYLOAD_TRANSFER_STATUS_T> status,
+ void *user_data)
+{
+ <PREFIX>_<NAME>_h h = user_data;
+ rpc_port_parcel_h parcel;
+ unsigned char *data;
+ <PAYLOAD_TYPE_E> type;
+ int cmd = -1;
+ int ret;
+ unsigned int data_len;
+
+ _W("service_name(%s)", service_name);
+
+ <PAYLOAD_GET_TYPE>
+ if (ret != <ERROR_NONE>) {
+ _E("Faled to <MODULE_PREFIX>_payload_get_type : %d", ret);
+ return;
+ }
+
+ if (type == <PAYLOAD_TYPE_DATA>) {
+ <PAYLOAD_GET_DATA>
+ if (ret != <ERROR_NONE>) {
+ _E("Faled to <MODULE_PREFIX>_payload_get_data : %d", ret);
+ return;
+ }
+
+ ret = rpc_port_parcel_create_from_raw(&parcel, data, data_len);
+ free(data);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle from data. error(%d)", ret);
+ return;
+ }
+
+
+ rpc_port_parcel_read_int32(parcel, &cmd);
+ if (cmd != <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_CALLBACK_) {
+ _E("Invalid protocol");
+ rpc_port_parcel_destroy(parcel);
+ return;
+ }
+
+ __<PREFIX>_<NAME>_process_received_event(&h->delegates, parcel);
+ rpc_port_parcel_destroy(parcel);
+
+ } else if (type == <PAYLOAD_TYPE_FILE>) {
+ if (h->callback.file_received)
+ h->callback.file_received(peer_info, payload, status, h->user_data);
+ }
+
+}
+
+<EXTRA> {
+ <PREFIX>_<NAME>_t *handle;
+ int ret;
+ <SECURITY_T>
+
+ if (service_name == nullptr || callback == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ if (callback->connection_result == nullptr || callback->disconnected == nullptr || callback->discovered == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ }
+
+ g_rec_mutex_init(&handle->mutex);
+
+ handle->service_name = strdup(service_name);
+ if (handle->service_name == nullptr) {
+ _E("Failed to duplicate service name");
+ <PREFIX>_<NAME>_destroy(handle);
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ }
+ <CLIENT_CREATE>
+
+ *h = handle;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ g_rec_mutex_unlock(&h->mutex);
+ g_rec_mutex_clear(&h->mutex);
+
+ if (h->delegates)
+ g_list_free_full(h->delegates, free);
+ <CLIENT_DESTROY>
+ if (h->service_name)
+ free(h->service_name);
+
+ free(h);
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_try_connect(<PREFIX>_<NAME>_h h, const <PEER_INFO_T> peer_info)
+{
+ int ret;
+
+ if (h == nullptr || h->client == nullptr || peer_info == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ <CLIENT_TRY_CONNECT>
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+
+int <PREFIX>_<NAME>_disconnect(<PREFIX>_<NAME>_h h)
+{
+ int ret;
+
+ if (h == nullptr || h->client == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ <CLIENT_DISCONNECT>
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_try_discovery(<PREFIX>_<NAME>_h h)
+{
+ int ret;
+
+ if (h == nullptr || h->client == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ <CLIENT_TRY_DISCOVERY>
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_stop_discovery(<PREFIX>_<NAME>_h h)
+{
+ int ret;
+
+ if (h == nullptr || h->client == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ <CLIENT_STOP_DISCOVERY>
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_PARAMS> The parameters of the method of the interface
+ * <METHOD_PARAMS_CHECK> The parameters check of the method.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ * <METHOD_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ * <METHOD_DELEGATES_APPEND> The implementation to add the delegates to the list.
+ */
+constexpr const char CB_INTERFACE_METHOD_ASYNC_BASE[] =
+R"__c_cb(
+void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
+{
+ rpc_port_parcel_h parcel_ = nullptr;
+ int res_;
+ unsigned int data_size_;
+ unsigned char *data_;
+ <PAYLOAD_T> pl_ = nullptr;
+ <FILE_LIST_DEF>
+
+ if (h == nullptr<METHOD_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ set_last_result(<ERROR_PREFIX>_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ if (h->client == nullptr) {
+ _E("Not connected");
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(<ERROR_PREFIX>_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ res_ = rpc_port_parcel_create(&parcel_);
+ if (res_ != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", res_);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(res_);
+ return;
+ }
+
+ rpc_port_parcel_write_int32(parcel_, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
+
+ <METHOD_PARCEL_WRITE>
+ <METHOD_DELEGATE_APPEND>
+
+ res_ = rpc_port_parcel_get_raw(parcel_, (void **)&data_, &data_size_);
+ if (res_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get raw. error(%d)", res_);
+ goto out;
+ }
+
+ <CLIENT_SEND_ASYNC>
+ <FILE_LIST_SEND>
+
+out:
+ rpc_port_parcel_destroy(parcel_);
+
+ <FILE_LIST_FREE>
+ set_last_result(res_);
+ g_rec_mutex_unlock(&h->mutex);
+
+}
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the method of the interface.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_ARGS> The value declarations for reading the data from the parcel.
+ * <ERROR_VALUE> The error value of the method.
+ * <METHOD_PARAMS> The parameters of the method of the interface.
+ * <METHOD_PARAMS_CHECK> The parameters check of the method.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ * <METHOD_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ * <METHOD_PARCEL_READ> The implementation to read results from the parcel.
+ * <METHOD_DELEGATE_APPEND> The implementation to add the delegates to the list.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE[] =
+R"__c_cb(
+<RETURN_TYPE><PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
+{
+ rpc_port_parcel_h parcel_ = nullptr;
+ int res_;
+ unsigned int data_size_, return_data_size_;
+ unsigned char *data_;
+ unsigned char *return_data_ = nullptr;
+ <RETURN_TYPE>ret_ = <ERROR_VALUE>;
+ <FILE_LIST_DEF>
+ <METHOD_ARGS>
+
+ if (h == nullptr<METHOD_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ set_last_result(<ERROR_PREFIX>_ERROR_INVALID_PARAMETER);
+ return ret_;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ if (h->client == nullptr) {
+ _E("Not connected");
+ set_last_result(<ERROR_PREFIX>_ERROR_INVALID_PARAMETER);
+ g_rec_mutex_unlock(&h->mutex);
+ return ret_;
+ }
+
+ res_ = rpc_port_parcel_create(&parcel_);
+ if (res_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", res_);
+ set_last_result(res_);
+ g_rec_mutex_unlock(&h->mutex);
+ return ret_;
+ }
+
+ rpc_port_parcel_write_int32(parcel_, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
+
+ <METHOD_PARCEL_WRITE>
+ <METHOD_DELEGATE_APPEND>
+
+ res_ = rpc_port_parcel_get_raw(parcel_, (void **)&data_, &data_size_);
+ if (res_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get raw. error(%d)", res_);
+ goto out;
+ }
+
+ <CLIENT_SEND>
+
+ rpc_port_parcel_destroy(parcel_);
+ parcel_ = nullptr;
+ __<PREFIX>_<NAME>_consume_command(return_data_, return_data_size_, &parcel_);
+ if (parcel_ == nullptr) {
+ _E("Invalid protocol");
+ res_ = <ERROR_PREFIX>_ERROR_IO_ERROR;
+ goto out;
+ }
+
+ <METHOD_PARCEL_READ>
+
+ <FILE_LIST_SEND>
+
+out:
+ set_last_result(res_);
+ rpc_port_parcel_destroy(parcel_);
+ free(return_data_);
+ <FILE_LIST_FREE>
+ g_rec_mutex_unlock(&h->mutex);
+
+ return ret_;
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel_, &<ARG>->parcelable, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+<PREFIX>_<NAME>_create(&<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to create handle");
+ res_ = <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ goto out;
+}
+
+rpc_port_parcel_read(parcel_, &<ARG>->parcelable, <ARG>);
+if (get_last_result() != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to read data");
+ <PREFIX>_<NAME>_destroy(<ARG>);
+ <ARG> = nullptr;
+ res_ = get_last_result();
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+rpc_port_parcel_read_bundle(parcel_, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ res_ = <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ goto out;
+
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+rpc_port_parcel_read_string(parcel_, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ res_ = <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel_, &<ARG>);
+)__c_cb";
+
+/**
+ * <PARAM> The name of the parameter.
+ */
+constexpr const char CB_INTERFACE_METHOD_PARAM_SET[] =
+R"__c_cb(
+*<PARAM> = new_<PARAM>;
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_DELEGATE_APPEND[] =
+R"__c_cb(
+h->delegates = g_list_append(h->delegates, <ARG>);
+)__c_cb";
+
+#endif // IDLC_C_CION_GEN_C_PROXY_BODY_GEN_CB_H_
diff --git a/idlc/gen_cion/c_cion_proxy_header_gen.cc b/idlc/gen_cion/c_cion_proxy_header_gen.cc
new file mode 100644
index 0000000..d1f71e8
--- /dev/null
+++ b/idlc/gen_cion/c_cion_proxy_header_gen.cc
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/c_cion_proxy_header_gen.h"
+
+namespace {
+#include "idlc/gen_cion/c_cion_proxy_header_gen_cb.h"
+}
+
+namespace tidl {
+
+CCionProxyHeaderGen::CCionProxyHeaderGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : CCionHeaderGeneratorBase(doc, trans) {
+}
+
+void CCionProxyHeaderGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenPragmaOnce(stream);
+ GenIncludeDefaultHeaders(stream, false);
+ GenExplicitLinkageOpen(stream);
+ GenCommonHandles(stream);
+ GenConnectionHandle(stream);
+ GenFileHandle(stream);
+ GenStructureHandles(stream);
+ GenInterfaceHandles(stream);
+ GenCommonBase(stream);
+ GenConnectionBase(stream);
+ GenFileBase(stream);
+ GenStructures(stream);
+ GenInterfaces(stream);
+}
+
+void CCionProxyHeaderGen::OnFiniGen(std::ofstream& stream) {
+ GenExplicitLinkageClose(stream);
+}
+
+void CCionProxyHeaderGen::GenInterfaceHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceHandle(stream, iface);
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateHandle(stream, iface, *d);
+ }
+ }
+}
+
+// @see #CB_INTERFACE_HANDLE
+void CCionProxyHeaderGen::GenInterfaceHandle(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_HANDLE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_DELEGATE_HANDLE
+void CCionProxyHeaderGen::GenInterfaceDelegateHandle(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_DELEGATE_HANDLE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", decl.GetID() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+void CCionProxyHeaderGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CCionProxyHeaderGen::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ for (const auto& d: iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateBase(stream, iface, *d);
+ }
+
+ GenInterfaceBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceMethodBase(stream, iface, *d);
+ }
+}
+
+// @see #CB_INTERFACE_BASE
+void CCionProxyHeaderGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_BASE, {
+ { "<EXTRA>", GetTransportable().C().GenClientExtra(false) },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType() },
+ { "<PAYLOAD_T>", GetTransportable().C().GenPayloadType() },
+ { "<PAYLOAD_TRANSFER_STATUS_T>",
+ GetTransportable().C().GenPayloadTransferStatusType() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+std::string CCionProxyHeaderGen::GenDelegateParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+// @see #CB_INTERFACE_DELEGATE_BASE
+void CCionProxyHeaderGen::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_DELEGATE_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", decl.GetID() },
+ { "<DELEGATE_PARAMS>", GenDelegateParams(iface, decl) },
+ { "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+std::string CCionProxyHeaderGen::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+// @see #CB_INTERFACE_METHOD_BASE
+void CCionProxyHeaderGen::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_BASE, {
+ { "<RETURN_TYPE>", GetReturnTypeString(decl.GetType()) },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_PARAMS>", GenMethodParams(iface, decl) },
+ { "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix() }
+ }));
+ stream << SmartIndent(code);
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/c_cion_proxy_header_gen.h b/idlc/gen_cion/c_cion_proxy_header_gen.h
new file mode 100644
index 0000000..12d99b1
--- /dev/null
+++ b/idlc/gen_cion/c_cion_proxy_header_gen.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_PROXY_HEADER_GEN_H_
+#define IDLC_C_CION_GEN_C_PROXY_HEADER_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/c_cion_header_gen_base.h"
+
+namespace tidl {
+
+class CCionProxyHeaderGen : public CCionHeaderGeneratorBase {
+ public:
+ explicit CCionProxyHeaderGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CCionProxyHeaderGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenInterfaceHandles(std::ofstream& stream);
+ void GenInterfaceHandle(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateHandle(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& ifaceo,
+ const Declaration& decl);
+
+ std::string GenDelegateParams(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_C_CION_GEN_C_PROXY_HEADER_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/c_cion_proxy_header_gen_cb.h b/idlc/gen_cion/c_cion_proxy_header_gen_cb.h
new file mode 100644
index 0000000..0f1e11e
--- /dev/null
+++ b/idlc/gen_cion/c_cion_proxy_header_gen_cb.h
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_PROXY_HEADER_GEN_CB_H_
+#define IDLC_C_CION_GEN_C_PROXY_HEADER_GEN_CB_H_
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_HANDLE[] =
+R"__c_cb(
+/**
+ * @brief The <PREFIX>_<NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_s *<PREFIX>_<NAME>_h;
+)__c_cb";
+
+constexpr const char CB_INTERFACE_DELEGATE_HANDLE[] =
+R"__c_cb(
+/**
+ * @brief The <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s *<PREFIX>_<NAME>_<DELEGATE_NAME>_h;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate.
+ * <DELEGATE_PARAMS> The parameters of the callback function.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
+R"__c_cb(
+/**
+ * @brief Called when the event is received.
+ *
+ * @param[in] user_data The user data passed from the callback registration function
+ * @param[in] ...
+ *
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_create()
+ */
+typedef void (*<PREFIX>_<NAME>_<DELEGATE_NAME>_cb)(void *user_data<DELEGATE_PARAMS>);
+
+/**
+ * @brief Creates a <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[out] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memorya
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose()
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_set_callback()
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_set_once()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_create()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME>_<DELEGATE_NAME> should be released using
+ * the <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME>_<DELEGATE_NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone);
+
+/**
+ * @brief Sets the callback function to the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[in] callback The callback function
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_callback(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback, void *user_data);
+
+/**
+ * @brief Set the once flag to the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ * @details If the once flag is 'true', the delegate handle will be deleted after invocation.
+ * If the @a h handle is not used using the method, the handle should be released using
+ * the <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy() when it's no longer needed.
+ * If you don't want the delegate callback function to be called after it's used using the method,
+ * you should release the handle using the <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose().
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[in] once The flag if it's true, the delegate will be deleted after invocation
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool once);
+
+/**
+ * @brief Gets the ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] id The ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id);
+
+/**
+ * @brief Gets the sequence ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] seq_id The Sequence ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id);
+
+/**
+ * @brief Checks whether the delegate is for one-time or not.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] once The flag, it's true, the handle is for one-time
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once);
+
+/**
+ * @brief Gets the tag from the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks The @a tag should be released using free().
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] tag The tag
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag);
+
+/**
+ * @brief Disposes the <PREFIX>_<NAME>_<DELEGATE_NAME> handle from the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] proxy The <PREFIX>_<NAME> handle
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_create()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose(<PREFIX>_<NAME>_h proxy, <PREFIX>_<NAME>_<DELEGATE_NAME>_h h);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+/**
+ * @brief Called when the connection is accepted or rejected.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] result The handle for connection result \n
+ * The @a result can be used only in the callback. To use outside, make a copy.
+ * @param[in] user_data The user data passed from the registeration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_connection_result_cb)(<PREFIX>_<NAME>_h h,
+ const <MODULE_PREFIX>_connection_result_h result, void *user_data);
+
+/**
+ * @brief Called when the proxy is disconnected.
+ * @details The callback function is called when the proxy is disconnected from the stub.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] user_data The user data passed from the registeration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_disconnected_cb)(<PREFIX>_<NAME>_h h, void *user_data);
+
+/**
+ * @brief Called when the stub is discovered.
+ *
+ * @param[in] peer_info The <MODULE_PREFIX> peer information handle \n
+ * The @a peer_info can be used only in the callback. To use outside, make a copy.
+ * @param[in] user_data The user data passed from the registeration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ * @see #<MODULE_PREFIX>_peer_info_get_app_id()
+ * @see #<MODULE_PREFIX>_peer_info_get_display_name()
+ * @see #<MODULE_PREFIX>_peer_info_clone()
+ * @par Sample code:
+ * @code
+
+void <PREFIX>_<NAME>_stub_discovered_cb(const <PEER_INFO_T> peer_info, void *user_data)
+{
+ <PREFIX>_<NAME>_h handle = user_data;
+ char *app_id = NULL;
+
+ <MODULE_PREFIX>_peer_info_get_app_id(peer_info, &app_id);
+ LOGI("stub_discovered(%s)", app_id);
+
+ <PREFIX>_<NAME>_try_connect(handle, peer_info);
+
+ free(app_id);
+}
+ * @endcode
+ */
+typedef void (*<PREFIX>_<NAME>_stub_discovered_cb)(const <PEER_INFO_T> peer_info, void *user_data);
+
+
+/**
+ * @brief Called when the payload is received.
+ *
+ * @param[in] peer_info The <MODULE_PREFIX> peer information handle \n
+ * The @a peer_info can be used only in the callback. To use outside, make a copy.
+ * @param[in] payload The received payload \n
+ * The @a payload can be used only in the callback. \n
+ * The @a payload should not be released.
+ * @param[in] status The status of transfer
+ * @param[in] user_data The user data passed from the registeration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ * @see #<MODULE_PREFIX>_peer_info_clone()
+ *
+ * @par Sample code:
+ * @code
+
+void <PREFIX>_<NAME>__file_received_cb(const <PEER_INFO_T> peer_info, const <PAYLOAD_T> payload,
+ <PAYLOAD_TRANSFER_STATUS_T> status, void *user_data)
+{
+ <PREFIX>_<NAME>_h handle = user_data;
+
+ char *app_id = NULL;
+ char *file_name = NULL;
+ char *data_path = NULL;
+ uint64_t bytes, total;
+ char data_path_buff[512];
+
+ <MODULE_PREFIX>_peer_info_get_app_id(peer_info, &app_id);
+ <MODULE_PREFIX>_payload_get_total_bytes(payload, &total);
+ <MODULE_PREFIX>_payload_get_received_bytes(payload, &bytes);
+ <MODULE_PREFIX>_payload_get_received_file_name(payload, &file_name);
+
+ if (status == <ERROR_PREFIX>_PAYLOAD_TRANSFER_STATUS_SUCCESS) {
+ data_path = app_get_data_path();
+ if (data_path == NULL) {
+ LOGE("failed to get data path.");
+ goto end;
+ }
+
+ snprintf(data_path_buff, 512, "%s%s", data_path, file_name);
+ ret = <MODULE_PREFIX>_payload_save_as_file(payload, data_path_buff);
+ free(data_path);
+ LOGI("save file %s : %d", data_path_buff, ret);
+ } else {
+ LOGI("[file received from [%s:%s] : %lld / %lld",
+ app_id, file_name, bytes, total);
+ }
+
+end:
+ free(name);
+ free(app_id);
+
+}
+ * @endcode
+ */
+typedef void (*<PREFIX>_<NAME>_file_received_cb)(const <PEER_INFO_T> peer_info, const <PAYLOAD_T> payload,
+ <PAYLOAD_TRANSFER_STATUS_T> status, void *user_data);
+
+/**
+ * @brief The structure type containing the set of callback functions for handling proxy events.
+ * @details It is one of the input parameters of the <PREFIX>_<NAME>_create() function.
+ *
+ * @see <PREFIX>_<NAME>_connection_result_cb
+ * @see <PREFIX>_<NAME>_disconnected_cb
+ * @see <PREFIX>_<NAME>_stub_discovered_cb
+ * @see <PREFIX>_<NAME>_file_received_cb
+ */
+typedef struct {
+ <PREFIX>_<NAME>_connection_result_cb connection_result; /**< This callback function is called when the connection is accepted or rejected.*/
+ <PREFIX>_<NAME>_disconnected_cb disconnected; /**< This callback function is called when the proxy is disconnected from the stub. */
+ <PREFIX>_<NAME>_stub_discovered_cb discovered; /**< This callback function is called when the stub is discovered. */
+ <PREFIX>_<NAME>_file_received_cb file_received; /**< This callback function is called when when the payload is received. */
+} <PREFIX>_<NAME>_callback_s;
+
+<EXTRA>
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Tries to connect to the stub
+ * @privilege http://tizen.org/privilege/d2d.datasharing
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] peer_info The <MODULE_PREFIX> peer information handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #<ERROR_PREFIX>_ERROR_IO_ERROR IO error
+ */
+int <PREFIX>_<NAME>_try_connect(<PREFIX>_<NAME>_h h, const <PEER_INFO_T> peer_info);
+
+/**
+ * @brief Disconnects from a server.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_disconnect(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Tries to discover a stub.
+ * @remarks Tries to discover the stub with service name that the <PREFIX>_<NAME>_h handle has.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_ALREADY_IN_PROGRESS Already in progress
+ * @retval #<ERROR_PREFIX>_ERROR_IO_ERROR IO error
+ * @see <PREFIX>_<NAME>_stub_discovered_cb
+ */
+int <PREFIX>_<NAME>_try_discovery(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Stops to discovery stub.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_OPERATION Invalid operation
+ * @see <PREFIX>_<NAME>_stub_discovered_cb
+ */
+int <PREFIX>_<NAME>_stop_discovery(<PREFIX>_<NAME>_h h);
+
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The type of the return value.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The of the interface.
+ * <METHOD_NAME> The name of the method.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE[] =
+R"__c_cb(
+/**
+ * @brief Calls the <METHOD_NAME>() method.
+ * @details The return value and args are decided by the interface declaration.
+ * You can get the result using get_last_result().
+ * Before returning the function, the function sets the result using set_last_result().
+ * @remarks The specific error code can be obtained using the get_last_result() function. Error codes are described in Exception section.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] ...
+ * @exception #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @exception #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @exception #<ERROR_PREFIX>_ERROR_IO_ERROR I/O error
+ */
+<RETURN_TYPE><PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>);
+)__c_cb";
+
+#endif // IDLC_C_CION_GEN_C_PROXY_HEADER_GEN_CB_H_
diff --git a/idlc/gen_cion/c_cion_stub_body_gen.cc b/idlc/gen_cion/c_cion_stub_body_gen.cc
new file mode 100644
index 0000000..060b45f
--- /dev/null
+++ b/idlc/gen_cion/c_cion_stub_body_gen.cc
@@ -0,0 +1,712 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+
+#include "idlc/gen_cion/c_cion_stub_body_gen.h"
+#include "idlc/gen_cion/c_cion_stub_body_gen_cb.h"
+
+namespace tidl {
+
+CCionStubBodyGen::CCionStubBodyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options, std::shared_ptr<tidl::Transportable> trans)
+ : CCionBodyGeneratorBase(doc, trans), options_(options) {
+}
+
+void CCionStubBodyGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenGNUSourceDefinition(stream);
+ GenIncludeDefaultHeaders(stream);
+ GenIncludeHeader(stream);
+ GenLogTag(stream, GetTransportable().C().GenStubPrefix());
+ GenLogDefinition(stream);
+ GenBaseDefinition(stream);
+ GenThreadEnableDefinition(stream);
+ GenInterfaceMethodHandlerType(stream);
+ GenInterfaceEnums(stream);
+ GenStructureDefs(stream);
+ GenInterfaceDefs(stream);
+ GenFilePayloadSend(stream, false);
+ GenStructures(stream);
+ GenCommonFuntions(stream);
+ GenInterfaces(stream);
+}
+
+void CCionStubBodyGen::OnFiniGen(std::ofstream& stream) {
+}
+
+// @see #CB_THREAD_ENABLE_DEF
+void CCionStubBodyGen::GenThreadEnableDefinition(std::ofstream& stream) {
+ if (!options_->IsThreadEnabled())
+ return;
+
+ stream << std::string(CB_THREAD_ENABLE_DEF);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_TYPE
+void CCionStubBodyGen::GenInterfaceMethodHandlerType(std::ofstream& stream) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_HANDLER_TYPE,
+ "<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType()));
+ code = ReplaceAll(code, "<MODULE_PREFIX>", GetMoudlePrefix());
+
+ stream << SmartIndent(code);
+}
+
+void CCionStubBodyGen::GenInterfaceEnums(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceEnum(stream, iface);
+ }
+}
+
+void CCionStubBodyGen::GenInterfaceEnum(std::ofstream& stream,
+ const Interface& iface) {
+ GenInterfaceMethodEnumBase(stream, iface);
+ GenInterfaceDelegateEnumBase(stream, iface);
+}
+
+// @see #CB_INTERFACE_METHOD_ENUM
+std::string CCionStubBodyGen::GenMethodEnums(const Interface& iface) {
+ std::string method_enum(ReplaceAll(CB_INTERFACE_METHOD_ENUM,
+ "<UPPERCASE_PREFIX>", GetHandlePrefix()));
+ method_enum = ReplaceAll(method_enum, "<UPPERCASE_NAME>", iface.GetID());
+ method_enum = ReplaceAll(method_enum, "<UPPERCASE_METHOD_NAME>", "RESULT_");
+ std::string method_enums = RemoveLine(method_enum);
+
+ method_enum = ReplaceAll(CB_INTERFACE_METHOD_ENUM, "<UPPERCASE_PREFIX>",
+ GetHandlePrefix());
+ method_enum = ReplaceAll(method_enum, "<UPPERCASE_NAME>", iface.GetID());
+ method_enum = ReplaceAll(method_enum, "<UPPERCASE_METHOD_NAME>", "CALLBACK_");
+ method_enums += RemoveLine(method_enum);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ method_enum = ReplaceAll(CB_INTERFACE_METHOD_ENUM, "<UPPERCASE_PREFIX>",
+ GetHandlePrefix());
+ method_enum = ReplaceAll(method_enum, "<UPPERCASE_NAME>", iface.GetID());
+ method_enum = ReplaceAll(method_enum, "<UPPERCASE_METHOD_NAME>",
+ d->GetID());
+
+ method_enums += RemoveLine(method_enum);
+ }
+ std::transform(method_enums.begin(), method_enums.end(), method_enums.begin(),
+ ::toupper);
+
+ return method_enums;
+}
+
+// @see #CB_INTERFACE_METHOD_ENUM_BASE
+void CCionStubBodyGen::GenInterfaceMethodEnumBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE, "<PREFIX>",
+ GetHandlePrefix()));
+ code = ReplaceAll(code, "<NAME>", iface.GetID());
+ code = ReplaceAll(code, "<METHOD_ENUMS>", GenMethodEnums(iface));
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_DELEGATE_ENUM
+std::string CCionStubBodyGen::GenDelegateEnums(const Interface& iface) {
+ unsigned int num = 1;
+ std::string method_enums;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string method_enum(ReplaceAll(CB_INTERFACE_DELEGATE_ENUM, {
+ { "<UPPERCASE_PREFIX>", GetHandlePrefix() },
+ { "<UPPERCASE_NAME>", iface.GetID() },
+ { "<UPPERCASE_DELEGATE_NAME>", d->GetID() },
+ { "<NUMBER>", std::to_string(num++) }
+ }));
+ method_enums += RemoveLine(method_enum);
+ }
+ std::transform(method_enums.begin(), method_enums.end(), method_enums.begin(),
+ ::toupper);
+
+ return method_enums;
+}
+
+// @see #CB_INTERFACE_DELEGATE_ENUM_BASE
+void CCionStubBodyGen::GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string delegate_enums = GenDelegateEnums(iface);
+ if (delegate_enums.empty())
+ return;
+
+ std::string code(ReplaceAll(CB_INTERFACE_DELEGATE_ENUM_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_ENUMS>", delegate_enums }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+void CCionStubBodyGen::GenInterfaceDefs(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceDef(stream, iface);
+ }
+}
+
+void CCionStubBodyGen::GenInterfaceDef(std::ofstream& stream,
+ const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateDef(stream, iface, *d);
+ }
+
+ GenInterfaceBaseDef(stream, iface);
+}
+
+// @see #CB_INTERFACE_DELEGATE_DEF
+void CCionStubBodyGen::GenInterfaceDelegateDef(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_DELEGATE_DEF, {
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", decl.GetID() },
+ { "<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<PREFIX>", GetHandlePrefix() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_BASE_DEF
+void CCionStubBodyGen::GenInterfaceBaseDef(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_BASE_DEF, {
+ { "<NAME>", iface.GetID() },
+ { "<SERVER_T>", GetTransportable().C().GenServerType() },
+ { "<SECURITY_T>", GetTransportable().C().GenSecurityType() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() },
+ { "<PREFIX>", GetHandlePrefix() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+void CCionStubBodyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CCionStubBodyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateBase(stream, iface, *d);
+ }
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceMethodHandlerBase(stream, iface, *d);
+ }
+
+ GenInterfaceMethodTable(stream, iface);
+ GenInterfaceContextBase(stream, iface);
+ GenInterfaceBase(stream, iface);
+}
+
+// @see #CB_INTERFACE_CONTEXT_BASE
+void CCionStubBodyGen::GenInterfaceContextBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_CONTEXT_BASE, {
+ { "<NAME>", iface.GetID() },
+ { "<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType() },
+ { "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<PREFIX>", GetHandlePrefix() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+std::string CCionStubBodyGen::GenDelegateParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+std::string CCionStubBodyGen::GenDelegateParamsCheck(const Interface& iface,
+ const Declaration& decl) {
+ std::string params_check;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array" ||
+ type.ToString() == "bundle" ||
+ type.ToString() == "string" ||
+ type.ToString() == "file")
+ params_check += " || " + p->GetID() + " == nullptr";
+ }
+
+ return params_check;
+}
+
+// @see #CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_WRITE
+// @see #CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_WRITE
+// @see #CB_INTERFACE_DELEGATE_STRING_PARCEL_WRITE
+// @see #CB_INTERFACE_DELEGATE_BASE_PARCEL_WRITE
+std::string CCionStubBodyGen::GenDelegateParcelWrite(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ std::string parcel_write_code;
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_WRITE, "<ARG>",
+ p->GetID());
+ parcel_write_code += GetPrivateSharingString(type, iface, "h->port",
+ p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_DELEGATE_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_DELEGATE_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ parcel_write_code += GetPrivateSharingString(type, iface, "h->port",
+ p->GetID());
+ } else {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_DELEGATE_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ARG>", p->GetID());
+ }
+
+ code += parcel_write_code;
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_DELEGATE_BASE
+void CCionStubBodyGen::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string file_send = GetFilePayloadSendString(iface, decl, false);
+ std::string file_free = GetFilePayloadFreeString(iface, decl);
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_DELEGATE_" + decl.GetID();
+ std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
+ ::toupper);
+ std::string file_def = GetFilePayloadDefString(iface, decl, false);
+
+ std::string code(ReplaceAll(CB_INTERFACE_DELEGATE_BASE, {
+ { "<FILE_LIST_SEND>", file_send },
+ { "<FILE_LIST_FREE>", file_free },
+ { "<SERVER_SEND_ASYNC>", GetTransportable().C().GenServerSendAsync(
+ "__<NAME>.stub", "", "pl_", "data_size_") },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", decl.GetID() },
+ { "<DELEGATE_PARAMS>", GenDelegateParams(iface, decl) },
+ { "<FILE_LIST_DEF>", file_def },
+ { "<DELEGATE_PARAMS_CHECK>", GenDelegateParamsCheck(iface, decl) },
+ { "<DELEGATE_ENUM_VALUE>", enum_value },
+ { "<DELEGATE_PARCEL_WRITE>", GenDelegateParcelWrite(iface, decl) },
+ { "<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType() },
+ { "<PAYLOAD_T>", GetTransportable().C().GenPayloadType() },
+ { "<PEER_INFO_DESTROY>",
+ GetTransportable().C().GenPeerInfoDestroy("h->peer_info") },
+ { "<PEER_INFO_CLONE1>",
+ GetTransportable().C()
+ .GenPeerInfoClone("h->peer_info", "&handle->peer_info") },
+ { "<PEER_INFO_CLONE2>",
+ GetTransportable().C()
+ .GenPeerInfoClone("peer_info", "&h->peer_info") },
+ { "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() },
+ { "<PREFIX>", GetHandlePrefix() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+std::string CCionStubBodyGen::GenMethodHandlerArgsDecl(const Interface& iface,
+ const Declaration& decl) {
+ std::string args_decl;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ args_decl += GetArgTypeString(type, iface) + p->GetID() + " = " +
+ GetErrorValue(type) + ";" + NLine(1);
+ }
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
+ //args_decl += "rpc_port_parcel_h parcel_;" + NLine(1);
+ args_decl += GetArgTypeString(decl.GetType(), iface) + "res_ = " +
+ GetErrorValue(decl.GetType()) + ";" + NLine(1);
+ }
+
+ return args_decl;
+}
+
+// @see #CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_READ
+std::string CCionStubBodyGen::GenMethodHandlerParcelRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ std::string parcel_read_code;
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type)) {
+ parcel_read_code = ReplaceAll(
+ CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>",
+ GetFullNameFromType(type, iface));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
+ } else if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_read_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>",
+ GetFullNameFromType(type, iface));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
+ }
+
+ code += parcel_read_code;
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_INVOKE
+std::string CCionStubBodyGen::GenMethodHandlerCallbackInvoke(
+ const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_INVOKE,
+ "<METHOD_NAME>", decl.GetID()));
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC)
+ code = ReplaceAll(code, "<RES_SET>", "res_ = ");
+ else
+ code = ReplaceAll(code, "<RES_SET>", "");
+
+ std::string args;
+ for (const auto& p : decl.GetParameters()) {
+ args += ", ";
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ args += "&";
+
+ args += p->GetID();
+ }
+ code = ReplaceAll(code, "<METHOD_ARGS>", args);
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_PARCEL_WRITE_PRE
+// @see #CB_INTERFACE_METHOD_PARCEL_WRITE_POST
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_WRITE
+std::string CCionStubBodyGen::GenMethodHandlerParcelWrite(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ if (decl.GetMethodType() != Declaration::MethodType::SYNC)
+ return code;
+
+ std::string prefix = GetHandlePrefix();
+ std::transform(prefix.begin(), prefix.end(), prefix.begin(), ::toupper);
+ code = ReplaceAll(CB_INTERFACE_METHOD_PARCEL_WRITE_PRE, "<UPPERCASE_PREFIX>",
+ prefix);
+
+ std::string name = iface.GetID();
+ std::transform(name.begin(), name.end(), name.begin(), ::toupper);
+ code = ReplaceAll(code, "<UPPERCASE_NAME>",
+ name);
+
+ std::string parcel_write_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() == ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE, "<ARG>",
+ p->GetID());
+
+ parcel_write_code += GetFilePayloadString(type, iface, p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ parcel_write_code += GetFilePayloadString(type, iface, p->GetID());
+ } else {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ARG>", p->GetID());
+ }
+
+ code += parcel_write_code;
+ }
+
+ auto& type = decl.GetType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE, "<ARG>", "res_");
+ parcel_write_code += GetFilePayloadString(type, iface, "res_");
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE,
+ "<ARG>", "res_");
+ } else if (type.ToString() == "string") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", "res_");
+ } else if (type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", "res_");
+ parcel_write_code += GetFilePayloadString(type, iface, "res_");
+ } else {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ARG>", "res_");
+ }
+
+ code += parcel_write_code;
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_FREE
+// @see #CB_INTERFACE_METHOD_BUNDLE_FREE
+// @see #CB_INTERFACE_METHOD_STRING_FREE
+std::string CCionStubBodyGen::GenMethodHandlerArgsFree(const Interface& iface,
+ const Declaration& decl) {
+ std::string free_code;
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_FREE,
+ "<PREFIX>", GetHandlePrefix());
+ free_code = ReplaceAll(free_code, "<NAME>",
+ GetFullNameFromType(type, iface));
+ free_code = ReplaceAll(free_code, "<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE,
+ "<ARG>", p->GetID());
+ } else {
+ free_code.clear();
+ }
+
+ code += free_code;
+ }
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
+ auto& type = decl.GetType();
+ if (IsDelegateType(iface, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_FREE,
+ "<PREFIX>", GetHandlePrefix());
+ free_code = ReplaceAll(free_code, "<NAME>",
+ GetFullNameFromType(type, iface));
+ free_code = ReplaceAll(free_code, "<ARG>", "res_");
+ } else if (type.ToString() == "bundle") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE,
+ "<ARG>", "res_");
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE,
+ "<ARG>", "res_");
+ } else {
+ free_code.clear();
+ }
+
+ code += free_code;
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_BASE
+void CCionStubBodyGen::GenInterfaceMethodHandlerBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string file_send = GetFilePayloadSendString(iface, decl, false);
+ std::string file_def = GetFilePayloadDefString(iface, decl, false);
+ std::string file_free = GetFilePayloadFreeString(iface, decl);
+
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_HANDLER_BASE, {
+ { "<FILE_LIST_SEND>", file_send },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_HANDLER_ARGS_DECL>", GenMethodHandlerArgsDecl(iface, decl) },
+ { "<FILE_LIST_DEF>", file_def },
+ { "<METHOD_HANDLER_PARCEL_READ>", GenMethodHandlerParcelRead(iface, decl) },
+ { "<METHOD_HANDLER_CALLBACK_INVOKE>", GenMethodHandlerCallbackInvoke(decl) },
+ { "<METHOD_HANDLER_PARCEL_WRITE>", GenMethodHandlerParcelWrite(iface, decl) },
+ { "<FILE_LIST_FREE>", file_free },
+ { "<METHOD_HANDLER_ARGS_FREE>", GenMethodHandlerArgsFree(iface, decl) },
+ { "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix() },
+ { "<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() },
+ { "<PREFIX>", GetHandlePrefix() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER
+std::string CCionStubBodyGen::GenMethodHandlers(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_METHOD_" + d->GetID();
+ std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
+ ::toupper);
+ std::string method_handler(ReplaceAll(CB_INTERFACE_METHOD_HANDLER, {
+ { "<ENUM_VALUE>", enum_value },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", d->GetID() }
+ }));
+
+ code += RemoveLine(method_handler);
+ }
+
+ return code;
+}
+
+// @see #CB_INTERFACE_METHOD_TABLE
+void CCionStubBodyGen::GenInterfaceMethodTable(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_TABLE, {
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_HANDLERS>", GenMethodHandlers(iface) }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_BASE
+void CCionStubBodyGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_BASE, {
+ { "<SERVER_REGISTER>", GetTransportable().C().GenServerRegister() },
+ { "<SERVER_UNREGISTER>", GetTransportable().C().GenServerUnregister() },
+ { "<SERVER_ACCEPT>", GetTransportable().C().GenServerAccept() },
+ { "<SERVER_REJECT>", GetTransportable().C().GenServerReject() },
+ { "<SERVER_SET_DISPLAY_NAME>",
+ GetTransportable().C().GenServerSetDisplayName() },
+ { "<EXTRA>", GetTransportable().C().GenServerExtra() },
+ { "<NAME>", iface.GetID() },
+ { "<SET_SECURITY>", GenSecurityString(iface) },
+ { "<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType() },
+ { "<PAYLOAD_T>", GetTransportable().C().GenPayloadType() },
+ { "<PAYLOAD_TRANSFER_STATUS_T>",
+ GetTransportable().C().GenPayloadTransferStatusType(true) },
+ { "<SECURITY_T>", GetTransportable().C().GenSecurityType() },
+ { "<PAYLOAD_TYPE_E>", GetTransportable().C().GenPayloadTypeEnum() },
+ { "<PAYLOAD_GET_TYPE>", GetTransportable().C().GenPayloadGetType() },
+ { "<ERROR_NONE>", GetTransportable().C().GenErrorNone() },
+ { "<PAYLOAD_TYPE_DATA>", GetTransportable().C().GenPayloadTypeData() },
+ { "<PAYLOAD_TYPE_FILE>", GetTransportable().C().GenPayloadTypeFile() },
+ { "<PAYLOAD_GET_DATA>", GetTransportable().C().GenPayloadGetData() },
+ { "<SERVER_FOREACH_CONNECTED_PEER_INFO>", GetTransportable().C().GenServerForeachConnectedPeerInfo(iface.GetID()) },
+ { "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() },
+ { "<PREFIX>", GetHandlePrefix() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/c_cion_stub_body_gen.h b/idlc/gen_cion/c_cion_stub_body_gen.h
new file mode 100644
index 0000000..81c8452
--- /dev/null
+++ b/idlc/gen_cion/c_cion_stub_body_gen.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_STUB_BODY_GEN_H_
+#define IDLC_C_CION_GEN_C_STUB_BODY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/c_cion_body_gen_base.h"
+#include "idlc/options.h"
+
+namespace tidl {
+
+class CCionStubBodyGen : public CCionBodyGeneratorBase {
+ public:
+ explicit CCionStubBodyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CCionStubBodyGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenThreadEnableDefinition(std::ofstream& stream);
+ void GenInterfaceMethodHandlerType(std::ofstream& stream);
+ void GenInterfaceEnums(std::ofstream& stream);
+ void GenInterfaceEnum(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodEnumBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& iface);
+
+ void GenInterfaceDefs(std::ofstream& stream);
+ void GenInterfaceDef(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceContextDef(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateDef(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceBaseDef(std::ofstream& stream, const Interface& iface);
+
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceContextBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceMethodHandlerBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl);
+ void GenInterfaceMethodTable(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceCallbackPortCheck(std::ofstream& stream,
+ const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+
+ std::string GenMethodEnums(const Interface& iface);
+ std::string GenDelegateEnums(const Interface& iface);
+
+ std::string GenDelegateParams(const Interface& iface, const Declaration& decl);
+ std::string GenDelegateParamsCheck(const Interface& iface,
+ const Declaration& decl);
+ std::string GenDelegateParcelWrite(const Interface& iface,
+ const Declaration& decl);
+
+ std::string GenMethodHandlerArgsDecl(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlerParcelRead(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlerCallbackInvoke(const Declaration& decl);
+ std::string GenMethodHandlerParcelWrite(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlerArgsFree(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlers(const Interface& iface);
+ std::string GenAccessControlSet(const Interface& iface);
+
+ private:
+ std::shared_ptr<Options> options_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_C_CION_GEN_C_STUB_BODY_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/c_cion_stub_body_gen_cb.h b/idlc/gen_cion/c_cion_stub_body_gen_cb.h
new file mode 100644
index 0000000..b16e7cf
--- /dev/null
+++ b/idlc/gen_cion/c_cion_stub_body_gen_cb.h
@@ -0,0 +1,854 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_STUB_BODY_GEN_CB_H_
+#define IDLC_C_CION_GEN_C_STUB_BODY_GEN_CB_H_
+
+constexpr const char CB_THREAD_ENABLE_DEF[] =
+R"__c_cb(
+#define TIDL_THREAD_ENABLE 1
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER_TYPE[] =
+R"__c_cb(
+typedef int (*_stub_method_handler)(const <PEER_INFO_T> peer_info, rpc_port_parcel_h parcel, rpc_port_parcel_h return_parcel, void *data);
+)__c_cb";
+
+/**
+ * <METHOD_ENUMS> The enumeration declarations of methods.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM_BASE[] =
+R"__c_cb(
+typedef enum {
+ <METHOD_ENUMS>
+} <PREFIX>_<NAME>_method_e;
+)__c_cb";
+
+/**
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM[] =
+R"__c_cb(
+<UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>,
+)__c_cb";
+
+/**
+ * <DELEGATE_ENUMS> The enumeration declarations of deleagtes.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_ENUM_BASE[] =
+R"__c_cb(
+typedef enum {
+ <DELEGATE_ENUMS>
+} <PREFIX>_<NAME>_delegate_e;
+)__c_cb";
+
+/**
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_DELEGATE_NAME> The uppercase delegate name of the interface.
+ * <NUMBER> The number of the delegate.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_ENUM[] =
+R"__c_cb(
+<UPPERCASE_PREFIX>_<UPPERCASE_NAME>_DELEGATE_<UPPERCASE_DELEGATE_NAME> = <NUMBER>,
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ <SERVER_T> stub;
+ <SECURITY_T>
+ <PREFIX>_<NAME>_callback_s callback;
+ void *user_data;
+ GRecMutex mutex;
+} <PREFIX>_<NAME>_t;
+
+static <PREFIX>_<NAME>_t __<NAME>;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ <PEER_INFO_T> peer_info;
+ int id;
+ int seq_id;
+ bool once;
+ bool valid;
+} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CONTEXT_BASE[] =
+R"__c_cb(
+static int __<PREFIX>_<NAME>_process_received_event(<PREFIX>_<NAME>_t *h, const <PEER_INFO_T> peer_info, rpc_port_parcel_h parcel, rpc_port_parcel_h return_parcel)
+{
+ int ret = <ERROR_PREFIX>_ERROR_NONE;
+ int cmd = -1;
+ static const int table_size = ARRAY_SIZE(__<NAME>_method_table);
+
+ rpc_port_parcel_read_int32(parcel, &cmd);
+ if (cmd > 1 && cmd < table_size) {
+ if (__<NAME>_method_table[cmd])
+ ret = __<NAME>_method_table[cmd](peer_info, parcel, return_parcel, h);
+ } else {
+ _W("Invalid protocol. cmd(%d)", cmd);
+ ret = <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ return ret;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ * <DELEGATE_PARAMS> The parameters of the delegate.
+ * <DELEGATE_PARAMS_CHECK> The implementation to check whether arguments are nullptr or not
+ * <DELEGATE_ENUM_VALUE> The enumeration value of the method.
+ * <DELEGATE_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_to(rpc_port_parcel_h parcel, void *user_data)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = user_data;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ rpc_port_parcel_write_int32(parcel, h->id);
+
+ rpc_port_parcel_write_int32(parcel, h->seq_id);
+
+ rpc_port_parcel_write_bool(parcel, h->once);
+
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+}
+
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_from(rpc_port_parcel_h parcel, void *user_data)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = user_data;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(<ERROR_PREFIX>_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ rpc_port_parcel_read_int32(parcel, &h->id);
+
+ rpc_port_parcel_read_int32(parcel, &h->seq_id);
+
+ rpc_port_parcel_read_bool(parcel, &h->once);
+
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+ set_last_result(<ERROR_PREFIX>_ERROR_NONE);
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_t *handle;
+ static int seq_num;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_<DELEGATE_NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_<DELEGATE_NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_<DELEGATE_NAME>_from;
+ handle->id = <DELEGATE_ENUM_VALUE>;
+ handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+ handle->once = false;
+ handle->valid = true;
+ _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+
+ *h = handle;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ _W("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+ if (h->peer_info)
+ <PEER_INFO_DESTROY>
+
+ free(h);
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h handle;
+ int ret;
+
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_<DELEGATE_NAME>_create(&handle);
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ <PEER_INFO_CLONE1>
+ handle->seq_id = h->seq_id;
+ handle->once = h->once;
+ handle->valid = h->valid;
+
+ *clone = handle;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id)
+{
+ if (h == nullptr || id == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ *id = h->id;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id)
+{
+ if (h == nullptr || seq_id == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ *seq_id = h->seq_id;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once)
+{
+ if (h == nullptr || once == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ *once = h->once;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag)
+{
+ char *value;
+ char buf[128];
+
+ if (h == nullptr || tag == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ snprintf(buf, sizeof(buf), "%d::%d", h->id, h->seq_id);
+ value = strdup(buf);
+ if (value == nullptr) {
+ _E("Out of memory");
+ return <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ }
+
+ *tag = value;
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+static int __<PREFIX>_<NAME>_<DELEGATE_NAME>_set_peerInfo(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, const <PEER_INFO_T> peer_info)
+{
+ if (h == nullptr || peer_info == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ return <PEER_INFO_CLONE2>
+}
+
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_invoke(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h<DELEGATE_PARAMS>)
+{
+ rpc_port_parcel_h parcel_ = nullptr;
+ int ret_;
+ unsigned int data_size_;
+ unsigned char *data_;
+ <PAYLOAD_T> pl_ = nullptr;
+ <PEER_INFO_T> peer_info;
+ <FILE_LIST_DEF>
+
+
+ if (h == nullptr || h->peer_info == nullptr<DELEGATE_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ peer_info = h->peer_info;
+
+ if (h->once && !h->valid) {
+ _E("The delegate handle is already used");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+ g_rec_mutex_lock(&__<NAME>.mutex);
+
+ ret_ = rpc_port_parcel_create(&parcel_);
+ if (ret_ != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret_);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+ return ret_;
+ }
+
+ rpc_port_parcel_write_int32(parcel_, <DELEGATE_ENUM_VALUE>);
+
+ rpc_port_parcel_write(parcel_, &h->parcelable, h);
+
+ <DELEGATE_PARCEL_WRITE>
+
+ ret_ = rpc_port_parcel_get_raw(parcel_, (void **)&data_, &data_size_);
+ if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get raw. error(%d)", ret_);
+ goto out;
+
+ }
+
+ <SERVER_SEND_ASYNC>
+
+ <FILE_LIST_SEND>
+
+ h->valid = false;
+
+out:
+ rpc_port_parcel_destroy(parcel_);
+ <FILE_LIST_FREE>
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+
+ return ret_;
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel_, &<ARG>->parcelable, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_HANDLER_ARGS_DECL> The declarations for arguments of the method.
+ * <METHOD_HANDLER_PARCEL_READ> The implementation to read the parameter from the parcel.
+ * <METHOD_HANDLER_CALLBACK_INVOKE> The implementation to invoke the callback function of the method.
+ * <METHOD_HANDLER_PARCEL_WRITE> The implementation to write the result to the parcel.
+ * <METHOD_HANDLER_ARGS_FREE> The implementation to release arguments.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER_BASE[] =
+R"__c_cb(
+static int __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler(const <PEER_INFO_T> peer_info, rpc_port_parcel_h parcel, rpc_port_parcel_h return_parcel, void *user_data)
+{
+ <PREFIX>_<NAME>_t *h = user_data;
+ int ret_ = <ERROR_PREFIX>_ERROR_NONE;
+ <FILE_LIST_DEF>
+
+ <METHOD_HANDLER_ARGS_DECL>
+ if (h == nullptr || h->stub == nullptr) {
+ _E("Invalid parameter");
+ ret_ = <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ goto out;
+ }
+ <METHOD_HANDLER_PARCEL_READ>
+ <METHOD_HANDLER_CALLBACK_INVOKE>
+ <METHOD_HANDLER_PARCEL_WRITE>
+
+ <FILE_LIST_SEND>
+
+ out:
+ <METHOD_HANDLER_ARGS_FREE>
+ return ret_;
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface
+ */
+constexpr const char CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ[] =
+R"__c_cb(
+ret_ = <PREFIX>_<NAME>_create(&<ARG>);
+if (ret_ != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret_);
+ goto out;
+}
+
+__<PREFIX>_<NAME>_set_peerInfo(<ARG>, peer_info);
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+ret_ = get_last_result();
+if (ret_ != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret_);
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <ARG> The name of the value.
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+ret_ = <PREFIX>_<NAME>_create(&<ARG>);
+if (ret_ != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret_);
+ goto out;
+}
+
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+ret_ = get_last_result();
+if (ret_ != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret_);
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_bundle(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ ret_ = <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_string(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ ret_ = <ERROR_PREFIX>_ERROR_OUT_OF_MEMORY;
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &<ARG>);
+)__c_cb";
+
+/**
+ * <RES_SET> The implemention to set the result of the callback function.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <METHOD_ARGS> The arguments of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_INVOKE[] =
+R"__c_cb(
+if (h->callback.<METHOD_NAME>)
+ <RES_SET>h->callback.<METHOD_NAME>(peer_info<METHOD_ARGS>, h->user_data);
+)__c_cb";
+
+/**
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_PARCEL_WRITE_PRE[] =
+R"__c_cb(
+rpc_port_parcel_write_int32(return_parcel, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_RESULT_);
+)__c_cb";
+
+constexpr const char CB_INTERFACE_METHOD_PARCEL_WRITE_POST[] =
+R"__c_cb(
+ret_ = rpc_port_parcel_send(parcel_, port);
+rpc_port_parcel_destroy(parcel_);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(return_parcel, &<ARG>->parcelable, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(return_parcel, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(return_parcel, <ARG>);
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(return_parcel, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ <PREFIX>_<NAME>_destroy(<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ bundle_free(<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ free(<ARG>);
+)__c_cb";
+
+/**
+ * <NAME> The name of the interface.
+ * <METHOD_HANDLERS> The declarations of method handlers.
+ */
+constexpr const char CB_INTERFACE_METHOD_TABLE[] =
+R"__c_cb(
+static _stub_method_handler __<NAME>_method_table[] = {
+ <METHOD_HANDLERS>
+};
+)__c_cb";
+
+/**
+ * <ENUM_VALUE> The enumeration value of the method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER[] =
+R"__c_cb(
+[<ENUM_VALUE>] = __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler,
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <ACCESS_CONTROL_SET> The implmentation to set the access control the stub handle.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_disconnected_cb(const char *service_name,
+ const <PEER_INFO_T> peer_info, void *user_data)
+{
+ <PREFIX>_<NAME>_t *h = user_data;
+
+ _W("service_name(%s)", service_name);
+ h->callback.disconnected(peer_info, h->user_data);
+}
+
+static void __<PREFIX>_<NAME>_connection_result_cb(const char *service_name, const <PEER_INFO_T> peer_info,
+ const <MODULE_PREFIX>_connection_result_h result, void *user_data)
+{
+ <PREFIX>_<NAME>_t *h = user_data;
+
+ _I("service_name(%s)", service_name);
+ h->callback.connection_result(peer_info, result, h->user_data);
+}
+
+static void __<PREFIX>_<NAME>_payload_received_cb(const char *service_name,
+ const <PEER_INFO_T> peer_info, const <PAYLOAD_T> payload,
+ <PAYLOAD_TRANSFER_STATUS_T> status,
+ void *user_data)
+{
+ <PREFIX>_<NAME>_t* h = user_data;
+ rpc_port_parcel_h parcel;
+ unsigned char *data;
+ <PAYLOAD_TYPE_E> type;
+ int ret;
+ unsigned int data_len;
+
+ _W("service_name(%s)", service_name);
+
+ <PAYLOAD_GET_TYPE>
+ if (ret != <ERROR_NONE>) {
+ _E("Faled to <MODULE_PREFIX>_payload_get_type : %d", ret);
+ return;
+ }
+
+ if (type == <PAYLOAD_TYPE_DATA>) {
+ <PAYLOAD_GET_DATA>
+ if (ret != <ERROR_NONE>) {
+ _E("Faled to <MODULE_PREFIX>_payload_get_data : %d", ret);
+ return;
+ }
+
+ ret = rpc_port_parcel_create_from_raw(&parcel, data, data_len);
+ free(data);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle from data. error(%d)", ret);
+ return;
+ }
+
+ __<PREFIX>_<NAME>_process_received_event(h, peer_info, parcel, NULL);
+ rpc_port_parcel_destroy(parcel);
+
+ } else if (type == <PAYLOAD_TYPE_FILE>) {
+ if (h->callback.file_received)
+ h->callback.file_received(peer_info, payload, status, h->user_data);
+ }
+
+}
+
+static void __<PREFIX>_<NAME>_data_received_cb(const char *service_name,
+ const <PEER_INFO_T> peer_info, const unsigned char *data,
+ unsigned int data_size, unsigned char **return_data,
+ unsigned int *return_data_size, void *user_data)
+{
+ <PREFIX>_<NAME>_t *h = user_data;
+ rpc_port_parcel_h return_parcel;
+ rpc_port_parcel_h parcel;
+ char *result;
+ int ret;
+
+ ret = rpc_port_parcel_create_from_raw(&parcel, data, data_size);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle from data. error(%d)", ret);
+ return;
+ }
+
+ ret = rpc_port_parcel_create(&return_parcel);
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret);
+ rpc_port_parcel_destroy(parcel);
+ return;
+ }
+
+ __<PREFIX>_<NAME>_process_received_event(h, peer_info, parcel, return_parcel);
+
+ ret = rpc_port_parcel_get_raw(return_parcel, (void **)&result, return_data_size);
+ if (ret != RPC_PORT_ERROR_NONE)
+ _E("Failed to get raw. error(%d)", ret);
+
+ *return_data = (unsigned char *)malloc(sizeof(unsigned char) * *return_data_size);
+ if (*return_data == NULL) {
+ *return_data_size = 0;
+ rpc_port_parcel_destroy(parcel);
+ rpc_port_parcel_destroy(return_parcel);
+ return;
+ }
+
+ memcpy(*return_data, result, *return_data_size);
+
+ rpc_port_parcel_destroy(parcel);
+ rpc_port_parcel_destroy(return_parcel);
+}
+
+static void __<PREFIX>_<NAME>_connection_request_cb(const char *service_name,
+ const <PEER_INFO_T> peer_info, void *user_data)
+{
+ <PREFIX>_<NAME>_t *h = user_data;
+
+ _W("service_name(%s)", service_name);
+ h->callback.connection_request(peer_info, h->user_data);
+
+}
+
+<EXTRA>{
+ int ret;
+ <SECURITY_T>
+
+ if (callback == nullptr || callback->connection_result == nullptr || callback->disconnected == nullptr || callback->connection_request == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ if (__<NAME>.stub) {
+ _E("Already exists");
+ return <ERROR_PREFIX>_ERROR_NONE;
+ }
+
+ g_rec_mutex_init(&__<NAME>.mutex);
+ __<NAME>.callback = *callback;
+ __<NAME>.user_data = user_data;
+
+ <SERVER_REGISTER>
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_unregister(void)
+{
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+ g_rec_mutex_clear(&__<NAME>.mutex);
+
+ <SERVER_UNREGISTER>
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_foreach_peer_info(<PREFIX>_<NAME>_peer_info_cb callback, void *user_data)
+{
+ if (callback == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ <SERVER_FOREACH_CONNECTED_PEER_INFO>
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+
+ return <ERROR_PREFIX>_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_accept(const <PEER_INFO_T> peer_info)
+{
+ int ret;
+
+ if (peer_info == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+ <SERVER_ACCEPT>
+
+ return ret;
+}
+
+int <PREFIX>_<NAME>_reject(const <PEER_INFO_T> peer_info, const char *reason)
+{
+ int ret;
+
+ if (peer_info == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ <SERVER_REJECT>
+
+ return ret;
+}
+
+int <PREFIX>_<NAME>_set_display_name(const char *display_name)
+{
+ int ret;
+
+ if (display_name == nullptr) {
+ _E("Invalid parameter");
+ return <ERROR_PREFIX>_ERROR_INVALID_PARAMETER;
+ }
+
+ <SERVER_SET_DISPLAY_NAME>
+
+ return ret;
+}
+)__c_cb";
+
+#endif // IDLC_C_CION_GEN_C_STUB_BODY_GEN_CB_H_
diff --git a/idlc/gen_cion/c_cion_stub_header_gen.cc b/idlc/gen_cion/c_cion_stub_header_gen.cc
new file mode 100644
index 0000000..135f0af
--- /dev/null
+++ b/idlc/gen_cion/c_cion_stub_header_gen.cc
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/c_cion_stub_header_gen.h"
+
+namespace {
+#include "idlc/gen_cion/c_cion_stub_header_gen_cb.h"
+}
+
+namespace tidl {
+
+CCionStubHeaderGen::CCionStubHeaderGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : CCionHeaderGeneratorBase(doc, trans) {}
+
+void CCionStubHeaderGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenPragmaOnce(stream);
+ GenIncludeDefaultHeaders(stream, false);
+ GenExplicitLinkageOpen(stream);
+ GenCommonHandles(stream);
+ GenConnectionHandle(stream);
+ GenFileHandle(stream);
+ GenStructureHandles(stream);
+ GenInterfaceHandles(stream);
+ GenCommonBase(stream);
+ GenConnectionBase(stream);
+ GenFileBase(stream);
+ GenStructures(stream);
+ GenInterfaceCallbacks(stream);
+ GenInterfaces(stream);
+}
+
+void CCionStubHeaderGen::OnFiniGen(std::ofstream& stream) {
+ GenExplicitLinkageClose(stream);
+}
+void CCionStubHeaderGen::GenInterfaceHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+ GenInterfaceDelegateHandle(stream, iface, *d);
+ }
+ }
+}
+
+// @see #CB_INTERFACE_DELEGATE_HANDLE
+void CCionStubHeaderGen::GenInterfaceDelegateHandle(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_DELEGATE_HANDLE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", decl.GetID() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+void CCionStubHeaderGen::GenInterfaceCallbacks(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceCallbackBase(stream, iface);
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceMethodCallbackBase(stream, iface, *d);
+ }
+ }
+}
+
+// @see #CB_INTERFACE_CALLBACK_BASE
+void CCionStubHeaderGen::GenInterfaceCallbackBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_CALLBACK_BASE, {
+ { "<NAME>", iface.GetID() },
+ { "<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType() },
+ { "<PAYLOAD_T>", GetTransportable().C().GenPayloadType() },
+ { "<PAYLOAD_TRANSFER_STATUS_T>",
+ GetTransportable().C().GenPayloadTransferStatusType() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix() },
+ { "<PREFIX>", GetHandlePrefix() },
+ }));
+
+ stream << SmartIndent(code);
+}
+
+std::string CCionStubHeaderGen::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_BASE
+void CCionStubHeaderGen::GenInterfaceMethodCallbackBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_BASE, {
+ { "<RETURN_TYPE>", GetReturnTypeString(decl.GetType()) },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_PARAMS>", GenMethodParams(iface, decl) },
+ { "<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<PREFIX>", GetHandlePrefix() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+void CCionStubHeaderGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CCionStubHeaderGen::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateBase(stream, iface, *d);
+ }
+ GenInterfaceBase(stream, iface);
+}
+
+std::string CCionStubHeaderGen::GenDelegateParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+// @see #CB_INTERFACE_DELEGATE_BASE
+void CCionStubHeaderGen::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_DELEGATE_BASE, {
+ { "<NAME>", iface.GetID() },
+ { "<DELEGATE_NAME>", decl.GetID() },
+ { "<DELEGATE_PARAMS>", GenDelegateParams(iface, decl) },
+ { "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix() },
+ { "<PREFIX>", GetHandlePrefix() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_DECL
+std::string CCionStubHeaderGen::GenMethodCallbackDecls(const Interface& iface) {
+ std::string method_callback_decls;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string method_callback_decl(ReplaceAll(
+ CB_INTERFACE_METHOD_CALLBACK_DECL, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", d->GetID() }
+ }));
+
+ method_callback_decl = RemoveLine(method_callback_decl);
+ method_callback_decls += RemoveLine(method_callback_decl, 2);
+ }
+
+ return method_callback_decls;
+}
+
+// @see #CB_INTERFACE_BASE
+void CCionStubHeaderGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code(ReplaceAll(CB_INTERFACE_BASE, {
+ { "<EXTRA>", GetTransportable().C().GenServerExtra(false) },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_CALLBACK_DECLS>", GenMethodCallbackDecls(iface) },
+ { "<PEER_INFO_T>", GetTransportable().C().GenPeerInfoType() },
+ { "<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<PREFIX>", GetHandlePrefix() }
+ }));
+
+ stream << SmartIndent(code);
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/c_cion_stub_header_gen.h b/idlc/gen_cion/c_cion_stub_header_gen.h
new file mode 100644
index 0000000..2ada031
--- /dev/null
+++ b/idlc/gen_cion/c_cion_stub_header_gen.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_STUB_HEADER_GEN_H_
+#define IDLC_C_CION_GEN_C_STUB_HEADER_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/c_cion_header_gen_base.h"
+
+namespace tidl {
+
+class CCionStubHeaderGen : public CCionHeaderGeneratorBase {
+ public:
+ explicit CCionStubHeaderGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CCionStubHeaderGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenInterfaceHandles(std::ofstream& stream);
+ void GenInterfaceDelegateHandle(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+
+ void GenInterfaceCallbacks(std::ofstream& stream);
+ void GenInterfaceCallbackBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodCallbackBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl);
+
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+
+ std::string GenDelegateParams(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+ std::string GenMethodCallbackDecls(const Interface& iface);
+};
+
+} // namespace tidl
+
+#endif // IDLC_C_CION_GEN_C_STUB_HEADER_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/c_cion_stub_header_gen_cb.h b/idlc/gen_cion/c_cion_stub_header_gen_cb.h
new file mode 100644
index 0000000..7dcf3fd
--- /dev/null
+++ b/idlc/gen_cion/c_cion_stub_header_gen_cb.h
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_CION_GEN_C_STUB_HEADER_GEN_CB_H_
+#define IDLC_C_CION_GEN_C_STUB_HEADER_GEN_CB_H_
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_HANDLE[] =
+R"__c_cb(
+/**
+ * @brief The <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s *<PREFIX>_<NAME>_<DELEGATE_NAME>_h;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate.
+ * <DELEGATE_PARAMS> The parameters of the callback function.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
+R"__c_cb(
+/**
+ * @brief Creates a <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[out] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_clone()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME>_<DELEGATE_NAME> should be released using
+ * the <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME>_<DELEGATE_NAME> handle will be returned
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone);
+
+/**
+ * @brief Gets the ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] id The ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id);
+
+/**
+ * @brief Gets the sequence ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] seq_id The Sequence ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id);
+
+/**
+ * @brief Checks whether the delegate is for one-time or not.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] once The flag, it's true, the handle is for one-time
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once);
+
+/**
+ * @brief Gets the tag from the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks The @a tag should be released using free().
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] tag The tag
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag);
+
+/**
+ * @brief Invokes the callback function of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[in] ...
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #<ERROR_PREFIX>_ERROR_IO_ERROR I/O error
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_invoke(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h<DELEGATE_PARAMS>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CALLBACK_BASE[] =
+R"__c_cb(
+/**
+ * @brief Called when the proxy is connected.
+ * @details The callback function is called when the proxy is connected to the stub.
+ *
+ * @param[in] peer_info The <MODULE_PREFIX> peer information handle
+ * The @a peer_info can be used only in the callback. To use outside, make a copy.
+ * @param[in] result The handle for connection result
+ * @param[in] user_data The user data passed from the registration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ * @see #<MODULE_PREFIX>_peer_info_clone()
+ */
+typedef void (*<PREFIX>_<NAME>_connection_result_cb)(const <PEER_INFO_T> peer_info,
+ const <MODULE_PREFIX>_connection_result_h result, void *user_data);
+
+/**
+ * @brief Called when the proxy is disconnected.
+ * @details The callback function is called when the proxy is disconnected from the stub.
+ *
+ * @param[in] peer_info The <MODULE_PREFIX> peer information handle
+ * The @a peer_info can be used only in the callback. To use outside, make a copy.
+ * @param[in] user_data The user data passed from the registration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ * @see #<MODULE_PREFIX>_peer_info_clone()
+ */
+typedef void (*<PREFIX>_<NAME>_disconnected_cb)(const <PEER_INFO_T> peer_info, void *user_data);
+
+/**
+ * @brief Called to get the proxy once for each connected proxy.
+ *
+ * @param[in] peer_info The peer_info handle
+ * @param[in] user_data The user data passed from the registration function
+ * @return @c true to continue with the next iteration of the loop,
+ * otherwise @c false to break out of the loop
+ * @pre <PREFIX>_<NAME>_foreach_peer_info_cb() will invoke this callback.
+ * @see <PREFIX>_<NAME>_foreach_peer_info_cb()
+ */
+typedef bool (*<PREFIX>_<NAME>_peer_info_cb)(const <PEER_INFO_T> peer_info, void *user_data);
+
+/**
+ * @brief Called when the payload is received.
+ *
+ * @param[in] peer_info The <MODULE_PREFIX> peer information handle \n
+ * The @a peer_info can be used only in the callback. To use outside, make a copy.
+ * @param[in] payload The received payload \n
+ * The @a payload can be used only in the callback. \n
+ * The @a payload should not be released.
+ * @param[in] status The status of transfer
+ * @param[in] user_data The user data passed from the registeration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ * @see #<MODULE_PREFIX>_peer_info_clone()
+ *
+ * @par Sample code:
+ * @code
+
+void <PREFIX>_<NAME>__file_received_cb(const <PEER_INFO_T> peer_info, const <PAYLOAD_T> payload,
+ <PAYLOAD_TRANSFER_STATUS_T> status, void *user_data)
+{
+ <PREFIX>_<NAME>_h handle = user_data;
+
+ char *app_id = NULL;
+ char *file_name = NULL;
+ char *data_path = NULL;
+ uint64_t bytes, total;
+ char data_path_buff[512];
+
+ <MODULE_PREFIX>_peer_info_get_app_id(peer_info, &app_id);
+ <MODULE_PREFIX>_payload_get_total_bytes(payload, &total);
+ <MODULE_PREFIX>_payload_get_received_bytes(payload, &bytes);
+ <MODULE_PREFIX>_payload_get_received_file_name(payload, &file_name);
+
+ if (status == <ERROR_PREFIX>_PAYLOAD_TRANSFER_STATUS_SUCCESS) {
+ data_path = app_get_data_path();
+ if (data_path == NULL) {
+ LOGE("failed to get data path.");
+ goto end;
+ }
+
+ snprintf(data_path_buff, 512, "%s%s", data_path, file_name);
+ ret = <MODULE_PREFIX>_payload_save_as_file(payload, data_path_buff);
+ free(data_path);
+ LOGI("save file %s : %d", data_path_buff, ret);
+ } else {
+ LOGE("[file received from [%s:%s] : %lld / %lld",
+ app_id, file_name, bytes, total);
+ }
+
+end:
+ free(name);
+ free(app_id);
+}
+
+ * @endcode
+ */
+typedef void (*<PREFIX>_<NAME>_file_received_cb)(const <PEER_INFO_T> peer_info, const <PAYLOAD_T> payload,
+ <PAYLOAD_TRANSFER_STATUS_T> status, void *user_data);
+
+/**
+ * @brief Called when a connection is requested.
+ * @since_tizen 6.5
+ * @param[in] peer_info The <MODULE_PREFIX> peer information handle \n
+ * The @a peer_info can be used only in the callback. To use outside, make a copy.
+ * @param[in] user_data The user data passed from the registration function
+ * @see #<PREFIX>_<NAME>_register()
+ * @see #<MODULE_PREFIX>_peer_info_clone()
+ *
+ * @par Sample code:
+ * @code
+
+void <PREFIX>_<NAME>_connection_request_cb(const <PEER_INFO_T> peer_info, void *user_data)
+{
+
+ char *app_version = NULL;
+
+ <MODULE_PREFIX>_peer_info_get_app_version(peer_info, &app_version);
+
+ if(strcmp(app_version, "1.1") == 0) {
+ <PREFIX>_<NAME>_accept(peer_info);
+ } else {
+ <PREFIX>_<NAME>_reject(peer_info, NULL);
+ }
+
+ free(app_version);
+}
+ * @endcode
+ */
+typedef void (*<PREFIX>_<NAME>_connection_request_cb)(const <PEER_INFO_T> peer_info, void *user_data);
+
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_BASE[] =
+R"__c_cb(
+/**
+ * @brief Called when the request of the proxy is delivered.
+ *
+ * @param[in] context The context handle
+ * @param[in] user_data The user data passed from the registration function
+ * @see #<PREFIX>_<NAME>_callback_s;
+ */
+typedef <RETURN_TYPE> (*<PREFIX>_<NAME>_<METHOD_NAME>_cb)(const <PEER_INFO_T> peer_info<METHOD_PARAMS>, void *user_data);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_CALLBACK_DECLS> The declarations of the method callback functions.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+/**
+ * @brief The structure type containing the set of callback functions for handling stub events.
+ * @details It is one of the input parameters of the <PREFIX>_<NAME>_register() function.
+ *
+ * @see <PREFIX>_<NAME>_create_cb
+ * @see <PREFIX>_<NAME>_terminate_cb
+ */
+typedef struct {
+ <PREFIX>_<NAME>_connection_result_cb connection_result;/**< This callback function is invoked when the proxy is connected to the stub. */
+ <PREFIX>_<NAME>_file_received_cb file_received;/**< This callback function is invoked when the payload is received. */
+ <PREFIX>_<NAME>_disconnected_cb disconnected;/**< This callback function is invoked when the proxy is disconnected. */
+ <PREFIX>_<NAME>_connection_request_cb connection_request;/**< This callback function is invoked when a connection is requested */
+ <METHOD_CALLBACK_DECLS>
+} <PREFIX>_<NAME>_callback_s;
+
+<EXTRA>
+
+/**
+ * @brief Unregisters the registered service_name.
+ */
+int <PREFIX>_<NAME>_unregister(void);
+
+/**
+ * @brief Retrieves the connected peer_info handles.
+ *
+ * @param[in] callback The callback function
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_peer_info_cb()
+ */
+int <PREFIX>_<NAME>_foreach_peer_info(<PREFIX>_<NAME>_peer_info_cb callback, void *user_data);
+
+/**
+ * @brief Accepts the connection request from a peer.
+
+ * @param[in] peer_info The <MODULE_PREFIX> peer information handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_register()
+ * @see <PREFIX>_<NAME>_connection_request_cb()
+ */
+int <PREFIX>_<NAME>_accept(const <PEER_INFO_T> peer_info);
+
+/**
+ * @brief Rejects the connection request from a peer.
+
+ * @param[in] peer_info The <MODULE_PREFIX> peer information handle
+ * @param[in] reason The reason of reject
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_register()
+ * @see <PREFIX>_<NAME>_connection_request_cb()
+ */
+int <PREFIX>_<NAME>_reject(const <PEER_INFO_T> peer_info, const char *reason);
+
+/**
+ * @brief Sets the stub display name.
+ * @details The display name is a customized name for stub.
+
+ * @param[in] display_name The display name
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #<ERROR_PREFIX>_ERROR_IO_ERROR IO error
+ * @see <MODULE_PREFIX>_peer_info_get_display_name()
+ */
+int <PREFIX>_<NAME>_set_display_name(const char *display_name);
+
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The name of the method of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_DECL[] =
+R"__c_cb(
+<PREFIX>_<NAME>_<METHOD_NAME>_cb <METHOD_NAME>; /**< This callback function is invoked when the <METHOD_NAME> request is delivered. */
+)__c_cb";
+
+#endif // IDLC_C_CION_GEN_C_STUB_HEADER_GEN_CB_H_
diff --git a/idlc/gen_cion/c_transportable.h b/idlc/gen_cion/c_transportable.h
new file mode 100644
index 0000000..b245c45
--- /dev/null
+++ b/idlc/gen_cion/c_transportable.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_C_TRANSPORTABLE_H_
+#define IDLC_GEN_CION_C_TRANSPORTABLE_H_
+
+#include <list>
+#include <string>
+
+namespace tidl {
+
+class CTransportable {
+ public:
+ virtual ~CTransportable() = default;
+ virtual std::string GenInclude(bool body = true, int type = 0) const = 0;
+ virtual std::string GenHeaderBase() const = 0;
+ virtual std::string GenHeaderPayloadHandle() const = 0;
+ virtual std::string GenHeaderCommonHandle() const = 0;
+ virtual std::string GenHeaderConnectionHandle() const = 0;
+ virtual std::string GenHeaderPayloadBase() const = 0;
+ virtual std::string GenHeaderConnectionBase() const = 0;
+ virtual std::string GenBodyPayloadBase() const = 0;
+ virtual std::string GenBodyConnectionBase() const = 0;
+ virtual std::string GenBodyPeerInfoBase() const = 0;
+ virtual std::string GenProxyPrefix() const = 0;
+ virtual std::string GenStubPrefix() const = 0;
+ virtual std::string GenGroupPrefix() const = 0;
+ virtual std::string GenModulePrefix() const = 0;
+ virtual std::string GenErrorPrefix() const = 0;
+ virtual std::string GenServerExtra(bool body = true) const = 0;
+ virtual std::string GenClientExtra(bool body = true) const = 0;
+ virtual std::string GenGroupExtra(bool body = true) const = 0;
+ virtual std::string GenClientSendAsync(std::string client,
+ std::string payload, std::string size) const = 0;
+ virtual std::string GenClientSend(std::string client, std::string data,
+ std::string data_size, std::string ret_data,
+ std::string ret_data_size) const = 0;
+ virtual std::string GenServerSendAsync(std::string server, std::string client,
+ std::string payload, std::string size) const = 0;
+ virtual std::string GenServerFileSend(std::string path, std::string server,
+ std::string peer) const = 0;
+ virtual std::string GenClientFileSend(std::string path,
+ std::string client) const = 0;
+ virtual std::string GenGroupType() const = 0;
+ virtual std::string GenPayloadTransferStatusType(bool internal_type = false) const = 0;
+ virtual std::string GenPeerInfoType() const = 0;
+ virtual std::string GenPeerInfoDestroy(std::string peer) const = 0;
+ virtual std::string GenPayloadType(bool internal_type = false) const = 0;
+ virtual std::string GenClientType() const = 0;
+ virtual std::string GenSecurityType(bool definition = true) const = 0;
+ virtual std::string GenServerType() const = 0;
+ virtual std::string GenClientTryConnect(std::string client,
+ std::string peer) const = 0;
+ virtual std::string GenClientDisconnect(std::string client) const = 0;
+ virtual std::string GenClientTryDiscovery(std::string client) const = 0;
+ virtual std::string GenClientStopDiscovery(std::string client) const = 0;
+ virtual std::string GenServerRegister() const = 0;
+ virtual std::string GenServerUnregister() const = 0;
+ virtual std::string GenClientExtraHeader() const = 0;
+ virtual std::string GenClientExtraBody() const = 0;
+ virtual std::string GenServerExtraHeader() const = 0;
+ virtual std::string GenServerExtraBody() const = 0;
+ virtual std::string GenServerAccept() const = 0;
+ virtual std::string GenServerReject() const = 0;
+ virtual std::string GenServerSetDisplayName() const = 0;
+ virtual std::string GenGroupPublish() const = 0;
+ virtual std::string GenPayloadTypeEnum() const = 0;
+ virtual std::string GenPayloadTypeData() const = 0;
+ virtual std::string GenPayloadTypeFile() const = 0;
+ virtual std::string GenPayloadGetType() const = 0;
+ virtual std::string GenErrorNone() const = 0;
+ virtual std::string GenPayloadGetData() const = 0;
+ virtual std::string GenClientCreate() const = 0;
+ virtual std::string GenGroupCreate() const = 0;
+ virtual std::string GenGroupDestroy() const = 0;
+ virtual std::string GenClientDestroy() const = 0;
+ virtual std::string GenSetSecurityCA(std::string arg) const = 0;
+ virtual std::string GenSetSecurityCert(std::string arg) const = 0;
+ virtual std::string GenSetSecurityPrivateKey(std::string arg) const = 0;
+ virtual std::string GenPeerInfoClone(std::string src_peer,
+ std::string dest_peer) const = 0;
+ virtual std::string GenServerForeachConnectedPeerInfo(std::string name) const = 0;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CION_C_TRANSPORTABLE_H_
diff --git a/idlc/gen_cion/cion_plugin_base.cc b/idlc/gen_cion/cion_plugin_base.cc
new file mode 100644
index 0000000..03124cb
--- /dev/null
+++ b/idlc/gen_cion/cion_plugin_base.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/cion_plugin_base.h"
+
+#include "idlc/gen_cion/plugin_loader.h"
+
+#include <utility>
+
+namespace tidl {
+
+CionPluginBase::CionPluginBase(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : Generator(std::move(doc)) {
+ transportable_ = trans;
+}
+
+Transportable& CionPluginBase::GetTransportable() {
+ return *transportable_;
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/cion_plugin_base.h b/idlc/gen_cion/cion_plugin_base.h
new file mode 100644
index 0000000..045c84a
--- /dev/null
+++ b/idlc/gen_cion/cion_plugin_base.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_CION_PLUGIN_BASE_H_
+#define IDLC_GEN_CION_CION_PLUGIN_BASE_H_
+
+#include <memory>
+
+#include "idlc/gen/generator.h"
+#include "idlc/gen_cion/plugin_loader.h"
+
+namespace tidl {
+
+class CionPluginBase : public Generator {
+ public:
+ explicit CionPluginBase(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CionPluginBase() = default;
+
+ Transportable& GetTransportable();
+
+ private:
+ std::shared_ptr<tidl::Transportable> transportable_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CION_CION_PLUGIN_BASE_H_
diff --git a/idlc/gen_cion/cpp_cion_gen_base.cc b/idlc/gen_cion/cpp_cion_gen_base.cc
new file mode 100644
index 0000000..85a7a23
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_gen_base.cc
@@ -0,0 +1,925 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ctime>
+#include <vector>
+#include <utility>
+#include <algorithm>
+
+#include "idlc/options.h"
+#include "idlc/gen_cion/cpp_cion_gen_base.h"
+
+namespace {
+#include "idlc/gen_cion/cpp_cion_gen_base_cb.h"
+}
+
+namespace tidl {
+
+CppCionGeneratorBase::CppCionGeneratorBase(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : CionPluginBase(doc, trans) {
+ type_map_ = {
+ {"char", "char"}, {"int", "int"}, {"short", "short"},
+ {"long", "long long"}, {"string", "std::string"}, {"bool", "bool"},
+ {"list", "std::list"}, {"float", "float"}, {"double", "double"},
+ {"file", "File"}, {"bundle", "Bundle"}, {"void", "void"},
+ {"array", "std::vector"}
+ };
+
+ parcel_type_map_ = {
+ {"char", "byte"},
+ {"int", "int32"},
+ {"short", "int16"},
+ {"long", "int64"},
+ {"string", "string"},
+ {"bool", "bool"},
+ {"float", "float"},
+ {"double", "double"},
+ {"bundle", "bundle"},
+ {"file", "string"},
+ };
+
+ type_init_map_ = {
+ {"char", "0"},
+ {"int", "0"},
+ {"short", "0"},
+ {"long", "0"},
+ {"bool", "false"},
+ {"float", "0.0f"},
+ {"double", "0.0"},
+ };
+}
+
+void CppCionGeneratorBase::GenStructuresForHeader(std::ofstream& stream,
+ bool is_group) {
+ // FIXME: need to check whether the interface use bundle/file instead of
+ // 'is_group'
+ if (!is_group) {
+ stream << CB_BUNDLE;
+ stream << CB_FILE;
+ }
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_STRUCTURE)
+ continue;
+ Structure& st = static_cast<Structure&>(*i);
+ GenStructureForHeader(stream, st);
+ stream << std::endl;
+ }
+}
+
+void CppCionGeneratorBase::GenStructureForHeader(std::ofstream& stream,
+ const Structure& st) {
+ const char ctor[] = " $$();\n" \
+ " $$($$);\n";
+ const char variable[] = "$$\n";
+
+ stream << "class " << st.GetID() << " final ";
+
+ GenBrace(stream, 0, [&]() {
+ stream << " public:" << NLine(1);
+ GenTemplate(ctor, stream,
+ [&]()->std::string {
+ return st.GetID();
+ },
+ [&]()->std::string {
+ return st.GetID();
+ },
+ [&]()->std::string {
+ std::string str;
+ int n = 1;
+ for (const auto& i : st.GetElements()) {
+ if (n != 1)
+ str += ", ";
+ str += ConvertTypeToString(i->GetType()) + " " + i->GetID();
+ n++;
+ }
+ return str;
+ });
+
+ stream << NLine(1);
+ for (const auto& i : st.GetElements()) {
+ GenSetter(stream, *i);
+ GenGetter(stream, *i);
+ stream << NLine(1);
+ }
+
+ stream << " private:";
+ GenTemplate(variable, stream,
+ [&]()->std::string {
+ std::string str;
+ for (const auto& i : st.GetElements()) {
+ str += NLine(1) + Tab(1)
+ + ConvertTypeToString(i->GetType()) + " "
+ + i->GetID() + "_";
+ if (type_init_map_.find(i->GetType().ToString())
+ == type_init_map_.end()) {
+ str += ";";
+ } else {
+ str += " = " + type_init_map_[i->GetType().ToString()] + ";";
+ }
+ }
+ str += NLine(1);
+ return str;
+ });
+ }, false, false);
+ stream << ";" << NLine(1);
+}
+
+void CppCionGeneratorBase::GenSetter(std::ofstream& stream, const Element& ele) {
+ const char setter[] =
+ "void Set$$($$ $$) {\n" \
+ " $$_ = $$;\n" \
+ "}\n";
+
+ GenTemplate(AddIndent(TAB_SIZE, setter, true), stream,
+ [&]()->std::string {
+ return ele.GetID();
+ },
+ [&]()->std::string {
+ return ConvertTypeToString(ele.GetType());
+ },
+ [&]()->std::string {
+ return ele.GetID();
+ },
+ [&]()->std::string {
+ return ele.GetID();
+ },
+ [&]()->std::string {
+ if (ele.GetType().IsUserDefinedType() ||
+ ele.GetType().GetMetaType() != nullptr ||
+ ele.GetType().ToString() == "string" ||
+ ele.GetType().ToString() == "bundle" ||
+ ele.GetType().ToString() == "file") {
+ return "std::move(" + ele.GetID() + ")";
+ }
+
+ return ele.GetID();
+ });
+ stream << NLine(1);
+}
+
+void CppCionGeneratorBase::GenGetter(std::ofstream& stream, const Element& ele) {
+ const char getter[] =
+ "$$ Get$$() const {\n" \
+ " return $$_;\n" \
+ "}\n";
+
+ GenTemplate(AddIndent(TAB_SIZE, getter, true), stream,
+ [&]()->std::string {
+ if (ele.GetType().IsUserDefinedType() ||
+ ele.GetType().GetMetaType() != nullptr ||
+ ele.GetType().ToString() == "string" ||
+ ele.GetType().ToString() == "bundle" ||
+ ele.GetType().ToString() == "file") {
+ return "const " + ConvertTypeToString(ele.GetType()) + "&";
+ }
+
+ return ConvertTypeToString(ele.GetType());
+ },
+ [&]()->std::string {
+ return ele.GetID();
+ },
+ [&]()->std::string {
+ return ele.GetID();
+ });
+}
+
+void CppCionGeneratorBase::GenStructuresForBody(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_STRUCTURE)
+ continue;
+ Structure& st = static_cast<Structure&>(*i);
+ GenStructureForBody(stream, st);
+ stream << std::endl;
+ }
+}
+
+void CppCionGeneratorBase::GenStructureForBody(std::ofstream& stream,
+ const Structure& st) {
+ std::vector<std::pair<std::string, std::string>> v;
+ const char ctor[] = "<CLS_NAME>::<CLS_NAME>() {}\n\n" \
+ "<CLS_NAME>::<CLS_NAME>(<PARAMS>)\n" \
+ " : <INIT> {}";
+
+ for (const auto& i : st.GetElements()) {
+ std::pair<std::string, std::string> p;
+
+ p.first = ConvertTypeToString(i->GetType());
+ p.second = i->GetID();
+ v.push_back(p);
+ }
+
+ ReplaceAll(ctor)
+ .Change("<CLS_NAME>", st.GetID())
+ .Change("<PARAMS>", [&]() {
+ std::string str;
+ for (auto& i : v) {
+ str += i.first + " " + i.second;
+
+ if (i != v.back())
+ str += ", ";
+ }
+ return str;
+ })
+ .Change("<INIT>", [&]() {
+ std::string str;
+ for (auto& i : v) {
+ str += i.second + "_(std::move(" + i.second + "))";
+
+ if (i != v.back())
+ str += ", ";
+ }
+ return str;
+ })
+ .Out(stream);
+
+ stream << NLine(2);
+}
+
+void CppCionGeneratorBase::GenSerializer(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_STRUCTURE)
+ continue;
+ Structure& st = static_cast<Structure&>(*i);
+ GenSerializer(stream, st);
+ stream << NLine(1);
+ }
+}
+
+void CppCionGeneratorBase::GenPrototype(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_STRUCTURE)
+ continue;
+ Structure& st = static_cast<Structure&>(*i);
+ GenSerializer(stream, st, true);
+ GenDeSerializer(stream, st, true);
+ }
+ GenListSerializer(stream, true);
+ stream << NLine(1);
+}
+
+void CppCionGeneratorBase::GenSerializer(std::ofstream& stream, const Structure& st,
+ bool proto) {
+ const char parcel_str[] = "rpc_port_parcel_h";
+
+ stream << parcel_str << " operator << ("
+ << parcel_str << " h, const " << st.GetID() << "& param)";
+ if (proto) {
+ stream << ";" << NLine(1);
+ return;
+ }
+
+ stream << " ";
+ GenBrace(stream, 0, [&]() {
+ for (const auto& i : st.GetElements()) {
+ stream << AddIndent(TAB_SIZE,
+ ConvertTypeToSerializer(i->GetType(),
+ "param.Get" + i->GetID() + "()", "h"));
+ }
+ stream << Tab(1) << "return h;" << NLine(1);
+ }, false);
+}
+
+void CppCionGeneratorBase::GenDeSerializer(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_STRUCTURE)
+ continue;
+ Structure& st = static_cast<Structure&>(*i);
+ GenDeSerializer(stream, st);
+ stream << std::endl;
+ }
+}
+
+void CppCionGeneratorBase::GenDeSerializer(std::ofstream& stream,
+ const Structure& st, bool proto) {
+ const char parcel_str[] = "rpc_port_parcel_h";
+
+ stream << parcel_str << " operator >> ("
+ << parcel_str << " h, " << st.GetID() << "& param)";
+ if (proto) {
+ stream << ";" << NLine(1);
+ return;
+ }
+
+ stream << " ";
+ GenBrace(stream, 0, [&]() {
+ for (const auto& i : st.GetElements()) {
+ auto& type = i->GetType();
+ stream << AddIndent(TAB_SIZE,
+ ConvertTypeToDeserializer(type, i->GetID(), "h"));
+
+ stream << Tab(1) << "param.Set" << i->GetID() << "(";
+ if (type.ToString() == "list" ||
+ type.ToString() == "array" ||
+ type.ToString() == "string" ||
+ type.ToString() == "bundle" ||
+ type.IsUserDefinedType())
+ stream << "std::move(" << i->GetID() << ")";
+ else
+ stream << i->GetID();
+
+ stream << ");" << NLine(2);
+ }
+ stream << Tab(1) << "return h;" << NLine(1);
+ }, false);
+}
+
+std::string CppCionGeneratorBase::ConvertTypeToString(const BaseType& type) {
+ if (type.IsUserDefinedType()) {
+ if (IsDelegateType(type)) {
+ return "std::unique_ptr<" + type.ToString() + ">";
+ }
+ return type.ToString();
+ }
+
+ if (type.GetMetaType() != nullptr)
+ return type_map_[type.ToString()] + "<" +
+ ConvertTypeToString(*(type.GetMetaType())) + ">";
+
+ return type_map_[type.ToString()];
+}
+
+std::string CppCionGeneratorBase::Tab(int cnt) {
+ std::string t(cnt * 2, ' ');
+
+ return t;
+}
+
+std::string CppCionGeneratorBase::NLine(int cnt) {
+ std::string t(cnt, '\n');
+
+ return t;
+}
+
+void CppCionGeneratorBase::AddSerializerList(const BaseType& type) {
+ if (type.GetMetaType() != nullptr) {
+ serializer_list_[ConvertTypeToString(type)] = &type;
+ AddSerializerList(*type.GetMetaType());
+ }
+}
+
+void CppCionGeneratorBase::GenListSerializer(std::ofstream& stream,
+ const BaseType& type, bool proto) {
+ stream << "rpc_port_parcel_h operator << (rpc_port_parcel_h h, const "
+ << ConvertTypeToString(type) << "& c)";
+
+ if (proto) {
+ stream << ";" << NLine(1);
+ stream << "rpc_port_parcel_h operator >> (rpc_port_parcel_h h, "
+ << ConvertTypeToString(type) << "& c);" << NLine(1);
+ return;
+ }
+
+ stream << " ";
+ GenBrace(stream, 0, [&]() {
+ stream << Tab(1)
+ << "rpc_port_parcel_write_array_count(h, c.size());"
+ << NLine(1);
+ stream << Tab(1) << "for (const auto& i : c) ";
+ GenBrace(stream, TAB_SIZE, [&]() {
+ if (type.GetMetaType() != nullptr) {
+ auto& mt = *type.GetMetaType();
+ stream << AddIndent(TAB_SIZE * 2,
+ ConvertTypeToSerializer(mt, "i", "h"));
+ }
+ }, false);
+ stream << Tab(1) << "return h;" << NLine(1);
+ }, false);
+ stream << NLine(1);
+
+ stream << "rpc_port_parcel_h operator >> (rpc_port_parcel_h h, "
+ << ConvertTypeToString(type) << "& c) ";
+ GenBrace(stream, 0, [&]() {
+ stream << Tab(1) << "int l = 0;" << NLine(1);
+ stream << Tab(1)
+ << "rpc_port_parcel_read_array_count(h, &l);" << NLine(1);
+ stream << Tab(1) << "for (int i = 0; i < l; i++) ";
+ GenBrace(stream, TAB_SIZE, [&]() {
+ if (type.GetMetaType() != nullptr) {
+ auto& mt = *type.GetMetaType();
+ stream << AddIndent(TAB_SIZE * 2,
+ ConvertTypeToDeserializer(mt, "v", "h", true));
+ stream << Tab(2) << "c.push_back(std::move(v));" << NLine(1);
+ }
+ }, false);
+ stream << Tab(1) << "return h;" << NLine(1);
+ }, false);
+}
+
+void CppCionGeneratorBase::GenListSerializer(std::ofstream& stream, bool proto) {
+ serializer_list_.clear();
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() == Block::TYPE_STRUCTURE) {
+ const Structure& st = static_cast<const Structure&>(*i);
+ for (const auto& j : st.GetElements()) {
+ auto& t = j->GetType();
+ AddSerializerList(t);
+ }
+ } else if (i->GetType() == Block::TYPE_INTERFACE) {
+ const Interface& iface = static_cast<const Interface&>(*i);
+ for (const auto& j : iface.GetDeclarations()) {
+ auto& t = j->GetType();
+ AddSerializerList(t);
+ for (const auto& k : j->GetParameters()) {
+ auto& t1 = k->GetParameterType().GetBaseType();
+ AddSerializerList(t1);
+ }
+ }
+ }
+ }
+
+ for (auto& p : serializer_list_) {
+ const BaseType* t = p.second;
+ GenListSerializer(stream, *t, proto);
+ }
+}
+
+void CppCionGeneratorBase::GenMethodId(std::ofstream& stream,
+ const Interface& iface, bool is_group) {
+ stream << Tab(1) << "enum class MethodId : int ";
+ GenBrace(stream, TAB_SIZE, [&]() {
+ int cnt = 0;
+ if (!is_group) {
+ cnt = 2;
+ stream << Tab(2) << "__Result = 0," << NLine(1);
+ stream << Tab(2) << "__Callback = 1," << NLine(1);
+ }
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+ stream << Tab(2)
+ << i->GetID() << " = " << cnt++ << "," << NLine(1);
+ }
+ }, false, false);
+ stream << ";" << NLine(2);
+}
+
+void CppCionGeneratorBase::GenDelegateId(std::ofstream& stream,
+ const Interface& iface) {
+ stream << Tab(1) << "enum class DelegateId : int ";
+ GenBrace(stream, TAB_SIZE, [&]() {
+ int cnt = 1;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+ stream << Tab(2)
+ << i->GetID() << " = " << cnt++ << "," << NLine(1);
+ }
+ }, false, false);
+ stream << ";" << NLine(2);
+}
+
+void CppCionGeneratorBase::GenParameters(std::ofstream& stream,
+ const Parameters& ps) {
+ stream << GetParameters(ps);
+}
+
+std::string CppCionGeneratorBase::GetParameters(const Parameters& ps) {
+ bool first = true;
+ std::string ret;
+ for (const auto& i : ps) {
+ if (!first) {
+ ret += ", ";
+ }
+
+ std::string ref;
+ auto dir = i->GetParameterType().GetDirection();
+ if (dir == ParameterType::Direction::OUT ||
+ dir == ParameterType::Direction::REF) {
+ ref = "&";
+ }
+
+ ret += ConvertTypeToString(i->GetParameterType().GetBaseType())
+ + ref + " " + i->GetID();
+ first = false;
+ }
+
+ return ret;
+}
+
+void CppCionGeneratorBase::GenDeclaration(std::ofstream& stream,
+ const Interface& iface,
+ const Declaration& decl) {
+ stream << ConvertTypeToString(decl.GetType()) << " " << iface.GetID() << "::"
+ << decl.GetID() << "(";
+ GenParameters(stream, decl.GetParameters());
+ stream << ") ";
+}
+
+std::string CppCionGeneratorBase::GenPrivateSharingRequest(const BaseType& type,
+ std::string id) {
+ std::string ret;
+ if (type.GetMetaType() != nullptr && (type.GetMetaType()->GetFullName() == "file")) {
+ ret += std::string("for (const auto& i : " + id + ") {\n")
+ + std::string(" std::string name = i.GetFileName();\n")
+ + std::string(" FilePayloadSend(name, service_.lock()->GetPeer());\n")
+ + std::string("}\n");
+ } else if (type.ToString() == "file") {
+ ret += std::string("std::string name = " + id + ".GetFileName();\n")
+ + std::string("FilePayloadSend(name, service_.lock()->GetPeer());\n");
+ }
+ return ret;
+}
+
+std::string CppCionGeneratorBase::ConvertTypeToSerializer(
+ const BaseType& type, std::string id, std::string parcel) {
+ std::string ret;
+
+ if (type.ToString() == "string") {
+ ret += "rpc_port_parcel_write_"
+ + parcel_type_map_[type.ToString()]
+ + "(" + parcel + ", " + id + ".c_str());\n";
+ } else if (type.ToString() == "file") {
+ ret += "rpc_port_parcel_write_"
+ + parcel_type_map_[type.ToString()]
+ + "(" + parcel + ", " + id + ".GetFileName()" + ".c_str());\n";
+ } else if (type.ToString() == "bundle") {
+ ret += "rpc_port_parcel_write_bundle(" + parcel + ", "
+ + id + ".GetHandle());\n";
+ } else if (type.GetMetaType() || type.IsUserDefinedType()) {
+ if (type.IsUserDefinedType() && IsDelegateType(type))
+ ret += parcel + " << *" + id + ";\n";
+ else
+ ret += parcel + " << " + id + ";\n";
+ } else {
+ ret += "rpc_port_parcel_write_"
+ + parcel_type_map_[type.ToString()]
+ + "(" + parcel + ", " + id + ");\n";
+ }
+
+ return ret;
+}
+
+std::string CppCionGeneratorBase::ConvertTypeToDeserializer(
+ const BaseType& type, std::string id, std::string parcel,
+ bool make_new_type) {
+ std::string ret;
+
+ if (type.ToString() == "string") {
+ ret += "char* " + id + "_raw = nullptr;\n";
+ ret += "rpc_port_parcel_read_" + parcel_type_map_[type.ToString()]
+ + "(" + parcel + ", &" + id + "_raw);\n";
+ if (make_new_type) {
+ ret += "std::string " + id + "(" + id + "_raw);\n";
+ } else {
+ ret += id + " = " + id + "_raw;\n";
+ }
+ ret += "free(" + id + "_raw);\n";
+ } else if (type.ToString() == "file") {
+ ret += "char* " + id + "_raw = nullptr;\n";
+ ret += "rpc_port_parcel_read_" + parcel_type_map_[type.ToString()]
+ + "(" + parcel + ", &" + id + "_raw);\n";
+ if (make_new_type) {
+ ret += "File " + id + "(" + id + "_raw);\n";
+ } else {
+ ret += id + " = " + id + "_raw;\n"
+ + "free(" + id + "_raw);\n";
+ }
+ } else if (type.ToString() == "bundle") {
+ ret += "bundle* " + id + "_raw = nullptr;\n";
+ ret += "rpc_port_parcel_read_" + parcel_type_map_[type.ToString()]
+ + "(" + parcel + ", &" + id + "_raw);\n";
+ if (make_new_type) {
+ ret += "Bundle " + id + "(" + id + "_raw);\n";
+ } else {
+ ret += id + " = " + id + "_raw;\n";
+ }
+ } else if (type.GetMetaType() != nullptr || type.IsUserDefinedType()) {
+ std::string n;
+
+ if (type.GetMetaType() != nullptr || IsDelegateType(type))
+ n = ConvertTypeToString(type);
+ else
+ n = type.ToString();
+
+ if (make_new_type) {
+ ret += n + " ";
+ if (IsDelegateType(type)) {
+ ret += id + "(new " + type.ToString()
+ + "(std::weak_ptr<ServiceBase>(b), stub->server_));\n";
+ } else {
+ ret += id + ";\n";
+ }
+ }
+ if (IsDelegateType(type))
+ ret += parcel + " >> *" + id + ";\n";
+ else
+ ret += parcel + " >> " + id + ";\n";
+ } else {
+ if (make_new_type)
+ ret += ConvertTypeToString(type) + " " + id + ";\n";
+ ret += "rpc_port_parcel_read_" + parcel_type_map_[type.ToString()]
+ + "(" + parcel + ", &" + id + ");\n";
+ }
+
+ return ret;
+}
+
+void CppCionGeneratorBase::GenBodyCallbacks(std::ofstream& stream,
+ const Interface& iface, bool is_proxy) {
+ stream << ReplaceAll(CB_CALLBACK_BASE, "##", iface.GetID());
+
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+ GenBodyCallback(stream, iface, *i, is_proxy);
+ }
+}
+
+void CppCionGeneratorBase::GenBodyCallback(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl, bool is_proxy) {
+ if (!is_proxy) {
+ GenTemplate(std::string(ReplaceAll(CB_CALLBACK_FILE_PAYLOAD_SEND, {
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<FILE_PAYLOAD_SEND>", GetTransportable().Cpp()
+ .GenServerFileSend("path", "server_", "peer") },
+ { "<PAYLOAD_T>", GetTransportable().Cpp().GenPayloadType() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() }
+ })),
+ stream,
+ [&]()->std::string {
+ return iface.GetID();
+ },
+ [&]()->std::string {
+ return decl.GetID();
+ });
+ GenTemplate(std::string(ReplaceAll(CB_CALLBACK_INVOKE_METHOD, {
+ { "<PAYLOAD_T>", GetTransportable().Cpp().GenPayloadType() },
+ { "<SERVER_SEND_ASYNC>", GetTransportable().Cpp()
+ .GenServerSendAsync("server_", "", "pl", "size") },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() }
+ })), stream,
+ [&]()->std::string {
+ return iface.GetID();
+ },
+ [&]()->std::string {
+ return decl.GetID();
+ },
+ [&]()->std::string {
+ return GetParameters(decl.GetParameters());
+ },
+ [&]()->std::string {
+ std::string m;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ m += AddIndent(TAB_SIZE,
+ GenPrivateSharingRequest(pt.GetBaseType(), i->GetID()));
+ m += AddIndent(TAB_SIZE,
+ ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p"));
+ }
+ return m;
+ });
+ } else {
+ GenTemplate(CB_CALLBACK_ON_RECEIVED_EVENT_METHOD, stream,
+ [&]()->std::string {
+ return iface.GetID();
+ },
+ [&]()->std::string {
+ return decl.GetID();
+ },
+ [&]()->std::string {
+ int cnt = 1;
+ std::string ret;
+ for (const auto& i : decl.GetParameters()) {
+ std::string v = "param" + std::to_string(cnt);
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, "parcel");
+ ret += AddIndent(TAB_SIZE, c) + NLine(1);
+ cnt++;
+ }
+
+ cnt = 1;
+ ret += Tab(1) + "OnReceived(";
+ for (auto i = decl.GetParameters().begin();
+ i != decl.GetParameters().end(); ++i) {
+ if (cnt != 1) {
+ ret += ", ";
+ }
+ ret += "std::move(param" + std::to_string(cnt) + ")";
+ cnt++;
+ }
+ ret += ");";
+
+ return ret;
+ });
+ }
+}
+
+void CppCionGeneratorBase::GenHeaderCallbacks(std::ofstream& stream,
+ const Interface& iface,
+ bool is_proxy) {
+ stream << CB_CALLBACK_BASE_HEADER_FRONT;
+ if (is_proxy) {
+ stream << Tab(1)
+ << " virtual void OnReceivedEvent(rpc_port_parcel_h port) = 0;;"
+ << NLine(1);
+ }
+ stream << CB_CALLBACK_BASE_HEADER_BACK;
+
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+ GenHeaderCallback(stream, *i, is_proxy);
+ }
+}
+
+void CppCionGeneratorBase::GenHeaderCallback(std::ofstream& stream,
+ const Declaration& decl,
+ bool is_proxy) {
+ ReplaceAll(CB_CALLBACK_CLASS)
+ .Select("<CTOR>",
+ { CB_CALLBACK_CTOR_PROXY, CB_CALLBACK_CTOR_STUB }, [&]() {
+ if (is_proxy)
+ return 0;
+ return 1;
+ })
+ .Change("<CLS_NAME>", decl.GetID())
+ .Change("<PUBLIC_MEMBERS>", [&]() {
+ std::string ret;
+ if (is_proxy) {
+ ret = Tab(2) + "virtual void OnReceived("
+ + GetParameters(decl.GetParameters())
+ + ") {}" + NLine(1);
+ } else {
+ ret = Tab(2) + "void Invoke("
+ + GetParameters(decl.GetParameters())
+ + ");" + NLine(1);
+ }
+
+ return ret;
+ })
+ .Change("<PRIVATE_MEMBERS>", [&]() {
+ return is_proxy ? CB_CALLBACK_PRIVATE_PROXY : CB_CALLBACK_PRIVATE_STUB;
+ })
+ .Change("<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType())
+ .Change("<SERVER_T>", GetTransportable().Cpp().GenServerType())
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+std::string CppCionGeneratorBase::GenSecurity(const Interface& iface) {
+ std::string security_path;
+
+ for (const auto& attr : iface.GetAttributes()) {
+ if (attr->GetKey() == "ca_path")
+ security_path +=
+ GetTransportable().Cpp().GenSetSecurityCA(attr->GetValue());
+ else if (attr->GetKey() == "cert_path")
+ security_path +=
+ GetTransportable().Cpp().GenSetSecurityCert(attr->GetValue());
+ else if (attr->GetKey() == "private_key")
+ security_path +=
+ GetTransportable().Cpp().GenSetSecurityPrivateKey(attr->GetValue());
+ }
+
+ return security_path;
+}
+
+std::string CppCionGeneratorBase::GetMoudlePrefix() {
+ std::string prefix = GetTransportable().Cpp().GenModulePrefix();
+
+ if (!HasNamespace() || !IsGeneratedAPI())
+ return prefix;
+
+ return prefix + "_" + GetFileNamespace();
+}
+
+std::string CppCionGeneratorBase::GetInternalHandlePrefix() {
+ std::string prefix = GetHandlePrefix();
+
+ if (!HasNamespace())
+ return prefix;
+
+ return prefix + "_internal";
+}
+
+std::string CppCionGeneratorBase::GetHandlePrefix() {
+ std::string prefix;
+ switch(GetChannelType()) {
+ case ChannelType::TYPE_STUB:
+ prefix = GetTransportable().Cpp().GenStubPrefix();
+ break;
+ case ChannelType::TYPE_PROXY:
+ prefix = GetTransportable().Cpp().GenProxyPrefix();
+ break;
+ case ChannelType::TYPE_GROUP:
+ prefix = GetTransportable().Cpp().GenGroupPrefix();
+ break;
+ default:
+ break;
+ }
+
+ if (!HasNamespace())
+ return prefix;
+
+ return prefix + "_" + GetFileNamespace();
+}
+
+void CppCionGeneratorBase::GenVersion(std::ofstream& stream) {
+ GenTemplate(CB_VERSION, stream,
+ [&]()->std::string {
+ return FULLVER;
+ });
+}
+
+void CppCionGeneratorBase::GenLogTag(std::ofstream& stream, std::string id) {
+ std::string tag = std::move(id);
+ std::transform(tag.begin(), tag.end(), tag.begin(), ::toupper);
+ std::string code(ReplaceAll(CB_LOG_TAG, "<LOG_TAG>", tag));
+ stream << code;
+}
+
+void CppCionGeneratorBase::GenLogDefinition(std::ofstream& stream) {
+ stream << CB_LOG_DEF;
+}
+
+void CppCionGeneratorBase::GenCommonBase(std::ofstream& stream) {
+ ReplaceAll(GetTransportable().Cpp().GenHeaderBase())
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CppCionGeneratorBase::GenCommonHandles(std::ofstream& stream) {
+ ReplaceAll(GetTransportable().Cpp().GenHeaderCommonHandle())
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CppCionGeneratorBase::GenClientHandles(std::ofstream& stream) {
+ ReplaceAll(GetTransportable().Cpp().GenHeaderClientHandle())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CppCionGeneratorBase::GenServerHandles(std::ofstream& stream) {
+ ReplaceAll(GetTransportable().Cpp().GenHeaderServerHandle())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CppCionGeneratorBase::GenGroupHandles(std::ofstream& stream) {
+ ReplaceAll(GetTransportable().Cpp().GenHeaderGroupHandle())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CppCionGeneratorBase::GenFileHandle(std::ofstream& stream) {
+ ReplaceAll(GetTransportable().Cpp().GenHeaderPayloadHandle())
+ .Change("<ERROR_PREFIX>", GetTransportable().C().GenErrorPrefix())
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CppCionGeneratorBase::GenFileBase(std::ofstream& stream) {
+ ReplaceAll(GetTransportable().Cpp().GenHeaderPayloadBase())
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CppCionGeneratorBase::GenConnectionHandle(std::ofstream& stream) {
+ ReplaceAll(GetTransportable().Cpp().GenHeaderConnectionHandle())
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CppCionGeneratorBase::GenConnectionBase(std::ofstream& stream) {
+ ReplaceAll(GetTransportable().Cpp().GenHeaderConnectionBase())
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CppCionGeneratorBase::GenCommonFunctions(std::ofstream& stream) {
+ std::string code = GetTransportable().Cpp().GenBodyPeerInfoBase();
+ if(GetChannelType() != ChannelType::TYPE_GROUP) {
+ code += GetTransportable().Cpp().GenBodyConnectionBase();
+ code += GetTransportable().Cpp().GenBodyPayloadBase();
+ }
+
+ ReplaceAll(code,"<PREFIX>", GetHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Change("<INTERNAL_PREFIX>", GetInternalHandlePrefix())
+ .Out(stream);
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/cpp_cion_gen_base.h b/idlc/gen_cion/cpp_cion_gen_base.h
new file mode 100644
index 0000000..d7ba76b
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_gen_base.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_CION_GEN_CPP_GEN_BASE_H_
+#define IDLC_CPP_CION_GEN_CPP_GEN_BASE_H_
+
+#include <memory>
+#include <string>
+#include <map>
+
+#include "idlc/ast/type.h"
+#include "idlc/ast/structure.h"
+#include "idlc/gen_cion/cion_plugin_base.h"
+
+namespace tidl {
+
+class CppCionGeneratorBase : public CionPluginBase {
+ public:
+ explicit CppCionGeneratorBase(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CppCionGeneratorBase() = default;
+
+ void GenVersion(std::ofstream& stream);
+ void GenStructuresForHeader(std::ofstream& stream, bool is_group = false);
+ void GenStructuresForBody(std::ofstream& stream);
+ void GenSerializer(std::ofstream& stream);
+ void GenDeSerializer(std::ofstream& stream);
+ void GenListSerializer(std::ofstream& stream, bool proto = false);
+ void GenPrototype(std::ofstream& stream);
+ void GenMethodId(std::ofstream& stream, const Interface& iface,
+ bool is_group = false);
+ void GenDelegateId(std::ofstream& stream, const Interface& iface);
+ void GenParameters(std::ofstream& stream, const Parameters& ps);
+ void GenDeclaration(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+ void GenBodyCallbacks(std::ofstream& stream, const Interface& iface,
+ bool is_proxy);
+ void GenHeaderCallbacks(std::ofstream& stream, const Interface& iface,
+ bool is_proxy);
+ std::string GenSecurity(const Interface& iface);
+ std::string ConvertTypeToString(const BaseType& type);
+ std::string Tab(int cnt);
+ std::string NLine(int cnt);
+ std::string ConvertTypeToDeserializer(const BaseType& type,
+ std::string id, std::string parcel,
+ bool make_new_type = true);
+ std::string ConvertTypeToSerializer(const BaseType& type,
+ std::string id, std::string parcel);
+ std::string GenPrivateSharingRequest(const BaseType& type, std::string id);
+ std::string GetParameters(const Parameters& ps);
+ void GenLogTag(std::ofstream& stream, std::string id);
+ void GenLogDefinition(std::ofstream& stream);
+ std::string GetMoudlePrefix();
+ std::string GetHandlePrefix();
+ std::string GetInternalHandlePrefix();
+
+ void GenCommonBase(std::ofstream& stream);
+ void GenCommonHandles(std::ofstream& stream);
+ void GenClientHandles(std::ofstream& stream);
+ void GenServerHandles(std::ofstream& stream);
+ void GenGroupHandles(std::ofstream& stream);
+ void GenFileHandle(std::ofstream& stream);
+ void GenFileBase(std::ofstream& stream);
+ void GenConnectionHandle(std::ofstream& stream);
+ void GenConnectionBase(std::ofstream& stream);
+ void GenCommonFunctions(std::ofstream& stream);
+
+ private:
+ void GenSetter(std::ofstream& stream, const Element& ele);
+ void GenGetter(std::ofstream& stream, const Element& ele);
+ void AddSerializerList(const BaseType& type);
+ void GenListSerializer(std::ofstream& stream, const BaseType& type,
+ bool proto = false);
+ void GenDeSerializer(std::ofstream& stream, const Structure& st,
+ bool proto = false);
+ void GenSerializer(std::ofstream& stream, const Structure& st,
+ bool proto = false);
+ void GenStructureForHeader(std::ofstream& stream, const Structure& st);
+ void GenStructureForBody(std::ofstream& stream, const Structure& st);
+ void GenBodyCallback(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl, bool is_proxy);
+ void GenHeaderCallback(std::ofstream& stream, const Declaration& decl,
+ bool is_proxy);
+
+ protected:
+ const int TAB_SIZE = 2;
+
+ private:
+ std::map<std::string, std::string> type_map_;
+ std::map<std::string, std::string> parcel_type_map_;
+ std::map<std::string, std::string> type_init_map_;
+ std::map<std::string, const BaseType*> serializer_list_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_CPP_CION_GEN_CPP_GEN_BASE_H_
diff --git a/idlc/gen_cion/cpp_cion_gen_base_cb.h b/idlc/gen_cion/cpp_cion_gen_base_cb.h
new file mode 100644
index 0000000..e5858f6
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_gen_base_cb.h
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_CION_GEN_CPP_GEN_BASE_CB_H_
+#define IDLC_CPP_CION_GEN_CPP_GEN_BASE_CB_H_
+
+const char CB_BUNDLE[] = R"__cls_bundle(class Bundle final {
+ public:
+ Bundle() {
+ raw_ = bundle_create();
+ }
+
+ Bundle(bundle* b) {
+ raw_ = b;
+ }
+
+ ~Bundle() {
+ if (raw_)
+ bundle_free(raw_);
+ }
+
+ Bundle(Bundle&& b) : raw_(b.raw_) {
+ b.raw_ = nullptr;
+ }
+
+ Bundle& operator = (Bundle&& b) {
+ if (this != &b) {
+ if (raw_)
+ bundle_free(raw_);
+
+ raw_ = b.raw_;
+ b.raw_ = nullptr;
+ }
+ return *this;
+ }
+
+ Bundle(const Bundle& b) : raw_(bundle_dup(b.GetHandle())) {}
+
+ Bundle& operator = (const Bundle& b) {
+ if (this != &b) {
+ if (raw_)
+ bundle_free(raw_);
+
+ raw_ = bundle_dup(b.GetHandle());
+ }
+ return *this;
+ }
+
+ bundle* GetHandle() const {
+ return raw_;
+ }
+
+ private:
+ bundle* raw_;
+};
+
+)__cls_bundle";
+
+const char CB_FILE[] = R"__cls_file(class File final {
+ public:
+ File() {
+ }
+
+ File(std::string filename) {
+ filename_ = filename;
+ }
+
+ std::string GetFileName() const {
+ return filename_;
+ }
+
+ private:
+ std::string filename_;
+};
+
+)__cls_file";
+
+const char CB_CALLBACK_BASE[] =
+R"__cpp_cb(
+std::atomic<int> ##::CallbackBase::seq_num_ { 0 };
+
+##::CallbackBase::CallbackBase(int delegate_id, bool once)
+ : id_(delegate_id), once_(once) {
+ seq_id_ = seq_num_++;
+}
+
+int ##::CallbackBase::GetId() const {
+ return id_;
+}
+
+int ##::CallbackBase::GetSeqId() const {
+ return seq_id_;
+}
+
+bool ##::CallbackBase::IsOnce() const {
+ return once_;
+}
+
+std::string ##::CallbackBase::GetTag() const {
+ return std::to_string(id_) + "::" + std::to_string(seq_id_);
+}
+
+rpc_port_parcel_h operator << (rpc_port_parcel_h h, const ##::CallbackBase& cb) {
+ rpc_port_parcel_write_int32(h, cb.id_);
+ rpc_port_parcel_write_int32(h, cb.seq_id_);
+ rpc_port_parcel_write_bool(h, cb.once_);
+
+ return h;
+}
+
+rpc_port_parcel_h operator >> (rpc_port_parcel_h h, ##::CallbackBase& cb) {
+ rpc_port_parcel_read_int32(h, &cb.id_);
+ rpc_port_parcel_read_int32(h, &cb.seq_id_);
+ rpc_port_parcel_read_bool(h, &cb.once_);
+
+ return h;
+}
+)__cpp_cb";
+
+const char CB_VERSION[] =
+R"__cpp_cb(/*
+ * Generated by tidlc $$.
+ */
+)__cpp_cb";
+
+const char CB_CALLBACK_BASE_HEADER_FRONT[] =
+R"__cpp_cb(
+ class CallbackBase {
+ public:
+ CallbackBase(int delegate_id, bool once);
+ virtual ~CallbackBase() = default;
+)__cpp_cb";
+
+const char CB_CALLBACK_BASE_HEADER_BACK[] =
+R"__cpp_cb(
+ int GetId() const;
+ int GetSeqId() const;
+ bool IsOnce() const;
+ std::string GetTag() const;
+
+ private:
+ friend rpc_port_parcel_h operator << (rpc_port_parcel_h h, const CallbackBase& cb);
+ friend rpc_port_parcel_h operator >> (rpc_port_parcel_h h, CallbackBase& cb);
+
+ static std::atomic<int> seq_num_;
+ int id_;
+ int seq_id_;
+ bool once_;
+ };
+)__cpp_cb";
+
+const char CB_CALLBACK_CLASS[] =
+R"__cpp_cb(
+ class <CLS_NAME> : public CallbackBase {
+ public:<CTOR>
+<PUBLIC_MEMBERS>
+ private:<PRIVATE_MEMBERS>
+ };
+)__cpp_cb";
+
+const char CB_CALLBACK_CTOR_STUB[] =
+R"__cpp_cb(
+ <CLS_NAME>(std::weak_ptr<ServiceBase> service, <SERVER_T> <PREFIX>_server)
+ : CallbackBase(static_cast<int>(DelegateId::<CLS_NAME>), false) {
+ service_ = std::move(service);
+ server_ = <PREFIX>_server;
+ }
+)__cpp_cb";
+
+const char CB_CALLBACK_CTOR_PROXY[] =
+R"__cpp_cb(
+ <CLS_NAME>(bool once = false)
+ : CallbackBase(static_cast<int>(DelegateId::<CLS_NAME>), once) {}
+)__cpp_cb";
+
+const char CB_CALLBACK_PRIVATE_PROXY[] =
+R"__cpp_cb(
+ void OnReceivedEvent(rpc_port_parcel_h parcel) override;
+)__cpp_cb";
+
+const char CB_CALLBACK_PRIVATE_STUB[] =
+R"__cpp_cb(
+ void FilePayloadSend(std::string path, <PEER_INFO_T> peer);
+
+ std::weak_ptr<ServiceBase> service_;
+ bool valid_ = true;
+ <SERVER_T> server_;
+)__cpp_cb";
+
+const char CB_CALLBACK_FILE_PAYLOAD_SEND[] = R"__cpp_cb(
+void $$::$$::FilePayloadSend(std::string path, <PEER_INFO_T> peer)
+{
+ <FILE_PAYLOAD_SEND>
+}
+)__cpp_cb";
+
+const char CB_CALLBACK_INVOKE_METHOD[] =
+R"__cpp_cb(
+void $$::$$::Invoke($$) {
+ if (service_.lock().get() == nullptr)
+ throw NotConnectedSocketException();
+
+ if (IsOnce() && !valid_)
+ throw InvalidCallbackException();
+
+ rpc_port_parcel_h p;
+ rpc_port_parcel_create(&p);
+ rpc_port_parcel_write_int32(p, static_cast<int>(MethodId::__Callback));
+ p << *this;
+$$
+ // Send
+ unsigned int size;
+ char *data;
+
+ int ret_ = rpc_port_parcel_get_raw(p, (void **)&data, &size);
+ if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get raw. error(%d)", ret_);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
+
+ <PAYLOAD_T> pl;
+ <SERVER_SEND_ASYNC>
+ rpc_port_parcel_destroy(p);
+ valid_ = false;
+}
+)__cpp_cb";
+
+const char CB_CALLBACK_ON_RECEIVED_EVENT_METHOD[] =
+R"__cpp_cb(
+void $$::$$::OnReceivedEvent(rpc_port_parcel_h parcel) {
+$$
+}
+)__cpp_cb";
+
+const char CB_LOG_TAG[] =
+R"__cpp_cb(
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "<LOG_TAG>"
+)__cpp_cb";
+
+const char CB_LOG_DEF[] =
+R"__cpp_cb(
+#ifdef _E
+#undef _E
+#endif
+
+#ifdef _W
+#undef _W
+#endif
+
+#ifdef _I
+#undef _I
+#endif
+
+#ifdef _D
+#undef _D
+#endif
+
+#define _E(fmt, ...) dlog_print(DLOG_ERROR, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+)__cpp_cb";
+
+#endif // IDLC_CPP_CION_GEN_CPP_GEN_BASE_CB_H_
diff --git a/idlc/gen_cion/cpp_cion_group_body_gen.cc b/idlc/gen_cion/cpp_cion_group_body_gen.cc
new file mode 100644
index 0000000..08bb172
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_group_body_gen.cc
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/cpp_cion_group_body_gen.h"
+
+namespace {
+#include "idlc/gen_cion/cpp_cion_group_body_gen_cb.h"
+}
+
+namespace tidl {
+
+CppCionGroupBodyGen::CppCionGroupBodyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans)
+ : CppCionGeneratorBase(doc, trans) {}
+
+void CppCionGroupBodyGen::OnInitGen(std::ofstream& stream) {
+ std::string key(".cc");
+ std::string header_file = FileName;
+
+ std::size_t found = header_file.rfind(key);
+ if (found != std::string::npos)
+ header_file.replace(found, key.length(), ".h");
+
+ GenVersion(stream);
+ stream << NLine(1);
+ stream << "#include <stdlib.h>" << NLine(1)
+ << "#include <assert.h>" << NLine(1)
+ << "#include <dlog.h>" << NLine(1)
+ << NLine(1)
+ << ReplaceAll(GetTransportable().Cpp().GenInclude(
+ static_cast<int>(GetChannelType())),
+ "<FILENAME>", GetFileNamespace())
+ << NLine(2)
+ << "#include \"" << header_file << "\"" << NLine(2);
+ GenLogTag(stream, GetTransportable().Cpp().GenGroupPrefix());
+ GenLogDefinition(stream);
+ stream << NLine(1);
+ GenCommonFunctions(stream);
+ stream << NLine(1);
+
+ GenNamespace(stream);
+}
+
+void CppCionGroupBodyGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void CppCionGroupBodyGen::GenNamespace(std::ofstream& stream) {
+ stream << "namespace " << GetTransportable().Cpp().GenNamespace() << " ";
+ GenBrace(stream, 0, [&]() {
+ stream << "namespace " << GetFileNamespace() << " ";
+ GenBrace(stream, 0, [&]() {
+ stream << NLine(1);
+ GenStructuresForBody(stream);
+ stream << "namespace group ";
+ GenBrace(stream, 0, [&]() {
+ GenPrototype(stream);
+ GenSerializer(stream);
+ GenDeSerializer(stream);
+ GenListSerializer(stream);
+ GenInterfaces(stream);
+ }, false, false);
+ stream << " // namespace group" + NLine(1);
+ }, false, false);
+ stream << " // namespace " + GetFileNamespace() + NLine(1);
+ }, false, false);
+ stream << " // namespace " + GetTransportable().Cpp().GenNamespace() + NLine(1);
+}
+
+void CppCionGroupBodyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CppCionGroupBodyGen::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ GenConstructor(stream, iface);
+ GenDestructor(stream, iface);
+ GenMethods(stream, iface);
+ GenCionPayloadReceivedEvent(stream, iface);
+}
+
+void CppCionGroupBodyGen::GenConstructor(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_GROUP_INTERFACE_CTOR)
+ .Change("<GROUP_CREATE>", GetTransportable().Cpp().GenGroupCreate())
+ .Change("<CLS_NAME>", iface.GetID())
+ .Change("<SET_SECURITY>", GenSecurity(iface))
+ .Change("<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType())
+ .Change("<PAYLOAD_T>", GetTransportable().Cpp().GenPayloadType())
+ .Change("<SECURITY_T>", GetTransportable().Cpp().GenSecurityType(false))
+ .Change("<GROUP_T>", GetTransportable().Cpp().GenGroupType())
+ .Change("<INTERNAL_PREFIX>", GetInternalHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CppCionGroupBodyGen::GenDestructor(std::ofstream& stream,
+ const Interface& iface) {
+ stream << ReplaceAll(CB_DTOR, {
+ { "<CLS_NAME>", iface.GetID() },
+ { "<GROUP_DESTROY>", GetTransportable().Cpp().GenGroupDestroy() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() }
+ }) << NLine(1);
+}
+
+void CppCionGroupBodyGen::GenCionPayloadReceivedEvent(std::ofstream& stream,
+ const Interface& iface) {
+ stream << ReplaceAll(CB_GROUP_ON_PAYLOAD_RECEIVED_CB_FRONT, {
+ { "<CLS_NAME>", iface.GetID() },
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<PAYLOAD_T>", GetTransportable().Cpp().GenPayloadType() },
+ { "<PAYLOAD_TYPE_E>", GetTransportable().Cpp().GenPayloadTypeEnum() },
+ { "<PAYLOAD_GET_TYPE>",
+ GetTransportable().Cpp().GenPayloadGetType() },
+ { "<ERROR_NONE>", GetTransportable().Cpp().GenErrorNone() },
+ { "<PAYLOAD_TYPE_DATA>",
+ GetTransportable().Cpp().GenPayloadTypeData() },
+ { "<PAYLOAD_GET_DATA>", GetTransportable().Cpp().GenPayloadGetData() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix()},
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix()}
+ });
+
+ for (const auto& i : iface.GetDeclarations()) {
+ stream << Tab(2) << "case static_cast<int>(MethodId::"
+ << i->GetID() << "): ";
+ GenBrace(stream, TAB_SIZE * 2, [&]() {
+ GenHandlerInvocation(stream, *i);
+ stream << Tab(3) << "break;" << NLine(1);
+ }, false);
+ }
+
+ stream << CB_GROUP_ON_PAYLOAD_RECEIVED_CB_BACK << NLine(1);
+}
+
+void CppCionGroupBodyGen::GenHandlerInvocation(std::ofstream& stream,
+ const Declaration& decl) {
+ int cnt = 1;
+ // Deserialize
+ for (const auto& i : decl.GetParameters()) {
+ std::string v = "param" + std::to_string(cnt);
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, "parcel_received");
+ stream << AddIndent(TAB_SIZE * 3, c);
+ cnt++;
+ }
+
+ // Invoke
+ std::string m;
+ m += "On" + decl.GetID() + "(peer_info";
+ cnt = 1;
+ for (auto i = decl.GetParameters().begin();
+ i != decl.GetParameters().end(); ++i) {
+ m += ", ";
+ m += "param" + std::to_string(cnt++);
+ }
+
+ m += ");\n";
+ stream << AddIndent(TAB_SIZE * 3, m);
+}
+
+void CppCionGroupBodyGen::GenMethods(std::ofstream& stream,
+ const Interface& iface) {
+ auto& decls = iface.GetDeclarations();
+
+ for (const auto& i : decls) {
+ GenDeclaration(stream, iface, *i);
+ GenBrace(stream, 0, [&]() {
+ GenInvocation(stream, *i);
+ }, false);
+ stream << NLine(1);
+ }
+}
+
+void CppCionGroupBodyGen::GenInvocation(std::ofstream& stream,
+ const Declaration& decl) {
+ stream << CB_INVOCATION_PRE;
+
+ // Serialize
+ stream << Tab(1)
+ << "rpc_port_parcel_write_int32(p, static_cast<int>(MethodId::"
+ << decl.GetID() << "));" << NLine(1);
+ std::string m;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p");
+ }
+ stream << AddIndent(TAB_SIZE, m) << NLine(1);
+
+ stream << Tab(1) << "do ";
+ GenBrace(stream, TAB_SIZE, [&]() {
+ stream << Tab(2) << "std::lock_guard<std::recursive_mutex> lock(mutex_);"
+ << NLine(2);
+ stream << ReplaceAll(CB_INVOCATION_ASYNC_MID, {
+ { "<PAYLOAD_T>", GetTransportable().Cpp().GenPayloadType() },
+ { "<GROUP_PUBLISH>", GetTransportable().Cpp().GenGroupPublish() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() }
+ }) << NLine(1);
+ }, false, false);
+ stream << " while (false);" << NLine(1);
+
+ stream << Tab(1) << "rpc_port_parcel_destroy(p);"
+ << NLine(1);
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/cpp_cion_group_body_gen.h b/idlc/gen_cion/cpp_cion_group_body_gen.h
new file mode 100644
index 0000000..a1a5a8c
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_group_body_gen.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_CION_GEN_CPP_GROUP_BODY_GEN_H_
+#define IDLC_CPP_CION_GEN_CPP_GROUP_BODY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/cpp_cion_gen_base.h"
+
+namespace tidl {
+
+class CppCionGroupBodyGen : public CppCionGeneratorBase {
+ public:
+ explicit CppCionGroupBodyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CppCionGroupBodyGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ void GenStructures(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenConstructor(std::ofstream& stream, const Interface& iface);
+ void GenDestructor(std::ofstream& stream, const Interface& iface);
+ void GenCionPayloadReceivedEvent(std::ofstream& stream,
+ const Interface& iface);
+ void GenMethods(std::ofstream& stream, const Interface& iface);
+ void GenInvocation(std::ofstream& stream, const Declaration& decl);
+ void GenHandlerInvocation(std::ofstream& stream, const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_CPP_CION_GEN_CPP_GROUP_BODY_GEN_H_
diff --git a/idlc/gen_cion/cpp_cion_group_body_gen_cb.h b/idlc/gen_cion/cpp_cion_group_body_gen_cb.h
new file mode 100644
index 0000000..b24b6c7
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_group_body_gen_cb.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_GEN_CION_CPP_GROUP_BODY_GEN_CB_H_
+#define IDLC_CPP_GEN_CION_CPP_GROUP_BODY_GEN_CB_H_
+
+const char CB_DTOR[] =
+R"__cpp_cb(
+<CLS_NAME>::~<CLS_NAME>() {
+ <GROUP_DESTROY>
+}
+)__cpp_cb";
+
+const char CB_INVOCATION_PRE[] =
+R"__cpp_cb( rpc_port_parcel_h p;
+ rpc_port_parcel_create(&p);
+)__cpp_cb";
+
+const char CB_INVOCATION_ASYNC_MID[] =
+R"__cpp_cb(
+ // Publish
+ unsigned int size;
+ char *data;
+
+ int ret = rpc_port_parcel_get_raw(p, (void **)&data, &size);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get raw. error(%d)", ret);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
+
+ <PAYLOAD_T> pl;
+ <GROUP_PUBLISH>
+)__cpp_cb";
+
+const char CB_GROUP_ON_PAYLOAD_RECEIVED_CB_FRONT[] =
+R"__cpp_cb(
+void <CLS_NAME>::OnPayloadReceivedCB(const <PEER_INFO_T> peer_info,
+ const <PAYLOAD_T> payload) {
+ <PAYLOAD_TYPE_E> type;
+ int ret;
+ <PAYLOAD_GET_TYPE>
+ if (ret != <ERROR_NONE>) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_get_type. error(%d)", ret);
+ return;
+ }
+
+ if (type != <PAYLOAD_TYPE_DATA>) {
+ _E("Wrong payload type, only data payload is available");
+ return;
+ }
+
+ unsigned char *data;
+ unsigned int size;
+ <PAYLOAD_GET_DATA>
+ if (ret != <ERROR_NONE>) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_get_data. error(%d)", ret);
+ return;
+ }
+
+ rpc_port_parcel_h parcel_received;
+ rpc_port_parcel_create_from_raw(&parcel_received, data, size);
+ free(data);
+
+ int cmd;
+ rpc_port_parcel_read_int32(parcel_received, &cmd);
+
+ switch (cmd) {
+)__cpp_cb";
+
+const char CB_GROUP_ON_PAYLOAD_RECEIVED_CB_BACK[] =
+R"__cpp_cb(
+ default:
+ _E("Unknown command(%d)", cmd);
+ }
+
+ rpc_port_parcel_destroy(parcel_received);
+}
+)__cpp_cb";
+
+const char CB_GROUP_INTERFACE_CTOR[] =
+R"__cpp_cb(
+<CLS_NAME>::<CLS_NAME>(std::string topic, const std::string broker_ip, int broker_port,
+ const std::string user_name, const std::string password, const std::string my_ip,
+ int protocols) : topic_name_(std::move(topic)) {
+ <GROUP_CREATE>
+}
+)__cpp_cb";
+
+#endif // IDLC_CPP_GEN_CION_CPP_GROUP_BODY_GEN_CB_H_
diff --git a/idlc/gen_cion/cpp_cion_group_header_gen.cc b/idlc/gen_cion/cpp_cion_group_header_gen.cc
new file mode 100644
index 0000000..189dae4
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_group_header_gen.cc
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/cpp_cion_group_header_gen.h"
+
+namespace {
+#include "idlc/gen_cion/cpp_cion_group_header_gen_cb.h"
+}
+
+namespace tidl {
+
+CppCionGroupHeaderGen::CppCionGroupHeaderGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : CppCionGeneratorBase(doc, trans) {}
+
+void CppCionGroupHeaderGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+
+ stream << CB_HEADER;
+
+ GenCommonHandles(stream);
+ GenGroupHandles(stream);
+ GenFileHandle(stream);
+ GenConnectionHandle(stream);
+ GenCommonBase(stream);
+ GenNamespace(stream);
+}
+
+void CppCionGroupHeaderGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void CppCionGroupHeaderGen::GenNamespace(std::ofstream& stream) {
+ stream << "namespace " << GetTransportable().Cpp().GenNamespace() << " ";
+ GenBrace(stream, 0, [&]() {
+ stream << "namespace " << GetFileNamespace() << " ";
+ GenBrace(stream, 0, [&]() {
+ stream << NLine(1);
+ GenStructuresForHeader(stream, true);
+ stream << "namespace group ";
+ GenBrace(stream, 0, [&]() {
+ GenExceptions(stream);
+ GenInterfaces(stream);
+ }, false, false);
+ stream << " // namespace group" + NLine(1);
+ }, false, false);
+ stream << " // namespace " + GetFileNamespace() + NLine(1);
+ }, false, false);
+ stream << " // namespace " + GetTransportable().Cpp().GenNamespace() + NLine(1);
+}
+
+void CppCionGroupHeaderGen::GenExceptions(std::ofstream& stream) {
+ stream << CB_EXCEPTIONS;
+}
+
+void CppCionGroupHeaderGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+ stream << NLine(1);
+}
+
+void CppCionGroupHeaderGen::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ stream << NLine(1) << "class " << iface.GetID() << " ";
+ GenBrace(stream, 0, [&]() {
+ stream << " public:" << NLine(1);
+ stream << ReplaceAll(CB_PUBLIC_MEMBERS, {
+ { "<CLS_NAME>", iface.GetID() },
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() }
+ })
+ << NLine(1);
+ GenMethods(stream, iface);
+ GenMethodHandlers(stream, iface);
+ stream << NLine(1) << " private:" << NLine(1);
+ GenMethodId(stream, iface, true);
+ stream << ReplaceAll(CB_PRIVATE_MEMBERS, {
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<PAYLOAD_T>", GetTransportable().Cpp().GenPayloadType() },
+ { "<GROUP_T>", GetTransportable().Cpp().GenGroupType() },
+ { "<SECURITY_T>", GetTransportable().Cpp().GenSecurityType() },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() }
+ });
+ }, false, false);
+ stream << ";" << NLine(1);
+}
+
+void CppCionGroupHeaderGen::GenMethods(std::ofstream& stream,
+ const Interface& iface) {
+ auto& decls = iface.GetDeclarations();
+
+ for (const auto& i : decls) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenDeclaration(stream, *i);
+ }
+}
+
+void CppCionGroupHeaderGen::GenMethodHandlers(std::ofstream& stream,
+ const Interface& iface) {
+ auto& decls = iface.GetDeclarations();
+
+ for (const auto& i : decls) {
+ stream << Tab(1) << "virtual " << ConvertTypeToString(i->GetType()) << " On"
+ << i->GetID() << ReplaceAll("(const <PEER_INFO_T> peer_info, ", {
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() }
+ });
+ GenParameters(stream, i->GetParameters());
+ stream << ") = 0;" << NLine(1);
+ }
+}
+
+void CppCionGroupHeaderGen::GenDeclaration(std::ofstream& stream,
+ const Declaration& decl) {
+ if (!decl.GetComments().empty())
+ stream << NLine(1) << AddIndent(TAB_SIZE, decl.GetComments());
+
+ stream << Tab(1) << ConvertTypeToString(decl.GetType()) << " "
+ << decl.GetID() << "(";
+ GenParameters(stream, decl.GetParameters());
+ stream << ");" << NLine(1);
+}
+} // namespace tidl
diff --git a/idlc/gen_cion/cpp_cion_group_header_gen.h b/idlc/gen_cion/cpp_cion_group_header_gen.h
new file mode 100644
index 0000000..e9d14f0
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_group_header_gen.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_CION_GEN_CPP_GROUP_HEADER_GEN_H_
+#define IDLC_CPP_CION_GEN_CPP_GROUP_HEADER_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/cpp_cion_gen_base.h"
+
+namespace tidl {
+
+class CppCionGroupHeaderGen : public CppCionGeneratorBase {
+ public:
+ explicit CppCionGroupHeaderGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CppCionGroupHeaderGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ void GenExceptions(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenMethods(std::ofstream& stream, const Interface& iface);
+ void GenMethodHandlers(std::ofstream& stream, const Interface& iface);
+ void GenDeclaration(std::ofstream& stream, const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_CPP_CION_GEN_CPP_GROUP_HEADER_GEN_H_
diff --git a/idlc/gen_cion/cpp_cion_group_header_gen_cb.h b/idlc/gen_cion/cpp_cion_group_header_gen_cb.h
new file mode 100644
index 0000000..a51d0fe
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_group_header_gen_cb.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_CION_GEN_CPP_GROUP_HEADER_GEN_CB_H_
+#define IDLC_CPP_CION_GEN_CPP_GROUP_HEADER_GEN_CB_H_
+
+const char CB_EXCEPTIONS[] =
+R"__cpp_cb(
+class Exception {};
+class NotConnectedSocketException : public Exception {};
+class InvalidProtocolException : public Exception {};
+class InvalidIOException : public Exception {};
+class UnauthorizedAccessException : public Exception {};
+)__cpp_cb";
+
+const char CB_PUBLIC_MEMBERS[] =
+R"__cpp_cb( /// <summary>
+ /// Constructor for this class
+ /// </summary>
+ /// <param name="topic_name">The topic name to subscribe</param>
+ /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <exception cref="UnauthorizedAccessException">
+ /// Thrown when an application does not have the privilege to access this method.
+ /// </exception>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ explicit <CLS_NAME>(std::string topic_name, const std::string broker_ip, int broker_port,
+ const std::string user_name, const std::string password, const std::string my_ip,
+ int protocols);
+
+ /// <summary>
+ /// Destructor for this class
+ /// </summary>
+ virtual ~<CLS_NAME>();
+
+ /// <summary>
+ /// This method will be invoked when the peer group app is joined to the topic.
+ /// </summary>
+ virtual void OnJoined(const <PEER_INFO_T> peer_info) = 0;
+
+ /// <summary>
+ /// This method will be invoked after the peer group app was left from the topic.
+ /// </summary>
+ virtual void OnLeft(const <PEER_INFO_T> peer_info) = 0;
+
+)__cpp_cb";
+
+const char CB_PRIVATE_MEMBERS[] =
+R"__cpp_cb( void OnPayloadReceivedCB(const <PEER_INFO_T> peer_info,
+ const <PAYLOAD_T> payload);
+ <GROUP_T> group_ = nullptr;
+ <SECURITY_T>
+ std::string topic_name_;
+ std::recursive_mutex mutex_;
+)__cpp_cb";
+
+const char CB_HEADER[] =
+R"__cpp_cb(
+#pragma once
+
+#include <rpc-port-parcel.h>
+
+#include <atomic>
+#include <list>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <vector>
+
+)__cpp_cb";
+
+#endif // IDLC_CPP_CION_GEN_CPP_GROUP_HEADER_GEN_CB_H_
diff --git a/idlc/gen_cion/cpp_cion_proxy_body_gen.cc b/idlc/gen_cion/cpp_cion_proxy_body_gen.cc
new file mode 100644
index 0000000..e61e3dd
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_proxy_body_gen.cc
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/cpp_cion_proxy_body_gen.h"
+
+namespace {
+#include "idlc/gen_cion/cpp_cion_proxy_body_gen_cb.h"
+}
+
+namespace tidl {
+
+CppCionProxyBodyGen::CppCionProxyBodyGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : CppCionGeneratorBase(doc, trans) {}
+
+void CppCionProxyBodyGen::OnInitGen(std::ofstream& stream) {
+ std::string key(".cc");
+ std::string header_file = FileName;
+
+ std::size_t found = header_file.rfind(key);
+ if (found != std::string::npos)
+ header_file.replace(found, key.length(), ".h");
+
+ GenVersion(stream);
+ stream << NLine(1);
+ stream << "#include <stdlib.h>" << NLine(1)
+ << "#include <assert.h>" << NLine(1)
+ << "#include <dlog.h>" << NLine(1)
+ << NLine(1)
+ << ReplaceAll(GetTransportable().Cpp().GenInclude(
+ static_cast<int>(GetChannelType())),
+ "<FILENAME>", GetFileNamespace())
+ << NLine(2)
+ << "#include \"" << header_file << "\"" << NLine(2);
+ GenLogTag(stream, GetTransportable().Cpp().GenProxyPrefix());
+ GenLogDefinition(stream);
+ stream << NLine(1);
+ GenCommonFunctions(stream);
+ stream << NLine(1);
+
+ GenNamespace(stream);
+}
+
+void CppCionProxyBodyGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void CppCionProxyBodyGen::GenNamespace(std::ofstream& stream) {
+ stream << "namespace " << GetTransportable().Cpp().GenNamespace() << " ";
+ GenBrace(stream, 0, [&]() {
+ stream << "namespace " << GetFileNamespace() << " ";
+ GenBrace(stream, 0, [&]() {
+ stream << NLine(1);
+ GenStructuresForBody(stream);
+ stream << "namespace proxy ";
+ GenBrace(stream, 0, [&]() {
+ GenPrototype(stream);
+ GenSerializer(stream);
+ GenDeSerializer(stream);
+ GenListSerializer(stream);
+ GenInterfaces(stream);
+ }, false, false);
+ stream << " // namespace proxy" + NLine(1);
+ }, false, false);
+ stream << " // namespace " + GetFileNamespace() + NLine(1);
+ }, false, false);
+ stream << " // namespace " + GetTransportable().Cpp().GenNamespace() + NLine(1);
+}
+
+void CppCionProxyBodyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CppCionProxyBodyGen::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ GenFilePayloadSend(stream, iface);
+ GenBodyCallbacks(stream, iface, true);
+ GenConstructor(stream, iface);
+ GenDestructor(stream, iface);
+ GenHelperMethods(stream, iface);
+ GenMethods(stream, iface);
+}
+
+void CppCionProxyBodyGen::GenConstructor(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_PROXY_INTERFACE_CTOR)
+ .Change("<CLIENT_CREATE>", GetTransportable().Cpp().GenClientCreate())
+ .Change("$$", iface.GetID())
+ .Change("<SET_SECURITY>", GenSecurity(iface))
+ .Change("<CLIENT_T>", GetTransportable().Cpp().GenClientType())
+ .Change("<SECURITY_T>", GetTransportable().Cpp().GenSecurityType(false))
+ .Change("<INTERNAL_PREFIX>", GetInternalHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CppCionProxyBodyGen::GenDestructor(std::ofstream& stream,
+ const Interface& iface) {
+ GenTemplate(std::string(ReplaceAll(CB_DTOR, {
+ { "<PEER_INFO_DESTROY>",
+ GetTransportable().Cpp().GenPeerInfoDestroy("peer_") },
+ { "<CLIENT_DESTROY>", GetTransportable().Cpp().GenClientDestroy() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() }
+ })), stream,
+ [&]()->std::string {
+ return iface.GetID();
+ },
+ [&]()->std::string {
+ return iface.GetID();
+ });
+}
+
+void CppCionProxyBodyGen::GenHelperMethods(std::ofstream& stream,
+ const Interface& iface) {
+ std::string client = "client_";
+ stream << ReplaceAll(CB_PROXY_HELPER_METHODS, {
+ { "##", iface.GetID() },
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<PAYLOAD_T>", GetTransportable().Cpp().GenPayloadType() },
+ { "<PAYLOAD_TRANSFER_STATUS_T>",
+ GetTransportable().Cpp().GenPayloadTransferStatusType(false) },
+ { "<PAYLOAD_ASYNC_RESULT_T>",
+ GetTransportable().Cpp().GenPayloadAsyncResultType() },
+ { "<CLIENT_TRY_CONNECT>",
+ GetTransportable().Cpp().GenClientTryConnect(
+ client , "peer_") },
+ { "<CLIENT_DISCONNECT>", GetTransportable().Cpp()
+ .GenClientDisconnect(client) },
+ { "<CLIENT_TRY_DISCOVERY>", GetTransportable().Cpp()
+ .GenClientTryDiscovery(client) },
+ { "<CLIENT_STOP_DISCOVERY>", GetTransportable().Cpp()
+ .GenClientStopDiscovery(client) },
+ { "<PAYLOAD_TYPE_E>", GetTransportable().Cpp().GenPayloadTypeEnum() },
+ { "<PAYLOAD_GET_TYPE>",
+ GetTransportable().Cpp().GenPayloadGetType() },
+ { "<ERROR_NONE>", GetTransportable().Cpp().GenErrorNone() },
+ { "<PAYLOAD_TYPE_DATA>",
+ GetTransportable().Cpp().GenPayloadTypeData() },
+ { "<PAYLOAD_TYPE_FILE>",
+ GetTransportable().Cpp().GenPayloadTypeFile() },
+ { "<PAYLOAD_GET_DATA>",
+ GetTransportable().Cpp().GenPayloadGetData() },
+ { "<PEER_INFO_CLONE>", GetTransportable().Cpp()
+ .GenPeerInfoClone("peer_info", "&cl->peer_") },
+ { "<PEER_INFO_GET_APPID>", GetTransportable().Cpp()
+ .GenPeerInfoGetAppID("peer_info", "&app_id") },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<ERROR_PREFIX>", GetTransportable().Cpp()
+ .GenErrorPrefix() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix()},
+ { "<CONNECTION_RESULT_PREFIX>", GetTransportable().Cpp()
+ .GenConnectionResultPrefix() }
+ }) << NLine(1);
+}
+
+void CppCionProxyBodyGen::GenMethods(std::ofstream& stream,
+ const Interface& iface) {
+ auto& decls = iface.GetDeclarations();
+
+ for (const auto& i : decls) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenDeclaration(stream, iface, *i);
+ GenBrace(stream, 0, [&]() {
+ GenInvocation(stream, *i);
+ }, false);
+ stream << NLine(1);
+ }
+}
+
+std::string CppCionProxyBodyGen::GenPrivateSharingRequestProxy(const BaseType& type,
+ std::string id) {
+ std::string ret;
+ if (type.GetMetaType() != nullptr && (type.GetMetaType()->GetFullName() == "file")) {
+ ret += std::string("for (const auto& i : " + id + ") {\n")
+ + std::string(" std::string name = i.GetFileName();\n")
+ + std::string(" FilePayloadSend(name);\n")
+ + std::string("}\n");
+ } else if (type.ToString() == "file") {
+ ret += std::string("std::string name = " + id + ".GetFileName();\n")
+ + std::string("FilePayloadSend(name);\n");
+ }
+ return ret;
+}
+
+void CppCionProxyBodyGen::GenFilePayloadSend(std::ofstream& stream,
+ const Interface& iface) {
+ GenTemplate(std::string(ReplaceAll(CB_PROXY_FILE_PAYLOAD_SEND, {
+ { "<FILE_PAYLOAD_SEND>", GetTransportable().Cpp()
+ .GenClientFileSend("path", "client_") },
+ { "<PAYLOAD_T>", GetTransportable().Cpp().GenPayloadType() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() }
+ })), stream,
+ [&]()->std::string {
+ return iface.GetID();
+ });
+}
+
+void CppCionProxyBodyGen::GenInvocation(std::ofstream& stream,
+ const Declaration& decl) {
+ stream << CB_INVOCATION_PRE;
+
+ // Serialize
+ stream << Tab(1)
+ << "rpc_port_parcel_write_int32(p, static_cast<int>(MethodId::"
+ << decl.GetID() << "));" << NLine(1);
+ std::string m;
+ std::string l;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT)
+ continue;
+ m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p");
+ if (IsDelegateType(pt.GetBaseType())) {
+ l += "delegate_list_.emplace_back(" + i->GetID() + ".release());\n";
+ }
+ }
+ stream << AddIndent(TAB_SIZE, m) << NLine(1);
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
+ stream << Tab(1) << "unsigned char *return_data;" << NLine(1);
+ stream << Tab(1) << "unsigned int return_data_size = 0;" << NLine(1);
+ }
+ stream << Tab(1) << "do ";
+ GenBrace(stream, TAB_SIZE, [&]() {
+ stream << Tab(2) << "std::lock_guard<std::recursive_mutex> lock(mutex_);"
+ << NLine(2);
+ if (!l.empty())
+ stream << AddIndent(TAB_SIZE * 2, l);
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC)
+ stream << ReplaceAll(CB_INVOCATION_SYNC_MID, {
+ { "<CLIENT_SEND>",
+ GetTransportable().Cpp().GenClientSend("client_", "data",
+ "size", "return_data", "return_data_size") },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() }
+ }) << NLine(1);
+ else if (decl.GetMethodType() == Declaration::MethodType::ASYNC)
+ stream << ReplaceAll(CB_INVOCATION_ASYNC_MID, {
+ { "<PAYLOAD_T>", GetTransportable().Cpp().GenPayloadType() },
+ { "<CLIENT_SEND_ASYNC>",
+ GetTransportable().Cpp().GenClientSendAsync(
+ "client_", "pl", "size") },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() }
+ }) << NLine(1);
+ }, false, false);
+ stream << " while (false);" << NLine(1);
+
+ // Deserialize
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
+ stream << Tab(1) << "rpc_port_parcel_destroy(p);"
+ << NLine(1);
+ return;
+ }
+
+ stream << CB_INVOCATION_RECEIVE << NLine(1);
+ for (const auto& i : decl.GetParameters()) {
+ if (i->GetParameterType().GetDirection() == ParameterType::Direction::IN) {
+ continue;
+ }
+
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(),
+ i->GetID(), "parcel_received", false);
+ if (c != "")
+ stream << AddIndent(TAB_SIZE, c);
+ }
+
+ if (decl.GetType().ToString() != "void") {
+ stream << AddIndent(TAB_SIZE,
+ ConvertTypeToDeserializer(decl.GetType(),
+ "ret", "parcel_received"));
+ }
+
+ std::string f;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT)
+ continue;
+ f += GenPrivateSharingRequestProxy(pt.GetBaseType(), i->GetID());
+ }
+ stream << AddIndent(TAB_SIZE, f) << NLine(1);
+
+ stream << CB_INVOCATION_END;
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/cpp_cion_proxy_body_gen.h b/idlc/gen_cion/cpp_cion_proxy_body_gen.h
new file mode 100644
index 0000000..64e6218
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_proxy_body_gen.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_CION_GEN_CPP_PROXY_BODY_GEN_H_
+#define IDLC_CPP_CION_GEN_CPP_PROXY_BODY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/cpp_cion_gen_base.h"
+
+namespace tidl {
+
+class CppCionProxyBodyGen : public CppCionGeneratorBase {
+ public:
+ explicit CppCionProxyBodyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CppCionProxyBodyGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ void GenStructures(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenConstructor(std::ofstream& stream, const Interface& iface);
+ void GenDestructor(std::ofstream& stream, const Interface& iface);
+ void GenHelperMethods(std::ofstream& stream, const Interface& iface);
+ void GenMethods(std::ofstream& stream, const Interface& iface);
+ void GenFilePayloadSend(std::ofstream& stream, const Interface& iface);
+ void GenInvocation(std::ofstream& stream, const Declaration& decl);
+
+ std::string GenPrivateSharingRequestProxy(const BaseType& type, std::string id);
+};
+
+} // namespace tidl
+
+#endif // IDLC_CPP_CION_GEN_CPP_PROXY_BODY_GEN_H_
diff --git a/idlc/gen_cion/cpp_cion_proxy_body_gen_cb.h b/idlc/gen_cion/cpp_cion_proxy_body_gen_cb.h
new file mode 100644
index 0000000..9356be5
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_proxy_body_gen_cb.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_GEN_CION_CPP_PROXY_BODY_GEN_CB_H_
+#define IDLC_CPP_GEN_CION_CPP_PROXY_BODY_GEN_CB_H_
+
+const char CB_DTOR[] =
+R"__cpp_cb(
+$$::~$$() {
+ if (peer_ != nullptr)
+ <PEER_INFO_DESTROY>
+<CLIENT_DESTROY>
+}
+)__cpp_cb";
+
+const char CB_INVOCATION_PRE[] =
+R"__cpp_cb( rpc_port_parcel_h p;
+ rpc_port_parcel_create(&p);
+)__cpp_cb";
+
+const char CB_INVOCATION_SYNC_MID[] =
+R"__cpp_cb(
+ // SendData(SYNC)
+ unsigned int size;
+ char *data;
+
+ int ret = rpc_port_parcel_get_raw(p, (void **)&data, &size);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get raw. error(%d)", ret);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
+<CLIENT_SEND>
+
+)__cpp_cb";
+
+const char CB_INVOCATION_ASYNC_MID[] =
+R"__cpp_cb(
+ // SendPayloadAsync
+ unsigned int size;
+ char *data;
+
+ int ret = rpc_port_parcel_get_raw(p, (void **)&data, &size);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get raw. error(%d)", ret);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
+
+ <PAYLOAD_T> pl;
+<CLIENT_SEND_ASYNC>
+)__cpp_cb";
+
+const char CB_INVOCATION_RECEIVE[] =
+R"__cpp_cb(
+ if (return_data_size == 0) {
+ _E("Invalid protocol");
+ rpc_port_parcel_destroy(p);
+ throw InvalidProtocolException();
+ }
+
+ rpc_port_parcel_h parcel_received;
+ rpc_port_parcel_create_from_raw(&parcel_received, return_data,
+ return_data_size);
+
+ int cmd;
+ rpc_port_parcel_read_int32(parcel_received, &cmd);
+ if (cmd != static_cast<int>(MethodId::__Result)) {
+ _E("Invalid result cmd");
+ rpc_port_parcel_destroy(p);
+ rpc_port_parcel_destroy(parcel_received);
+ throw InvalidProtocolException();
+ }
+)__cpp_cb";
+
+const char CB_INVOCATION_END[] =
+R"__cpp_cb(
+ rpc_port_parcel_destroy(p);
+ rpc_port_parcel_destroy(parcel_received);
+
+ return ret;
+)__cpp_cb";
+
+const char CB_PROXY_FILE_PAYLOAD_SEND[] = R"__cpp_cb(
+void $$::FilePayloadSend(std::string path)
+{
+ <FILE_PAYLOAD_SEND>
+}
+)__cpp_cb";
+
+const char CB_PROXY_HELPER_METHODS[] =
+R"__cpp_cb(
+void ##::Connect() {
+ if (peer_) {
+ <CLIENT_TRY_CONNECT>
+ } else {
+ _E("Not discovered");
+ }
+}
+
+void ##::DisposeCallback(const std::string& tag) {
+ for (auto& i : delegate_list_) {
+ if (i->GetTag() == tag) {
+ delegate_list_.remove(i);
+ return;
+ }
+ }
+}
+
+void ##::ProcessReceivedEvent(rpc_port_parcel_h parcel) {
+ int id = 0;
+ int seq_id = 0;
+ bool once = false;
+
+ rpc_port_parcel_read_int32(parcel, &id);
+ rpc_port_parcel_read_int32(parcel, &seq_id);
+ rpc_port_parcel_read_bool(parcel, &once);
+
+ for (auto& i : delegate_list_) {
+ if (i->GetId() == id && i->GetSeqId() == seq_id) {
+ i->OnReceivedEvent(parcel);
+ if (i->IsOnce())
+ delegate_list_.remove(i);
+ break;
+ }
+ }
+}
+
+void ##::Disconnect() {
+ <CLIENT_DISCONNECT>
+}
+
+void ##::Discovery() {
+ <CLIENT_TRY_DISCOVERY>
+}
+
+void ##::StopDiscovery() {
+ <CLIENT_STOP_DISCOVERY>
+}
+
+void ##::OnConnectionResultCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, const <MODULE_PREFIX>_connection_result_h result,
+ void *user_data) {
+ ## *cl = static_cast<##*>(user_data);
+ <MODULE_PREFIX>_connection_status_e status;
+ int ret = <MODULE_PREFIX>_connection_result_get_status(result, &status);
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to <MODULE_PREFIX>_connection_result_get_status. error(%d)", ret);
+ return;
+ }
+
+ if (static_cast<int>(status) == <CONNECTION_RESULT_PREFIX>CONNECTION_STATUS_OK)
+ cl->listener_->OnConnected();
+ else if (static_cast<int>(status) == <CONNECTION_RESULT_PREFIX>CONNECTION_STATUS_REJECTED)
+ cl->listener_->OnRejected();
+}
+
+void ##::OnDisconnectedCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, void *user_data) {
+ ## *cl = static_cast<##*>(user_data);
+ cl->delegate_list_.clear();
+ cl->listener_->OnDisconnected();
+}
+
+void ##::OnDiscoveredCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, void *user_data) {
+ ## *cl = static_cast<##*>(user_data);
+ char *app_id;
+ int ret = <PEER_INFO_GET_APPID>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_peer_info_get_app_id. error(%d)", ret);
+ return;
+ }
+
+ auto app_id_auto = std::unique_ptr<char, decltype(std::free)*>(
+ app_id, std::free);
+ if (std::string(app_id) == cl->target_appid_) {
+ ret = <PEER_INFO_CLONE>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_peer_info_clone. error(%d)", ret);
+ return;
+ }
+
+ cl->listener_->OnDiscovered();
+ }
+}
+
+void ##::OnPayloadAsyncResultCB(const <PAYLOAD_ASYNC_RESULT_T> result,
+ void* user_data) {
+}
+
+void ##::OnPayloadReceivedCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, const <PAYLOAD_T> payload,
+ <PAYLOAD_TRANSFER_STATUS_T> status,
+ void *user_data) {
+ ## *cl = static_cast<##*>(user_data);
+ char *app_id;
+ int ret = <PEER_INFO_GET_APPID>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_peer_info_get_app_id. error(%d)", ret);
+ return;
+ }
+
+ auto app_id_auto = std::unique_ptr<char, decltype(std::free)*>(
+ app_id, std::free);
+ if (std::string(app_id) != cl->target_appid_) {
+ _E("peer is wrong");
+ return;
+ }
+
+ <PAYLOAD_TYPE_E> type;
+ <PAYLOAD_GET_TYPE>
+ if (ret != <ERROR_NONE>) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_get_type. error(%d)", ret);
+ return;
+ }
+
+ if (type == <PAYLOAD_TYPE_FILE>) {
+ cl->listener_->OnFileReceived(peer_info, payload, status);
+ return;
+ }
+
+ unsigned char *data;
+ unsigned int size;
+ <PAYLOAD_GET_DATA>
+ if (ret != <ERROR_NONE>) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_get_data. error(%d)", ret);
+ return;
+ }
+
+ rpc_port_parcel_h parcel_received;
+ rpc_port_parcel_create_from_raw(&parcel_received, data, size);
+
+ int cmd;
+ rpc_port_parcel_read_int32(parcel_received, &cmd);
+ if (cmd != static_cast<int>(MethodId::__Callback)) {
+ rpc_port_parcel_destroy(parcel_received);
+ return;
+ }
+
+ cl->ProcessReceivedEvent(parcel_received);
+ rpc_port_parcel_destroy(parcel_received);
+}
+)__cpp_cb";
+
+const char CB_PROXY_INTERFACE_CTOR[] =
+R"__cpp_cb(
+$$::$$(IEventListener* listener, const std::string& service_name,
+ const std::string& target_appid, const std::string& broker_ip, int broker_port,
+ const std::string& user_name, const std::string& password, const std::string& my_ip,
+ int protocols)
+ : listener_(listener), service_name_(service_name),
+ target_appid_(target_appid) {
+ <CLIENT_CREATE>
+}
+)__cpp_cb";
+
+#endif // IDLC_CPP_GEN_CION_CPP_PROXY_BODY_GEN_CB_H_
diff --git a/idlc/gen_cion/cpp_cion_proxy_header_gen.cc b/idlc/gen_cion/cpp_cion_proxy_header_gen.cc
new file mode 100644
index 0000000..397c1c2
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_proxy_header_gen.cc
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/cpp_cion_proxy_header_gen.h"
+
+namespace {
+#include "idlc/gen_cion/cpp_cion_proxy_header_gen_cb.h"
+}
+
+namespace tidl {
+
+CppCionProxyHeaderGen::CppCionProxyHeaderGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans)
+ : CppCionGeneratorBase(doc, trans) {}
+
+void CppCionProxyHeaderGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+
+ stream << CB_HEADER;
+
+ GenCommonHandles(stream);
+ GenClientHandles(stream);
+ GenFileHandle(stream);
+ GenConnectionHandle(stream);
+ GenCommonBase(stream);
+ GenFileBase(stream);
+ GenNamespace(stream);
+}
+
+void CppCionProxyHeaderGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void CppCionProxyHeaderGen::GenNamespace(std::ofstream& stream) {
+ stream << "namespace " << GetTransportable().Cpp().GenNamespace() << " ";
+ GenBrace(stream, 0, [&]() {
+ stream << "namespace " << GetFileNamespace() << " ";
+ GenBrace(stream, 0, [&]() {
+ stream << NLine(1);
+ GenStructuresForHeader(stream);
+ stream << "namespace proxy ";
+ GenBrace(stream, 0, [&]() {
+ GenExceptions(stream);
+ GenInterfaces(stream);
+ }, false, false);
+ stream << " // namespace proxy" + NLine(1);
+ }, false, false);
+ stream << " // namespace " + GetFileNamespace() + NLine(1);
+ }, false, false);
+ stream << " // namespace " + GetTransportable().Cpp().GenNamespace() + NLine(1);
+}
+
+void CppCionProxyHeaderGen::GenExceptions(std::ofstream& stream) {
+ stream << CB_EXCEPTIONS;
+}
+
+void CppCionProxyHeaderGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CppCionProxyHeaderGen::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ stream << NLine(1) << "class " << iface.GetID() << " final ";
+ GenBrace(stream, 0, [&]() {
+ stream << " public:" << NLine(1);
+ GenHeaderCallbacks(stream, iface, true);
+ GenTemplate(std::string(ReplaceAll(CB_PUBLIC_MEMBERS, {
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<PAYLOAD_T>", GetTransportable().Cpp().GenPayloadType() },
+ { "<PAYLOAD_TRANSFER_STATUS_T>",
+ GetTransportable().Cpp().GenPayloadTransferStatusType(false) },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() }
+ })), stream,
+ [&]()->std::string {
+ return iface.GetID();
+ },
+ [&]()->std::string {
+ return iface.GetID();
+ });
+ GenMethods(stream, iface);
+ GenDelegateId(stream, iface);
+ stream << NLine(1) << " private:" << NLine(1);
+ GenMethodId(stream, iface);
+ stream << ReplaceAll(CB_PRIVATE_MEMBERS, {
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<PAYLOAD_T>", GetTransportable().Cpp().GenPayloadType() },
+ { "<CLIENT_T>", GetTransportable().Cpp().GenClientType() },
+ { "<PAYLOAD_TRANSFER_STATUS_T>",
+ GetTransportable().Cpp().GenPayloadTransferStatusType(false) },
+ { "<PAYLOAD_ASYNC_RESULT_T>",
+ GetTransportable().Cpp().GenPayloadAsyncResultType() },
+ { "<SECURITY_T>", GetTransportable().Cpp().GenSecurityType() },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() }
+ });
+ }, false, false);
+ stream << ";" << NLine(1);
+}
+
+void CppCionProxyHeaderGen::GenMethods(std::ofstream& stream,
+ const Interface& iface) {
+ auto& decls = iface.GetDeclarations();
+
+ for (const auto& i : decls) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenDeclaration(stream, *i);
+ }
+}
+
+void CppCionProxyHeaderGen::GenDeclaration(std::ofstream& stream,
+ const Declaration& decl) {
+ if (!decl.GetComments().empty())
+ stream << NLine(1) << AddIndent(TAB_SIZE, decl.GetComments());
+
+ stream << Tab(1) << ConvertTypeToString(decl.GetType()) << " "
+ << decl.GetID() << "(";
+ GenParameters(stream, decl.GetParameters());
+ stream << ");" << NLine(1);
+}
+} // namespace tidl
diff --git a/idlc/gen_cion/cpp_cion_proxy_header_gen.h b/idlc/gen_cion/cpp_cion_proxy_header_gen.h
new file mode 100644
index 0000000..11c5b92
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_proxy_header_gen.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_CION_GEN_CPP_PROXY_HEADER_GEN_H_
+#define IDLC_CPP_CION_GEN_CPP_PROXY_HEADER_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/cpp_cion_gen_base.h"
+
+namespace tidl {
+
+class CppCionProxyHeaderGen : public CppCionGeneratorBase {
+ public:
+ explicit CppCionProxyHeaderGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CppCionProxyHeaderGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ void GenExceptions(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenMethods(std::ofstream& stream, const Interface& iface);
+ void GenDeclaration(std::ofstream& stream, const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_CPP_CION_GEN_CPP_PROXY_HEADER_GEN_H_
diff --git a/idlc/gen_cion/cpp_cion_proxy_header_gen_cb.h b/idlc/gen_cion/cpp_cion_proxy_header_gen_cb.h
new file mode 100644
index 0000000..965680b
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_proxy_header_gen_cb.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_CION_GEN_CPP_PROXY_HEADER_GEN_CB_H_
+#define IDLC_CPP_CION_GEN_CPP_PROXY_HEADER_GEN_CB_H_
+
+const char CB_EXCEPTIONS[] =
+R"__cpp_cb(
+class Exception {};
+class NotConnectedSocketException : public Exception {};
+class InvalidProtocolException : public Exception {};
+class InvalidIOException : public Exception {};
+class UnauthorizedAccessException : public Exception {};
+)__cpp_cb";
+
+const char CB_PUBLIC_MEMBERS[] =
+R"__cpp_cb(
+ class IEventListener {
+ public:
+ /// <summary>
+ /// This method will be invoked when the client app is connected to the service app.
+ /// </summary>
+ virtual void OnConnected() = 0;
+
+ /// <summary>
+ /// This method will be invoked after the client app was disconnected from the service app.
+ /// </summary>
+ virtual void OnDisconnected() = 0;
+
+ /// <summary>
+ /// This method will be invoked when the service app rejects the client app.
+ /// </summary>
+ virtual void OnRejected() = 0;
+
+ /// <summary>
+ /// This method will be invoked when the service app is discovered.
+ /// </summary>
+ virtual void OnDiscovered() = 0;
+
+ /// <summary>
+ /// This method will be invoked when file receieved from service.
+ /// </summary>
+ virtual void OnFileReceived(<PEER_INFO_T> peer_info,
+ <PAYLOAD_T> file_payload, <PAYLOAD_TRANSFER_STATUS_T> status) = 0;
+ };
+
+ /// <summary>
+ /// Constructor for this class
+ /// </summary>
+ /// <param name="listener">The listener for events</param>
+ /// <param name="service_name">The service name to connect</param>
+ /// <param name="target_appid">The service app ID to connect</param>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ explicit $$(IEventListener* listener, const std::string& service_name,
+ const std::string& target_appid, const std::string& broker_ip, int broker_port,
+ const std::string& user_name, const std::string& password, const std::string& my_ip,
+ int protocols);
+
+ /// <summary>
+ /// Destructor for this class
+ /// </summary>
+ virtual ~$$();
+
+ /// <summary>
+ /// Connects to the service app.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <exception cref="UnauthorizedAccessException">
+ /// Thrown when an application does not have the privilege to access this method.
+ /// </exception>
+ /// <exception cref="NotConnectedSocketException">
+ /// Thrown when a service app was not discovered.
+ /// </exception>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ void Connect();
+
+ /// <summary>
+ /// Disconnects to the service app.
+ /// </summary>
+ /// <exception cref="NotConnectedSocketException">
+ /// Thrown when a service app was not connected.
+ /// </exception>
+ void Disconnect();
+
+ /// <summary>
+ /// Tries to discover a server.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <exception cref="UnauthorizedAccessException">
+ /// Thrown when an application does not have the privilege to access this method.
+ /// </exception>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ void Discovery();
+
+ /// <summary>
+ /// Stops discovering.
+ /// </summary>
+ void StopDiscovery();
+
+ /// <summary>
+ /// Disposes delegate objects in this interface
+ /// </summary>
+ /// <param name="tag">The tag string from delegate object</param>
+ void DisposeCallback(const std::string& tag);
+)__cpp_cb";
+
+const char CB_PRIVATE_MEMBERS[] =
+R"__cpp_cb( void ProcessReceivedEvent(rpc_port_parcel_h parcel);
+ void FilePayloadSend(std::string path);
+
+ static void OnConnectionResultCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, const <MODULE_PREFIX>_connection_result_h result,
+ void *user_data);
+ static void OnDisconnectedCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, void *user_data);
+ static void OnDiscoveredCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, void *user_data);
+ static void OnPayloadAsyncResultCB(const <PAYLOAD_ASYNC_RESULT_T> result,
+ void *user_data);
+ static void OnPayloadReceivedCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, const <PAYLOAD_T> payload,
+ <PAYLOAD_TRANSFER_STATUS_T> status,
+ void *user_data);
+
+ <CLIENT_T> client_ = nullptr;
+ <SECURITY_T>
+ <PEER_INFO_T> peer_ = nullptr;
+ IEventListener* listener_;
+ std::string service_name_;
+ std::string target_appid_;
+ std::recursive_mutex mutex_;
+ std::list<std::unique_ptr<CallbackBase>> delegate_list_;
+)__cpp_cb";
+
+const char CB_HEADER[] =
+R"__cpp_cb(
+#pragma once
+
+#include <rpc-port-parcel.h>
+
+#include <string>
+#include <vector>
+#include <list>
+#include <memory>
+#include <mutex>
+#include <atomic>
+
+)__cpp_cb";
+
+#endif // IDLC_CPP_CION_GEN_CPP_PROXY_HEADER_GEN_CB_H_
diff --git a/idlc/gen_cion/cpp_cion_stub_body_gen.cc b/idlc/gen_cion/cpp_cion_stub_body_gen.cc
new file mode 100644
index 0000000..761a218
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_stub_body_gen.cc
@@ -0,0 +1,399 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/cpp_cion_stub_body_gen.h"
+
+namespace {
+#include "idlc/gen_cion/cpp_cion_stub_body_gen_cb.h"
+}
+
+namespace tidl {
+
+CppCionStubBodyGen::CppCionStubBodyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options, std::shared_ptr<tidl::Transportable> trans)
+ : CppCionGeneratorBase(doc, trans), options_(options) {}
+
+void CppCionStubBodyGen::OnInitGen(std::ofstream& stream) {
+ std::string key(".cc");
+ std::string header_file = FileName;
+
+ std::size_t found = header_file.rfind(key);
+ if (found != std::string::npos)
+ header_file.replace(found, key.length(), ".h");
+
+ GenVersion(stream);
+ stream << NLine(1);
+ stream << "#include <stdlib.h>" << NLine(1)
+ << "#include <assert.h>" << NLine(1)
+ << "#include <libgen.h>" << NLine(1)
+ << "#include <dlog.h>" << NLine(1)
+ << NLine(1)
+ << ReplaceAll(GetTransportable().Cpp().GenInclude(
+ static_cast<int>(GetChannelType())),
+ "<FILENAME>", GetFileNamespace())
+ << NLine(2)
+ << "#include \"" << header_file << "\"" << NLine(2);
+ GenLogTag(stream, GetTransportable().Cpp().GenStubPrefix());
+ GenLogDefinition(stream);
+ stream << NLine(1);
+ GenCommonFunctions(stream);
+ stream << NLine(1);
+
+ GenNamespace(stream);
+}
+
+void CppCionStubBodyGen::OnFiniGen(std::ofstream& stream) {}
+
+void CppCionStubBodyGen::GenNamespace(std::ofstream& stream) {
+ stream << "namespace " << GetTransportable().Cpp().GenNamespace() << " ";
+ GenBrace(stream, 0, [&]() {
+ stream << "namespace " << GetFileNamespace() << " ";
+ GenBrace(stream, 0, [&]() {
+ stream << NLine(1);
+ GenStructuresForBody(stream);
+ stream << "namespace stub ";
+ GenBrace(stream, 0, [&]() {
+ GenPrototype(stream);
+ GenSerializer(stream);
+ GenDeSerializer(stream);
+ GenListSerializer(stream);
+ GenInterfaces(stream);
+ }, false, false);
+ stream << " // namespace stub" + NLine(1);
+ }, false, false);
+ stream << " // namespace " + GetFileNamespace() + NLine(1);
+ }, false, false);
+ stream << " // namespace " + GetTransportable().Cpp().GenNamespace() + NLine(1);
+}
+
+void CppCionStubBodyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CppCionStubBodyGen::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ GenFilePayloadSend(stream, iface);
+ GenServiceBase(stream, iface);
+ GenBodyCallbacks(stream, iface, false);
+ GenDefaultMethods(stream, iface);
+ GenCionDataReceivedEvent(stream, iface);
+ GenCionPayloadReceivedEvent(stream, iface);
+}
+
+void CppCionStubBodyGen::GenServiceBase(std::ofstream& stream,
+ const Interface& iface) {
+ GenTemplate(std::string(ReplaceAll(CB_CTOR_SERVICE_BASE, {
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<PEER_INFO_CLONE>", GetTransportable().Cpp()
+ .GenPeerInfoClone("peer", "&peer_") },
+ { "<ERROR_PREFIX>", GetTransportable().Cpp()
+ .GenErrorPrefix() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() }
+ })), stream,
+ [&]()->std::string {
+ return iface.GetID();
+ });
+ stream << NLine(1);
+}
+
+void CppCionStubBodyGen::GenConstructor(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_CTOR_FRONT)
+ .Change("<SERVER_REGISTER>", GetTransportable().Cpp().GenServerRegister())
+ .Change("##", iface.GetID())
+ .Change("<SET_SECURITY>", GenSecurity(iface))
+ .Change("<SERVER_T>", GetTransportable().Cpp().GenServerType())
+ .Change("<SECURITY_T>", GetTransportable().Cpp().GenSecurityType(false))
+ .Change("<INTERNAL_PREFIX>", GetInternalHandlePrefix())
+ .Change("<MODULE_PREFIX>", GetMoudlePrefix())
+ .Out(stream);
+}
+
+void CppCionStubBodyGen::GenDefaultMethods(std::ofstream& stream,
+ const Interface& iface) {
+ GenConstructor(stream, iface);
+ if (options_->IsThreadEnabled())
+ stream << ReplaceAll(CB_DEFAULT_THREAD_METHODS, "##", iface.GetID());
+
+ stream << ReplaceAll(CB_DEFAULT_METHODS, {
+ { "##", iface.GetID() },
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<SERVER_UNREGISTER>",
+ GetTransportable().Cpp().GenServerUnregister() },
+ { "<SERVER_ACCEPT>",
+ GetTransportable().Cpp().GenServerAccept() },
+ { "<SERVER_REJECT>",
+ GetTransportable().Cpp().GenServerReject() },
+ { "<SERVER_SET_DISPLAY_NAME>",
+ GetTransportable().Cpp().GenServerSetDisplayName() },
+ { "<SERVER_SET_ONDEMAND_LAUNCH_ENABLED>",
+ GetTransportable().Cpp().GenServerSetOnDemandLaunchEnabled() },
+ { "<SERVER_LISTEN>",
+ GetTransportable().Cpp().GenServerListen() },
+ { "<SERVER_DISCONNECT>", GetTransportable().Cpp()
+ .GenServerDisconnect("server_", "p") },
+ { "<PEER_INFO_GET_APPID1>", GetTransportable().Cpp()
+ .GenPeerInfoGetAppID("peer_info", "&peer_app_id") },
+ { "<PEER_INFO_GET_APPID2>", GetTransportable().Cpp()
+ .GenPeerInfoGetAppID("s->get()->GetPeer()", "&service_app_id") },
+ { "<PEER_INFO_GET_UUID1>", GetTransportable().Cpp()
+ .GenPeerInfoGetUUID("peer_info", "&peer_uuid") },
+ { "<PEER_INFO_GET_UUID2>", GetTransportable().Cpp()
+ .GenPeerInfoGetUUID("s->get()->GetPeer()", "&service_uuid") },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() },
+ { "<ERROR_PREFIX>", GetTransportable().Cpp()
+ .GenErrorPrefix() }
+ });
+}
+
+void CppCionStubBodyGen::GenCionDataReceivedEvent(std::ofstream& stream,
+ const Interface& iface) {
+ if (options_->IsThreadEnabled()) {
+ GenTemplate(CB_RUN_PENDING_JOB_FRONT, stream,
+ [&]()->std::string {
+ return iface.GetID();
+ });
+ } else {
+ GenTemplate(std::string(ReplaceAll(CB_CION_ON_DATA_RECEIVED_CB_FRONT, {
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<PEER_INFO_GET_APPID1>", GetTransportable().Cpp()
+ .GenPeerInfoGetAppID("peer_info", "&peer_app_id") },
+ { "<PEER_INFO_GET_APPID2>", GetTransportable().Cpp()
+ .GenPeerInfoGetAppID("s->GetPeer()", "&service_app_id") },
+ { "<PEER_INFO_GET_UUID1>", GetTransportable().Cpp()
+ .GenPeerInfoGetUUID("peer_info", "&peer_uuid") },
+ { "<PEER_INFO_GET_UUID2>", GetTransportable().Cpp()
+ .GenPeerInfoGetUUID("s->GetPeer()", "&service_uuid") },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() },
+ { "<ERROR_PREFIX>", GetTransportable().Cpp()
+ .GenErrorPrefix() }
+ })), stream,
+ [&]()->std::string {
+ return iface.GetID();
+ },
+ [&]()->std::string {
+ return iface.GetID();
+ },
+ [&]()->std::string {
+ return iface.GetID();
+ });
+ }
+
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE ||
+ i->GetMethodType() == Declaration::MethodType::ASYNC)
+ continue;
+ stream << Tab(2) << "case static_cast<int>(MethodId::"
+ << i->GetID() << "): ";
+ GenBrace(stream, TAB_SIZE * 2, [&]() {
+ GenInvocation(stream, *i);
+ stream << Tab(3) << "break;" << NLine(1);
+ }, false);
+ stream << NLine(1);
+ }
+
+ if (options_->IsThreadEnabled()) {
+ stream << CB_RUN_PENDING_JOB_BACK << NLine(1);
+
+ GenTemplate(CB_ON_DATA_RECEIVED_CB, stream,
+ [&]()->std::string {
+ return iface.GetID();
+ },
+ [&]()->std::string {
+ return iface.GetID();
+ });
+ } else {
+ stream << CB_CION_ON_DATA_RECEIVED_CB_BACK << NLine(1);
+ }
+}
+
+void CppCionStubBodyGen::GenCionPayloadReceivedEvent(std::ofstream& stream,
+ const Interface& iface) {
+ GenTemplate(std::string(ReplaceAll(CB_CION_ON_PAYLOAD_RECEIVED_CB_FRONT, {
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<PAYLOAD_T>", GetTransportable().Cpp().GenPayloadType() },
+ { "<PAYLOAD_TRANSFER_STATUS_T>",
+ GetTransportable().Cpp().GenPayloadTransferStatusType(false) },
+ { "<PAYLOAD_TYPE_E>", GetTransportable().Cpp().GenPayloadTypeEnum() },
+ { "<PAYLOAD_GET_TYPE>",
+ GetTransportable().Cpp().GenPayloadGetType() },
+ { "<ERROR_NONE>", GetTransportable().Cpp().GenErrorNone() },
+ { "<PAYLOAD_TYPE_DATA>",
+ GetTransportable().Cpp().GenPayloadTypeData() },
+ { "<PAYLOAD_TYPE_FILE>",
+ GetTransportable().Cpp().GenPayloadTypeFile() },
+ { "<PAYLOAD_GET_DATA>",
+ GetTransportable().Cpp().GenPayloadGetData() },
+ { "<PEER_INFO_GET_APPID1>", GetTransportable().Cpp()
+ .GenPeerInfoGetAppID("peer_info", "&peer_app_id") },
+ { "<PEER_INFO_GET_APPID2>", GetTransportable().Cpp()
+ .GenPeerInfoGetAppID("s->GetPeer()", "&service_app_id") },
+ { "<PEER_INFO_GET_UUID1>", GetTransportable().Cpp()
+ .GenPeerInfoGetUUID("peer_info", "&peer_uuid") },
+ { "<PEER_INFO_GET_UUID2>", GetTransportable().Cpp()
+ .GenPeerInfoGetUUID("s->GetPeer()", "&service_uuid") },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() },
+ { "<ERROR_PREFIX>", GetTransportable().Cpp()
+ .GenErrorPrefix() }
+ })), stream,
+ [&]()->std::string {
+ return iface.GetID();
+ },
+ [&]()->std::string {
+ return iface.GetID();
+ },
+ [&]()->std::string {
+ return iface.GetID();
+ });
+
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE ||
+ i->GetMethodType() == Declaration::MethodType::SYNC)
+ continue;
+ stream << Tab(2) << "case static_cast<int>(MethodId::"
+ << i->GetID() << "): ";
+ GenBrace(stream, TAB_SIZE * 2, [&]() {
+ GenInvocation(stream, *i);
+ stream << Tab(3) << "break;" << NLine(1);
+ }, false);
+ stream << NLine(1);
+ }
+
+ stream << CB_CION_ON_PAYLOAD_RECEIVED_CB_BACK << NLine(1);
+}
+
+std::string CppCionStubBodyGen::GenPrivateSharingRequestStub(const BaseType& type,
+ std::string id) {
+ std::string ret;
+ if (type.GetMetaType() != nullptr && (type.GetMetaType()->GetFullName() == "file")) {
+ ret += std::string("for (const auto& i : " + id + ") {\n")
+ + std::string(" std::string name = i.GetFileName();\n")
+ + std::string(" stub->FilePayloadSend(name, b->GetPeer());\n")
+ + std::string("}\n");
+ } else if (type.ToString() == "file") {
+ ret += std::string("std::string name = " + id + ".GetFileName();\n")
+ + std::string("stub->FilePayloadSend(name, b->GetPeer());\n");
+ }
+ return ret;
+}
+
+void CppCionStubBodyGen::GenInvocation(std::ofstream& stream,
+ const Declaration& decl) {
+ int cnt = 1;
+
+ // Deserialize
+ for (const auto& i : decl.GetParameters()) {
+ if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT) {
+ cnt++;
+ continue;
+ }
+
+ std::string v = "param" + std::to_string(cnt);
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, "p");
+ stream << AddIndent(TAB_SIZE * 3, c);
+ cnt++;
+ }
+
+ // Invoke
+ cnt = 1;
+ std::string m;
+ std::string d;
+ bool hasRet = false;
+
+ if (decl.GetType().ToString() != "void") {
+ m += "auto retVal = ";
+ hasRet = true;
+ }
+
+ m += "b->" + decl.GetID() + "(";
+ for (const auto& i : decl.GetParameters()) {
+ if (cnt != 1) {
+ m += ", ";
+ }
+
+ std::string v = "param" + std::to_string(cnt);
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT) {
+ d += ConvertTypeToString(pt.GetBaseType()) + " " + v + ";\n";
+ }
+ if (IsDelegateType(pt.GetBaseType())) {
+ m += "std::move(";
+ m += v;
+ m += ")";
+ } else {
+ m += v;
+ }
+ cnt++;
+ }
+
+ m += ");\n";
+ stream << AddIndent(TAB_SIZE * 3, d);
+ stream << AddIndent(TAB_SIZE * 3, m);
+
+ // Serialize
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC)
+ return;
+
+ cnt = 0;
+ m = "rpc_port_parcel_write_int32(" \
+ "result, static_cast<int>(MethodId::__Result));\n";
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ cnt++;
+ if (pt.GetDirection() == ParameterType::Direction::IN)
+ continue;
+ m += GenPrivateSharingRequestStub(pt.GetBaseType(), "param" + std::to_string(cnt));
+ m += ConvertTypeToSerializer(pt.GetBaseType(),
+ "param" + std::to_string(cnt), "result");
+ }
+
+ if (hasRet) {
+ m += GenPrivateSharingRequestStub(decl.GetType(), "retVal");
+ m += ConvertTypeToSerializer(decl.GetType(), "retVal", "result");
+ }
+
+ //m += "_I(\"retVal(%d)\", retVal);\n";
+ stream << AddIndent(TAB_SIZE * 3, m);
+}
+
+void CppCionStubBodyGen::GenFilePayloadSend(std::ofstream& stream,
+ const Interface& iface) {
+ GenTemplate(std::string(ReplaceAll(CB_FILE_PAYLOAD_SEND, {
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<FILE_PAYLOAD_SEND>", GetTransportable().Cpp()
+ .GenServerFileSend("path", "server_", "peer") },
+ { "<PAYLOAD_T>", GetTransportable().Cpp().GenPayloadType() },
+ { "<INTERNAL_PREFIX>", GetInternalHandlePrefix() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() }
+ })), stream,
+ [&]()->std::string {
+ return iface.GetID();
+ });
+ stream << NLine(1);
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/cpp_cion_stub_body_gen.h b/idlc/gen_cion/cpp_cion_stub_body_gen.h
new file mode 100644
index 0000000..3d3e129
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_stub_body_gen.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_CION_GEN_CPP_STUB_BODY_GEN_H_
+#define IDLC_CPP_CION_GEN_CPP_STUB_BODY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/cpp_cion_gen_base.h"
+#include "idlc/options.h"
+
+namespace tidl {
+
+class CppCionStubBodyGen : public CppCionGeneratorBase {
+ public:
+ explicit CppCionStubBodyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CppCionStubBodyGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenServiceBase(std::ofstream& stream, const Interface& iface);
+ void GenDefaultMethods(std::ofstream& stream, const Interface& iface);
+ void GenCionDataReceivedEvent(std::ofstream& stream, const Interface& iface);
+ void GenCionPayloadReceivedEvent(std::ofstream& stream, const Interface& iface);
+ void GenInvocation(std::ofstream& stream, const Declaration& decl);
+ void GenConstructor(std::ofstream& stream, const Interface& iface);
+ void GenFilePayloadSend(std::ofstream& stream, const Interface& iface);
+ std::string GenPrivateSharingRequestStub(const BaseType& type, std::string id);
+
+ private:
+ std::shared_ptr<Options> options_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_CPP_CION_GEN_CPP_STUB_BODY_GEN_H_
diff --git a/idlc/gen_cion/cpp_cion_stub_body_gen_cb.h b/idlc/gen_cion/cpp_cion_stub_body_gen_cb.h
new file mode 100644
index 0000000..fcf421c
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_stub_body_gen_cb.h
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_CION_GEN_CPP_STUB_BODY_GEN_CB_H_
+#define IDLC_CPP_CION_GEN_CPP_STUB_BODY_GEN_CB_H_
+
+const char CB_CTOR_FRONT[] =
+R"__cpp_cb(
+##::##(const std::string& service_name, const std::string& display_name,
+ const std::string& broker_ip, int broker_port, const std::string& user_name,
+ const std::string& password, const std::string& my_ip, int protocols) {
+ <SERVER_REGISTER>
+}
+)__cpp_cb";
+
+const char CB_DEFAULT_METHODS[] =
+R"__cpp_cb(
+##::~##() {
+ for (auto& i : services_) {
+ i->OnTerminate();
+ }
+<SERVER_UNREGISTER>
+}
+
+void ##::Listen(std::shared_ptr<##::ServiceBase::Factory> service_factory) {
+ service_factory_ = std::move(service_factory);
+ <SERVER_LISTEN>
+}
+
+void ##::Accept(std::shared_ptr<ServiceBase> service) {
+ <SERVER_ACCEPT>
+}
+
+void ##::Reject(std::shared_ptr<ServiceBase> service, std::string reason) {
+ <SERVER_REJECT>
+}
+
+void ##::Disconnect(std::shared_ptr<ServiceBase> service) {
+ auto p = service->GetPeer();
+ <SERVER_DISCONNECT>
+}
+
+void ##::SetDisplayName(std::string display_name) {
+ <SERVER_SET_DISPLAY_NAME>
+}
+
+void ##::SetOndemandLaunchEnable(bool enabled) {
+ <SERVER_SET_ONDEMAND_LAUNCH_ENABLED>
+}
+
+void ##::OnConnectionResultCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, const <MODULE_PREFIX>_connection_result_h result,
+ void *user_data) {
+}
+
+void ##::OnDisconnectedCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, void *user_data) {
+ ##* stub = static_cast<##*>(user_data);
+ char* peer_app_id = nullptr;
+ int ret = <PEER_INFO_GET_APPID1>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("<INTERNAL_PREFIX>_peer_info_get_app_id() is failed. error(%d)", ret);
+ return;
+ }
+ auto perr_app_id_auto = std::unique_ptr<char, decltype(std::free)*>(peer_app_id, std::free);
+
+ char* peer_uuid = nullptr;
+ ret = <PEER_INFO_GET_UUID1>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("<INTERNAL_PREFIX>_peer_info_get_uuid() is failed. error(%d)", ret);
+ return;
+ }
+ auto peer_uuid_auto = std::unique_ptr<char, decltype(std::free)*>(peer_uuid, std::free);
+
+ for (auto s = stub->services_.begin(); s != stub->services_.end(); s++) {
+ char* service_app_id = nullptr;
+ ret = <PEER_INFO_GET_APPID2>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("<INTERNAL_PREFIX>_peer_info_get_app_id() is failed. error(%d)", ret);
+ return;
+ }
+ auto service_app_id_auto = std::unique_ptr<char, decltype(std::free)*>(service_app_id, std::free);
+
+ char* service_uuid = nullptr;;
+ ret = <PEER_INFO_GET_UUID2>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("<INTERNAL_PREFIX>_peer_info_get_uuid() is failed. error(%d)", ret);
+ return;
+ }
+ auto service_uuid_auto = std::unique_ptr<char, decltype(std::free)*>(service_uuid, std::free);
+
+ if (strcmp(peer_app_id, service_app_id) == 0 &&
+ strcmp(peer_uuid, service_uuid) == 0) {
+ stub->services_.erase(s);
+ return;
+ }
+ }
+}
+
+void ##::OnConnectionRequestCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, void *user_data) {
+ ##* stub = static_cast<##*>(user_data);
+ auto s = stub->service_factory_->CreateService(peer_info);
+ s->OnRequested(s);
+}
+
+)__cpp_cb";
+
+const char CB_DEFAULT_THREAD_METHODS[] =
+R"__cpp_cb(
+void ##::ServiceBase::Dispatch(rpc_port_h port,
+ rpc_port_h callback_port,
+ rpc_port_parcel_h parcel,
+ std::shared_ptr<ServiceBase> service) {
+ active_object_->Send(
+ std::shared_ptr<Job>(
+ new (std::nothrow) PendingJob(
+ port, callback_port, parcel, service)));
+}
+
+##::PendingJob::PendingJob(rpc_port_h port,
+ rpc_port_h callback_port,
+ rpc_port_parcel_h parcel,
+ std::shared_ptr<ServiceBase> service)
+ : Job(this),
+ port_(port),
+ callback_port_(callback_port),
+ parcel_(parcel),
+ service_(std::move(service)) {
+}
+
+)__cpp_cb";
+
+const char CB_RUN_PENDING_JOB_FRONT[] =
+R"__cpp_cb(
+void $$::PendingJob::Run() {
+ rpc_port_parcel_h result;
+ int cmd;
+ int ret;
+ rpc_port_parcel_h p = parcel_;
+ std::shared_ptr<ServiceBase> b = service_;
+ rpc_port_h port = port_;
+
+ rpc_port_parcel_create(&result);
+ rpc_port_parcel_read_int32(parcel_, &cmd);
+
+ switch (cmd) {
+)__cpp_cb";
+
+const char CB_RUN_PENDING_JOB_BACK[] =
+R"__cpp_cb( default:
+ _E("Unknown command(%d)", cmd);
+ rpc_port_parcel_destroy(parcel_);
+ rpc_port_parcel_destroy(result);
+ return;
+ }
+
+ rpc_port_parcel_destroy(parcel_);
+ rpc_port_parcel_destroy(result);
+}
+)__cpp_cb";
+
+const char CB_ON_DATA_RECEIVED_CB[] =
+R"__cpp_cb(
+int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void *data)
+{
+ auto* cxt = static_cast<$$*>(data);
+ std::shared_ptr<ServiceBase> b;
+ rpc_port_parcel_h parcel;
+ rpc_port_h callback_port;
+
+ for (auto& i : cxt->services_) {
+ if (i->GetInstance() == instance) {
+ b = i;
+ break;
+ }
+ }
+
+ if (b.get() == nullptr) {
+ _E("Failed to find $$ context(%s)", instance);
+ return -1;
+ }
+
+ int ret = rpc_port_stub_get_port(cxt->stub_, RPC_PORT_PORT_CALLBACK, instance,
+ &callback_port);
+ if (ret != 0) {
+ _E("Failed to get callback port");
+ }
+
+ ret = rpc_port_parcel_create_from_port(&parcel, port);
+ if (ret != 0) {
+ _E("Failed to create parcel from port");
+ return ret;
+ }
+ b->Dispatch(port, callback_port, parcel, b);
+
+ return ret;
+}
+)__cpp_cb";
+
+const char CB_CTOR_SERVICE_BASE[] =
+R"__cpp_cb($$::ServiceBase::ServiceBase(<PEER_INFO_T> peer)
+ : active_object_(new ActiveObject()) {
+ int ret = <PEER_INFO_CLONE>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_peer_info_clone. error(%d)", ret);
+ return;
+ }
+})__cpp_cb";
+
+
+const char CB_FILE_PAYLOAD_SEND[] = R"__cpp_cb(
+void $$::FilePayloadSend(std::string path, <PEER_INFO_T> peer)
+{
+ <FILE_PAYLOAD_SEND>
+}
+)__cpp_cb";
+
+const char CB_CION_ON_PAYLOAD_RECEIVED_CB_FRONT[] =
+R"__cpp_cb(
+void $$::OnPayloadReceivedCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, const <PAYLOAD_T> payload,
+ <PAYLOAD_TRANSFER_STATUS_T> status,
+ void *user_data) {
+ $$* stub = static_cast<$$*>(user_data);
+ std::shared_ptr<ServiceBase> b;
+ rpc_port_parcel_h p;
+ char* peer_app_id = nullptr;
+ int ret = <PEER_INFO_GET_APPID1>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("<INTERNAL_PREFIX>_peer_info_get_app_id() is failed. error(%d)", ret);
+ return;
+ }
+ auto peer_app_id_auto = std::unique_ptr<char, decltype(std::free)*>(peer_app_id, std::free);
+
+ char* peer_uuid = nullptr;;
+ ret = <PEER_INFO_GET_UUID1>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("<INTERNAL_PREFIX>_peer_info_get_uuid() is failed. error(%d)", ret);
+ return;
+ }
+ auto peer_uuid_auto = std::unique_ptr<char, decltype(std::free)*>(peer_uuid, std::free);
+
+ for (auto& s : stub->services_) {
+ char* service_app_id = nullptr;
+ ret = <PEER_INFO_GET_APPID2>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("<INTERNAL_PREFIX>_peer_info_get_app_id() is failed. error(%d)", ret);
+ return;
+ }
+ auto service_app_id_auto = std::unique_ptr<char, decltype(std::free)*>(service_app_id, std::free);
+
+ char* service_uuid = nullptr;
+ ret = <PEER_INFO_GET_UUID2>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("<INTERNAL_PREFIX>_peer_info_get_uuid() is failed. error(%d)", ret);
+ return;
+ }
+ auto service_uuid_auto = std::unique_ptr<char, decltype(std::free)*>(service_uuid, std::free);
+
+ if (strcmp(peer_app_id, service_app_id) == 0 &&
+ strcmp(peer_uuid, service_uuid) == 0) {
+ b = s;
+ break;
+ }
+ }
+
+ if (b.get() == nullptr) {
+ _E("Failed to find service base(%s)", peer_app_id);
+ return;
+ }
+
+ <PAYLOAD_TYPE_E> type;
+ <PAYLOAD_GET_TYPE>
+ if (ret != <ERROR_NONE>) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_get_type. error(%d)", ret);
+ return;
+ }
+
+ if (type == <PAYLOAD_TYPE_FILE>) {
+ b->OnFileReceived(peer_info, payload, status);
+ return;
+ }
+
+ unsigned char *data;
+ unsigned int size;
+ <PAYLOAD_GET_DATA>
+ if (ret != <ERROR_NONE>) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_get_data. error(%d)", ret);
+ return;
+ }
+
+ ret = rpc_port_parcel_create_from_raw(&p, data, size);
+ if (ret != 0) {
+ _E("Failed to create parcel from port");
+ return;
+ }
+
+ int cmd;
+ rpc_port_parcel_read_int32(p, &cmd);
+
+ switch (cmd) {
+)__cpp_cb";
+
+const char CB_CION_ON_PAYLOAD_RECEIVED_CB_BACK[] =
+R"__cpp_cb( default:
+ _E("Unknown command(%d)", cmd);
+ rpc_port_parcel_destroy(p);
+ }
+
+ rpc_port_parcel_destroy(p);
+
+}
+)__cpp_cb";
+
+const char CB_CION_ON_DATA_RECEIVED_CB_FRONT[] =
+R"__cpp_cb(
+void $$::OnDataReceivedCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, const unsigned char *data,
+ unsigned int data_size, unsigned char **return_data,
+ unsigned int *return_data_size, void *user_data) {
+ $$* stub = static_cast<$$*>(user_data);
+ std::shared_ptr<ServiceBase> b;
+ rpc_port_parcel_h p;
+ char* peer_app_id = nullptr;
+ int ret = <PEER_INFO_GET_APPID1>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("<INTERNAL_PREFIX>_peer_info_get_app_id() is failed. error(%d)", ret);
+ return;
+ }
+ auto peer_app_id_auto = std::unique_ptr<char, decltype(std::free)*>(peer_app_id, std::free);
+
+ char* peer_uuid = nullptr;
+ ret = <PEER_INFO_GET_UUID1>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("<INTERNAL_PREFIX>_peer_info_get_uuid() is failed. error(%d)", ret);
+ return;
+ }
+ auto peer_uuid_auto = std::unique_ptr<char, decltype(std::free)*>(peer_uuid, std::free);
+
+ for (auto& s : stub->services_) {
+ char* service_app_id = nullptr;
+ ret = <PEER_INFO_GET_APPID2>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("<INTERNAL_PREFIX>_peer_info_get_app_id() is failed. error(%d)", ret);
+ return;
+ }
+ auto service_app_id_auto = std::unique_ptr<char, decltype(std::free)*>(service_app_id, std::free);
+
+ char* service_uuid = nullptr;
+ ret = <PEER_INFO_GET_UUID2>
+ if (ret != <ERROR_PREFIX>_ERROR_NONE) {
+ _E("<INTERNAL_PREFIX>_peer_info_get_uuid() is failed. error(%d)", ret);
+ return;
+ }
+ auto service_uuid_auto = std::unique_ptr<char, decltype(std::free)*>(service_uuid, std::free);
+
+ if (strcmp(peer_app_id, service_app_id) == 0 &&
+ strcmp(peer_uuid, service_uuid) == 0) {
+ b = s;
+ break;
+ }
+ }
+
+ if (b.get() == nullptr) {
+ _E("Failed to find service base(%s)", peer_app_id);
+ return;
+ }
+
+ ret = rpc_port_parcel_create_from_raw(&p, data, data_size);
+ if (ret != 0) {
+ _E("Failed to create parcel from port");
+ return;
+ }
+
+ int cmd;
+ rpc_port_parcel_read_int32(p, &cmd);
+
+ rpc_port_parcel_h result = nullptr;
+ rpc_port_parcel_create(&result);
+ switch (cmd) {
+)__cpp_cb";
+
+const char CB_CION_ON_DATA_RECEIVED_CB_BACK[] =
+R"__cpp_cb( default:
+ _E("Unknown command(%d)", cmd);
+ rpc_port_parcel_destroy(p);
+ rpc_port_parcel_destroy(result);
+ return;
+ }
+
+ void *raw_data;
+ ret = rpc_port_parcel_get_raw(result, &raw_data, return_data_size);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get raw. error(%d)", ret);
+ rpc_port_parcel_destroy(p);
+ rpc_port_parcel_destroy(result);
+ return;
+ }
+
+ *return_data = (unsigned char *)malloc(sizeof(unsigned char) * *return_data_size);
+ if (*return_data == NULL) {
+ *return_data_size = 0;
+ rpc_port_parcel_destroy(p);
+ rpc_port_parcel_destroy(result);
+ return;
+ }
+
+ memcpy(*return_data, raw_data, *return_data_size);
+
+ rpc_port_parcel_destroy(p);
+ rpc_port_parcel_destroy(result);
+}
+)__cpp_cb";
+
+#endif // IDLC_CPP_CION_GEN_CPP_STUB_BODY_GEN_CB_H_
diff --git a/idlc/gen_cion/cpp_cion_stub_header_gen.cc b/idlc/gen_cion/cpp_cion_stub_header_gen.cc
new file mode 100644
index 0000000..1edca75
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_stub_header_gen.cc
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/cpp_cion_stub_header_gen.h"
+
+namespace {
+#include "idlc/gen_cion/cpp_cion_stub_header_gen_cb.h"
+}
+
+namespace tidl {
+
+CppCionStubHeaderGen::CppCionStubHeaderGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options, std::shared_ptr<tidl::Transportable> trans)
+ : CppCionGeneratorBase(doc, trans), options_(options) {}
+
+void CppCionStubHeaderGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+
+ stream << CB_HEADER;
+
+ GenCommonHandles(stream);
+ GenServerHandles(stream);
+ GenFileHandle(stream);
+ GenConnectionHandle(stream);
+ GenCommonBase(stream);
+ GenFileBase(stream);
+ GenNamespace(stream);
+}
+
+void CppCionStubHeaderGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void CppCionStubHeaderGen::GenNamespace(std::ofstream& stream) {
+ stream << "namespace " << GetTransportable().Cpp().GenNamespace() << " ";
+ GenBrace(stream, 0, [&]() {
+ stream << "namespace " << GetFileNamespace() << " ";
+ GenBrace(stream, 0, [&]() {
+ stream << NLine(1);
+ GenStructuresForHeader(stream);
+ stream << "namespace stub ";
+ GenBrace(stream, 0, [&]() {
+ GenExceptions(stream);
+ stream << CB_JOB;
+ stream << CB_SHARED_QUEUE;
+ stream << CB_ACTIVE_OBJECT;
+ GenInterfaces(stream);
+ }, false, false);
+ stream << " // namespace stub" + NLine(1);
+ }, false, false);
+ stream << " // namespace " + GetFileNamespace() + NLine(1);
+ }, false, false);
+ stream << " // namespace " + GetTransportable().Cpp().GenNamespace() + NLine(1);
+}
+
+void CppCionStubHeaderGen::GenExceptions(std::ofstream& stream) {
+ stream << CB_EXCEPTIONS;
+}
+
+void CppCionStubHeaderGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CppCionStubHeaderGen::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ stream << NLine(1) << "class " << iface.GetID() << " final ";
+ GenBrace(stream, 0, [&]() {
+ GenPublic(stream, iface);
+ GenPrivate(stream, iface);
+ }, false, false);
+ stream << ";" << NLine(1);
+}
+
+void CppCionStubHeaderGen::GenPublic(std::ofstream& stream,
+ const Interface& iface) {
+ stream << " public:" << NLine(1);
+ stream << " class ServiceBase;" << NLine(1);
+ GenHeaderCallbacks(stream, iface, false);
+ if (options_->IsThreadEnabled())
+ stream << CB_PENDING_JOB << NLine(1);
+ GenServiceBase(stream, iface);
+ GenPublicMethods(stream, iface);
+}
+
+void CppCionStubHeaderGen::GenPrivate(std::ofstream& stream,
+ const Interface& iface) {
+ stream << " private:" << NLine(1);
+ GenMethodId(stream, iface);
+ GenDelegateId(stream, iface);
+ stream << ReplaceAll(CB_PRIVATE_MEMBERS, {
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<PAYLOAD_T>", GetTransportable().Cpp().GenPayloadType() },
+ { "<SERVER_T>", GetTransportable().Cpp().GenServerType() },
+ { "<PAYLOAD_TRANSFER_STATUS_T>",
+ GetTransportable().Cpp().GenPayloadTransferStatusType(false) },
+ { "<SECURITY_T>", GetTransportable().Cpp().GenSecurityType() },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() }
+ });
+}
+
+void CppCionStubHeaderGen::GenServiceBase(std::ofstream& stream,
+ const Interface& iface) {
+ stream << ReplaceAll(CB_SERVICE_BASE_FRONT, {
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<PAYLOAD_T>", GetTransportable().Cpp().GenPayloadType() },
+ { "<PAYLOAD_TRANSFER_STATUS_T>",
+ GetTransportable().Cpp().GenPayloadTransferStatusType(false) },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() },
+ });
+ auto& decls = iface.GetDeclarations();
+
+ for (const auto& i : decls) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+ if (!i->GetComments().empty())
+ stream << NLine(1) << AddIndent(TAB_SIZE * 2, i->GetComments());
+ stream << Tab(2) << "virtual " << ConvertTypeToString(i->GetType())
+ << " " << i->GetID() << "(";
+ GenParameters(stream, i->GetParameters());
+ stream << ") = 0;" << NLine(1);
+ }
+
+ stream << ReplaceAll(CB_SERVICE_BASE_BACK, {
+ { "<PEER_INFO_T>", GetTransportable().Cpp().GenPeerInfoType() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() }
+ }) << NLine(2);
+}
+
+void CppCionStubHeaderGen::GenPublicMethods(std::ofstream& stream,
+ const Interface& iface) {
+ stream << ReplaceAll(CB_PUBLIC_METHODS, {
+ { "##", iface.GetID() },
+ { "<MODULE_PREFIX>", GetMoudlePrefix() }
+ });
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/cpp_cion_stub_header_gen.h b/idlc/gen_cion/cpp_cion_stub_header_gen.h
new file mode 100644
index 0000000..6f63b82
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_stub_header_gen.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_CION_GEN_CPP_STUB_HEADER_GEN_H_
+#define IDLC_CPP_CION_GEN_CPP_STUB_HEADER_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/cpp_cion_gen_base.h"
+#include "idlc/options.h"
+
+namespace tidl {
+
+class CppCionStubHeaderGen : public CppCionGeneratorBase {
+ public:
+ explicit CppCionStubHeaderGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CppCionStubHeaderGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenExceptions(std::ofstream& stream);
+ void GenNamespace(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenPublic(std::ofstream& stream, const Interface& iface);
+ void GenPrivate(std::ofstream& stream, const Interface& iface);
+ void GenServiceBase(std::ofstream& stream, const Interface& iface);
+ void GenPublicMethods(std::ofstream& stream, const Interface& iface);
+
+ private:
+ std::shared_ptr<Options> options_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_CPP_GEN_CPP_STUB_HEADER_GEN_H_
diff --git a/idlc/gen_cion/cpp_cion_stub_header_gen_cb.h b/idlc/gen_cion/cpp_cion_stub_header_gen_cb.h
new file mode 100644
index 0000000..c5bda5a
--- /dev/null
+++ b/idlc/gen_cion/cpp_cion_stub_header_gen_cb.h
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_CION_GEN_CPP_STUB_HEADER_GEN_CB_H_
+#define IDLC_CPP_CION_GEN_CPP_STUB_HEADER_GEN_CB_H_
+
+const char CB_EXCEPTIONS[] =
+R"__cpp_cb(
+class Exception {};
+class NotConnectedSocketException : public Exception {};
+class InvalidProtocolException : public Exception {};
+class InvalidIOException : public Exception {};
+class UnauthorizedAccessException : public Exception {};
+class InvalidCallbackException : public Exception {};
+)__cpp_cb";
+
+const char CB_PRIVATE_MEMBERS[] =
+R"__cpp_cb(
+ void FilePayloadSend(std::string path, <PEER_INFO_T> peer);
+
+ static void OnConnectionResultCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, const <MODULE_PREFIX>_connection_result_h result,
+ void *user_data);
+ static void OnDisconnectedCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, void *user_data);
+ static void OnConnectionRequestCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, void *user_data);
+ static void OnDataReceivedCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, const unsigned char *data,
+ unsigned int data_size, unsigned char **return_data,
+ unsigned int *return_data_size, void *user_data);
+ static void OnPayloadReceivedCB(const char *service_name,
+ const <PEER_INFO_T> peer_info, const <PAYLOAD_T> payload,
+ <PAYLOAD_TRANSFER_STATUS_T> status,
+ void *user_data);
+
+ std::shared_ptr<ServiceBase::Factory> service_factory_;
+ std::list<std::shared_ptr<ServiceBase>> services_;
+ <SECURITY_T>
+ <SERVER_T> server_ = nullptr;
+)__cpp_cb";
+
+const char CB_SERVICE_BASE_FRONT[] =
+R"__cpp_cb(
+ class ServiceBase {
+ public:
+ class Factory {
+ public:
+ virtual ~Factory() = default;
+
+ /// <summary>
+ /// The method for making service instances
+ /// </summary>
+ /// <param name="peer">The client peer info</param>
+ virtual std::shared_ptr<ServiceBase> CreateService(<PEER_INFO_T> peer) = 0;
+ };
+
+ virtual ~ServiceBase() = default;
+
+ /// <summary>
+ /// Gets peer info
+ /// </summary>
+ const <PEER_INFO_T> GetPeer() const {
+ return peer_;
+ }
+
+ /// <summary>
+ /// This method will be called when file receieved from client app
+ /// </summary>
+ virtual void OnFileReceived(<PEER_INFO_T> peer_info,
+ <PAYLOAD_T> file_payload, <PAYLOAD_TRANSFER_STATUS_T> status) = 0;
+
+ /// <summary>
+ /// This method will be called when the client is connection requested
+ /// </summary>
+ virtual void OnRequested(std::shared_ptr<ServiceBase> s) = 0;
+
+ /// <summary>
+ /// This method will be called when the client is connected
+ /// </summary>
+ virtual void OnCreate() = 0;
+
+ /// <summary>
+ /// This method will be called when the client is disconnected
+ /// </summary>
+ virtual void OnTerminate() = 0;
+
+ void Dispatch(rpc_port_h port, rpc_port_h callback_port,
+ rpc_port_parcel_h parcel, std::shared_ptr<ServiceBase> service);
+
+)__cpp_cb";
+
+const char CB_SERVICE_BASE_BACK[] =
+R"__cpp_cb(
+ protected:
+ ServiceBase(<PEER_INFO_T> peer);
+
+ private:
+ <PEER_INFO_T> peer_;
+ std::unique_ptr<ActiveObject> active_object_;
+ };)__cpp_cb";
+
+const char CB_PENDING_JOB[] =
+R"__cpp_cb(
+ class PendingJob : public Job, Job::IEvent {
+ public:
+ PendingJob(rpc_port_h port, rpc_port_h callback_port,
+ rpc_port_parcel_h parcel, std::shared_ptr<ServiceBase> service_);
+
+ private:
+ void Run() override;
+
+ private:
+ rpc_port_h port_;
+ rpc_port_h callback_port_;
+ rpc_port_parcel_h parcel_;
+ std::shared_ptr<ServiceBase> service_;
+ };
+)__cpp_cb";
+
+const char CB_PUBLIC_METHODS[] =
+R"__cpp_cb(
+ /// <summary>
+ /// Constructor for this class
+ /// </summary>
+ /// <param name="service_name">The service name of server</param>
+ /// <param name="display_name">The display name of server</param>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ ##(const std::string& service_name, const std::string& display_name,
+ const std::string& broker_ip, int broker_port, const std::string& user_name,
+ const std::string& password, const std::string& my_ip, int protocols);
+ ~##();
+
+ /// <summary>
+ /// Listens to client apps
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <param name="service_factory">The factory object for making service instances</param>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">
+ /// Thrown when an application does not have the privilege to access this method.
+ /// </exception>
+ void Listen(std::shared_ptr<ServiceBase::Factory> service_factory);
+
+ /// <summary>
+ /// Accepts client apps
+ /// </summary>
+ /// <param name="service">The service object to accept <MODULE_PREFIX> client</param>
+ void Accept(std::shared_ptr<ServiceBase> service);
+
+ /// <summary>
+ /// Rejects client apps
+ /// </summary>
+ /// <param name="service">The service object to reject <MODULE_PREFIX> client</param>
+ /// <param name="reason">The reason message for rejection</param>
+ void Reject(std::shared_ptr<ServiceBase> service, std::string reason);
+
+ /// <summary>
+ /// Disconnects client apps
+ /// </summary>
+ /// <param name="service">The service object to disconnect <MODULE_PREFIX> client</param>
+ void Disconnect(std::shared_ptr<ServiceBase> service);
+
+ /// <summary>
+ /// Sets the stub display name.
+ /// The display name is a customized name for stub.
+ void SetDisplayName(std::string display_name);
+
+ /// <summary>
+ /// Sets on-demand launch state
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/d2d.remotelaunch</privilege>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">
+ /// Thrown when an application does not have the privilege to access this method.
+ /// </exception>
+ void SetOndemandLaunchEnable(bool enabled);
+
+ /// <summary>
+ /// Gets service objects which are connected
+ /// </summary>
+ /// <returns>The list of service objects which are connected</returns>
+ const std::list<std::shared_ptr<ServiceBase>>& GetServices() const {
+ return services_;
+ }
+
+)__cpp_cb";
+
+
+const char CB_JOB[] = R"__cls_job(class Job {
+ public:
+ class IEvent {
+ public:
+ virtual void Run() = 0;
+ };
+
+ Job() : handler_(nullptr) {
+ }
+
+ Job(IEvent* handler) : handler_(handler) {
+ }
+ virtual ~Job() = default;
+
+ Job(const Job& job) {
+ handler_ = job.handler_;
+ }
+
+ Job& operator = (const Job& job) {
+ if (this != &job)
+ handler_ = job.handler_;
+ return *this;
+ }
+ Job(Job&& job) noexcept {
+ handler_ = job.handler_;
+ job.handler_ = nullptr;
+ }
+
+ Job& operator = (Job&& job) noexcept {
+ if (this != &job) {
+ handler_ = job.handler_;
+ job.handler_ = nullptr;
+ }
+ return *this;
+ }
+
+ void Invoke() {
+ if (handler_)
+ handler_->Run();
+ }
+
+ private:
+ IEvent* handler_;
+};
+
+)__cls_job";
+
+const char CB_SHARED_QUEUE[] = R"__cls_shared_que(
+template <class T>
+class SharedQueue {
+ public:
+ SharedQueue() = default;
+ virtual ~SharedQueue() = default;
+
+ void Push(T item) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ queue_.push_back(item);
+ cond_var_.notify_one();
+ }
+
+ void PushFront(T item) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ queue_.push_front(item);
+ cond_var_.notify_one();
+ }
+
+ bool TryAndPop(T& item) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ if (queue_.empty())
+ return false;
+
+ item = queue_.front();
+ queue_.pop_front();
+
+ return true;
+ }
+
+ void WaitAndPop(T& item) {
+ std::unique_lock<std::mutex> lock(mutex_);
+ while (queue_.empty())
+ cond_var_.wait(lock);
+
+ item = queue_.front();
+ queue_.pop_front();
+ }
+
+ bool Empty() {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return queue_.empty();
+ }
+
+ int Size() {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return queue_.size();
+ }
+
+ private:
+ std::deque<T> queue_;
+ mutable std::mutex mutex_;
+ std::condition_variable cond_var_;
+};
+
+)__cls_shared_que";
+
+const char CB_ACTIVE_OBJECT[] = R"__cls_active_obj(class ActiveObject : public Job::IEvent {
+ public:
+ ActiveObject() {
+ thread_ = std::thread([&]{
+ do {
+ std::shared_ptr<Job> item;
+ queue_.WaitAndPop(item);
+ item->Invoke();
+ } while (!done_);
+ });
+ }
+ virtual ~ActiveObject() {
+ Quit();
+ thread_.join();
+ }
+
+ public:
+ void Send(std::shared_ptr<Job> job) {
+ queue_.Push(std::move(job));
+ }
+
+ private:
+ void Quit() {
+ Send(std::shared_ptr<Job>(new (std::nothrow) Job(this)));
+ }
+ void Run() override {
+ done_ = true;
+ }
+
+ private:
+ std::thread thread_;
+ bool done_ = false;
+ SharedQueue<std::shared_ptr<Job>> queue_;
+};
+
+)__cls_active_obj";
+
+const char CB_HEADER[] =
+R"__cpp_cb(
+#pragma once
+
+#include <bundle.h>
+#include <rpc-port-parcel.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+#include <list>
+#include <atomic>
+#include <condition_variable>
+#include <mutex>
+#include <deque>
+#include <thread>
+
+)__cpp_cb";
+
+#endif // IDLC_CPP_CION_GEN_CPP_STUB_HEADER_GEN_CB_H_
diff --git a/idlc/gen_cion/cpp_transportable.h b/idlc/gen_cion/cpp_transportable.h
new file mode 100644
index 0000000..1c6e48c
--- /dev/null
+++ b/idlc/gen_cion/cpp_transportable.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_CPP_TRANSPORTABLE_H_
+#define IDLC_GEN_CION_CPP_TRANSPORTABLE_H_
+
+#include <string>
+
+namespace tidl {
+
+class CppTransportable {
+ public:
+ virtual ~CppTransportable() = default;
+ virtual std::string GenInclude(int type = 0) const = 0;
+ virtual std::string GenClientSendAsync(std::string client,
+ std::string payload, std::string size) const = 0;
+ virtual std::string GenClientSend(std::string client, std::string data,
+ std::string data_size, std::string ret_data,
+ std::string ret_data_size) const = 0;
+ virtual std::string GenServerSendAsync(std::string server, std::string client,
+ std::string payload, std::string size) const = 0;
+ virtual std::string GenServerFileSend(std::string path, std::string server,
+ std::string peer) const = 0;
+ virtual std::string GenClientFileSend(std::string path,
+ std::string client) const = 0;
+ virtual std::string GenGroupType() const = 0;
+ virtual std::string GenPayloadTransferStatusType(bool internal_type = false) const = 0;
+ virtual std::string GenPayloadAsyncResultType() const = 0;
+ virtual std::string GenPeerInfoType() const = 0;
+ virtual std::string GenPeerInfoDestroy(std::string peer) const = 0;
+ virtual std::string GenPayloadType() const = 0;
+ virtual std::string GenClientType() const = 0;
+ virtual std::string GenSecurityType(bool definition = true) const = 0;
+ virtual std::string GenServerType() const = 0;
+ virtual std::string GenClientTryConnect(std::string client,
+ std::string peer) const = 0;
+ virtual std::string GenClientDisconnect(std::string client) const = 0;
+ virtual std::string GenClientTryDiscovery(std::string client) const = 0;
+ virtual std::string GenClientStopDiscovery(std::string client) const = 0;
+ virtual std::string GenServerRegister() const = 0;
+ virtual std::string GenServerUnregister() const = 0;
+ virtual std::string GenClientExtraHeader() const = 0;
+ virtual std::string GenClientExtraBody() const = 0;
+ virtual std::string GenServerExtraHeader() const = 0;
+ virtual std::string GenServerExtraBody() const = 0;
+ virtual std::string GenServerAccept() const = 0;
+ virtual std::string GenServerReject() const = 0;
+ virtual std::string GenServerSetDisplayName() const = 0;
+ virtual std::string GenGroupPublish() const = 0;
+ virtual std::string GenPayloadTypeEnum() const = 0;
+ virtual std::string GenPayloadTypeData() const = 0;
+ virtual std::string GenPayloadTypeFile() const = 0;
+ virtual std::string GenPayloadGetType() const = 0;
+ virtual std::string GenErrorNone() const = 0;
+ virtual std::string GenPayloadGetData() const = 0;
+ virtual std::string GenClientCreate() const = 0;
+ virtual std::string GenGroupCreate() const = 0;
+ virtual std::string GenGroupDestroy() const = 0;
+ virtual std::string GenClientDestroy() const = 0;
+ virtual std::string GenSetSecurityCA(std::string arg) const = 0;
+ virtual std::string GenSetSecurityCert(std::string arg) const = 0;
+ virtual std::string GenSetSecurityPrivateKey(std::string arg) const = 0;
+ virtual std::string GenPeerInfoClone(std::string src_peer,
+ std::string dest_peer) const = 0;
+ virtual std::string GenServerSetOnDemandLaunchEnabled() const = 0;
+ virtual std::string GenServerListen() const = 0;
+ virtual std::string GenServerDisconnect(std::string server,
+ std::string peer) const = 0;
+ virtual std::string GenPeerInfoGetAppID(std::string peer,
+ std::string appid) const = 0;
+ virtual std::string GenPeerInfoGetUUID(std::string peer,
+ std::string uuid) const = 0;
+ virtual std::string GenHeaderBase() const = 0;
+ virtual std::string GenHeaderPayloadHandle() const = 0;
+ virtual std::string GenHeaderCommonHandle() const = 0;
+ virtual std::string GenHeaderClientHandle() const = 0;
+ virtual std::string GenHeaderServerHandle() const = 0;
+ virtual std::string GenHeaderGroupHandle() const = 0;
+ virtual std::string GenHeaderConnectionHandle() const = 0;
+ virtual std::string GenHeaderPayloadBase() const = 0;
+ virtual std::string GenHeaderConnectionBase() const = 0;
+ virtual std::string GenBodyPayloadBase() const = 0;
+ virtual std::string GenBodyConnectionBase() const = 0;
+ virtual std::string GenBodyPeerInfoBase() const = 0;
+ virtual std::string GenProxyPrefix() const = 0;
+ virtual std::string GenStubPrefix() const = 0;
+ virtual std::string GenGroupPrefix() const = 0;
+ virtual std::string GenModulePrefix() const = 0;
+ virtual std::string GenErrorPrefix() const = 0;
+ virtual std::string GenNamespace() const = 0;
+ virtual std::string GenConnectionResultPrefix() const = 0;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CION_CPP_TRANSPORTABLE_H_
diff --git a/idlc/gen_cion/cs_cion_cb_version.h b/idlc/gen_cion/cs_cion_cb_version.h
new file mode 100644
index 0000000..2408488
--- /dev/null
+++ b/idlc/gen_cion/cs_cion_cb_version.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_CB_VERSION_H_
+#define IDLC_CS_CION_GEN_CS_CB_VERSION_H_
+
+const char cs_cion_cb_version[] =
+R"__cs_cb(/*
+ * Generated by tidlc $$.
+ */
+)__cs_cb";
+
+#endif // IDLC_CS_CION_GEN_CS_CB_VERSION_H_
diff --git a/idlc/gen_cion/cs_cion_gen_base.cc b/idlc/gen_cion/cs_cion_gen_base.cc
new file mode 100644
index 0000000..e6a8c21
--- /dev/null
+++ b/idlc/gen_cion/cs_cion_gen_base.cc
@@ -0,0 +1,643 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ctime>
+#include <vector>
+
+#include "idlc/gen_cion/cs_cion_gen_base.h"
+
+namespace {
+#include "idlc/gen_cion/cs_cion_cb_version.h"
+#include "idlc/gen_cion/cs_cion_gen_base_cb.h"
+}
+
+namespace tidl {
+
+CsCionGeneratorBase::CsCionGeneratorBase(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans)
+ : CionPluginBase(std::move(doc), trans) {
+ type_map_ = {
+ {"char", "byte"}, {"int", "int"}, {"short", "short"},
+ {"long", "long"}, {"string", "string"}, {"bool", "bool"},
+ {"list", "LinkedList"}, {"array", "List"}, {"float", "float"},
+ {"double", "double"}, {"bundle", "Bundle"}, {"void", "void"},
+ {"file", "string"}
+ };
+
+ parcel_type_map_ = {
+ {"char", "Byte"},
+ {"int", "Int"},
+ {"short", "Short"},
+ {"long", "Long"},
+ {"string", "String"},
+ {"bool", "Bool"},
+ {"float", "Float"},
+ {"double", "Double"},
+ {"bundle", "Bundle"},
+ {"file", "String"}
+ };
+}
+
+void CsCionGeneratorBase::GenStructures(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_STRUCTURE)
+ continue;
+ Structure& st = static_cast<Structure&>(*i);
+ GenStructure(stream, st);
+ stream << std::endl;
+ }
+}
+
+void CsCionGeneratorBase::GenStructure(std::ofstream& stream, const Structure& st) {
+ std::vector<std::string> v;
+
+ stream << Tab(1) <<"public sealed class " << st.GetID() << NLine(1);
+ GenBrace(stream, TAB_SIZE, [&]() {
+ for (const auto& i : st.GetElements()) {
+ GenTemplate(CB_PROPERTY, stream,
+ [&]()->std::string {
+ return ConvertTypeToString(i->GetType());
+ },
+ [&]()->std::string {
+ return i->GetID();
+ });
+ if (i->GetType().ToString() == "bundle") {
+ v.push_back(i->GetID() + " = " + "new Bundle()");
+ }
+ }
+
+ GenTemplate(CB_CTOR, stream,
+ [&]()->std::string {
+ return st.GetID();
+ },
+ [&]()->std::string {
+ std::string str;
+ for (auto& i : v) {
+ str += " " + i + ";\n";
+ }
+ return str;
+ });
+ });
+}
+
+void CsCionGeneratorBase::GenSerializer(std::ofstream& stream,
+ const Structure& st) {
+ stream << NLine(1) << Tab(3) << "private static void Serialize(Parcel h, "
+ << st.GetID() << " param)" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 3, [&]() {
+ for (const auto& i : st.GetElements()) {
+ auto& t = i->GetType();
+ if (!t.IsUserDefinedType() && t.GetMetaType() == nullptr) {
+ stream << Tab(4) << "h.Write"
+ << ConvertTypeToParcelType(t.ToString())
+ << "(param."
+ << i->GetID()
+ << ");" << NLine(1);
+ } else {
+ stream << Tab(4) << "Serialize(h, param." << i->GetID()
+ << ");" << NLine(1);
+ }
+ }
+ });
+ stream << NLine(1);
+
+ stream << Tab(3) << "private static void Deserialize(Parcel h, "
+ << st.GetID() << " param)" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 3, [&]() {
+ for (const auto& i : st.GetElements()) {
+ auto& t = i->GetType();
+ if (!t.IsUserDefinedType() && t.GetMetaType() == nullptr) {
+ stream << Tab(4) << "var " << i->GetID() << " = "
+ << "h.Read"
+ << ConvertTypeToParcelType(t.ToString())
+ << "();" << NLine(1);
+ stream << Tab(4) << "param." << i->GetID() << " = " << i->GetID()
+ << ";" << NLine(1);
+ } else {
+ stream << Tab(4) << "param." << i->GetID() << " = new "
+ << ConvertTypeToString(t)
+ << "();" << NLine(1);
+ stream << Tab(4) << "Deserialize(h, param." << i->GetID()
+ << ");" << NLine(1);
+ }
+ }
+ });
+}
+
+void CsCionGeneratorBase::GenSerializer(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() == Block::TYPE_STRUCTURE) {
+ const Structure& st = static_cast<const Structure&>(*i);
+ GenSerializer(stream, st);
+ }
+ }
+}
+
+std::string CsCionGeneratorBase::GetFullNameFromType(const BaseType& type,
+ const Interface& iface) {
+ std::string str;
+ if (IsDelegateType(iface, type))
+ str += iface.GetID() + "_";
+
+ str += type.ToString();
+
+ if (type.GetMetaType() != nullptr) {
+ str += "_";
+ str += GetFullNameFromType(*type.GetMetaType(), iface);
+ }
+
+ return str;
+}
+
+std::string CsCionGeneratorBase::GetFullNameFromType(const BaseType& type) {
+ std::string str;
+
+ str += type.ToString();
+
+ if (type.GetMetaType() != nullptr) {
+ str += "_";
+ str += GetFullNameFromType(*type.GetMetaType());
+ }
+
+ return str;
+}
+
+bool CsCionGeneratorBase::HasFile(const Interface& iface, const BaseType& type) {
+ if (type.ToString() == "list" || type.ToString() == "array") {
+ std::string name = GetFullNameFromType(type, iface);
+ if (name == "array_file" || name == "list_file" || name == "file")
+ return true;
+ } else if (type.ToString() == "file") {
+ return true;
+ }
+
+ return false;
+}
+
+bool CsCionGeneratorBase::HasFile(const BaseType& type) {
+ if (type.ToString() == "list" || type.ToString() == "array") {
+ std::string name = GetFullNameFromType(type);
+ if (name == "array_file" || name == "list_file" || name == "file")
+ return true;
+ } else if (type.ToString() == "file") {
+ return true;
+ }
+
+ return false;
+}
+
+bool CsCionGeneratorBase::HasFile(const Interface& iface, const Declaration& decl, bool is_proxy) {
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (is_proxy) {
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+ } else if (decl.GetMethodType() == Declaration::MethodType::DELEGATE) {
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+ } else {
+ if (param_type.GetDirection() == ParameterType::Direction::IN)
+ continue;
+ }
+
+ if (HasFile(iface, param_type.GetBaseType()) == true)
+ return true;
+ }
+
+ if (is_proxy)
+ return false;
+
+ return HasFile(iface, decl.GetType());
+}
+
+
+void CsCionGeneratorBase::GenShareFile(std::ofstream& stream, const Interface& iface, bool is_proxy) {
+ bool hasFile = false;
+
+ for (const auto& d : iface.GetDeclarations()) {
+ hasFile = HasFile(iface, *d, is_proxy);
+ if (hasFile == true)
+ break;
+ }
+
+ if (hasFile == false)
+ return;
+
+ ReplaceAll(CB_SHARE_FILE_DEF)
+ .Change("<SHARE_FILE>", GetTransportable().Cs().GenFileSend("path"))
+ .Out(stream);
+}
+
+void CsCionGeneratorBase::AddSerializerList(const BaseType& type) {
+ if (type.GetMetaType() != nullptr) {
+ serializer_list_[ConvertTypeToString(type)] = &type;
+ AddSerializerList(*type.GetMetaType());
+ }
+}
+
+void CsCionGeneratorBase::GenListSerializer(std::ofstream& stream,
+ const BaseType& type) {
+ stream << NLine(1) << Tab(3) << "private static void Serialize(Parcel h, "
+ << ConvertTypeToString(type) << " param)" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 3, [&]() {
+ stream << Tab(4)
+ << "h.WriteArrayCount(param.Count);"
+ << NLine(1);
+ stream << Tab(4) << "foreach (var i in param)" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 4, [&]() {
+ auto* ptr = type.GetMetaType();
+ if (ptr == nullptr) return;
+
+ auto& mt = *ptr;
+ if (!mt.IsUserDefinedType() && mt.GetMetaType() == nullptr) {
+ stream << Tab(5) << "h.Write"
+ << ConvertTypeToParcelType(mt.ToString())
+ << "(i);" << NLine(1);
+ } else {
+ stream << Tab(5) << "Serialize(h, i);" << NLine(1);
+ }
+ });
+ });
+ stream << NLine(1);
+
+ stream << Tab(3) << "private static void Deserialize(Parcel h, "
+ << ConvertTypeToString(type) << " param)" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 3, [&]() {
+ stream << Tab(4)
+ << "int l = h.ReadArrayCount();"
+ << NLine(1);
+ stream << Tab(4) << "for (int i = 0; i < l; i++)" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 4, [&]() {
+ auto* ptr = type.GetMetaType();
+ if (ptr == nullptr)
+ return;
+
+ auto& mt = *ptr;
+ if (!mt.IsUserDefinedType() && mt.GetMetaType() == nullptr) {
+ stream << Tab(5) << "var v = h.Read"
+ << ConvertTypeToParcelType(mt.ToString())
+ << "();" << NLine(1);
+ } else {
+ stream << Tab(5) << "var v = new " << ConvertTypeToString(mt)
+ << "();" << NLine(1);
+ stream << Tab(5) << "Deserialize(h, v);" << NLine(1);
+ }
+ if (type.ToString() == "list")
+ stream << Tab(5) << "param.AddLast(v);" << NLine(1);
+ else
+ stream << Tab(5) << "param.Add(v);" << NLine(1);
+ });
+ });
+}
+
+void CsCionGeneratorBase::GenListSerializer(std::ofstream& stream) {
+ serializer_list_.clear();
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() == Block::TYPE_STRUCTURE) {
+ const Structure& st = static_cast<const Structure&>(*i);
+ for (const auto& j : st.GetElements()) {
+ auto& t = j->GetType();
+ AddSerializerList(t);
+ }
+ } else if (i->GetType() == Block::TYPE_INTERFACE) {
+ const Interface& iface = static_cast<const Interface&>(*i);
+ for (const auto& j : iface.GetDeclarations()) {
+ auto& t = j->GetType();
+ AddSerializerList(t);
+ for (const auto& k : j->GetParameters()) {
+ auto& t1 = k->GetParameterType().GetBaseType();
+ AddSerializerList(t1);
+ }
+ }
+ }
+ }
+
+ for (auto& p : serializer_list_) {
+ const BaseType* t = p.second;
+ GenListSerializer(stream, *t);
+ }
+}
+
+std::string CsCionGeneratorBase::ConvertTypeToString(const BaseType& type) {
+ if (type.IsUserDefinedType())
+ return type.ToString();
+
+ if (type.GetMetaType() != nullptr)
+ return type_map_[type.ToString()] + "<" +
+ ConvertTypeToString(*(type.GetMetaType())) + ">";
+
+ return type_map_[type.ToString()];
+}
+
+std::string CsCionGeneratorBase::ConvertTypeToParcelType(const std::string& key) {
+ return parcel_type_map_[key];
+}
+
+std::string CsCionGeneratorBase::ConvertTypeToDeserializer(
+ const BaseType& type, std::string id, std::string parcel,
+ bool make_new_type, std::string iface_id) {
+ if (type.IsUserDefinedType() ||
+ type.GetMetaType() != nullptr) {
+ std::string n;
+
+ if (type.GetMetaType() != nullptr)
+ n = ConvertTypeToString(type);
+ else
+ n = type.ToString();
+
+ std::string ret;
+
+ if (make_new_type)
+ ret = n + " ";
+
+ if (IsDelegateType(type)) {
+ ret += id + " = new " + n
+ + "(peerInfo, new WeakReference(b), new WeakReference(this));\n";
+ ret += "CallbackBase.";
+ } else {
+ ret += id + " = new " + n +"();\n";
+ }
+ if (iface_id != "")
+ ret += iface_id + ".";
+ ret += "Deserialize(" + parcel + ", " + id +");\n";
+ return ret;
+ }
+
+ std::string ret;
+ if (make_new_type) {
+ ret = ConvertTypeToString(type) + " "
+ + id + " = " + parcel + ".Read"
+ + parcel_type_map_[type.ToString()]
+ + "();\n";
+ } else {
+ ret = id + " = " + parcel + ".Read"
+ + parcel_type_map_[type.ToString()]
+ + "();\n";
+ }
+
+ return ret;
+}
+
+std::string CsCionGeneratorBase::ConvertTypeToSerializer(
+ const BaseType& type, std::string id, std::string parcel,
+ std::string iface_id) {
+ std::string ret;
+
+ if (type.IsUserDefinedType() ||
+ type.GetMetaType() != nullptr) {
+ if (IsDelegateType(type))
+ return "CallbackBase.Serialize(" + parcel + ", " + id + ");\n";
+ if (iface_id != "")
+ ret += iface_id + ".";
+ ret += "Serialize(" + parcel + ", " + id + ");\n";
+ return ret;
+ }
+
+ ret += parcel + ".Write"
+ + parcel_type_map_[type.ToString()] + "(" + id + ");\n";
+
+ return ret;
+}
+
+std::string CsCionGeneratorBase::Tab(int cnt) {
+ std::string t;
+
+ for (int i = 0; i < cnt; i++) {
+ t += " ";
+ }
+
+ return t;
+}
+
+std::string CsCionGeneratorBase::NLine(int cnt) {
+ std::string t;
+
+ for (int i = 0; i < cnt; i++) {
+ t += "\n";
+ }
+
+ return t;
+}
+
+void CsCionGeneratorBase::GenWriteBundle(std::ofstream& stream,
+ const std::string& id) {
+ GenTemplate(CB_WRITE_BUNDLE, stream,
+ [&]()->std::string {
+ return id;
+ },
+ [&]()->std::string {
+ return id;
+ });
+}
+
+void CsCionGeneratorBase::GenMethodId(std::ofstream& stream,
+ const Interface& iface, bool is_group) {
+ stream << Tab(3) << "private enum MethodId : int" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 3, [&]() {
+ int cnt = 0;
+ if (!is_group) {
+ stream << Tab(4) << "__Result = 0," << NLine(1);
+ stream << Tab(4) << "__Callback = 1," << NLine(1);
+ cnt = 2;
+ }
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+ stream << Tab(4)
+ << i->GetID() << " = " << cnt++ << "," << NLine(1);
+ }
+ });
+}
+
+void CsCionGeneratorBase::GenDelegateId(std::ofstream& stream,
+ const Interface& iface) {
+ stream << Tab(3) << "private enum DelegateId : int" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 3, [&]() {
+ int cnt = 1;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+ stream << Tab(4)
+ << i->GetID() << " = " << cnt++ << "," << NLine(1);
+ }
+ });
+ stream << NLine(1);
+}
+
+void CsCionGeneratorBase::GenDeclaration(std::ofstream& stream,
+ const Declaration& decl, bool semicol) {
+ stream << ConvertTypeToString(decl.GetType()) << " "
+ << decl.GetID() << "(";
+ GenParameters(stream, decl.GetParameters());
+ if (semicol)
+ stream << ");";
+ else
+ stream << ")";
+}
+
+void CsCionGeneratorBase::GenParameters(std::ofstream& stream,
+ const Parameters& ps) {
+ stream << GetParameters(ps);
+}
+
+std::string CsCionGeneratorBase::GetParameters(const Parameters& ps) {
+ bool first = true;
+ std::string ret;
+ for (const auto& i : ps) {
+ if (!first) {
+ ret += ", ";
+ }
+
+ auto dir = i->GetParameterType().GetDirection();
+ if (dir == ParameterType::Direction::OUT) {
+ ret += "out ";
+ } else if (dir == ParameterType::Direction::REF) {
+ ret += "ref ";
+ }
+
+ ret += ConvertTypeToString(i->GetParameterType().GetBaseType())
+ + " " + i->GetID();
+ first = false;
+ }
+
+ return ret;
+}
+
+void CsCionGeneratorBase::GenCallbacks(std::ofstream& stream,
+ const Interface& iface, bool is_proxy) {
+ stream << CB_CALLBACK_BASE;
+
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+ GenCallback(stream, *i, iface.GetID(), is_proxy);
+ }
+}
+
+void CsCionGeneratorBase::GenCallback(std::ofstream& stream,
+ const Declaration& decl,
+ const std::string& id, bool is_proxy) {
+ stream << Tab(3) << "public sealed class " << decl.GetID()
+ << " : CallbackBase" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 3, [&]() {
+ if (is_proxy) {
+ GenTemplate(
+ CB_CALLBACK_CTOR_PROXY, stream,
+ [&]()->std::string {
+ return decl.GetID();
+ },
+ [&]()->std::string {
+ return decl.GetID();
+ });
+ } else {
+ GenTemplate(
+ CB_CALLBACK_CTOR_STUB, stream,
+ [&]()->std::string {
+ return decl.GetID();
+ },
+ [&]()->std::string {
+ return decl.GetID();
+ },
+ [&]()->std::string {
+ return id;
+ });
+ }
+ stream << NLine(1);
+
+ if (is_proxy) {
+ stream << Tab(4) << "public delegate void Callback(";
+ GenParameters(stream, decl.GetParameters());
+ stream << ");" << NLine(1);
+ stream << Tab(4) << "public event Callback Received;" << NLine(2);
+ GenReceivedEvent(stream, decl, id);
+ } else {
+ GenTemplate(
+ CB_CALLBACK_STUB_MEMBERS, stream,
+ [&]()->std::string {
+ return id;
+ });
+ GenInvokeMethod(stream, decl, id);
+ }
+ });
+ stream << NLine(1);
+}
+
+void CsCionGeneratorBase::GenReceivedEvent(std::ofstream& stream,
+ const Declaration& decl,
+ const std::string& id) {
+ stream << Tab(4) << "internal override void OnReceivedEvent(Parcel parcel)"
+ << NLine(1);
+ GenBrace(stream, TAB_SIZE * 4, [&]() {
+ int cnt = 1;
+ for (const auto& i : decl.GetParameters()) {
+ std::string v = "param" + std::to_string(cnt);
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, "parcel", true, id);
+ stream << AddIndent(TAB_SIZE * 5, c);
+ cnt++;
+ }
+
+ cnt = 1;
+ stream << Tab(5) << "Received?.Invoke(";
+ for (auto i = decl.GetParameters().begin();
+ i != decl.GetParameters().end(); ++i) {
+ if (cnt != 1) {
+ stream << ", ";
+ }
+ std::string v = "param" + std::to_string(cnt);
+ stream << v;
+ cnt++;
+ }
+ stream << ");" << NLine(1);
+ });
+ stream << NLine(1);
+}
+
+void CsCionGeneratorBase::GenInvokeMethod(std::ofstream& stream,
+ const Declaration& decl,
+ const std::string& id) {
+ GenTemplate(CB_CALLBACK_INVOKE_METHOD, stream,
+ [&]()->std::string {
+ return GetParameters(decl.GetParameters());
+ },
+ [&]()->std::string {
+ std::string m;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p", id);
+ }
+ return AddIndent(TAB_SIZE * 6, m);
+ },
+ [&]()->std::string {
+ std::string m;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if(HasFile(pt.GetBaseType()))
+ m += "_serverBase.TryShareFile(" + i->GetID() + ");\n";
+ }
+ return AddIndent(TAB_SIZE * 6, m);
+ });
+}
+
+void CsCionGeneratorBase::GenVersion(std::ofstream& stream) {
+ GenTemplate(::cs_cion_cb_version, stream,
+ [&]()->std::string {
+ return FULLVER;
+ });
+ stream << NLine(1);
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/cs_cion_gen_base.h b/idlc/gen_cion/cs_cion_gen_base.h
new file mode 100644
index 0000000..27def63
--- /dev/null
+++ b/idlc/gen_cion/cs_cion_gen_base.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_GEN_BASE_H_
+#define IDLC_CS_CION_GEN_CS_GEN_BASE_H_
+
+#include <memory>
+#include <string>
+#include <map>
+
+#include "idlc/ast/type.h"
+#include "idlc/ast/structure.h"
+#include "idlc/gen_cion/cion_plugin_base.h"
+
+namespace tidl {
+
+class CsCionGeneratorBase : public CionPluginBase {
+ public:
+ explicit CsCionGeneratorBase(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CsCionGeneratorBase() = default;
+
+ void GenVersion(std::ofstream& stream);
+ void GenStructures(std::ofstream& stream);
+ void GenStructure(std::ofstream& stream, const Structure& st);
+ void GenSerializer(std::ofstream& stream);
+ void GenSerializer(std::ofstream& stream, const Structure& st);
+ void GenListSerializer(std::ofstream& stream);
+ void GenListSerializer(std::ofstream& stream, const BaseType& type);
+ void GenShareFile(std::ofstream& stream, const Interface& iface, bool is_proxy);
+ void GenMethodId(std::ofstream& stream, const Interface& iface, bool is_group = false);
+ void GenDelegateId(std::ofstream& stream, const Interface& iface);
+ void GenDeclaration(std::ofstream& stream,
+ const Declaration& decl, bool semicol = true);
+ void GenParameters(std::ofstream& stream, const Parameters& ps);
+ void GenCallbacks(std::ofstream& stream, const Interface& iface,
+ bool is_proxy);
+
+ std::string GetFullNameFromType(const BaseType& type, const Interface& iface);
+ std::string GetFullNameFromType(const BaseType& type);
+ bool HasFile(const Interface& iface, const Declaration& decl, bool is_proxy);
+ bool HasFile(const Interface& iface, const BaseType& type);
+ bool HasFile(const BaseType& type);
+ std::string ConvertTypeToString(const BaseType& type);
+ std::string ConvertTypeToDeserializer(const BaseType& type,
+ std::string id, std::string parcel,
+ bool make_new_type = true,
+ const std::string iface_id = "");
+ std::string ConvertTypeToSerializer(const BaseType& type,
+ std::string id, std::string parcel,
+ const std::string iface_id = "");
+ std::string ConvertTypeToParcelType(const std::string& key);
+ std::string GetParameters(const Parameters& ps);
+ std::string Tab(int cnt);
+ std::string NLine(int cnt);
+
+ protected:
+ const int TAB_SIZE = 4;
+
+ private:
+ void GenWriteBundle(std::ofstream& stream, const std::string& id);
+ void AddSerializerList(const BaseType& type);
+ void GenCallback(std::ofstream& stream, const Declaration& decl,
+ const std::string& id, bool is_proxy);
+ void GenReceivedEvent(std::ofstream& stream, const Declaration& decl,
+ const std::string& id);
+ void GenInvokeMethod(std::ofstream& stream, const Declaration& decl,
+ const std::string& id);
+
+ private:
+ std::map<std::string, std::string> type_map_;
+ std::map<std::string, std::string> parcel_type_map_;
+ std::map<std::string, const BaseType*> serializer_list_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_CS_CION_GEN_CS_GEN_BASE_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/cs_cion_gen_base_cb.h b/idlc/gen_cion/cs_cion_gen_base_cb.h
new file mode 100644
index 0000000..7bcd81e
--- /dev/null
+++ b/idlc/gen_cion/cs_cion_gen_base_cb.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_BASE_CB_H_
+#define IDLC_CS_CION_BASE_CB_H_
+
+const char CB_CALLBACK_BASE[] =
+R"__cs_cb(
+ public abstract class CallbackBase
+ {
+ internal int Id;
+ internal int SeqId;
+ internal bool Once;
+ private static volatile int _seqNum = 0;
+
+ public string Tag
+ {
+ get
+ {
+ return Id.ToString() + "::" + SeqId.ToString();
+ }
+ }
+
+ public CallbackBase(int delegateId, bool once)
+ {
+ Id = delegateId;
+ SeqId = _seqNum++;
+ Once = once;
+ }
+
+ internal virtual void OnReceivedEvent(Parcel p) {}
+
+ internal static void Serialize(Parcel h, CallbackBase param)
+ {
+ h.WriteInt(param.Id);
+ h.WriteInt(param.SeqId);
+ h.WriteBool(param.Once);
+ }
+
+ internal static void Deserialize(Parcel h, CallbackBase param)
+ {
+ param.Id = h.ReadInt();
+ param.SeqId = h.ReadInt();
+ param.Once = h.ReadBool();
+ }
+ }
+
+)__cs_cb";
+
+const char CB_CALLBACK_CTOR_PROXY[] =
+R"__cs_cb( public $$(bool once = false) : base((int)DelegateId.$$, once)
+ {
+ }
+)__cs_cb";
+
+const char CB_CALLBACK_CTOR_STUB[] =
+R"__cs_cb( internal $$(PeerInfo peerInfo, WeakReference service, WeakReference serverBase) : base((int)DelegateId.$$, false)
+ {
+ _peerInfo = peerInfo;
+ _service = service;
+ _serverBase = ($$)serverBase.Target;
+ }
+)__cs_cb";
+
+const char CB_CALLBACK_STUB_MEMBERS[] =
+R"__cs_cb( private PeerInfo _peerInfo;
+ private WeakReference _service;
+ private bool _valid = true;
+ private $$ _serverBase;
+)__cs_cb";
+
+const char CB_CALLBACK_INVOKE_METHOD[] =
+R"__cs_cb(
+ public void Invoke($$)
+ {
+ if (!_service.IsAlive)
+ throw new InvalidProtocolException();
+ if (Once && !_valid)
+ throw new InvalidCallbackException();
+
+ using (var p = new Parcel())
+ {
+ p.WriteInt((int)MethodId.__Callback);
+ Serialize(p, this);
+$$
+ // Send
+ DataPayload dp = new DataPayload(p.ToBytes());
+ _serverBase.SendPayloadAsync(dp);
+ _valid = false;
+
+$$
+ }
+ }
+)__cs_cb";
+
+const char CB_PROPERTY[] = R"__cs_cb( public $$ $$ { get; set; }
+)__cs_cb";
+
+const char CB_CTOR[] = R"__cs_cb(
+ public $$()
+ {
+$$
+ }
+)__cs_cb";
+
+const char CB_WRITE_BUNDLE[] =
+R"__cs_cb(
+ if (param.$$ != null)
+ {
+ h.WriteBundle(param.$$);
+ }
+ else
+ {
+ h.WriteBundle(new Bundle());
+ }
+)__cs_cb";
+
+
+const char CB_SHARE_FILE_DEF[] =
+R"__cs_cb(
+ private void TryShareFile(IEnumerable<string> paths)
+ {
+ if (paths == null)
+ throw new ArgumentException("Invalid path");
+
+ foreach (string path in paths)
+ {
+ TryShareFile(path);
+ }
+
+ }
+
+ private void TryShareFile(string path)
+ {
+ <SHARE_FILE>
+ }
+)__cs_cb";
+
+#endif // IDLC_CS_CION_BASE_CB_H_
diff --git a/idlc/gen_cion/cs_cion_group_gen.cc b/idlc/gen_cion/cs_cion_group_gen.cc
new file mode 100644
index 0000000..1924610
--- /dev/null
+++ b/idlc/gen_cion/cs_cion_group_gen.cc
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/cs_cion_group_gen.h"
+
+namespace {
+#include "idlc/gen_cion/cs_cion_group_gen_cb.h"
+}
+
+namespace tidl {
+
+CsCionGroupGen::CsCionGroupGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans)
+ : CsCionGeneratorBase(doc, trans) {}
+
+void CsCionGroupGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ stream << GetTransportable().Cs().GenInclude();
+ GenNamespace(stream);
+}
+
+void CsCionGroupGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void CsCionGroupGen::GenNamespace(std::ofstream& stream) {
+ stream << NLine(1);
+ stream << "namespace Cion" << NLine(1);
+ GenBrace(stream, 0, [&]() {
+ stream << "namespace " << GetFileNamespace() << NLine(1);
+ GenBrace(stream, 0, [&]() {
+ GenStructures(stream);
+ stream << Tab(1) << "namespace Group" << NLine(1);
+ GenBrace(stream, TAB_SIZE, [&]() {
+ GenInterfaces(stream);
+ });
+ });
+ });
+}
+
+void CsCionGroupGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ GenInterface(stream, iface);
+ stream << NLine(1);
+ }
+}
+
+void CsCionGroupGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ stream << Tab(2) << "public class " << iface.GetID()
+ << " : GroupBase" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 2, [&]() {
+ ReplaceAll(CB_DATA_MEMBERS)
+ .Change("<PEER_INFO_T>", GetTransportable().Cs().GenPeerInfoType())
+ .Out(stream);
+ GenEvents(stream, iface);
+ stream << NLine(1);
+ GenMethodId(stream, iface, true);
+ ReplaceAll(CB_EVENT_METHODS)
+ .Change("<PEER_INFO_T>", GetTransportable().Cs().GenPeerInfoType())
+ .Out(stream);
+ GenSerializer(stream);
+ GenListSerializer(stream);
+ GenCtor(stream, iface);
+ GenFinalizer(stream, iface);
+ GenCionPayloadReceivedEvent(stream, iface);
+ GenMethods(stream, iface);
+ });
+}
+
+void CsCionGroupGen::GenEvents(std::ofstream& stream, const Interface& iface) {
+ stream << NLine(1);
+ for (const auto& decl : iface.GetDeclarations())
+ GenEvent(stream, *decl);
+}
+
+void CsCionGroupGen::GenEvent(std::ofstream& stream, const Declaration& decl) {
+ stream << Tab(3) << "public delegate void " << decl.GetID()
+ << "EventHandler(object sender, PeerInfo peer";
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT)
+ continue;
+ stream << ", " << i->GetParameterType().GetBaseType().ToString() << " "
+ << i->GetID();
+ }
+ stream << ");" << NLine(1);
+ stream << Tab(3) << "public event " << decl.GetID() << "EventHandler "
+ << decl.GetID() << "Event;" << NLine(1);
+}
+
+void CsCionGroupGen::GenCtor(std::ofstream& stream, const Interface& iface) {
+ stream << GetTransportable().Cs().GenGroupBaseCtor(iface);
+}
+
+void CsCionGroupGen::GenFinalizer(std::ofstream& stream,
+ const Interface& iface) {
+ stream << ReplaceAll(CB_FINALIZER, "##", iface.GetID());
+}
+
+void CsCionGroupGen::GenMethods(std::ofstream& stream, const Interface& iface) {
+ auto& decls = iface.GetDeclarations();
+
+ for (const auto& i : decls) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ stream << NLine(1);
+ if (!i->GetComments().empty())
+ stream << AddIndent(TAB_SIZE * 3, i->GetComments());
+
+ stream << Tab(3) << "public ";
+ GenDeclaration(stream, *i, false);
+ stream << NLine(1);
+ GenBrace(stream, TAB_SIZE * 3, [&]() {
+ GenInvocation(stream, *i);
+ });
+ }
+}
+
+void CsCionGroupGen::GenInvocation(std::ofstream& stream,
+ const Declaration& decl) {
+ GenTemplate(CB_INVOCATION_PRE, stream,
+ [&]()->std::string {
+ std::string st;
+ st += Tab(5) + "p.WriteInt((int)MethodId." + decl.GetID() + ");" +
+ NLine(1);
+ std::string m;
+ std::string l;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT)
+ continue;
+ m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p");
+ }
+
+ st += AddIndent(TAB_SIZE * 5, m) + NLine(1);
+
+ st += Tab(5) + "lock (_lock)" + NLine(1);
+ st += Tab(5) + "{" + NLine(1);
+ if (!l.empty())
+ st += AddIndent(TAB_SIZE * 6, l) + NLine(1);
+
+ // Deserialize
+ st += CB_ASYNC_INVOCATION_MID;
+ st += Tab(5) + "}";
+
+ return st;
+ });
+}
+
+void CsCionGroupGen::GenCionPayloadReceivedEvent(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_ON_PAYLOAD_RECEIVED_FRONT)
+ .Change("<PEER_INFO_T>", GetTransportable().Cs().GenPeerInfoType())
+ .Change("<PAYLOAD_T>", GetTransportable().Cs().GenPayloadType())
+ .Out(stream);
+
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE ||
+ i->GetMethodType() == Declaration::MethodType::SYNC)
+ continue;
+ stream << Tab(6) << "case (int)MethodId." << i->GetID() << ":" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 6, [&]() {
+ GenHandlerInvocation(stream, *i);
+ stream << Tab(7) << "break;" << NLine(1);
+ });
+ }
+
+ stream << CB_ON_PAYLOAD_RECEIVED_BACK << NLine(1);
+}
+
+void CsCionGroupGen::GenHandlerInvocation(std::ofstream& stream,
+ const Declaration& decl) {
+ int cnt = 1;
+ // Deserialize
+ for (const auto& i : decl.GetParameters()) {
+ std::string v = "param" + std::to_string(cnt);
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, "parcelReceived");
+ stream << AddIndent(TAB_SIZE * 7, c);
+ cnt++;
+ }
+
+ // Invoke
+ std::string m;
+ m += decl.GetID() + "Event?.Invoke(this, peerInfo";
+ cnt = 1;
+ for (auto i = decl.GetParameters().begin();
+ i != decl.GetParameters().end(); ++i) {
+ m += ", param" + std::to_string(cnt++);
+ }
+
+ m += ");\n";
+ stream << AddIndent(TAB_SIZE * 7, m);
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/cs_cion_group_gen.h b/idlc/gen_cion/cs_cion_group_gen.h
new file mode 100644
index 0000000..413888b
--- /dev/null
+++ b/idlc/gen_cion/cs_cion_group_gen.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_GROUP_GEN_H_
+#define IDLC_CS_CION_GEN_CS_GROUP_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/cs_cion_gen_base.h"
+
+namespace tidl {
+
+class CsCionGroupGen : public CsCionGeneratorBase {
+ public:
+ explicit CsCionGroupGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CsCionGroupGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenEvents(std::ofstream& stream, const Interface& iface);
+ void GenEvent(std::ofstream& stream, const Declaration& decl);
+ void GenCtor(std::ofstream& stream, const Interface& iface);
+ void GenFinalizer(std::ofstream& stream, const Interface& iface);
+ void GenMethods(std::ofstream& stream, const Interface& iface);
+ void GenInvocation(std::ofstream& stream, const Declaration& decl);
+ void GenCionPayloadReceivedEvent(std::ofstream& stream,
+ const Interface& iface);
+ void GenHandlerInvocation(std::ofstream& stream,
+ const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_CS_CION_GEN_CS_GROUP_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/cs_cion_group_gen_cb.h b/idlc/gen_cion/cs_cion_group_gen_cb.h
new file mode 100644
index 0000000..09d3813
--- /dev/null
+++ b/idlc/gen_cion/cs_cion_group_gen_cb.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_GROUP_GEN_CB_H_
+#define IDLC_CS_CION_GEN_CS_GROUP_GEN_CB_H_
+
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
+const char CB_DATA_MEMBERS[] =
+R"__cs_cb( public delegate void JoinedHandler(object sender, <PEER_INFO_T> peerInfo);
+ public delegate void LeftHandler(object sender, <PEER_INFO_T> peerInfo);
+
+ /// <summary>
+ /// This event will be invoked when the peer group app is joined to the topic.
+ /// </summary>
+ public event JoinedHandler Joined;
+
+ /// <summary>
+ /// This event will be invoked after the peer group app was left from the topic.
+ /// </summary>
+ public event LeftHandler Left;
+
+ public string TopicName;
+
+ private Object _lock = new Object();
+)__cs_cb";
+
+const char CB_FINALIZER[] =
+R"__cs_cb(
+ ~##()
+ {
+ base.Unsubscribe();
+ }
+)__cs_cb";
+
+const char CB_EVENT_METHODS[] =
+R"__cs_cb(
+ protected override void OnJoined(<PEER_INFO_T> peerInfo)
+ {
+ Joined?.Invoke(this, peerInfo);
+ }
+
+ protected override void OnLeft(<PEER_INFO_T> peerInfo)
+ {
+ Left?.Invoke(this, peerInfo);
+ }
+)__cs_cb";
+
+const char CB_ON_PAYLOAD_RECEIVED_FRONT[] =
+R"__cs_cb(
+ protected override void OnPayloadReceived(<PAYLOAD_T> payload, <PEER_INFO_T> peerInfo)
+ {
+ Parcel parcelReceived;
+
+ try
+ {
+ parcelReceived = new Parcel(((DataPayload)payload).Data);
+ }
+ catch (InvalidIOException)
+ {
+ return;
+ }
+
+ using (parcelReceived)
+ {
+ int cmd = parcelReceived.ReadInt();
+ switch (cmd)
+ {
+)__cs_cb";
+
+const char CB_ON_PAYLOAD_RECEIVED_BACK[] =
+R"__cs_cb(
+ default:
+ // log here?
+ break;
+ }
+ }
+ }
+)__cs_cb";
+
+const char CB_INVOCATION_PRE[] =
+R"__cs_cb( using (Parcel p = new Parcel())
+ {
+$$
+ }
+)__cs_cb";
+
+const char CB_ASYNC_INVOCATION_MID[] =
+R"__cs_cb( // Send
+ DataPayload dp = new DataPayload(p.ToBytes());
+ base.Publish(dp);
+)__cs_cb";
+
+#endif // IDLC_CS_CION_GEN_CS_PROXY_GEN_CB_H_
diff --git a/idlc/gen_cion/cs_cion_proxy_gen.cc b/idlc/gen_cion/cs_cion_proxy_gen.cc
new file mode 100644
index 0000000..3971498
--- /dev/null
+++ b/idlc/gen_cion/cs_cion_proxy_gen.cc
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/cs_cion_proxy_gen.h"
+
+namespace {
+#include "idlc/gen_cion/cs_cion_proxy_gen_cb.h"
+}
+
+namespace tidl {
+
+CsCionProxyGen::CsCionProxyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans)
+ : CsCionGeneratorBase(doc, trans) {}
+
+void CsCionProxyGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ stream << GetTransportable().Cs().GenInclude();
+ GenNamespace(stream);
+}
+
+void CsCionProxyGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void CsCionProxyGen::GenNamespace(std::ofstream& stream) {
+ stream << "namespace Cion" << NLine(1);
+ GenBrace(stream, 0, [&]() {
+ stream << "namespace " << GetFileNamespace() << NLine(1);
+ GenBrace(stream, 0, [&]() {
+ GenStructures(stream);
+ stream << Tab(1) << "namespace Proxy" << NLine(1);
+ GenBrace(stream, TAB_SIZE, [&]() {
+ GenInterfaces(stream);
+ });
+ });
+ });
+}
+
+void CsCionProxyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ GenInterface(stream, iface);
+ stream << NLine(1);
+ }
+}
+
+void CsCionProxyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ stream << Tab(2) << "public class " << iface.GetID()
+ << " : ClientBase" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 2, [&]() {
+ ReplaceAll(CB_DATA_MEMBERS)
+ .Change("<PEER_INFO_T>", GetTransportable().Cs().GenPeerInfoType())
+ .Change("<PAYLOAD_TRANSFER_STATUS>",
+ GetTransportable().Cs().GenPayloadTransferStatusType())
+ .Out(stream);
+ GenCallbacks(stream, iface, true);
+ GenDelegateId(stream, iface);
+ GenMethodId(stream, iface);
+ GenEventMethods(stream, iface);
+ GenSerializer(stream);
+ GenListSerializer(stream);
+ GenShareFile(stream, iface, true);
+ GenCtor(stream, iface);
+ GenConnectMethods(stream, iface);
+ GenMethods(stream, iface);
+ });
+}
+
+void CsCionProxyGen::GenCtor(std::ofstream& stream, const Interface& iface) {
+ stream << GetTransportable().Cs().GenClientBaseCtor(iface);
+}
+
+void CsCionProxyGen::GenConnectMethods(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_CONNECT_METHOD)
+ .Change("<PEER_INFO_T>", GetTransportable().Cs().GenPeerInfoType())
+ .Out(stream);
+ stream << NLine(1);
+}
+
+void CsCionProxyGen::GenEventMethods(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_EVENT_METHODS)
+ .Change("<PEER_INFO_T>", GetTransportable().Cs().GenPeerInfoType())
+ .Change("<PAYLOAD_T>", GetTransportable().Cs().GenPayloadType())
+ .Change("<PAYLOAD_TYPE_FILE>",
+ GetTransportable().Cs().GenPayloadTypeFile())
+ .Change("<PAYLOAD_TRANSFER_STATUS>",
+ GetTransportable().Cs().GenPayloadTransferStatusType())
+ .Out(stream);
+}
+
+void CsCionProxyGen::GenMethods(std::ofstream& stream, const Interface& iface) {
+ auto& decls = iface.GetDeclarations();
+
+ for (const auto& i : decls) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ if (!i->GetComments().empty())
+ stream << AddIndent(TAB_SIZE * 3, i->GetComments());
+
+ stream << Tab(3) << "public ";
+ GenDeclaration(stream, *i, false);
+ stream << NLine(1);
+ GenBrace(stream, TAB_SIZE * 3, [&]() {
+ GenInvocation(stream, *i);
+ });
+ stream << NLine(1);
+ }
+}
+
+void CsCionProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
+ GenTemplate(CB_INVOCATION_PRE, stream,
+ [&]()->std::string {
+ std::string st;
+ st += Tab(5)
+ + "p.WriteInt((int)MethodId." + decl.GetID() + ");" + NLine(1);
+ std::string m;
+ std::string l;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT)
+ continue;
+ m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p");
+ if (IsDelegateType(pt.GetBaseType())) {
+ l += "_delegateList.Add(" + i->GetID() + ");\n";
+ }
+ }
+
+ st += AddIndent(TAB_SIZE * 5, m) + NLine(1);
+
+ st += Tab(5) + "lock (_lock)" + NLine(1);
+ st += Tab(5) + "{" + NLine(1);
+ if (!l.empty())
+ st += AddIndent(TAB_SIZE * 6, l) + NLine(1);
+
+ // Deserialize
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
+ st += CB_ASYNC_INVOCATION_MID;
+ } else {
+ st += CB_SYNC_INVOCATION_MID;
+ }
+
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT)
+ continue;
+
+ if (pt.GetBaseType().ToString() == "file" ||
+ (pt.GetBaseType().GetMetaType() != nullptr &&
+ pt.GetBaseType().GetMetaType()->ToString() == "file")) {
+ st += GenTemplateString(CB_SHARE_FILE, [&]()->std::string {
+ std::string str = "";
+ str += Tab(7) + "TryShareFile(" + i->GetID() + ");";
+ return str;
+ });
+ }
+ }
+
+ // Deserialize
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
+ st += Tab(5) + "}";
+ return st;
+ }
+
+ for (const auto& i : decl.GetParameters()) {
+ if (i->GetParameterType().GetDirection() ==
+ ParameterType::Direction::IN) {
+ continue;
+ }
+
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(),
+ i->GetID(), "parcelReceived", false);
+ if (c != "")
+ st += AddIndent(TAB_SIZE * 6, c);
+ }
+
+ if (decl.GetType().ToString() != "void") {
+ st += AddIndent(TAB_SIZE * 6,
+ ConvertTypeToDeserializer(decl.GetType(),
+ "ret", "parcelReceived"));
+ }
+
+ st += Tab(6) + "parcelReceived.Dispose();" + NLine(1);
+ st += NLine(1) + Tab(6) + "return ret;" + NLine(1);
+ st += Tab(5) + "}";
+
+ return st;
+ });
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/cs_cion_proxy_gen.h b/idlc/gen_cion/cs_cion_proxy_gen.h
new file mode 100644
index 0000000..98c7736
--- /dev/null
+++ b/idlc/gen_cion/cs_cion_proxy_gen.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_PROXY_GEN_H_
+#define IDLC_CS_CION_GEN_CS_PROXY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/cs_cion_gen_base.h"
+
+namespace tidl {
+
+class CsCionProxyGen : public CsCionGeneratorBase {
+ public:
+ explicit CsCionProxyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CsCionProxyGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenCtor(std::ofstream& stream, const Interface& iface);
+ void GenConnectMethods(std::ofstream& stream, const Interface& iface);
+ void GenEventMethods(std::ofstream& stream, const Interface& iface);
+ void GenMethods(std::ofstream& stream, const Interface& iface);
+ void GenInvocation(std::ofstream& stream, const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_CS_CION_GEN_CS_PROXY_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/cs_cion_proxy_gen_cb.h b/idlc/gen_cion/cs_cion_proxy_gen_cb.h
new file mode 100644
index 0000000..85169a8
--- /dev/null
+++ b/idlc/gen_cion/cs_cion_proxy_gen_cb.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_PROXY_GEN_CB_H_
+#define IDLC_CS_CION_GEN_CS_PROXY_GEN_CB_H_
+
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
+const char CB_DATA_MEMBERS[] =
+R"__cs_cb( public delegate void DiscoveredEvent(object sender, <PEER_INFO_T> peerInfo);
+ public delegate void DisconnectedEvent(object sender);
+ public delegate void FileReceivedEvent(object sender, FilePayload payload, <PAYLOAD_TRANSFER_STATUS> status);
+ public delegate void ConnectionResultEvent(object sender, ConnectionResult result);
+
+ public event DiscoveredEvent Discovered;
+ public event DisconnectedEvent Disconnected;
+ public event FileReceivedEvent FileReceived;
+ public event ConnectionResultEvent ConnectionResult;
+
+ public new string ServiceName;
+
+ private bool _online = false;
+ private Object _lock = new Object();
+ private List<CallbackBase> _delegateList = new List<CallbackBase>();
+)__cs_cb";
+
+const char CB_EVENT_METHODS[] =
+R"__cs_cb(
+ protected override void OnConnectionResult(<PEER_INFO_T> peerInfo, ConnectionResult result)
+ {
+ if (result.Status == ConnectionStatus.OK)
+ {
+ _online = true;
+ }
+
+ ConnectionResult?.Invoke(this, result);
+ }
+
+ protected override void OnDisconnected(<PEER_INFO_T> peerInfo)
+ {
+ _online = false;
+ Disconnected?.Invoke(this);
+ }
+
+ protected override void OnDiscovered(<PEER_INFO_T> peerInfo)
+ {
+ Discovered?.Invoke(this, peerInfo);
+ }
+
+ protected override void OnPayloadReceived(<PAYLOAD_T> payload, <PAYLOAD_TRANSFER_STATUS> status)
+ {
+ if(payload.PayloadType == <PAYLOAD_TYPE_FILE>)
+ {
+ FileReceived?.Invoke(this, (FilePayload)payload, status);
+ }
+ else
+ {
+ Parcel parcelReceived;
+
+ try
+ {
+ parcelReceived = new Parcel(((DataPayload)payload).Data);
+ }
+ catch (InvalidIOException)
+ {
+ return;
+ }
+
+ using (parcelReceived)
+ {
+ int cmd = parcelReceived.ReadInt();
+ if (cmd != (int)MethodId.__Callback)
+ {
+ return;
+ }
+
+ ProcessReceivedEvent(parcelReceived);
+ }
+ }
+ }
+
+ private void ProcessReceivedEvent(Parcel parcel)
+ {
+ int id = parcel.ReadInt();
+ int seqId = parcel.ReadInt();
+ bool once = parcel.ReadBool();
+
+ foreach (var i in _delegateList)
+ {
+ if ((int)i.Id == id && i.SeqId == seqId)
+ {
+ i.OnReceivedEvent(parcel);
+ if (i.Once)
+ _delegateList.Remove(i);
+ break;
+ }
+ }
+ }
+)__cs_cb";
+
+const char CB_CONNECT_METHOD[] =
+R"__cs_cb(
+ /// <summary>
+ /// Starts discovering cion servers.
+ /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown when the discovery operation is already in progress.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
+ public new void TryDiscovery()
+ {
+ base.TryDiscovery();
+ }
+
+ /// <summary>
+ /// Connects to the stub app.
+ /// </summary>
+ /// <param name="peer">The peer to connect.</param>
+ /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ /// <exception cref="PermissionDeniedException">
+ /// Thrown when the permission is denied.
+ /// </exception>
+ /// <remark> If you want to use this method, you must add privileges.</remark>
+ public new void Connect(<PEER_INFO_T> peer)
+ {
+ base.Connect(peer);
+ }
+
+ /// <summary>
+ /// Disconnects from the stub app.
+ /// </summary>
+ public new void Disconnect()
+ {
+ base.Disconnect();
+ }
+
+ /// <summary>
+ /// Disposes delegate objects in this interface
+ /// </summary>
+ /// <param name="tag">The tag string from delegate object</param>
+ void DisposeCallback(string tag)
+ {
+ foreach (var i in _delegateList)
+ {
+ if (i.Tag.Equals(tag))
+ {
+ _delegateList.Remove(i);
+ return;
+ }
+ }
+ }
+)__cs_cb";
+
+const char CB_INVOCATION_PRE[] =
+R"__cs_cb( if (!_online)
+ throw new NotConnectedSocketException();
+
+ using (Parcel p = new Parcel())
+ {
+$$
+ }
+)__cs_cb";
+
+
+const char CB_SHARE_FILE[] =
+R"__cs_cb(
+ try
+ {
+$$
+ }
+ catch (InvalidIOException)
+ {
+ throw new InvalidIOException();
+ }
+)__cs_cb";
+
+const char CB_ASYNC_INVOCATION_MID[] =
+R"__cs_cb( // Send
+ DataPayload dp = new DataPayload(p.ToBytes());
+ base.SendPayloadAsync(dp);
+)__cs_cb";
+
+const char CB_SYNC_INVOCATION_MID[] =
+R"__cs_cb( // Send
+ byte[] dataReceived = base.SendData(p.ToBytes(), 5 * 1000);
+
+ Parcel parcelReceived = new Parcel(dataReceived);
+
+ int cmd = parcelReceived.ReadInt();
+ if (cmd != (int)MethodId.__Result)
+ throw new InvalidProtocolException();
+)__cs_cb";
+#endif // IDLC_CS_CION_GEN_CS_PROXY_GEN_CB_H_
diff --git a/idlc/gen_cion/cs_cion_stub_gen.cc b/idlc/gen_cion/cs_cion_stub_gen.cc
new file mode 100644
index 0000000..652defd
--- /dev/null
+++ b/idlc/gen_cion/cs_cion_stub_gen.cc
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/cs_cion_stub_gen.h"
+
+namespace {
+#include "idlc/gen_cion/cs_cion_stub_gen_cb.h"
+}
+
+namespace tidl {
+
+CsCionStubGen::CsCionStubGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans)
+ : CsCionGeneratorBase(doc, trans) {}
+
+void CsCionStubGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ stream << GetTransportable().Cs().GenInclude();
+
+ GenNamespace(stream);
+}
+
+void CsCionStubGen::OnFiniGen(std::ofstream& stream) {}
+
+void CsCionStubGen::GenNamespace(std::ofstream& stream) {
+ stream << "namespace Cion" << NLine(1);
+ GenBrace(stream, 0, [&]() {
+ stream << "namespace " << GetFileNamespace() << NLine(1);
+ GenBrace(stream, 0, [&]() {
+ GenStructures(stream);
+ stream << Tab(1) << "namespace Stub" << NLine(1);
+ GenBrace(stream, TAB_SIZE, [&]() {
+ GenInterfaces(stream);
+ });
+ });
+ });
+}
+
+void CsCionStubGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ GenInterface(stream, iface);
+ stream << std::endl;
+ }
+}
+
+void CsCionStubGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ stream << Tab(2) << "public sealed class " << iface.GetID()
+ << " : ServerBase" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 2, [&]() {
+ stream << ReplaceAll(CB_DATA_MEMBERS, "<VERSION>", FULLVER);
+ GenServiceBase(stream, iface);
+ GenCallbacks(stream, iface, false);
+ GenDelegateId(stream, iface);
+ GenMethodId(stream, iface);
+ GenSerializer(stream);
+ GenListSerializer(stream);
+ GenReceivedAsyncEvent(stream, iface);
+ GenReceivedSyncEvent(stream, iface);
+ GenConnectionRequestedEvent(stream);
+ GenDisconnectedEvent(stream);
+ GenConnectedEvent(stream);
+ GenShareFile(stream, iface, false);
+ GenCtor(stream, iface);
+ GenCommonMethods(stream);
+ GenExtraMethods(stream);
+ });
+}
+
+void CsCionStubGen::GenServiceBase(std::ofstream& stream, const Interface& iface) {
+ ReplaceAll(CB_SERVICE_BASE_FRONT)
+ .Change("<PEER_INFO_T>", GetTransportable().Cs().GenPeerInfoType())
+ .Change("<PAYLOAD_TRANSFER_STATUS>",
+ GetTransportable().Cs().GenPayloadTransferStatusType())
+ .Out(stream);
+ GenDeclarations(stream, iface.GetDeclarations());
+ stream << NLine(1);
+ stream << AddIndent(TAB_SIZE * 3, "}\n");
+}
+
+void CsCionStubGen::GenDeclarations(std::ofstream& stream,
+ const Declarations& decls) {
+ for (const auto& i : decls) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+ if (!i->GetComments().empty())
+ stream << NLine(1) << AddIndent(TAB_SIZE * 4, i->GetComments());
+ stream << Tab(4) << "public abstract ";
+ GenDeclaration(stream, *i);
+ stream << NLine(1);
+ }
+}
+
+void CsCionStubGen::GenReceivedSyncEvent(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_ON_RECEIVED_SYNC_EVENT_FRONT)
+ .Change("<PEER_INFO_T>", GetTransportable().Cs().GenPeerInfoType())
+ .Out(stream);
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::SYNC)
+ continue;
+ stream << Tab(7) << "case MethodId." << i->GetID() << ":" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 7, [&]() {
+ GenSyncInvocation(stream, *i);
+ stream << Tab(8) << "break;" << NLine(1);
+ });
+ }
+ stream << CB_ON_RECEIVED_SYNC_EVENT_BACK;
+}
+
+void CsCionStubGen::GenReceivedAsyncEvent(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_ON_RECEIVED_ASYNC_EVENT_FRONT)
+ .Change("<PEER_INFO_T>", GetTransportable().Cs().GenPeerInfoType())
+ .Change("<PAYLOAD_TRANSFER_STATUS>",
+ GetTransportable().Cs().GenPayloadTransferStatusType())
+ .Change("<PAYLOAD_T>", GetTransportable().Cs().GenPayloadType())
+ .Change("<PAYLOAD_TYPE_FILE>",
+ GetTransportable().Cs().GenPayloadTypeFile())
+ .Out(stream);
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::ASYNC)
+ continue;
+ stream << Tab(6) << "case MethodId." << i->GetID() << ":" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 6, [&]() {
+ GenAsyncInvocation(stream, *i);
+ stream << Tab(7) << "break;" << NLine(1);
+ });
+ }
+ stream << CB_ON_RECEIVED_ASYNC_EVENT_BACK;
+}
+
+void CsCionStubGen::GenSyncInvocation(std::ofstream& stream, const Declaration& decl) {
+ int cnt = 1;
+
+ // Deserialize
+ for (const auto& i : decl.GetParameters()) {
+ if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT) {
+ cnt++;
+ continue;
+ }
+
+ std::string v = "param" + std::to_string(cnt);
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, "p");
+ stream << AddIndent(TAB_SIZE * 8, c);
+ cnt++;
+ }
+
+ // Invoke
+ cnt = 1;
+ std::string m;
+ bool hasRet = false;
+
+ if (decl.GetType().ToString() != "void") {
+ m += "var retVal = ";
+ hasRet = true;
+ }
+
+ m += "b." + decl.GetID() + "(";
+ for (const auto& i : decl.GetParameters()) {
+ if (cnt != 1) {
+ m += ", ";
+ }
+
+ std::string v = "param" + std::to_string(cnt);
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT) {
+ m += "out " + ConvertTypeToString(pt.GetBaseType()) + " ";
+ } else if (pt.GetDirection() == ParameterType::Direction::REF) {
+ m += "ref ";
+ }
+ m += v;
+ cnt++;
+ }
+
+ m += ");\n";
+ stream << AddIndent(TAB_SIZE * 8, m);
+
+ // Serialize
+ cnt = 0;
+ m = CB_INVOCATION_RESULT_PRE;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ cnt++;
+ if (pt.GetDirection() == ParameterType::Direction::IN)
+ continue;
+ m += ConvertTypeToSerializer(pt.GetBaseType(),
+ "param" + std::to_string(cnt), "result");
+
+ if (HasFile(pt.GetBaseType())) {
+ m += "TryShareFile(param" + std::to_string(cnt) + ");\n\n";
+ }
+ }
+
+ if (hasRet) {
+ m += ConvertTypeToSerializer(decl.GetType(), "retVal", "result");
+ if (HasFile(decl.GetType())) {
+ m += "TryShareFile(retVal);\n";
+ }
+ }
+
+ m += "\nreturnData = result.ToBytes();\n";
+
+ stream << AddIndent(TAB_SIZE * 8, m);
+}
+
+void CsCionStubGen::GenAsyncInvocation(std::ofstream& stream, const Declaration& decl) {
+ int cnt = 1;
+
+ // Deserialize
+ for (const auto& i : decl.GetParameters()) {
+ if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT) {
+ cnt++;
+ continue;
+ }
+
+ std::string v = "param" + std::to_string(cnt);
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, "p");
+ stream << AddIndent(TAB_SIZE * 7, c);
+ cnt++;
+ }
+
+ // Invoke
+ cnt = 1;
+ std::string m;
+
+ if (decl.GetType().ToString() != "void") {
+ m += "var retVal = ";
+ }
+
+ m += "b." + decl.GetID() + "(";
+ for (const auto& i : decl.GetParameters()) {
+ if (cnt != 1) {
+ m += ", ";
+ }
+
+ std::string v = "param" + std::to_string(cnt);
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT) {
+ m += "out " + ConvertTypeToString(pt.GetBaseType()) + " ";
+ } else if (pt.GetDirection() == ParameterType::Direction::REF) {
+ m += "ref ";
+ }
+ m += v;
+ cnt++;
+ }
+
+ m += ");\n";
+ stream << AddIndent(TAB_SIZE * 7, m);
+}
+
+void CsCionStubGen::GenConnectionRequestedEvent(std::ofstream& stream) {
+ ReplaceAll(CB_ON_CONNECTIONREQUESTED_EVENT)
+ .Change("<PEER_INFO_T>", GetTransportable().Cs().GenPeerInfoType())
+ .Out(stream);
+}
+
+void CsCionStubGen::GenConnectedEvent(std::ofstream& stream) {
+ ReplaceAll(CB_ON_CONNECTED_EVENT)
+ .Change("<PEER_INFO_T>", GetTransportable().Cs().GenPeerInfoType())
+ .Out(stream);
+}
+
+void CsCionStubGen::GenDisconnectedEvent(std::ofstream& stream) {
+ ReplaceAll(CB_ON_DISCONNECTED_EVENT)
+ .Change("<PEER_INFO_T>", GetTransportable().Cs().GenPeerInfoType())
+ .Out(stream);
+}
+
+void CsCionStubGen::GenCtor(std::ofstream& stream, const Interface& iface) {
+ stream << GetTransportable().Cs().GenServerBaseCtor(iface);
+}
+
+void CsCionStubGen::GenCommonMethods(std::ofstream& stream) {
+ stream << CB_COMMON_METHODS;
+}
+
+void CsCionStubGen::GenExtraMethods(std::ofstream& stream) {
+ stream << GetTransportable().Cs().GenServerExtraBody();
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/cs_cion_stub_gen.h b/idlc/gen_cion/cs_cion_stub_gen.h
new file mode 100644
index 0000000..b794d4a
--- /dev/null
+++ b/idlc/gen_cion/cs_cion_stub_gen.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_STUB_GEN_H_
+#define IDLC_CS_CION_GEN_CS_STUB_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/cs_cion_gen_base.h"
+
+namespace tidl {
+
+class CsCionStubGen : public CsCionGeneratorBase {
+ public:
+ explicit CsCionStubGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~CsCionStubGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenNamespace(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenServiceBase(std::ofstream& stream, const Interface& iface);
+ void GenReceivedAsyncEvent(std::ofstream& stream, const Interface& iface);
+ void GenReceivedSyncEvent(std::ofstream& stream, const Interface& iface);
+ void GenConnectionRequestedEvent(std::ofstream& stream);
+ void GenConnectedEvent(std::ofstream& stream);
+ void GenDisconnectedEvent(std::ofstream& stream);
+ void GenCtor(std::ofstream& stream, const Interface& iface);
+ void GenCommonMethods(std::ofstream& stream);
+ void GenExtraMethods(std::ofstream& stream);
+ void GenDeclarations(std::ofstream& stream, const Declarations& decls);
+ void GenSyncInvocation(std::ofstream& stream, const Declaration& decl);
+ void GenAsyncInvocation(std::ofstream& stream, const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_CS_CION_GEN_CS_STUB_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/cs_cion_stub_gen_cb.h b/idlc/gen_cion/cs_cion_stub_gen_cb.h
new file mode 100644
index 0000000..b7870bb
--- /dev/null
+++ b/idlc/gen_cion/cs_cion_stub_gen_cb.h
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_STUB_GEN_CB_H_
+#define IDLC_CS_CION_GEN_CS_STUB_GEN_CB_H_
+
+const char CB_DATA_MEMBERS[] =
+R"__cs_cb( private List<ServiceBase> _services = new List<ServiceBase>();
+ private Type _serviceType;
+)__cs_cb";
+
+const char CB_SERVICE_BASE_FRONT[] =
+R"__cs_cb(
+ public abstract class ServiceBase
+ {
+ /// <summary>
+ /// The name of service
+ /// </summary>
+ public string ServiceName
+ {
+ get; internal set;
+ }
+
+ /// <summary>
+ /// The display name of service
+ /// </summary>
+ public string DisplayName
+ {
+ get; internal set;
+ }
+
+ /// <summary>
+ /// The PeerInfo of client
+ /// </summary>
+ public <PEER_INFO_T> Client
+ {
+ get; internal set;
+ }
+
+ internal <PEER_INFO_T> ConnectionRequestClient;
+
+ internal ServerBase ServerBase;
+
+ protected ServiceBase()
+ {
+ }
+
+ /// <summary>
+ /// Disconnects from the client app
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">
+ /// Thrown when an internal IO error occurrs.
+ /// </exception>
+ public void Disconnect()
+ {
+ if (Client != null)
+ ServerBase.Disconnect(Client);
+ }
+
+ /// <summary>
+ /// Accepts the connection request from the client.
+ /// </summary>
+ public void Accept()
+ {
+ if (ConnectionRequestClient != null)
+ ServerBase.Accept(ConnectionRequestClient);
+ }
+
+ /// <summary>
+ /// Rejects the connection request from the client.
+ /// </summary>
+ /// <param name="reason">The reason why reject the connection request.</param>
+ public void Reject(string reason)
+ {
+ if (ConnectionRequestClient != null)
+ ServerBase.Reject(ConnectionRequestClient, reason);
+ }
+
+ /// <summary>
+ /// This method will be called when connection requested from the client
+ /// </summary>
+ public abstract void OnConnectionRequest();
+
+ /// <summary>
+ /// This method will be called when received file payload.
+ /// </summary>
+ public abstract void OnFilePayloadReceived(FilePayload file, <PAYLOAD_TRANSFER_STATUS> status);
+
+ /// <summary>
+ /// This method will be called when the client is disconnected
+ /// </summary>
+ public abstract void OnTerminate();
+
+ /// <summary>
+ /// This method will be called when the client is connected
+ /// </summary>
+ public abstract void OnConnected();
+)__cs_cb";
+
+const char CB_ON_RECEIVED_ASYNC_EVENT_FRONT[] =
+R"__cs_cb(
+ protected override void OnPayloadReceived(<PAYLOAD_T> data, <PEER_INFO_T> peerInfo, <PAYLOAD_TRANSFER_STATUS> status)
+ {
+ try
+ {
+ Parcel p;
+ ServiceBase b = null;
+
+ foreach (var i in _services)
+ {
+ if (i.Client == null)
+ continue;
+
+ if (i.Client.AppId.Equals(peerInfo.AppId) && i.Client.UUID.Equals(peerInfo.UUID))
+ {
+ b = i;
+ break;
+ }
+ }
+
+ if (b == null)
+ {
+ return;
+ }
+
+ if (data.PayloadType == <PAYLOAD_TYPE_FILE>)
+ {
+ b.OnFilePayloadReceived((FilePayload)data, status);
+ return;
+ }
+
+ DataPayload dp = (DataPayload)data;
+
+ try
+ {
+ p = new Parcel(dp.Data);
+ }
+ catch (InvalidIOException)
+ {
+ return;
+ }
+
+ int cmd = p.ReadInt();
+ switch ((MethodId)cmd)
+ {
+)__cs_cb";
+
+const char CB_ON_RECEIVED_ASYNC_EVENT_BACK[] =
+R"__cs_cb(
+ default:
+ return;
+ }
+ }
+ catch (InvalidIOException)
+ {
+ return;
+ }
+ }
+)__cs_cb";
+
+
+
+const char CB_ON_RECEIVED_SYNC_EVENT_FRONT[] =
+R"__cs_cb(
+ protected override byte[] OnDataReceived(byte[] data, <PEER_INFO_T> peerInfo)
+ {
+ Parcel p;
+ byte[] returnData = new byte[0];
+
+ try
+ {
+ p = new Parcel(data);
+ }
+ catch (InvalidIOException)
+ {
+ return returnData;
+ }
+
+ try
+ {
+ ServiceBase b = null;
+
+ foreach (var i in _services)
+ {
+ if (i.Client == null)
+ continue;
+
+ if (i.Client.AppId.Equals(peerInfo.AppId) && i.Client.UUID.Equals(peerInfo.UUID))
+ {
+ b = i;
+ break;
+ }
+ }
+
+ if (b == null)
+ {
+ return returnData;
+ }
+
+ using (var result = new Parcel())
+ {
+ int cmd = p.ReadInt();
+
+ switch ((MethodId)cmd)
+ {
+)__cs_cb";
+
+const char CB_ON_RECEIVED_SYNC_EVENT_BACK[] =
+R"__cs_cb(
+ default:
+ return returnData;
+ }
+ }
+
+ return returnData;
+ }
+ catch (InvalidIOException)
+ {
+ return returnData;
+ }
+ finally
+ {
+ p?.Dispose();
+ }
+ }
+)__cs_cb";
+
+
+const char CB_ON_CONNECTIONREQUESTED_EVENT[] =
+R"__cs_cb(
+ protected override void OnConnectionRequest(<PEER_INFO_T> peerInfo)
+ {
+ ServiceBase s = Activator.CreateInstance(_serviceType) as ServiceBase;
+ s.ServiceName = base.ServiceName;
+ s.DisplayName = base.DisplayName;
+ s.ConnectionRequestClient = peerInfo;
+ s.ServerBase = this;
+ _services.Add(s);
+ s.OnConnectionRequest();
+ }
+)__cs_cb";
+
+const char CB_ON_CONNECTED_EVENT[] =
+R"__cs_cb(
+ protected override void OnConnectionResult(<PEER_INFO_T> peerInfo, ConnectionResult result)
+ {
+ foreach (var i in _services)
+ {
+ if (i.ConnectionRequestClient == null)
+ continue;
+
+ if (i.ConnectionRequestClient.AppId.Equals(peerInfo.AppId) && i.ConnectionRequestClient.UUID.Equals(peerInfo.UUID))
+ {
+ if (result.Status == ConnectionStatus.OK) {
+ i.Client = i.ConnectionRequestClient;
+ i.ConnectionRequestClient = null;
+ i.OnConnected();
+ } else {
+ _services.Remove(i);
+ }
+ break;
+ }
+ }
+ }
+)__cs_cb";
+
+const char CB_ON_DISCONNECTED_EVENT[] =
+R"__cs_cb(
+ protected override void OnDisconnected(<PEER_INFO_T> peerInfo)
+ {
+ foreach (var i in _services)
+ {
+ if (i.Client == null)
+ continue;
+
+ if (i.Client.AppId.Equals(peerInfo.AppId) && i.Client.UUID.Equals(peerInfo.UUID))
+ {
+ i.OnTerminate();
+ _services.Remove(i);
+ break;
+ }
+ }
+ }
+)__cs_cb";
+
+const char CB_COMMON_METHODS[] =
+R"__cs_cb(
+ /// <summary>
+ /// Listens to client apps
+ /// </summary>
+ /// <param name="serviceType">The type object for making service instances</param>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// Thrown when serviceType is invalid.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Thrown when the listen operation is already in progress.
+ /// </exception>
+ /// <exception cref="UnauthorizedAccessException">
+ /// Thrown when an application does not have the privilege to access this method.
+ /// </exception>
+ /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege>
+ /// <privilege>http://tizen.org/privilege/internet</privilege>
+ public void Listen(Type serviceType)
+ {
+ if (!typeof(ServiceBase).IsAssignableFrom(serviceType))
+ throw new ArgumentException("Invalid type");
+ _serviceType = serviceType;
+ base.Listen();
+ }
+
+
+ /// <summary>
+ /// Stops the listen operation.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown when the server is not listening.</exception>
+ public new void Stop()
+ {
+ base.Stop();
+ _services.Clear();
+ }
+
+ /// <summary>
+ /// Gets service objects which are connected
+ /// </summary>
+ /// <returns>The enumerable service objects which are connected</returns>
+ public IEnumerable<ServiceBase> GetServices()
+ {
+ return _services;
+ }
+)__cs_cb";
+
+constexpr const char CB_INVOCATION_RESULT_PRE[] =
+R"__cs_cb(
+result.WriteInt((int)MethodId.__Result);
+)__cs_cb";
+
+#endif // IDLC_CS_CION_GEN_CS_STUB_GEN_CB_H_
diff --git a/idlc/gen_cion/cs_transportable.h b/idlc/gen_cion/cs_transportable.h
new file mode 100644
index 0000000..419200a
--- /dev/null
+++ b/idlc/gen_cion/cs_transportable.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_CS_TRANSPORTABLE_H_
+#define IDLC_GEN_CION_CS_TRANSPORTABLE_H_
+
+#include <string>
+
+#include "idlc/ast/interface.h"
+
+namespace tidl {
+
+class CsTransportable {
+ public:
+ virtual ~CsTransportable() = default;
+ virtual std::string GenInclude() const = 0;
+ virtual std::string GenFileSend(std::string path) const = 0;
+ virtual std::string GenGroupType() const = 0;
+ virtual std::string GenPayloadTransferStatusType() const = 0;
+ virtual std::string GenPeerInfoType() const = 0;
+ virtual std::string GenPayloadType() const = 0;
+ virtual std::string GenClientType() const = 0;
+ virtual std::string GenServerType() const = 0;
+ virtual std::string GenClientExtraHeader() const = 0;
+ virtual std::string GenClientExtraBody() const = 0;
+ virtual std::string GenServerExtraHeader() const = 0;
+ virtual std::string GenServerExtraBody() const = 0;
+ virtual std::string GenPayloadTypeData() const = 0;
+ virtual std::string GenPayloadTypeFile() const = 0;
+ virtual std::string GenClientBaseCtor(const Interface& iface) const = 0;
+ virtual std::string GenGroupBaseCtor(const Interface& iface) const = 0;
+ virtual std::string GenServerBaseCtor(const Interface& iface) const = 0;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CION_CS_TRANSPORTABLE_H_
diff --git a/idlc/gen_cion/dart_cion_gen_base.cc b/idlc/gen_cion/dart_cion_gen_base.cc
new file mode 100644
index 0000000..be42069
--- /dev/null
+++ b/idlc/gen_cion/dart_cion_gen_base.cc
@@ -0,0 +1,706 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/dart_cion_gen_base.h"
+#include "idlc/gen_cion/dart_cion_gen_base_cb.h"
+
+#include <algorithm>
+#include <ctime>
+#include <sstream>
+#include <stack>
+#include <utility>
+#include <vector>
+
+namespace tidl {
+
+DartCionGeneratorBase::DartCionGeneratorBase(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans) : CionPluginBase(doc, trans) {
+ type_map_ = {
+ {"char", "int"},
+ {"int", "int"},
+ {"short", "int"},
+ {"long", "int"},
+ {"string", "String"},
+ {"bool", "bool"},
+ {"list", "List"},
+ {"array", "List"},
+ {"double", "double"},
+ {"bundle", "Bundle"},
+ {"void", "void"},
+ {"file", "String"}
+ };
+
+ parcel_type_map_ = {
+ {"char", "Byte"},
+ {"int", "Int32"},
+ {"short", "Int16"},
+ {"long", "Int64"},
+ {"string", "String"},
+ {"bool", "Bool"},
+ {"double", "Double"},
+ {"bundle", "Bundle"},
+ {"file", "String"}
+ };
+
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ for (const auto& e : st.GetElements()) {
+ auto& type = e->GetType();
+ AddListSerializer(type);
+ }
+ } else {
+ auto& iface = static_cast<const Interface&>(*b);
+ for (const auto& d : iface.GetDeclarations()) {
+ for (const auto& p : d->GetParameters())
+ AddListSerializer(p->GetParameterType().GetBaseType());
+
+ if (d->GetMethodType() == Declaration::MethodType::SYNC)
+ AddListSerializer(d->GetType());
+ }
+ }
+ }
+}
+
+void DartCionGeneratorBase::AddListSerializer(const BaseType& type) {
+ if (type.ToString() != "list" && type.ToString() != "array")
+ return;
+
+ std::string type_name = ConvertTypeToString(type);
+ AddListSerializer(*type.GetMetaType());
+
+ if (list_serializer_.find(type_name) != list_serializer_.end())
+ return;
+
+ list_serializer_[std::move(type_name)] = &type;
+}
+
+void DartCionGeneratorBase::GenAnnotation(std::ofstream& stream) {
+ ReplaceAll(CB_ANNOTATION, "<VERSION>", FULLVER)
+ .Transform([&](std::string str) {
+ return RemoveLine(str);
+ })
+ .Out(stream);
+}
+
+void DartCionGeneratorBase::GenImport(std::ofstream& stream) {
+ stream << GetTransportable().Dart().GenImport() << std::endl;
+}
+
+void DartCionGeneratorBase::GenVersion(std::ofstream& stream) {
+ ReplaceAll(CB_VERSION_DEF, "<VERSION>", FULLVER).Out(stream);
+ stream << NLine(1);
+}
+
+void DartCionGeneratorBase::GenDelegateId(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code;
+ int cnt = 1;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ if (cnt != 1)
+ code += "," + NLine(1);
+
+ std::string name = i->GetID();
+ name[0] = ::tolower(name[0]);
+ code += ReplaceAll(CB_ENUM, {
+ { "<NAME>", name },
+ { "<VALUE>", std::to_string(cnt++) }
+ });
+ }
+ code += ";";
+
+ if (cnt != 1) {
+ ReplaceAll(CB_DELEGATE_ID, "<DELEGATE_IDS>", code)
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+ }
+}
+
+void DartCionGeneratorBase::GenDelegateId(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenDelegateId(stream, iface);
+ }
+}
+
+void DartCionGeneratorBase::GenMethodId(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code;
+ int cnt = 2;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ if (cnt != 2)
+ code += "," + NLine(1);
+
+ std::string name = i->GetID();
+ name[0] = ::tolower(name[0]);
+ code += ReplaceAll(CB_ENUM, {
+ { "<NAME>", name },
+ { "<VALUE>", std::to_string(cnt++) }
+ });
+ }
+ code += ";";
+
+ ReplaceAll(CB_METHOD_ID, "<METHOD_IDS>", code)
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+}
+
+void DartCionGeneratorBase::GenMethodId(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenMethodId(stream, iface);
+ }
+}
+
+void DartCionGeneratorBase::GenCallbackBase(std::ofstream& stream) {
+ std::string code = IsProxy() ? CB_PROXY_CALLBACK_BASE : CB_STUB_CALLBACK_BASE;
+ stream << SmartIndent(std::move(code));
+}
+
+void DartCionGeneratorBase::GenStructures(std::ofstream& stream) {
+ GenListSerializer(stream);
+
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_STRUCTURE)
+ continue;
+
+ Structure& st = static_cast<Structure&>(*i);
+ GenStructure(stream, st);
+ stream << std::endl;
+ }
+}
+
+void DartCionGeneratorBase::GenListSerializer(std::ofstream& stream) {
+ if (list_serializer_.empty())
+ return;
+
+ ReplaceAll(CB_LIST_SERIALIZER, {
+ { "<SERIALIZE>", GenListSerializerSerialize() },
+ { "<DESERIALIZE>", GenListSerializerDeserialize() }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+std::string DartCionGeneratorBase::GenListSerializerSerialize() {
+ std::string code;
+ for (const auto& iter : list_serializer_) {
+ std::string parcel_write;
+ auto& type = *(iter.second);
+ if (type.GetMetaType()->IsUserDefinedType()) {
+ parcel_write = ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<NAME>", "value" },
+ { "<PARCEL>", "parcel" }
+ });
+ parcel_write += NLine(1);
+ } else if (type.GetMetaType()->ToString() == "list" ||
+ type.GetMetaType()->ToString() == "array") {
+ parcel_write = ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<NAME>", "value" },
+ { "<PARCEL>", "parcel" }
+ });
+ parcel_write += NLine(1);
+ } else {
+ parcel_write = ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>",
+ ConvertTypeToParcelType(type.GetMetaType()->ToString()) },
+ { "<NAME>", "value" }
+ });
+ parcel_write += NLine(1);
+ }
+
+ code += ReplaceAll(CB_LIST_SERIALIZER_SERIALIZE, {
+ { "<TYPE>", iter.first },
+ { "<VALUE_TYPE>", ConvertTypeToString(*type.GetMetaType()) },
+ { "<PARCEL_WRITE>", parcel_write }
+ });
+ }
+
+ return RemoveLine(code);
+}
+
+std::string DartCionGeneratorBase::GenListSerializerDeserialize() {
+ std::string code;
+ for (const auto& iter : list_serializer_) {
+ std::string parcel_read;
+ auto& type = *(iter.second);
+ if (type.GetMetaType()->IsUserDefinedType()) {
+ parcel_read = "final " + ConvertTypeToString(*type.GetMetaType()) +
+ " value = " + ConvertTypeToString(*type.GetMetaType()) + "();";
+ parcel_read += NLine(1);
+ parcel_read += ReplaceAll(CB_USER_DEFINED_PARCEL_READ, {
+ { "<NAME>", "value" },
+ { "<PARCEL>", "parcel" }
+ });
+ } else if (type.GetMetaType()->ToString() == "list" ||
+ type.GetMetaType()->ToString() == "array") {
+ parcel_read = "final " + ConvertTypeToString(*type.GetMetaType()) +
+ " value = [];";
+ parcel_read += NLine(1);
+ parcel_read += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<NAME>", "value" },
+ { "<PARCEL>", "parcel" }
+ });
+ } else {
+ parcel_read = "final " + ConvertTypeToString(*type.GetMetaType()) + " ";
+ parcel_read += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>",
+ ConvertTypeToParcelType(type.GetMetaType()->ToString()) },
+ { "<NAME>", "value" }
+ });
+ }
+
+ code += ReplaceAll(CB_LIST_SERIALIZER_DESERIALIZE, {
+ { "<TYPE>", iter.first },
+ { "<PARCEL_READ>", parcel_read }
+ });
+ }
+
+ return RemoveLine(code);
+}
+
+void DartCionGeneratorBase::GenStructure(std::ofstream& stream,
+ const Structure& st) {
+ auto& elms = st.GetElements();
+ ReplaceAll(CB_STRUCTURE_BASE, {
+ { "<NAME>", GetClassName(st.GetID()) },
+ { "<ELEMENTS>", GenBaseElements(elms) },
+ { "<PARCEL_WRITE>", GenBaseParcelWrite(elms) },
+ { "<PARCEL_READ>", GenBaseParcelRead(elms) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+std::string DartCionGeneratorBase::GenBaseElements(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ if (!code.empty())
+ code += NLine(1);
+
+ auto& type = elm->GetType();
+ auto param_type = ConvertTypeToString(type);
+ code += "/// The " + elm->GetID();
+ code += NLine(1);
+ code += "late " + param_type + " " + elm->GetID() + ";";
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+std::string DartCionGeneratorBase::GenBaseParcelWrite(const Elements& elms) {
+ std::string code;
+ bool has_file = false;
+ for (const auto& elm : elms) {
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<NAME>", elm->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<NAME>", elm->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ if (type.GetMetaType() != nullptr &&
+ type.GetMetaType()->ToString() == "file") {
+ code += ReplaceAll(CB_FILE_ADD_ALL, {
+ { "<FILE_LIST>", elm->GetID()},
+ });
+ code += NLine(1);
+ has_file = true;
+ }
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>", elm->GetID() }
+ });
+ code += NLine(1);
+ if (type.ToString() == "file") {
+ code += ReplaceAll(CB_FILE_ADD, {
+ { "<FILE>", elm->GetID()},
+ });
+ code += NLine(1);
+ has_file = true;
+ }
+ }
+ }
+
+ if (has_file)
+ code = GetFileSharing(code, "this.send(payload);");
+ return code;
+}
+
+std::string DartCionGeneratorBase::GenBaseParcelRead(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_READ, {
+ { "<NAME>", elm->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<NAME>", elm->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>", elm->GetID() }
+ });
+ code += NLine(1);
+ }
+ }
+
+ return code;
+}
+
+std::string DartCionGeneratorBase::ConvertTypeToString(const BaseType& type) {
+ if (type.IsUserDefinedType())
+ return type.ToString();
+
+ if (type.GetMetaType() != nullptr)
+ return type_map_[type.ToString()] + "<" +
+ ConvertTypeToString(*(type.GetMetaType())) + ">";
+
+ return type_map_[type.ToString()];
+}
+
+std::string DartCionGeneratorBase::ConvertTypeToParcelType(const std::string& key) {
+ return parcel_type_map_[key];
+}
+
+std::string DartCionGeneratorBase::Tab(int cnt) {
+ std::string t;
+ for (int i = 0; i < cnt; i++)
+ t += " ";
+
+ return t;
+}
+
+std::string DartCionGeneratorBase::NLine(int cnt) {
+ std::string t;
+ for (int i = 0; i < cnt; i++)
+ t += "\n";
+
+ return t;
+}
+
+std::string DartCionGeneratorBase::RemoveSpaces(const std::string& str) {
+ // for annotation
+ if (str.compare(0, 3, "/**") == 0 ||
+ str.compare(0, 2, " *") == 0 ||
+ str.compare(0, 3, " */") == 0)
+ return str;
+
+ std::size_t found = str.find_first_not_of(' ');
+ if (found == std::string::npos)
+ return "";
+
+ return str.substr(found, str.size() - found);
+}
+
+std::string DartCionGeneratorBase::Trim(const std::string& str) {
+ // for annotation
+ if (str.compare(0, 3, "/**") == 0 ||
+ str.compare(0, 2, " *") == 0 ||
+ str.compare(0, 3, " */") == 0)
+ return str;
+
+ std::size_t first = str.find_first_not_of(" \t\r\n");
+ if (first == std::string::npos)
+ return str;
+
+ std::size_t last = str.find_last_not_of(" \t\r\n");
+ return str.substr(first, (last - first + 1));
+}
+
+std::string DartCionGeneratorBase::RemoveLine(std::string lines,
+ unsigned int line_num) {
+ std::stringstream ss(lines);
+ std::string result;
+ std::string line;
+ unsigned int line_count = 0;
+
+ while (std::getline(ss, line, '\n')) {
+ line_count++;
+ if (line_num == line_count)
+ continue;
+
+ result += Trim(line);
+ result += NLine(1);
+ }
+
+ return result;
+}
+
+std::string DartCionGeneratorBase::SmartIndent(std::string lines) {
+ std::stringstream stream(lines);
+ std::string next_line;
+ std::string line;
+ std::string tab;
+ std::string line_back;
+ std::string code;
+ unsigned int line_count = 0;
+ int tab_size = 0;
+ std::stack<int> prev_tab_size;
+ bool tab_once = false;
+ bool continuous = false;
+ bool enum_block = false;
+
+ while (std::getline(stream, next_line, '\n')) {
+ next_line = RemoveSpaces(std::move(next_line));
+ line_count++;
+ if (line_count == 1) {
+ line = Trim(next_line);
+ continue;
+ }
+
+ tab.clear();
+ // Checks whether the brace is end or not.
+ if (line.find_first_of("}") < line.find_first_of("{"))
+ tab_size--;
+
+ // Set tab
+ if (line.length() > 0)
+ tab += Tab(tab_size);
+
+ // Set tab for if statement or for loop or while loop
+ if (tab_once) {
+ tab += Tab(1);
+ tab_once = false;
+ }
+
+ if (continuous) {
+ tab += Tab(2);
+ continuous = false;
+ }
+
+ if (line.front() == ':')
+ tab += Tab(2);
+
+ // Checks whether switch case is end or not.
+ line_back = "__INVALID__";
+ if (line.length() > 0)
+ line_back = line.back();
+
+ if (!prev_tab_size.empty() && prev_tab_size.top() == (tab_size - 1) &&
+ line_back == "}") {
+ prev_tab_size.pop();
+ tab_size--;
+ enum_block = false;
+ }
+
+ if (line.empty() || std::all_of(line.begin(), line.end(), isspace)) {
+ std::string new_line = Trim(next_line);
+ if (new_line.empty() || new_line.find('}') != std::string::npos ||
+ std::all_of(new_line.begin(), new_line.end(), isspace)) {
+ line = std::move(new_line);
+ continue;
+ }
+
+ code += tab + line + NLine(1);
+ } else {
+ if (line.compare(0, 2, " *") != 0)
+ code += tab;
+
+ code += line + NLine(1);
+ }
+
+ // Checks whether the brace is starting or not
+ if (line_back == "{" ) {
+ tab_size++;
+ if (line.find("enum ") != std::string::npos)
+ enum_block = true;
+ }
+
+ if (line_back != "{") {
+ // Checks whether if statement or for loop or while loop without braces is starting or not.
+ if (line.find("if (") != std::string::npos ||
+ line.find("for (") != std::string::npos ||
+ line.find("while (") != std::string::npos)
+ tab_once = true;
+
+ /// Checks whether switch case is starting or not.
+ if ((line.find("case ") != std::string::npos && line_back == ":") ||
+ line.find("default:") != std::string::npos) {
+ tab_size++;
+
+ prev_tab_size.push(tab_size - 1);
+ }
+
+ if (!enum_block && line_back == ",")
+ continuous = true;
+ }
+
+ line = std::move(Trim(next_line));
+ }
+
+ code += line + NLine(1);
+ return code;
+}
+
+std::string DartCionGeneratorBase::GetClassName(std::string name) {
+ name[0] = ::toupper(name[0]);
+ return name;
+}
+
+std::string DartCionGeneratorBase::GetFullNameFromType(const BaseType& type) {
+ std::string str;
+
+ str += type.ToString();
+
+ if (type.GetMetaType() != nullptr) {
+ str += "_";
+ str += GetFullNameFromType(*type.GetMetaType());
+ }
+
+ return str;
+}
+
+std::string DartCionGeneratorBase::GetFullNameFromType(const BaseType& type,
+ const Interface& iface) {
+ std::string str;
+ if (IsDelegateType(iface, type))
+ str += iface.GetID() + "_";
+
+ str += type.ToString();
+
+ if (type.GetMetaType() != nullptr) {
+ str += "_";
+ str += GetFullNameFromType(*type.GetMetaType(), iface);
+ } else if (type.GetKeyType() != nullptr) {
+ str += "_";
+ str += GetFullNameFromType(*type.GetKeyType(), iface);
+ str += "_";
+ str += GetFullNameFromType(*type.GetValueType(), iface);
+ }
+
+ return str;
+}
+
+bool DartCionGeneratorBase::HasFile(const Interface& iface, const BaseType& type) {
+ if (type.ToString() == "list" || type.ToString() == "array") {
+ std::string name = GetFullNameFromType(type, iface);
+ if (name == "array_file" || name == "list_file" || name == "file")
+ return true;
+ } else if (type.ToString() == "file") {
+ return true;
+ }
+
+ return false;
+}
+
+bool DartCionGeneratorBase::HasFile(const BaseType& type) {
+ if (type.ToString() == "list" || type.ToString() == "array") {
+ std::string name = GetFullNameFromType(type);
+ if (name == "array_file" || name == "list_file" || name == "file")
+ return true;
+ } else if (type.ToString() == "file") {
+ return true;
+ }
+
+ return false;
+}
+
+bool DartCionGeneratorBase::HasFile(const Declaration& decl) {
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+
+ if (type.ToString() == "file")
+ return true;
+
+ if (type.ToString() == "list" || type.ToString() == "array") {
+ if (type.GetMetaType() != nullptr &&
+ type.GetMetaType()->ToString() == "file")
+ return true;
+
+ }
+ }
+ return false;
+}
+
+bool DartCionGeneratorBase::HasFile(const Interface& iface, bool is_proxy) {
+ for (const auto& d : iface.GetDeclarations()) {
+ if (is_proxy) {
+ if (HasFile(iface, d->GetType()) == true)
+ return true;
+ }
+
+ for (const auto& p : d->GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (is_proxy) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE) {
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+ } else {
+ if (param_type.GetDirection() == ParameterType::Direction::IN)
+ continue;
+ }
+ if (HasFile(iface, param_type.GetBaseType()) == true)
+ return true;
+ } else {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE) {
+ if (param_type.GetDirection() == ParameterType::Direction::IN)
+ continue;
+ } else {
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+ }
+ if (HasFile(iface, param_type.GetBaseType()) == true)
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+std::string DartCionGeneratorBase::GetFileSharing(std::string src, std::string sender) {
+ std::string file_send;
+ file_send += ReplaceAll(CB_FILE_SEND, "<SEND_ASYNC_FILE>", sender);
+ return CB_FILE_LIST + NLine(1) + src + NLine(1) + file_send + NLine(1);
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/dart_cion_gen_base.h b/idlc/gen_cion/dart_cion_gen_base.h
new file mode 100644
index 0000000..077d2c3
--- /dev/null
+++ b/idlc/gen_cion/dart_cion_gen_base.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_CION_GEN_BASE_H_
+#define IDLC_GEN_DART_CION_GEN_BASE_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "idlc/ast/structure.h"
+#include "idlc/ast/type.h"
+#include "idlc/gen/generator.h"
+
+#include "idlc/gen_cion/cion_plugin_base.h"
+
+namespace tidl {
+
+class DartCionGeneratorBase : public CionPluginBase {
+ public:
+ explicit DartCionGeneratorBase(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~DartCionGeneratorBase() = default;
+
+ void GenAnnotation(std::ofstream& stream);
+ void GenImport(std::ofstream& stream);
+ void GenVersion(std::ofstream& stream);
+ void GenDelegateId(std::ofstream& stream);
+ void GenMethodId(std::ofstream& stream);
+ void GenCallbackBase(std::ofstream& stream);
+ void GenStructures(std::ofstream& stream);
+
+ std::string ConvertTypeToParcelType(const std::string& key);
+ std::string ConvertTypeToString(const BaseType& type);
+ std::string GetClassName(std::string name);
+ std::string NLine(int cnt);
+ std::string RemoveLine(std::string lines, unsigned int line_num = 1);
+ std::string RemoveSpaces(const std::string& str);
+ std::string SmartIndent(std::string lines);
+ std::string Tab(int cnt);
+ std::string Trim(const std::string& str);
+
+ bool HasFile(const Interface& iface, bool is_proxy);
+ bool HasFile(const BaseType& type);
+ bool HasFile(const Interface& iface, const BaseType& type);
+ bool HasFile(const Declaration& decl);
+ std::string GetFileSharing(std::string src, std::string sender);
+
+ private:
+ void AddListSerializer(const BaseType& type);
+ void GenListSerializer(std::ofstream& stream);
+ std::string GenListSerializerSerialize();
+ std::string GenListSerializerDeserialize();
+ void GenStructure(std::ofstream& stream, const Structure& st);
+ std::string GenBaseElements(const Elements& elms);
+ std::string GenBaseParcelWrite(const Elements& elms);
+ std::string GenBaseParcelRead(const Elements& elms);
+ void GenDelegateId(std::ofstream& stream, const Interface& iface);
+ void GenMethodId(std::ofstream& stream, const Interface& iface);
+ std::string GetFullNameFromType(const BaseType& type,
+ const Interface& iface);
+ std::string GetFullNameFromType(const BaseType& type);
+
+ protected:
+ const int TAB_SIZE = 2;
+
+ private:
+ std::map<std::string, std::string> type_map_;
+ std::map<std::string, std::string> parcel_type_map_;
+ std::unordered_map<std::string, const BaseType*> list_serializer_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_GEN_BASE_H_
diff --git a/idlc/gen_cion/dart_cion_gen_base_cb.h b/idlc/gen_cion/dart_cion_gen_base_cb.h
new file mode 100644
index 0000000..77f7c21
--- /dev/null
+++ b/idlc/gen_cion/dart_cion_gen_base_cb.h
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_CION_GEN_BASE_CB_H_
+#define IDLC_GEN_DART_CION_GEN_BASE_CB_H_
+
+namespace tidl {
+
+/**
+ * <VERSION> The TIDLC version.
+ */
+constexpr const char CB_ANNOTATION[] =
+R"__dart_cb(
+/// Generated by tidlc <VERSION>
+
+// ignore_for_file: public_member_api_docs, omit_local_variable_types
+)__dart_cb";
+
+/**
+ * <LOG_TAG> The log tag.
+ */
+constexpr const char CB_LOG_TAG[] =
+R"__dart_cb(const String _logTag = '<LOG_TAG>';)__dart_cb";
+
+/**
+ * <VERSION> The TIDLC version.
+ */
+constexpr const char CB_VERSION_DEF[] =
+R"__dart_cb(const String _tidlVersion = '<VERSION>';)__dart_cb";
+
+/**
+ * <METHOD_IDS> The method IDs.
+ */
+constexpr const char CB_METHOD_ID[] =
+R"__dart_cb(
+enum _MethodId {
+ result(0),
+ callback(1),
+ <METHOD_IDS>
+
+ const _MethodId(this.id);
+ final int id;
+}
+)__dart_cb";
+
+/**
+ * <DELEGATE_IDS> The delegate IDs.
+ */
+constexpr const char CB_DELEGATE_ID[] =
+R"__dart_cb(
+enum _DelegateId {
+ <DELEGATE_IDS>
+
+ const _DelegateId(this.id);
+ final int id;
+}
+)__dart_cb";
+
+/**
+ * <NAME> The name of the enumeration.
+ * <VALUE> The value of the enumeration.
+ */
+constexpr const char CB_ENUM[] =
+R"__dart_cb(<NAME>(<VALUE>))__dart_cb";
+
+constexpr const char CB_PROXY_CALLBACK_BASE[] =
+R"__dart_cb(
+abstract class _Delegate extends Parcelable {
+ _Delegate(this.id, this.once, this.callback) {
+ sequenceId = sequenceNum++;
+ }
+
+ int id = 0;
+ bool once = false;
+ int sequenceId = 0;
+ Function callback;
+ static int sequenceNum = 0;
+
+ Future<void> onReceivedEvent(Parcel parcel);
+
+ @override
+ void serialize(Parcel parcel) {
+ parcel.writeInt32(id);
+ parcel.writeInt32(sequenceId);
+ parcel.writeBool(once);
+ }
+
+ @override
+ void deserialize(Parcel parcel) {
+ id = parcel.readInt32();
+ sequenceId = parcel.readInt32();
+ once = parcel.readBool();
+ }
+}
+)__dart_cb";
+
+constexpr const char CB_STUB_CALLBACK_BASE[] =
+R"__dart_cb(
+abstract class _Delegate extends Parcelable {
+ _Delegate(this.id, this.once);
+
+ int id = 0;
+ bool once = false;
+ int sequenceId = 0;
+
+ @override
+ void serialize(Parcel parcel) {
+ parcel.writeInt32(id);
+ parcel.writeInt32(sequenceId);
+ parcel.writeBool(once);
+ }
+
+ @override
+ void deserialize(Parcel parcel) {
+ id = parcel.readInt32();
+ sequenceId = parcel.readInt32();
+ once = parcel.readBool();
+ }
+}
+)__dart_cb";
+
+/**
+ * <NAME> The name of the structure.
+ * <ELEMENTS> Elements of the structure.
+ * <PARCEL_WRITE> The implementation to write the data to the parcel.
+ * <PARCEL_READ> The implementation to read the data from the parcel.
+ */
+constexpr const char CB_STRUCTURE_BASE[] =
+R"__dart_cb(
+/// The [<NAME>] class.
+class <NAME> extends Parcelable {
+ /// Constructor for this class.
+ <NAME>();
+
+ /// Constructor for creating a [<NAME>] class from the parcel.
+ <NAME>.fromParcel(Parcel parcel) {
+ deserialize(parcel);
+ }
+
+ <ELEMENTS>
+
+ @override
+ void serialize(Parcel parcel) {
+ <PARCEL_WRITE>
+ }
+
+ @override
+ void deserialize(Parcel parcel) {
+ <PARCEL_READ>
+ }
+}
+)__dart_cb";
+
+/**
+ * <NAME> The variable name of the user defined type.
+ * <PARCEL> The name of the parcel instance.
+ */
+constexpr const char CB_USER_DEFINED_PARCEL_WRITE[] =
+R"__dart_cb(<NAME>.serialize(<PARCEL>);)__dart_cb";
+
+/**
+ * <PARCEL> The name of the parcel instance.
+ * <NAME> The variable name of the list type.
+ */
+constexpr const char CB_LIST_PARCEL_WRITE[] =
+R"__dart_cb(ListSerializer().serialize(<PARCEL>, <NAME>);)__dart_cb";
+
+/**
+ * <PARCEL> The name of the parcel instance.
+ * <PARCEL_TYPE> The type of the parcel of the variable.
+ * <NAME> The variable name of the base type.
+ */
+constexpr const char CB_BASE_PARCEL_WRITE[] =
+R"__dart_cb(<PARCEL>.write<PARCEL_TYPE>(<NAME>);)__dart_cb";
+
+/**
+ * <NAME> The variable name of the user defined type.
+ * <PARCEL> The name of the parcel instance.
+ */
+constexpr const char CB_USER_DEFINED_PARCEL_READ[] =
+R"__dart_cb(<NAME>.deserialize(<PARCEL>);)__dart_cb";
+
+/**
+ * <PARCEL> The name of the parcel instance.
+ * <NAME> The variable name of the list type.
+ */
+constexpr const char CB_LIST_PARCEL_READ[] =
+R"__dart_cb(ListSerializer().deserialize(<PARCEL>, <NAME>);)__dart_cb";
+
+/**
+ * <PARCEL> The name of the parcel instance.
+ * <PARCEL_TYPE> The type of the parcel of the element.
+ * <NAME> The variable name of the base type.
+ */
+constexpr const char CB_BASE_PARCEL_READ[] =
+R"__dart_cb(<NAME> = <PARCEL>.read<PARCEL_TYPE>();)__dart_cb";
+
+constexpr const char CB_FILE_LIST[] =
+R"__dart_cb(final List<String> fileList = List<String>.empty(growable: true);)__dart_cb";
+
+/**
+ * <FILE> The name of the file.
+ */
+constexpr const char CB_FILE_ADD[] =
+R"__dart_cb(
+fileList.add(<FILE>);
+)__dart_cb";
+
+/**
+ * <FILE_LIST> The list of the file names.
+ */
+constexpr const char CB_FILE_ADD_ALL[] =
+R"__dart_cb(
+fileList.addAll(<FILE_LIST>);
+)__dart_cb";
+
+/**
+ * <SENDER> The payload sender.
+ */
+constexpr const char CB_FILE_SEND[] =
+R"__dart_cb(
+for (final String file in fileList) {
+ final Payload payload = FilePayload(file);
+ <SEND_ASYNC_FILE>
+}
+)__dart_cb";
+
+/**
+ * <PORT> The rpc port handle.
+ * <ARG> The argument.
+ */
+constexpr const char CB_LIST_FILE_SET_PRIVATE_SHARING[] =
+R"__dart_cb(<PORT>.shareFiles(<ARG>);)__dart_cb";
+
+/**
+ * <SERIALIZE> The implementation to serialize the data to the parcel.
+ * <DESERIALIZE> The implementation to deserialize the data from the parcel.
+ */
+constexpr const char CB_LIST_SERIALIZER[] =
+R"__dart_cb(
+/// The [ListSerializer] class for serializing a list to the parcel.
+class ListSerializer {
+ /// Gets the instance of the [ListSerializer].
+ factory ListSerializer() {
+ return _instance;
+ }
+
+ ListSerializer._internal();
+
+ static final ListSerializer _instance = ListSerializer._internal();
+
+ /// Serailizes the parameter to the parcel.
+ void serialize(Parcel parcel, dynamic param) {
+ switch (param.runtimeType) {
+ <SERIALIZE>
+ default:
+ {
+ return;
+ }
+ }
+ }
+
+ /// Deserializes the parameter from the parcel.
+ void deserialize(Parcel parcel, dynamic param) {
+ switch (param.runtimeType) {
+ <DESERIALIZE>
+ default:
+ {
+ return;
+ }
+ }
+ }
+}
+)__dart_cb";
+
+/**
+ * <TYPE> The data type.
+ * <VALUE_TYPE> The value type of the list element.
+ * <PARCEL_WRITE> The implementation to write the data to the parcel.
+ */
+constexpr const char CB_LIST_SERIALIZER_SERIALIZE[] =
+R"__dart_cb(
+case <TYPE>:
+ {
+ parcel.writeArrayCount(param.length as int);
+ param.forEach((<VALUE_TYPE> value) {
+ <PARCEL_WRITE>
+ });
+ return;
+ }
+)__dart_cb";
+
+/**
+ * <TYPE> The data type.
+ * <PARCEL_READ> The implementation to read the data from the parcel.
+ */
+constexpr const char CB_LIST_SERIALIZER_DESERIALIZE[] =
+R"__dart_cb(
+case <TYPE>:
+ {
+ final int count = parcel.readArrayCount();
+ for (int i = 0; i < count; ++i) {
+ <PARCEL_READ>
+ param.add(value);
+ }
+ return;
+ }
+)__dart_cb";
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_CION_GEN_BASE_CB_H_
diff --git a/idlc/gen_cion/dart_cion_group_gen.cc b/idlc/gen_cion/dart_cion_group_gen.cc
new file mode 100644
index 0000000..ec7349a
--- /dev/null
+++ b/idlc/gen_cion/dart_cion_group_gen.cc
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/dart_cion_group_gen.h"
+
+#include "idlc/gen_cion/dart_cion_gen_base_cb.h"
+#include "idlc/gen_cion/dart_cion_group_gen_cb.h"
+
+namespace tidl {
+
+DartCionGroupGen::DartCionGroupGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans)
+ : DartCionGeneratorBase(doc, trans) {}
+
+void DartCionGroupGen::OnInitGen(std::ofstream& stream) {
+ GenAnnotation(stream);
+ GenImport(stream);
+ GenVersion(stream);
+ GenGroupMethodId(stream);
+ GenStructures(stream);
+ GenInterfaces(stream);
+}
+
+void DartCionGroupGen::OnFiniGen(std::ofstream& stream) {}
+
+void DartCionGroupGen::GenGroupMethodId(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code;
+ int cnt = 0;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ if (cnt != 0)
+ code += "," + NLine(1);
+
+ std::string name = i->GetID();
+ name[0] = ::tolower(name[0]);
+ code += ReplaceAll(CB_ENUM, {
+ { "<NAME>", name },
+ { "<VALUE>", std::to_string(cnt++) }
+ });
+ }
+ code += ";";
+
+ ReplaceAll(CB_GROUP_METHOD_ID, "<METHOD_IDS>", code)
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+}
+
+void DartCionGroupGen::GenGroupMethodId(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenGroupMethodId(stream, iface);
+ }
+}
+
+void DartCionGroupGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void DartCionGroupGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ GenInterfaceBase(stream, iface);
+}
+
+void DartCionGroupGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string name = iface.GetID();
+ name[0] = ::toupper(name[0]);
+ ReplaceAll(CB_INTERFACE_BASE, {
+ { "<CTOR>", GenInterfaceCtor(iface) },
+ { "<INTERFACE_NAME>", name },
+ { "<METHOD>", GenInterfaceMethods(iface) },
+ { "<METHOD_HANDLERS>", GenInterfaceMethodHandlers(iface) },
+ { "<METHOD_HANDLER_DECL>", GenMethodHandlerDecl(iface) },
+ { "<PEER_INFO_T>", GetTransportable().Dart().GenPeerInfo() }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(std::move(str));
+ })
+ .Out(stream);
+}
+
+std::string DartCionGroupGen::GenInterfaceCtor(const Interface& iface) {
+ std::string method_handler_table;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string name = d->GetID();
+ name[0] = ::tolower(name[0]);
+ method_handler_table += ReplaceAll(CB_METHOD_HANDLER_TABLE, {
+ { "<METHOD_ID>", name },
+ { "<METHOD_NAME>", d->GetID() }
+ });
+ method_handler_table += NLine(1);
+ }
+
+ std::string code = std::move(method_handler_table);
+ code += NLine(1);
+
+ return code;
+}
+
+std::string DartCionGroupGen::GenInterfaceMethods(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string args;
+ for (auto& param : d->GetParameters())
+ args += ConvertTypeToString(param->GetParameterType().GetBaseType())
+ + ' ' + param->GetID() + ", ";
+
+ if (!args.empty()) {
+ args.pop_back();
+ args.pop_back();
+ }
+
+ std::string name = d->GetID();
+ name[0] = ::tolower(name[0]);
+
+ code += ReplaceAll(CB_METHOD, {
+ { "<METHOD_NAME>", d->GetID() },
+ { "<LOWER_METHOD_NAME>", name },
+ { "<ARGS>", args },
+ { "<PARCEL_WRITE>", GenMethodParcelWrite(*d)},
+ });
+ }
+
+ return RemoveLine(code);
+}
+
+std::string DartCionGroupGen::GenMethodParcelWrite(const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<NAME>", p->GetID() }
+ });
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<NAME>", p->GetID() }
+ });
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>" , p->GetID() }
+ });
+ }
+
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+std::string DartCionGroupGen::GenMethodParcelRead(
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ std::string prefix = "final " + ConvertTypeToString(type) + " " + p->GetID();
+
+ if (type.IsUserDefinedType()) {
+ code += prefix + " = " + ConvertTypeToString(type) + "();" + NLine(1);
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_READ, {
+ { "<PARCEL>", "parcel" },
+ { "<NAME>", p->GetID() }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += prefix + " = [];" + NLine(1);
+ code += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<PARCEL>", "parcel" },
+ { "<NAME>", p->GetID() }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>" , prefix }
+ });
+ code += NLine(1);
+ }
+ }
+
+ code += NLine(1);
+ return code;
+}
+
+std::string DartCionGroupGen::GenInterfaceMethodHandlers(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_METHOD_HANDLER_BASE, {
+ { "<METHOD_NAME>", d->GetID() },
+ { "<PEER_INFO_T>", GetTransportable().Dart().GenPeerInfo()},
+ { "<PARCEL_READ>", GenMethodParcelRead(*d)},
+ { "<METHOD_HANDLE_INVOKE>", GenMethodHandlerInvoke(*d)},
+ });
+ }
+
+ return RemoveLine(code);
+}
+
+std::string DartCionGroupGen::GenMethodHandlerInvoke(const Declaration& decl) {
+ std::string args;
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ if (!args.empty())
+ args += ", ";
+
+ args += p->GetID();
+ }
+
+ code += ReplaceAll(CB_METHOD_HANDLER_INVOKE, {
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<ARGS>", args }
+ });
+ return code;
+}
+
+std::string DartCionGroupGen::GenMethodHandlerDecl(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string args;
+ for (auto& param : d->GetParameters())
+ args += ConvertTypeToString(param->GetParameterType().GetBaseType())
+ + ", ";
+
+ if (!args.empty()) {
+ args.pop_back();
+ args.pop_back();
+ }
+
+ code += ReplaceAll(CB_METHOD_HANDLER, {
+ { "<METHOD_NAME>", d->GetID() },
+ { "<PEER_INFO_T>", GetTransportable().Dart().GenPeerInfo()},
+ { "<ARGS>", args},
+ });
+ }
+
+ return RemoveLine(code);
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/dart_cion_group_gen.h b/idlc/gen_cion/dart_cion_group_gen.h
new file mode 100644
index 0000000..86cb869
--- /dev/null
+++ b/idlc/gen_cion/dart_cion_group_gen.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_CION_GROUP_GEN_H_
+#define IDLC_GEN_DART_CION_GROUP_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/dart_cion_gen_base.h"
+
+namespace tidl {
+
+class DartCionGroupGen : public DartCionGeneratorBase {
+ public:
+ explicit DartCionGroupGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~DartCionGroupGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenGroupMethodId(std::ofstream& stream, const Interface& iface);
+ void GenGroupMethodId(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ std::string GenInterfaceCtor(const Interface& iface);
+ std::string GenInterfaceMethods(const Interface& iface);
+ std::string GenInterfaceMethodHandlers(const Interface& iface);
+ std::string GenMethodHandlerInvoke(const Declaration& decl);
+ std::string GenMethodParcelWrite(const Declaration& decl);
+ std::string GenMethodParcelRead(const Declaration& decl);
+ std::string GenMethodHandlerDecl(const Interface& iface);
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_CION_GROUP_GEN_H_
diff --git a/idlc/gen_cion/dart_cion_group_gen_cb.h b/idlc/gen_cion/dart_cion_group_gen_cb.h
new file mode 100644
index 0000000..46a7f8e
--- /dev/null
+++ b/idlc/gen_cion/dart_cion_group_gen_cb.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_CION_GROUP_GEN_CB_H_
+#define IDLC_GEN_DART_CION_GROUP_GEN_CB_H_
+
+namespace tidl {
+
+/**
+ * <METHOD_IDS> The method IDs.
+ */
+constexpr const char CB_GROUP_METHOD_ID[] =
+R"__dart_cb(
+enum _MethodId {
+ <METHOD_IDS>
+
+ const _MethodId(this.id);
+ final int id;
+}
+)__dart_cb";
+
+/**
+ * <INTERFACE_NAME> The name of the interface.
+ * <CTOR> The implementation of the constructor of the interface.
+ * <METHOD> The implementation of method of interface.
+ * <METHOD_HANDLERS> The implementation of the method handlers of the interface.
+ * <METHOD_HANDLER_DECL> The declarations of the method handlers.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+ R"__dart_cb(
+/// The method type for receiving joined group event.
+typedef OnJoined = Future<void> Function(<PEER_INFO_T>);
+
+/// The method type for receiving left group event.
+typedef OnLeft = Future<void> Function(<PEER_INFO_T>);
+
+typedef _MethodHandler = Future<void> Function(<PEER_INFO_T>, Parcel);
+
+/// [<INTERFACE_NAME>] class for RPC.
+class <INTERFACE_NAME> {
+ /// Constructor for this class.
+ <INTERFACE_NAME>({SecurityInfo? security} )
+ : _group = Group('<INTERFACE_NAME>', security: security) {
+ <CTOR>
+ }
+
+ OnJoined? _onJoined;
+ OnLeft? _onLeft;
+
+ bool _isJoined = false;
+ final Group _group;
+ final Map<int, _MethodHandler> _methodHandlers = <int, _MethodHandler>{};
+
+ Future<void> subscribe(
+ {required OnJoined onJoined, required OnLeft onLeft}) async {
+ if (_isJoined) {
+ return;
+ }
+ _onJoined = onJoined;
+ _onLeft = onLeft;
+
+ await _group.subscribe(
+ onJoined: _onJoinedEvent,
+ onLeft: _onLeftEvent,
+ onReceived: _onReceivedEvent);
+ _isJoined = true;
+ }
+
+ void unSubscribe() {
+ if (!_isJoined) {
+ return;
+ }
+
+ _group.unsubscribe();
+ _isJoined = false;
+ }
+
+ Future<void> _onJoinedEvent(<PEER_INFO_T> peer) async {
+ _onJoined?.call(peer);
+ }
+
+ Future<void> _onLeftEvent(<PEER_INFO_T> peer) async {
+ _onLeft?.call(peer);
+ }
+
+ Future<void> _onReceivedEvent(<PEER_INFO_T> peer, DataPayload payload) async {
+ final Uint8List raw = payload.data;
+ final Parcel parcel = Parcel.fromRaw(raw);
+
+ final int cmd = parcel.readInt32();
+ if (_methodHandlers.containsKey(cmd)) {
+ await _methodHandlers[cmd]!(peer, parcel);
+ }
+ }
+
+ <METHOD>
+
+ <METHOD_HANDLERS>
+
+ <METHOD_HANDLER_DECL>
+}
+)__dart_cb";
+
+/**
+ * <METHOD_ID> The ID of the method.
+ * <METHOD_NAME> The name of the method.
+ */
+constexpr const char CB_METHOD_HANDLER_TABLE[] =
+R"__dart_cb(_methodHandlers[_MethodId.<METHOD_ID>.id] = _on<METHOD_NAME>Method;)__dart_cb";
+
+/**
+ * <METHOD_NAME> The name of the method.
+ * <ARGS> The arguments of method.
+ * <PARCEL_WRITE> The implementation of parcel write.
+ */
+constexpr const char CB_METHOD[] =
+R"__dart_cb(
+/// This method is used to send <METHOD_NAME> request to the other joined apps.
+Future<void> <METHOD_NAME>(<ARGS>) async {
+ final Parcel parcel = Parcel();
+ parcel.writeInt32(_MethodId.<LOWER_METHOD_NAME>.id);
+
+ <PARCEL_WRITE>
+
+ // Send
+ DataPayload payload = DataPayload(parcel.asRaw());
+ _group.publish(payload);
+}
+)__dart_cb";
+
+/**
+ * <METHOD_NAME> The name of the method.
+ * <PARCEL_READ> The implementation of parcel read.
+ * <METHOD_HANDLE_INVOKE> The implementation to invoke the method handle.
+ */
+constexpr const char CB_METHOD_HANDLER_BASE[] =
+R"__dart_cb(
+Future<void> _on<METHOD_NAME>Method(<PEER_INFO_T> peer, Parcel parcel) async {
+ if (on<METHOD_NAME>Handler != null) {
+ <PARCEL_READ>
+
+ <METHOD_HANDLE_INVOKE>
+ }
+}
+)__dart_cb";
+
+/**
+ * <METHOD_NAME> The name of the method.
+ * <ARGS> The arguments of method.
+ */
+constexpr const char CB_METHOD_HANDLER_INVOKE[] =
+R"__dart_cb(on<METHOD_NAME>Handler!.call(peer, <ARGS>);)__dart_cb";
+
+/**
+ * <METHOD_NAME> The name of the method.
+ * <ARGS> The arguments of method.
+ */
+constexpr const char CB_METHOD_HANDLER[] =
+R"__dart_cb(
+Future<void> Function(<PEER_INFO_T>, <ARGS>)? on<METHOD_NAME>Handler;
+
+)__dart_cb";
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_CION_GROUP_GEN_CB_H_
diff --git a/idlc/gen_cion/dart_cion_proxy_gen.cc b/idlc/gen_cion/dart_cion_proxy_gen.cc
new file mode 100644
index 0000000..e2a74d1
--- /dev/null
+++ b/idlc/gen_cion/dart_cion_proxy_gen.cc
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/dart_cion_proxy_gen.h"
+
+#include <cctype>
+#include <utility>
+
+#include "idlc/gen_cion/dart_cion_gen_base_cb.h"
+#include "idlc/gen_cion/dart_cion_proxy_gen_cb.h"
+
+namespace tidl {
+
+DartCionProxyGen::DartCionProxyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans)
+ : DartCionGeneratorBase(doc, trans) {}
+
+void DartCionProxyGen::OnInitGen(std::ofstream& stream) {
+ GenAnnotation(stream);
+ GenImport(stream);
+ GenVersion(stream);
+ GenDelegateId(stream);
+ GenMethodId(stream);
+ GenStructures(stream);
+ GenInterfaces(stream);
+}
+
+void DartCionProxyGen::OnFiniGen(std::ofstream& stream) {}
+
+void DartCionProxyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*i);
+ GenCallbackBase(stream);
+ GenInterface(stream, iface);
+ }
+}
+
+void DartCionProxyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ GenDelegateBase(stream, *d);
+ }
+
+ GenInterfaceBase(stream, iface);
+}
+
+void DartCionProxyGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string name = iface.GetID();
+ name[0] = ::toupper(name[0]);
+
+ bool has_file = HasFile(iface, true);
+
+ ReplaceAll(CB_INTERFACE_BASE, {
+ { "<INTERFACE_NAME>", name },
+ { "<METHODS>", GenInterfaceMethods(iface) },
+ { "<FILE_REVEIVE_DEF>", has_file ? ", required OnFileReceived onFileReceived" : "" },
+ { "<FILE_REVEIVE_CB>", has_file ? "_onFileReceived = onFileReceived;" : "" }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(std::move(str));
+ })
+ .Out(stream);
+}
+
+std::string DartCionProxyGen::GenInterfaceMethods(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string args;
+ for (auto& param : d->GetParameters())
+ args += ConvertTypeToString(param->GetParameterType().GetBaseType())
+ + ' ' + param->GetID() + ", ";
+
+ if (!args.empty()) {
+ args.pop_back();
+ args.pop_back();
+ }
+
+ std::string method_name = d->GetID();
+ method_name[0] = std::tolower(method_name[0]);
+
+ code += ReplaceAll(CB_METHOD_BASE, {
+ { "<METHOD_NAME>", d->GetID() },
+ { "<LOWER_METHOD_NAME>", std::move(method_name) },
+ { "<RETURN_TYPE>", GenReturnType(*d) },
+ { "<ARGS>", args },
+ { "<ASYNC>", GenAsync(*d) },
+ { "<METHOD_PARCEL_WRITE>", GenMethodParcelWrite(*d) },
+ { "<SEND_ASYNC_FILE>", "_client.send(payload);" },
+ });
+ }
+
+ return RemoveLine(code);
+}
+
+std::string DartCionProxyGen::GenReturnType(const Declaration& decl) {
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC)
+ return "Future<" + ConvertTypeToString(decl.GetType()) + ">";
+
+ return ConvertTypeToString(decl.GetType());
+}
+
+std::string DartCionProxyGen::GenAsync(const Declaration& decl) {
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC)
+ return "async ";
+
+ return "";
+}
+
+std::string DartCionProxyGen::GenMethodParcelWrite(const Declaration& decl) {
+ std::string code;
+ bool has_file = false;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(type)) {
+ code += ReplaceAll(CB_METHOD_DELEGATE_WRITE, {
+ { "<DELEGATE_TYPE>", ConvertTypeToString(type) },
+ { "<DELEGATE_NAME>", p->GetID() }
+ });
+ } else if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<NAME>", p->GetID() }
+ });
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<NAME>", p->GetID() }
+ });
+ if (type.GetMetaType() != nullptr &&
+ type.GetMetaType()->ToString() == "file") {
+ code += ReplaceAll(CB_FILE_ADD_ALL, {
+ { "<FILE_LIST>", p->GetID()},
+ });
+ has_file = true;
+ }
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>" , p->GetID() }
+ });
+ if (type.ToString() == "file") {
+ code += ReplaceAll(CB_FILE_ADD, {
+ { "<FILE>", p->GetID()},
+ });
+ has_file = true;
+ }
+ }
+
+ code += NLine(1);
+ }
+
+ std::string method_id = decl.GetID();
+ method_id[0] = ::tolower(method_id[0]);
+
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
+ code = ReplaceAll(CB_METHOD_PARCEL_WRITE,
+ {{"<PARCEL_WRITE>", code}, {"<METHOD_NAME>", method_id}});
+
+ if (has_file)
+ code = GetFileSharing(code,"_client.send(payload);");
+ } else {
+ std::string read_code = GenMethodResultParcelRead(decl);
+ read_code += GenMethodOutParamParcelRead(decl);
+ code = ReplaceAll(CB_METHOD_PARCEL_WRITE_AND_READ,
+ {{"<PARCEL_WRITE>", code},
+ {"<METHOD_NAME>", method_id},
+ {"<PARCEL_READ>", read_code}});
+ if (has_file) {
+ code = CB_FILE_LIST + code;
+ code = ReplaceAll(code, {
+ {"<FILE_SEND>", CB_FILE_SEND},
+ });
+ code = ReplaceAll(code, {
+ {"<SEND_ASYNC_FILE>", "_client.send(payload);"},
+ });
+ } else {
+ code = ReplaceAll(code, {
+ {"<FILE_SEND>", ""},
+ });
+ }
+ }
+
+ return code;
+}
+
+std::string DartCionProxyGen::GenMethodResultParcelRead(
+ const Declaration& decl) {
+ std::string code;
+ auto& type = decl.GetType();
+ std::string prefix = "final " + ConvertTypeToString(type) + " ret";
+ if (type.IsUserDefinedType()) {
+ code += prefix + " = " + ConvertTypeToString(type) + "();" + NLine(1);
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_READ, {
+ { "<PARCEL>", "parcelReceived" },
+ { "<NAME>", "ret" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += prefix + " = [];" + NLine(1);
+ code += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<PARCEL>", "parcelReceived" },
+ { "<NAME>", "ret" }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcelReceived" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>" , prefix }
+ });
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+std::string DartCionProxyGen::GenMethodOutParamParcelRead(
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_READ, {
+ { "<PARCEL>", "parcelReceived" },
+ { "<NAME>", p->GetID() }
+ });
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<PARCEL>", "parcelReceived" },
+ { "<NAME>", p->GetID() }
+ });
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcelReceived" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>" , p->GetID() }
+ });
+ }
+ }
+
+ code += NLine(1);
+ return code;
+}
+
+std::string DartCionProxyGen::GenMethodArgsFree(const Declaration& decl) {
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC)
+ return {};
+
+ std::string code;
+ if (decl.GetType().ToString() == "bundle") {
+ code += "ret.dispose();";
+ code += NLine(1);
+ }
+
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.ToString() == "bundle") {
+ code += p->GetID() + ".dispose();";
+ code += NLine(1);
+ }
+ }
+
+ return code;
+}
+
+std::string DartCionProxyGen::GenMethodParams(const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ if (!params.empty())
+ params += ", ";
+
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += ConvertTypeToString(type) + " " + p->GetID();
+ }
+
+ return params;
+}
+
+void DartCionProxyGen::GenDelegateBase(std::ofstream& stream,
+ const Declaration& decl) {
+ std::string id = decl.GetID();
+ id[0] = ::tolower(id[0]);
+ ReplaceAll(CB_DELEGATE_BASE, {
+ { "<DELEGATE_NAME>", GetClassName(decl.GetID()) },
+ { "<DELEGATE_ID>", id },
+ { "<DELEGATE_PARAMS>", GenDelegateParams(decl) },
+ { "<DELEGATE_PARAM_TYPES>", GenDelegateParamTypes(decl) },
+ { "<DELEGATE_PARCEL_READ>", GenDelegateParcelRead(decl) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+std::string DartCionProxyGen::GenDelegateParams(const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ if (!params.empty())
+ params += ", ";
+
+ params += p->GetID();
+ }
+
+ return params;
+}
+
+std::string DartCionProxyGen::GenDelegateParamTypes(const Declaration& decl) {
+ std::string types;
+ for (const auto& p : decl.GetParameters()) {
+ if (!types.empty())
+ types += ", ";
+
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ types += ConvertTypeToString(type);
+ }
+
+ return types;
+}
+
+std::string DartCionProxyGen::GenDelegateParcelRead(const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ code += "final " + ConvertTypeToString(type) + " ";
+ if (type.IsUserDefinedType()) {
+ code += p->GetID() + " = " + ConvertTypeToString(type) + "();" + NLine(1);
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_READ,
+ {{"<NAME>", p->GetID()}, {"<PARCEL>", "parcel"}});
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += p->GetID() + " = [];" + NLine(1);
+ code += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<NAME>", p->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>", p->GetID() }
+ });
+ code += NLine(1);
+ }
+ }
+
+ return code;
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/dart_cion_proxy_gen.h b/idlc/gen_cion/dart_cion_proxy_gen.h
new file mode 100644
index 0000000..76f204f
--- /dev/null
+++ b/idlc/gen_cion/dart_cion_proxy_gen.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_CION_PROXY_GEN_H_
+#define IDLC_GEN_DART_CION_PROXY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/dart_cion_gen_base.h"
+
+namespace tidl {
+
+class DartCionProxyGen : public DartCionGeneratorBase {
+ public:
+ explicit DartCionProxyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~DartCionProxyGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenOnDisconnected(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ std::string GenInterfaceMethods(const Interface& iface);
+ std::string GenMethodInvoke(const Declaration& decl);
+ std::string GenReturnType(const Declaration& decl);
+ std::string GenAsync(const Declaration& decl);
+ std::string GenMethodParcelWrite(const Declaration& decl);
+ std::string GenMethodResultParcelRead(const Declaration& decl);
+ std::string GenMethodOutParamParcelRead(const Declaration& decl);
+ std::string GenMethodArgsFree(const Declaration& decl);
+ void GenServiceBase(std::ofstream& stream, const Interface& iface);
+ std::string GenServiceBaseMethodDecls(const Interface& iface);
+ std::string GenMethodParams(const Declaration& decl);
+ void GenDelegateBase(std::ofstream& stream, const Declaration& decl);
+ std::string GenDelegateParams(const Declaration& decl);
+ std::string GenDelegateParamTypes(const Declaration& decl);
+ std::string GenDelegateParcelRead(const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_CION_PROXY_GEN_H_
diff --git a/idlc/gen_cion/dart_cion_proxy_gen_cb.h b/idlc/gen_cion/dart_cion_proxy_gen_cb.h
new file mode 100644
index 0000000..f96a881
--- /dev/null
+++ b/idlc/gen_cion/dart_cion_proxy_gen_cb.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_CION_PROXY_GEN_CB_H_
+#define IDLC_GEN_DART_CION_PROXY_GEN_CB_H_
+
+namespace tidl {
+
+/**
+ * <DELEGATE_NAME> The name of the delegate.
+ * <DELEGATE_ID> The ID of the delegate.
+ * <DELEGATE_PARAMS> Parameters of the delegate.
+ * <DELEGATE_PARAM_TYPES> Types of Parameters of the delegate.
+ * <DELEGATE_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ */
+constexpr const char CB_DELEGATE_BASE[] =
+R"__dart_cb(
+/// Called when the <DELEGATE_NAME> event is received.
+typedef <DELEGATE_NAME> = void Function(<DELEGATE_PARAM_TYPES>);
+
+class _<DELEGATE_NAME> extends _Delegate {
+ /// Constructor for this class.
+ _<DELEGATE_NAME>(<DELEGATE_NAME> callback, {bool once = false})
+ : super(_DelegateId.<DELEGATE_ID>.id, once, callback);
+
+ @override
+ Future<void> onReceivedEvent(Parcel parcel) async {
+ <DELEGATE_PARCEL_READ>
+ callback?.call(<DELEGATE_PARAMS>);
+ }
+}
+)__dart_cb";
+
+/**
+ * <INTERFACE_NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__dart_cb(
+typedef OnDisconnected = Future<void> Function(PeerInfo);
+typedef OnFileReceived = Future<void> Function(PeerInfo, Payload, PayloadTransferStatus);
+
+/// [<INTERFACE_NAME>] class for Cion.
+class <INTERFACE_NAME> {
+ /// Constructor for this class.
+ <INTERFACE_NAME>(this.serverDisplayName, {SecurityInfo? security}) : _client = Client('<INTERFACE_NAME>', security: security);
+
+ final List<_Delegate> _delegates = <_Delegate>[];
+
+ Future<void> _onDisconnectedEvent(PeerInfo peer) async {
+ _isConnected = false;
+ _onDisconnected?.call(peer);
+ }
+
+ Future<void> _onDiscoveredEvent(PeerInfo peer) async {
+ if (serverDisplayName != peer.displayName) {
+ return;
+ }
+
+ _client.stopDiscovery();
+ final ConnectionResult result = await _client.connect(peer,
+ onDisconnected: _onDisconnectedEvent, onReceived: _onReceivedEvent);
+ if (result.status == ConnectionStatus.ok) {
+ _isConnected = true;
+ } else {
+ _isConnected = false;
+ }
+
+ if (_connectCompleter != null) {
+ _connectCompleter!.complete(_isConnected);
+ _connectCompleter = null;
+ }
+ }
+
+ Future<void> _onReceivedEvent(
+ PeerInfo peer, Payload payload, PayloadTransferStatus status) async {
+
+ if (payload.type == PayloadType.file) {
+ _onFileReceived?.call(peer, payload as FilePayload, status);
+ return;
+ }
+
+ final Uint8List raw = (payload as DataPayload).data;
+ final Parcel parcel = Parcel.fromRaw(raw);
+
+ final int cmd = parcel.readInt32();
+ if (cmd != _MethodId.callback.id) {
+ return;
+ }
+
+ final int id = parcel.readInt32();
+ final int sequenceId = parcel.readInt32();
+ final bool once = parcel.readBool();
+
+ for (final _Delegate delegate in _delegates) {
+ if (delegate.id == id && delegate.sequenceId == sequenceId) {
+ await delegate.onReceivedEvent(parcel);
+ if (delegate.once && once) {
+ _delegates.remove(delegate);
+ }
+ break;
+ }
+ }
+ }
+
+ /// Connects with the server.
+ Future<bool> connect({required OnDisconnected onDisconnected<FILE_REVEIVE_DEF>}) async {
+ if (_isConnected) {
+ return true;
+ }
+
+ if (_connectCompleter != null) {
+ throw StateError('Already try to connect');
+ }
+
+
+ <FILE_REVEIVE_CB>
+ _onDisconnected = onDisconnected;
+ await _client.tryDiscovery(onDiscovered: _onDiscoveredEvent);
+ _connectCompleter = Completer<bool>();
+ return _connectCompleter!.future;
+ }
+
+ /// Disconnects with the server.
+ void disconnect() {
+ if (!_isConnected) {
+ return;
+ }
+
+ _client.disconnect();
+ }
+
+ /// Disposes of registered delegate interface.
+ void disposeCallback(Function callback) {
+ _delegates
+ .removeWhere((_Delegate delegate) => delegate.callback == callback);
+ }
+
+ <METHODS>
+
+ final Client _client;
+ final String serverDisplayName;
+ bool _isConnected = false;
+ OnDisconnected? _onDisconnected;
+ OnFileReceived? _onFileReceived;
+ Completer<bool>? _connectCompleter;
+}
+)__dart_cb";
+
+/**
+ * <METHOD_NAME> The name of method.
+ * <RETURN_TYPE> The type of return value.
+ * <ARGS> The arguments of method.
+ * <METHOD_PARCEL_WRITE> The implementation to write to the parcel.
+ * <METHOD_PARCEL_READ> The implementation to read the arguments from the parcel.
+ * to the parcel.
+ */
+constexpr const char CB_METHOD_BASE[] =
+R"__dart_cb(
+/// This method is used to send '<METHOD_NAME>' request to the stub app.
+<RETURN_TYPE> <LOWER_METHOD_NAME>(<ARGS>) <ASYNC>{
+ <METHOD_PARCEL_WRITE>
+}
+)__dart_cb";
+
+/**
+ * <METHOD_NAME> The name of method.
+ * <PARCEL_WRITE> The implementation of parcel write.
+ */
+constexpr const char CB_METHOD_PARCEL_WRITE[] =
+R"__dart_cb(
+if (!_isConnected) {
+ throw StateError('Must be connected first');
+}
+
+final Parcel parcel = Parcel();
+parcel.writeInt32(_MethodId.<METHOD_NAME>.id);
+
+<PARCEL_WRITE>
+final Payload payload = DataPayload(parcel.asRaw());
+_client.send(payload);
+)__dart_cb";
+
+/**
+ * <PARCEL_READ> The implementation of parcel read.
+ */
+constexpr const char CB_METHOD_PARCEL_WRITE_AND_READ[] =
+R"__dart_cb(
+if (!_isConnected) {
+ throw StateError('Must be connected first');
+}
+
+final Parcel parcel = Parcel();
+parcel.writeInt32(_MethodId.<METHOD_NAME>.id);
+
+<PARCEL_WRITE>
+final Uint8List raw = parcel.asRaw();
+final Uint8List receivedData = _client.sendAndReceiveData(raw);
+final Parcel parcelReceived = Parcel.fromRaw(receivedData);
+
+final int cmd = parcelReceived.readInt32();
+if (cmd != _MethodId.result.id) {
+ throw StateError('Invalid protocol exception');
+}
+
+<FILE_SEND>
+<PARCEL_READ>
+return ret;
+)__dart_cb";
+
+/**
+ * <DELEGATE_TYPE> The name of the delegate object.
+ * <DELEGATE_NAME> The name of the delegate object.
+ */
+constexpr const char CB_METHOD_DELEGATE_WRITE[] =
+R"__dart_cb(
+{
+ final _<DELEGATE_TYPE> delegate = _<DELEGATE_TYPE>(<DELEGATE_NAME>);
+ delegate.serialize(parcel);
+ _delegates.add(delegate);
+}
+)__dart_cb";
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_CION_PROXY_GEN_CB_H_
diff --git a/idlc/gen_cion/dart_cion_stub_gen.cc b/idlc/gen_cion/dart_cion_stub_gen.cc
new file mode 100644
index 0000000..4ca293f
--- /dev/null
+++ b/idlc/gen_cion/dart_cion_stub_gen.cc
@@ -0,0 +1,434 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/dart_cion_stub_gen.h"
+
+#include "idlc/gen_cion/dart_cion_gen_base_cb.h"
+#include "idlc/gen_cion/dart_cion_stub_gen_cb.h"
+
+namespace tidl {
+
+DartCionStubGen::DartCionStubGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans)
+ : DartCionGeneratorBase(doc, trans) {}
+
+void DartCionStubGen::OnInitGen(std::ofstream& stream) {
+ GenAnnotation(stream);
+ GenImport(stream);
+ GenVersion(stream);
+ GenDelegateId(stream);
+ GenMethodId(stream);
+ GenCallbackBase(stream);
+ GenStructures(stream);
+ GenInterfaces(stream);
+}
+
+void DartCionStubGen::OnFiniGen(std::ofstream& stream) {}
+
+void DartCionStubGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void DartCionStubGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ GenServiceBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ GenDelegateBase(stream, *d);
+ }
+
+ GenInterfaceBase(stream, iface);
+}
+
+void DartCionStubGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string name = iface.GetID();
+ name[0] = ::toupper(name[0]);
+ ReplaceAll(CB_INTERFACE_BASE, {
+ { "<CTOR>", GenInterfaceCtor(iface) },
+ { "<EXTEND_NAME>", GetTransportable().Dart().GenStubExtend() },
+ { "<FILE_RECEIVE>",
+ HasFile(iface, false) ? GetTransportable().Dart().GenFileRecive() : "" },
+ { "<PARAM_DEF>", GetTransportable().Dart().GenStubParamDef() },
+ { "<SUPER_PARAM>", GetTransportable().Dart().GenStubSuperParam() },
+ { "<INTERFACE_NAME>", name },
+ { "<METHOD_HANDLERS>", GenInterfaceMethodHandlers(iface) },
+ { "<PEER_INFO_T>", GetTransportable().Dart().GenPeerInfo() }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(std::move(str));
+ })
+ .Out(stream);
+}
+
+std::string DartCionStubGen::GenInterfaceCtor(const Interface& iface) {
+ std::string method_handler_table;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string name = d->GetID();
+ name[0] = ::tolower(name[0]);
+
+ std::string handler;
+ if (d->GetMethodType() == Declaration::MethodType::ASYNC)
+ handler = CB_METHOD_ASYNC_HANDLER_TABLE;
+ else
+ handler = CB_METHOD_SYNC_HANDLER_TABLE;
+
+ method_handler_table += ReplaceAll(handler, {
+ { "<METHOD_ID>", name },
+ { "<METHOD_NAME>", d->GetID() }
+ });
+ method_handler_table += NLine(1);
+ }
+
+ std::string attributes;
+ for (const auto& i : iface.GetAttributes()) {
+ if (i->GetKey() == "privilege") {
+ attributes += "addPrivilege('" + i->GetValue() + "');";
+ attributes += NLine(1);
+ } else if (i->GetKey() == "trusted" && i->GetValue() == "true") {
+ attributes += "setTrusted(true);";
+ attributes += NLine(1);
+ }
+ }
+
+ std::string code = std::move(method_handler_table);
+ code += NLine(1);
+ code += attributes;
+ return code;
+}
+
+std::string DartCionStubGen::GenInterfaceMethodHandlers(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string handler;
+ if (d->GetMethodType() == Declaration::MethodType::ASYNC)
+ handler = CB_METHOD_ASYNC_HANDLER_BASE;
+ else
+ handler = CB_METHOD_SYNC_HANDLER_BASE;
+ code += ReplaceAll(handler, {
+ { "<METHOD_NAME>", d->GetID() },
+ { "<METHOD_HANDLER_PARCEL_READ>", GenMethodHandlerParcelRead(*d) },
+ { "<METHOD_HANDLER_INVOKE>", GenMethodHandlerInvoke(*d) },
+ { "<METHOD_HANDLER_PARCEL_WRITE>", GenMethodHandlerParcelWrite(*d) },
+ });
+ }
+
+ return RemoveLine(code);
+}
+
+std::string DartCionStubGen::GenMethodHandlerParcelRead(const Declaration& decl) {
+ std::string code;
+
+ if (HasFile(decl.GetType()))
+ code += CB_FILE_LIST + NLine(1);
+
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType()) {
+ code += "final " + ConvertTypeToString(type) + " " + p->GetID() +
+ " = " + ConvertTypeToString(type);
+ code += IsDelegateType(type) ? "(service);" : "();";
+ code += NLine(1);
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_READ, {
+ { "<NAME>", p->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += "final " + ConvertTypeToString(type) + " " + p->GetID() +
+ " = [];";
+ code += NLine(1);
+ code += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<NAME>", p->GetID() },
+ { "<PARCEL>" , "parcel" }
+ });
+ code += NLine(1);
+ } else {
+ code += "final " + ConvertTypeToString(type) + " ";
+ code += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcel" },
+ { "<NAME>", p->GetID() },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) }
+ });
+ code += NLine(1);
+ }
+ }
+
+ return code;
+}
+
+std::string DartCionStubGen::GenMethodHandlerInvoke(const Declaration& decl) {
+ std::string args;
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ if (!args.empty())
+ args += ", ";
+
+ args += p->GetID();
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType()) {
+ code += "final " + ConvertTypeToString(type) + " " + p->GetID() +
+ " = " + ConvertTypeToString(type) + "();";
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += "final " + ConvertTypeToString(type) + " " + p->GetID() +
+ " = [];";
+ code += NLine(1);
+ } else {
+ code += "final " + ConvertTypeToString(type) + " " + p->GetID() + ";";
+ code += NLine(1);
+ }
+ }
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC)
+ code += "final " + ConvertTypeToString(decl.GetType()) + " ret = await ";
+
+ code += ReplaceAll(CB_METHOD_HANDLER_INVOKE, {
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<ARGS>", args }
+ });
+ return code;
+}
+
+std::string DartCionStubGen::GenMethodHandlerParcelWrite(const Declaration& decl) {
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC)
+ return {};
+
+ std::string code = GenMethodHandlerResultParcelWrite(decl);
+ code += GenMethodHandlerOutParamParcelWrite(decl);
+
+ if (HasFile(decl.GetType()))
+ code += ReplaceAll(CB_FILE_SEND, "<SEND_ASYNC_FILE>",
+ "service._serverBase!.send(service.peer!, payload);");
+
+ code = ReplaceAll(CB_METHOD_HANDLER_PARCEL_WRITE, "<PARCEL_WRITE>", code);
+ return code;
+}
+
+std::string DartCionStubGen::GenMethodHandlerResultParcelWrite(
+ const Declaration& decl) {
+ std::string code;
+ auto& type = decl.GetType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<NAME>", "ret" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<NAME>", "ret" }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>" , "ret" }
+ });
+
+ if (HasFile(type))
+ code += ReplaceAll(CB_FILE_ADD, "<FILE>", "ret");
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+std::string DartCionStubGen::GenMethodHandlerOutParamParcelWrite(
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<NAME>", p->GetID() }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<NAME>", p->GetID() }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>" , p->GetID() }
+ });
+ code += NLine(1);
+ }
+ }
+
+ return code;
+}
+
+void DartCionStubGen::GenServiceBase(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_SERVICE_BASE, {
+ { "<PEER_INFO_T>", GetTransportable().Dart().GenPeerInfo() },
+ { "<FILE_RECEIVE_DECL>",
+ HasFile(iface, false) ? GetTransportable().Dart().GenFileReciveDef() : "" },
+ { "<METHOD_DECLS>", GenServiceBaseMethodDecls(iface) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(RemoveLine(std::move(str)));
+ })
+ .Out(stream);
+}
+
+std::string DartCionStubGen::GenServiceBaseMethodDecls(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_METHOD_DECL, {
+ { "<RETURN_TYPE>", ConvertTypeToString(d->GetType()) },
+ { "<METHOD_NAME>", d->GetID() },
+ { "<METHOD_PARAMS>", GenMethodParams(*d) }
+ });
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+std::string DartCionStubGen::GenMethodParams(const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ if (!params.empty())
+ params += ", ";
+
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += ConvertTypeToString(type) + " " + p->GetID();
+ }
+
+ return params;
+}
+
+void DartCionStubGen::GenDelegateBase(std::ofstream& stream,
+ const Declaration& decl) {
+ std::string id = decl.GetID();
+ id[0] = ::tolower(id[0]);
+ ReplaceAll(CB_DELEGATE_BASE, {
+ { "<DELEGATE_NAME>", GetClassName(decl.GetID()) },
+ { "<DELEGATE_ID>", id },
+ { "<DELEGATE_PARAMS>", GenDelegateParams(decl) },
+ { "<SEND_FILE>", HasFile(decl) ? CB_FILE_SEND : "" },
+ { "<SEND_ASYNC_FILE>", "service._serverBase!.send(service.peer!, payload);" },
+ { "<SEND_ASYNC>", GetTransportable().Dart().GenStubSendAsync("parcel",
+ "service._serverBase", "service.peer" ) },
+ { "<DELEGATE_PARCEL_WRITE>", GenDelegateParcelWrite(decl) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+std::string DartCionStubGen::GenDelegateParams(const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ if (!params.empty())
+ params += ", ";
+
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += ConvertTypeToString(type) + " " + p->GetID();
+ }
+
+ return params;
+}
+
+std::string DartCionStubGen::GenDelegateParcelWrite(const Declaration& decl) {
+ std::string code;
+ bool has_file = false;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<NAME>", p->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<NAME>", p->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ if (type.GetMetaType() != nullptr &&
+ type.GetMetaType()->ToString() == "file") {
+ code += ReplaceAll(CB_FILE_ADD_ALL, {
+ { "<FILE_LIST>", p->GetID()},
+ });
+ has_file = true;
+ code += NLine(1);
+ }
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>", p->GetID() }
+ });
+ code += NLine(1);
+ if (type.ToString() == "file") {
+ code += ReplaceAll(CB_FILE_ADD, {
+ { "<FILE>", p->GetID()},
+ });
+ has_file = true;
+ code += NLine(1);
+ }
+ }
+ }
+
+ if (has_file)
+ code = CB_FILE_LIST + NLine(1) + code;
+
+ return code;
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/dart_cion_stub_gen.h b/idlc/gen_cion/dart_cion_stub_gen.h
new file mode 100644
index 0000000..7e8ad83
--- /dev/null
+++ b/idlc/gen_cion/dart_cion_stub_gen.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_CION_STUB_GEN_H_
+#define IDLC_GEN_DART_CION_STUB_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/dart_cion_gen_base.h"
+
+namespace tidl {
+
+class DartCionStubGen : public DartCionGeneratorBase {
+ public:
+ explicit DartCionStubGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~DartCionStubGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ std::string GenInterfaceCtor(const Interface& iface);
+ std::string GenInterfaceMethodHandlers(const Interface& iface);
+ std::string GenMethodHandlerParcelRead(const Declaration& decl);
+ std::string GenMethodHandlerInvoke(const Declaration& decl);
+ std::string GenMethodHandlerParcelWrite(const Declaration& decl);
+ std::string GenMethodHandlerResultParcelWrite(const Declaration& decl);
+ std::string GenMethodHandlerOutParamParcelWrite(const Declaration& decl);
+ void GenServiceBase(std::ofstream& stream, const Interface& iface);
+ std::string GenServiceBaseMethodDecls(const Interface& iface);
+ std::string GenMethodParams(const Declaration& decl);
+ void GenDelegateBase(std::ofstream& stream, const Declaration& decl);
+ std::string GenDelegateParams(const Declaration& decl);
+ std::string GenDelegateParcelWrite(const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_CION_STUB_GEN_H_
diff --git a/idlc/gen_cion/dart_cion_stub_gen_cb.h b/idlc/gen_cion/dart_cion_stub_gen_cb.h
new file mode 100644
index 0000000..28a5045
--- /dev/null
+++ b/idlc/gen_cion/dart_cion_stub_gen_cb.h
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_CION_STUB_GEN_CB_H_
+#define IDLC_GEN_DART_CION_STUB_GEN_CB_H_
+
+namespace tidl {
+
+/**
+ * <METHOD_DECLS> The declarations of methods.
+ */
+constexpr const char CB_SERVICE_BASE[] =
+R"__dart_cb(
+/// Abstract class for creating a service base class for RPC.
+abstract class ServiceBase {
+ /// Constructor for this class.
+ ServiceBase(this.peer);
+
+ /// The PeerInfo of client
+ <PEER_INFO_T>? peer;
+
+ bool _isConnected = false;
+ Server? _serverBase;
+
+ /// Disconnects with the client.
+ void disconnect() {
+ if (peer != null && _isConnected) {
+ _serverBase!.disconnect(peer!);
+ peer = null;
+ _isConnected = false;
+ }
+ }
+
+ /// Accepts the connection request from the client.
+ void accept() {
+ if (peer != null && !_isConnected) {
+ _serverBase!.accept(peer!);
+ _isConnected = true;
+ }
+ }
+
+ /// Rejects the connection request from the client.
+ void reject(String reason) {
+ if (peer != null && !_isConnected) {
+ _serverBase!.reject(peer!, reason);
+ peer = null;
+ }
+ }
+
+
+ /// This method will be called when connection requested from the client
+ Future<void> onConnectionRequest();
+
+ /// This abstract method will be called when the client is disconnected.
+ Future<void> onTerminate();
+ <FILE_RECEIVE_DECL>
+ <METHOD_DECLS>
+}
+)__dart_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the method.
+ * <METHOD_NAME> The name of the method.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_METHOD_DECL[] =
+R"__dart_cb(
+/// This abstract method will be called when the '<METHOD_NAME>' request is delivered.
+Future<<RETURN_TYPE>> on<METHOD_NAME>(<METHOD_PARAMS>);)__dart_cb";
+
+
+/**
+ * <DELEGATE_NAME> The name of the delegate.
+ * <DELEGATE_ID> The ID of the delegate.
+ * <DELEGATE_PARAMS> Parameters of the delegate.
+ * <DELEGATE_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ */
+constexpr const char CB_DELEGATE_BASE[] =
+R"__dart_cb(
+/// '<DELEGATE_NAME>' class to invoke the delegate method.
+class <DELEGATE_NAME> extends _Delegate {
+ /// Constructor for this class.
+ <DELEGATE_NAME>(this.service, {bool once = false})
+ : super(_DelegateId.<DELEGATE_ID>.id, once);
+
+ /// The client service.
+ ServiceBase service;
+ bool _wasInvoked = false;
+
+ /// Invokes the delegate method of the client.
+ Future<void> invoke(<DELEGATE_PARAMS>) async {
+ if (service.peer == null) {
+ throw StateError('Must be connected first');
+ }
+
+ if (once && _wasInvoked) {
+ throw Exception('Can be invoked only once');
+ }
+
+ final Parcel parcel = Parcel();
+ parcel.writeInt32(_MethodId.callback.id);
+ serialize(parcel);
+
+ <DELEGATE_PARCEL_WRITE>
+
+ <SEND_ASYNC>
+
+ <SEND_FILE>
+
+ _wasInvoked = true;
+ }
+}
+)__dart_cb";
+
+/**
+ * <INTERFACE_NAME> The name of the interface.
+ * <CTOR> The implementation of the constructor of the interface.
+ * <METHOD_HANDLERS> The implementation of the method handlers of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+ R"__dart_cb(
+
+/// This is used when creating a service instance.
+typedef ServiceBuilder = ServiceBase Function(<PEER_INFO_T> peer);
+
+typedef _AsyncMethodHandler = Future<void> Function(ServiceBase, Parcel);
+typedef _SyncMethodHandler = Future<Uint8List> Function(ServiceBase, Parcel);
+
+/// [<INTERFACE_NAME>] class for RPC.
+class <INTERFACE_NAME> extends <EXTEND_NAME> {
+ /// Constructor for this class.
+ <INTERFACE_NAME>({<PARAM_DEF>required ServiceBuilder serviceBuilder} )
+ : _serviceBuilder = serviceBuilder,
+ super(<SUPER_PARAM>) {
+ <CTOR>
+ }
+
+ /// The indexable collection of [ServiceBase] class.
+ final List<ServiceBase> services = <ServiceBase>[];
+ final Map<int, _AsyncMethodHandler> _asyncMethodHandlers = <int, _AsyncMethodHandler>{};
+ final Map<int, _SyncMethodHandler> _syncMethodHandlers = <int, _SyncMethodHandler>{};
+ final ServiceBuilder _serviceBuilder;
+
+ /// Listens to the requests for connections.
+ Future<void> start() async {
+ await super.listen(
+ onConnectionRequest: (<PEER_INFO_T> peer) async {
+ final ServiceBase service = _serviceBuilder(peer);
+ service._serverBase = this;
+ service.onConnectionRequest();
+ if (service._isConnected) {
+ services.add(service);
+ }
+ }, onDisconnected: (<PEER_INFO_T> peer) async {
+ for (final ServiceBase service in services) {
+ if (service.peer!.uuid == peer.uuid) {
+ await service.onTerminate();
+ services.remove(service);
+ break;
+ }
+ }
+ }, onDataReceived : (<PEER_INFO_T> peer, Uint8List data) async {
+ Uint8List returnData = Uint8List(0);
+ ServiceBase? service;
+ for (final ServiceBase s in services) {
+ if (s.peer!.uuid == peer.uuid) {
+ service = s;
+ break;
+ }
+ }
+
+ if (service == null) {
+ return returnData;
+ }
+
+ final Parcel parcel = Parcel.fromRaw(data);
+
+ final int cmd = parcel.readInt32();
+ if (_syncMethodHandlers.containsKey(cmd)) {
+ returnData = await _syncMethodHandlers[cmd]!(service!, parcel);
+ }
+
+ return returnData;
+
+ }, onPayloadReceived:
+ (<PEER_INFO_T> peer, Payload payload, PayloadTransferStatus status) async {
+ ServiceBase? service;
+ for (final ServiceBase s in services) {
+ if (s.peer!.uuid == peer.uuid) {
+ service = s;
+ break;
+ }
+ }
+
+ if (service == null) {
+ return;
+ }
+ <FILE_RECEIVE>
+
+ final Uint8List raw = (payload as DataPayload).data;
+ final Parcel parcel = Parcel.fromRaw(raw);
+
+ final int cmd = parcel.readInt32();
+ if (_asyncMethodHandlers.containsKey(cmd)) {
+ await _asyncMethodHandlers[cmd]!(service!, parcel);
+ }
+ }
+ );
+ }
+
+ @override
+ Future<void> stop() async {
+ await super.stop();
+ }
+
+ <METHOD_HANDLERS>
+}
+)__dart_cb";
+
+/**
+ * <METHOD_ID> The ID of the method.
+ * <METHOD_NAME> The name of the method.
+ */
+constexpr const char CB_METHOD_ASYNC_HANDLER_TABLE[] =
+R"__dart_cb(_asyncMethodHandlers[_MethodId.<METHOD_ID>.id] = _on<METHOD_NAME>Method;)__dart_cb";
+
+/**
+ * <METHOD_ID> The ID of the method.
+ * <METHOD_NAME> The name of the method.
+ */
+constexpr const char CB_METHOD_SYNC_HANDLER_TABLE[] =
+R"__dart_cb(_syncMethodHandlers[_MethodId.<METHOD_ID>.id] = _on<METHOD_NAME>Method;)__dart_cb";
+
+/**
+ * <METHOD_NAME> The name of the method.
+ * <METHOD_HANDLER_PARCEL_READ> The implementation to read the arguments from the parcel.
+ * <METHOD_HANDLER_INVOKE> The implementation to invoke the method handle.
+ * <METHOD_HANDLER_PARCEL_WRITE> The implementation to write the result to the parcel.
+ */
+constexpr const char CB_METHOD_ASYNC_HANDLER_BASE[] =
+R"__dart_cb(
+Future<void> _on<METHOD_NAME>Method(ServiceBase service, Parcel parcel) async {
+ <METHOD_HANDLER_PARCEL_READ>
+ <METHOD_HANDLER_INVOKE>
+ <METHOD_HANDLER_PARCEL_WRITE>
+}
+)__dart_cb";
+
+/**
+ * <METHOD_NAME> The name of the method.
+ * <METHOD_HANDLER_PARCEL_READ> The implementation to read the arguments from the parcel.
+ * <METHOD_HANDLER_INVOKE> The implementation to invoke the method handle.
+ * <METHOD_HANDLER_PARCEL_WRITE> The implementation to write the result to the parcel.
+ * <METHOD_HANDLER_ARGS_FREE> The implementation to release arguments.
+ */
+constexpr const char CB_METHOD_SYNC_HANDLER_BASE[] =
+R"__dart_cb(
+Future<Uint8List> _on<METHOD_NAME>Method(ServiceBase service, Parcel parcel) async {
+ Uint8List returnData = Uint8List(0);
+ <METHOD_HANDLER_PARCEL_READ>
+ <METHOD_HANDLER_INVOKE>
+ <METHOD_HANDLER_PARCEL_WRITE>
+ return returnData;
+}
+)__dart_cb";
+
+
+/**
+ * <METHOD_NAME> The name of the method.
+ * <ARGS> The arguments of the method.
+ */
+constexpr const char CB_METHOD_HANDLER_INVOKE[] =
+R"__dart_cb(service.on<METHOD_NAME>(<ARGS>);)__dart_cb";
+
+/**
+ * <PARCEL_WRITE> The implementation to write the result to the parcel.
+ */
+constexpr const char CB_METHOD_HANDLER_PARCEL_WRITE[] =
+R"__dart_cb(
+final Parcel result = Parcel();
+final ParcelHeader header = parcel.header;
+final ParcelHeader resultHeader = result.header;
+resultHeader.tag = _tidlVersion;
+resultHeader.sequenceNumber = header.sequenceNumber;
+
+result.writeInt32(_MethodId.result.id);
+<PARCEL_WRITE>
+
+returnData = result.asRaw();
+
+)__dart_cb";
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_CION_STUB_GEN_CB_H_
diff --git a/idlc/gen_cion/dart_transportable.h b/idlc/gen_cion/dart_transportable.h
new file mode 100644
index 0000000..4040e02
--- /dev/null
+++ b/idlc/gen_cion/dart_transportable.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_DART_TRANSPORTABLE_H_
+#define IDLC_GEN_CION_DART_TRANSPORTABLE_H_
+
+#include <list>
+#include <string>
+
+namespace tidl {
+
+class DartTransportable {
+ public:
+ virtual ~DartTransportable() = default;
+ virtual std::string GenImport() const = 0;
+ virtual std::string GenPeerInfo() const = 0;
+ virtual std::string GenStubSendAsync(std::string parcel,
+ std::string server, std::string peer) const = 0;
+ virtual std::string GenFileReciveDef() const = 0;
+ virtual std::string GenFileRecive() const = 0;
+
+ virtual std::string GenStubExtend() const = 0;
+ virtual std::string GenStubParamDef() const = 0;
+ virtual std::string GenStubSuperParam() const = 0;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CION_DART_TRANSPORTABLE_H_
diff --git a/idlc/gen_cion/default_c_transportable.cc b/idlc/gen_cion/default_c_transportable.cc
new file mode 100644
index 0000000..081f90e
--- /dev/null
+++ b/idlc/gen_cion/default_c_transportable.cc
@@ -0,0 +1,846 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/default_c_transportable.h"
+
+#include <utility>
+
+#include "idlc/gen/replace_all.h"
+
+namespace {
+
+constexpr const char __CLINET_FILE_SEND[] =
+R"__c_cb(
+ cion_payload_h pl;
+ int ret = cion_payload_create(&pl, CION_PAYLOAD_TYPE_FILE);
+
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_create : %d", ret);
+ return ret;
+ }
+
+ ret = cion_payload_set_file_path(pl, <FILE_PATH>);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_set_file_path : %d - %s", ret, value);
+ cion_payload_destroy(pl);
+ return ret;
+ }
+
+ ret = cion_client_send_payload_async(<CLIENT_H>, pl, NULL, NULL);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_client_send_payload_async : %d - %s", ret, value);
+ cion_payload_destroy(pl);
+ return ret;
+ }
+
+ cion_payload_destroy(pl);
+)__c_cb";
+
+constexpr const char __SERVER_FILE_SEND[] =
+R"__c_cb(
+ cion_payload_h pl;
+ int r = cion_payload_create(&pl, CION_PAYLOAD_TYPE_FILE);
+
+ if (r != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_create : %d", r);
+ return r;
+ }
+
+ r = cion_payload_set_file_path(pl, <FILE_PATH>);
+ if (r != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_set_file_path : %d - %s", r, value);
+ cion_payload_destroy(pl);
+ return r;
+ }
+
+ r = cion_server_send_payload_async(<SERVER_H>, <PEER_H>, pl, NULL, NULL);
+ if (r != CION_ERROR_NONE) {
+ _E("Failed to cion_server_send_payload_async : %d - %s", r, value);
+ cion_payload_destroy(pl);
+ return r;
+ }
+
+ cion_payload_destroy(pl);
+)__c_cb";
+
+constexpr const char __SERVER_REGISTER[] =
+R"__c_cb(
+ ret = cion_security_create(&security);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to create security handle. error(%d)", ret);
+ return ret;
+ }
+
+ <SET_SECURITY>
+ __<NAME>.security = security;
+
+ ret = cion_server_create(&__<NAME>.stub, service_name, display_name, __<NAME>.security);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to create stub handle. error(%d)", ret);
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = cion_server_add_connection_result_cb(__<NAME>.stub, __<PREFIX>_<NAME>_connection_result_cb, &__<NAME>);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to add connection result event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = cion_server_add_payload_received_cb(__<NAME>.stub, __<PREFIX>_<NAME>_payload_received_cb, &__<NAME>);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to add payload recieved event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = cion_server_add_disconnected_cb(__<NAME>.stub, __<PREFIX>_<NAME>_disconnected_cb, &__<NAME>);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to add disconnected event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = cion_server_set_data_received_cb(__<NAME>.stub, __<PREFIX>_<NAME>_data_received_cb, &__<NAME>);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to add data recieved event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = cion_server_listen(__<NAME>.stub, __<PREFIX>_<NAME>_connection_request_cb, &__<NAME>);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to listen events. error(%d)", ret);
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+)__c_cb";
+
+
+
+constexpr const char __SERVER_UNREGISTER[] =
+R"__c_cb(
+ if (__<NAME>.security)
+ cion_security_destroy(__<NAME>.security);
+
+ if (__<NAME>.stub) {
+ cion_server_destroy(__<NAME>.stub);
+ __<NAME>.stub = nullptr;
+ }
+)__c_cb";
+
+constexpr const char __SERVER_ACCEPT[] =
+R"__c_cb(
+ ret = cion_server_accept(__<NAME>.stub, peer_info);
+ if (ret != CION_ERROR_NONE)
+ _E("Failed to accept. error(%d)", ret);
+)__c_cb";
+
+constexpr const char __SERVER_REJECT[] =
+R"__c_cb(
+ ret = cion_server_reject(__<NAME>.stub, peer_info, reason);
+ if (ret != CION_ERROR_NONE)
+ _E("Failed to reject. error(%d)", ret);
+)__c_cb";
+
+constexpr const char __SERVER_SET_DISPLAY_NAME[] =
+R"__c_cb(
+ ret = cion_server_set_display_name(__<NAME>.stub, display_name);
+ if (ret != CION_ERROR_NONE)
+ _E("Failed to set display name. error(%d)", ret);
+)__c_cb";
+
+constexpr const char __CLIENT_TRY_CONNECT[] =
+R"__c_cb(
+ ret = cion_client_connect(<CLIENT>, <PEER>);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to connect to stub. error(%d)", ret);
+ return ret;
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_DISCONNECT[] =
+R"__c_cb(
+ ret = cion_client_disconnect(<CLIENT>);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to disconnect to stub. error(%d)", ret);
+ return ret;
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_TRY_DISCOVERY[] =
+R"__c_cb(
+ ret = cion_client_try_discovery(<CLIENT>, __<PREFIX>_<NAME>_discovered, h);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to discovery to stub. error(%d)", ret);
+ return ret;
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_STOP_DISCOVERY[] =
+R"__c_cb(
+ ret = cion_client_stop_discovery(<CLIENT>);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to stop discovery to stub. error(%d)", ret);
+ return ret;
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_SEND_ASYNC[] =
+R"__c_cb(
+ res_ = cion_payload_create(&<PAYLOAD>, CION_PAYLOAD_TYPE_DATA);
+ if (res_ != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_create : %d", res_);
+ cion_payload_destroy(<PAYLOAD>);
+ goto out;
+ }
+
+ res_ = cion_payload_set_data(<PAYLOAD>, (const unsigned char*)data_, <SIZE>);
+ if (res_ != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_set_data : %d", res_);
+ cion_payload_destroy(<PAYLOAD>);
+ goto out;
+ }
+
+ res_ = cion_client_send_payload_async(<CLIENT>, <PAYLOAD>, NULL, NULL);
+ cion_payload_destroy(<PAYLOAD>);
+ if (res_ != CION_ERROR_NONE) {
+ _E("Failed to cion_client_send_payload_async : %d", res_);
+ goto out;
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_SEND[] =
+R"__c_cb(
+ res_ = cion_client_send_data(<CLIENT>, <DATA>, <DATA_SIZE> , 5 * 1000, &<RET_DATA>, &<RET_DATA_SIZE>);
+
+ if (res_ != CION_ERROR_NONE) {
+ _E("Failed to send parcel. error(%d)", res_);
+ goto out;
+ }
+)__c_cb";
+
+constexpr const char __SERVER_SEND_ASYNC[] =
+R"__c_cb(
+ ret_ = cion_payload_create(&<PAYLOAD>, CION_PAYLOAD_TYPE_DATA);
+ if (ret_ != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_create : %d", ret_);
+ cion_payload_destroy(<PAYLOAD>);
+ goto out;
+ }
+
+ ret_ = cion_payload_set_data(<PAYLOAD>, (const unsigned char*)data_, <SIZE>);
+ if (ret_ != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_set_data : %d", ret_);
+ cion_payload_destroy(<PAYLOAD>);
+ goto out;
+ }
+
+ ret_ = cion_server_send_payload_async(<SERVER>, peer_info, <PAYLOAD>, NULL, NULL);
+ cion_payload_destroy(<PAYLOAD>);
+ if (ret_ != CION_ERROR_NONE) {
+ _E("Failed to cion_client_send_payload_async : %d", ret_);
+ goto out;
+ }
+)__c_cb";
+
+constexpr const char __GROUP_PUBLISH[] =
+R"__c_cb(
+ res_ = cion_payload_create(&pl_, CION_PAYLOAD_TYPE_DATA);
+ if (res_ != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_create : %d", res_);
+ cion_payload_destroy(pl_);
+ goto out;
+ }
+
+ res_ = cion_payload_set_data(pl_, (const unsigned char*)data_, data_size_);
+ if (res_ != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_set_data : %d", res_);
+ cion_payload_destroy(pl_);
+ goto out;
+ }
+
+ res_ = cion_group_publish(h->group, pl_);
+ cion_payload_destroy(pl_);
+ if (res_ != CION_ERROR_NONE) {
+ _E("Failed to cion_group_publish : %d", res_);
+ goto out;
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_CREATE[] =
+R"__c_cb(
+ ret = cion_security_create(&security);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to create security handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ <SET_SECURITY>
+ handle->security = security;
+
+ ret = cion_client_create(&handle->client, service_name, handle->security);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to create proxy handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ handle->callback = *callback;
+ handle->user_data = user_data;
+
+ ret = cion_client_add_connection_result_cb(handle->client, __<PREFIX>_<NAME>_connection_result, handle);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to add connection result cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = cion_client_add_disconnected_cb(handle->client, __<PREFIX>_<NAME>_disconnected, handle);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to add disconnected event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = cion_client_add_payload_received_cb(handle->client, __<PREFIX>_<NAME>_received, handle);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to add received event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+)__c_cb";
+
+constexpr const char __GROUP_CREATE[] =
+R"__c_cb(
+ ret = cion_security_create(&security);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to create security handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ <SET_SECURITY>
+ handle->security = security;
+
+ ret = cion_group_create(&handle->group, topic_name, handle->security);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to create group handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ handle->callback = *callback;
+ handle->user_data = user_data;
+
+ ret = cion_group_add_joined_cb(handle->group, __<PREFIX>_<NAME>_joined_cb, handle);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to add connection result cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = cion_group_add_left_cb(handle->group, __<PREFIX>_<NAME>_left_cb, handle);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to add disconnected event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = cion_group_add_payload_received_cb(handle->group, __<PREFIX>_<NAME>_received, handle);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to add received event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = cion_group_subscribe(handle->group);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to subscribe event. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ *h = handle;
+)__c_cb";
+
+constexpr const char __GROUP_DESTROY[] =
+R"__c_cb(
+ if (h->group) {
+ cion_group_unsubscribe(h->group);
+ cion_group_destroy(h->group);
+ }
+
+ if (h->security)
+ cion_security_destroy(h->security);
+)__c_cb";
+
+constexpr const char __CLIENT_DESTROY[] =
+R"__c_cb(
+ if (h->client)
+ cion_client_destroy(h->client);
+
+ if (h->security)
+ cion_security_destroy(h->security);
+)__c_cb";
+
+constexpr const char __SET_SECURITY_CA[] =
+R"__c_cb(
+cion_security_set_ca_path(security, "<ARG>");
+)__c_cb";
+
+constexpr const char __SET_SECURITY_CERT[] =
+R"__c_cb(
+cion_security_set_cert_path(security, "<ARG>");
+)__c_cb";
+
+constexpr const char __SET_SECURITY_PRIVATE_KEY[] =
+R"__c_cb(
+cion_security_set_private_key_path(security, "<ARG>");
+)__c_cb";
+
+constexpr const char __PEER_INFO_CLONE[] =
+ "cion_peer_info_clone(<SRC_PEER>, <DEST_PEER>);";
+
+constexpr const char __SERVER_FOREACH_CONNECTED_PEER_INFO[] =
+ "cion_server_foreach_connected_peer_info(__<NAME>.stub, callback, user_data);";
+
+constexpr const char __SERVER_HEADER_EXTRA[] =
+R"__c_cb(
+/**
+ * @brief Sets on-demand launch state.
+ * @details If the on-demand launch state is enabled, the server is launched on demand
+ * when the request comes.
+ * @privilege http://tizen.org/privilege/d2d.remotelaunch
+
+ * @param[in] enabled The enable state
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #<ERROR_PREFIX>_ERROR_IO_ERROR IO error
+ */
+int <PREFIX>_<NAME>_set_ondemand_launch_enabled(bool enable);
+
+/**
+ * @brief Registers the set of the callback functions and the service_name.
+ * @details This function registers the set of the callback functions to handle stub events.
+ * And, the <PREFIX>_server_listen() is called internally to handle events.
+
+ * @privilege %http://tizen.org/privilege/d2d.datasharing \n
+ * %http://tizen.org/privilege/internet
+ * @param[in] service_name The name of service
+ * @param[in] display_name The display name of service
+ * @param[in] callback The set of callback functions to handle stub events
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_NOT_SUPPORTED Not supported
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #<ERROR_PREFIX>_ERROR_IO_ERROR IO error
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #<ERROR_PREFIX>_ERROR_OPERATION_FAILED Operation failed
+ * @retval #<ERROR_PREFIX>_ERROR_PERMISSION_DENIED Permission denied
+ * @see <PREFIX>_<NAME>_unregister()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+int <PREFIX>_<NAME>_register(const char *service_name, const char *display_name, <PREFIX>_<NAME>_callback_s *callback, void *user_data);
+)__c_cb";
+
+constexpr const char __SERVER_BODY_EXTRA[] =
+R"__c_cb(
+int <PREFIX>_<NAME>_set_ondemand_launch_enabled(bool enable)
+{
+ int ret;
+
+ ret = cion_server_set_on_demand_launch_enabled(__<NAME>.stub, enable);
+ if (ret != CION_ERROR_NONE)
+ _E("Failed to set ondemand launch enable. error(%d)", ret);
+
+ return ret;
+}
+
+int <PREFIX>_<NAME>_register(const char *service_name, const char *display_name, <PREFIX>_<NAME>_callback_s *callback, void *user_data)
+)__c_cb";
+
+constexpr const char __CLIENT_HEADER_EXTRA[] =
+R"__c_cb(
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ * @remarks The @a h handle should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @privilege %http://tizen.org/privilege/d2d.datasharing \n
+ * %http://tizen.org/privilege/internet
+ * @param[in] service_name The name of service
+ * @param[in] callback The set of callback functions to handle proxy events
+ * @param[in] user_data The user data to be passed to the callback function
+ * @param[out] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #<ERROR_PREFIX>_ERROR_PERMISSION_DENIED Permission denied
+ * @see <PREFIX>_<NAME>_destroy()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+int <PREFIX>_<NAME>_create(const char *service_name, <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h);
+
+)__c_cb";
+
+constexpr const char __CLIENT_BODY_EXTRA[] =
+R"__c_cb(
+int <PREFIX>_<NAME>_create(const char *service_name, <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h)
+)__c_cb";
+
+constexpr const char __GROUP_HEADER_EXTRA[] =
+R"__c_cb(
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ * @remarks The @a h handle should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ *
+ * @privilege %http://tizen.org/privilege/d2d.datasharing
+ * %http://tizen.org/privilege/internet
+ *
+ * @param[in] topic_name topic_name The name of topic
+ * @param[in] callback The set of callback functions to handle events
+ * @param[in] user_data The user data to be passed to the callback function
+ * @param[out] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_NOT_SUPPORTED Not supported
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #<ERROR_PREFIX>_ERROR_PERMISSION_DENIED Permission denied
+
+ * @see <PREFIX>_<NAME>_destroy()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+int <PREFIX>_<NAME>_create(const char *topic_name, <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h);
+)__c_cb";
+
+constexpr const char __GROUP_BODY_EXTRA[] =
+R"__c_cb(
+int <PREFIX>_<NAME>_create(const char *topic_name, <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h)
+)__c_cb";
+
+} // namespace
+
+namespace tidl {
+
+std::string DefaultCTransportable::GenInclude(bool body, int type) const {
+ return "#include <cion.h>";
+}
+
+std::string DefaultCTransportable::GenHeaderBase() const {
+ return "";
+}
+
+std::string DefaultCTransportable::GenHeaderPayloadHandle() const {
+ return "";
+}
+
+std::string DefaultCTransportable::GenHeaderCommonHandle() const {
+ return "";
+}
+
+std::string DefaultCTransportable::GenHeaderConnectionHandle() const {
+ return "";
+}
+
+std::string DefaultCTransportable::GenHeaderPayloadBase() const {
+ return "";
+}
+
+std::string DefaultCTransportable::GenHeaderConnectionBase() const {
+ return "";
+}
+
+std::string DefaultCTransportable::GenBodyPayloadBase() const {
+ return "";
+}
+
+std::string DefaultCTransportable::GenBodyConnectionBase() const {
+ return "";
+}
+
+std::string DefaultCTransportable::GenBodyPeerInfoBase() const {
+ return "";
+}
+
+std::string DefaultCTransportable::GenProxyPrefix() const {
+ return "cion_proxy";
+}
+
+std::string DefaultCTransportable::GenStubPrefix() const {
+ return "cion_stub";
+}
+
+std::string DefaultCTransportable::GenGroupPrefix() const {
+ return "cion_group";
+}
+
+std::string DefaultCTransportable::GenModulePrefix() const {
+ return "cion";
+}
+
+std::string DefaultCTransportable::GenErrorPrefix() const {
+ return "CION";
+}
+
+std::string DefaultCTransportable::GenServerExtra(bool body) const {
+ if (body)
+ return __SERVER_BODY_EXTRA;
+ else
+ return __SERVER_HEADER_EXTRA;
+}
+
+std::string DefaultCTransportable::GenClientExtra(bool body) const {
+ if (body)
+ return __CLIENT_BODY_EXTRA;
+ else
+ return __CLIENT_HEADER_EXTRA;
+}
+
+std::string DefaultCTransportable::GenGroupExtra(bool body) const {
+ if (body)
+ return __GROUP_BODY_EXTRA;
+ else
+ return __GROUP_HEADER_EXTRA;
+}
+
+std::string DefaultCTransportable::GenClientSendAsync(std::string client,
+ std::string payload, std::string size) const {
+ return std::string(ReplaceAll(__CLIENT_SEND_ASYNC, {
+ { "<CLIENT>", client },
+ { "<PAYLOAD>", payload},
+ { "<SIZE>", size} }));
+}
+
+std::string DefaultCTransportable::GenClientSend(std::string client,
+ std::string data, std::string data_size,
+ std::string ret_data, std::string ret_data_size) const {
+ return std::string(ReplaceAll(__CLIENT_SEND, {
+ { "<CLIENT>", client },
+ { "<DATA>", data},
+ { "<DATA_SIZE>", data_size},
+ { "<RET_DATA>", ret_data},
+ { "<RET_DATA_SIZE>", ret_data_size} }));
+}
+
+std::string DefaultCTransportable::GenServerSendAsync(std::string server,
+ std::string client,
+ std::string payload, std::string size) const {
+ return std::string(ReplaceAll(__SERVER_SEND_ASYNC, {
+ { "<SERVER>", server },
+ { "<CLIENT>", client},
+ { "<PAYLOAD>", payload},
+ { "<SIZE>", size} }));
+}
+
+std::string DefaultCTransportable::GenServerFileSend(std::string path,
+ std::string server, std::string peer) const {
+ return std::string(ReplaceAll(__SERVER_FILE_SEND, {
+ { "<FILE_PATH>", path },
+ { "<SERVER_H>", server },
+ { "<PEER_H>", peer } }));
+}
+
+std::string DefaultCTransportable::GenClientFileSend(std::string path,
+ std::string client) const {
+ return std::string(ReplaceAll(__CLINET_FILE_SEND, {
+ { "<FILE_PATH>", path },
+ { "<CLIENT_H>", client } }));
+}
+
+std::string DefaultCTransportable::GenGroupType() const {
+ return "cion_group_h";
+}
+
+std::string DefaultCTransportable::GenPayloadTransferStatusType(bool internal_type) const {
+ return "cion_payload_transfer_status_e";
+}
+
+std::string DefaultCTransportable::GenPeerInfoType() const {
+ return "cion_peer_info_h";
+}
+
+std::string DefaultCTransportable::GenPeerInfoDestroy(std::string peer) const {
+ return std::string(ReplaceAll("cion_peer_info_destroy(<PEER>);", {
+ { "<PEER>", peer } }));
+}
+
+std::string DefaultCTransportable::GenPayloadType(bool internal_type) const {
+ return "cion_payload_h";
+}
+
+std::string DefaultCTransportable::GenClientType() const {
+ return "cion_client_h";
+}
+
+std::string DefaultCTransportable::GenSecurityType(bool definition) const {
+ if (definition)
+ return "cion_security_h security;";
+ else
+ return "cion_security_h";
+}
+
+std::string DefaultCTransportable::GenServerType() const {
+ return "cion_server_h";
+}
+
+std::string DefaultCTransportable::GenClientTryConnect(std::string client,
+ std::string peer) const {
+ return std::string(ReplaceAll(__CLIENT_TRY_CONNECT, {
+ { "<CLIENT>", client },
+ { "<PEER>", peer } }));
+}
+
+std::string DefaultCTransportable::GenClientDisconnect(
+ std::string client) const {
+ return std::string(ReplaceAll(__CLIENT_DISCONNECT, {
+ { "<CLIENT>", client } }));
+}
+
+std::string DefaultCTransportable::GenClientTryDiscovery(
+ std::string client) const {
+ return std::string(ReplaceAll(__CLIENT_TRY_DISCOVERY, {
+ { "<CLIENT>", client } }));
+}
+
+std::string DefaultCTransportable::GenClientStopDiscovery(
+ std::string client) const {
+ return std::string(ReplaceAll(__CLIENT_STOP_DISCOVERY, {
+ { "<CLIENT>", client } }));
+}
+
+std::string DefaultCTransportable::GenServerRegister() const {
+ return __SERVER_REGISTER;
+}
+
+std::string DefaultCTransportable::GenServerUnregister() const {
+ return __SERVER_UNREGISTER;
+}
+
+std::string DefaultCTransportable::GenClientExtraHeader() const {
+ return "";
+}
+
+std::string DefaultCTransportable::GenClientExtraBody() const {
+ return "";
+}
+
+std::string DefaultCTransportable::GenServerExtraHeader() const {
+ return "";
+}
+
+std::string DefaultCTransportable::GenServerExtraBody() const {
+ return "";
+}
+
+std::string DefaultCTransportable::GenServerAccept() const {
+ return __SERVER_ACCEPT;
+}
+
+std::string DefaultCTransportable::GenServerReject() const {
+ return __SERVER_REJECT;
+}
+
+std::string DefaultCTransportable::GenServerSetDisplayName() const {
+ return __SERVER_SET_DISPLAY_NAME;
+}
+
+std::string DefaultCTransportable::GenGroupPublish() const {
+ return __GROUP_PUBLISH;
+}
+
+std::string DefaultCTransportable::GenPayloadTypeEnum() const {
+ return "cion_payload_type_e";
+}
+
+std::string DefaultCTransportable::GenPayloadTypeData() const {
+ return "CION_PAYLOAD_TYPE_DATA";
+}
+
+std::string DefaultCTransportable::GenPayloadTypeFile() const {
+ return "CION_PAYLOAD_TYPE_FILE";
+}
+
+std::string DefaultCTransportable::GenPayloadGetType() const {
+ return "ret = cion_payload_get_type(payload, &type);";
+}
+
+std::string DefaultCTransportable::GenErrorNone() const {
+ return "CION_ERROR_NONE";
+}
+
+std::string DefaultCTransportable::GenPayloadGetData() const {
+ return "ret = cion_payload_get_data(payload, &data, &data_len);";
+}
+
+std::string DefaultCTransportable::GenClientCreate() const {
+ return __CLIENT_CREATE;
+}
+
+std::string DefaultCTransportable::GenGroupCreate() const {
+ return __GROUP_CREATE;
+}
+
+std::string DefaultCTransportable::GenGroupDestroy() const {
+ return __GROUP_DESTROY;
+}
+
+std::string DefaultCTransportable::GenClientDestroy() const {
+ return __CLIENT_DESTROY;
+}
+
+std::string DefaultCTransportable::GenSetSecurityCA(std::string arg) const {
+ return std::string(ReplaceAll(__SET_SECURITY_CA, {
+ { "<ARG>", arg } }));
+}
+
+std::string DefaultCTransportable::GenSetSecurityCert(std::string arg) const {
+ return std::string(ReplaceAll(__SET_SECURITY_CERT, {
+ { "<ARG>", arg } }));
+}
+
+std::string DefaultCTransportable::GenSetSecurityPrivateKey(std::string arg) const {
+ return std::string(ReplaceAll(__SET_SECURITY_PRIVATE_KEY, {
+ { "<ARG>", arg } }));
+}
+
+std::string DefaultCTransportable::GenPeerInfoClone(std::string src_peer,
+ std::string dest_peer) const {
+ return std::string(ReplaceAll(__PEER_INFO_CLONE, {
+ { "<SRC_PEER>", src_peer },
+ { "<DEST_PEER>", dest_peer } }));
+}
+
+std::string DefaultCTransportable::GenServerForeachConnectedPeerInfo(
+ std::string name) const {
+ return std::string(ReplaceAll(__SERVER_FOREACH_CONNECTED_PEER_INFO, {
+ { "<NAME>", name } }));
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/default_c_transportable.h b/idlc/gen_cion/default_c_transportable.h
new file mode 100644
index 0000000..0fbc445
--- /dev/null
+++ b/idlc/gen_cion/default_c_transportable.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_DEFAULT_C_TRANSPORTABLE_H_
+#define IDLC_GEN_CION_DEFAULT_C_TRANSPORTABLE_H_
+
+#include <string>
+
+#include "idlc/gen_cion/c_transportable.h"
+
+namespace tidl {
+
+class DefaultCTransportable : public CTransportable {
+ public:
+ virtual ~DefaultCTransportable() = default;
+ std::string GenInclude(bool body = true, int type = 0) const override;
+ std::string GenHeaderBase() const override;
+ std::string GenHeaderPayloadHandle() const override;
+ std::string GenHeaderCommonHandle() const override;
+ std::string GenHeaderConnectionHandle() const override;
+ std::string GenHeaderPayloadBase() const override;
+ std::string GenHeaderConnectionBase() const override;
+ std::string GenBodyPayloadBase() const override;
+ std::string GenBodyConnectionBase() const override;
+ std::string GenBodyPeerInfoBase() const override;
+ std::string GenProxyPrefix() const override;
+ std::string GenStubPrefix() const override;
+ std::string GenGroupPrefix() const override;
+ std::string GenModulePrefix() const override;
+ std::string GenErrorPrefix() const override;
+ std::string GenServerExtra(bool body = true) const override;
+ std::string GenClientExtra(bool body = true) const override;
+ std::string GenGroupExtra(bool body = true) const override;
+ std::string GenClientSendAsync(std::string client,
+ std::string payload, std::string size) const override;
+ std::string GenClientSend(std::string client, std::string data,
+ std::string data_size, std::string ret_data,
+ std::string ret_data_size) const override;
+ std::string GenServerSendAsync(std::string server, std::string client,
+ std::string payload, std::string size) const override;
+ std::string GenServerFileSend(std::string path,
+ std::string server, std::string peer) const override;
+ std::string GenClientFileSend(std::string path,
+ std::string client) const override;
+ std::string GenGroupType() const override;
+ std::string GenPayloadTransferStatusType(bool internal_type) const override;
+ std::string GenPeerInfoType() const override;
+ std::string GenPeerInfoDestroy(std::string peer) const override;
+ std::string GenPayloadType(bool internal_type) const override;
+ std::string GenClientType() const override;
+ std::string GenSecurityType(bool definition = true) const override;
+ std::string GenServerType() const override;
+ std::string GenClientTryConnect(std::string client,
+ std::string peer) const override;
+ std::string GenClientDisconnect(std::string client) const override;
+ std::string GenClientTryDiscovery(std::string client) const override;
+ std::string GenClientStopDiscovery(std::string client) const override;
+ std::string GenServerRegister() const override;
+ std::string GenServerUnregister() const override;
+ std::string GenClientExtraHeader() const override;
+ std::string GenClientExtraBody() const override;
+ std::string GenServerExtraHeader() const override;
+ std::string GenServerExtraBody() const override;
+ std::string GenServerAccept() const override;
+ std::string GenServerReject() const override;
+ std::string GenServerSetDisplayName() const override;
+ std::string GenGroupPublish() const override;
+ std::string GenPayloadTypeEnum() const override;
+ std::string GenPayloadTypeData() const override;
+ std::string GenPayloadTypeFile() const override;
+ std::string GenPayloadGetType() const override;
+ std::string GenErrorNone() const override;
+ std::string GenPayloadGetData() const override;
+ std::string GenClientCreate() const override;
+ std::string GenGroupCreate() const override;
+ std::string GenGroupDestroy() const override;
+ std::string GenClientDestroy() const override;
+ std::string GenSetSecurityCA(std::string arg) const override;
+ std::string GenSetSecurityCert(std::string arg) const override;
+ std::string GenSetSecurityPrivateKey(std::string arg) const override;
+ std::string GenPeerInfoClone(std::string src_peer,
+ std::string dest_peer) const override;
+ std::string GenServerForeachConnectedPeerInfo(std::string name) const override;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CION_DEFAULT_C_TRANSPORTABLE_H_
diff --git a/idlc/gen_cion/default_cpp_transportable.cc b/idlc/gen_cion/default_cpp_transportable.cc
new file mode 100644
index 0000000..103c4f8
--- /dev/null
+++ b/idlc/gen_cion/default_cpp_transportable.cc
@@ -0,0 +1,846 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/default_cpp_transportable.h"
+
+#include <utility>
+
+#include "idlc/gen/replace_all.h"
+
+namespace {
+
+constexpr const char __CLINET_FILE_SEND[] =
+R"__cpp_cb(<PAYLOAD_T> pl;
+ int ret = cion_payload_create(&pl, CION_PAYLOAD_TYPE_FILE);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_create : %d", ret);
+ return;
+ }
+
+ ret = cion_payload_set_file_path(pl, <FILE_PATH>.c_str());
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_set_file_path : %d - %s", ret, <FILE_PATH>.c_str());
+ cion_payload_destroy(pl);
+ return;
+ }
+
+ ret = cion_client_send_payload_async(<CLIENT_H>, pl, nullptr, nullptr);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_client_send_payload_async : %d", ret);
+ cion_payload_destroy(pl);
+ return;
+ }
+
+ cion_payload_destroy(pl);
+)__cpp_cb";
+
+constexpr const char __SERVER_FILE_SEND[] =
+R"__cpp_cb(<PAYLOAD_T> pl;
+ int ret = cion_payload_create(&pl, CION_PAYLOAD_TYPE_FILE);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_create : %d", ret);
+ return;
+ }
+
+ ret = cion_payload_set_file_path(pl, <FILE_PATH>.c_str());
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_set_file_path : %d - %s", ret, <FILE_PATH>.c_str());
+ cion_payload_destroy(pl);
+ return;
+ }
+
+ ret = cion_server_send_payload_async(<SERVER_H>, <PEER_H>, pl, nullptr, nullptr);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_server_send_payload_async : %d", ret);
+ cion_payload_destroy(pl);
+ return;
+ }
+
+ cion_payload_destroy(pl);
+)__cpp_cb";
+
+constexpr const char __SERVER_REGISTER[] =
+R"__cpp_cb(<SECURITY_T> security;
+ int ret = cion_security_create(&security);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to create security handle. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ auto security_auto = std::unique_ptr<
+ std::remove_pointer<<SECURITY_T>>::type, decltype(cion_security_destroy)*>(
+ security, cion_security_destroy);
+<SET_SECURITY>
+ <SERVER_T> server;
+ ret = cion_server_create(&server, service_name.c_str(),
+ display_name.c_str(), security);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ throw InvalidIOException();
+ }
+ auto server_auto = std::unique_ptr<
+ std::remove_pointer<<SERVER_T>>::type, decltype(cion_server_destroy)*>(
+ server, cion_server_destroy);
+
+ ret = cion_server_add_connection_result_cb(server, OnConnectionResultCB,
+ this);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_server_add_connection_result_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = cion_server_add_payload_received_cb(server, OnPayloadReceivedCB,
+ this);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_server_add_payload_received_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = cion_server_set_data_received_cb(server, OnDataReceivedCB, this);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_server_set_data_received_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = cion_server_add_disconnected_cb(server, OnDisconnectedCB, this);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_server_add_disconnected_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ cion_security_ = security_auto.release();
+ server_ = server_auto.release();
+)__cpp_cb";
+
+
+
+constexpr const char __SERVER_UNREGISTER[] =
+R"__cpp_cb(
+ if (server_ != nullptr)
+ cion_server_destroy(server_);
+
+ if (cion_security_ != nullptr)
+ cion_security_destroy(cion_security_);
+)__cpp_cb";
+
+constexpr const char __SERVER_ACCEPT[] =
+R"__cpp_cb(auto p = service->GetPeer();
+ int ret = cion_server_accept(server_, p);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_server_accept. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ service->OnCreate();
+ services_.emplace_back(std::move(service));
+)__cpp_cb";
+
+constexpr const char __SERVER_REJECT[] =
+R"__cpp_cb(auto p = service->GetPeer();
+ int ret = cion_server_reject(server_, p, reason.c_str());
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_server_reject. error(%d)", ret);
+ throw InvalidIOException();
+ }
+)__cpp_cb";
+
+constexpr const char __SERVER_SET_DISPLAY_NAME[] =
+R"__cpp_cb(int ret = cion_server_set_display_name(server_, display_name.c_str());
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_server_set_display_name. error(%d)", ret);
+ InvalidIOException();
+ }
+)__cpp_cb";
+
+constexpr const char __CLIENT_TRY_CONNECT[] =
+R"__cpp_cb(int ret = cion_client_connect(<CLIENT>, <PEER>);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to connect to stub. error(%d)", ret);
+ switch(ret) {
+ case CION_ERROR_PERMISSION_DENIED :
+ throw UnauthorizedAccessException();
+ break;
+ case CION_ERROR_INVALID_PARAMETER :
+ throw NotConnectedSocketException();
+ break;
+ default :
+ throw InvalidIOException();
+ }
+ }
+)__cpp_cb";
+
+constexpr const char __CLIENT_DISCONNECT[] =
+R"__cpp_cb(int ret = cion_client_disconnect(<CLIENT>);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to disconnect to stub. error(%d)", ret);
+ throw NotConnectedSocketException();
+ }
+)__cpp_cb";
+
+constexpr const char __CLIENT_TRY_DISCOVERY[] =
+R"__cpp_cb(int ret = cion_client_try_discovery(<CLIENT>, OnDiscoveredCB, this);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to discovery to stub. error(%d)", ret);
+ switch(ret) {
+ case CION_ERROR_PERMISSION_DENIED :
+ throw UnauthorizedAccessException();
+ break;
+ default :
+ throw InvalidIOException();
+ }
+ }
+)__cpp_cb";
+
+constexpr const char __CLIENT_STOP_DISCOVERY[] =
+R"__cpp_cb(int ret = cion_client_stop_discovery(<CLIENT>);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to stop discovery. error(%d)", ret);
+ return;
+ }
+)__cpp_cb";
+
+constexpr const char __CLIENT_SEND_ASYNC[] =
+R"__cpp_cb(
+ ret = cion_payload_create(&<PAYLOAD>, CION_PAYLOAD_TYPE_DATA);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_create : %d", ret);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
+
+ ret = cion_payload_set_data(<PAYLOAD>, (const unsigned char*)data, <SIZE>);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_set_data : %d", ret);
+ rpc_port_parcel_destroy(p);
+ cion_payload_destroy(<PAYLOAD>);
+ throw InvalidIOException();
+ }
+
+ ret = cion_client_send_payload_async(<CLIENT>, <PAYLOAD>, nullptr, nullptr);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_client_send_payload_async : %d", ret);
+ rpc_port_parcel_destroy(p);
+ cion_payload_destroy(<PAYLOAD>);
+ throw InvalidIOException();
+ }
+
+ cion_payload_destroy(<PAYLOAD>);
+)__cpp_cb";
+
+constexpr const char __CLIENT_SEND[] =
+R"__cpp_cb(
+ ret = cion_client_send_data(<CLIENT>, (unsigned char *)<DATA>, <DATA_SIZE>,
+ 100, &<RET_DATA>, &<RET_DATA_SIZE>);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to cion_client_send_data : error(%d)", ret);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
+)__cpp_cb";
+
+constexpr const char __SERVER_SEND_ASYNC[] =
+R"__cpp_cb(ret_ = cion_payload_create(&<PAYLOAD>, CION_PAYLOAD_TYPE_DATA);
+ if (ret_ != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_create : %d", ret_);
+ rpc_port_parcel_destroy(p);
+ return;
+ }
+
+ ret_ = cion_payload_set_data(<PAYLOAD>, (const unsigned char*)data, <SIZE>);
+ if (ret_ != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_set_data : %d", ret_);
+ rpc_port_parcel_destroy(p);
+ cion_payload_destroy(<PAYLOAD>);
+ return;
+ }
+
+ ret_ = cion_server_send_payload_async(<SERVER>, service_.lock()->GetPeer(), <PAYLOAD>, nullptr, nullptr);
+ cion_payload_destroy(<PAYLOAD>);
+ if (ret_ != CION_ERROR_NONE) {
+ _E("Failed to cion_client_send_payload_async : %d", ret_);
+ rpc_port_parcel_destroy(p);
+ return;
+ }
+)__cpp_cb";
+
+constexpr const char __GROUP_PUBLISH[] =
+R"__c_cb(ret = cion_payload_create(&pl, CION_PAYLOAD_TYPE_DATA);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_create : %d", ret);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
+
+ ret = cion_payload_set_data(pl, (const unsigned char*)data, size);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_payload_set_data : %d", ret);
+ rpc_port_parcel_destroy(p);
+ cion_payload_destroy(pl);
+ throw InvalidIOException();
+ }
+
+ ret = cion_group_publish(group_, pl);
+ cion_payload_destroy(pl);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_group_publish : %d", ret);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_CREATE[] =
+R"__c_cb(<SECURITY_T> security;
+ int ret = cion_security_create(&security);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to create security handle. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ auto security_auto = std::unique_ptr<
+ std::remove_pointer<<SECURITY_T>>::type, decltype(cion_security_destroy)*>(
+ security, cion_security_destroy);
+<SET_SECURITY>
+ <CLIENT_T> client = nullptr;
+ ret = cion_client_create(&client, service_name.c_str(), security);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ throw InvalidIOException();
+ }
+ auto client_auto = std::unique_ptr<
+ std::remove_pointer<<CLIENT_T>>::type, decltype(cion_client_destroy)*>(
+ client, cion_client_destroy);
+
+ ret = cion_client_add_disconnected_cb(client, OnDisconnectedCB,
+ this);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_client_add_disconnected_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+
+ ret = cion_client_add_connection_result_cb(client, OnConnectionResultCB,
+ this);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_client_add_connection_result_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = cion_client_add_payload_received_cb(client, OnPayloadReceivedCB,
+ this);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_client_add_payload_received_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ cion_security_ = security_auto.release();
+ client_ = client_auto.release();
+)__c_cb";
+
+constexpr const char __GROUP_CREATE[] =
+R"__c_cb(<SECURITY_T> security;
+ int ret = cion_security_create(&security);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to create security handle. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ auto security_auto = std::unique_ptr<
+ std::remove_pointer<<SECURITY_T>>::type, decltype(cion_security_destroy)*>(
+ security, cion_security_destroy);
+<SET_SECURITY>
+ <GROUP_T> group = nullptr;
+ ret = cion_group_create(&group, topic_name_.c_str(), security);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ throw InvalidIOException();
+ }
+ auto group_auto = std::unique_ptr<
+ std::remove_pointer<<GROUP_T>>::type, decltype(cion_group_destroy)*>(
+ group, cion_group_destroy);
+
+ ret = cion_group_add_joined_cb(group,
+ [](const char *topic_name, const <PEER_INFO_T> peer_info,
+ void *user_data) {
+ <CLS_NAME> *gr = static_cast<<CLS_NAME>*>(user_data);
+ gr->OnJoined(peer_info);
+ },
+ this);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_group_add_joined_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = cion_group_add_left_cb(group,
+ [](const char *topic_name, const <PEER_INFO_T> peer_info,
+ void *user_data) {
+ <CLS_NAME> *gr = static_cast<<CLS_NAME>*>(user_data);
+ gr->OnLeft(peer_info);
+ },
+ this);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_group_add_left_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = cion_group_add_payload_received_cb(group,
+ [](const char *topic_name, const <PEER_INFO_T> peer_info,
+ const <PAYLOAD_T> payload, void *user_data) {
+ <CLS_NAME> *gr = static_cast<<CLS_NAME>*>(user_data);
+ gr->OnPayloadReceivedCB(peer_info, payload);
+ },
+ this);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_group_add_payload_received_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = cion_group_subscribe(group);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to subscribe. error(%d)", ret);
+ switch (ret) {
+ case CION_ERROR_PERMISSION_DENIED :
+ throw UnauthorizedAccessException();
+ break;
+ case CION_ERROR_INVALID_PARAMETER :
+ throw NotConnectedSocketException();
+ break;
+ default :
+ throw InvalidIOException();
+ }
+ }
+
+ cion_security_ = security_auto.release();
+ group_ = group_auto.release();
+)__c_cb";
+
+constexpr const char __GROUP_DESTROY[] =
+R"__c_cb(if (group_ != nullptr) {
+ int ret = cion_group_unsubscribe(group_);
+ if (ret != CION_ERROR_NONE)
+ _E("Failed to unsubscribe. error(%d)", ret);
+
+ cion_group_destroy(group_);
+ }
+
+ if (cion_security_ != nullptr)
+ cion_security_destroy(cion_security_);
+)__c_cb";
+
+constexpr const char __CLIENT_DESTROY[] =
+R"__c_cb(
+ if (client_ != nullptr)
+ cion_client_destroy(client_);
+
+ if (cion_security_ != nullptr)
+ cion_security_destroy(cion_security_);
+)__c_cb";
+
+const char __SET_SECURITY_CA[] =
+R"__cpp_cb(
+ if (cion_security_set_ca_path(security, "<ARG>") != CION_ERROR_NONE) {
+ _E("Failed to set ca path.");
+ throw InvalidIOException();
+ }
+)__cpp_cb";
+
+const char __SET_SECURITY_CERT[] =
+R"__cpp_cb(
+ if (cion_security_set_cert_path(security, "<ARG>") != CION_ERROR_NONE) {
+ _E("Failed to set cert path.");
+ throw InvalidIOException();
+ }
+)__cpp_cb";
+
+const char __SET_SECURITY_PRIVATE_KEY[] =
+R"__cpp_cb(
+ if (cion_security_set_private_key_path(security, "<ARG>") != CION_ERROR_NONE) {
+ _E("Failed to set private key path.");
+ throw InvalidIOException();
+ }
+)__cpp_cb";
+
+const char __PEER_INFO_CLONE[] =
+ "cion_peer_info_clone(<SRC_PEER>, <DEST_PEER>);";
+
+constexpr const char __SERVER_SET_ONDEMAND_LAUNCH_ENABLED[] =
+R"__c_cb(int ret = cion_server_set_on_demand_launch_enabled(server_, enabled);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_server_set_on_demand_launch_enabled. error(%d)", ret);
+ switch(ret) {
+ case CION_ERROR_PERMISSION_DENIED :
+ throw UnauthorizedAccessException();
+ break;
+ default :
+ throw InvalidIOException();
+ }
+ }
+)__c_cb";
+
+constexpr const char __SERVER_LISTEN[] =
+R"__c_cb(int ret = cion_server_listen(server_, OnConnectionRequestCB, this);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_server_listen. error(%d)", ret);
+ switch(ret) {
+ case CION_ERROR_PERMISSION_DENIED :
+ throw UnauthorizedAccessException();
+ break;
+ default :
+ throw InvalidIOException();
+ }
+ }
+)__c_cb";
+
+constexpr const char __SERVER_DISCONNECT[] =
+R"__c_cb(int ret = cion_server_disconnect(<SERVER>, <PEER>);
+ if (ret != CION_ERROR_NONE) {
+ _E("Failed to cion_server_disconnect. error(%d)", ret);
+ throw InvalidIOException();
+ }
+)__c_cb";
+
+constexpr const char __PEER_INFO_GET_APPID[] =
+ "cion_peer_info_get_app_id(<PEER>, <APPID>);";
+
+constexpr const char __PEER_INFO_GET_UUID[] =
+ "cion_peer_info_get_uuid(<PEER>, <UUID>);";
+
+} // namespace
+
+namespace tidl {
+
+std::string DefaultCppTransportable::GenInclude(int type) const {
+ return "#include <cion.h>";
+}
+
+std::string DefaultCppTransportable::GenClientSendAsync(std::string client,
+ std::string payload, std::string size) const {
+ return std::string(ReplaceAll(__CLIENT_SEND_ASYNC, {
+ { "<CLIENT>", client },
+ { "<PAYLOAD>", payload},
+ { "<SIZE>", size} }));
+}
+
+std::string DefaultCppTransportable::GenClientSend(std::string client,
+ std::string data, std::string data_size,
+ std::string ret_data, std::string ret_data_size) const {
+ return std::string(ReplaceAll(__CLIENT_SEND, {
+ { "<CLIENT>", client },
+ { "<DATA>", data},
+ { "<DATA_SIZE>", data_size},
+ { "<RET_DATA>", ret_data},
+ { "<RET_DATA_SIZE>", ret_data_size} }));
+}
+
+std::string DefaultCppTransportable::GenServerSendAsync(std::string server,
+ std::string client,
+ std::string payload, std::string size) const {
+ return std::string(ReplaceAll(__SERVER_SEND_ASYNC, {
+ { "<SERVER>", server },
+ { "<CLIENT>", client},
+ { "<PAYLOAD>", payload},
+ { "<SIZE>", size} }));
+}
+
+std::string DefaultCppTransportable::GenServerFileSend(std::string path,
+ std::string server, std::string peer) const {
+ return std::string(ReplaceAll(__SERVER_FILE_SEND, {
+ { "<FILE_PATH>", path },
+ { "<SERVER_H>", server },
+ { "<PEER_H>", peer } }));
+}
+
+std::string DefaultCppTransportable::GenClientFileSend(std::string path,
+ std::string client) const {
+ return std::string(ReplaceAll(__CLINET_FILE_SEND, {
+ { "<FILE_PATH>", path },
+ { "<CLIENT_H>", client } }));
+}
+
+std::string DefaultCppTransportable::GenGroupType() const {
+ return "cion_group_h";
+}
+
+std::string DefaultCppTransportable::GenPayloadTransferStatusType(bool internal_type) const {
+ return "cion_payload_transfer_status_e";
+}
+
+std::string DefaultCppTransportable::GenPayloadAsyncResultType() const {
+ return "cion_payload_async_result_h";
+}
+
+std::string DefaultCppTransportable::GenPeerInfoType() const {
+ return "cion_peer_info_h";
+}
+
+std::string DefaultCppTransportable::GenPeerInfoDestroy(
+ std::string peer) const {
+ return std::string(ReplaceAll("cion_peer_info_destroy(<PEER>);", {
+ { "<PEER>", peer } }));
+}
+
+std::string DefaultCppTransportable::GenHeaderBase() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenHeaderPayloadHandle() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenHeaderCommonHandle() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenHeaderClientHandle() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenHeaderServerHandle() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenHeaderGroupHandle() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenHeaderConnectionHandle() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenHeaderPayloadBase() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenHeaderConnectionBase() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenBodyPayloadBase() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenBodyConnectionBase() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenBodyPeerInfoBase() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenPayloadType() const {
+ return "cion_payload_h";
+}
+
+std::string DefaultCppTransportable::GenClientType() const {
+ return "cion_client_h";
+}
+
+std::string DefaultCppTransportable::GenSecurityType(bool definition) const {
+ if (definition)
+ return "cion_security_h cion_security_ = nullptr;";
+ else
+ return "cion_security_h";
+}
+
+std::string DefaultCppTransportable::GenServerType() const {
+ return "cion_server_h";
+}
+
+std::string DefaultCppTransportable::GenProxyPrefix() const {
+ return "cion_proxy";
+}
+
+std::string DefaultCppTransportable::GenStubPrefix() const {
+ return "cion_stub";
+}
+
+std::string DefaultCppTransportable::GenGroupPrefix() const {
+ return "cion_group";
+}
+
+std::string DefaultCppTransportable::GenModulePrefix() const {
+ return "cion";
+}
+
+std::string DefaultCppTransportable::GenErrorPrefix() const {
+ return "CION";
+}
+
+std::string DefaultCppTransportable::GenConnectionResultPrefix() const {
+ return "CION_";
+}
+
+std::string DefaultCppTransportable::GenNamespace() const {
+ return "cion";
+}
+
+std::string DefaultCppTransportable::GenClientTryConnect(std::string client,
+ std::string peer) const {
+ return std::string(ReplaceAll(__CLIENT_TRY_CONNECT, {
+ { "<CLIENT>", client },
+ { "<PEER>", peer } }));
+}
+
+std::string DefaultCppTransportable::GenClientDisconnect(
+ std::string client) const {
+ return std::string(ReplaceAll(__CLIENT_DISCONNECT, {
+ { "<CLIENT>", client } }));
+}
+
+std::string DefaultCppTransportable::GenClientTryDiscovery(
+ std::string client) const {
+ return std::string(ReplaceAll(__CLIENT_TRY_DISCOVERY, {
+ { "<CLIENT>", client } }));
+}
+
+std::string DefaultCppTransportable::GenClientStopDiscovery(
+ std::string client) const {
+ return std::string(ReplaceAll(__CLIENT_STOP_DISCOVERY, {
+ { "<CLIENT>", client } }));
+}
+
+std::string DefaultCppTransportable::GenServerRegister() const {
+ return __SERVER_REGISTER;
+}
+
+std::string DefaultCppTransportable::GenServerUnregister() const {
+ return __SERVER_UNREGISTER;
+}
+
+std::string DefaultCppTransportable::GenClientExtraHeader() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenClientExtraBody() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenServerExtraHeader() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenServerExtraBody() const {
+ return "";
+}
+
+std::string DefaultCppTransportable::GenServerAccept() const {
+ return __SERVER_ACCEPT;
+}
+
+std::string DefaultCppTransportable::GenServerReject() const {
+ return __SERVER_REJECT;
+}
+
+std::string DefaultCppTransportable::GenServerSetDisplayName() const {
+ return __SERVER_SET_DISPLAY_NAME;
+}
+
+std::string DefaultCppTransportable::GenGroupPublish() const {
+ return __GROUP_PUBLISH;
+}
+
+std::string DefaultCppTransportable::GenPayloadTypeEnum() const {
+ return "cion_payload_type_e";
+}
+
+std::string DefaultCppTransportable::GenPayloadTypeData() const {
+ return "CION_PAYLOAD_TYPE_DATA";
+}
+
+std::string DefaultCppTransportable::GenPayloadTypeFile() const {
+ return "CION_PAYLOAD_TYPE_FILE";
+}
+
+std::string DefaultCppTransportable::GenPayloadGetType() const {
+ return "ret = cion_payload_get_type(payload, &type);";
+}
+
+std::string DefaultCppTransportable::GenErrorNone() const {
+ return "CION_ERROR_NONE";
+}
+
+std::string DefaultCppTransportable::GenPayloadGetData() const {
+ return "ret = cion_payload_get_data(payload, &data, &size);";
+}
+
+std::string DefaultCppTransportable::GenClientCreate() const {
+ return __CLIENT_CREATE;
+}
+
+std::string DefaultCppTransportable::GenGroupCreate() const {
+ return __GROUP_CREATE;
+}
+
+std::string DefaultCppTransportable::GenGroupDestroy() const {
+ return __GROUP_DESTROY;
+}
+
+std::string DefaultCppTransportable::GenClientDestroy() const {
+ return __CLIENT_DESTROY;
+}
+
+std::string DefaultCppTransportable::GenSetSecurityCA(std::string arg) const {
+ return std::string(ReplaceAll(__SET_SECURITY_CA, {
+ { "<ARG>", arg } }));
+}
+
+std::string DefaultCppTransportable::GenSetSecurityCert(std::string arg) const {
+ return std::string(ReplaceAll(__SET_SECURITY_CERT, {
+ { "<ARG>", arg } }));
+}
+
+std::string DefaultCppTransportable::GenSetSecurityPrivateKey(
+ std::string arg) const {
+ return std::string(ReplaceAll(__SET_SECURITY_PRIVATE_KEY, {
+ { "<ARG>", arg } }));
+}
+
+std::string DefaultCppTransportable::GenPeerInfoClone(std::string src_peer,
+ std::string dest_peer) const {
+ return std::string(ReplaceAll(__PEER_INFO_CLONE, {
+ { "<SRC_PEER>", src_peer },
+ { "<DEST_PEER>", dest_peer } }));
+}
+
+std::string DefaultCppTransportable::GenServerSetOnDemandLaunchEnabled() const {
+ return __SERVER_SET_ONDEMAND_LAUNCH_ENABLED;
+}
+
+std::string DefaultCppTransportable::GenServerListen() const {
+ return __SERVER_LISTEN;
+}
+
+std::string DefaultCppTransportable::GenServerDisconnect(std::string server,
+ std::string peer) const {
+ return std::string(ReplaceAll(__SERVER_DISCONNECT, {
+ { "<SERVER>", server },
+ { "<PEER>", peer } }));
+}
+
+std::string DefaultCppTransportable::GenPeerInfoGetAppID(std::string peer,
+ std::string appid) const {
+ return std::string(ReplaceAll(__PEER_INFO_GET_APPID, {
+ { "<PEER>", peer},
+ { "<APPID>", appid} }));
+}
+
+std::string DefaultCppTransportable::GenPeerInfoGetUUID(std::string peer,
+ std::string uuid) const {
+ return std::string(ReplaceAll(__PEER_INFO_GET_UUID, {
+ { "<PEER>", peer},
+ { "<UUID>", uuid} }));
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/default_cpp_transportable.h b/idlc/gen_cion/default_cpp_transportable.h
new file mode 100644
index 0000000..dae42f4
--- /dev/null
+++ b/idlc/gen_cion/default_cpp_transportable.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_DEFAULT_CPP_TRANSPORTABLE_H_
+#define IDLC_GEN_CION_DEFAULT_CPP_TRANSPORTABLE_H_
+
+#include <string>
+
+#include "idlc/gen_cion/cpp_transportable.h"
+
+namespace tidl {
+
+class DefaultCppTransportable : public CppTransportable {
+ public:
+ virtual ~DefaultCppTransportable() = default;
+ std::string GenInclude(int type = 0) const override;
+ std::string GenClientSendAsync(std::string client,
+ std::string payload, std::string size) const override;
+ std::string GenClientSend(std::string client, std::string data,
+ std::string data_size, std::string ret_data,
+ std::string ret_data_size) const override;
+ std::string GenServerSendAsync(std::string server, std::string client,
+ std::string payload, std::string size) const override;
+ std::string GenServerFileSend(std::string path,
+ std::string server, std::string peer) const override;
+ std::string GenClientFileSend(std::string path,
+ std::string client) const override;
+ std::string GenGroupType() const override;
+ std::string GenPayloadTransferStatusType(bool internal_type = false) const override;
+ std::string GenPayloadAsyncResultType() const override;
+ std::string GenPeerInfoType() const override;
+ std::string GenPeerInfoDestroy(std::string peer) const override;
+ std::string GenPayloadType() const override;
+ std::string GenClientType() const override;
+ std::string GenSecurityType(bool definition = true) const override;
+ std::string GenServerType() const override;
+ std::string GenClientTryConnect(std::string client,
+ std::string peer) const override;
+ std::string GenClientDisconnect(std::string client) const override;
+ std::string GenClientTryDiscovery(std::string client) const override;
+ std::string GenClientStopDiscovery(std::string client) const override;
+ std::string GenServerRegister() const override;
+ std::string GenServerUnregister() const override;
+ std::string GenClientExtraHeader() const override;
+ std::string GenClientExtraBody() const override;
+ std::string GenServerExtraHeader() const override;
+ std::string GenServerExtraBody() const override;
+ std::string GenServerAccept() const override;
+ std::string GenServerReject() const override;
+ std::string GenServerSetDisplayName() const override;
+ std::string GenGroupPublish() const override;
+ std::string GenPayloadTypeEnum() const override;
+ std::string GenPayloadTypeData() const override;
+ std::string GenPayloadTypeFile() const override;
+ std::string GenPayloadGetType() const override;
+ std::string GenErrorNone() const override;
+ std::string GenPayloadGetData() const override;
+ std::string GenClientCreate() const override;
+ std::string GenGroupCreate() const override;
+ std::string GenGroupDestroy() const override;
+ std::string GenClientDestroy() const override;
+ std::string GenSetSecurityCA(std::string arg) const override;
+ std::string GenSetSecurityCert(std::string arg) const override;
+ std::string GenSetSecurityPrivateKey(std::string arg) const override;
+ std::string GenPeerInfoClone(std::string src_peer,
+ std::string dest_peer) const override;
+ std::string GenServerSetOnDemandLaunchEnabled() const override;
+ std::string GenServerListen() const override;
+ std::string GenServerDisconnect(std::string server,
+ std::string peer) const override;
+ std::string GenPeerInfoGetAppID(std::string peer,
+ std::string appid) const override;
+ std::string GenPeerInfoGetUUID(std::string peer,
+ std::string uuid) const override;
+ std::string GenHeaderBase() const override;
+ std::string GenHeaderPayloadHandle() const override;
+ std::string GenHeaderCommonHandle() const override;
+ std::string GenHeaderClientHandle() const override;
+ std::string GenHeaderServerHandle() const override;
+ std::string GenHeaderGroupHandle() const override;
+ std::string GenHeaderConnectionHandle() const override;
+ std::string GenHeaderPayloadBase() const override;
+ std::string GenHeaderConnectionBase() const override;
+ std::string GenBodyPayloadBase() const override;
+ std::string GenBodyConnectionBase() const override;
+ std::string GenBodyPeerInfoBase() const override;
+ std::string GenProxyPrefix() const override;
+ std::string GenStubPrefix() const override;
+ std::string GenGroupPrefix() const override;
+ std::string GenModulePrefix() const override;
+ std::string GenErrorPrefix() const override;
+ std::string GenConnectionResultPrefix() const override;
+ std::string GenNamespace() const override;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CION_DEFAULT_CPP_TRANSPORTABLE_H_
diff --git a/idlc/gen_cion/default_cs_transportable.cc b/idlc/gen_cion/default_cs_transportable.cc
new file mode 100644
index 0000000..d73e24b
--- /dev/null
+++ b/idlc/gen_cion/default_cs_transportable.cc
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/default_cs_transportable.h"
+
+#include <utility>
+
+#include "idlc/gen/replace_all.h"
+
+namespace {
+
+constexpr const char __USING[] =
+R"__cs_cb(
+using System;
+using System.Collections.Generic;
+using Tizen.Applications;
+using Tizen.Applications.Cion;
+)__cs_cb";
+
+constexpr const char __FILE_SEND[] =
+R"__cs_cb(if (path == null)
+ throw new ArgumentException("Invalid path");
+
+ Payload fp = new FilePayload(<FILE_PATH>);
+ base.SendPayloadAsync(fp);
+)__cs_cb";
+
+constexpr const char __CLIENT_CTOR[] =
+R"__cs_cb(
+ public ##(string serviceName) : base(serviceName<SECURITY>)
+ {
+ ServiceName = serviceName;
+ }
+)__cs_cb";
+
+constexpr const char __GROUP_CTOR[] =
+R"__cs_cb(
+ public ##(string topicName) : base(topicName<SECURITY>)
+ {
+ TopicName = topicName;
+ try
+ {
+ base.Subscribe();
+ }
+ catch
+ {
+ throw;
+ }
+ }
+)__cs_cb";
+
+constexpr const char __SERVER_CTOR[] =
+R"__cs_cb(
+ public ##(string serviceName, string displayName) : base(serviceName, displayName<SECURITY>)
+ {
+ }
+)__cs_cb";
+
+constexpr const char __SERVER_EXTRA_METHOD[] =
+R"__cs_cb(
+ /// <summary>
+ /// Sets ondemand launch enabled flag.
+ /// </summary>
+ /// <param name="enable">Whether ondemand launch is enabled or not.</param>
+ /// <exception cref="UnauthorizedAccessException">
+ /// Thrown when an application does not have the privilege to access this method.
+ /// </exception>
+ /// <privilege>http://tizen.org/privilege/d2d.remotelaunch</privilege>
+ public new void SetOndemandLaunchEnabled(bool enable)
+ {
+ base.SetOndemandLaunchEnabled(enable);
+ }
+)__cs_cb";
+
+constexpr int TAB_SIZE = 2;
+
+} // namespace
+
+namespace tidl {
+
+std::string DefaultCsTransportable::GenInclude() const {
+ return __USING;
+}
+
+std::string DefaultCsTransportable::GenFileSend(std::string path) const {
+ return std::string(ReplaceAll(__FILE_SEND, {
+ { "<FILE_PATH>", path } }));
+}
+
+std::string DefaultCsTransportable::GenGroupType() const {
+ return "GroupBase";
+}
+
+std::string DefaultCsTransportable::GenPayloadTransferStatusType() const {
+ return "PayloadTransferStatus";
+}
+
+std::string DefaultCsTransportable::GenPeerInfoType() const {
+ return "PeerInfo";
+}
+
+std::string DefaultCsTransportable::GenPayloadType() const {
+ return "Payload";
+}
+
+std::string DefaultCsTransportable::GenClientType() const {
+ return "ClientBase";
+}
+
+std::string DefaultCsTransportable::GenServerType() const {
+ return "ServerBase";
+}
+
+std::string DefaultCsTransportable::GenClientExtraHeader() const {
+ return "";
+}
+
+std::string DefaultCsTransportable::GenClientExtraBody() const {
+ return "";
+}
+
+std::string DefaultCsTransportable::GenServerExtraHeader() const {
+ return "";
+}
+
+std::string DefaultCsTransportable::GenServerExtraBody() const {
+ return __SERVER_EXTRA_METHOD;
+}
+
+std::string DefaultCsTransportable::GenPayloadTypeData() const {
+ return "PayloadType.DataPayload";
+}
+
+std::string DefaultCsTransportable::GenPayloadTypeFile() const {
+ return "PayloadType.FilePayload";
+}
+
+std::string DefaultCsTransportable::GenClientBaseCtor(
+ const Interface& iface) const {
+ return GenCtor(iface, CtorType::Client);
+}
+
+std::string DefaultCsTransportable::GenGroupBaseCtor(
+ const Interface& iface) const {
+ return GenCtor(iface, CtorType::Group);
+}
+
+std::string DefaultCsTransportable::GenServerBaseCtor(
+ const Interface& iface) const {
+ return GenCtor(iface, CtorType::Server);
+}
+
+std::string DefaultCsTransportable::GenCtor(
+ const Interface& iface, CtorType type) const {
+ bool security_check = false;
+ std::string security = ", new Security {";
+ for (const auto& attr : iface.GetAttributes()) {
+ if (attr->GetKey() == "ca_path") {
+ security += "CaPath = \"" + attr->GetValue() + "\", ";
+ security_check = true;
+ } else if (attr->GetKey() == "cert_path") {
+ security += "CertPath = \"" + attr->GetValue() + "\", ";
+ security_check = true;
+ } else if (attr->GetKey() == "private_key") {
+ security += "PrivateKeyPath = \"" + attr->GetValue() + "\", ";
+ security_check = true;
+ }
+ }
+ security += "}";
+
+ std::string base;
+ switch (type) {
+ case CtorType::Client:
+ base = __CLIENT_CTOR;
+ break;
+ case CtorType::Group:
+ base = __GROUP_CTOR;
+ break;
+ case CtorType::Server:
+ base = __SERVER_CTOR;
+ break;
+ }
+
+ std::string ctor(ReplaceAll(base, {
+ { "<SECURITY>", security_check ? security : "" },
+ { "##", iface.GetID() },
+ }));
+
+ return ctor;
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/default_cs_transportable.h b/idlc/gen_cion/default_cs_transportable.h
new file mode 100644
index 0000000..d366d1a
--- /dev/null
+++ b/idlc/gen_cion/default_cs_transportable.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_DEFAULT_CS_TRANSPORTABLE_H_
+#define IDLC_GEN_CION_DEFAULT_CS_TRANSPORTABLE_H_
+
+#include <string>
+
+#include "idlc/ast/interface.h"
+#include "idlc/gen_cion/cs_transportable.h"
+
+namespace tidl {
+
+class DefaultCsTransportable : public CsTransportable {
+ public:
+ virtual ~DefaultCsTransportable() = default;
+ std::string GenInclude() const override;
+ std::string GenFileSend(std::string path) const override;
+ std::string GenGroupType() const override;
+ std::string GenPayloadTransferStatusType() const override;
+ std::string GenPeerInfoType() const override;
+ std::string GenPayloadType() const override;
+ std::string GenClientType() const override;
+ std::string GenServerType() const override;
+ std::string GenClientExtraHeader() const override;
+ std::string GenClientExtraBody() const override;
+ std::string GenServerExtraHeader() const override;
+ std::string GenServerExtraBody() const override;
+ std::string GenPayloadTypeData() const override;
+ std::string GenPayloadTypeFile() const override;
+ std::string GenClientBaseCtor(const Interface& iface) const override;
+ std::string GenGroupBaseCtor(const Interface& iface) const override;
+ std::string GenServerBaseCtor(const Interface& iface) const override;
+
+ private:
+ enum class CtorType {
+ Client = 0,
+ Group = 1,
+ Server = 2,
+ };
+ std::string GenCtor(const Interface& iface, CtorType type) const;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CION_DEFAULT_CS_TRANSPORTABLE_H_
diff --git a/idlc/gen_cion/default_dart_transportable.cc b/idlc/gen_cion/default_dart_transportable.cc
new file mode 100644
index 0000000..4ed09cb
--- /dev/null
+++ b/idlc/gen_cion/default_dart_transportable.cc
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/default_dart_transportable.h"
+
+#include <utility>
+
+#include "idlc/gen/replace_all.h"
+
+namespace {
+constexpr const char ___STUB_SEND_ASYNC[] =
+R"__dart_cb(
+ final DataPayload dp = DataPayload(<PARCEL_NAME>.asRaw());
+ <SERVER_NAME>!.send(<PEER_NAME>!, dp);
+)__dart_cb";
+
+} // namespace
+
+namespace tidl {
+
+std::string DefaultDartTransportable::GenImport() const {
+ return R"__dart_cb(
+import 'dart:async';
+
+import 'package:tizen_cion/tizen_cion.dart';
+import 'package:tizen_rpc_port/tizen_rpc_port.dart';
+)__dart_cb";
+}
+
+std::string DefaultDartTransportable::GenPeerInfo() const {
+ return "PeerInfo";
+}
+
+std::string DefaultDartTransportable::GenStubSendAsync(std::string parcel,
+ std::string server, std::string peer) const {
+ return std::string(ReplaceAll(___STUB_SEND_ASYNC, {
+ { "<PARCEL_NAME>", parcel },
+ { "<PEER_NAME>", peer },
+ { "<SERVER_NAME>", server } }));
+}
+
+std::string DefaultDartTransportable::GenFileReciveDef() const {
+ return R"__dart_cb(
+/// This method will be called when received file payload.
+Future<void> onFilePayloadReceived(FilePayload file, PayloadTransferStatus status);
+)__dart_cb";
+}
+
+std::string DefaultDartTransportable::GenFileRecive() const {
+ return R"__dart_cb(
+ if (payload.type == PayloadType.file) {
+ service!.onFilePayloadReceived(payload as FilePayload, status);
+ return;
+ }
+)__dart_cb";
+}
+
+std::string DefaultDartTransportable::GenStubExtend() const {
+ return "Server";
+}
+
+std::string DefaultDartTransportable::GenStubParamDef() const {
+ return R"__dart_cb(String? displayName,
+ SecurityInfo? security,
+)__dart_cb";
+}
+
+std::string DefaultDartTransportable::GenStubSuperParam() const {
+ return "'<INTERFACE_NAME>', displayName ?? '', security: security";
+}
+} // namespace tidl
diff --git a/idlc/gen_cion/default_dart_transportable.h b/idlc/gen_cion/default_dart_transportable.h
new file mode 100644
index 0000000..df55758
--- /dev/null
+++ b/idlc/gen_cion/default_dart_transportable.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_DEFAULT_DART_TRANSPORTABLE_H_
+#define IDLC_GEN_CION_DEFAULT_DART_TRANSPORTABLE_H_
+
+#include <string>
+
+#include "idlc/gen_cion/dart_transportable.h"
+
+namespace tidl {
+
+class DefaultDartTransportable : public DartTransportable {
+ public:
+ virtual ~DefaultDartTransportable() = default;
+ std::string GenImport() const override;
+ std::string GenPeerInfo() const override;
+ std::string GenStubSendAsync(std::string parcel,
+ std::string server, std::string peer) const override;
+ std::string GenFileReciveDef() const override;
+ std::string GenFileRecive() const override;
+ std::string GenStubExtend() const override;
+ std::string GenStubParamDef() const override;
+ std::string GenStubSuperParam() const override;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CION_DEFAULT_DART_TRANSPORTABLE_H_
diff --git a/idlc/gen_cion/default_java_transportable.cc b/idlc/gen_cion/default_java_transportable.cc
new file mode 100644
index 0000000..e36a865
--- /dev/null
+++ b/idlc/gen_cion/default_java_transportable.cc
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/default_java_transportable.h"
+
+#include <utility>
+
+#include "idlc/gen/replace_all.h"
+
+namespace {
+
+std::string ParamsToString(std::vector<std::string> params) {
+ std::string res;
+ for (auto it = params.begin(); it != params.end(); it++) {
+ res += *it;
+ if ((it + 1) != params.end())
+ res += ", ";
+ }
+
+ return res;
+}
+
+constexpr const char __SERVER_ACCEPT[] = "<SERVER>.acceptRequest(peerInfo);";
+
+constexpr const char __SERVER_STOP[] = "<SERVER>.stop();";
+
+constexpr const char __SERVER_REJECT[] =
+ "<SERVER>.rejectRequest(<PEER>, <REASON>);";
+
+constexpr const char __CLIENT_TRY_CONNECT[] =
+ "<CLIENT>.tryConnect(<PEER>, this);";
+
+constexpr const char __CLIENT_DISCONNECT[] =
+ "<CLIENT>.disconnect();";
+
+constexpr const char __CLIENT_TRY_DISCOVERY[] =
+ "<CLIENT>.tryDiscovery(this);";
+
+constexpr const char __CLIENT_STOP_DISCOVERY[] =
+ "<CLIENT>.stopDiscovery();";
+
+constexpr const char __CLIENT_SEND_ASYNC[] =
+ "<CLIENT>.sendPayloadAsync(<PAYLOAD>, this);";
+
+constexpr const char __CLIENT_SEND[] =
+R"__java_cb(try {
+ return <CLIENT>.sendData(<DATA>, <DATA_SIZE>);
+ } catch (SocketTimeoutException e) {
+ e.printStackTrace();
+ }
+ return null;)__java_cb";
+
+constexpr const char __SERVER_SEND_ASYNC[] =
+ "<SERVER>.sendPayloadAsync(<PAYLOAD>, this);";
+
+constexpr const char __GROUP_PUBLISH[] = "<GROUP>.publish(<DATA>);";
+
+constexpr const char __GROUP_SUBSCRIBE[] = "<GROUP>.subscribe(this);";
+
+constexpr const char __GROUP_UNSUBSCRIBE[] = "<GROUP>.unsubscribe();";
+
+constexpr const char __SERVER_LISTEN[] =
+ "<SERVER>.listen(this);";
+
+constexpr const char __SERVER_DISCONNECT[] = "<SERVER>.disconnect(<PEER>);";
+
+constexpr const char __PEER_INFO_GET_APPID[] =
+ "<PEER>.getAppId()";
+
+constexpr const char __PEER_INFO_GET_UUID[] =
+ "<PEER>.getUuid()";
+
+constexpr const char __CLIENT_BASE_CONSTRUCTOR[] =
+R"__java_cb(
+ /**
+ * Constructor
+ * @param mContext The Context
+ * @param serviceName Service name
+ */
+ public ClientBase(Context mContext, String serviceName) {
+ mClient = new <CLIENT_CHANNEL>(mContext, serviceName);
+ this.mContext = mContext;
+ }
+
+ /**
+ * Constructor with security information
+ * @param mContext The context
+ * @param serviceName Service name
+ * @param sec Security information
+ */
+ public ClientBase(Context mContext, String serviceName, <SECURITY_T> sec) {
+ mClient = new <CLIENT_CHANNEL>(mContext, serviceName, sec);
+ this.mContext = mContext;
+ }
+)__java_cb";
+
+constexpr const char __SERVER_BASE_CONSTRUCTOR[] =
+R"__java_cb(
+ /**
+ * Constructor
+ * @param mContext Context
+ * @param mServiceName Service name
+ * @param mDisplayName Display name
+ */
+ public ServerBase(Context mContext, String mServiceName, String mDisplayName) {
+ mServer = new <SERVER_CHANNEL>(mContext, mServiceName, mDisplayName);
+ this.mContext = mContext;
+ this.mServiceName = mServiceName;
+ this.mDisplayName = mDisplayName;
+ }
+
+ /**
+ * Constructor with security information
+ * @param mContext Context
+ * @param mServiceName Service name
+ * @param mDisplayName Display name
+ * @param sec Security information
+ */
+ public ServerBase(Context mContext, String mServiceName, String mDisplayName, <SECURITY_T> sec) {
+ mServer = new <SERVER_CHANNEL>(mContext, mServiceName, mDisplayName, sec);
+ this.mContext = mContext;
+ this.mServiceName = mServiceName;
+ this.mDisplayName = mDisplayName;
+ }
+)__java_cb";
+
+constexpr const char __GROUP_BASE_CONSTRUCTOR[] =
+R"__java_cb(
+ /**
+ * Constructor
+ * @param mContext The Context
+ * @param topicName Topic name
+ */
+ public GroupBase(Context mContext, String topicName) {
+ mGroup = new <GROUP_CHANNEL>(mContext, topicName);
+ this.mContext = mContext;
+ }
+
+ /**
+ * Constructor with security information
+ * @param mContext The context
+ * @param topicName Topic name
+ * @param sec Security information
+ */
+ public GroupBase(Context mContext, String topicName, <SECURITY_T> sec) {
+ mGroup = new <GROUP_CHANNEL>(mContext, topicName, sec);
+ this.mContext = mContext;
+ }
+)__java_cb";
+
+constexpr const char __ON_LEFT_EVENT_METHOD[] =
+R"__java_cb(
+ @Override
+ public void onLeft(<PEER_INFO_T> peerInfo) {
+ }
+)__java_cb";
+
+constexpr const char __ON_JOINED_EVENT_METHOD[] =
+R"__java_cb(
+ @Override
+ public void onJoined(PeerInfo peerInfo, String topic_name) {
+ }
+)__java_cb";
+
+constexpr const char __INHERITED_CLASS_CONSTRUCTOR[] =
+R"__java_cb(
+public $$(<PARAMETERS>) {
+ super(<BASE_CLASS_PARAMETERS>);
+ <EXTRA_OPERATION>
+}
+)__java_cb";
+
+
+} // namespace
+
+namespace tidl {
+
+std::string DefaultJavaTransportable::GenInclude() const {
+ return "import org.tizen.cion.*;";
+}
+
+std::string DefaultJavaTransportable::GenParcelInclude() const {
+ return "import org.tizen.cion.CionParcel;";
+}
+
+std::string DefaultJavaTransportable::GenParcel() const {
+ return "CionParcel";
+}
+
+std::string DefaultJavaTransportable::GenClientChannel() const {
+ return "ClientChannel";
+}
+
+std::string DefaultJavaTransportable::GenServerChannel() const {
+ return "ServerChannel";
+}
+
+std::string DefaultJavaTransportable::GenGroupChannel() const {
+ return "GroupChannel";
+}
+
+std::string DefaultJavaTransportable::GenClientSendAsync(std::string client,
+ std::string payload) const {
+ return std::string(ReplaceAll(__CLIENT_SEND_ASYNC, {
+ { "<CLIENT>", client },
+ { "<PAYLOAD>", payload} }));
+}
+
+std::string DefaultJavaTransportable::GenClientSend(std::string client,
+ std::string data, std::string data_size) const {
+ return std::string(ReplaceAll(__CLIENT_SEND, {
+ { "<CLIENT>", client },
+ { "<DATA>", data},
+ { "<DATA_SIZE>", data_size} }));
+}
+
+std::string DefaultJavaTransportable::GenServerSendAsync(std::string server,
+ std::string payload) const {
+ return std::string(ReplaceAll(__SERVER_SEND_ASYNC, {
+ { "<SERVER>", server },
+ { "<PAYLOAD>", payload} }));
+}
+
+std::string DefaultJavaTransportable::GenPeerInfoType() const {
+ return "PeerInfo";
+}
+
+std::string DefaultJavaTransportable::GenSecurityType() const {
+ return "SecurityInfo";
+}
+
+std::string DefaultJavaTransportable::GenClientTryConnect(std::string client,
+ std::string peer) const {
+ return std::string(ReplaceAll(__CLIENT_TRY_CONNECT, {
+ { "<CLIENT>", client },
+ { "<PEER>", peer } }));
+}
+
+std::string DefaultJavaTransportable::GenClientDisconnect(
+ std::string client) const {
+ return std::string(ReplaceAll(__CLIENT_DISCONNECT, {
+ { "<CLIENT>", client } }));
+}
+
+std::string DefaultJavaTransportable::GenClientTryDiscovery(
+ std::string client) const {
+ return std::string(ReplaceAll(__CLIENT_TRY_DISCOVERY, {
+ { "<CLIENT>", client } }));
+}
+
+std::string DefaultJavaTransportable::GenClientStopDiscovery(
+ std::string client) const {
+ return std::string(ReplaceAll(__CLIENT_STOP_DISCOVERY, {
+ { "<CLIENT>", client } }));
+}
+
+std::string DefaultJavaTransportable::GenClientExtraHeader() const {
+ return "";
+}
+
+std::string DefaultJavaTransportable::GenClientExtraBody() const {
+ return "";
+}
+
+std::string DefaultJavaTransportable::GenServerExtraHeader() const {
+ return "";
+}
+
+std::string DefaultJavaTransportable::GenServerExtraBody() const {
+ return "";
+}
+
+std::string DefaultJavaTransportable::GenServerAccept(
+ std::string server) const {
+ return std::string(ReplaceAll(__SERVER_ACCEPT, {
+ { "<SERVER>", server } }));
+}
+
+std::string DefaultJavaTransportable::GenServerStop(
+ std::string server) const {
+ return std::string(ReplaceAll(__SERVER_STOP, {
+ { "<SERVER>", server } }));
+}
+
+std::string DefaultJavaTransportable::GenServerReject(std::string server,
+ std::string peer, std::string reason) const {
+ return std::string(ReplaceAll(__SERVER_REJECT, {
+ { "<SERVER>", server },
+ { "<PEER>", peer },
+ { "<REASON>", reason } }));
+}
+
+std::string DefaultJavaTransportable::GenGroupPublish(
+ std::string group, std::string data) const {
+ return std::string(ReplaceAll(__GROUP_PUBLISH, {
+ { "<GROUP>", group },
+ { "<DATA>", data } }));
+}
+
+std::string DefaultJavaTransportable::GenGroupSubscribe(
+ std::string group) const {
+ return std::string(ReplaceAll(__GROUP_SUBSCRIBE, {
+ { "<GROUP>", group } }));
+}
+
+std::string DefaultJavaTransportable::GenGroupUnsubscribe(
+ std::string group) const {
+ return std::string(ReplaceAll(__GROUP_UNSUBSCRIBE, {
+ { "<GROUP>", group } }));
+}
+
+std::string DefaultJavaTransportable::GenServerListen(std::string server) const {
+ return std::string(ReplaceAll(__SERVER_LISTEN, {
+ {"<SERVER>", server} }));
+}
+
+std::string DefaultJavaTransportable::GenServerDisconnect(std::string server,
+ std::string peer) const {
+ return std::string(ReplaceAll(__SERVER_DISCONNECT, {
+ { "<SERVER>", server },
+ { "<PEER>", peer } }));
+}
+
+std::string DefaultJavaTransportable::GenPeerInfoGetAppID(
+ std::string peer) const {
+ return std::string(ReplaceAll(__PEER_INFO_GET_APPID, {
+ { "<PEER>", peer} }));
+}
+
+std::string DefaultJavaTransportable::GenPeerInfoGetUUID(
+ std::string peer) const {
+ return std::string(ReplaceAll(__PEER_INFO_GET_UUID, {
+ { "<PEER>", peer} }));
+}
+
+std::string DefaultJavaTransportable::GenClientBaseConstructor() const {
+ return __CLIENT_BASE_CONSTRUCTOR;
+}
+
+std::string DefaultJavaTransportable::GenServerBaseConstructor() const {
+ return __SERVER_BASE_CONSTRUCTOR;
+}
+
+std::string DefaultJavaTransportable::GenGroupBaseConstructor() const {
+ return __GROUP_BASE_CONSTRUCTOR;
+}
+
+std::string DefaultJavaTransportable::GenOnLeftEventMethod() const {
+ return __ON_LEFT_EVENT_METHOD;
+}
+
+std::string DefaultJavaTransportable::GenOnJoinedEventMethod() const {
+ return __ON_JOINED_EVENT_METHOD;
+}
+
+std::string DefaultJavaTransportable::GenInheritedClassConstructor(
+ std::vector<std::string> params, std::vector<std::string> base_class_params,
+ std::string extra_operation) const {
+ return std::string(ReplaceAll(__INHERITED_CLASS_CONSTRUCTOR, {
+ { "<PARAMETERS>", ParamsToString(params) },
+ { "<BASE_CLASS_PARAMETERS>", ParamsToString(base_class_params) },
+ { "<EXTRA_OPERATION>", extra_operation }
+ }));
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/default_java_transportable.h b/idlc/gen_cion/default_java_transportable.h
new file mode 100644
index 0000000..8f186d5
--- /dev/null
+++ b/idlc/gen_cion/default_java_transportable.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_DEFAULT_JAVA_TRANSPORTABLE_H_
+#define IDLC_GEN_CION_DEFAULT_JAVA_TRANSPORTABLE_H_
+
+#include <string>
+
+#include "idlc/gen_cion/java_transportable.h"
+
+namespace tidl {
+
+class DefaultJavaTransportable : public JavaTransportable {
+ public:
+ virtual ~DefaultJavaTransportable() = default;
+ std::string GenInclude() const override;
+ std::string GenParcelInclude() const override;
+ std::string GenParcel() const override;
+ std::string GenClientChannel() const override;
+ std::string GenServerChannel() const override;
+ std::string GenGroupChannel() const override;
+ std::string GenClientSendAsync(std::string client,
+ std::string payload) const override;
+ std::string GenClientSend(std::string client, std::string data,
+ std::string data_size) const override;
+ std::string GenServerSendAsync(std::string server,
+ std::string payload) const override;
+ std::string GenPeerInfoType() const override;
+ std::string GenSecurityType() const override;
+ std::string GenClientTryConnect(std::string client,
+ std::string peer) const override;
+ std::string GenClientDisconnect(std::string client) const override;
+ std::string GenClientTryDiscovery(std::string client) const override;
+ std::string GenClientStopDiscovery(std::string client) const override;
+ std::string GenClientExtraHeader() const override;
+ std::string GenClientExtraBody() const override;
+ std::string GenServerExtraHeader() const override;
+ std::string GenServerExtraBody() const override;
+ std::string GenServerAccept(std::string server) const override;
+ std::string GenServerStop(std::string server) const override;
+ std::string GenServerReject(std::string server,
+ std::string peer, std::string reason) const override;
+ std::string GenGroupPublish(std::string group, std::string data) const override;
+ std::string GenGroupSubscribe(std::string group) const override;
+ std::string GenGroupUnsubscribe(std::string group) const override;
+ std::string GenServerListen(std::string server) const override;
+ std::string GenServerDisconnect(std::string server,
+ std::string peer) const override;
+ std::string GenPeerInfoGetAppID(std::string peer) const override;
+ std::string GenPeerInfoGetUUID(std::string peer) const override;
+ std::string GenClientBaseConstructor() const override;
+ std::string GenServerBaseConstructor() const override;
+ std::string GenGroupBaseConstructor() const override;
+ std::string GenOnLeftEventMethod() const override;
+ std::string GenOnJoinedEventMethod() const override;
+ std::string GenInheritedClassConstructor(std::vector<std::string> params,
+ std::vector<std::string> base_class_params,
+ std::string extra_operation) const override;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CION_DEFAULT_JAVA_TRANSPORTABLE_H_
diff --git a/idlc/gen_cion/java_cion_common_gen.cc b/idlc/gen_cion/java_cion_common_gen.cc
new file mode 100644
index 0000000..7850897
--- /dev/null
+++ b/idlc/gen_cion/java_cion_common_gen.cc
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/java_cion_common_gen.h"
+#include "idlc/gen_cion/java_cion_gen_cb.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <ctime>
+#include <vector>
+
+namespace tidl {
+
+JavaCionCommonGen::JavaCionCommonGen(
+ std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : JavaCionGeneratorBase(doc, trans) {
+}
+
+void JavaCionCommonGen::OnInitGen(std::ofstream& stream) {
+ std::string fname = MakeDir(FileName, "/common");
+ if (fname.empty())
+ return;
+
+ stream.open(fname + "/DelegatorBase.java");
+ stream << "package org.tizen.gen." << FileName + ".common;" << NLine(1);
+ stream << ReplaceAll(DELEGATOR_BASE, {
+ { "<DELEGATOR_IDS>", GetDelegateId() },
+ { "<PARCEL_INCLUDE>", GetTransportable().Java().GenParcelInclude() },
+ { "<PARCEL>", GetTransportable().Java().GenParcel() }
+ });
+ stream.close();
+
+ stream.open(fname + "/NotConnectedSocketException.java");
+ stream << "package org.tizen.gen." << FileName << ".common;" << NLine(2);
+ stream << CB_CION_JAVA_EXCEPTION_NotConnectedSocketException << NLine(1);
+ stream.close();
+
+ stream.open(fname + "/InvalidProtocolException.java");
+ stream << "package org.tizen.gen." << FileName << ".common;" << NLine(2);
+ stream << CB_CION_JAVA_EXCEPTION_InvalidProtocolException << NLine(1);
+ stream.close();
+
+ stream.open(fname + "/InvalidIOException.java");
+ stream << "package org.tizen.gen." << FileName << ".common;" << NLine(2);
+ stream << CB_CION_JAVA_EXCEPTION_InvalidIOException << NLine(1);
+ stream.close();
+
+ stream.open(fname + "/PermissionDeniedException.java");
+ stream << "package org.tizen.gen." << FileName << ".common;" << NLine(2);
+ stream << CB_CION_JAVA_EXCEPTION_PermissionDeniedException << NLine(1);
+ stream.close();
+
+ stream.open(fname + "/InvalidIDException.java");
+ stream << "package org.tizen.gen." << FileName << ".common;" << NLine(2);
+ stream << CB_CION_JAVA_EXCEPTION_InvalidIDException << NLine(1);
+ stream.close();
+
+ stream.open(fname + "/InvalidCallbackException.java");
+ stream << "package org.tizen.gen." << FileName << ".common;" << NLine(2);
+ stream << CB_CION_JAVA_EXCEPTION_InvalidCallbackException << NLine(1);
+ stream.close();
+
+ stream.open(fname + "/InvalidArgumentException.java");
+ stream << "package org.tizen.gen." << FileName << ".common;" << NLine(2);
+ stream << CB_CION_JAVA_EXCEPTION_InvalidArgumentException << NLine(1);
+ stream.close();
+}
+
+std::string JavaCionCommonGen::GetDelegateId() {
+ int id = 1;
+ std::string str;
+
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ Interface& iface = static_cast<Interface&>(*i);
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ str += Tab(1);
+ str += "public static final int ";
+ str = str + i->GetID() + "_" + d->GetID() + "__ = "
+ + std::to_string(id++) + ";\n";
+ }
+ }
+
+ return str;
+}
+
+void JavaCionCommonGen::OnFiniGen(std::ofstream& stream) {
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/java_cion_common_gen.h b/idlc/gen_cion/java_cion_common_gen.h
new file mode 100644
index 0000000..cdf478d
--- /dev/null
+++ b/idlc/gen_cion/java_cion_common_gen.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_JAVA_CION_COMMON_GEN_H_
+#define IDLC_GEN_CION_JAVA_CION_COMMON_GEN_H_
+
+#include <memory>
+#include <string>
+#include <map>
+
+#include "idlc/gen_cion/java_cion_gen_base.h"
+
+namespace tidl {
+
+class JavaCionCommonGen : public JavaCionGeneratorBase {
+ public:
+ explicit JavaCionCommonGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~JavaCionCommonGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+ std::string GetDelegateId();
+};
+
+} // namespace tidl
+#endif // IDLC_GEN_CION_JAVA_CION_COMMON_GEN_H_
diff --git a/idlc/gen_cion/java_cion_gen_base.cc b/idlc/gen_cion/java_cion_gen_base.cc
new file mode 100644
index 0000000..7831352
--- /dev/null
+++ b/idlc/gen_cion/java_cion_gen_base.cc
@@ -0,0 +1,702 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/java_cion_gen_base.h"
+#include "idlc/gen_cion/java_cion_gen_cb.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <ctime>
+#include <vector>
+
+#if (defined(_WIN32) || defined(__WIN32__))
+#define mkdir(A, B) mkdir(A)
+#endif
+
+namespace tidl {
+
+JavaCionGeneratorBase::JavaCionGeneratorBase(
+ std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : CionPluginBase(std::move(doc), trans) {
+ type_map_ = {
+ {"char", "byte"}, {"int", "int"}, {"short", "short"},
+ {"long", "long"}, {"string", "String"}, {"bool", "boolean"},
+ {"list", "LinkedList"}, {"array", "ArrayList"}, {"float", "float"},
+ {"double", "double"}, {"bundle", "Bundle"}, {"void", "void"},
+ {"file", "String"}
+ };
+
+ meta_type_map_ = {
+ {"char", "Byte"},
+ {"int", "Integer"},
+ {"short", "Short"},
+ {"long", "Long"},
+ {"string", "String"},
+ {"bool", "Boolean"},
+ {"float", "Float"},
+ {"double", "Double"},
+ {"bundle", "Bundle"},
+ {"file", "String"}
+ };
+
+ parcel_reader_map_ = {
+ {"char", "Byte"},
+ {"int", "Int"},
+ {"short", "Short"},
+ {"long", "Long"},
+ {"string", "String"},
+ {"bool", "Boolean"},
+ {"float", "Float"},
+ {"double", "Double"},
+ {"bundle", "Bundle"},
+ {"file", "String"}
+ };
+}
+
+void JavaCionGeneratorBase::GenMethodId(std::ofstream& stream,
+ const Interface& iface, bool is_group) {
+ int cnt = 0;
+
+ if (!is_group) {
+ stream << Tab(1) << "public static final int __RESULT = 0;" << NLine(2);
+ stream << Tab(1) << "public static final int __CALLBACK = 1;" << NLine(2);
+ cnt = 2;
+ }
+
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+ stream << Tab(1)
+ << "public static final int __"
+ << i->GetID() << " = " << cnt++ << ";" << NLine(2);
+ }
+}
+
+void JavaCionGeneratorBase::GenDeclaration(std::ofstream& stream,
+ const Declaration& decl, bool semicol) {
+ stream << ConvertTypeToString(decl.GetType()) << " "
+ << decl.GetID() << "(";
+ GenParameters(stream, decl.GetParameters());
+ if (semicol)
+ stream << ");";
+ else
+ stream << ")";
+}
+
+void JavaCionGeneratorBase::GenParameters(std::ofstream& stream,
+ const Parameters& ps) {
+ stream << GetParameters(ps);
+}
+
+std::string JavaCionGeneratorBase::ConvertTypeToString(
+ const BaseType& type, bool is_meta) {
+ if (type.IsUserDefinedType())
+ return type.ToString();
+
+ if (type.GetMetaType() != nullptr)
+ return type_map_[type.ToString()] + "<" +
+ ConvertTypeToString(*(type.GetMetaType()), true) + ">";
+
+ if (is_meta)
+ return meta_type_map_[type.ToString()];
+
+ return type_map_[type.ToString()];
+}
+
+std::string JavaCionGeneratorBase::GetParameters(const Parameters& ps) {
+ bool first = true;
+ std::string ret;
+ for (const auto& i : ps) {
+ if (!first) {
+ ret += ", ";
+ }
+
+ auto dir = i->GetParameterType().GetDirection();
+ if (dir == ParameterType::Direction::OUT) {
+ ret += "Out<"
+ + ConvertTypeToString(i->GetParameterType().GetBaseType(), true)
+ + ">";
+ } else if (dir == ParameterType::Direction::REF) {
+ ret += "Ref<"
+ + ConvertTypeToString(i->GetParameterType().GetBaseType(), true)
+ + ">";
+ } else {
+ ret += ConvertTypeToString(i->GetParameterType().GetBaseType());
+ }
+
+ ret += " " + i->GetID();
+ first = false;
+ }
+
+ return ret;
+}
+
+std::string JavaCionGeneratorBase::GetViewModelName(std::string id) {
+ return id + "ViewModel";
+}
+
+std::string JavaCionGeneratorBase::GetRepoClassName(std::string id) {
+ return id + "Repo";
+}
+
+std::string JavaCionGeneratorBase::GetServiceBaseClassName(std::string id) {
+ return id;
+}
+
+std::string JavaCionGeneratorBase::GetParcelReader(
+ const BaseType& type, std::string parcel_name,
+ std::string variable_name, int tab_size, bool assign) {
+ std::string ret_str = "";
+ if (type.IsUserDefinedType()) {
+ ret_str += Tab(tab_size) + ConvertTypeToString(type);
+ ret_str += " " + variable_name + " = ";
+ ret_str += "new " + ConvertTypeToString(type) + "();" + NLine(1);
+ ret_str += Tab(tab_size) + variable_name + ".deserialize(" + parcel_name + ");" + NLine(1);
+ return ret_str;
+ }
+
+ if (type.GetMetaType() != nullptr) {
+ ret_str += Tab(tab_size) + "int " + variable_name + "_size = "
+ + parcel_name + ".readInt();" + NLine(1);
+ ret_str += Tab(tab_size) + ConvertTypeToString(type);
+ ret_str += " " + variable_name + " = ";
+ ret_str += "new " + ConvertTypeToString(type) + "();" + NLine(1);
+ ret_str += Tab(tab_size) + "for (int i = 0; i < "
+ + variable_name + "_size; i++) {" + NLine(1);
+ if (type.GetMetaType()->IsUserDefinedType()) {
+ ret_str += GetParcelReader(*(type.GetMetaType()),
+ parcel_name, "temp", tab_size +1, false) + NLine(1);
+ ret_str += Tab(tab_size + 1) + variable_name + ".add(temp);" + NLine(1);
+ } else {
+ ret_str += Tab(tab_size + 1) + variable_name + ".add(" +
+ GetParcelReader(*(type.GetMetaType()),
+ parcel_name, variable_name, 0, false) + ");" + NLine(1);
+ }
+ ret_str += Tab(tab_size) + "}" + NLine(1);
+ return ret_str;
+ }
+
+ if (assign) {
+ ret_str += Tab(tab_size) + ConvertTypeToString(type);
+ ret_str += " " + variable_name + " = " + parcel_name + "."
+ + "read" + parcel_reader_map_[type.ToString()] + "();";
+ } else {
+ ret_str += Tab(tab_size) + parcel_name + "."
+ + "read" + parcel_reader_map_[type.ToString()] + "();";
+ }
+
+ return ret_str;
+}
+
+std::string JavaCionGeneratorBase::Tab(int cnt) {
+ std::string t;
+
+ for (int i = 0; i < cnt; i++) {
+ t += " ";
+ }
+
+ return t;
+}
+
+std::string JavaCionGeneratorBase::NLine(int cnt) {
+ std::string t;
+
+ for (int i = 0; i < cnt; i++) {
+ t += "\n";
+ }
+
+ return t;
+}
+
+std::string JavaCionGeneratorBase::MakeDir(const std::string& file_name,
+ const std::string& opt) {
+ std::string fname = "./java/org/tizen/gen/" + file_name + opt;
+ std::string name = "./java/org/tizen/gen/" + file_name;
+ if (access(fname.c_str(), F_OK) != 0) {
+ /* 02000: S_ISGID */
+ mode_t mod = (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH | 02000);
+
+ mkdir("./java", mod);
+ mkdir("./java/org", mod);
+ mkdir("./java/org/tizen", mod);
+ mkdir("./java/org/tizen/gen", mod);
+ mkdir(name.c_str(), mod);
+ int r = mkdir(fname.c_str(), mod);
+
+ if (r < 0) {
+ std::cout << "fail to create folder " << fname << std::endl;
+ return "";
+ }
+ }
+
+ return fname;
+}
+
+void JavaCionGeneratorBase::GenSerializer(std::ofstream& stream,
+ const Structure& st) {
+ stream << Tab(1) << ReplaceAll("private static void serialize(<PARCEL> h, ",
+ "<PARCEL>", GetTransportable().Java().GenParcel())
+ << st.GetID() << " param) ";
+ GenBrace(stream, TAB_SIZE * 1, [&]() {
+ for (const auto& i : st.GetElements()) {
+ auto& t = i->GetType();
+ if (!t.IsUserDefinedType() && t.GetMetaType() == nullptr) {
+ stream << Tab(2) << "h.write"
+ << "(param.get"
+ << i->GetID()
+ << "());" << NLine(1);
+ } else {
+ if (t.GetMetaType() != nullptr) {
+ stream << Tab(2) << "serialize(h, param.get" << i->GetID()
+ << "(), null);" << NLine(1);
+ } else {
+ stream << Tab(2) << "serialize(h, param.get" << i->GetID()
+ << "());" << NLine(1);
+ }
+ }
+ }
+ }, false);
+ stream << NLine(1);
+ stream << Tab(1) << ReplaceAll("private static void deserialize(<PARCEL> h, ",
+ "<PARCEL>", GetTransportable().Java().GenParcel())
+ << st.GetID() << " param) ";
+ GenBrace(stream, TAB_SIZE * 1, [&]() {
+ for (const auto& i : st.GetElements()) {
+ auto& t = i->GetType();
+ if (!t.IsUserDefinedType() && t.GetMetaType() == nullptr) {
+ stream << Tab(2) << ConvertTypeToString(t)
+ << " " << i->GetID() << " = "
+ << "h.read"
+ << ConvertTypeToParcelType(t.ToString())
+ << "();" << NLine(1);
+ stream << Tab(2) << "param.set" << i->GetID() << "(" << i->GetID()
+ << ");" << NLine(1);
+ } else {
+ stream << Tab(2) << "param.set" << i->GetID() << "(new "
+ << ConvertTypeToString(t)
+ << "());" << NLine(1);
+ if (t.GetMetaType() != nullptr) {
+ stream << Tab(2) << "deserialize(h, param.get" << i->GetID()
+ << "(), null);" << NLine(1);
+ } else {
+ stream << Tab(2) << "deserialize(h, param.get" << i->GetID()
+ << "());" << NLine(1);
+ }
+ }
+ }
+ }, false);
+ stream << NLine(1);
+}
+
+void JavaCionGeneratorBase::GenSerializer(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() == Block::TYPE_STRUCTURE) {
+ const Structure& st = static_cast<const Structure&>(*i);
+ GenSerializer(stream, st);
+ }
+ }
+}
+
+void JavaCionGeneratorBase::GenListSerializer(std::ofstream& stream,
+ const BaseType& type) {
+ auto* ptr = type.GetMetaType();
+ if (ptr == nullptr)
+ return;
+
+ auto& mt = *ptr;
+ stream << Tab(1) << ReplaceAll("private static void serialize(<PARCEL> h, ",
+ "<PARCEL>", GetTransportable().Java().GenParcel())
+ << ConvertTypeToString(type) << " param, "
+ << ConvertTypeToString(mt, true) << " a) ";
+ GenBrace(stream, TAB_SIZE, [&]() {
+ stream << Tab(2)
+ << "h.write(param.size());"
+ << NLine(1);
+ stream << Tab(2) << "for (" << ConvertTypeToString(mt, true)
+ << " i : param) ";
+ GenBrace(stream, TAB_SIZE * 2, [&]() {
+ if (!mt.IsUserDefinedType() && mt.GetMetaType() == nullptr) {
+ stream << Tab(3) << "h.write(i);" << NLine(1);
+ } else {
+ if (mt.GetMetaType() != nullptr) {
+ stream << Tab(3) << "serialize(h, i, null);" << NLine(1);
+ } else {
+ stream << Tab(3) << "serialize(h, i);" << NLine(1);
+ }
+ }
+ }, false);
+ }, false);
+ stream << NLine(1);
+
+ stream << Tab(1) << ReplaceAll("private static void deserialize(<PARCEL> h, ",
+ "<PARCEL>", GetTransportable().Java().GenParcel())
+ << ConvertTypeToString(type) << " param, "
+ << ConvertTypeToString(mt, true) << " a) ";
+ GenBrace(stream, TAB_SIZE, [&]() {
+ stream << Tab(2)
+ << "int l = h.readInt();"
+ << NLine(1);
+ stream << Tab(2) << "for (int i = 0; i < l; i++) ";
+ GenBrace(stream, TAB_SIZE * 2, [&]() {
+ if (!mt.IsUserDefinedType() && mt.GetMetaType() == nullptr) {
+ stream << Tab(3) << ConvertTypeToString(mt, true)
+ << " v = h.read"
+ << ConvertTypeToParcelType(mt.ToString())
+ << "();" << NLine(1);
+ } else {
+ stream << Tab(3) << ConvertTypeToString(mt, true)
+ << " v = new " << ConvertTypeToString(mt)
+ << "();" << NLine(1);
+ if (mt.GetMetaType() != nullptr) {
+ stream << Tab(3) << "deserialize(h, v, null);" << NLine(1);
+ } else {
+ stream << Tab(3) << "deserialize(h, v);" << NLine(1);
+ }
+ }
+ if (type.ToString() == "list")
+ stream << Tab(3) << "param.addLast(v);" << NLine(1);
+ else
+ stream << Tab(3) << "param.add(v);" << NLine(1);
+ }, false);
+ }, false);
+ stream << NLine(1);
+}
+
+void JavaCionGeneratorBase::GenListSerializer(std::ofstream& stream) {
+ serializer_list_.clear();
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() == Block::TYPE_STRUCTURE) {
+ const Structure& st = static_cast<const Structure&>(*i);
+ for (const auto& j : st.GetElements()) {
+ auto& t = j->GetType();
+ AddSerializerList(t);
+ }
+ } else if (i->GetType() == Block::TYPE_INTERFACE) {
+ const Interface& iface = static_cast<const Interface&>(*i);
+ for (const auto& j : iface.GetDeclarations()) {
+ auto& t = j->GetType();
+ AddSerializerList(t);
+ for (const auto& k : j->GetParameters()) {
+ auto& t1 = k->GetParameterType().GetBaseType();
+ AddSerializerList(t1);
+ }
+ }
+ }
+ }
+
+ for (auto& p : serializer_list_) {
+ const BaseType* t = p.second;
+ GenListSerializer(stream, *t);
+ }
+}
+
+void JavaCionGeneratorBase::AddSerializerList(const BaseType& type) {
+ if (type.GetMetaType() != nullptr) {
+ serializer_list_[ConvertTypeToString(type)] = &type;
+ AddSerializerList(*type.GetMetaType());
+ }
+}
+
+std::string JavaCionGeneratorBase::ConvertTypeToParcelType(const std::string& key) {
+ return parcel_reader_map_[key];
+}
+
+void JavaCionGeneratorBase::GenCallbacks(std::ofstream& stream,
+ const Interface& iface, bool is_proxy) {
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+ if (is_proxy)
+ GenCallbackProxy(stream, *i, iface.GetID());
+ else
+ GenCallbackStub(stream, *i, iface.GetID());
+ }
+}
+
+void JavaCionGeneratorBase::GenCallbackProxy(std::ofstream& stream,
+ const Declaration& decl, const std::string& id) {
+ std::string str;
+
+ str = ReplaceAll(CB_CALLBACK_CLASS_PROXY, {
+ { "<CLS_NAME>", decl.GetID() },
+ { "<PARCEL>", GetTransportable().Java().GenParcel() }
+ });
+ str = ReplaceAll(str, "<CALLBACK_PARAMS>",
+ GetParameters(decl.GetParameters()));
+ str = ReplaceAll(str, "<METHOD_ON_INVOKED>",
+ GetOnInvoked(decl, id));
+ str = ReplaceAll(str, "<IFACE_NAME>",id);
+ str = ReplaceAll(str, "<DELEGATOR_NAME>",decl.GetID());
+ stream << str;
+ stream << NLine(1);
+}
+
+void JavaCionGeneratorBase::GenCallbackStub(std::ofstream& stream,
+ const Declaration& decl, const std::string& id) {
+ std::string str;
+ str = ReplaceAll(CB_CALLBACK_CLASS_STUB, {
+ { "<CLS_NAME>", decl.GetID() },
+ { "<PEER_INFO_T>", GetTransportable().Java().GenPeerInfoType() },
+ { "<PARCEL>", GetTransportable().Java().GenParcel() }
+ });
+ str = ReplaceAll(str, "<CALLBACK_PARAMS>",
+ GetParameters(decl.GetParameters()));
+ str = ReplaceAll(str, "<IFACE_NAME>",id);
+ str = ReplaceAll(str, "<DELEGATOR_NAME>",decl.GetID());
+
+ std::string ser;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ ser += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p", id);
+ }
+
+ ser = AddIndent(TAB_SIZE * 3, ser);
+ str = ReplaceAll(str, "<SERIALIZE>", ser);
+
+ std::string share;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if(HasFile(pt.GetBaseType()))
+ share += "_serverBase.shareFile(" + i->GetID() + ");\n";
+ }
+
+ share = AddIndent(TAB_SIZE * 3, share);
+ str = ReplaceAll(str, "<SHARE_FILE>", share);
+
+ stream << str;
+ stream << NLine(1);
+}
+
+std::string JavaCionGeneratorBase::GetOnInvoked(const Declaration& decl,
+ const std::string& id) {
+ std::string str;
+ int cnt = 1;
+ for (const auto& i : decl.GetParameters()) {
+ std::string v = "param" + std::to_string(cnt);
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, "parcel", true, id);
+ str += AddIndent(TAB_SIZE * 3, c);
+ cnt++;
+ }
+
+ cnt = 1;
+ str += Tab(3);
+ str += "onInvoked(";
+ for (auto i = decl.GetParameters().begin();
+ i != decl.GetParameters().end(); ++i) {
+ if (cnt != 1) {
+ str += ", ";
+ }
+ std::string v = "param" + std::to_string(cnt);
+ str += v;
+ cnt++;
+ }
+ str += ");";
+
+ return str;
+}
+
+std::string JavaCionGeneratorBase::ConvertTypeToSerializer(
+ const BaseType& type, std::string id, std::string parcel,
+ std::string iface_id) {
+ std::string ret;
+
+ if (type.IsUserDefinedType() ||
+ type.GetMetaType() != nullptr) {
+ if (IsDelegateType(type))
+ return "DelegatorBase.serialize(" + parcel + ", " + id + ");\n";
+ if (iface_id != "")
+ ret += iface_id + ".";
+ if (type.GetMetaType() != nullptr)
+ ret += "serialize(" + parcel + ", " + id + ", null);\n";
+ else
+ ret += "serialize(" + parcel + ", " + id + ");\n";
+ return ret;
+ }
+
+ ret += parcel + ".write(" + id + ");\n";
+
+ return ret;
+}
+
+std::string JavaCionGeneratorBase::ConvertTypeToDeserializer(
+ const BaseType& type, std::string id, std::string parcel,
+ bool make_new_type, std::string iface_id, bool setter) {
+ if (type.IsUserDefinedType() ||
+ type.GetMetaType() != nullptr) {
+ std::string n;
+
+ if (type.GetMetaType() != nullptr)
+ n = ConvertTypeToString(type);
+ else
+ n = type.ToString();
+
+ std::string ret;
+
+ if (make_new_type)
+ ret = n + " ";
+
+ if (IsDelegateType(type)) {
+ ret += id + " = new " + n
+ + "(info, new WeakReference(b));\n";
+ ret += "DelegatorBase.";
+ } else {
+ ret += id + " = new " + n +"();\n";
+ }
+ if (iface_id != "")
+ ret += iface_id + ".";
+
+ if (type.GetMetaType() != nullptr)
+ ret += "deserialize(" + parcel + ", " + id + ", null);\n";
+ else
+ ret += "deserialize(" + parcel + ", " + id + ");\n";
+ return ret;
+ }
+
+ std::string ret;
+ if (make_new_type) {
+ ret = ConvertTypeToString(type) + " "
+ + id + " = " + parcel + ".read"
+ + parcel_reader_map_[type.ToString()]
+ + "();\n";
+ } else if (!setter) {
+ ret = id + " = " + parcel + ".read"
+ + parcel_reader_map_[type.ToString()]
+ + "();\n";
+ } else {
+ ret = id + ".set(" + parcel + ".read"
+ + parcel_reader_map_[type.ToString()]
+ + "());\n";
+ }
+
+ return ret;
+}
+
+bool JavaCionGeneratorBase::HasFile(const BaseType& type) {
+ if (type.ToString() == "list" || type.ToString() == "array") {
+ std::string name = GetFullNameFromType(type);
+ if (name == "array_file" || name == "list_file" || name == "file")
+ return true;
+ } else if (type.ToString() == "file") {
+ return true;
+ }
+
+ return false;
+}
+
+std::string JavaCionGeneratorBase::GetFullNameFromType(const BaseType& type) {
+ std::string str;
+
+ str += type.ToString();
+
+ if (type.GetMetaType() != nullptr) {
+ str += "_";
+ str += GetFullNameFromType(*type.GetMetaType());
+ }
+
+ return str;
+}
+
+void JavaCionGeneratorBase::GenVersion(std::ofstream& stream) {
+ GenTemplate(::CB_CION_JAVA_VERSION, stream,
+ [&]()->std::string {
+ return FULLVER;
+ });
+ stream << NLine(1);
+}
+
+void JavaCionGeneratorBase::GenDelegateId(std::ofstream& stream,
+ const Interface& iface) {
+ int cnt = 1;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+ stream << Tab(1) << "private static final int __"
+ << i->GetID() << " = " << cnt++ << ";" << NLine(2);
+ }
+}
+
+void JavaCionGeneratorBase::GenShareFile(std::ofstream& stream,
+ const Interface& iface, bool is_proxy) {
+ bool hasFile = false;
+
+ for (const auto& d : iface.GetDeclarations()) {
+ hasFile = HasFile(iface, *d, is_proxy);
+ if (hasFile == true)
+ break;
+ }
+
+ if (hasFile == false)
+ return;
+
+ stream << CB_SHARE_FILE_DEF << NLine(1);
+}
+
+std::string JavaCionGeneratorBase::GetFullNameFromType(const BaseType& type,
+ const Interface& iface) {
+ std::string str;
+ if (IsDelegateType(iface, type))
+ str += iface.GetID() + "_";
+
+ str += type.ToString();
+
+ if (type.GetMetaType() != nullptr) {
+ str += "_";
+ str += GetFullNameFromType(*type.GetMetaType(), iface);
+ }
+
+ return str;
+}
+
+bool JavaCionGeneratorBase::HasFile(const Interface& iface, const BaseType& type) {
+ if (type.ToString() == "list" || type.ToString() == "array") {
+ std::string name = GetFullNameFromType(type, iface);
+ if (name == "array_file" || name == "list_file" || name == "file")
+ return true;
+ } else if (type.ToString() == "file") {
+ return true;
+ }
+
+ return false;
+}
+
+bool JavaCionGeneratorBase::HasFile(const Interface& iface, const Declaration& decl, bool is_proxy) {
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (is_proxy) {
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+ } else if (decl.GetMethodType() == Declaration::MethodType::DELEGATE) {
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+ } else {
+ if (param_type.GetDirection() == ParameterType::Direction::IN)
+ continue;
+ }
+
+ if (HasFile(iface, param_type.GetBaseType()) == true)
+ return true;
+ }
+
+ if (is_proxy)
+ return false;
+
+ return HasFile(iface, decl.GetType());
+}
+
+
+} // namespace tidl
diff --git a/idlc/gen_cion/java_cion_gen_base.h b/idlc/gen_cion/java_cion_gen_base.h
new file mode 100644
index 0000000..73444b8
--- /dev/null
+++ b/idlc/gen_cion/java_cion_gen_base.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_JAVA_CION_GEN_BASE_H_
+#define IDLC_GEN_CION_JAVA_CION_GEN_BASE_H_
+
+#include <memory>
+#include <string>
+#include <map>
+
+#include "idlc/ast/type.h"
+#include "idlc/ast/structure.h"
+#include "idlc/gen_cion/cion_plugin_base.h"
+
+namespace tidl {
+
+class JavaCionGeneratorBase : public CionPluginBase {
+ public:
+ explicit JavaCionGeneratorBase(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~JavaCionGeneratorBase() = default;
+ void GenMethodId(std::ofstream& stream,
+ const Interface& iface, bool is_group = false);
+ void GenDeclaration(std::ofstream& stream,
+ const Declaration& decl, bool semicol = true);
+ void GenParameters(std::ofstream& stream, const Parameters& ps);
+ std::string ConvertTypeToString(const BaseType& type, bool is_meta = false);
+ std::string GetParameters(const Parameters& ps);
+ std::string GetParcelReader(const BaseType& type, std::string parcel_name,
+ std::string variable_name, int tab_size, bool assign = true);
+ std::string GetOnInvoked(const Declaration& decl, const std::string& id);
+
+ std::string GetRepoClassName(std::string id);
+ std::string GetServiceBaseClassName(std::string id);
+ std::string GetViewModelName(std::string id);
+ void GenSerializer(std::ofstream& stream, const Structure& st);
+ void GenSerializer(std::ofstream& stream);
+ void GenListSerializer(std::ofstream& stream, const BaseType& type);
+ void GenListSerializer(std::ofstream& stream);
+ void GenCallbacks(std::ofstream& stream, const Interface& iface, bool is_proxy);
+ void GenCallbackProxy(std::ofstream& stream, const Declaration& decl,
+ const std::string& id);
+ void GenCallbackStub(std::ofstream& stream, const Declaration& decl,
+ const std::string& id);
+
+ std::string ConvertTypeToSerializer(const BaseType& type, std::string id,
+ std::string parcel, std::string iface_id = "");
+ std::string ConvertTypeToDeserializer(const BaseType& type, std::string id,
+ std::string parcel, bool make_new_type = true,
+ std::string iface_id = "", bool setter = false);
+
+ std::string ConvertTypeToParcelType(const std::string& key);
+ void AddSerializerList(const BaseType& type);
+
+ std::string Tab(int cnt);
+ std::string NLine(int cnt);
+ std::string MakeDir(const std::string& file_name, const std::string& opt);
+ bool HasFile(const BaseType& type);
+ bool HasFile(const Interface& iface, const BaseType& type);
+ bool HasFile(const Interface& iface, const Declaration& decl, bool is_proxy);
+ std::string GetFullNameFromType(const BaseType& type);
+ std::string GetFullNameFromType(const BaseType& type, const Interface& iface);
+ void GenVersion(std::ofstream& stream);
+ void GenDelegateId(std::ofstream& stream, const Interface& iface);
+ void GenShareFile(std::ofstream& stream, const Interface& iface,
+ bool is_proxy);
+
+ protected:
+ const int TAB_SIZE = 4;
+
+ private:
+ std::map<std::string, std::string> type_map_;
+ std::map<std::string, std::string> meta_type_map_;
+ std::map<std::string, std::string> parcel_reader_map_;
+ std::map<std::string, const BaseType*> serializer_list_;
+};
+
+} // namespace tidl
+#endif // IDLC_GEN_CION_JAVA_CION_GEN_BASE_H_
diff --git a/idlc/gen_cion/java_cion_gen_cb.h b/idlc/gen_cion/java_cion_gen_cb.h
new file mode 100644
index 0000000..2901323
--- /dev/null
+++ b/idlc/gen_cion/java_cion_gen_cb.h
@@ -0,0 +1,492 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_JAVA_CION_GEN_CB_H_
+#define IDLC_GEN_CION_JAVA_CION_GEN_CB_H_
+
+
+const char DEFAULT_PROXY_REPO[] =
+R"__java_cb(
+import android.content.Context;
+
+<INCLUDE>
+
+import java.net.SocketTimeoutException;
+
+/**
+ * Abstract class for making a client
+ */
+public abstract class ClientBase implements DiscoveryCallback,
+ ClientConnectionLifecycleCallback, PayloadAsyncResultCallback {
+ private <CLIENT_CHANNEL> mClient;
+
+ private Context mContext;
+<CLIENT_BASE_CONSTRUCTOR>
+ /**
+ * Disconnects server
+ */
+ public void disconnect() {
+ <CLIENT_DISCONNECT>
+ }
+
+ /**
+ * Connects the server
+ * @param peer Server information
+ */
+ public void tryConnect(<PEER_INFO_T> peer) {
+ <CLIENT_TRY_CONNECT>
+ }
+
+ /**
+ * Finds available servers
+ */
+ public void tryDiscovery() {
+ <CLIENT_TRY_DISCOVERY>
+ }
+
+ /**
+ * Stops finding servers
+ */
+ public void stopDiscovery() {
+ <CLIENT_STOP_DISCOVERY>
+ }
+
+ /**
+ * Sends data payload asynchronously to the connected server
+ * @param payload Data payload
+ */
+ public void sendAsync(DataPayload payload) {
+ <CLIENT_SEND_ASYNC>
+ }
+
+ /**
+ * Sends file payload asynchronously to the connected server
+ * @param payload File payload
+ */
+ public void sendAsync(FilePayload payload) {
+ <CLIENT_SEND_ASYNC>
+ }
+
+ /**
+ * Sends data synchronously to the connected server
+ * @param data Data to send
+ * @return Received data
+ */
+ public byte[] sendData(byte[] data) {
+ <CLIENT_SEND>
+ }
+
+ @Override
+ public final void onLost(<PEER_INFO_T> peerInfo) {
+ }
+}
+
+)__java_cb";
+
+const char DEFAULT_STUB_REPO[] =
+R"__java_cb(
+import android.content.Context;
+
+<INCLUDE>
+
+/**
+ * Abstract class for making a server
+ */
+public abstract class ServerBase implements ServerConnectionLifecycleCallback,
+ PayloadAsyncResultCallback {
+ private <SERVER_CHANNEL> mServer;
+
+ private Context mContext;
+
+ private String mServiceName;
+
+ private String mDisplayName;
+<SERVER_BASE_CONSTRUCTOR>
+ /**
+ * Gets context
+ * @return Context
+ */
+ public Context getContext() {
+ return mContext;
+ }
+
+ /**
+ * Gets service name
+ * @return Service name
+ */
+ public String getServiceName() {
+ return mServiceName;
+ }
+
+ /**
+ * Gets display name
+ * @return Display name
+ */
+ public String getDisplayName() {
+ return mDisplayName;
+ }
+
+ /**
+ * Waits clients
+ */
+ public void listen() {
+ <SERVER_LISTEN>
+ }
+
+ /**
+ * Stops waiting clients
+ */
+ public void stop() {
+ <SERVER_STOP>
+ }
+
+ /**
+ * Disconnects the connected client
+ * @param peerInfo Client information
+ */
+ public void disconnect(<PEER_INFO_T> peerInfo) {
+ <SERVER_DISCONNECT>
+ }
+
+ /**
+ * Accepts the client
+ * @param peerInfo Client information
+ */
+ public void accept(<PEER_INFO_T> peerInfo) {
+ <SERVER_ACCEPT>
+ }
+
+ /**
+ * Rejects the client
+ * @param peerInfo Client information
+ * @param reason The reason for rejecting the client
+ */
+ public void reject(<PEER_INFO_T> peerInfo, String reason) {
+ <SERVER_REJECT>
+ }
+
+ /**
+ * Sends data asynchronously to the all connected clients
+ * @param payload Data
+ */
+ public void sendPayloadAsync(IPayload payload) {
+ <SERVER_SEND_ASYNC>
+ }
+}
+
+)__java_cb";
+
+const char DEFAULT_GROUP_REPO[] =
+R"__java_cb(
+import android.content.Context;
+
+<INCLUDE>
+
+import java.net.SocketTimeoutException;
+
+/**
+ * Abstract class for making a group
+ */
+public abstract class GroupBase implements GroupConnectionLifecycleCallback{
+ private <GROUP_CHANNEL> mGroup;
+
+ private Context mContext;
+<GROUP_BASE_CONSTRUCTOR>
+ /**
+ * Subscribes the topic.
+ */
+ public void subscribe() {
+ <GROUP_SUBSCRIBE>
+ }
+
+ /**
+ * Unsubscribes the topic.
+ */
+ public void unsubscribe() {
+ <GROUP_UNSUBSCRIBE>
+ }
+
+ /**
+ * Publishes payload to current group.
+ * @param data Data payload
+ */
+ public void publish(IPayload data) {
+ <GROUP_PUBLISH>
+ }
+}
+
+)__java_cb";
+
+const char OUT_CLASS[] =
+R"__java_cb(
+
+public class Out<T> {
+ T s;
+ public void set(T value){
+ s = value;
+ }
+
+ public T get(){
+ return s;
+ }
+
+ public Out() {
+ }
+}
+
+)__java_cb";
+
+const char REF_CLASS[] =
+R"__java_cb(
+
+public class Ref<T> {
+ T s;
+ public void set(T value) {
+ s = value;
+ }
+
+ public T get() {
+ return s;
+ }
+
+ public Ref(T value) {
+ s = value;
+ }
+}
+
+)__java_cb";
+
+
+const char DELEGATOR_BASE[] =
+R"__java_cb(
+
+<PARCEL_INCLUDE>
+
+/**
+ * Abstract class for making delegator
+ */
+public abstract class DelegatorBase {
+ private int mId;
+
+ private int mSeqId;
+
+ private boolean mOnce;
+
+ private static int sSeqNum = 0;
+
+<DELEGATOR_IDS>
+
+ /**
+ * Constructor
+ * @param delegateId Delegate ID
+ * @param once Use only once
+ */
+ public DelegatorBase(int delegateId, boolean once) {
+ this.mId = delegateId;
+ this.mSeqId = sSeqNum++;
+ this.mOnce = once;
+ }
+
+ /**
+ * This method will be invoked when the remote callback is called
+ * @param parcel Data
+ */
+ public abstract void onInvoked(<PARCEL> parcel);
+
+ /**
+ * Gets sequence ID
+ * @return Sequence ID
+ */
+ public int getDelegateId() {
+ return mId;
+ }
+
+ /**
+ * Gets sequence ID
+ * @return Sequence ID
+ */
+ public int getSequenceId() {
+ return mSeqId;
+ }
+
+ /**
+ * Gets once flag
+ * @return Once flag
+ */
+ public boolean isOnce() {
+ return mOnce;
+ }
+
+ public static void serialize(<PARCEL> h, DelegatorBase from) {
+ h.write(from.mId);
+ h.write(from.mSeqId);
+ h.write(from.mOnce);
+ }
+
+ public static void deserialize(<PARCEL> h, DelegatorBase to) {
+ to.mId = h.readInt();
+ to.mSeqId = h.readInt();
+ to.mOnce = h.readBoolean();
+ }
+
+ /**
+ * Gets once flag
+ * @return Once flag
+ */
+ public String getTag() {
+ return (new Integer(mId).toString()) + "_" + (new Integer(mSeqId).toString());
+ }
+}
+
+)__java_cb";
+
+const char CB_CALLBACK_CLASS_PROXY[] =
+R"__java_cb(
+ public static class <CLS_NAME> extends DelegatorBase {
+
+ /**
+ * Constructor
+ */
+ public <CLS_NAME>(boolean once) {
+ super(DelegatorBase.<IFACE_NAME>_<DELEGATOR_NAME>__, once);
+ }
+
+ /**
+ * Constructor
+ */
+ public <CLS_NAME>() {
+ super(DelegatorBase.<IFACE_NAME>_<DELEGATOR_NAME>__, false);
+ }
+
+ @Override
+ public final void onInvoked(<PARCEL> parcel) {
+<METHOD_ON_INVOKED>
+ }
+
+ /**
+ * This method will be invoked when remote callback is called
+ */
+ public void onInvoked(<CALLBACK_PARAMS>) {}
+ }
+)__java_cb";
+
+const char CB_CALLBACK_CLASS_STUB[] =
+R"__java_cb(
+ public static final class <CLS_NAME> extends DelegatorBase {
+ private <PEER_INFO_T> mPeerInfo;
+
+ private WeakReference<ServiceBase> mService;
+
+ private boolean mValid = true;
+
+ private <IFACE_NAME> mServerBase;
+
+ public <CLS_NAME>(<PEER_INFO_T> info, WeakReference<ServiceBase> service) {
+ super(DelegatorBase.<IFACE_NAME>_<DELEGATOR_NAME>__, false);
+ this.mPeerInfo = info;
+ this.mService = service;
+ this.mServerBase = (<IFACE_NAME>) service.get().mServerBase;
+ }
+
+ @Override
+ public final void onInvoked(<PARCEL> parcel) {}
+
+ /**
+ * Invokes a remote callback
+ */
+ public void Invoke(<CALLBACK_PARAMS>) {
+ if (mService.get() == null)
+ throw new InvalidProtocolException();
+ if (isOnce() && !mValid)
+ throw new InvalidCallbackException();
+
+ <PARCEL> p = new <PARCEL>();
+
+ p.write(__CALLBACK);
+ serialize(p, this);
+<SERIALIZE>
+ // Send
+ DataPayload dp = new DataPayload(p.toByteArray());
+ mServerBase.sendPayloadAsync(dp);
+ mValid = false;
+<SHARE_FILE>
+ }
+ }
+)__java_cb";
+
+const char CB_SHARE_FILE_DEF[] =
+R"__java_cb(
+ private void shareFile(List<String> paths) {
+ if (paths == null)
+ throw new InvalidArgumentException();
+
+ for (String path : paths) {
+ shareFile(path);
+ }
+ }
+
+ private void shareFile(String path) {
+ if (path == null)
+ throw new InvalidArgumentException();
+
+ FilePayload fp = new FilePayload();
+ fp.setFilePath(path);
+ super.sendAsync(fp);
+ }
+)__java_cb";
+
+const char CB_CION_JAVA_VERSION[] =
+R"__java_cb(/*
+ * Generated by tidlc $$.
+ */
+)__java_cb";
+
+const char CB_CION_JAVA_EXCEPTION_NotConnectedSocketException[] =
+R"__java_cb(
+public class NotConnectedSocketException extends RuntimeException {}
+)__java_cb";
+
+const char CB_CION_JAVA_EXCEPTION_InvalidProtocolException[] =
+R"__java_cb(
+public class InvalidProtocolException extends RuntimeException {}
+)__java_cb";
+
+const char CB_CION_JAVA_EXCEPTION_InvalidIOException[] =
+R"__java_cb(
+public class InvalidIOException extends RuntimeException {}
+)__java_cb";
+
+const char CB_CION_JAVA_EXCEPTION_PermissionDeniedException[] =
+R"__java_cb(
+public class PermissionDeniedException extends RuntimeException {}
+)__java_cb";
+
+const char CB_CION_JAVA_EXCEPTION_InvalidIDException[] =
+R"__java_cb(
+public class InvalidIDException extends RuntimeException {}
+)__java_cb";
+
+const char CB_CION_JAVA_EXCEPTION_InvalidCallbackException[] =
+R"__java_cb(
+public class InvalidCallbackException extends RuntimeException {}
+)__java_cb";
+
+const char CB_CION_JAVA_EXCEPTION_InvalidArgumentException[] =
+R"__java_cb(
+public class InvalidArgumentException extends RuntimeException {}
+)__java_cb";
+
+#endif // IDLC_GEN_CION_JAVA_CION_GEN_CB_H_
diff --git a/idlc/gen_cion/java_cion_group_gen.cc b/idlc/gen_cion/java_cion_group_gen.cc
new file mode 100644
index 0000000..fc196a2
--- /dev/null
+++ b/idlc/gen_cion/java_cion_group_gen.cc
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/java_cion_group_gen.h"
+
+namespace {
+#include "idlc/gen_cion/java_cion_gen_cb.h"
+#include "idlc/gen_cion/java_cion_group_gen_cb.h"
+}
+
+namespace tidl {
+
+JavaCionGroupGen::JavaCionGroupGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans)
+ : JavaCionGeneratorBase(doc, trans) {}
+
+void JavaCionGroupGen::OnInitGen(std::ofstream& stream) {
+ std::string fname = MakeDir(FileName, "/group");
+ if (fname.empty())
+ return;
+
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ stream.open(fname + "/" + iface.GetID() + ".java");
+ GenVersion(stream);
+ stream << "package org.tizen.gen." << FileName + ".group;" << NLine(2);
+ stream << std::endl;
+
+ stream << "import org.tizen.gen." << FileName + ".common.*;" << NLine(2);
+ stream << GetTransportable().Java().GenInclude() << NLine(1)
+ << "import android.content.Context;" << NLine(1)
+ << "import java.util.ArrayList;" << NLine(1)
+ << "import java.util.LinkedList;" << NLine(1)
+ << "import java.util.List;" << NLine(2);
+
+ GenInterface(stream, iface);
+ stream << NLine(1);
+ stream.close();
+ }
+}
+
+void JavaCionGroupGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void JavaCionGroupGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ stream << "public abstract class " << iface.GetID()
+ << " extends GroupBase ";
+ GenBrace(stream, TAB_SIZE * 0, [&]() {
+ stream << ReplaceAll(CB_DATA_MEMBERS, "<VERSION>", FULLVER);
+ GenMethodId(stream, iface, true);
+ GenCionPayloadReceivedEvent(stream, iface);
+ GenEvents(stream, iface);
+ GenSerializer(stream);
+ GenListSerializer(stream);
+ GenCtor(stream, iface);
+ GenMethods(stream, iface);
+ }, false);
+}
+
+void JavaCionGroupGen::GenEvents(std::ofstream& stream, const Interface& iface) {
+ stream << ReplaceAll(CB_EVENT_METHODS,
+ {
+ { "<ON_LEFT_EVENT_METHOD>",
+ GetTransportable().Java().GenOnLeftEventMethod() },
+ { "<ON_JOINED_EVENT_METHOD>",
+ GetTransportable().Java().GenOnJoinedEventMethod() },
+ { "<PEER_INFO_T>", GetTransportable().Java().GenPeerInfoType() }
+ }) << NLine(1);
+
+ for (const auto& decl : iface.GetDeclarations())
+ GenEvent(stream, iface, *decl);
+
+ stream << NLine(1);
+}
+
+void JavaCionGroupGen::GenEvent(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl) {
+
+ stream << Tab(1) << "/**"<< NLine(1) << Tab(1)
+ << "/* This method will be invoked when the "
+ << decl.GetID() << " request is delivered."
+ << NLine(1) << Tab(1) << "*/" << NLine(1);
+
+ stream << Tab(1) << "public abstract void On" << decl.GetID() << "(" << GetTransportable().Java().GenPeerInfoType() << " peerInfo, ";
+ GenParameters(stream, decl.GetParameters());
+ stream << ");" << NLine(1);
+}
+
+void JavaCionGroupGen::GenCtor(std::ofstream& stream, const Interface& iface) {
+ bool securityCheck = false;
+ std::string security_inst = "new " +
+ GetTransportable().Java().GenSecurityType() + "(";
+
+ for (const auto& attr : iface.GetAttributes()) {
+ if (attr->GetKey() == "ca_path") {
+ security_inst += "\"" + attr->GetValue() + "\", ";
+ securityCheck = true;
+ } else if (attr->GetKey() == "cert_path") {
+ security_inst += "\"" + attr->GetValue() + "\", ";
+ securityCheck = true;
+ } else if (attr->GetKey() == "private_key") {
+ security_inst += "\"" + attr->GetValue() + "\", ";
+ securityCheck = true;
+ }
+ }
+
+ if (securityCheck) {
+ security_inst = security_inst.substr(0, security_inst.find_last_of(','));
+ security_inst += ")";
+ }
+
+ std::string m = GetTransportable().Java().GenInheritedClassConstructor(
+ { "Context context", "String topicName"},
+ (securityCheck ?
+ std::vector<std::string>{ "context", "topicName", security_inst } :
+ std::vector<std::string>{ "context", "topicName" }),
+ { "this.topicName = topicName;" });
+
+ GenTemplate(AddIndent(TAB_SIZE, m), stream,
+ [&]()->std::string {
+ return iface.GetID();
+ });
+}
+
+void JavaCionGroupGen::GenMethods(std::ofstream& stream, const Interface& iface) {
+ auto& decls = iface.GetDeclarations();
+
+ for (const auto& i : decls) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ if (!i->GetComments().empty())
+ stream << AddIndent(TAB_SIZE * 1, i->GetComments());
+
+ stream << NLine(1) << Tab(1) << "public ";
+ GenDeclaration(stream, *i, false);
+ GenBrace(stream, TAB_SIZE * 1, [&]() {
+ GenInvocation(stream, *i);
+ }, false);
+ stream << NLine(1);
+ }
+}
+
+void JavaCionGroupGen::GenCionPayloadReceivedEvent(std::ofstream& stream,
+ const Interface& iface) {
+ stream << ReplaceAll(CB_ON_PAYLOAD_RECEIVED_FRONT, {
+ { "<PEER_INFO_T>", GetTransportable().Java().GenPeerInfoType() },
+ { "<PARCEL>", GetTransportable().Java().GenParcel() }
+ });
+
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE ||
+ i->GetMethodType() == Declaration::MethodType::SYNC)
+ continue;
+ stream << Tab(3) << "case __" << i->GetID() << ":" << NLine(1);
+ GenBrace(stream, TAB_SIZE * 3, [&]() {
+ GenHandlerInvocation(stream, *i);
+ stream << Tab(4) << "break;" << NLine(1);
+ });
+ }
+
+ stream << CB_ON_PAYLOAD_RECEIVED_BACK;
+}
+
+void JavaCionGroupGen::GenHandlerInvocation(std::ofstream& stream,
+ const Declaration& decl) {
+ int cnt = 1;
+ // Deserialize
+ for (const auto& i : decl.GetParameters()) {
+ std::string v = "param" + std::to_string(cnt);
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, "parcelReceived");
+ stream << AddIndent(TAB_SIZE * 4, c);
+ cnt++;
+ }
+
+ // Invoke
+ std::string m;
+ m += "On" + decl.GetID() + "(peerInfo";
+ cnt = 1;
+ for (auto i = decl.GetParameters().begin();
+ i != decl.GetParameters().end(); ++i) {
+ m += ", param" + std::to_string(cnt++);
+ }
+
+ m += ");\n";
+ stream << AddIndent(TAB_SIZE * 4, m);
+}
+
+void JavaCionGroupGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
+ GenTemplate(std::string(ReplaceAll(CB_INVOCATION_PRE,
+ "<PARCEL>", GetTransportable().Java().GenParcel())), stream,
+ [&]()->std::string {
+ std::string st;
+ st += Tab(2)
+ + "p.write(__" + decl.GetID() + ");" + NLine(1);
+ std::string m;
+
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p");
+ }
+
+ st += AddIndent(TAB_SIZE * 2, m)
+ + NLine(1)
+ += Tab(2)
+ + "synchronized (mLock) {"
+ + CB_ASYNC_INVOCATION_MID
+ + Tab(2)
+ + "}";
+
+ return st;
+ });
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/java_cion_group_gen.h b/idlc/gen_cion/java_cion_group_gen.h
new file mode 100644
index 0000000..71dbc99
--- /dev/null
+++ b/idlc/gen_cion/java_cion_group_gen.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_JAVA_CION_GEN_JAVA_GROUP_GEN_H_
+#define IDLC_JAVA_CION_GEN_JAVA_GROUP_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/java_cion_gen_base.h"
+
+namespace tidl {
+
+class JavaCionGroupGen : public JavaCionGeneratorBase {
+ public:
+ explicit JavaCionGroupGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~JavaCionGroupGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenCtor(std::ofstream& stream, const Interface& iface);
+ void GenConnectMethod(std::ofstream& stream, const Interface& iface);
+ void GenMethods(std::ofstream& stream, const Interface& iface);
+ void GenInvocation(std::ofstream& stream, const Declaration& decl);
+ void GenCionPayloadReceivedEvent(std::ofstream& stream,
+ const Interface& iface);
+ void GenEvents(std::ofstream& stream, const Interface& iface);
+ void GenEvent(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl);
+ void GenHandlerInvocation(std::ofstream& stream, const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_JAVA_CION_GEN_JAVA_GROUP_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/java_cion_group_gen_cb.h b/idlc/gen_cion/java_cion_group_gen_cb.h
new file mode 100644
index 0000000..e8cba61
--- /dev/null
+++ b/idlc/gen_cion/java_cion_group_gen_cb.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_JAVA_CION_GEN_JAVA_GROUP_GEN_CB_H_
+#define IDLC_JAVA_CION_GEN_JAVA_GROUP_GEN_CB_H_
+
+
+const char CB_DATA_MEMBERS[] =
+R"__java_cb(
+ public String topicName;
+
+ private static final String sTidlVersion = "<VERSION>";
+
+ private Object mLock = new Object();
+
+)__java_cb";
+
+const char CB_EVENT_METHODS[] =
+R"__java_cb(
+ /**
+ * This method will be invoked when another peer left from the current group.
+ */
+<ON_LEFT_EVENT_METHOD>
+
+ /**
+ * This method will be invoked when another peer joined from the current group.
+ */
+<ON_JOINED_EVENT_METHOD>
+)__java_cb";
+
+const char CB_ON_PAYLOAD_RECEIVED_FRONT[] =
+R"__java_cb( @Override
+ public final void onPayloadReceived(<PEER_INFO_T> peerInfo, IPayload payload) {
+ if(payload.getType() == IPayload.PayloadType.PAYLOAD_FILE) {
+ return;
+ }
+
+ <PARCEL> parcelReceived;
+
+ parcelReceived = new <PARCEL>(((DataPayload)payload).getData());
+ int cmd = parcelReceived.readInt();
+ switch (cmd)
+ {
+)__java_cb";
+
+const char CB_ON_PAYLOAD_RECEIVED_BACK[] =
+R"__java_cb(
+ default:
+ break;
+ }
+ }
+)__java_cb";
+
+const char CB_INVOCATION_PRE[] =
+R"__java_cb( <PARCEL> p = new <PARCEL>();
+$$
+)__java_cb";
+
+const char CB_ASYNC_INVOCATION_MID[] =
+R"__java_cb(
+ // Send
+ DataPayload dp = new DataPayload(p.toByteArray());
+ super.publish(dp);
+)__java_cb";
+
+#endif // IDLC_JAVA_CION_GEN_JAVA_GROUP_GEN_CB_H_
diff --git a/idlc/gen_cion/java_cion_group_repo_gen.cc b/idlc/gen_cion/java_cion_group_repo_gen.cc
new file mode 100644
index 0000000..895cc80
--- /dev/null
+++ b/idlc/gen_cion/java_cion_group_repo_gen.cc
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/java_cion_group_repo_gen.h"
+#include "idlc/gen_cion/java_cion_gen_cb.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <ctime>
+#include <vector>
+
+namespace tidl {
+
+JavaCionGroupRepoGen::JavaCionGroupRepoGen(
+ std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : JavaCionGeneratorBase(doc, trans) {
+}
+
+void JavaCionGroupRepoGen::OnInitGen(std::ofstream& stream) {
+ std::string fname = MakeDir(FileName, "/group");
+ if (fname.empty())
+ return;
+
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ stream.open(fname + "/GroupBase.java");
+ stream << "package org.tizen.gen." << FileName + ".group;" << NLine(2);
+ stream << ReplaceAll(DEFAULT_GROUP_REPO, {
+ { "<INCLUDE>", GetTransportable().Java().GenInclude() },
+ { "<GROUP_BASE_CONSTRUCTOR>",
+ GetTransportable().Java().GenGroupBaseConstructor() },
+ { "<GROUP_CHANNEL>", GetTransportable().Java().GenGroupChannel() },
+ { "<GROUP_SUBSCRIBE>",
+ GetTransportable().Java().GenGroupSubscribe("mGroup") },
+ { "<GROUP_UNSUBSCRIBE>",
+ GetTransportable().Java().GenGroupUnsubscribe("mGroup") },
+ { "<GROUP_PUBLISH>",
+ GetTransportable().Java().GenGroupPublish("mGroup", "data") },
+ { "<SECURITY_T>", GetTransportable().Java().GenSecurityType() }
+ });
+ stream.close();
+ }
+}
+
+void JavaCionGroupRepoGen::OnFiniGen(std::ofstream& stream) {
+}
+
+std::string JavaCionGroupRepoGen::NLine(int cnt) {
+ std::string t;
+
+ for (int i = 0; i < cnt; i++) {
+ t += "\n";
+ }
+
+ return t;
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/java_cion_group_repo_gen.h b/idlc/gen_cion/java_cion_group_repo_gen.h
new file mode 100644
index 0000000..4079e05
--- /dev/null
+++ b/idlc/gen_cion/java_cion_group_repo_gen.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_JAVA_CION_GROUP_REPO_GEN_H_
+#define IDLC_GEN_CION_JAVA_CION_GROUP_REPO_GEN_H_
+
+#include <memory>
+#include <string>
+#include <map>
+
+#include "idlc/gen_cion/java_cion_gen_base.h"
+
+namespace tidl {
+
+class JavaCionGroupRepoGen : public JavaCionGeneratorBase {
+ public:
+ explicit JavaCionGroupRepoGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~JavaCionGroupRepoGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+ std::string NLine(int cnt);
+};
+
+} // namespace tidl
+#endif // IDLC_GEN_CION_JAVA_CION_GROUP_REPO_GEN_H_
diff --git a/idlc/gen_cion/java_cion_proxy_gen.cc b/idlc/gen_cion/java_cion_proxy_gen.cc
new file mode 100644
index 0000000..63f9cb7
--- /dev/null
+++ b/idlc/gen_cion/java_cion_proxy_gen.cc
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/java_cion_proxy_gen.h"
+
+namespace {
+#include "idlc/gen_cion/java_cion_gen_cb.h"
+#include "idlc/gen_cion/java_cion_proxy_gen_cb.h"
+}
+
+namespace tidl {
+
+JavaCionProxyGen::JavaCionProxyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans)
+ : JavaCionGeneratorBase(doc, trans) {}
+
+void JavaCionProxyGen::OnInitGen(std::ofstream& stream) {
+ std::string fname = MakeDir(FileName, "/client");
+ if (fname.empty())
+ return;
+
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ stream.open(fname + "/" + iface.GetID() + ".java");
+ GenVersion(stream);
+ stream << "package org.tizen.gen." << FileName + ".client;" << NLine(2);
+ stream << std::endl;
+
+ stream << "import org.tizen.gen." << FileName + ".common.*;" << NLine(2);
+ stream << GetTransportable().Java().GenInclude() << NLine(1)
+ << "import android.content.Context;" << NLine(1)
+ << "import java.util.ArrayList;" << NLine(1)
+ << "import java.util.LinkedList;" << NLine(1)
+ << "import java.util.List;" << NLine(2);
+
+ GenInterface(stream, iface);
+ stream << NLine(1);
+ stream.close();
+ }
+}
+
+void JavaCionProxyGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void JavaCionProxyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ stream << "public class " << iface.GetID()
+ << " extends ClientBase ";
+ GenBrace(stream, TAB_SIZE * 0, [&]() {
+ stream << ReplaceAll(CB_DATA_MEMBERS, "<VERSION>", FULLVER);
+ GenCallbacks(stream, iface, true);
+ GenDelegateId(stream, iface);
+ GenMethodId(stream, iface);
+ stream << ReplaceAll(CB_EVENT_METHODS, {
+ { "<PEER_INFO_T>", GetTransportable().Java().GenPeerInfoType() },
+ { "<PARCEL>", GetTransportable().Java().GenParcel() },
+ });
+ GenSerializer(stream);
+ GenListSerializer(stream);
+ GenShareFile(stream, iface, true);
+ GenCtor(stream, iface);
+ GenConnectMethod(stream, iface);
+ GenMethods(stream, iface);
+ }, false);
+}
+
+void JavaCionProxyGen::GenCtor(std::ofstream& stream, const Interface& iface) {
+ bool securityCheck = false;
+ std::string security_inst = "new " +
+ GetTransportable().Java().GenSecurityType() + "(";
+
+ for (const auto& attr : iface.GetAttributes()) {
+ if (attr->GetKey() == "ca_path") {
+ security_inst += "\"" + attr->GetValue() + "\", ";
+ securityCheck = true;
+ } else if (attr->GetKey() == "cert_path") {
+ security_inst += "\"" + attr->GetValue() + "\", ";
+ securityCheck = true;
+ } else if (attr->GetKey() == "private_key") {
+ security_inst += "\"" + attr->GetValue() + "\", ";
+ securityCheck = true;
+ }
+ }
+
+ if (securityCheck) {
+ security_inst = security_inst.substr(0, security_inst.find_last_of(','));
+ security_inst += ")";
+ }
+
+ std::string m = GetTransportable().Java().GenInheritedClassConstructor(
+ { "Context context", "String serviceName" },
+ (securityCheck ?
+ std::vector<std::string>{ "context", "serviceName", security_inst } :
+ std::vector<std::string>{ "context", "serviceName"}),
+ { "this.serviceName = serviceName;" });
+
+ GenTemplate(AddIndent(TAB_SIZE, m), stream,
+ [&]()->std::string {
+ return iface.GetID();
+ });
+}
+
+void JavaCionProxyGen::GenConnectMethod(std::ofstream& stream,
+ const Interface& iface) {
+ stream << CB_CONNECT_METHOD;
+ stream << NLine(1);
+}
+
+void JavaCionProxyGen::GenMethods(std::ofstream& stream, const Interface& iface) {
+ auto& decls = iface.GetDeclarations();
+
+ for (const auto& i : decls) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ if (!i->GetComments().empty())
+ stream << AddIndent(TAB_SIZE * 1, i->GetComments());
+
+ stream << Tab(1) << "public ";
+ GenDeclaration(stream, *i, false);
+ GenBrace(stream, TAB_SIZE * 1, [&]() {
+ GenInvocation(stream, *i);
+ }, false);
+ stream << NLine(1);
+ }
+}
+
+void JavaCionProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
+ GenTemplate(std::string(ReplaceAll(CB_INVOCATION_PRE, "<PARCEL>",
+ GetTransportable().Java().GenParcel())), stream,
+ [&]()->std::string {
+ std::string st;
+ st += Tab(2)
+ + "p.write(__" + decl.GetID() + ");" + NLine(1);
+ std::string m;
+ std::string l;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT)
+ continue;
+ std::string id = i->GetID();
+ if (pt.GetDirection() == ParameterType::Direction::REF)
+ id += ".get()";
+ m += ConvertTypeToSerializer(pt.GetBaseType(), id, "p");
+ if (IsDelegateType(pt.GetBaseType())) {
+ l += "mDelegateList.add(" + id + ");\n";
+ }
+ }
+
+ st += AddIndent(TAB_SIZE * 2, m) + NLine(1);
+
+ st += Tab(2) + "synchronized (mLock) {" + NLine(1);
+ if (!l.empty())
+ st += AddIndent(TAB_SIZE * 3, l) + NLine(1);
+
+ // Deserialize
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
+ st += CB_ASYNC_INVOCATION_MID;
+ } else {
+ st += ReplaceAll(CB_SYNC_INVOCATION_MID,
+ "<PARCEL>", GetTransportable().Java().GenParcel());
+ }
+
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT)
+ continue;
+
+ if (pt.GetBaseType().ToString() == "file" ||
+ (pt.GetBaseType().GetMetaType() != nullptr &&
+ pt.GetBaseType().GetMetaType()->ToString() == "file")) {
+ st += GenTemplateString(CB_SHARE_FILE, [&]()->std::string {
+ std::string str = "";
+ str += Tab(3) + "shareFile(" + i->GetID() + ");";
+ return str;
+ });
+ }
+ }
+
+ // Deserialize
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
+ st += Tab(2) + "}";
+ return st;
+ }
+
+ for (const auto& i : decl.GetParameters()) {
+ if (i->GetParameterType().GetDirection() ==
+ ParameterType::Direction::IN) {
+ continue;
+ }
+
+ // Out or Ref
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(),
+ i->GetID() + "_raw", "parcelReceived", true, "", true);
+ c += i->GetID() + ".set(" + i->GetID() + "_raw);" + NLine(1);
+
+ if (c != "")
+ st += AddIndent(TAB_SIZE * 3, c);
+ }
+
+ if (decl.GetType().ToString() != "void") {
+ st += AddIndent(TAB_SIZE * 3, ConvertTypeToDeserializer(decl.GetType(),
+ "ret", "parcelReceived"));
+ }
+
+ st += NLine(1) + Tab(3) + "return ret;" + NLine(1);
+ st += Tab(2) + "}";
+
+ return st;
+ });
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/java_cion_proxy_gen.h b/idlc/gen_cion/java_cion_proxy_gen.h
new file mode 100644
index 0000000..238fd4e
--- /dev/null
+++ b/idlc/gen_cion/java_cion_proxy_gen.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_JAVA_CION_GEN_JAVA_PROXY_GEN_H_
+#define IDLC_JAVA_CION_GEN_JAVA_PROXY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/java_cion_gen_base.h"
+
+namespace tidl {
+
+class JavaCionProxyGen : public JavaCionGeneratorBase {
+ public:
+ explicit JavaCionProxyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~JavaCionProxyGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenCtor(std::ofstream& stream, const Interface& iface);
+ void GenConnectMethod(std::ofstream& stream, const Interface& iface);
+ void GenMethods(std::ofstream& stream, const Interface& iface);
+ void GenInvocation(std::ofstream& stream, const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_JAVA_CION_GEN_JAVA_PROXY_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/java_cion_proxy_gen_cb.h b/idlc/gen_cion/java_cion_proxy_gen_cb.h
new file mode 100644
index 0000000..a68fec5
--- /dev/null
+++ b/idlc/gen_cion/java_cion_proxy_gen_cb.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_JAVA_CION_GEN_JAVA_PROXY_GEN_CB_H_
+#define IDLC_JAVA_CION_GEN_JAVA_PROXY_GEN_CB_H_
+
+
+const char CB_DATA_MEMBERS[] =
+R"__java_cb(
+ public String serviceName;
+
+ private static final String sTidlVersion = "<VERSION>";
+
+ private boolean mOnline = false;
+
+ private Object mLock = new Object();
+
+ private List<DelegatorBase> mDelegateList = new LinkedList<DelegatorBase>();
+)__java_cb";
+
+const char CB_EVENT_METHODS[] =
+R"__java_cb(
+ private void processReceivedEvent(<PARCEL> parcel) {
+ int id = parcel.readInt();
+ int seqId = parcel.readInt();
+ boolean once = parcel.readBoolean();
+
+ for (DelegatorBase i : mDelegateList) {
+ if (i.getDelegateId() == id && i.getSequenceId() == seqId) {
+ i.onInvoked(parcel);
+ if (i.isOnce())
+ mDelegateList.remove(i);
+ break;
+ }
+ }
+ }
+
+ /**
+ * This method will be invoked when this client gets the response from the server
+ * @param peerInfo Server information
+ * @param result Connection result
+ */
+ @Override
+ public void onConnectionResult(<PEER_INFO_T> peerInfo, ConnectionResult result) {
+ if (result.status == ConnectionResult.ConnectionStatus.CONNECTION_OK) {
+ mOnline = true;
+ }
+ }
+
+ /**
+ * This method will be invoked when this client is disconnected from the server
+ * @param peerInfo Server information
+ */
+ @Override
+ public void onDisconnected(<PEER_INFO_T> peerInfo) {
+ mOnline = false;
+ }
+
+ /**
+ * This method will be invoked when an available server is discovered
+ * @param peerInfo Server information
+ */
+ @Override
+ public void onDiscovered(<PEER_INFO_T> peerInfo) {
+ }
+
+ @Override
+ public final void onResultReceived(PayloadAsyncResult payloadAsyncResult) {
+ }
+
+ @Override
+ public final void onPayloadReceived(IPayload payload, PayloadTransferStatus status) {
+ if(payload.getType() == IPayload.PayloadType.PAYLOAD_FILE) {
+ onFileReceived((FilePayload)payload, status);
+ } else {
+ <PARCEL> parcelReceived;
+
+ parcelReceived = new <PARCEL>(((DataPayload)payload).getData());
+ int cmd = parcelReceived.readInt();
+ if (cmd != __CALLBACK)
+ return;
+
+ processReceivedEvent(parcelReceived);
+ }
+ }
+
+ /**
+ * This method will be invoked when data for a file is received from the server
+ * @param payload File data
+ * @param status Status
+ */
+ public void onFileReceived(FilePayload payload, PayloadTransferStatus status) {}
+
+)__java_cb";
+
+const char CB_CONNECT_METHOD[] =
+R"__java_cb(
+ /**
+ * Disposes delegate objects in this interface
+ * @param tag String handle
+ */
+ public void disposeCallback(String tag) {
+ for (DelegatorBase i : mDelegateList) {
+ if (i.getTag().equals(tag)) {
+ mDelegateList.remove(i);
+ return;
+ }
+ }
+ }
+)__java_cb";
+
+const char CB_INVOCATION_PRE[] =
+R"__java_cb( if (!mOnline)
+ throw new NotConnectedSocketException();
+
+ <PARCEL> p = new <PARCEL>();
+$$
+)__java_cb";
+
+const char CB_SHARE_FILE[] =
+R"__java_cb(
+ try {
+$$
+ } catch (InvalidArgumentException e) {
+ }
+)__java_cb";
+
+const char CB_ASYNC_INVOCATION_MID[] =
+R"__java_cb(
+ // Send
+ DataPayload dp = new DataPayload(p.toByteArray());
+ super.sendAsync(dp);
+)__java_cb";
+
+const char CB_SYNC_INVOCATION_MID[] =
+R"__java_cb(
+ // Send
+ byte[] dataReceived = sendData(p.toByteArray());
+
+ <PARCEL> parcelReceived = new <PARCEL>(dataReceived);
+
+ int cmd = parcelReceived.readInt();
+ if (cmd != __RESULT)
+ throw new InvalidProtocolException();
+)__java_cb";
+#endif // IDLC_JAVA_CION_GEN_JAVA_PROXY_GEN_CB_H_
diff --git a/idlc/gen_cion/java_cion_proxy_repo_gen.cc b/idlc/gen_cion/java_cion_proxy_repo_gen.cc
new file mode 100644
index 0000000..80fd2a1
--- /dev/null
+++ b/idlc/gen_cion/java_cion_proxy_repo_gen.cc
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/java_cion_proxy_repo_gen.h"
+#include "idlc/gen_cion/java_cion_gen_cb.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <ctime>
+#include <vector>
+
+namespace tidl {
+
+JavaCionProxyRepoGen::JavaCionProxyRepoGen(
+ std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : JavaCionGeneratorBase(doc, trans) {
+}
+
+void JavaCionProxyRepoGen::OnInitGen(std::ofstream& stream) {
+ std::string fname = MakeDir(FileName, "/client");
+ if (fname.empty())
+ return;
+
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ stream.open(fname + "/ClientBase.java");
+ stream << "package org.tizen.gen." << FileName + ".client;" << NLine(2);
+ stream << ReplaceAll(DEFAULT_PROXY_REPO, {
+ { "<INCLUDE>", GetTransportable().Java().GenInclude() },
+ { "<PEER_INFO_T>", GetTransportable().Java().GenPeerInfoType() },
+ { "<CLIENT_BASE_CONSTRUCTOR>",
+ GetTransportable().Java().GenClientBaseConstructor() },
+ { "<CLIENT_CHANNEL>", GetTransportable().Java().GenClientChannel() },
+ { "<CLIENT_SEND_ASYNC>", GetTransportable().Java()
+ .GenClientSendAsync("mClient", "payload") },
+ { "<CLIENT_SEND>", GetTransportable().Java()
+ .GenClientSend("mClient", "data", "5000") },
+ { "<CLIENT_DISCONNECT>", GetTransportable().Java()
+ .GenClientDisconnect("mClient") },
+ { "<CLIENT_TRY_CONNECT>", GetTransportable().Java()
+ .GenClientTryConnect("mClient", "peer") },
+ { "<CLIENT_TRY_DISCOVERY>", GetTransportable().Java()
+ .GenClientTryDiscovery("mClient") },
+ { "<CLIENT_STOP_DISCOVERY>", GetTransportable().Java()
+ .GenClientStopDiscovery("mClient") },
+ { "<SECURITY_T>", GetTransportable().Java().GenSecurityType() }
+ });
+ stream.close();
+ }
+}
+
+void JavaCionProxyRepoGen::OnFiniGen(std::ofstream& stream) {
+}
+
+std::string JavaCionProxyRepoGen::NLine(int cnt) {
+ std::string t;
+
+ for (int i = 0; i < cnt; i++) {
+ t += "\n";
+ }
+
+ return t;
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/java_cion_proxy_repo_gen.h b/idlc/gen_cion/java_cion_proxy_repo_gen.h
new file mode 100644
index 0000000..6659350
--- /dev/null
+++ b/idlc/gen_cion/java_cion_proxy_repo_gen.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_JAVA_CION_PROXY_REPO_GEN_H_
+#define IDLC_GEN_CION_JAVA_CION_PROXY_REPO_GEN_H_
+
+#include <memory>
+#include <string>
+#include <map>
+
+#include "idlc/gen_cion/java_cion_gen_base.h"
+
+namespace tidl {
+
+class JavaCionProxyRepoGen : public JavaCionGeneratorBase {
+ public:
+ explicit JavaCionProxyRepoGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~JavaCionProxyRepoGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+ std::string NLine(int cnt);
+};
+
+} // namespace tidl
+#endif // IDLC_GEN_CION_JAVA_CION_PROXY_REPO_GEN_H_
diff --git a/idlc/gen_cion/java_cion_structure_gen.cc b/idlc/gen_cion/java_cion_structure_gen.cc
new file mode 100644
index 0000000..d40cf2d
--- /dev/null
+++ b/idlc/gen_cion/java_cion_structure_gen.cc
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/java_cion_structure_gen.h"
+#include "idlc/gen_cion/java_cion_gen_cb.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <ctime>
+#include <vector>
+
+namespace tidl {
+
+JavaCionStructureGen::JavaCionStructureGen(
+ std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : JavaCionGeneratorBase(doc, trans) {
+}
+
+void JavaCionStructureGen::OnInitGen(std::ofstream& stream) {
+ std::string fname = MakeDir(FileName, "/common");
+ if (fname.empty())
+ return;
+
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_STRUCTURE)
+ continue;
+ Structure& st = static_cast<Structure&>(*i);
+ stream.open(fname + "/" + st.GetID() + ".java");
+ stream << "package org.tizen.gen." << FileName + ".common;" << NLine(2);
+ GenStructure(stream, st);
+ stream << std::endl;
+ stream.close();
+ }
+}
+
+void JavaCionStructureGen::GenStructure(std::ofstream& stream,
+ const Structure& st) {
+ const char variable[] = "$$\n";
+
+ stream << GetTransportable().Java().GenParcelInclude() << NLine(1);
+ stream << "import java.util.ArrayList;" << NLine(1);
+ stream << "import java.util.LinkedList;" << NLine(1);
+ stream << NLine(1);
+ stream << "public final class " << st.GetID() << " ";
+ GenBrace(stream, 0, [&]() {
+ GenTemplate(variable, stream,
+ [&]()->std::string {
+ std::string str;
+ for (const auto& i : st.GetElements()) {
+ str += NLine(1) + Tab(1) + "private ";
+ if (i->GetType().GetMetaType() == nullptr) {
+ str += ConvertTypeToString(i->GetType()) + " "
+ + i->GetID() + "_;";
+ } else {
+ str += ConvertTypeToString(i->GetType()) + " "
+ + i->GetID() + "_ = new "
+ + ConvertTypeToString(i->GetType()) + "();";
+ }
+ str += NLine(1);
+ }
+
+ return str;
+ });
+
+ for (const auto& i : st.GetElements()) {
+ GenSetter(stream, *i);
+ GenGetter(stream, *i);
+ stream << NLine(1);
+ }
+ }, false, false);
+ stream << NLine(1);
+}
+
+void JavaCionStructureGen::GenSetter(std::ofstream& stream,
+ const Element& ele) {
+ const char setter[] =
+ "public void set$$($$ $$) {\n" \
+ " $$_ = $$;\n" \
+ "}\n";
+
+ GenTemplate(AddIndent(TAB_SIZE, setter, true), stream,
+ [&]()->std::string {
+ return ele.GetID();
+ },
+ [&]()->std::string {
+ return ConvertTypeToString(ele.GetType());
+ },
+ [&]()->std::string {
+ return ele.GetID();
+ },
+ [&]()->std::string {
+ return ele.GetID();
+ },
+ [&]()->std::string {
+ return ele.GetID();
+ });
+ stream << NLine(1);
+}
+
+void JavaCionStructureGen::GenGetter(std::ofstream& stream,
+ const Element& ele) {
+ const char getter[] =
+ "public $$ get$$() {\n" \
+ " return $$_;\n" \
+ "}\n";
+
+ GenTemplate(AddIndent(TAB_SIZE, getter, true), stream,
+ [&]()->std::string {
+ return ConvertTypeToString(ele.GetType());
+ },
+ [&]()->std::string {
+ return ele.GetID();
+ },
+ [&]()->std::string {
+ return ele.GetID();
+ });
+}
+
+void JavaCionStructureGen::OnFiniGen(std::ofstream& stream) {
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/java_cion_structure_gen.h b/idlc/gen_cion/java_cion_structure_gen.h
new file mode 100644
index 0000000..0902da1
--- /dev/null
+++ b/idlc/gen_cion/java_cion_structure_gen.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_JAVA_CION_STRUCTURE_GEN_H_
+#define IDLC_GEN_CION_JAVA_CION_STRUCTURE_GEN_H_
+
+#include <memory>
+#include <string>
+#include <map>
+
+#include "idlc/gen_cion/java_cion_gen_base.h"
+
+namespace tidl {
+
+class JavaCionStructureGen : public JavaCionGeneratorBase {
+ public:
+ explicit JavaCionStructureGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~JavaCionStructureGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+ void GenStructure(std::ofstream& stream,
+ const Structure& st);
+ void GenSetter(std::ofstream& stream, const Element& ele);
+ void GenGetter(std::ofstream& stream, const Element& ele);
+};
+
+} // namespace tidl
+#endif // IDLC_GEN_CION_JAVA_CION_STRUCTURE_GEN_H_
diff --git a/idlc/gen_cion/java_cion_stub_gen.cc b/idlc/gen_cion/java_cion_stub_gen.cc
new file mode 100644
index 0000000..d547cba
--- /dev/null
+++ b/idlc/gen_cion/java_cion_stub_gen.cc
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/java_cion_stub_gen.h"
+
+namespace {
+#include "idlc/gen_cion/java_cion_gen_cb.h"
+#include "idlc/gen_cion/java_cion_stub_gen_cb.h"
+}
+
+namespace tidl {
+
+JavaCionStubGen::JavaCionStubGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : JavaCionGeneratorBase(doc, trans) {}
+
+void JavaCionStubGen::OnInitGen(std::ofstream& stream) {
+ std::string fname = MakeDir(FileName, "/server");
+ if (fname.empty())
+ return;
+
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+ Interface& iface = static_cast<Interface&>(*i);
+ stream.open(fname + "/" + iface.GetID() + ".java");
+ GenVersion(stream);
+ stream << NLine(1);
+ stream << "package org.tizen.gen." << FileName + ".server;" << NLine(2);
+ stream << std::endl;
+
+ stream << "import org.tizen.gen." << FileName + ".common.*;" << NLine(2);
+ stream << GetTransportable().Java().GenInclude() << NLine(1)
+ << "import android.content.Context;" << NLine(1)
+ << "import java.lang.ref.WeakReference;" << NLine(1)
+ << "import java.util.ArrayList;" << NLine(1)
+ << "import java.util.LinkedList;" << NLine(1)
+ << "import java.util.List;" << NLine(2);
+ GenInterface(stream, iface);
+ stream.close();
+ }
+}
+
+void JavaCionStubGen::OnFiniGen(std::ofstream& stream) {}
+
+void JavaCionStubGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ stream << "public class " << iface.GetID()
+ << " extends ServerBase ";
+ GenBrace(stream, TAB_SIZE * 0, [&]() {
+ stream << ReplaceAll(CB_DATA_MEMBERS, "<VERSION>", FULLVER);
+ GenMethodId(stream, iface);
+ GenDelegateId(stream, iface);
+ GenServiceBase(stream, iface);
+ GenCallbacks(stream, iface, false);
+ GenSerializer(stream);
+ GenListSerializer(stream);
+ GenReceivedAsyncEvent(stream, iface);
+ GenReceivedSyncEvent(stream, iface);
+ GenConnectionRequestedEvent(stream);
+ GenDisconnectedEvent(stream);
+ GenConnectedEvent(stream);
+ GenShareFile(stream, iface, false);
+ GenCtor(stream, iface);
+ GenCommonMethods(stream);
+ }, false);
+}
+
+void JavaCionStubGen::GenServiceBase(std::ofstream& stream, const Interface& iface) {
+ stream << ReplaceAll(CB_SERVICE_BASE_FRONT,
+ "<PEER_INFO_T>", GetTransportable().Java().GenPeerInfoType());
+ GenDeclarations(stream, iface.GetDeclarations());
+ stream << AddIndent(TAB_SIZE * 1, "}\n");
+}
+
+void JavaCionStubGen::GenDeclarations(std::ofstream& stream,
+ const Declarations& decls) {
+ for (const auto& i : decls) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+ if (!i->GetComments().empty())
+ stream << NLine(1) << AddIndent(TAB_SIZE * 2, i->GetComments());
+ stream << Tab(2) << "public abstract ";
+ GenDeclaration(stream, *i);
+ stream << NLine(2);
+ }
+}
+
+void JavaCionStubGen::GenReceivedSyncEvent(std::ofstream& stream,
+ const Interface& iface) {
+ stream << ReplaceAll(CB_ON_RECEIVED_SYNC_EVENT_FRONT, {
+ { "<PEER_INFO_T>", GetTransportable().Java().GenPeerInfoType() },
+ { "<PEER_INFO_GET_APPID1>",
+ GetTransportable().Java().GenPeerInfoGetAppID("i.mClient") },
+ { "<PEER_INFO_GET_APPID2>",
+ GetTransportable().Java().GenPeerInfoGetAppID("info") },
+ { "<PEER_INFO_GET_UUID1>",
+ GetTransportable().Java().GenPeerInfoGetUUID("i.mClient") },
+ { "<PEER_INFO_GET_UUID2>",
+ GetTransportable().Java().GenPeerInfoGetUUID("info") },
+ { "<PARCEL>", GetTransportable().Java().GenParcel() }
+ });
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::SYNC)
+ continue;
+ stream << Tab(4) << "case __" << i->GetID() << ": ";
+ GenBrace(stream, TAB_SIZE * 5, [&]() {
+ GenSyncInvocation(stream, *i);
+ stream << Tab(5) << "break;" << NLine(1);
+ }, false);
+ }
+ stream << CB_ON_RECEIVED_SYNC_EVENT_BACK;
+}
+
+void JavaCionStubGen::GenReceivedAsyncEvent(std::ofstream& stream,
+ const Interface& iface) {
+ stream << ReplaceAll(CB_ON_RECEIVED_ASYNC_EVENT_FRONT, {
+ { "<PEER_INFO_T>", GetTransportable().Java().GenPeerInfoType() },
+ { "<PEER_INFO_GET_APPID1>",
+ GetTransportable().Java().GenPeerInfoGetAppID("i.mClient") },
+ { "<PEER_INFO_GET_APPID2>",
+ GetTransportable().Java().GenPeerInfoGetAppID("info") },
+ { "<PEER_INFO_GET_UUID1>",
+ GetTransportable().Java().GenPeerInfoGetUUID("i.mClient") },
+ { "<PEER_INFO_GET_UUID2>",
+ GetTransportable().Java().GenPeerInfoGetUUID("info") },
+ { "<PARCEL>", GetTransportable().Java().GenParcel() }
+ });
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::ASYNC)
+ continue;
+ stream << Tab(4) << "case __" << i->GetID() << ": ";
+ GenBrace(stream, TAB_SIZE * 5, [&]() {
+ GenAsyncInvocation(stream, *i);
+ stream << Tab(5) << "break;" << NLine(1);
+ }, false);
+ }
+ stream << CB_ON_RECEIVED_ASYNC_EVENT_BACK;
+}
+
+void JavaCionStubGen::GenSyncInvocation(std::ofstream& stream, const Declaration& decl) {
+ bool hasRet = GenAsyncInvocation(stream, decl);
+
+ // Serialize
+ int cnt = 0;
+ std::string m = CB_INVOCATION_RESULT_PRE;
+ for (const auto& i : decl.GetParameters()) {
+ auto& pt = i->GetParameterType();
+ cnt++;
+ if (pt.GetDirection() == ParameterType::Direction::IN)
+ continue;
+ m += ConvertTypeToSerializer(pt.GetBaseType(),
+ "ref_param" + std::to_string(cnt) + ".get()", "result");
+
+ if (HasFile(pt.GetBaseType())) {
+ m += "shareFile(ref_param" + std::to_string(cnt) + ".get());\n\n";
+ }
+ }
+
+ if (hasRet) {
+ m += ConvertTypeToSerializer(decl.GetType(), "retVal", "result");
+ if (HasFile(decl.GetType())) {
+ m += "shareFile(retVal);\n";
+ }
+ }
+
+ m += "\nreturnData = result.toByteArray();\n";
+
+ stream << AddIndent(TAB_SIZE * 5, m);
+}
+
+bool JavaCionStubGen::GenAsyncInvocation(std::ofstream& stream, const Declaration& decl) {
+ int cnt = 1;
+
+ // Deserialize
+ for (const auto& i : decl.GetParameters()) {
+ std::string v = "param" + std::to_string(cnt);
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::OUT) {
+ std::string mt = "Out<" + ConvertTypeToString(pt.GetBaseType(), true) + ">";
+ mt += " ref_" + v + " = new " + mt + "();\n";
+ stream << AddIndent(TAB_SIZE * 5, mt);
+ cnt++;
+ continue;
+ }
+
+ std::string c = ConvertTypeToDeserializer(
+ i->GetParameterType().GetBaseType(), v, "p");
+ stream << AddIndent(TAB_SIZE * 5, c);
+
+ if (pt.GetDirection() == ParameterType::Direction::REF) {
+ std::string mt = "Ref<" + ConvertTypeToString(pt.GetBaseType(), true) + ">";
+ mt += " ref_" + v + " = new " + mt + "(" + v + ");\n";
+ stream << AddIndent(TAB_SIZE * 5, mt);
+ }
+
+ cnt++;
+ }
+
+ // Invoke
+ cnt = 1;
+ std::string m;
+
+ bool hasRet = false;
+ if (decl.GetType().ToString() != "void") {
+ m += ConvertTypeToString(decl.GetType()) + " retVal = ";
+ hasRet = true;
+ }
+
+ m += "b." + decl.GetID() + "(";
+ for (const auto& i : decl.GetParameters()) {
+ if (cnt != 1) {
+ m += ", ";
+ }
+
+ std::string v;
+ auto& pt = i->GetParameterType();
+ if (pt.GetDirection() == ParameterType::Direction::REF ||
+ pt.GetDirection() == ParameterType::Direction::OUT) {
+ v = "ref_";
+ }
+
+ m += v + "param" + std::to_string(cnt);
+ cnt++;
+ }
+
+ m += ");\n";
+ stream << AddIndent(TAB_SIZE * 5, m);
+
+ return hasRet;
+}
+
+void JavaCionStubGen::GenConnectionRequestedEvent(std::ofstream& stream) {
+ stream << ReplaceAll(CB_ON_CONNECTIONREQUESTED_EVENT,
+ "<PEER_INFO_T>", GetTransportable().Java().GenPeerInfoType());
+}
+
+void JavaCionStubGen::GenConnectedEvent(std::ofstream& stream) {
+ stream << ReplaceAll(CB_ON_CONNECTED_EVENT, {
+ { "<PEER_INFO_T>", GetTransportable().Java().GenPeerInfoType() },
+ { "<PEER_INFO_GET_APPID1>", GetTransportable().Java()
+ .GenPeerInfoGetAppID("i.mConnectionRequestClient") },
+ { "<PEER_INFO_GET_APPID2>", GetTransportable().Java()
+ .GenPeerInfoGetAppID("peerInfo") },
+ { "<PEER_INFO_GET_UUID1>", GetTransportable().Java()
+ .GenPeerInfoGetUUID("i.mConnectionRequestClient") },
+ { "<PEER_INFO_GET_UUID2>", GetTransportable().Java()
+ .GenPeerInfoGetUUID("peerInfo") },
+ });
+}
+
+void JavaCionStubGen::GenDisconnectedEvent(std::ofstream& stream) {
+ stream << ReplaceAll(CB_ON_DISCONNECTED_EVENT, {
+ { "<PEER_INFO_T>", GetTransportable().Java().GenPeerInfoType() },
+ { "<PEER_INFO_GET_APPID1>",
+ GetTransportable().Java().GenPeerInfoGetAppID("i.mClient") },
+ { "<PEER_INFO_GET_APPID2>",
+ GetTransportable().Java().GenPeerInfoGetAppID("peerInfo") },
+ { "<PEER_INFO_GET_UUID1>",
+ GetTransportable().Java().GenPeerInfoGetUUID("i.mClient") },
+ { "<PEER_INFO_GET_UUID2>",
+ GetTransportable().Java().GenPeerInfoGetUUID("peerInfo") },
+ });
+}
+
+void JavaCionStubGen::GenCtor(std::ofstream& stream, const Interface& iface) {
+ bool securityCheck = false;
+ std::string security_inst = "new " +
+ GetTransportable().Java().GenSecurityType() + "(";
+
+ for (const auto& attr : iface.GetAttributes()) {
+ if (attr->GetKey() == "ca_path") {
+ security_inst += "\"" + attr->GetValue() + "\", ";
+ securityCheck = true;
+ } else if (attr->GetKey() == "cert_path") {
+ security_inst += "\"" + attr->GetValue() + "\", ";
+ securityCheck = true;
+ } else if (attr->GetKey() == "private_key") {
+ security_inst += "\"" + attr->GetValue() + "\", ";
+ securityCheck = true;
+ }
+ }
+
+ if (securityCheck) {
+ security_inst = security_inst.substr(0, security_inst.find_last_of(','));
+ security_inst += ")";
+ }
+
+ std::string m = GetTransportable().Java().GenInheritedClassConstructor(
+ { "Context context", "String serviceName", "String displayName" },
+ (securityCheck ?
+ std::vector<std::string>{ "context", "serviceName",
+ "displayName", security_inst } :
+ std::vector<std::string>{ "context", "serviceName", "displayName"}),
+ {});
+
+ GenTemplate(AddIndent(TAB_SIZE * 1, m), stream,
+ [&]()->std::string {
+ return iface.GetID();
+ });
+}
+
+void JavaCionStubGen::GenCommonMethods(std::ofstream& stream) {
+ stream << CB_COMMON_METHODS;
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/java_cion_stub_gen.h b/idlc/gen_cion/java_cion_stub_gen.h
new file mode 100644
index 0000000..2526f1b
--- /dev/null
+++ b/idlc/gen_cion/java_cion_stub_gen.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_JAVA_CION_GEN_JAVA_STUB_GEN_H_
+#define IDLC_JAVA_CION_GEN_JAVA_STUB_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/java_cion_gen_base.h"
+
+namespace tidl {
+
+class JavaCionStubGen : public JavaCionGeneratorBase {
+ public:
+ explicit JavaCionStubGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~JavaCionStubGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenServiceBase(std::ofstream& stream, const Interface& iface);
+ void GenReceivedAsyncEvent(std::ofstream& stream, const Interface& iface);
+ void GenReceivedSyncEvent(std::ofstream& stream, const Interface& iface);
+ void GenConnectionRequestedEvent(std::ofstream& stream);
+ void GenConnectedEvent(std::ofstream& stream);
+ void GenDisconnectedEvent(std::ofstream& stream);
+ void GenCtor(std::ofstream& stream, const Interface& iface);
+ void GenCommonMethods(std::ofstream& stream);
+ void GenDeclarations(std::ofstream& stream, const Declarations& decls);
+ void GenSyncInvocation(std::ofstream& stream, const Declaration& decl);
+ bool GenAsyncInvocation(std::ofstream& stream, const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_JAVA_CION_GEN_JAVA_STUB_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen_cion/java_cion_stub_gen_cb.h b/idlc/gen_cion/java_cion_stub_gen_cb.h
new file mode 100644
index 0000000..c434eac
--- /dev/null
+++ b/idlc/gen_cion/java_cion_stub_gen_cb.h
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_JAVA_CION_GEN_JAVA_STUB_GEN_CB_H_
+#define IDLC_JAVA_CION_GEN_JAVA_STUB_GEN_CB_H_
+
+const char CB_DATA_MEMBERS[] =
+R"__java_cb( private List<ServiceBase> mServices = new LinkedList<ServiceBase>();
+
+ private Class<?> mServiceType;
+
+ private static final String sTidlVersion = "<VERSION>";
+
+)__java_cb";
+
+const char CB_SERVICE_BASE_FRONT[] =
+R"__java_cb(
+ /**
+ * Abstract class for making a service
+ */
+ public static abstract class ServiceBase {
+ private String mServiceName;
+
+ private String mDisplayName;
+
+ private <PEER_INFO_T> mClient;
+
+ private <PEER_INFO_T> mConnectionRequestClient;
+
+ private ServerBase mServerBase;
+
+ /**
+ * Gets server object
+ * @return Server object
+ */
+ public ServerBase getServer() {
+ return mServerBase;
+ }
+
+ /**
+ * Gets service name
+ * @return Service name
+ */
+ public String getServiceName() {
+ return mServiceName;
+ }
+
+ /**
+ * Gets display name
+ * @return Display name
+ */
+ public String getDisplayName() {
+ return mDisplayName;
+ }
+
+ /**
+ * Gets client information
+ * @return Client information
+ */
+ public <PEER_INFO_T> getClient() {
+ return mClient;
+ }
+
+ protected ServiceBase() {}
+
+ /**
+ * Disconnects from the client app
+ */
+ public void disconnect() {
+ if (mClient != null)
+ mServerBase.disconnect(mClient);
+ }
+
+ /**
+ * Accepts the connection request from the client
+ */
+ public void accept() {
+ if (mConnectionRequestClient != null)
+ mServerBase.accept(mConnectionRequestClient);
+ }
+
+ /**
+ * Rejects the connection request from the client
+ * @param reason The season
+ */
+ public void reject(String reason) {
+ if (mConnectionRequestClient != null)
+ mServerBase.reject(mConnectionRequestClient, reason);
+ }
+
+ /**
+ * This method will be called when connection requested from the client
+ */
+ public abstract void onConnectionRequest();
+
+ /**
+ * This method will be called when received file payload
+ * @param file File information
+ * @param status The status
+ */
+ public abstract void onFilePayloadReceived(FilePayload file, PayloadTransferStatus status);
+
+ /**
+ * This method will be called when the client is disconnected
+ */
+ public abstract void onTerminate();
+
+ /**
+ * This method will be called when the client is connected
+ */
+ public abstract void onConnected();
+
+)__java_cb";
+
+const char CB_ON_RECEIVED_ASYNC_EVENT_FRONT[] =
+R"__java_cb(
+ @Override
+ public final void onPayloadReceived(<PEER_INFO_T> info, IPayload data, PayloadTransferStatus status) {
+ try {
+ <PARCEL> p;
+ ServiceBase b = null;
+
+ for (ServiceBase i : mServices) {
+ if (i.mClient == null)
+ continue;
+
+ if (<PEER_INFO_GET_APPID1>.equals(<PEER_INFO_GET_APPID2>) &&
+ <PEER_INFO_GET_UUID1>.equals(<PEER_INFO_GET_UUID2>)) {
+ b = i;
+ break;
+ }
+ }
+
+ if (b == null)
+ return;
+
+ if (data.getType() == IPayload.PayloadType.PAYLOAD_FILE) {
+ b.onFilePayloadReceived((FilePayload)data, status);
+ return;
+ }
+
+ DataPayload dp = (DataPayload)data;
+ p = new <PARCEL>(dp.getData());
+ int cmd = p.readInt();
+ switch (cmd) {
+)__java_cb";
+
+const char CB_ON_RECEIVED_ASYNC_EVENT_BACK[] =
+R"__java_cb(
+ default:
+ return;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+ }
+)__java_cb";
+
+const char CB_ON_RECEIVED_SYNC_EVENT_FRONT[] =
+R"__java_cb(
+ @Override
+ public final byte[] onDataReceived(<PEER_INFO_T> info, byte[] data) {
+ <PARCEL> p;
+ byte[] returnData = new byte[0];
+
+ p = new <PARCEL>(data);
+ try {
+ ServiceBase b = null;
+
+ for (ServiceBase i : mServices) {
+ if (i.mClient == null)
+ continue;
+
+ if (<PEER_INFO_GET_APPID1>.equals(<PEER_INFO_GET_APPID2>) &&
+ <PEER_INFO_GET_UUID1>.equals(<PEER_INFO_GET_UUID2>)) {
+ b = i;
+ break;
+ }
+ }
+
+ if (b == null)
+ return returnData;
+
+ <PARCEL> result = new <PARCEL>();
+ int cmd = p.readInt();
+
+ switch (cmd) {
+)__java_cb";
+
+const char CB_ON_RECEIVED_SYNC_EVENT_BACK[] =
+R"__java_cb(
+ default:
+ return returnData;
+ }
+
+ return returnData;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return returnData;
+ }
+ }
+)__java_cb";
+
+
+const char CB_ON_CONNECTIONREQUESTED_EVENT[] =
+R"__java_cb(
+ @Override
+ public void onConnectionRequest(<PEER_INFO_T> peerInfo) {
+ ServiceBase s;
+ try {
+ final Object o = mServiceType.newInstance();
+ s = (ServiceBase) o;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+
+ s.mServiceName = getServiceName();
+ s.mDisplayName = getDisplayName();
+ s.mConnectionRequestClient = peerInfo;
+ s.mServerBase = this;
+ mServices.add(s);
+ s.onConnectionRequest();
+ }
+)__java_cb";
+
+const char CB_ON_CONNECTED_EVENT[] =
+R"__java_cb(
+ @Override
+ public void onConnectionResult(<PEER_INFO_T> peerInfo, ConnectionResult result) {
+ for (ServiceBase i : mServices) {
+ if (i.mConnectionRequestClient == null)
+ continue;
+
+ if (<PEER_INFO_GET_APPID1>.equals(<PEER_INFO_GET_APPID2>) &&
+ <PEER_INFO_GET_UUID1>.equals(<PEER_INFO_GET_UUID2>)) {
+ if (result.status == ConnectionResult.ConnectionStatus.CONNECTION_OK) {
+ i.mClient = i.mConnectionRequestClient;
+ i.mConnectionRequestClient = null;
+ i.onConnected();
+ } else {
+ mServices.remove(i);
+ }
+ break;
+ }
+ }
+ }
+
+)__java_cb";
+
+const char CB_ON_DISCONNECTED_EVENT[] =
+R"__java_cb(
+ @Override
+ public void onDisconnected(<PEER_INFO_T> peerInfo) {
+ for (ServiceBase i : mServices) {
+ if (i.mClient == null)
+ continue;
+
+ if (<PEER_INFO_GET_APPID1>.equals(<PEER_INFO_GET_APPID2>) &&
+ <PEER_INFO_GET_UUID1>.equals(<PEER_INFO_GET_UUID2>)) {
+ i.onTerminate();
+ mServices.remove(i);
+ break;
+ }
+ }
+ }
+)__java_cb";
+
+const char CB_COMMON_METHODS[] =
+R"__java_cb(
+ @Override
+ public final void onResultReceived(PayloadAsyncResult payloadAsyncResult) {
+ }
+
+ /**
+ * Waits clients
+ * @param serviceType Service class type
+ */
+ public void listen(Class<?> serviceType) {
+ mServiceType = serviceType;
+ super.listen();
+ }
+
+ /**
+ * Stops the listen operation
+ */
+ @Override
+ public void stop() {
+ super.stop();
+ mServices.clear();
+ }
+
+ /**
+ * Gets service objects which are connected
+ * @return Service objects which are connected
+ */
+ public List<ServiceBase> getServices() {
+ return mServices;
+ }
+
+)__java_cb";
+
+
+constexpr const char CB_INVOCATION_RESULT_PRE[] =
+R"__java_cb(
+result.write(__RESULT);
+)__java_cb";
+
+#endif // IDLC_JAVA_CION_GEN_JAVA_STUB_GEN_CB_H_
diff --git a/idlc/gen_cion/java_cion_stub_repo_gen.cc b/idlc/gen_cion/java_cion_stub_repo_gen.cc
new file mode 100644
index 0000000..b640b03
--- /dev/null
+++ b/idlc/gen_cion/java_cion_stub_repo_gen.cc
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/java_cion_stub_repo_gen.h"
+#include "idlc/gen_cion/java_cion_gen_cb.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <ctime>
+#include <vector>
+
+namespace tidl {
+
+JavaCionStubRepoGen::JavaCionStubRepoGen(
+ std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : JavaCionGeneratorBase(doc, trans) {
+}
+
+void JavaCionStubRepoGen::OnInitGen(std::ofstream& stream) {
+ std::string fname = MakeDir(FileName, "/server");
+ if (fname.empty())
+ return;
+
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ stream.open(fname + "/ServerBase.java");
+ stream << "package org.tizen.gen." << FileName << ".server;" << NLine(2);
+ stream << ReplaceAll(DEFAULT_STUB_REPO, {
+ { "<INCLUDE>", GetTransportable().Java().GenInclude() },
+ { "<PEER_INFO_T>", GetTransportable().Java().GenPeerInfoType() },
+ { "<SERVER_BASE_CONSTRUCTOR>",
+ GetTransportable().Java().GenServerBaseConstructor() },
+ { "<SERVER_CHANNEL>", GetTransportable().Java().GenServerChannel() },
+ { "<SERVER_SEND_ASYNC>", GetTransportable().Java().GenServerSendAsync("mServer", "payload") },
+ { "<SERVER_LISTEN>", GetTransportable().Java().GenServerListen("mServer") },
+ { "<SERVER_ACCEPT>", GetTransportable().Java().GenServerAccept("mServer") },
+ { "<SERVER_STOP>", GetTransportable().Java().GenServerStop("mServer") },
+ { "<SERVER_DISCONNECT>", GetTransportable().Java()
+ .GenServerDisconnect("mServer", "peerInfo") },
+ { "<SERVER_REJECT>", GetTransportable().Java()
+ .GenServerReject("mServer", "peerInfo", "reason") },
+ { "<SECURITY_T>", GetTransportable().Java().GenSecurityType() }
+ }) << NLine(1);
+ stream.close();
+ }
+}
+
+void JavaCionStubRepoGen::OnFiniGen(std::ofstream& stream) {
+}
+
+std::string JavaCionStubRepoGen::NLine(int cnt) {
+ std::string t;
+
+ for (int i = 0; i < cnt; i++) {
+ t += "\n";
+ }
+
+ return t;
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/java_cion_stub_repo_gen.h b/idlc/gen_cion/java_cion_stub_repo_gen.h
new file mode 100644
index 0000000..d37cb40
--- /dev/null
+++ b/idlc/gen_cion/java_cion_stub_repo_gen.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_JAVA_CION_STUB_REPO_GEN_H_
+#define IDLC_GEN_CION_JAVA_CION_STUB_REPO_GEN_H_
+
+#include <memory>
+#include <string>
+#include <map>
+
+#include "idlc/gen_cion/java_cion_gen_base.h"
+
+namespace tidl {
+
+class JavaCionStubRepoGen : public JavaCionGeneratorBase {
+ public:
+ explicit JavaCionStubRepoGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~JavaCionStubRepoGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+ std::string NLine(int cnt);
+};
+
+} // namespace tidl
+#endif // IDLC_GEN_CION_JAVA_CION_STUB_REPO_GEN_H_
diff --git a/idlc/gen_cion/java_cion_utility_gen.cc b/idlc/gen_cion/java_cion_utility_gen.cc
new file mode 100644
index 0000000..078a268
--- /dev/null
+++ b/idlc/gen_cion/java_cion_utility_gen.cc
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/java_cion_utility_gen.h"
+#include "idlc/gen_cion/java_cion_gen_cb.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <ctime>
+#include <vector>
+
+namespace tidl {
+
+JavaCionUtilityGen::JavaCionUtilityGen(
+ std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : JavaCionGeneratorBase(doc, trans) {
+}
+
+void JavaCionUtilityGen::OnInitGen(std::ofstream& stream) {
+ std::string fname = MakeDir(FileName, "/common");
+ if (fname.empty())
+ return;
+
+ stream.open(fname + "/Out.java");
+ stream << "package org.tizen.gen." << FileName << ".common;" << NLine(2);
+ stream << OUT_CLASS;
+ stream.close();
+
+ stream.open(fname + "/Ref.java");
+ stream << "package org.tizen.gen." << FileName << ".common;" << NLine(2);
+ stream << REF_CLASS;
+ stream.close();
+}
+
+void JavaCionUtilityGen::OnFiniGen(std::ofstream& stream) {
+}
+
+std::string JavaCionUtilityGen::NLine(int cnt) {
+ std::string t;
+
+ for (int i = 0; i < cnt; i++) {
+ t += "\n";
+ }
+
+ return t;
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/java_cion_utility_gen.h b/idlc/gen_cion/java_cion_utility_gen.h
new file mode 100644
index 0000000..bee4c12
--- /dev/null
+++ b/idlc/gen_cion/java_cion_utility_gen.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_JAVA_CION_UTILITY_GEN_H_
+#define IDLC_GEN_CION_JAVA_CION_UTILITY_GEN_H_
+
+#include <memory>
+#include <string>
+#include <map>
+
+#include "idlc/ast/type.h"
+#include "idlc/ast/structure.h"
+#include "idlc/gen_cion/java_cion_gen_base.h"
+
+namespace tidl {
+
+class JavaCionUtilityGen : public JavaCionGeneratorBase {
+ public:
+ explicit JavaCionUtilityGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~JavaCionUtilityGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+ std::string NLine(int cnt);
+};
+
+} // namespace tidl
+#endif // IDLC_GEN_CION_JAVA_CION_UTILITY_GEN_H_
diff --git a/idlc/gen_cion/java_transportable.h b/idlc/gen_cion/java_transportable.h
new file mode 100644
index 0000000..f5b10a7
--- /dev/null
+++ b/idlc/gen_cion/java_transportable.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_JAVA_TRANSPORTABLE_H_
+#define IDLC_GEN_CION_JAVA_TRANSPORTABLE_H_
+
+#include <string>
+#include <vector>
+
+namespace tidl {
+
+class JavaTransportable {
+ public:
+ virtual ~JavaTransportable() = default;
+ virtual std::string GenInclude() const = 0;
+ virtual std::string GenParcelInclude() const = 0;
+ virtual std::string GenParcel() const = 0;
+ virtual std::string GenClientChannel() const = 0;
+ virtual std::string GenServerChannel() const = 0;
+ virtual std::string GenGroupChannel() const = 0;
+ virtual std::string GenClientSendAsync(std::string client,
+ std::string payload) const = 0;
+ virtual std::string GenClientSend(std::string client, std::string data,
+ std::string data_size) const = 0;
+ virtual std::string GenServerSendAsync(std::string server,
+ std::string payload) const = 0;
+ virtual std::string GenPeerInfoType() const = 0;
+ virtual std::string GenSecurityType() const = 0;
+ virtual std::string GenClientTryConnect(std::string client,
+ std::string peer) const = 0;
+ virtual std::string GenClientDisconnect(std::string client) const = 0;
+ virtual std::string GenClientTryDiscovery(std::string client) const = 0;
+ virtual std::string GenClientStopDiscovery(std::string client) const = 0;
+ virtual std::string GenClientExtraHeader() const = 0;
+ virtual std::string GenClientExtraBody() const = 0;
+ virtual std::string GenServerExtraHeader() const = 0;
+ virtual std::string GenServerExtraBody() const = 0;
+ virtual std::string GenServerAccept(std::string server) const = 0;
+ virtual std::string GenServerStop(std::string server) const = 0;
+ virtual std::string GenServerReject(std::string server,
+ std::string peer, std::string reason) const = 0;
+ virtual std::string GenGroupPublish(std::string group, std::string data) const = 0;
+ virtual std::string GenGroupSubscribe(std::string group) const = 0;
+ virtual std::string GenGroupUnsubscribe(std::string group) const = 0;
+ virtual std::string GenServerListen(std::string server) const = 0;
+ virtual std::string GenServerDisconnect(std::string server,
+ std::string peer) const = 0;
+ virtual std::string GenPeerInfoGetAppID(std::string peer) const = 0;
+ virtual std::string GenPeerInfoGetUUID(std::string peer) const = 0;
+ virtual std::string GenClientBaseConstructor() const = 0;
+ virtual std::string GenServerBaseConstructor() const = 0;
+ virtual std::string GenGroupBaseConstructor() const = 0;
+ virtual std::string GenOnLeftEventMethod() const = 0;
+ virtual std::string GenOnJoinedEventMethod() const = 0;
+ virtual std::string GenInheritedClassConstructor(
+ std::vector<std::string> params,
+ std::vector<std::string> base_class_params,
+ std::string extra_operation) const = 0;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CION_JAVA_TRANSPORTABLE_H_
diff --git a/idlc/gen_cion/plugin_loader.cc b/idlc/gen_cion/plugin_loader.cc
new file mode 100644
index 0000000..1f9313b
--- /dev/null
+++ b/idlc/gen_cion/plugin_loader.cc
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/plugin_loader.h"
+
+#include "idlc/gen_cion/default_c_transportable.h"
+#include "idlc/gen_cion/default_cpp_transportable.h"
+#include "idlc/gen_cion/default_java_transportable.h"
+#include "idlc/gen_cion/default_cs_transportable.h"
+#include "idlc/gen_cion/default_dart_transportable.h"
+
+namespace tidl {
+
+PluginLoader::PluginLoader(const std::string& plugin_path) {
+ if (plugin_path.empty()) {
+ C_.reset(new DefaultCTransportable());
+ Cpp_.reset(new DefaultCppTransportable());
+ Cs_.reset(new DefaultCsTransportable());
+ Java_.reset(new DefaultJavaTransportable());
+ Dart_.reset(new DefaultDartTransportable());
+ } else {
+ // TODO
+ }
+}
+
+const CTransportable& PluginLoader::C() {
+ return *C_;
+}
+
+const CppTransportable& PluginLoader::Cpp() {
+ return *Cpp_;
+}
+
+const CsTransportable& PluginLoader::Cs() {
+ return *Cs_;
+}
+
+const JavaTransportable& PluginLoader::Java() {
+ return *Java_;
+}
+
+const DartTransportable& PluginLoader::Dart() {
+ return *Dart_;
+}
+
+} // namespace tidl
diff --git a/idlc/gen_cion/plugin_loader.h b/idlc/gen_cion/plugin_loader.h
new file mode 100644
index 0000000..bdf9c61
--- /dev/null
+++ b/idlc/gen_cion/plugin_loader.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_PLUGIN_LOADER_H_
+#define IDLC_GEN_CION_PLUGIN_LOADER_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/transportable.h"
+
+namespace tidl {
+
+class PluginLoader : public Transportable {
+ public:
+ explicit PluginLoader(const std::string& plugin_path);
+
+ const CTransportable& C() override;
+ const CppTransportable& Cpp() override;
+ const CsTransportable& Cs() override;
+ const JavaTransportable& Java() override;
+ const DartTransportable& Dart() override;
+
+ private:
+ std::unique_ptr<CTransportable> C_;
+ std::unique_ptr<CppTransportable> Cpp_;
+ std::unique_ptr<CsTransportable> Cs_;
+ std::unique_ptr<JavaTransportable> Java_;
+ std::unique_ptr<DartTransportable> Dart_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CION_PLUGIN_LOADER_H_
diff --git a/idlc/gen_cion/transportable.h b/idlc/gen_cion/transportable.h
new file mode 100644
index 0000000..c62c8d0
--- /dev/null
+++ b/idlc/gen_cion/transportable.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_TRANSPORTABLE_H_
+#define IDLC_GEN_CION_TRANSPORTABLE_H_
+
+#include "idlc/gen_cion/c_transportable.h"
+#include "idlc/gen_cion/cpp_transportable.h"
+#include "idlc/gen_cion/cs_transportable.h"
+#include "idlc/gen_cion/java_transportable.h"
+#include "idlc/gen_cion/dart_transportable.h"
+
+namespace tidl {
+
+class Transportable {
+ public:
+ virtual ~Transportable() = default;
+ virtual const CTransportable& C() = 0;
+ virtual const CppTransportable& Cpp() = 0;
+ virtual const CsTransportable& Cs() = 0;
+ virtual const JavaTransportable& Java() = 0;
+ virtual const DartTransportable& Dart() = 0;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CION_TRANSPORTABLE_H_
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_c_transportable.cc b/idlc/gen_mqtt_plugin/mqtt_plugin_c_transportable.cc
new file mode 100644
index 0000000..59938e4
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_c_transportable.cc
@@ -0,0 +1,1191 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_c_transportable.h"
+
+#include <utility>
+
+#include "idlc/gen/replace_all.h"
+
+namespace {
+
+constexpr const char __CLINET_FILE_SEND[] =
+R"__c_cb(
+ <INTERNAL_PREFIX>_payload_h pl;
+ int ret = <INTERNAL_PREFIX>_payload_create(&pl, MQTT_PLUGIN_PAYLOAD_TYPE_FILE);
+
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_create : %d", ret);
+ return ret;
+ }
+
+ ret = <INTERNAL_PREFIX>_payload_set_file_path(pl, <FILE_PATH>);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_set_file_path : %d - %s", ret, value);
+ <INTERNAL_PREFIX>_payload_destroy(pl);
+ return ret;
+ }
+
+ ret = <INTERNAL_PREFIX>_client_send_payload_async(<CLIENT_H>, pl, NULL, NULL);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_client_send_payload_async : %d - %s", ret, value);
+ <INTERNAL_PREFIX>_payload_destroy(pl);
+ return ret;
+ }
+
+ <INTERNAL_PREFIX>_payload_destroy(pl);
+)__c_cb";
+
+constexpr const char __SERVER_FILE_SEND[] =
+R"__c_cb(
+ <INTERNAL_PREFIX>_payload_h pl;
+ int r = <INTERNAL_PREFIX>_payload_create(&pl, MQTT_PLUGIN_PAYLOAD_TYPE_FILE);
+
+ if (r != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_create : %d", r);
+ return r;
+ }
+
+ r = <INTERNAL_PREFIX>_payload_set_file_path(pl, <FILE_PATH>);
+ if (r != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_set_file_path : %d - %s", r, value);
+ <INTERNAL_PREFIX>_payload_destroy(pl);
+ return r;
+ }
+
+ r = <INTERNAL_PREFIX>_server_send_payload_async(<SERVER_H>, <PEER_H>, pl, NULL, NULL);
+ if (r != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_server_send_payload_async : %d - %s", r, value);
+ <INTERNAL_PREFIX>_payload_destroy(pl);
+ return r;
+ }
+
+ <INTERNAL_PREFIX>_payload_destroy(pl);
+)__c_cb";
+
+constexpr const char __SERVER_REGISTER[] =
+R"__c_cb(
+
+ ret = <INTERNAL_PREFIX>_server_create(&__<NAME>.stub, service_name, display_name, broker_ip, broker_port, user_name, password);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to create stub handle. error(%d)", ret);
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = <INTERNAL_PREFIX>_server_add_connection_result_cb(__<NAME>.stub, __<PREFIX>_<NAME>_connection_result_cb, &__<NAME>);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to add connection result event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = <INTERNAL_PREFIX>_server_add_payload_received_cb(__<NAME>.stub, __<PREFIX>_<NAME>_payload_received_cb, &__<NAME>);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to add payload recieved event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = <INTERNAL_PREFIX>_server_add_disconnected_cb(__<NAME>.stub, __<PREFIX>_<NAME>_disconnected_cb, &__<NAME>);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to add disconnected event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = <INTERNAL_PREFIX>_server_set_data_received_cb(__<NAME>.stub, __<PREFIX>_<NAME>_data_received_cb, &__<NAME>);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to add data recieved event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = <INTERNAL_PREFIX>_server_listen(__<NAME>.stub, __<PREFIX>_<NAME>_connection_request_cb, &__<NAME>);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to listen events. error(%d)", ret);
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+)__c_cb";
+
+constexpr const char __SERVER_UNREGISTER[] =
+R"__c_cb(
+ if (__<NAME>.stub) {
+ <INTERNAL_PREFIX>_server_destroy(__<NAME>.stub);
+ __<NAME>.stub = nullptr;
+ }
+)__c_cb";
+
+constexpr const char __SERVER_ACCEPT[] =
+R"__c_cb(
+ ret = <INTERNAL_PREFIX>_server_accept(__<NAME>.stub, peer_info);
+ if (ret != MQTT_PLUGIN_ERROR_NONE)
+ _E("Failed to accept. error(%d)", ret);
+)__c_cb";
+
+constexpr const char __SERVER_REJECT[] =
+R"__c_cb(
+ ret = <INTERNAL_PREFIX>_server_reject(__<NAME>.stub, peer_info, reason);
+ if (ret != MQTT_PLUGIN_ERROR_NONE)
+ _E("Failed to reject. error(%d)", ret);
+)__c_cb";
+
+constexpr const char __SERVER_SET_DISPLAY_NAME[] =
+R"__c_cb(
+ ret = <INTERNAL_PREFIX>_server_set_display_name(__<NAME>.stub, display_name);
+ if (ret != MQTT_PLUGIN_ERROR_NONE)
+ _E("Failed to set display name. error(%d)", ret);
+)__c_cb";
+
+constexpr const char __CLIENT_TRY_CONNECT[] =
+R"__c_cb(
+ ret = <INTERNAL_PREFIX>_client_connect(<CLIENT>, <PEER>);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to connect to stub. error(%d)", ret);
+ return ret;
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_DISCONNECT[] =
+R"__c_cb(
+ ret = <INTERNAL_PREFIX>_client_disconnect(<CLIENT>);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to disconnect to stub. error(%d)", ret);
+ return ret;
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_TRY_DISCOVERY[] =
+R"__c_cb(
+ ret = <INTERNAL_PREFIX>_client_try_discovery(<CLIENT>, __<PREFIX>_<NAME>_discovered, h);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to discovery to stub. error(%d)", ret);
+ return ret;
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_STOP_DISCOVERY[] =
+R"__c_cb(
+ ret = <INTERNAL_PREFIX>_client_stop_discovery(<CLIENT>);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to stop discovery to stub. error(%d)", ret);
+ return ret;
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_SEND_ASYNC[] =
+R"__c_cb(
+ res_ = <INTERNAL_PREFIX>_payload_create(&<PAYLOAD>, MQTT_PLUGIN_PAYLOAD_TYPE_DATA);
+ if (res_ != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_create : %d", res_);
+ <INTERNAL_PREFIX>_payload_destroy(<PAYLOAD>);
+ goto out;
+ }
+
+ res_ = <INTERNAL_PREFIX>_payload_set_data(<PAYLOAD>, (const unsigned char*)data_, <SIZE>);
+ if (res_ != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_set_data : %d", res_);
+ <INTERNAL_PREFIX>_payload_destroy(<PAYLOAD>);
+ goto out;
+ }
+
+ res_ = <INTERNAL_PREFIX>_client_send_payload_async(<CLIENT>, <PAYLOAD>, NULL, NULL);
+ <INTERNAL_PREFIX>_payload_destroy(<PAYLOAD>);
+ if (res_ != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_client_send_payload_async : %d", res_);
+ goto out;
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_SEND[] =
+R"__c_cb(
+ res_ = <INTERNAL_PREFIX>_client_send_data(<CLIENT>, <DATA>, <DATA_SIZE> , 5 * 1000, &<RET_DATA>, &<RET_DATA_SIZE>);
+ if (res_ != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to send parcel. error(%d)", res_);
+ goto out;
+ }
+)__c_cb";
+
+constexpr const char __SERVER_SEND_ASYNC[] =
+R"__c_cb(
+ ret_ = <INTERNAL_PREFIX>_payload_create(&<PAYLOAD>, MQTT_PLUGIN_PAYLOAD_TYPE_DATA);
+ if (ret_ != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_create : %d", ret_);
+ <INTERNAL_PREFIX>_payload_destroy(<PAYLOAD>);
+ goto out;
+ }
+
+ ret_ = <INTERNAL_PREFIX>_payload_set_data(<PAYLOAD>, (const unsigned char*)data_, <SIZE>);
+ if (ret_ != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_set_data : %d", ret_);
+ <INTERNAL_PREFIX>_payload_destroy(<PAYLOAD>);
+ goto out;
+ }
+
+ ret_ = <INTERNAL_PREFIX>_server_send_payload_async(<SERVER>, peer_info, <PAYLOAD>, NULL, NULL);
+ <INTERNAL_PREFIX>_payload_destroy(<PAYLOAD>);
+ if (ret_ != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_client_send_payload_async : %d", ret_);
+ goto out;
+ }
+)__c_cb";
+
+constexpr const char __GROUP_PUBLISH[] =
+R"__c_cb(
+ res_ = <INTERNAL_PREFIX>_payload_create(&pl_, MQTT_PLUGIN_PAYLOAD_TYPE_DATA);
+ if (res_ != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_create : %d", res_);
+ <INTERNAL_PREFIX>_payload_destroy(pl_);
+ goto out;
+ }
+
+ res_ = <INTERNAL_PREFIX>_payload_set_data(pl_, (const unsigned char*)data_, data_size_);
+ if (res_ != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_set_data : %d", res_);
+ <INTERNAL_PREFIX>_payload_destroy(pl_);
+ goto out;
+ }
+
+ res_ = <INTERNAL_PREFIX>_group_publish(h->group, pl_);
+ <INTERNAL_PREFIX>_payload_destroy(pl_);
+ if (res_ != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_group_publish : %d", res_);
+ goto out;
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_CREATE[] =
+R"__c_cb(
+ ret = <INTERNAL_PREFIX>_client_create(&handle->client, service_name, broker_ip, broker_port, user_name, password);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to create proxy handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ handle->callback = *callback;
+ handle->user_data = user_data;
+
+ ret = <INTERNAL_PREFIX>_client_add_connection_result_cb(handle->client, __<PREFIX>_<NAME>_connection_result, handle);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to add connection result cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = <INTERNAL_PREFIX>_client_add_disconnected_cb(handle->client, __<PREFIX>_<NAME>_disconnected, handle);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to add disconnected event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = <INTERNAL_PREFIX>_client_add_payload_received_cb(handle->client, __<PREFIX>_<NAME>_received, handle);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to add received event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+)__c_cb";
+
+constexpr const char __GROUP_CREATE[] =
+R"__c_cb(
+ ret = <INTERNAL_PREFIX>_group_create(&handle->group, topic_name, broker_ip, broker_port, user_name, password);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to create group handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ handle->callback = *callback;
+ handle->user_data = user_data;
+
+ ret = <INTERNAL_PREFIX>_group_add_joined_cb(handle->group, __<PREFIX>_<NAME>_joined_cb, handle);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to add connection result cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = <INTERNAL_PREFIX>_group_add_left_cb(handle->group, __<PREFIX>_<NAME>_left_cb, handle);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to add disconnected event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = <INTERNAL_PREFIX>_group_add_payload_received_cb(handle->group, __<PREFIX>_<NAME>_received, handle);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to add received event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = <INTERNAL_PREFIX>_group_subscribe(handle->group);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to subscribe event. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ *h = handle;
+)__c_cb";
+
+constexpr const char __GROUP_DESTROY[] =
+R"__c_cb(
+ if (h->group) {
+ <INTERNAL_PREFIX>_group_unsubscribe(h->group);
+ <INTERNAL_PREFIX>_group_destroy(h->group);
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_DESTROY[] =
+R"__c_cb(
+ if (h->client)
+ <INTERNAL_PREFIX>_client_destroy(h->client);
+)__c_cb";
+
+constexpr const char __PEER_INFO_CLONE[] =
+ "<INTERNAL_PREFIX>_peer_info_clone(<SRC_PEER>, <DEST_PEER>);";
+
+constexpr const char __SERVER_FOREACH_CONNECTED_PEER_INFO[] =
+ "<INTERNAL_PREFIX>_server_foreach_connected_peer_info(__<NAME>.stub, callback, user_data);";
+
+constexpr const char __SERVER_SET_ONDEMAND_LAUNCH_ENABLED[] =
+R"__c_cb(
+ int ret;
+
+ ret = <INTERNAL_PREFIX>_server_set_on_demand_launch_enabled(__<NAME>.stub, enable);
+ if (ret != MQTT_PLUGIN_ERROR_NONE)
+ _E("Failed to set ondemand launch enable. error(%d)", ret);
+
+ return ret;
+)__c_cb";
+
+constexpr const char __COMMON_HEADER_HANDLES[] =
+R"__c_cb(
+
+typedef enum _<MODULE_PREFIX>_error {
+ MQTT_PLUGIN_ERROR_NONE = TIZEN_ERROR_NONE, /**< Success */
+ MQTT_PLUGIN_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O error */
+ MQTT_PLUGIN_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
+ MQTT_PLUGIN_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */
+ MQTT_PLUGIN_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+ MQTT_PLUGIN_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Function not implemented */
+ MQTT_PLUGIN_ERROR_ALREADY_IN_PROGRESS = TIZEN_ERROR_ALREADY_IN_PROGRESS, /**< Already in progress */
+ MQTT_PLUGIN_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */
+ MQTT_PLUGIN_ERROR_TIMED_OUT = TIZEN_ERROR_TIMED_OUT, /**< Timed out */
+ MQTT_PLUGIN_ERROR_OPERATION_FAILED = TIZEN_ERROR_CION | 0x01, /**< Operation failed */
+} <MODULE_PREFIX>_error_e;
+
+enum MqttProtocol {
+ MQTT_TYPE_MQTT = (0x1 << 0), // Publish message through the MQTT
+ MQTT_TYPE_TCP = (0x1 << 1), // Publish message to peers using the TCP
+ MQTT_TYPE_UDP = (0x1 << 2), // Publish message to peers using the UDP
+ MQTT_TYPE_SRTP = (0x1 << 3), // Publish message to peers using the SRTP
+ MQTT_TYPE_WEBRTC = (0x1 << 4), // Publish message to peers using the WEBRTC
+};
+
+/**
+ * @brief The mqtt plugin peer info handle.
+ */
+typedef void *<MODULE_PREFIX>_peer_info_h;
+
+)__c_cb";
+
+constexpr const char __COMMON_HEADER_CONNECTION_RESULT_HANDLE[] =
+R"__c_cb(
+typedef enum _mqtt_connection_status_e {
+ MQTT_PLUGIN_CONNECTION_STATUS_OK, /**< Connection is ok **/
+ MQTT_PLUGIN_CONNECTION_STATUS_REJECTED, /**< Connection is rejected **/
+ MQTT_PLUGIN_CONNECTION_STATUS_ERROR, /**< Connection error occurs **/
+} <MODULE_PREFIX>_connection_status_e;
+
+/**
+ * @brief The Mqtt plugin connection result handle.
+ */
+typedef void *<MODULE_PREFIX>_connection_result_h;
+)__c_cb";
+
+constexpr const char __COMMON_HEADER_PAYLOAD_HANDLE[] =
+R"__c_cb(
+/**
+ * @brief Enumeration for <MODULE_PREFIX>_payload transfer status types.
+ */
+typedef enum _payload_transfer_status_e {
+ MQTT_PLUGIN_PAYLOAD_TRANSFER_STATUS_SUCCESS, /**< Transfer is success **/
+ MQTT_PLUGIN_PAYLOAD_TRANSFER_STATUS_FAILURE, /**< Transfer is failed **/
+ MQTT_PLUGIN_PAYLOAD_TRANSFER_STATUS_IN_PROGRESS, /**< Transfer is in progress **/
+} <MODULE_PREFIX>_payload_transfer_status_e;
+
+/**
+ * @brief The <MODULE_PREFIX>_payload handle.
+ */
+ typedef void *<MODULE_PREFIX>_payload_h;
+
+)__c_cb";
+
+constexpr const char __COMMON_HEADER_PAYLOAD_BASE[] =
+R"__c_cb(
+/**
+ * @brief Saves the payload as a file.
+ * @remarks The @a path is absolute path.
+ * @remarks If the media storage is used, %http://tizen.org/privilege/mediastorage privilege is necessary. \n
+ * If the external storage is used, %http://tizen.org/privilege/externalstorage privilege is necessary.
+ * @param[in] payload The <MODULE_PREFIX>_payload handle
+ * @param[in] path The path of file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OPERATION_FAILED Operation failed
+ */
+int <MODULE_PREFIX>_payload_save_as_file(<MODULE_PREFIX>_payload_h payload, const char *path);
+
+/**
+ * @brief Gets the name of received file from the payload.
+ * @remarks @a file_name must be released using free().
+ * @param[in] payload The <MODULE_PREFIX>_payload handle
+ * @param[out] file_name The name of file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+
+int <MODULE_PREFIX>_payload_get_received_file_name(<MODULE_PREFIX>_payload_h payload,
+ char **file_name);
+
+/**
+ * @brief Gets the size of currently received file from the payload.
+ * @param[in] payload The <MODULE_PREFIX>_payload handle
+ * @param[out] bytes The size of file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <MODULE_PREFIX>_payload_get_received_bytes(<MODULE_PREFIX>_payload_h payload, uint64_t *bytes);
+
+/**
+ * @brief Gets the total size of file from the payload.
+ * @param[in] payload The <MODULE_PREFIX>_payload handle
+ * @param[out] bytes The size of file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <MODULE_PREFIX>_payload_get_total_bytes(<MODULE_PREFIX>_payload_h payload, uint64_t *bytes);
+)__c_cb";
+
+constexpr const char __COMMON_HEADER_COMMON_BASE[] =
+R"__c_cb(
+/**
+ * @brief Creates a clone of mqtt plugin peer info handle.
+ * @remarks @a peer_info_clone must be released using <MODULE_PREFIX>_peer_info_destroy().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] peer_info_clone The cloned peer information handle
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MQTT_PLUGIN_ERROR_IO_ERROR IO error
+ * @see <MODULE_PREFIX>_peer_info_destroy()
+ */
+int <MODULE_PREFIX>_peer_info_clone(const <MODULE_PREFIX>_peer_info_h peer_info,
+ <MODULE_PREFIX>_peer_info_h *peer_info_clone);
+
+/**
+ * @brief Destroys the peer info handle and releases all its resources.
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <MODULE_PREFIX>_peer_info_clone()
+ */
+int <MODULE_PREFIX>_peer_info_destroy(<MODULE_PREFIX>_peer_info_h peer_info);
+
+/**
+ * @brief Gets the device ID.
+ * @remarks @a device_id must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] device_id The device ID
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_device_id(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_id);
+
+/**
+ * @brief Gets the device name.
+ * @remarks @a device_name must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] device_name The device name
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_device_name(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_name);
+
+/**
+ * @brief Gets the device's platform.
+ * @remarks @a device_platform must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] device_platform The platform name
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_device_platform(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_platform);
+
+/**
+ * @brief Gets the device's platform version.
+ * @remarks @a device_platform_version must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] device_platform_version The platform version
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_device_platform_version(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_platform_version);
+
+/**
+ * @brief Gets the device's type.
+ * @remarks @a device_type must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] device_type Device type
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_device_type(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_type);
+
+/**
+ * @brief Gets application ID of peer.
+ * @remarks @a app_id must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] app_id The application ID
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_app_id(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **app_id);
+
+/**
+ * @brief Gets application version of peer.
+ * @remarks @a app_version must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] app_version The application version
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_app_version(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **app_version);
+
+/**
+ * @brief Gets UUID of peer.
+ * @remarks @a uuid must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] uuid The UUID
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_uuid(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **uuid);
+
+/**
+ * @brief Gets display name of peer.
+ * @details The custom name for service name. \n
+ * It is possible that @a display_name does not exist.
+ * @remarks @a display_name must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] display_name The display name
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_display_name(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **display_name);
+)__c_cb";
+
+constexpr const char __COMMON_HEADER_CONNECTION_RESULT_BASE[] =
+R"__c_cb(
+/**
+ * @brief Gets the connection result status.
+ * @param[in] result The connection result handle
+ * @param[out] status Connection result status
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <MODULE_PREFIX>_connection_result_get_status(const <MODULE_PREFIX>_connection_result_h result,
+ <MODULE_PREFIX>_connection_status_e *status);
+
+/**
+ * @brief Gets the connection result reason.
+ * @remarks @a reason must be released using free().
+ * @param[in] result The connection result handle
+ * @param[out] reason Connection result reason, should be freed after use
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_connection_result_get_reason(const <MODULE_PREFIX>_connection_result_h result,
+ char **reason);
+)__c_cb";
+
+constexpr const char __COMMON_BODY_PEERINFO_BASE[] =
+R"__c_cb(
+int <MODULE_PREFIX>_peer_info_clone(const <MODULE_PREFIX>_peer_info_h peer_info,
+ <MODULE_PREFIX>_peer_info_h *peer_info_clone) {
+ return <INTERNAL_PREFIX>_peer_info_clone(peer_info, peer_info_clone);
+}
+
+int <MODULE_PREFIX>_peer_info_destroy(<MODULE_PREFIX>_peer_info_h peer_info) {
+ return <INTERNAL_PREFIX>_peer_info_destroy(peer_info);
+}
+
+int <MODULE_PREFIX>_peer_info_get_device_id(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_id) {
+ return <INTERNAL_PREFIX>_peer_info_get_device_id(peer_info, device_id);
+}
+
+int <MODULE_PREFIX>_peer_info_get_device_name(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_name) {
+ return <INTERNAL_PREFIX>_peer_info_get_device_name(peer_info, device_name);
+}
+
+int <MODULE_PREFIX>_peer_info_get_device_platform(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_platform) {
+ return <INTERNAL_PREFIX>_peer_info_get_device_platform(peer_info, device_platform);
+}
+
+int <MODULE_PREFIX>_peer_info_get_device_platform_version(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_platform_version) {
+ return <INTERNAL_PREFIX>_peer_info_get_device_platform_version(peer_info, device_platform_version);
+}
+
+int <MODULE_PREFIX>_peer_info_get_device_type(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_type) {
+ return <INTERNAL_PREFIX>_peer_info_get_device_type(peer_info, device_type);
+}
+
+int <MODULE_PREFIX>_peer_info_get_app_id(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **app_id) {
+ return <INTERNAL_PREFIX>_peer_info_get_app_id(peer_info, app_id);
+}
+
+int <MODULE_PREFIX>_peer_info_get_app_version(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **app_version) {
+ return <INTERNAL_PREFIX>_peer_info_get_app_version(peer_info, app_version);
+}
+
+int <MODULE_PREFIX>_peer_info_get_uuid(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **uuid) {
+ return <INTERNAL_PREFIX>_peer_info_get_uuid(peer_info, uuid);
+}
+
+int <MODULE_PREFIX>_peer_info_get_display_name(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **display_name) {
+ return <INTERNAL_PREFIX>_peer_info_get_display_name(peer_info, display_name);
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the connection result.
+ */
+constexpr const char __COMMON_BODY_CONNECTION_RESULT_BASE[] =
+R"__c_cb(
+int <MODULE_PREFIX>_connection_result_get_status(const <MODULE_PREFIX>_connection_result_h result,
+ <MODULE_PREFIX>_connection_status_e *status) {
+ return <INTERNAL_PREFIX>_connection_result_get_status(result,(<INTERNAL_PREFIX>_connection_status_e *)status);
+}
+
+int <MODULE_PREFIX>_connection_result_get_reason(const <MODULE_PREFIX>_connection_result_h result,
+ char **reason) {
+ return <INTERNAL_PREFIX>_connection_result_get_reason(result, reason);
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the payload.
+ */
+constexpr const char __COMMON_BODY_PAYLOAD_BASE[] =
+R"__c_cb(
+int <MODULE_PREFIX>_payload_save_as_file(<MODULE_PREFIX>_payload_h payload, const char *path) {
+ return <INTERNAL_PREFIX>_payload_save_as_file(payload, path);
+}
+
+int <MODULE_PREFIX>_payload_get_received_file_name(<MODULE_PREFIX>_payload_h payload,
+ char **file_name) {
+ return <INTERNAL_PREFIX>_payload_get_received_file_name(payload, file_name);
+}
+
+int <MODULE_PREFIX>_payload_get_received_bytes(<MODULE_PREFIX>_payload_h payload, uint64_t *bytes) {
+ return <INTERNAL_PREFIX>_payload_get_received_bytes( payload, bytes);
+}
+
+int <MODULE_PREFIX>_payload_get_total_bytes(<MODULE_PREFIX>_payload_h payload, uint64_t *bytes) {
+ return <INTERNAL_PREFIX>_payload_get_total_bytes( payload, bytes);
+}
+)__c_cb";
+
+constexpr const char __INCLUDE_HEADER_DEF[] =
+R"__c_cb(
+#include <stdlib.h>
+#include <stdint.h>
+)__c_cb";
+
+constexpr const char __SERVER_HEADER_EXTRA[] =
+R"__c_cb(
+/**
+ * @brief Registers the set of the callback functions and the service_name.
+ * @details This function registers the set of the callback functions to handle stub events.
+ * And, the <MODULE_PREFIX>_server_listen() is called internally to handle events.
+
+ * @privilege %http://tizen.org/privilege/d2d.datasharing \n
+ * %http://tizen.org/privilege/internet
+ * @param[in] service_name The name of service
+ * @param[in] display_name The display name of service
+ * @param[in] broker_ip IP address of the broker to connect to
+ * @param[in] port The network port to connect to. Usually 1883
+ * @param[in] user_name The user name to connect to
+ * @param[in] password The Password to connect to
+ * @param[in] callback The set of callback functions to handle stub events
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_NOT_SUPPORTED Not supported
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #<ERROR_PREFIX>_ERROR_IO_ERROR IO error
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #<ERROR_PREFIX>_ERROR_OPERATION_FAILED Operation failed
+ * @retval #<ERROR_PREFIX>_ERROR_PERMISSION_DENIED Permission denied
+ * @see <PREFIX>_<NAME>_unregister()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+int <PREFIX>_<NAME>_register(const char *service_name, const char *display_name,
+ const char *broker_ip, int broker_port, const char *user_name,
+ const char *password, <PREFIX>_<NAME>_callback_s *callback, void *user_data);
+)__c_cb";
+
+constexpr const char __SERVER_BODY_EXTRA[] =
+R"__c_cb(
+int <PREFIX>_<NAME>_register(const char *service_name, const char *display_name,
+ const char *broker_ip, int broker_port, const char *user_name,
+ const char *password, <PREFIX>_<NAME>_callback_s *callback, void *user_data)
+)__c_cb";
+
+constexpr const char __CLIENT_HEADER_EXTRA[] =
+R"__c_cb(
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ * @remarks The @a h handle should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @privilege %http://tizen.org/privilege/d2d.datasharing \n
+ * %http://tizen.org/privilege/internet
+ * @param[in] service_name The name of service
+ * @param[in] broker_ip IP address of the broker to connect to
+ * @param[in] port The network port to connect to. Usually 1883.
+ * @param[in] user_name The user name to connect to
+ * @param[in] password The Password to connect to
+ * @param[in] callback The set of callback functions to handle proxy events
+ * @param[in] user_data The user data to be passed to the callback function
+ * @param[out] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #<ERROR_PREFIX>_ERROR_NONE Successful
+ * @retval #<ERROR_PREFIX>_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #<ERROR_PREFIX>_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+int <PREFIX>_<NAME>_create(const char *service_name, const char *broker_ip, int broker_port,
+ const char *user_name, const char *password,
+ <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h);
+)__c_cb";
+
+constexpr const char __CLIENT_BODY_EXTRA[] =
+R"__c_cb(
+int <PREFIX>_<NAME>_create(const char *service_name, const char *broker_ip, int broker_port,
+ const char *user_name, const char *password,
+ <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h)
+)__c_cb";
+
+
+constexpr const char __GROUP_HEADER_EXTRA[] =
+R"__c_cb(
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ * @remarks The @a h handle should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ *
+ * @privilege %http://tizen.org/privilege/d2d.datasharing
+ * %http://tizen.org/privilege/internet
+ * @param[in] topic_name topic_name The name of topic
+ * @param[in] broker_ip IP address of the broker to connect to
+ * @param[in] port The network port to connect to. Usually 1883.
+ * @param[in] user_name The user name to connect to
+ * @param[in] password The Password to connect to
+ * @param[in] callback The set of callback functions to handle events
+ * @param[in] user_data The user data to be passed to the callback function
+ * @param[out] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MQTT_PLUGIN_ERROR_PERMISSION_DENIED Permission denied
+
+ * @see <PREFIX>_<NAME>_destroy()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+int <PREFIX>_<NAME>_create(const char *topic_name, const char *broker_ip, int broker_port,
+ const char *user_name, const char *password,
+ <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h);
+)__c_cb";
+
+constexpr const char __GROUP_BODY_EXTRA[] =
+R"__c_cb(
+int <PREFIX>_<NAME>_create(const char *topic_name, const char *broker_ip, int broker_port,
+ const char *user_name, const char *password,
+ <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h)
+)__c_cb";
+
+
+} // namespace
+
+namespace tidl {
+
+std::string MqttPluginCTransportable::GenInclude(bool body, int type) const {
+ if (!body)
+ return __INCLUDE_HEADER_DEF;
+ else
+ return "#include \"<FILENAME>_internal.h\"";
+}
+
+std::string MqttPluginCTransportable::GenHeaderBase() const {
+ return __COMMON_HEADER_COMMON_BASE;
+}
+
+std::string MqttPluginCTransportable::GenHeaderPayloadHandle() const {
+ return __COMMON_HEADER_PAYLOAD_HANDLE;
+}
+
+std::string MqttPluginCTransportable::GenHeaderCommonHandle() const {
+ return __COMMON_HEADER_HANDLES;
+}
+
+std::string MqttPluginCTransportable::GenHeaderConnectionHandle() const {
+ return __COMMON_HEADER_CONNECTION_RESULT_HANDLE;
+}
+
+std::string MqttPluginCTransportable::GenHeaderPayloadBase() const {
+ return __COMMON_HEADER_PAYLOAD_BASE;
+}
+
+std::string MqttPluginCTransportable::GenHeaderConnectionBase() const {
+ return __COMMON_HEADER_CONNECTION_RESULT_BASE;
+}
+
+std::string MqttPluginCTransportable::GenBodyPayloadBase() const {
+ return __COMMON_BODY_PAYLOAD_BASE;
+}
+
+std::string MqttPluginCTransportable::GenBodyConnectionBase() const {
+ return __COMMON_BODY_CONNECTION_RESULT_BASE;
+}
+
+std::string MqttPluginCTransportable::GenBodyPeerInfoBase() const {
+ return __COMMON_BODY_PEERINFO_BASE;
+}
+
+std::string MqttPluginCTransportable::GenProxyPrefix() const {
+ return "mqtt_plugin_proxy";
+}
+
+std::string MqttPluginCTransportable::GenStubPrefix() const {
+ return "mqtt_plugin_stub";
+}
+
+std::string MqttPluginCTransportable::GenGroupPrefix() const {
+ return "mqtt_plugin_group";
+}
+
+std::string MqttPluginCTransportable::GenModulePrefix() const {
+ return "mqtt_plugin";
+}
+
+std::string MqttPluginCTransportable::GenErrorPrefix() const {
+ return "MQTT_PLUGIN";
+}
+
+std::string MqttPluginCTransportable::GenServerExtra(bool body) const {
+ if (body)
+ return __SERVER_BODY_EXTRA;
+ else
+ return __SERVER_HEADER_EXTRA;
+}
+
+std::string MqttPluginCTransportable::GenClientExtra(bool body) const {
+ if (body)
+ return __CLIENT_BODY_EXTRA;
+ else
+ return __CLIENT_HEADER_EXTRA;
+}
+
+std::string MqttPluginCTransportable::GenGroupExtra(bool body) const {
+ if (body)
+ return __GROUP_BODY_EXTRA;
+ else
+ return __GROUP_HEADER_EXTRA;
+}
+
+std::string MqttPluginCTransportable::GenClientSendAsync(std::string client,
+ std::string payload, std::string size) const {
+ return std::string(ReplaceAll(__CLIENT_SEND_ASYNC, {
+ { "<CLIENT>", client },
+ { "<PAYLOAD>", payload},
+ { "<SIZE>", size} }));
+}
+
+std::string MqttPluginCTransportable::GenClientSend(std::string client,
+ std::string data, std::string data_size,
+ std::string ret_data, std::string ret_data_size) const {
+ return std::string(ReplaceAll(__CLIENT_SEND, {
+ { "<CLIENT>", client },
+ { "<DATA>", data},
+ { "<DATA_SIZE>", data_size},
+ { "<RET_DATA>", ret_data},
+ { "<RET_DATA_SIZE>", ret_data_size} }));
+}
+
+std::string MqttPluginCTransportable::GenServerSendAsync(std::string server,
+ std::string client,
+ std::string payload, std::string size) const {
+ return std::string(ReplaceAll(__SERVER_SEND_ASYNC, {
+ { "<SERVER>", server },
+ { "<CLIENT>", client},
+ { "<PAYLOAD>", payload},
+ { "<SIZE>", size} }));
+}
+
+std::string MqttPluginCTransportable::GenServerFileSend(std::string path,
+ std::string server, std::string peer) const {
+ return std::string(ReplaceAll(__SERVER_FILE_SEND, {
+ { "<FILE_PATH>", path },
+ { "<SERVER_H>", server },
+ { "<PEER_H>", peer } }));
+}
+
+std::string MqttPluginCTransportable::GenClientFileSend(std::string path,
+ std::string client) const {
+ return std::string(ReplaceAll(__CLINET_FILE_SEND, {
+ { "<FILE_PATH>", path },
+ { "<CLIENT_H>", client } }));
+}
+
+std::string MqttPluginCTransportable::GenGroupType() const {
+ return "<INTERNAL_PREFIX>_group_h";
+}
+
+std::string MqttPluginCTransportable::GenPayloadTransferStatusType(bool internal_type) const {
+ if (internal_type)
+ return "<INTERNAL_PREFIX>_transfer_status_e";
+ else
+ return "<MODULE_PREFIX>_payload_transfer_status_e";
+}
+
+std::string MqttPluginCTransportable::GenPeerInfoType() const {
+ return "<MODULE_PREFIX>_peer_info_h";
+}
+
+std::string MqttPluginCTransportable::GenPeerInfoDestroy(std::string peer) const {
+ return std::string(ReplaceAll("<MODULE_PREFIX>_peer_info_destroy(<PEER>);", {
+ { "<PEER>", peer } }));
+}
+
+std::string MqttPluginCTransportable::GenPayloadType(bool internal_type) const {
+ if (internal_type)
+ return "<INTERNAL_PREFIX>_payload_h";
+ else
+ return "<MODULE_PREFIX>_payload_h";
+}
+
+std::string MqttPluginCTransportable::GenClientType() const {
+ return "<INTERNAL_PREFIX>_client_h";
+}
+
+std::string MqttPluginCTransportable::GenSecurityType(bool definition) const {
+ return "";
+}
+
+std::string MqttPluginCTransportable::GenServerType() const {
+ return "<INTERNAL_PREFIX>_server_h";
+}
+
+std::string MqttPluginCTransportable::GenClientTryConnect(std::string client,
+ std::string peer) const {
+ return std::string(ReplaceAll(__CLIENT_TRY_CONNECT, {
+ { "<CLIENT>", client },
+ { "<PEER>", peer } }));
+}
+
+std::string MqttPluginCTransportable::GenClientDisconnect(
+ std::string client) const {
+ return std::string(ReplaceAll(__CLIENT_DISCONNECT, {
+ { "<CLIENT>", client } }));
+}
+
+std::string MqttPluginCTransportable::GenClientTryDiscovery(
+ std::string client) const {
+ return std::string(ReplaceAll(__CLIENT_TRY_DISCOVERY, {
+ { "<CLIENT>", client } }));
+}
+
+std::string MqttPluginCTransportable::GenClientStopDiscovery(
+ std::string client) const {
+ return std::string(ReplaceAll(__CLIENT_STOP_DISCOVERY, {
+ { "<CLIENT>", client } }));
+}
+
+std::string MqttPluginCTransportable::GenServerRegister() const {
+ return __SERVER_REGISTER;
+}
+
+std::string MqttPluginCTransportable::GenServerUnregister() const {
+ return __SERVER_UNREGISTER;
+}
+
+std::string MqttPluginCTransportable::GenClientExtraHeader() const {
+ return "";
+}
+
+std::string MqttPluginCTransportable::GenClientExtraBody() const {
+ return "";
+}
+
+std::string MqttPluginCTransportable::GenServerExtraHeader() const {
+ return "";
+}
+
+std::string MqttPluginCTransportable::GenServerExtraBody() const {
+ return "";
+}
+
+std::string MqttPluginCTransportable::GenServerAccept() const {
+ return __SERVER_ACCEPT;
+}
+
+std::string MqttPluginCTransportable::GenServerReject() const {
+ return __SERVER_REJECT;
+}
+
+std::string MqttPluginCTransportable::GenServerSetDisplayName() const {
+ return __SERVER_SET_DISPLAY_NAME;
+}
+
+std::string MqttPluginCTransportable::GenGroupPublish() const {
+ return __GROUP_PUBLISH;
+}
+
+std::string MqttPluginCTransportable::GenPayloadTypeEnum() const {
+ return "<INTERNAL_PREFIX>_payload_type_e";
+}
+
+std::string MqttPluginCTransportable::GenPayloadTypeData() const {
+ return "MQTT_PLUGIN_PAYLOAD_TYPE_DATA";
+}
+
+std::string MqttPluginCTransportable::GenPayloadTypeFile() const {
+ return "MQTT_PLUGIN_PAYLOAD_TYPE_FILE";
+}
+
+std::string MqttPluginCTransportable::GenPayloadGetType() const {
+ return "ret = <INTERNAL_PREFIX>_payload_get_type(payload, &type);";
+}
+
+std::string MqttPluginCTransportable::GenErrorNone() const {
+ return "MQTT_PLUGIN_ERROR_NONE";
+}
+
+std::string MqttPluginCTransportable::GenPayloadGetData() const {
+ return "ret = <INTERNAL_PREFIX>_payload_get_data(payload, &data, &data_len);";
+}
+
+std::string MqttPluginCTransportable::GenClientCreate() const {
+ return __CLIENT_CREATE;
+}
+
+std::string MqttPluginCTransportable::GenGroupCreate() const {
+ return __GROUP_CREATE;
+}
+
+std::string MqttPluginCTransportable::GenGroupDestroy() const {
+ return __GROUP_DESTROY;
+}
+
+std::string MqttPluginCTransportable::GenClientDestroy() const {
+ return __CLIENT_DESTROY;
+}
+
+std::string MqttPluginCTransportable::GenSetSecurityCA(std::string arg) const {
+ return "";
+}
+
+std::string MqttPluginCTransportable::GenSetSecurityCert(std::string arg) const {
+ return "";
+}
+
+std::string MqttPluginCTransportable::GenSetSecurityPrivateKey(std::string arg) const {
+ return "";
+}
+
+std::string MqttPluginCTransportable::GenPeerInfoClone(std::string src_peer,
+ std::string dest_peer) const {
+ return std::string(ReplaceAll(__PEER_INFO_CLONE, {
+ { "<SRC_PEER>", src_peer },
+ { "<DEST_PEER>", dest_peer } }));
+}
+
+std::string MqttPluginCTransportable::GenServerForeachConnectedPeerInfo(
+ std::string name) const {
+ return std::string(ReplaceAll(__SERVER_FOREACH_CONNECTED_PEER_INFO, {
+ { "<NAME>", name } }));
+}
+
+} // namespace tidl
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_c_transportable.h b/idlc/gen_mqtt_plugin/mqtt_plugin_c_transportable.h
new file mode 100644
index 0000000..c88010f
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_c_transportable.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_MQTT_PLUGIN_C_TRANSPORTABLE_H_
+#define IDLC_GEN_MQTT_PLUGIN_C_TRANSPORTABLE_H_
+
+#include <string>
+
+#include "idlc/gen_cion/c_transportable.h"
+
+namespace tidl {
+
+class MqttPluginCTransportable : public CTransportable {
+ public:
+ virtual ~MqttPluginCTransportable() = default;
+ std::string GenInclude(bool body = true, int type = 0) const override;
+ std::string GenHeaderBase() const override;
+ std::string GenHeaderPayloadHandle() const override;
+ std::string GenHeaderCommonHandle() const override;
+ std::string GenHeaderConnectionHandle() const override;
+ std::string GenHeaderPayloadBase() const override;
+ std::string GenHeaderConnectionBase() const override;
+ std::string GenBodyPayloadBase() const override;
+ std::string GenBodyConnectionBase() const override;
+ std::string GenBodyPeerInfoBase() const override;
+ std::string GenProxyPrefix() const override;
+ std::string GenStubPrefix() const override;
+ std::string GenGroupPrefix() const override;
+ std::string GenModulePrefix() const override;
+ std::string GenErrorPrefix() const override;
+ std::string GenServerExtra(bool body = true) const override;
+ std::string GenClientExtra(bool body = true) const override;
+ std::string GenGroupExtra(bool body = true) const override;
+ std::string GenClientSendAsync(std::string client,
+ std::string payload, std::string size) const override;
+ std::string GenClientSend(std::string client, std::string data,
+ std::string data_size, std::string ret_data,
+ std::string ret_data_size) const override;
+ std::string GenServerSendAsync(std::string server, std::string client,
+ std::string payload, std::string size) const override;
+ std::string GenServerFileSend(std::string path,
+ std::string server, std::string peer) const override;
+ std::string GenClientFileSend(std::string path,
+ std::string client) const override;
+ std::string GenGroupType() const override;
+ std::string GenPayloadTransferStatusType(bool internal_type = false) const override;
+ std::string GenPeerInfoType() const override;
+ std::string GenPeerInfoDestroy(std::string peer) const override;
+ std::string GenPayloadType(bool internal_type = false) const override;
+ std::string GenClientType() const override;
+ std::string GenSecurityType(bool definition = true) const override;
+ std::string GenServerType() const override;
+ std::string GenClientTryConnect(std::string client,
+ std::string peer) const override;
+ std::string GenClientDisconnect(std::string client) const override;
+ std::string GenClientTryDiscovery(std::string client) const override;
+ std::string GenClientStopDiscovery(std::string client) const override;
+ std::string GenServerRegister() const override;
+ std::string GenServerUnregister() const override;
+ std::string GenClientExtraHeader() const override;
+ std::string GenClientExtraBody() const override;
+ std::string GenServerExtraHeader() const override;
+ std::string GenServerExtraBody() const override;
+ std::string GenServerAccept() const override;
+ std::string GenServerReject() const override;
+ std::string GenServerSetDisplayName() const override;
+ std::string GenGroupPublish() const override;
+ std::string GenPayloadTypeEnum() const override;
+ std::string GenPayloadTypeData() const override;
+ std::string GenPayloadTypeFile() const override;
+ std::string GenPayloadGetType() const override;
+ std::string GenErrorNone() const override;
+ std::string GenPayloadGetData() const override;
+ std::string GenClientCreate() const override;
+ std::string GenGroupCreate() const override;
+ std::string GenGroupDestroy() const override;
+ std::string GenClientDestroy() const override;
+ std::string GenSetSecurityCA(std::string arg) const override;
+ std::string GenSetSecurityCert(std::string arg) const override;
+ std::string GenSetSecurityPrivateKey(std::string arg) const override;
+ std::string GenPeerInfoClone(std::string src_peer,
+ std::string dest_peer) const override;
+ std::string GenServerForeachConnectedPeerInfo(std::string name) const override;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_MQTT_PLUGIN_C_TRANSPORTABLE_H_
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_cpp_transportable.cc b/idlc/gen_mqtt_plugin/mqtt_plugin_cpp_transportable.cc
new file mode 100644
index 0000000..3cbad61
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_cpp_transportable.cc
@@ -0,0 +1,1189 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_cpp_transportable.h"
+
+#include <utility>
+
+#include "idlc/gen/replace_all.h"
+
+namespace {
+
+constexpr const char __CLINET_FILE_SEND[] =
+R"__cpp_cb(<PAYLOAD_T> pl;
+ int ret = <INTERNAL_PREFIX>_payload_create(&pl, MQTT_PLUGIN_PAYLOAD_TYPE_FILE);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_create : %d", ret);
+ return;
+ }
+
+ ret = <INTERNAL_PREFIX>_payload_set_file_path(pl, <FILE_PATH>.c_str());
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_set_file_path : %d - %s", ret, <FILE_PATH>.c_str());
+ <INTERNAL_PREFIX>_payload_destroy(pl);
+ return;
+ }
+
+ ret = <INTERNAL_PREFIX>_client_send_payload_async(<CLIENT_H>, pl, nullptr, nullptr);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_client_send_payload_async : %d", ret);
+ <INTERNAL_PREFIX>_payload_destroy(pl);
+ return;
+ }
+
+ <INTERNAL_PREFIX>_payload_destroy(pl);
+)__cpp_cb";
+
+constexpr const char __SERVER_FILE_SEND[] =
+R"__cpp_cb(<PAYLOAD_T> pl;
+ int ret = <INTERNAL_PREFIX>_payload_create(&pl, MQTT_PLUGIN_PAYLOAD_TYPE_FILE);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_create : %d", ret);
+ return;
+ }
+
+ ret = <INTERNAL_PREFIX>_payload_set_file_path(pl, <FILE_PATH>.c_str());
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_set_file_path : %d - %s", ret, <FILE_PATH>.c_str());
+ <INTERNAL_PREFIX>_payload_destroy(pl);
+ return;
+ }
+
+ ret = <INTERNAL_PREFIX>_server_send_payload_async(<SERVER_H>, <PEER_H>, pl, nullptr, nullptr);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_server_send_payload_async : %d", ret);
+ <INTERNAL_PREFIX>_payload_destroy(pl);
+ return;
+ }
+
+ <INTERNAL_PREFIX>_payload_destroy(pl);
+)__cpp_cb";
+
+constexpr const char __SERVER_REGISTER[] =
+R"__cpp_cb(<SERVER_T> server;
+ int ret = <INTERNAL_PREFIX>_server_create(&server, service_name.c_str(),
+ display_name.c_str(), broker_ip.c_str(), broker_port, user_name.c_str(), password.c_str());
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = <INTERNAL_PREFIX>_server_add_connection_result_cb(server, OnConnectionResultCB,
+ this);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_server_add_connection_result_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = <INTERNAL_PREFIX>_server_add_payload_received_cb(server,
+ [](const char *service_name, const <INTERNAL_PREFIX>_peer_info_h peer_info,
+ const <INTERNAL_PREFIX>_payload_h payload, <INTERNAL_PREFIX>_transfer_status_e status, void *user_data) {
+ ## *sr = static_cast<##*>(user_data);
+ sr->OnPayloadReceivedCB(service_name, peer_info, payload,
+ static_cast<<MODULE_PREFIX>_payload_transfer_status_e>(status), user_data);
+ },
+ this);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_server_add_payload_received_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = <INTERNAL_PREFIX>_server_set_data_received_cb(server, OnDataReceivedCB, this);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_server_set_data_received_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = <INTERNAL_PREFIX>_server_add_disconnected_cb(server, OnDisconnectedCB, this);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_server_add_disconnected_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ server_ = server;
+)__cpp_cb";
+
+
+
+constexpr const char __SERVER_UNREGISTER[] =
+R"__cpp_cb(
+ if (server_ != nullptr)
+ <INTERNAL_PREFIX>_server_destroy(server_);
+)__cpp_cb";
+
+constexpr const char __SERVER_ACCEPT[] =
+R"__cpp_cb(auto p = service->GetPeer();
+ int ret = <INTERNAL_PREFIX>_server_accept(server_, p);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_server_accept. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ service->OnCreate();
+ services_.emplace_back(std::move(service));
+)__cpp_cb";
+
+constexpr const char __SERVER_REJECT[] =
+R"__cpp_cb(auto p = service->GetPeer();
+ int ret = <INTERNAL_PREFIX>_server_reject(server_, p, reason.c_str());
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_server_reject. error(%d)", ret);
+ throw InvalidIOException();
+ }
+)__cpp_cb";
+
+constexpr const char __SERVER_SET_DISPLAY_NAME[] =
+R"__cpp_cb(int ret = <INTERNAL_PREFIX>_server_set_display_name(server_, display_name.c_str());
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_server_set_display_name. error(%d)", ret);
+ InvalidIOException();
+ }
+)__cpp_cb";
+
+constexpr const char __CLIENT_TRY_CONNECT[] =
+R"__cpp_cb(int ret = <INTERNAL_PREFIX>_client_connect(<CLIENT>, <PEER>);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to connect to stub. error(%d)", ret);
+ switch(ret) {
+ case MQTT_PLUGIN_ERROR_PERMISSION_DENIED :
+ throw UnauthorizedAccessException();
+ break;
+ case MQTT_PLUGIN_ERROR_INVALID_PARAMETER :
+ throw NotConnectedSocketException();
+ break;
+ default :
+ throw InvalidIOException();
+ }
+ }
+)__cpp_cb";
+
+constexpr const char __CLIENT_DISCONNECT[] =
+R"__cpp_cb(int ret = <INTERNAL_PREFIX>_client_disconnect(<CLIENT>);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to disconnect to stub. error(%d)", ret);
+ throw NotConnectedSocketException();
+ }
+)__cpp_cb";
+
+constexpr const char __CLIENT_TRY_DISCOVERY[] =
+R"__cpp_cb(int ret = <INTERNAL_PREFIX>_client_try_discovery(<CLIENT>, OnDiscoveredCB, this);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to discovery to stub. error(%d)", ret);
+ switch(ret) {
+ case MQTT_PLUGIN_ERROR_PERMISSION_DENIED :
+ throw UnauthorizedAccessException();
+ break;
+ default :
+ throw InvalidIOException();
+ }
+ }
+)__cpp_cb";
+
+constexpr const char __CLIENT_STOP_DISCOVERY[] =
+R"__cpp_cb(int ret = <INTERNAL_PREFIX>_client_stop_discovery(<CLIENT>);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to stop discovery. error(%d)", ret);
+ return;
+ }
+)__cpp_cb";
+
+constexpr const char __CLIENT_SEND_ASYNC[] =
+R"__cpp_cb(
+ ret = <INTERNAL_PREFIX>_payload_create(&<PAYLOAD>, MQTT_PLUGIN_PAYLOAD_TYPE_DATA);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_create : %d", ret);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
+
+ ret = <INTERNAL_PREFIX>_payload_set_data(<PAYLOAD>, (const unsigned char*)data, <SIZE>);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_set_data : %d", ret);
+ rpc_port_parcel_destroy(p);
+ <INTERNAL_PREFIX>_payload_destroy(<PAYLOAD>);
+ throw InvalidIOException();
+ }
+
+ ret = <INTERNAL_PREFIX>_client_send_payload_async(<CLIENT>, <PAYLOAD>, nullptr, nullptr);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_client_send_payload_async : %d", ret);
+ rpc_port_parcel_destroy(p);
+ <INTERNAL_PREFIX>_payload_destroy(<PAYLOAD>);
+ throw InvalidIOException();
+ }
+
+ <INTERNAL_PREFIX>_payload_destroy(<PAYLOAD>);
+)__cpp_cb";
+
+constexpr const char __CLIENT_SEND[] =
+R"__cpp_cb(
+ ret = <INTERNAL_PREFIX>_client_send_data(<CLIENT>, (unsigned char *)<DATA>, <DATA_SIZE>,
+ 100, &<RET_DATA>, &<RET_DATA_SIZE>);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_client_send_data : error(%d)", ret);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
+)__cpp_cb";
+
+constexpr const char __SERVER_SEND_ASYNC[] =
+R"__cpp_cb(ret_ = <INTERNAL_PREFIX>_payload_create(&<PAYLOAD>, MQTT_PLUGIN_PAYLOAD_TYPE_DATA);
+ if (ret_ != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_create : %d", ret_);
+ rpc_port_parcel_destroy(p);
+ return;
+ }
+
+ ret_ = <INTERNAL_PREFIX>_payload_set_data(<PAYLOAD>, (const unsigned char*)data, <SIZE>);
+ if (ret_ != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_set_data : %d", ret_);
+ rpc_port_parcel_destroy(p);
+ <INTERNAL_PREFIX>_payload_destroy(<PAYLOAD>);
+ return;
+ }
+
+ ret_ = <INTERNAL_PREFIX>_server_send_payload_async(<SERVER>, service_.lock()->GetPeer(), <PAYLOAD>, nullptr, nullptr);
+ <INTERNAL_PREFIX>_payload_destroy(<PAYLOAD>);
+ if (ret_ != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_client_send_payload_async : %d", ret_);
+ rpc_port_parcel_destroy(p);
+ return;
+ }
+)__cpp_cb";
+
+constexpr const char __GROUP_HANDLES[] =
+R"__c_cb(
+ /**
+ * @brief The mqtt group handle.
+ */
+typedef void *<MODULE_PREFIX>_group_h;
+
+)__c_cb";
+
+constexpr const char __GROUP_PUBLISH[] =
+R"__c_cb(ret = <INTERNAL_PREFIX>_payload_create(&pl, MQTT_PLUGIN_PAYLOAD_TYPE_DATA);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_create : %d", ret);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
+
+ ret = <INTERNAL_PREFIX>_payload_set_data(pl, (const unsigned char*)data, size);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_payload_set_data : %d", ret);
+ rpc_port_parcel_destroy(p);
+ <INTERNAL_PREFIX>_payload_destroy(pl);
+ throw InvalidIOException();
+ }
+
+ ret = <INTERNAL_PREFIX>_group_publish(group_, pl);
+ <INTERNAL_PREFIX>_payload_destroy(pl);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_group_publish : %d", ret);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_CREATE[] =
+R"__c_cb(<CLIENT_T> client = nullptr;
+ int ret = <INTERNAL_PREFIX>_client_create(&client, service_name.c_str(),
+ broker_ip.c_str(), broker_port, user_name.c_str(), password.c_str());
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = <INTERNAL_PREFIX>_client_add_disconnected_cb(client, OnDisconnectedCB,
+ this);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_client_add_disconnected_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = <INTERNAL_PREFIX>_client_add_connection_result_cb(client, OnConnectionResultCB,
+ this);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_client_add_connection_result_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = <INTERNAL_PREFIX>_client_add_payload_received_cb(client,
+ [](const char *service_name, const <INTERNAL_PREFIX>_peer_info_h peer_info,
+ const <INTERNAL_PREFIX>_payload_h payload, <INTERNAL_PREFIX>_transfer_status_e status, void *user_data) {
+ $$ *sr = static_cast<$$*>(user_data);
+ sr->OnPayloadReceivedCB(service_name, peer_info, payload,
+ static_cast<<MODULE_PREFIX>_payload_transfer_status_e>(status), user_data);
+ }, this);
+
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_client_add_payload_received_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ client_ = client;
+)__c_cb";
+
+constexpr const char __GROUP_CREATE[] =
+R"__c_cb(<GROUP_T> group = nullptr;
+ int ret = <INTERNAL_PREFIX>_group_create(&group, topic_name_.c_str(),
+ broker_ip.c_str(), broker_port, user_name.c_str(), password.c_str());
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = <INTERNAL_PREFIX>_group_add_joined_cb(group,
+ [](const char *topic_name, const <PEER_INFO_T> peer_info,
+ void *user_data) {
+ <CLS_NAME> *gr = static_cast<<CLS_NAME>*>(user_data);
+ gr->OnJoined(peer_info);
+ },
+ this);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_group_add_joined_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = <INTERNAL_PREFIX>_group_add_left_cb(group,
+ [](const char *topic_name, const <PEER_INFO_T> peer_info,
+ void *user_data) {
+ <CLS_NAME> *gr = static_cast<<CLS_NAME>*>(user_data);
+ gr->OnLeft(peer_info);
+ },
+ this);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_group_add_left_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = <INTERNAL_PREFIX>_group_add_payload_received_cb(group,
+ [](const char *topic_name, const <PEER_INFO_T> peer_info,
+ const <PAYLOAD_T> payload, void *user_data) {
+ <CLS_NAME> *gr = static_cast<<CLS_NAME>*>(user_data);
+ gr->OnPayloadReceivedCB(peer_info, payload);
+ },
+ this);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_group_add_payload_received_cb. error(%d)", ret);
+ throw InvalidIOException();
+ }
+
+ ret = <INTERNAL_PREFIX>_group_subscribe(group);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to subscribe. error(%d)", ret);
+ switch (ret) {
+ case MQTT_PLUGIN_ERROR_PERMISSION_DENIED :
+ throw UnauthorizedAccessException();
+ break;
+ case MQTT_PLUGIN_ERROR_INVALID_PARAMETER :
+ throw NotConnectedSocketException();
+ break;
+ default :
+ throw InvalidIOException();
+ }
+ }
+
+ group_ = group;
+)__c_cb";
+
+constexpr const char __GROUP_DESTROY[] =
+R"__c_cb(if (group_ != nullptr) {
+ <INTERNAL_PREFIX>_group_unsubscribe(group_);
+ <INTERNAL_PREFIX>_group_destroy(group_);
+ }
+)__c_cb";
+
+constexpr const char __CLIENT_DESTROY[] =
+R"__c_cb(
+ if (client_ != nullptr)
+ <INTERNAL_PREFIX>_client_destroy(client_);
+)__c_cb";
+
+const char __PEER_INFO_CLONE[] =
+ "<INTERNAL_PREFIX>_peer_info_clone(<SRC_PEER>, <DEST_PEER>);";
+
+constexpr const char __SERVER_SET_ONDEMAND_LAUNCH_ENABLED[] =
+R"__c_cb(int ret = <INTERNAL_PREFIX>_server_set_on_demand_launch_enabled(server_, enabled);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_server_set_on_demand_launch_enabled. error(%d)", ret);
+ switch(ret) {
+ case MQTT_PLUGIN_ERROR_PERMISSION_DENIED :
+ throw UnauthorizedAccessException();
+ break;
+ default :
+ throw InvalidIOException();
+ }
+ }
+)__c_cb";
+
+constexpr const char __SERVER_LISTEN[] =
+R"__c_cb(int ret = <INTERNAL_PREFIX>_server_listen(server_, OnConnectionRequestCB, this);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_server_listen. error(%d)", ret);
+ switch(ret) {
+ case MQTT_PLUGIN_ERROR_PERMISSION_DENIED :
+ throw UnauthorizedAccessException();
+ break;
+ default :
+ throw InvalidIOException();
+ }
+ }
+)__c_cb";
+
+constexpr const char __SERVER_DISCONNECT[] =
+R"__c_cb(int ret = <INTERNAL_PREFIX>_server_disconnect(<SERVER>, <PEER>);
+ if (ret != MQTT_PLUGIN_ERROR_NONE) {
+ _E("Failed to <INTERNAL_PREFIX>_server_disconnect. error(%d)", ret);
+ throw InvalidIOException();
+ }
+)__c_cb";
+
+constexpr const char __PEER_INFO_GET_APPID[] =
+ "<INTERNAL_PREFIX>_peer_info_get_app_id(<PEER>, <APPID>);";
+
+constexpr const char __PEER_INFO_GET_UUID[] =
+ "<INTERNAL_PREFIX>_peer_info_get_uuid(<PEER>, <UUID>);";
+
+} // namespace
+
+constexpr const char __COMMON_HEADER_PAYLOAD_HANDLE[] =
+R"__c_cb(
+/**
+ * @brief Enumeration for <MODULE_PREFIX>_payload transfer status types.
+ */
+typedef enum _<MODULE_PREFIX>_payload_transfer_status_e {
+ MQTT_PLUGIN_PAYLOAD_TRANSFER_STATUS_SUCCESS, /**< Transfer is success **/
+ MQTT_PLUGIN_PAYLOAD_TRANSFER_STATUS_FAILURE, /**< Transfer is failed **/
+ MQTT_PLUGIN_PAYLOAD_TRANSFER_STATUS_IN_PROGRESS, /**< Transfer is in progress **/
+} <MODULE_PREFIX>_payload_transfer_status_e;
+
+/**
+ * @brief The <MODULE_PREFIX>_payload handle.
+ */
+ typedef void *<MODULE_PREFIX>_payload_h;
+ typedef void *<MODULE_PREFIX>_payload_async_result_h;
+
+)__c_cb";
+
+constexpr const char __COMMON_HEADER_HANDLES[] =
+R"__c_cb(
+
+typedef enum _<MODULE_PREFIX>_error {
+ MQTT_PLUGIN_ERROR_NONE = TIZEN_ERROR_NONE, /**< Success */
+ MQTT_PLUGIN_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O error */
+ MQTT_PLUGIN_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
+ MQTT_PLUGIN_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */
+ MQTT_PLUGIN_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+ MQTT_PLUGIN_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Function not implemented */
+ MQTT_PLUGIN_ERROR_ALREADY_IN_PROGRESS = TIZEN_ERROR_ALREADY_IN_PROGRESS, /**< Already in progress */
+ MQTT_PLUGIN_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */
+ MQTT_PLUGIN_ERROR_TIMED_OUT = TIZEN_ERROR_TIMED_OUT, /**< Timed out */
+ MQTT_PLUGIN_ERROR_OPERATION_FAILED = TIZEN_ERROR_CION | 0x01, /**< Operation failed */
+} <MODULE_PREFIX>_error_e;
+
+enum MqttProtocol {
+ MQTT_TYPE_MQTT = (0x1 << 0), // Publish message through the MQTT
+ MQTT_TYPE_TCP = (0x1 << 1), // Publish message to peers using the TCP
+ MQTT_TYPE_UDP = (0x1 << 2), // Publish message to peers using the UDP
+ MQTT_TYPE_SRTP = (0x1 << 3), // Publish message to peers using the SRTP
+ MQTT_TYPE_WEBRTC = (0x1 << 4), // Publish message to peers using the WEBRTC
+};
+
+/**
+ * @brief The mqtt plugin peer info handle.
+ */
+typedef void *<MODULE_PREFIX>_peer_info_h;
+
+)__c_cb";
+
+constexpr const char __CLIENT_HEADER_HANDLES[] =
+R"__c_cb(
+ /**
+ * @brief The mqtt client handle.
+ */
+typedef void *<MODULE_PREFIX>_client_h;
+
+)__c_cb";
+
+constexpr const char __CLIENT_SERVER_HANDLES[] =
+R"__c_cb(
+ /**
+ * @brief The mqtt server handle.
+ */
+typedef void *<MODULE_PREFIX>_server_h;
+
+)__c_cb";
+
+constexpr const char __COMMON_HEADER_CONNECTION_RESULT_HANDLE[] =
+R"__c_cb(
+typedef enum _mqtt_connection_status_e {
+ MQTT_PLUGIN_CONNECTION_STATUS_OK, /**< Connection is ok **/
+ MQTT_PLUGIN_CONNECTION_STATUS_REJECTED, /**< Connection is rejected **/
+ MQTT_PLUGIN_CONNECTION_STATUS_ERROR, /**< Connection error occurs **/
+} <MODULE_PREFIX>_connection_status_e;
+
+/**
+ * @brief The Mqtt plugin connection result handle.
+ */
+typedef void *<MODULE_PREFIX>_connection_result_h;
+
+)__c_cb";
+
+constexpr const char __COMMON_HEADER_COMMON_BASE[] =
+R"__c_cb(
+/**
+ * @brief Creates a clone of mqtt plugin peer info handle.
+ * @remarks @a peer_info_clone must be released using <MODULE_PREFIX>_peer_info_destroy().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] peer_info_clone The cloned peer information handle
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MQTT_PLUGIN_ERROR_IO_ERROR IO error
+ * @see <MODULE_PREFIX>_peer_info_destroy()
+ */
+int <MODULE_PREFIX>_peer_info_clone(const <MODULE_PREFIX>_peer_info_h peer_info,
+ <MODULE_PREFIX>_peer_info_h *peer_info_clone);
+
+/**
+ * @brief Destroys the peer info handle and releases all its resources.
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <MODULE_PREFIX>_peer_info_clone()
+ */
+int <MODULE_PREFIX>_peer_info_destroy(<MODULE_PREFIX>_peer_info_h peer_info);
+
+/**
+ * @brief Gets the device ID.
+ * @remarks @a device_id must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] device_id The device ID
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_device_id(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_id);
+
+/**
+ * @brief Gets the device name.
+ * @remarks @a device_name must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] device_name The device name
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_device_name(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_name);
+
+/**
+ * @brief Gets the device's platform.
+ * @remarks @a device_platform must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] device_platform The platform name
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_device_platform(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_platform);
+
+/**
+ * @brief Gets the device's platform version.
+ * @remarks @a device_platform_version must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] device_platform_version The platform version
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_device_platform_version(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_platform_version);
+
+/**
+ * @brief Gets the device's type.
+ * @remarks @a device_type must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] device_type Device type
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_device_type(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_type);
+
+/**
+ * @brief Gets application ID of peer.
+ * @remarks @a app_id must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] app_id The application ID
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_app_id(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **app_id);
+
+/**
+ * @brief Gets application version of peer.
+ * @remarks @a app_version must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] app_version The application version
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_app_version(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **app_version);
+
+/**
+ * @brief Gets UUID of peer.
+ * @remarks @a uuid must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] uuid The UUID
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_uuid(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **uuid);
+
+/**
+ * @brief Gets display name of peer.
+ * @details The custom name for service name. \n
+ * It is possible that @a display_name does not exist.
+ * @remarks @a display_name must be released using free().
+ * @param[in] peer_info The mqtt plugin peer information handle
+ * @param[out] display_name The display name
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_peer_info_get_display_name(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **display_name);
+
+)__c_cb";
+
+
+constexpr const char __COMMON_HEADER_PAYLOAD_BASE[] =
+R"__c_cb(
+/**
+ * @brief Saves the payload as a file.
+ * @remarks The @a path is absolute path.
+ * @remarks If the media storage is used, %http://tizen.org/privilege/mediastorage privilege is necessary. \n
+ * If the external storage is used, %http://tizen.org/privilege/externalstorage privilege is necessary.
+ * @param[in] payload The <MODULE_PREFIX>_payload handle
+ * @param[in] path The path of file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OPERATION_FAILED Operation failed
+ */
+int <MODULE_PREFIX>_payload_save_as_file(<MODULE_PREFIX>_payload_h payload, const char *path);
+
+/**
+ * @brief Gets the name of received file from the payload.
+ * @remarks @a file_name must be released using free().
+ * @param[in] payload The <MODULE_PREFIX>_payload handle
+ * @param[out] file_name The name of file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+
+int <MODULE_PREFIX>_payload_get_received_file_name(<MODULE_PREFIX>_payload_h payload,
+ char **file_name);
+
+/**
+ * @brief Gets the size of currently received file from the payload.
+ * @param[in] payload The <MODULE_PREFIX>_payload handle
+ * @param[out] bytes The size of file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <MODULE_PREFIX>_payload_get_received_bytes(<MODULE_PREFIX>_payload_h payload, uint64_t *bytes);
+
+/**
+ * @brief Gets the total size of file from the payload.
+ * @param[in] payload The <MODULE_PREFIX>_payload handle
+ * @param[out] bytes The size of file
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <MODULE_PREFIX>_payload_get_total_bytes(<MODULE_PREFIX>_payload_h payload, uint64_t *bytes);
+
+)__c_cb";
+
+constexpr const char __COMMON_HEADER_CONNECTION_RESULT_BASE[] =
+R"__c_cb(
+/**
+ * @brief Gets the connection result status.
+ * @param[in] result The connection result handle
+ * @param[out] status Connection result status
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <MODULE_PREFIX>_connection_result_get_status(const <MODULE_PREFIX>_connection_result_h result,
+ <MODULE_PREFIX>_connection_status_e *status);
+
+/**
+ * @brief Gets the connection result reason.
+ * @remarks @a reason must be released using free().
+ * @param[in] result The connection result handle
+ * @param[out] reason Connection result reason, should be freed after use
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MQTT_PLUGIN_ERROR_NONE Successful
+ * @retval #MQTT_PLUGIN_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MQTT_PLUGIN_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int <MODULE_PREFIX>_connection_result_get_reason(const <MODULE_PREFIX>_connection_result_h result,
+ char **reason);
+
+)__c_cb";
+
+constexpr const char __COMMON_BODY_PAYLOAD_BASE[] =
+R"__c_cb(
+int <MODULE_PREFIX>_payload_save_as_file(<MODULE_PREFIX>_payload_h payload, const char *path) {
+ return <INTERNAL_PREFIX>_payload_save_as_file(payload, path);
+}
+
+int <MODULE_PREFIX>_payload_get_received_file_name(<MODULE_PREFIX>_payload_h payload,
+ char **file_name) {
+ return <INTERNAL_PREFIX>_payload_get_received_file_name(payload, file_name);
+}
+
+int <MODULE_PREFIX>_payload_get_received_bytes(<MODULE_PREFIX>_payload_h payload, uint64_t *bytes) {
+ return <INTERNAL_PREFIX>_payload_get_received_bytes(payload, bytes);
+}
+
+int <MODULE_PREFIX>_payload_get_total_bytes(<MODULE_PREFIX>_payload_h payload, uint64_t *bytes) {
+ return <INTERNAL_PREFIX>_payload_get_total_bytes(payload, bytes);
+}
+
+)__c_cb";
+
+constexpr const char __COMMON_BODY_CONNECTION_RESULT_BASE[] =
+R"__c_cb(
+int <MODULE_PREFIX>_connection_result_get_status(const <MODULE_PREFIX>_connection_result_h result,
+ <MODULE_PREFIX>_connection_status_e *status) {
+ return <INTERNAL_PREFIX>_connection_result_get_status(result,(<INTERNAL_PREFIX>_connection_status_e *)status);
+}
+
+int <MODULE_PREFIX>_connection_result_get_reason(const <MODULE_PREFIX>_connection_result_h result,
+ char **reason) {
+ return <INTERNAL_PREFIX>_connection_result_get_reason(result, reason);
+}
+
+)__c_cb";
+
+constexpr const char __COMMON_BODY_PEERINFO_BASE[] =
+R"__c_cb(
+int <MODULE_PREFIX>_peer_info_clone(const <MODULE_PREFIX>_peer_info_h peer_info,
+ <MODULE_PREFIX>_peer_info_h *peer_info_clone) {
+ return <INTERNAL_PREFIX>_peer_info_clone(peer_info, peer_info_clone);
+}
+
+int <MODULE_PREFIX>_peer_info_destroy(<MODULE_PREFIX>_peer_info_h peer_info) {
+ return <INTERNAL_PREFIX>_peer_info_destroy(peer_info);
+}
+
+int <MODULE_PREFIX>_peer_info_get_device_id(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_id) {
+ return <INTERNAL_PREFIX>_peer_info_get_device_id(peer_info, device_id);
+}
+
+int <MODULE_PREFIX>_peer_info_get_device_name(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_name) {
+ return <INTERNAL_PREFIX>_peer_info_get_device_name(peer_info, device_name);
+}
+
+int <MODULE_PREFIX>_peer_info_get_device_platform(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_platform) {
+ return <INTERNAL_PREFIX>_peer_info_get_device_platform(peer_info, device_platform);
+}
+
+int <MODULE_PREFIX>_peer_info_get_device_platform_version(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_platform_version) {
+ return <INTERNAL_PREFIX>_peer_info_get_device_platform_version(peer_info, device_platform_version);
+}
+
+int <MODULE_PREFIX>_peer_info_get_device_type(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **device_type) {
+ return <INTERNAL_PREFIX>_peer_info_get_device_type(peer_info, device_type);
+}
+
+int <MODULE_PREFIX>_peer_info_get_app_id(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **app_id) {
+ return <INTERNAL_PREFIX>_peer_info_get_app_id(peer_info, app_id);
+}
+
+int <MODULE_PREFIX>_peer_info_get_app_version(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **app_version) {
+ return <INTERNAL_PREFIX>_peer_info_get_app_version(peer_info, app_version);
+}
+
+int <MODULE_PREFIX>_peer_info_get_uuid(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **uuid) {
+ return <INTERNAL_PREFIX>_peer_info_get_uuid(peer_info, uuid);
+}
+
+int <MODULE_PREFIX>_peer_info_get_display_name(<MODULE_PREFIX>_peer_info_h peer_info,
+ char **display_name) {
+ return <INTERNAL_PREFIX>_peer_info_get_display_name(peer_info, display_name);
+}
+
+)__c_cb";
+
+namespace tidl {
+
+std::string MqttPluginCppTransportable::GenInclude(int type) const {
+ return "#include \"<FILENAME>_internal.h\"";
+}
+
+std::string MqttPluginCppTransportable::GenHeaderBase() const {
+ return __COMMON_HEADER_COMMON_BASE;
+}
+
+std::string MqttPluginCppTransportable::GenHeaderPayloadHandle() const {
+ return __COMMON_HEADER_PAYLOAD_HANDLE;
+}
+
+std::string MqttPluginCppTransportable::GenHeaderCommonHandle() const {
+ return __COMMON_HEADER_HANDLES;
+}
+
+std::string MqttPluginCppTransportable::GenHeaderClientHandle() const {
+ return __CLIENT_HEADER_HANDLES;
+}
+
+std::string MqttPluginCppTransportable::GenHeaderServerHandle() const {
+ return __CLIENT_SERVER_HANDLES;
+}
+std::string MqttPluginCppTransportable::GenHeaderGroupHandle() const {
+ return __GROUP_HANDLES;
+}
+
+std::string MqttPluginCppTransportable::GenHeaderConnectionHandle() const {
+ return __COMMON_HEADER_CONNECTION_RESULT_HANDLE;
+}
+
+std::string MqttPluginCppTransportable::GenHeaderPayloadBase() const {
+ return __COMMON_HEADER_PAYLOAD_BASE;
+}
+
+std::string MqttPluginCppTransportable::GenHeaderConnectionBase() const {
+ return __COMMON_HEADER_CONNECTION_RESULT_BASE;
+}
+
+std::string MqttPluginCppTransportable::GenBodyPayloadBase() const {
+ return __COMMON_BODY_PAYLOAD_BASE;
+}
+
+std::string MqttPluginCppTransportable::GenBodyConnectionBase() const {
+ return __COMMON_BODY_CONNECTION_RESULT_BASE;
+}
+
+std::string MqttPluginCppTransportable::GenBodyPeerInfoBase() const {
+ return __COMMON_BODY_PEERINFO_BASE;
+}
+
+std::string MqttPluginCppTransportable::GenNamespace() const {
+ return "mqtt";
+}
+
+std::string MqttPluginCppTransportable::GenProxyPrefix() const {
+ return "mqtt_plugin_proxy";
+}
+
+std::string MqttPluginCppTransportable::GenStubPrefix() const {
+ return "mqtt_plugin_stub";
+}
+
+std::string MqttPluginCppTransportable::GenGroupPrefix() const {
+ return "mqtt_plugin_group";
+}
+
+std::string MqttPluginCppTransportable::GenModulePrefix() const {
+ return "mqtt_plugin";
+}
+
+std::string MqttPluginCppTransportable::GenErrorPrefix() const {
+ return "MQTT_PLUGIN";
+}
+
+std::string MqttPluginCppTransportable::GenConnectionResultPrefix() const {
+ return "";
+}
+
+std::string MqttPluginCppTransportable::GenClientSendAsync(std::string client,
+ std::string payload, std::string size) const {
+ return std::string(ReplaceAll(__CLIENT_SEND_ASYNC, {
+ { "<CLIENT>", client },
+ { "<PAYLOAD>", payload},
+ { "<SIZE>", size} }));
+}
+
+std::string MqttPluginCppTransportable::GenClientSend(std::string client,
+ std::string data, std::string data_size,
+ std::string ret_data, std::string ret_data_size) const {
+ return std::string(ReplaceAll(__CLIENT_SEND, {
+ { "<CLIENT>", client },
+ { "<DATA>", data},
+ { "<DATA_SIZE>", data_size},
+ { "<RET_DATA>", ret_data},
+ { "<RET_DATA_SIZE>", ret_data_size} }));
+}
+
+std::string MqttPluginCppTransportable::GenServerSendAsync(std::string server,
+ std::string client,
+ std::string payload, std::string size) const {
+ return std::string(ReplaceAll(__SERVER_SEND_ASYNC, {
+ { "<SERVER>", server },
+ { "<CLIENT>", client},
+ { "<PAYLOAD>", payload},
+ { "<SIZE>", size} }));
+}
+
+std::string MqttPluginCppTransportable::GenServerFileSend(std::string path,
+ std::string server, std::string peer) const {
+ return std::string(ReplaceAll(__SERVER_FILE_SEND, {
+ { "<FILE_PATH>", path },
+ { "<SERVER_H>", server },
+ { "<PEER_H>", peer } }));
+}
+
+std::string MqttPluginCppTransportable::GenClientFileSend(std::string path,
+ std::string client) const {
+ return std::string(ReplaceAll(__CLINET_FILE_SEND, {
+ { "<FILE_PATH>", path },
+ { "<CLIENT_H>", client } }));
+}
+
+std::string MqttPluginCppTransportable::GenGroupType() const {
+ return "<MODULE_PREFIX>_group_h";
+}
+
+std::string MqttPluginCppTransportable::GenPayloadTransferStatusType(bool internal_type) const {
+ if (internal_type)
+ return "<INTERNAL_PREFIX>_transfer_status_e";
+ else
+ return "<MODULE_PREFIX>_payload_transfer_status_e";
+}
+
+std::string MqttPluginCppTransportable::GenPayloadAsyncResultType() const {
+ return "<MODULE_PREFIX>_payload_async_result_h";
+}
+
+std::string MqttPluginCppTransportable::GenPeerInfoType() const {
+ return "<MODULE_PREFIX>_peer_info_h";
+}
+
+std::string MqttPluginCppTransportable::GenPeerInfoDestroy(
+ std::string peer) const {
+ return std::string(ReplaceAll("<MODULE_PREFIX>_peer_info_destroy(<PEER>);", {
+ { "<PEER>", peer } }));
+}
+
+std::string MqttPluginCppTransportable::GenPayloadType() const {
+ return "<MODULE_PREFIX>_payload_h";
+}
+
+std::string MqttPluginCppTransportable::GenClientType() const {
+ return "<MODULE_PREFIX>_client_h";
+}
+
+std::string MqttPluginCppTransportable::GenSecurityType(bool definition) const {
+ return "";
+}
+
+std::string MqttPluginCppTransportable::GenServerType() const {
+ return "<MODULE_PREFIX>_server_h";
+}
+
+std::string MqttPluginCppTransportable::GenClientTryConnect(std::string client,
+ std::string peer) const {
+ return std::string(ReplaceAll(__CLIENT_TRY_CONNECT, {
+ { "<CLIENT>", client },
+ { "<PEER>", peer } }));
+}
+
+std::string MqttPluginCppTransportable::GenClientDisconnect(
+ std::string client) const {
+ return std::string(ReplaceAll(__CLIENT_DISCONNECT, {
+ { "<CLIENT>", client } }));
+}
+
+std::string MqttPluginCppTransportable::GenClientTryDiscovery(
+ std::string client) const {
+ return std::string(ReplaceAll(__CLIENT_TRY_DISCOVERY, {
+ { "<CLIENT>", client } }));
+}
+
+std::string MqttPluginCppTransportable::GenClientStopDiscovery(
+ std::string client) const {
+ return std::string(ReplaceAll(__CLIENT_STOP_DISCOVERY, {
+ { "<CLIENT>", client } }));
+}
+
+std::string MqttPluginCppTransportable::GenServerRegister() const {
+ return __SERVER_REGISTER;
+}
+
+std::string MqttPluginCppTransportable::GenServerUnregister() const {
+ return __SERVER_UNREGISTER;
+}
+
+std::string MqttPluginCppTransportable::GenClientExtraHeader() const {
+ return "";
+}
+
+std::string MqttPluginCppTransportable::GenClientExtraBody() const {
+ return "";
+}
+
+std::string MqttPluginCppTransportable::GenServerExtraHeader() const {
+ return "";
+}
+
+std::string MqttPluginCppTransportable::GenServerExtraBody() const {
+ return "";
+}
+
+std::string MqttPluginCppTransportable::GenServerAccept() const {
+ return __SERVER_ACCEPT;
+}
+
+std::string MqttPluginCppTransportable::GenServerReject() const {
+ return __SERVER_REJECT;
+}
+
+std::string MqttPluginCppTransportable::GenServerSetDisplayName() const {
+ return __SERVER_SET_DISPLAY_NAME;
+}
+
+std::string MqttPluginCppTransportable::GenGroupPublish() const {
+ return __GROUP_PUBLISH;
+}
+
+std::string MqttPluginCppTransportable::GenPayloadTypeEnum() const {
+ return "<INTERNAL_PREFIX>_payload_type_e";
+}
+
+std::string MqttPluginCppTransportable::GenPayloadTypeData() const {
+ return "MQTT_PLUGIN_PAYLOAD_TYPE_DATA";
+}
+
+std::string MqttPluginCppTransportable::GenPayloadTypeFile() const {
+ return "MQTT_PLUGIN_PAYLOAD_TYPE_FILE";
+}
+
+std::string MqttPluginCppTransportable::GenPayloadGetType() const {
+ return "ret = <INTERNAL_PREFIX>_payload_get_type(payload, &type);";
+}
+
+std::string MqttPluginCppTransportable::GenErrorNone() const {
+ return "MQTT_PLUGIN_ERROR_NONE";
+}
+
+std::string MqttPluginCppTransportable::GenPayloadGetData() const {
+ return "ret = <INTERNAL_PREFIX>_payload_get_data(payload, &data, &size);";
+}
+
+std::string MqttPluginCppTransportable::GenClientCreate() const {
+ return __CLIENT_CREATE;
+}
+
+std::string MqttPluginCppTransportable::GenGroupCreate() const {
+ return __GROUP_CREATE;
+}
+
+std::string MqttPluginCppTransportable::GenGroupDestroy() const {
+ return __GROUP_DESTROY;
+}
+
+std::string MqttPluginCppTransportable::GenClientDestroy() const {
+ return __CLIENT_DESTROY;
+}
+
+std::string MqttPluginCppTransportable::GenSetSecurityCA(std::string arg) const {
+ return "";
+}
+
+std::string MqttPluginCppTransportable::GenSetSecurityCert(std::string arg) const {
+ return "";
+}
+
+std::string MqttPluginCppTransportable::GenSetSecurityPrivateKey(
+ std::string arg) const {
+ return "";
+}
+
+std::string MqttPluginCppTransportable::GenPeerInfoClone(std::string src_peer,
+ std::string dest_peer) const {
+ return std::string(ReplaceAll(__PEER_INFO_CLONE, {
+ { "<SRC_PEER>", src_peer },
+ { "<DEST_PEER>", dest_peer } }));
+}
+
+std::string MqttPluginCppTransportable::GenServerSetOnDemandLaunchEnabled() const {
+ return "";
+}
+
+std::string MqttPluginCppTransportable::GenServerListen() const {
+ return __SERVER_LISTEN;
+}
+
+std::string MqttPluginCppTransportable::GenServerDisconnect(std::string server,
+ std::string peer) const {
+ return std::string(ReplaceAll(__SERVER_DISCONNECT, {
+ { "<SERVER>", server },
+ { "<PEER>", peer } }));
+}
+
+std::string MqttPluginCppTransportable::GenPeerInfoGetAppID(std::string peer,
+ std::string appid) const {
+ return std::string(ReplaceAll(__PEER_INFO_GET_APPID, {
+ { "<PEER>", peer},
+ { "<APPID>", appid} }));
+}
+
+std::string MqttPluginCppTransportable::GenPeerInfoGetUUID(std::string peer,
+ std::string uuid) const {
+ return std::string(ReplaceAll(__PEER_INFO_GET_UUID, {
+ { "<PEER>", peer},
+ { "<UUID>", uuid} }));
+}
+
+} // namespace tidl
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_cpp_transportable.h b/idlc/gen_mqtt_plugin/mqtt_plugin_cpp_transportable.h
new file mode 100644
index 0000000..d55507e
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_cpp_transportable.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_MQTT_PLUGIN_CPP_TRANSPORTABLE_H_
+#define IDLC_GEN_MQTT_PLUGIN_CPP_TRANSPORTABLE_H_
+
+#include <string>
+
+#include "idlc/gen_cion/cpp_transportable.h"
+
+namespace tidl {
+
+class MqttPluginCppTransportable : public CppTransportable {
+ public:
+ virtual ~MqttPluginCppTransportable() = default;
+ std::string GenInclude(int type = 0) const override;
+ std::string GenClientSendAsync(std::string client,
+ std::string payload, std::string size) const override;
+ std::string GenClientSend(std::string client, std::string data,
+ std::string data_size, std::string ret_data,
+ std::string ret_data_size) const override;
+ std::string GenServerSendAsync(std::string server, std::string client,
+ std::string payload, std::string size) const override;
+ std::string GenServerFileSend(std::string path,
+ std::string server, std::string peer) const override;
+ std::string GenClientFileSend(std::string path,
+ std::string client) const override;
+ std::string GenGroupType() const override;
+ std::string GenPayloadTransferStatusType(bool internal_type = false) const override;
+ std::string GenPayloadAsyncResultType() const override;
+ std::string GenPeerInfoType() const override;
+ std::string GenPeerInfoDestroy(std::string peer) const override;
+ std::string GenPayloadType() const override;
+ std::string GenClientType() const override;
+ std::string GenSecurityType(bool definition = true) const override;
+ std::string GenServerType() const override;
+ std::string GenClientTryConnect(std::string client,
+ std::string peer) const override;
+ std::string GenClientDisconnect(std::string client) const override;
+ std::string GenClientTryDiscovery(std::string client) const override;
+ std::string GenClientStopDiscovery(std::string client) const override;
+ std::string GenServerRegister() const override;
+ std::string GenServerUnregister() const override;
+ std::string GenClientExtraHeader() const override;
+ std::string GenClientExtraBody() const override;
+ std::string GenServerExtraHeader() const override;
+ std::string GenServerExtraBody() const override;
+ std::string GenServerAccept() const override;
+ std::string GenServerReject() const override;
+ std::string GenServerSetDisplayName() const override;
+ std::string GenGroupPublish() const override;
+ std::string GenPayloadTypeEnum() const override;
+ std::string GenPayloadTypeData() const override;
+ std::string GenPayloadTypeFile() const override;
+ std::string GenPayloadGetType() const override;
+ std::string GenErrorNone() const override;
+ std::string GenPayloadGetData() const override;
+ std::string GenClientCreate() const override;
+ std::string GenGroupCreate() const override;
+ std::string GenGroupDestroy() const override;
+ std::string GenClientDestroy() const override;
+ std::string GenSetSecurityCA(std::string arg) const override;
+ std::string GenSetSecurityCert(std::string arg) const override;
+ std::string GenSetSecurityPrivateKey(std::string arg) const override;
+ std::string GenPeerInfoClone(std::string src_peer,
+ std::string dest_peer) const override;
+ std::string GenServerSetOnDemandLaunchEnabled() const override;
+ std::string GenServerListen() const override;
+ std::string GenServerDisconnect(std::string server,
+ std::string peer) const override;
+ std::string GenPeerInfoGetAppID(std::string peer,
+ std::string appid) const override;
+ std::string GenPeerInfoGetUUID(std::string peer,
+ std::string uuid) const override;
+ std::string GenHeaderBase() const override;
+ std::string GenHeaderPayloadHandle() const override;
+ std::string GenHeaderCommonHandle() const override;
+ std::string GenHeaderClientHandle() const override;
+ std::string GenHeaderServerHandle() const override;
+ std::string GenHeaderGroupHandle() const override;
+ std::string GenHeaderConnectionHandle() const override;
+ std::string GenHeaderPayloadBase() const override;
+ std::string GenHeaderConnectionBase() const override;
+ std::string GenBodyPayloadBase() const override;
+ std::string GenBodyConnectionBase() const override;
+ std::string GenBodyPeerInfoBase() const override;
+ std::string GenNamespace() const override;
+ std::string GenProxyPrefix() const override;
+ std::string GenStubPrefix() const override;
+ std::string GenGroupPrefix() const override;
+ std::string GenModulePrefix() const override;
+ std::string GenErrorPrefix() const override;
+ std::string GenConnectionResultPrefix() const override;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_MQTT_PLUGIN_CPP_TRANSPORTABLE_H_ \ No newline at end of file
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_cs_base_gen.cc b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_base_gen.cc
new file mode 100644
index 0000000..1ec6b6f
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_base_gen.cc
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_cs_base_gen.h"
+
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_cs_base_gen_cb.h"
+
+namespace tidl {
+
+MqttPluginCsBaseGen::MqttPluginCsBaseGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans) : CionPluginBase(doc, trans) {
+}
+
+void MqttPluginCsBaseGen::OnInitGen(std::ofstream& stream) {
+ GenUsing(stream);
+ stream << "namespace Tizen.Applications.MqttPlugin\n";
+ stream << "{\n";
+ GenBase(stream);
+ stream << "}\n";
+}
+
+void MqttPluginCsBaseGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void MqttPluginCsBaseGen::GenUsing(std::ofstream& stream) {
+ stream << CB_BASE_USING;
+}
+
+void MqttPluginCsBaseGen::GenBase(std::ofstream& stream) {
+ stream << CB_ERROR_FACTORY;
+ stream << CB_DATA_PAYLOAD;
+ stream << CB_FILE_PAYLOAD;
+ stream << CB_PEER_INFO;
+ stream << CB_PEER_INFO_SAFE_HANDLE;
+ stream << CB_PAYLOAD;
+ stream << CB_PAYLOAD_ASYNC_RESULT;
+ stream << CB_PAYLOAD_ASYNC_RESULT_CODE;
+ stream << CB_PAYLOAD_SAFE_HANDLE;
+ stream << CB_PAYLOAD_TRANSFER_STATUS;
+ stream << CB_PAYLOAD_TYPE;
+ stream << CB_CONNECTION_RESULT;
+ stream << CB_CONNECTION_STATUS;
+
+ switch (GetChannelType()) {
+ case ChannelType::TYPE_PROXY:
+ stream << CB_CLIENT_SAFE_HANDLE;
+ stream << CB_CLIENT_BASE;
+ break;
+ case ChannelType::TYPE_STUB:
+ stream << CB_SERVER_SAFE_HANDLE;
+ stream << CB_SERVER_BASE;
+ break;
+ case ChannelType::TYPE_GROUP:
+ stream << CB_GROUP_SAFE_HANDLE;
+ stream << CB_GROUP_BASE;
+ break;
+ default:
+ break;
+ }
+}
+
+} // namespace tidl
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_cs_base_gen.h b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_base_gen.h
new file mode 100644
index 0000000..5e9dc9e
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_base_gen.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_MQTT_PLUGIN_MQTT_PLUGIN_CS_BASE_GEN_H_
+#define IDLC_GEN_MQTT_PLUGIN_MQTT_PLUGIN_CS_BASE_GEN_H_
+
+#include <memory>
+
+#include "idlc/gen_cion/cion_plugin_base.h"
+
+namespace tidl {
+
+class MqttPluginCsBaseGen : public CionPluginBase {
+ public:
+ explicit MqttPluginCsBaseGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~MqttPluginCsBaseGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenUsing(std::ofstream& stream);
+ void GenBase(std::ofstream& stream);
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_MQTT_PLUGIN_MQTT_PLUGIN_CS_BASE_GEN_H_
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_cs_base_gen_cb.h b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_base_gen_cb.h
new file mode 100644
index 0000000..a30bc14
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_base_gen_cb.h
@@ -0,0 +1,1301 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_MQTT_PLUGIN_MQTT_PLUGIN_CS_BASE_GEN_CB_H_
+#define IDLC_GEN_MQTT_PLUGIN_MQTT_PLUGIN_CS_BASE_GEN_CB_H_
+
+constexpr char CB_BASE_USING[] =
+R"__cs_cb(
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+)__cs_cb";
+
+constexpr char CB_ERROR_FACTORY[] =
+R"__cs_cb(
+ internal static class MqttPluginErrorFactory
+ {
+ internal static Exception GetException(Interop.MqttPlugin.ErrorCode err, string message)
+ {
+ string errMessage = string.Format("{0} err = {1}", message, err);
+ switch (err)
+ {
+ case Interop.MqttPlugin.ErrorCode.IoError:
+ return new InvalidOperationException(errMessage);
+ case Interop.MqttPlugin.ErrorCode.OutOfMemory:
+ return new InvalidOperationException(errMessage);
+ case Interop.MqttPlugin.ErrorCode.PermissionDenied:
+ return new UnauthorizedAccessException(errMessage);
+ case Interop.MqttPlugin.ErrorCode.InvalidParameter:
+ return new ArgumentException(errMessage);
+ case Interop.MqttPlugin.ErrorCode.InvalidOperation:
+ return new InvalidOperationException(errMessage);
+ case Interop.MqttPlugin.ErrorCode.AlreadyInProgress:
+ return new InvalidOperationException(errMessage);
+ case Interop.MqttPlugin.ErrorCode.NotSupported:
+ return new NotSupportedException(errMessage);
+ case Interop.MqttPlugin.ErrorCode.TimedOut:
+ return new TimeoutException(errMessage);
+ case Interop.MqttPlugin.ErrorCode.OperationFailed:
+ return new InvalidOperationException(errMessage);
+ default:
+ return new InvalidOperationException(errMessage);
+ }
+ }
+ }
+)__cs_cb";
+
+constexpr char CB_CLIENT_BASE[] =
+R"__cs_cb(
+ public abstract class ClientBase : IDisposable
+ {
+ private readonly string LogTag = "Tizen.Applications.MqttPlugin";
+ private readonly ClientSafeHandle _handle;
+
+ private PeerInfo _peer;
+
+ private Interop.MqttPluginClient.MqttPluginClientServerDiscoveredCb _discoveredCb;
+ private Interop.MqttPluginClient.MqttPluginClientConnectionResultCb _connectionResultCb;
+ private Interop.MqttPluginClient.MqttPluginClientPayloadReceivedCb _payloadRecievedCb;
+ private Interop.MqttPluginClient.MqttPluginClientDisconnectedCb _disconnectedCb;
+ private Dictionary<string, TaskCompletionSource<PayloadAsyncResult>> _tcsDictionary = new Dictionary<string, TaskCompletionSource<PayloadAsyncResult>>();
+ private Dictionary<string, Interop.MqttPluginClient.MqttPluginClientPayloadAsyncResultCb> _payloadAsyncCbDictionary = new Dictionary<string, Interop.MqttPluginClient.MqttPluginClientPayloadAsyncResultCb>();
+
+ public string ServiceName { get; }
+
+ public PeerInfo PeerInfo
+ {
+ get
+ {
+ return _peer;
+ }
+ }
+
+ public ClientBase(string serviceName, string brokerIp, int brokerPort, string userName, string password)
+ {
+ ServiceName = serviceName;
+
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginClient.MqttPluginClientCreate(out _handle, serviceName, brokerIp, brokerPort, userName, password);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to create client.");
+ }
+
+ _connectionResultCb = new Interop.MqttPluginClient.MqttPluginClientConnectionResultCb(
+ (string service, IntPtr peerInfo, IntPtr result, IntPtr userData) =>
+ {
+ Interop.MqttPlugin.ErrorCode clone_ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, string.Format("Failed to clone peer info."));
+ return;
+ }
+
+ PeerInfo peer = new PeerInfo(clone);
+ ConnectionResult connectionResult = new ConnectionResult(result);
+ if (connectionResult.Status == ConnectionStatus.OK)
+ {
+ _peer = peer;
+ }
+
+ OnConnectionResult(peer, connectionResult);
+ });
+ ret = Interop.MqttPluginClient.MqttPluginClientAddConnectionResultCb(_handle, _connectionResultCb, IntPtr.Zero);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to add connection status changed callback.");
+ }
+
+ _payloadRecievedCb = new Interop.MqttPluginClient.MqttPluginClientPayloadReceivedCb(
+ (string service, IntPtr peerInfo, IntPtr payload, int status, IntPtr userData) =>
+ {
+ Payload receivedPayload;
+ Interop.MqttPluginPayload.MqttPluginPayloadGetType(payload, out Interop.MqttPluginPayload.PayloadType type);
+ switch (type)
+ {
+ case Interop.MqttPluginPayload.PayloadType.Data:
+ receivedPayload = new DataPayload(new PayloadSafeHandle(payload, false));
+ break;
+ case Interop.MqttPluginPayload.PayloadType.File:
+ receivedPayload = new FilePayload(new PayloadSafeHandle(payload, false));
+ break;
+ default:
+ Log.Error(LogTag, "Invalid payload type received.");
+ return;
+ }
+ OnPayloadReceived(receivedPayload, (PayloadTransferStatus)status);
+ });
+ ret = Interop.MqttPluginClient.MqttPluginClientAddPayloadReceivedCb(_handle, _payloadRecievedCb, IntPtr.Zero);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to add payload received callback.");
+ }
+
+ _disconnectedCb = new Interop.MqttPluginClient.MqttPluginClientDisconnectedCb(
+ (string service, IntPtr peerInfo, IntPtr userData) =>
+ {
+ Interop.MqttPlugin.ErrorCode clone_ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, string.Format("Failed to clone peer info."));
+ return;
+ }
+ OnDisconnected(new PeerInfo(clone));
+ });
+ ret = Interop.MqttPluginClient.MqttPluginClientAddDisconnectedCb(_handle, _disconnectedCb, IntPtr.Zero);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to add disconnected callback.");
+ }
+ }
+
+ public void TryDiscovery()
+ {
+ if (_discoveredCb == null)
+ {
+ Interop.MqttPluginClient.MqttPluginClientServerDiscoveredCb cb = new Interop.MqttPluginClient.MqttPluginClientServerDiscoveredCb(
+ (string serviceName, IntPtr peerInfo, IntPtr userData) =>
+ {
+ Interop.MqttPlugin.ErrorCode clone_ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to clone peer info.");
+ return;
+ }
+ OnDiscovered(new PeerInfo(clone));
+ });
+ _discoveredCb = cb;
+ }
+
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginClient.MqttPluginClientTryDiscovery(_handle, _discoveredCb, IntPtr.Zero);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to try discovery.");
+ }
+ }
+
+ public void StopDiscovery()
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginClient.MqttPluginClientStopDiscovery(_handle);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to stop discovery.");
+ }
+ }
+
+ public void Connect(PeerInfo peer)
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginClient.MqttPluginClientConnect(_handle, peer?._handle);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to connect.");
+ }
+ }
+
+ public void Disconnect()
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginClient.MqttPluginClientDisconnect(_handle);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, string.Format("Failed to disconnect: {0}", ret));
+ }
+ _peer = null;
+ }
+
+ public byte[] SendData(byte[] data, int timeout)
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginClient.MqttPluginClientSendData(_handle, data, data?.Length ?? -1, timeout, out IntPtr returnDataPtr, out int returnDataSize);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to send data.");
+ }
+ byte[] returnData = new byte[returnDataSize];
+ Marshal.Copy(returnDataPtr, returnData, 0, returnDataSize);
+ Log.Info(LogTag, string.Format("Returned data size: {0}", returnDataSize));
+
+ return returnData;
+ }
+
+ public Task<PayloadAsyncResult> SendPayloadAsync(Payload payload)
+ {
+ if (payload == null || payload.Id.Length == 0)
+ {
+ throw new ArgumentException("Payload is invalid.");
+ }
+
+ if (_tcsDictionary.ContainsKey(payload.Id))
+ {
+ throw new InvalidOperationException("Payload is already sent.");
+ }
+
+ TaskCompletionSource<PayloadAsyncResult> tcs = new TaskCompletionSource<PayloadAsyncResult>();
+ _tcsDictionary[payload.Id] = tcs;
+
+ Interop.MqttPluginClient.MqttPluginClientPayloadAsyncResultCb cb = new Interop.MqttPluginClient.MqttPluginClientPayloadAsyncResultCb(
+ (IntPtr result, IntPtr userData) =>
+ {
+ TaskCompletionSource<PayloadAsyncResult> tcsToReturn = _tcsDictionary[payload.Id];
+ PayloadAsyncResult resultPayload = null;
+ try
+ {
+ resultPayload = PayloadAsyncResult.CreateFromHandle(result);
+ }
+ catch (Exception e)
+ {
+ Log.Error(LogTag, string.Format("Failed to create PayloadAsyncResult from result handle: {0}.", e.Message));
+ tcsToReturn.SetException(e);
+ return;
+ }
+ tcsToReturn.SetResult(resultPayload);
+ _payloadAsyncCbDictionary.Remove(resultPayload.PayloadId);
+ _tcsDictionary.Remove(resultPayload.PayloadId);
+ });
+
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginClient.MqttPluginClientSendPayloadAsync(_handle, payload?._handle, cb, IntPtr.Zero);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to send payload.");
+ }
+
+ _payloadAsyncCbDictionary[payload?.Id] = cb;
+
+ return tcs.Task;
+ }
+
+ protected abstract void OnConnectionResult(PeerInfo peerInfo, ConnectionResult result);
+ protected abstract void OnPayloadReceived(Payload payload, PayloadTransferStatus status);
+ protected abstract void OnDiscovered(PeerInfo peerInfo);
+ protected abstract void OnDisconnected(PeerInfo peerInfo);
+
+ private bool disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ _handle.Dispose();
+ }
+ disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ }
+)__cs_cb";
+
+constexpr char CB_CLIENT_SAFE_HANDLE[] =
+R"__cs_cb(
+ internal sealed class ClientSafeHandle : SafeHandle
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public ClientSafeHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool IsInvalid
+ {
+ get { return this.DangerousGetHandle() == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.MqttPluginClient.MqttPluginClientDestroy(this.handle);
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+)__cs_cb";
+
+constexpr char CB_CONNECTION_RESULT[] =
+R"__cs_cb(
+ public class ConnectionResult
+ {
+ private readonly string _reason;
+ private readonly ConnectionStatus _status;
+
+ internal ConnectionResult(IntPtr handle)
+ {
+ Interop.MqttPluginConnectionResult.MqttPluginConnectionResultGetReason(handle, out _reason);
+ Interop.MqttPluginConnectionResult.MqttPluginConnectionResultGetStatus(handle, out _status);
+ }
+
+ public ConnectionStatus Status
+ {
+ get
+ {
+ return _status;
+ }
+ }
+
+ public string Reason
+ {
+ get
+ {
+ return _reason;
+ }
+ }
+ }
+)__cs_cb";
+
+constexpr char CB_CONNECTION_STATUS[] =
+R"__cs_cb(
+ public enum ConnectionStatus
+ {
+ OK,
+ Rejected,
+ Error,
+ }
+)__cs_cb";
+
+constexpr char CB_DATA_PAYLOAD[] =
+R"__cs_cb(
+ public class DataPayload : Payload
+ {
+ internal DataPayload(PayloadSafeHandle handle)
+ {
+ _handle = handle;
+ }
+
+ public DataPayload(byte[] data)
+ {
+ Interop.MqttPluginPayload.MqttPluginPayloadCreate(out _handle, Interop.MqttPluginPayload.PayloadType.Data);
+ Interop.MqttPluginPayload.MqttPluginPayloadSetData(_handle, data, data?.Length ?? -1);
+ }
+
+ public override PayloadType PayloadType
+ {
+ get
+ {
+ return PayloadType.DataPayload;
+ }
+ }
+
+ public byte[] Data
+ {
+ get
+ {
+ Interop.MqttPluginPayload.MqttPluginPayloadGetData(_handle, out IntPtr byteArrPtr, out int size);
+ byte[] byteArr = new byte[size];
+ Marshal.Copy(byteArrPtr, byteArr, 0, size);
+ return byteArr;
+ }
+ set
+ {
+ Interop.MqttPluginPayload.MqttPluginPayloadSetData(_handle, value, value?.Length ?? 0);
+ }
+ }
+ }
+)__cs_cb";
+
+constexpr char CB_FILE_PAYLOAD[] =
+R"__cs_cb(
+ public class FilePayload : Payload
+ {
+ private readonly string LogTag = "Tizen.Applications.MqttPlugin";
+
+ internal FilePayload(PayloadSafeHandle handle)
+ {
+ _handle = handle;
+ }
+
+ public FilePayload(string path)
+ {
+ Interop.MqttPluginPayload.MqttPluginPayloadCreate(out _handle, Interop.MqttPluginPayload.PayloadType.File);
+ Interop.MqttPluginPayload.MqttPluginPayloadSetFilePath(_handle, path);
+ }
+
+ public string ReceivedFileName
+ {
+ get
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginPayload.MqttPluginPayloadGetReceivedFileName(_handle, out string path);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ // property should not throw exception.
+ return "";
+ }
+ return path;
+ }
+ }
+
+ public UInt64 ReceivedBytes
+ {
+ get
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginPayload.MqttPluginPayloadGetReceivedBytes(_handle, out UInt64 bytes);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get received bytes.");
+ return Byte.MinValue;
+ }
+ return bytes;
+ }
+ }
+
+ public UInt64 TotalBytes
+ {
+ get
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginPayload.MqttPluginPayloadGetTotalBytes(_handle, out UInt64 bytes);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get total bytes.");
+ return Byte.MinValue;
+ }
+ return bytes;
+ }
+ }
+
+ public override PayloadType PayloadType
+ {
+ get
+ {
+ return PayloadType.FilePayload;
+ }
+ }
+
+ public void SaveAsFile(string path)
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginPayload.MqttPluginPayloadSaveAsFile(_handle, path);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to save as file.");
+ }
+ }
+ }
+)__cs_cb";
+
+constexpr char CB_GROUP_BASE[] =
+R"__cs_cb(
+ public abstract class GroupBase : IDisposable
+ {
+ private readonly string LogTag = "Tizen.Applications.MqttPlugin";
+ private readonly GroupSafeHandle _handle;
+
+ private Interop.MqttPluginGroup.MqttPluginGroupPayloadReceivedCb _payloadReceivedCb;
+ private Interop.MqttPluginGroup.MqttPluginGroupLeftCb _leftCb;
+ private Interop.MqttPluginGroup.MqttPluginGroupJoinedCb _joinedCb;
+
+ public string Topic { get; }
+
+ public GroupBase(string topicName, string brokerIp, int brokerPort, string userName, string password)
+ {
+ Topic = topicName;
+
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginGroup.MqttPluginGroupCreate(out _handle, topicName, brokerIp, brokerPort, userName, password);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to create group.");
+ }
+
+ _payloadReceivedCb = new Interop.MqttPluginGroup.MqttPluginGroupPayloadReceivedCb(
+ (IntPtr group, IntPtr peerInfo, IntPtr payload, IntPtr userData) =>
+ {
+ Payload receivedPayload;
+ Interop.MqttPluginPayload.MqttPluginPayloadGetType(payload, out Interop.MqttPluginPayload.PayloadType type);
+ switch (type)
+ {
+ case Interop.MqttPluginPayload.PayloadType.Data:
+ receivedPayload = new DataPayload(new PayloadSafeHandle(payload, false));
+ break;
+ case Interop.MqttPluginPayload.PayloadType.File:
+ receivedPayload = new FilePayload(new PayloadSafeHandle(payload, false));
+ break;
+ default:
+ Log.Error(LogTag, "Invalid payload type received.");
+ return;
+ }
+ Interop.MqttPlugin.ErrorCode clone_ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to clone peer info.");
+ return;
+ }
+ OnPayloadReceived(receivedPayload, new PeerInfo(clone));
+ });
+ ret = Interop.MqttPluginGroup.MqttPluginGroupAddPayloadReceivedCb(_handle, _payloadReceivedCb, IntPtr.Zero);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to add payload received callback.");
+ }
+
+ _joinedCb = new Interop.MqttPluginGroup.MqttPluginGroupJoinedCb(
+ (string name, IntPtr peerInfo, IntPtr userData) =>
+ {
+ Interop.MqttPlugin.ErrorCode clone_ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ return;
+ }
+ OnJoined(new PeerInfo(clone));
+ });
+ ret = Interop.MqttPluginGroup.MqttPluginGroupAddJoinedCb(_handle, _joinedCb, IntPtr.Zero);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to add joined callback.");
+ }
+
+ _leftCb = new Interop.MqttPluginGroup.MqttPluginGroupLeftCb(
+ (string name, IntPtr peerInfo, IntPtr userData) =>
+ {
+ Interop.MqttPlugin.ErrorCode clone_ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ return;
+ }
+ OnLeft(new PeerInfo(clone));
+ });
+ ret = Interop.MqttPluginGroup.MqttPluginGroupAddLeftCb(_handle, _leftCb, IntPtr.Zero);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to add joined callback.");
+ }
+ }
+
+ public void Subscribe()
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginGroup.MqttPluginGroupSubscribe(_handle);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to subscribe.");
+ }
+ }
+
+ public void Unsubscribe()
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginGroup.MqttPluginGroupUnsubscribe(_handle);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, string.Format("Failed to unsubscribe: {0}", ret));
+ }
+ }
+
+ public void Publish(Payload payload)
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginGroup.MqttPluginGroupPublish(_handle, payload?._handle);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to publish payload.");
+ }
+ }
+
+ protected abstract void OnPayloadReceived(Payload payload, PeerInfo peer);
+ protected abstract void OnJoined(PeerInfo peerInfo);
+ protected abstract void OnLeft(PeerInfo peerInfo);
+
+ private bool disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ _handle.Dispose();
+ }
+ disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ }
+)__cs_cb";
+
+constexpr char CB_GROUP_SAFE_HANDLE[] =
+R"__cs_cb(
+ internal sealed class GroupSafeHandle : SafeHandle
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public GroupSafeHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool IsInvalid
+ {
+ get { return this.DangerousGetHandle() == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.MqttPluginGroup.MqttPluginGroupDestroy(this.handle);
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+)__cs_cb";
+
+constexpr char CB_PAYLOAD[] =
+R"__cs_cb(
+ public abstract class Payload
+ {
+ private readonly string LogTag = "Tizen.Applications.MqttPlugin";
+ internal PayloadSafeHandle _handle;
+
+ public abstract PayloadType PayloadType { get; }
+
+ public string Id
+ {
+ get
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginPayload.MqttPluginPayloadGetPayloadID(_handle, out string id);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get id of payload.");
+ return "";
+ }
+ return id;
+ }
+ }
+ }
+)__cs_cb";
+
+constexpr char CB_PAYLOAD_ASYNC_RESULT[] =
+R"__cs_cb(
+ public class PayloadAsyncResult : IDisposable
+ {
+ private PayloadAsyncResult(PayloadAsyncResultCode result, PeerInfo peer, string payloadId)
+ {
+ Result = result;
+ PeerInfo = peer;
+ PayloadId = payloadId;
+ }
+
+ internal static PayloadAsyncResult CreateFromHandle(IntPtr handle)
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginPayloadAsyncResult.MqttPluginPayloadAsyncResultGetResult(handle, out int code);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Fail to get result code from the AsyncResult");
+ }
+
+ ret = Interop.MqttPluginPayloadAsyncResult.MqttPluginPayloadAsyncResultGetPayloadID(handle, out string payloadId);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Fail to get payload id from the AsyncResult");
+ }
+
+ ret = Interop.MqttPluginPayloadAsyncResult.MqttPluginPayloadAsyncResultGetPeerInfo(handle, out IntPtr peer);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Fail to get peerinfo from the AsyncResult");
+ }
+ ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoClone(peer, out PeerInfoSafeHandle clone);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to clone peer info.");
+ }
+
+ return new PayloadAsyncResult((PayloadAsyncResultCode)code, new PeerInfo(clone), payloadId);
+ }
+
+ public PayloadAsyncResultCode Result { get; }
+
+ public PeerInfo PeerInfo { get; }
+
+ public string PayloadId { get; }
+
+ private bool disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ PeerInfo?.Dispose();
+ }
+ disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ }
+)__cs_cb";
+
+constexpr char CB_PAYLOAD_ASYNC_RESULT_CODE[] =
+R"__cs_cb(
+ public enum PayloadAsyncResultCode
+ {
+ Error = -1,
+ Pending = 0,
+ Success,
+ Fail,
+ }
+)__cs_cb";
+
+constexpr char CB_PAYLOAD_SAFE_HANDLE[] =
+R"__cs_cb(
+ internal sealed class PayloadSafeHandle : SafeHandle
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public PayloadSafeHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ internal PayloadSafeHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool IsInvalid
+ {
+ get { return this.DangerousGetHandle() == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.MqttPluginPayload.MqttPluginPayloadDestroy(this.handle);
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+)__cs_cb";
+
+constexpr char CB_PAYLOAD_TRANSFER_STATUS[] =
+R"__cs_cb(
+ public enum PayloadTransferStatus
+ {
+ Success,
+ Failure,
+ InProgress,
+ }
+)__cs_cb";
+
+constexpr char CB_PAYLOAD_TYPE[] =
+R"__cs_cb(
+ public enum PayloadType
+ {
+ DataPayload,
+ FilePayload,
+ }
+)__cs_cb";
+
+constexpr char CB_PEER_INFO[] =
+R"__cs_cb(
+ public class PeerInfo : IDisposable
+ {
+ private readonly string LogTag = "Tizen.Applications.MqttPlugin";
+ internal PeerInfoSafeHandle _handle;
+
+ internal PeerInfo(PeerInfoSafeHandle handle)
+ {
+ _handle = handle;
+ }
+
+ public string DeviceId
+ {
+ get
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoGetDeviceId(_handle, out string deviceId);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get device id.");
+ return "";
+ }
+ return deviceId;
+ }
+ }
+
+ public string DeviceName
+ {
+ get
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoGetDeviceName(_handle, out string deviceName);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get device name.");
+ return "";
+ }
+ return deviceName;
+ }
+ }
+
+ public string DevicePlatform
+ {
+ get
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoGetDevicePlatform(_handle, out string devicePlatform);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get device platform.");
+ return "";
+ }
+ return devicePlatform;
+ }
+ }
+
+ public string DevicePlatformVersion
+ {
+ get
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoGetDevicePlatformVersion(_handle, out string devicePlatformVersion);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get device platform version.");
+ return "";
+ }
+ return devicePlatformVersion;
+ }
+ }
+
+ public string DeviceType
+ {
+ get
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoGetDeviceType(_handle, out string deviceType);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get device platform type.");
+ return "";
+ }
+ return deviceType;
+ }
+ }
+
+ public string AppId
+ {
+ get
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoGetAppId(_handle, out string AppId);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get application id.");
+ return "";
+ }
+ return AppId;
+ }
+ }
+
+ public string AppVersion
+ {
+ get
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoGetAppVersion(_handle, out string AppVersion);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get application version.");
+ return "";
+ }
+ return AppVersion;
+ }
+ }
+
+ public string UUID
+ {
+ get
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoGetUuid(_handle, out string uuid);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get UUID.");
+ return "";
+ }
+ return uuid;
+ }
+ }
+
+ private bool disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ _handle.Dispose();
+ }
+ disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ }
+)__cs_cb";
+
+constexpr char CB_PEER_INFO_SAFE_HANDLE[] =
+R"__cs_cb(
+ internal sealed class PeerInfoSafeHandle : SafeHandle
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public PeerInfoSafeHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ internal PeerInfoSafeHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool IsInvalid
+ {
+ get { return this.DangerousGetHandle() == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.MqttPluginPeerInfo.MqttPluginPeerInfoDestroy(this.handle);
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+)__cs_cb";
+
+constexpr char CB_SERVER_BASE[] =
+R"__cs_cb(
+ public abstract class ServerBase : IDisposable
+ {
+ private readonly string LogTag = "Tizen.Applications.MqttPlugin";
+
+ private string _displayName;
+ private readonly ServerSafeHandle _handle;
+ private Interop.MqttPluginServer.MqttPluginServerConnectionRequestCb _connectionRequestCb;
+ private Interop.MqttPluginServer.MqttPluginServerConnectionResultCb _connectionResultCb;
+ private Interop.MqttPluginServer.MqttPluginServerDataReceivedCb _dataReceivedCb;
+ private Interop.MqttPluginServer.MqttPluginServerPayloadReceivedCb _payloadRecievedCb;
+ private Interop.MqttPluginServer.MqttPluginServerDisconnectedCb _disconnectedCb;
+ private Interop.MqttPluginServer.MqttPluginServerPayloadAsyncResultCb _payloadAsyncResultCb;
+ private Dictionary<Tuple<string, string>, TaskCompletionSource<PayloadAsyncResult>> _tcsDictionary = new Dictionary<Tuple<string, string>, TaskCompletionSource<PayloadAsyncResult>>();
+
+ public string ServiceName { get; }
+
+ public string DisplayName
+ {
+ get
+ {
+ return _displayName;
+ }
+
+ set
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginServer.MqttPluginServerSetDisplayName(_handle, value);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, string.Format("Failed to set display name: {0}", ret));
+ }
+ else
+ {
+ _displayName = value;
+ }
+ }
+ }
+
+ public ServerBase(string serviceName, string displayName, string brokerIp, int brokerPort, string userName, string password)
+ {
+ ServiceName = serviceName;
+ _displayName = displayName;
+
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginServer.MqttPluginServerCreate(out _handle, serviceName, displayName, brokerIp, brokerPort, userName, password);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to create server handle.");
+ }
+
+ _connectionResultCb = new Interop.MqttPluginServer.MqttPluginServerConnectionResultCb(
+ (string service, IntPtr peerInfo, IntPtr result, IntPtr userData) =>
+ {
+ Interop.MqttPlugin.ErrorCode clone_ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to clone peer info.");
+ return;
+ }
+ OnConnectionResult(new PeerInfo(clone), new ConnectionResult(result));
+ });
+ ret = Interop.MqttPluginServer.MqttPluginServerAddConnectionResultCb(_handle, _connectionResultCb, IntPtr.Zero);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to add connection status changed callback.");
+ }
+
+ _dataReceivedCb = new Interop.MqttPluginServer.MqttPluginServerDataReceivedCb(
+ (string service, IntPtr peerInfo, IntPtr data, int dataSize, out IntPtr returnData, out int returnDataSize, IntPtr userData) =>
+ {
+ Interop.MqttPlugin.ErrorCode clone_ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to clone peer info.");
+ returnData = IntPtr.Zero;
+ returnDataSize = -1;
+ }
+ byte[] receivedData = new byte[dataSize];
+ Marshal.Copy(data, receivedData, 0, dataSize);
+ byte[] returnDataRaw = OnDataReceived(receivedData, new PeerInfo(clone));
+ returnDataSize = returnDataRaw.Length;
+ returnData = Interop.MqttPlugin.Malloc(returnDataSize);
+ Marshal.Copy(returnDataRaw, 0, returnData, returnDataSize);
+ });
+ ret = Interop.MqttPluginServer.MqttPluginServerSetDataReceivedCb(_handle, _dataReceivedCb, IntPtr.Zero);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to set data received callback.");
+ }
+
+ _payloadRecievedCb = new Interop.MqttPluginServer.MqttPluginServerPayloadReceivedCb(
+ (string service, IntPtr peerInfo, IntPtr payload, int status, IntPtr userData) =>
+ {
+ Payload receivedPayload;
+ Interop.MqttPluginPayload.MqttPluginPayloadGetType(payload, out Interop.MqttPluginPayload.PayloadType type);
+ switch (type)
+ {
+ case Interop.MqttPluginPayload.PayloadType.Data:
+ receivedPayload = new DataPayload(new PayloadSafeHandle(payload, false));
+ break;
+ case Interop.MqttPluginPayload.PayloadType.File:
+ receivedPayload = new FilePayload(new PayloadSafeHandle(payload, false));
+ break;
+ default:
+ Log.Error(LogTag, "Invalid payload type received.");
+ return;
+ }
+ Interop.MqttPlugin.ErrorCode clone_ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to clone peer info.");
+ return;
+ }
+ OnPayloadReceived(receivedPayload, new PeerInfo(clone), (PayloadTransferStatus)status);
+ });
+ ret = Interop.MqttPluginServer.MqttPluginServerAddPayloadReceivedCb(_handle, _payloadRecievedCb, IntPtr.Zero);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to add payload received callback.");
+ }
+
+ _disconnectedCb = new Interop.MqttPluginServer.MqttPluginServerDisconnectedCb(
+ (string service, IntPtr peerInfo, IntPtr userData) =>
+ {
+ Interop.MqttPlugin.ErrorCode clone_ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, string.Format("Failed to clone peer info."));
+ return;
+ }
+ OnDisconnected(new PeerInfo(clone));
+ });
+ ret = Interop.MqttPluginServer.MqttPluginServerAddDisconnectedCb(_handle, _disconnectedCb, IntPtr.Zero);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ _handle.Dispose();
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to add disconnected callback.");
+ }
+ }
+
+ public void Listen()
+ {
+ if (_connectionRequestCb == null)
+ {
+ Interop.MqttPluginServer.MqttPluginServerConnectionRequestCb cb = new Interop.MqttPluginServer.MqttPluginServerConnectionRequestCb(
+ (serviceName, peerInfo, userData) =>
+ {
+ Interop.MqttPlugin.ErrorCode clone_ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to clone peer info");
+ return;
+ }
+ OnConnectionRequest(new PeerInfo(clone));
+ });
+ _connectionRequestCb = cb;
+ }
+
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginServer.MqttPluginServerListen(_handle, _connectionRequestCb, IntPtr.Zero);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to listen server.");
+ }
+ }
+
+ public void Stop()
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginServer.MqttPluginServerStop(_handle);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to stop server.");
+ }
+ }
+
+ public void Disconnect(PeerInfo peerInfo)
+ {
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginServer.MqttPluginServerDisconnect(_handle, peerInfo?._handle);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to stop server.");
+ }
+ }
+
+ public Task<PayloadAsyncResult> SendPayloadAsync(Payload payload, PeerInfo peerInfo)
+ {
+ if (payload == null || payload.Id.Length == 0 || peerInfo == null || peerInfo.UUID.Length == 0)
+ {
+ throw new ArgumentException("Payload or peerinfo is invalid.");
+ }
+
+ TaskCompletionSource<PayloadAsyncResult> tcs = new TaskCompletionSource<PayloadAsyncResult>();
+ _tcsDictionary[Tuple.Create(payload.Id, peerInfo.UUID)] = tcs;
+
+ if (_payloadAsyncResultCb == null)
+ {
+ Interop.MqttPluginServer.MqttPluginServerPayloadAsyncResultCb cb = new Interop.MqttPluginServer.MqttPluginServerPayloadAsyncResultCb(
+ (IntPtr result, IntPtr userData) =>
+ {
+ PayloadAsyncResult resultPayload = null;
+ try
+ {
+ resultPayload = PayloadAsyncResult.CreateFromHandle(result);
+ }
+ catch (Exception e)
+ {
+ Log.Error(LogTag, string.Format("Failed to create PayloadAsyncResult from result handle: {0}.", e.Message));
+ return;
+ }
+ TaskCompletionSource<PayloadAsyncResult> tcsToReturn = _tcsDictionary[Tuple.Create(resultPayload.PayloadId, resultPayload.PeerInfo.UUID)];
+ tcsToReturn.SetResult(resultPayload);
+ _tcsDictionary.Remove(Tuple.Create(resultPayload.PayloadId, resultPayload.PeerInfo.UUID));
+ });
+ _payloadAsyncResultCb = cb;
+ }
+
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginServer.MqttPluginServerSendPayloadAsync(_handle, peerInfo?._handle, payload?._handle, _payloadAsyncResultCb, IntPtr.Zero);
+ if (ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ throw MqttPluginErrorFactory.GetException(ret, "Failed to send payload.");
+ }
+
+ return tcs.Task;
+ }
+
+ public void SendPayloadAsync(Payload payload)
+ {
+ var peerList = GetConnectedPeerList();
+ foreach (var peer in peerList)
+ {
+ SendPayloadAsync(payload, peer);
+ }
+ }
+
+ public void Accept(PeerInfo peerInfo)
+ {
+ Interop.MqttPluginServer.MqttPluginServerAccept(_handle, peerInfo?._handle);
+ }
+
+ public void Reject(PeerInfo peerInfo, string reason)
+ {
+ Interop.MqttPluginServer.MqttPluginServerReject(_handle, peerInfo?._handle, reason);
+ }
+
+ public IEnumerable<PeerInfo> GetConnectedPeerList()
+ {
+ List<PeerInfo> peerInfoList = new List<PeerInfo>();
+ Interop.MqttPlugin.ErrorCode ret = Interop.MqttPluginServer.MqttPluginServerForeachConnectedPeerInfo(_handle, (peer, userData) =>
+ {
+ Interop.MqttPlugin.ErrorCode clone_ret = Interop.MqttPluginPeerInfo.MqttPluginPeerInfoClone(peer, out PeerInfoSafeHandle clone);
+ if (clone_ret != Interop.MqttPlugin.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to clone peer info.");
+ return false;
+ }
+ peerInfoList.Add(new PeerInfo(clone));
+ return true;
+ }, IntPtr.Zero);
+ return peerInfoList;
+ }
+
+ protected abstract void OnConnectionResult(PeerInfo peerInfo, ConnectionResult result);
+ protected abstract byte[] OnDataReceived(byte[] data, PeerInfo peerInfo);
+ protected abstract void OnPayloadReceived(Payload data, PeerInfo peerInfo, PayloadTransferStatus status);
+ protected abstract void OnConnectionRequest(PeerInfo peerInfo);
+ protected abstract void OnDisconnected(PeerInfo peerInfo);
+
+ private bool disposedValue = false;
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ _handle.Dispose();
+ }
+ disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ }
+)__cs_cb";
+
+constexpr char CB_SERVER_SAFE_HANDLE[] =
+R"__cs_cb(
+ internal sealed class ServerSafeHandle : SafeHandle
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public ServerSafeHandle() : base(IntPtr.Zero, true)
+ {
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public override bool IsInvalid
+ {
+ get { return this.DangerousGetHandle() == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.MqttPluginServer.MqttPluginServerDestroy(this.handle);
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+)__cs_cb";
+
+#endif // IDLC_GEN_MQTT_PLUGIN_MQTT_PLUGIN_CS_BASE_GEN_CB_H_
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_cs_interop_gen.cc b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_interop_gen.cc
new file mode 100644
index 0000000..3c484d7
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_interop_gen.cc
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_cs_interop_gen.h"
+
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_cs_interop_gen_cb.h"
+
+namespace tidl {
+
+MqttPluginCsInteropGen::MqttPluginCsInteropGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans) : CionPluginBase(doc, trans) {
+}
+
+void MqttPluginCsInteropGen::OnInitGen(std::ofstream& stream) {
+ GenUsing(stream);
+ stream << "internal static partial class Interop\n";
+ stream << "{\n";
+ GenLibraries(stream);
+ GenErrorCode(stream);
+ GenMalloc(stream);
+ GenInterop(stream);
+ stream << "}\n";
+}
+
+void MqttPluginCsInteropGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void MqttPluginCsInteropGen::GenUsing(std::ofstream& stream) {
+ stream << CB_INTEROP_USING;
+}
+
+void MqttPluginCsInteropGen::GenLibraries(std::ofstream& stream) {
+ stream << CB_LIBRARIES;
+}
+
+void MqttPluginCsInteropGen::GenErrorCode(std::ofstream& stream) {
+ stream << CB_ERROR_CODE;
+}
+
+void MqttPluginCsInteropGen::GenMalloc(std::ofstream& stream) {
+ stream << CB_INTEROP_MALLOC;
+}
+
+void MqttPluginCsInteropGen::GenInterop(std::ofstream& stream) {
+ stream << CB_INTEROP_PAYLOAD;
+ stream << CB_INTEROP_PAYLOAD_ASYNC_RESULT;
+ stream << CB_INTEROP_PEER_INFO;
+ stream << CB_INTEROP_CONNECTION_RESULT;
+ switch (GetChannelType()) {
+ case ChannelType::TYPE_PROXY:
+ stream << CB_INTEROP_CLIENT;
+ break;
+ case ChannelType::TYPE_STUB:
+ stream << CB_INTEROP_SERVER;
+ break;
+ case ChannelType::TYPE_GROUP:
+ stream << CB_INTEROP_GROUP;
+ break;
+ default:
+ break;
+ }
+}
+
+} // namespace tidl
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_cs_interop_gen.h b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_interop_gen.h
new file mode 100644
index 0000000..c6fd1d9
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_interop_gen.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_MQTT_PLUGIN_MQTT_PLUGIN_CS_INTEROP_GEN_H_
+#define IDLC_GEN_MQTT_PLUGIN_MQTT_PLUGIN_CS_INTEROP_GEN_H_
+
+#include <memory>
+
+#include "idlc/gen_cion/cion_plugin_base.h"
+
+namespace tidl {
+
+class MqttPluginCsInteropGen : public CionPluginBase {
+ public:
+ explicit MqttPluginCsInteropGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~MqttPluginCsInteropGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenUsing(std::ofstream& stream);
+ void GenLibraries(std::ofstream& stream);
+ void GenErrorCode(std::ofstream& stream);
+ void GenMalloc(std::ofstream& stream);
+ void GenInterop(std::ofstream& stream);
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_MQTT_PLUGIN_MQTT_PLUGIN_CS_INTEROP_GEN_H_
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_cs_interop_gen_cb.h b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_interop_gen_cb.h
new file mode 100644
index 0000000..090183a
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_interop_gen_cb.h
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_MQTT_PLUGIN_MQTT_PLUGIN_CS_INTEROP_GEN_CB_H_
+#define IDLC_GEN_MQTT_PLUGIN_MQTT_PLUGIN_CS_INTEROP_GEN_CB_H_
+
+constexpr char CB_INTEROP_USING[] =
+R"__cs_cb(
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications.MqttPlugin;
+
+using ErrorCode = Interop.MqttPlugin.ErrorCode;
+
+)__cs_cb";
+
+constexpr char CB_LIBRARIES[] =
+R"__cs_cb(
+ internal static partial class Libraries
+ {
+ public const string MqttPlugin = "libcion-mqtt-plugin.so.1";
+ public const string Libc = "libc.so.6";
+ }
+)__cs_cb";
+
+constexpr char CB_ERROR_CODE[] =
+R"__cs_cb(
+ internal static partial class MqttPlugin
+ {
+ internal enum ErrorCode : int
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ InvalidOperation = Tizen.Internals.Errors.ErrorCode.InvalidOperation,
+ AlreadyInProgress = Tizen.Internals.Errors.ErrorCode.AlreadyInProgress,
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
+ TimedOut = Tizen.Internals.Errors.ErrorCode.TimedOut,
+ OperationFailed = -0x030C0000 | 0x01,
+ }
+ }
+)__cs_cb";
+
+constexpr char CB_INTEROP_MALLOC[] =
+R"__cs_cb(
+ internal static partial class MqttPlugin
+ {
+ [DllImport(Libraries.Libc, EntryPoint = "malloc")]
+ internal static extern IntPtr Malloc(int size);
+ }
+)__cs_cb";
+
+constexpr char CB_INTEROP_CLIENT[] =
+R"__cs_cb(
+ internal static partial class MqttPluginClient
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MqttPluginClientServerDiscoveredCb(string serviceName, IntPtr peerInfo, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MqttPluginClientConnectionResultCb(string serviceName, IntPtr peerInfo, IntPtr result, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MqttPluginClientPayloadReceivedCb(string serviceName, IntPtr peerInfo, IntPtr payload, int status, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MqttPluginClientDisconnectedCb(string serviceName, IntPtr peerInfo, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MqttPluginClientPayloadAsyncResultCb(IntPtr result, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_client_create")]
+ internal static extern ErrorCode MqttPluginClientCreate(out ClientSafeHandle client, string serviceName, string brokerIp, int brokerPort, string userName, string password);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_client_destroy")]
+ internal static extern ErrorCode MqttPluginClientDestroy(IntPtr client);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_client_try_discovery")]
+ internal static extern ErrorCode MqttPluginClientTryDiscovery(ClientSafeHandle client, MqttPluginClientServerDiscoveredCb cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_client_stop_discovery")]
+ internal static extern ErrorCode MqttPluginClientStopDiscovery(ClientSafeHandle client);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_client_connect")]
+ internal static extern ErrorCode MqttPluginClientConnect(ClientSafeHandle client, PeerInfoSafeHandle peerInfo);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_client_disconnect")]
+ internal static extern ErrorCode MqttPluginClientDisconnect(ClientSafeHandle client);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_client_send_data")]
+ internal static extern ErrorCode MqttPluginClientSendData(ClientSafeHandle client, byte[] data, int dataSize, int timeout, out IntPtr returnData, out int returnDataSize);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_client_send_payload_async")]
+ internal static extern ErrorCode MqttPluginClientSendPayloadAsync(ClientSafeHandle client, PayloadSafeHandle payload, MqttPluginClientPayloadAsyncResultCb cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_client_add_connection_result_cb")]
+ internal static extern ErrorCode MqttPluginClientAddConnectionResultCb(ClientSafeHandle client, MqttPluginClientConnectionResultCb cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_client_remove_connection_result_cb")]
+ internal static extern ErrorCode MqttPluginClientRemoveConnectionResultCb(ClientSafeHandle client, MqttPluginClientConnectionResultCb cb);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_client_add_payload_received_cb")]
+ internal static extern ErrorCode MqttPluginClientAddPayloadReceivedCb(ClientSafeHandle client, MqttPluginClientPayloadReceivedCb cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_client_remove_payload_received_cb")]
+ internal static extern ErrorCode MqttPluginClientRemovePayloadReceivedCb(ClientSafeHandle client, MqttPluginClientPayloadReceivedCb cb);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_client_add_disconnected_cb")]
+ internal static extern ErrorCode MqttPluginClientAddDisconnectedCb(ClientSafeHandle client, MqttPluginClientDisconnectedCb cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_client_remove_disconnected_cb")]
+ internal static extern ErrorCode MqttPluginClientRemoveDisconnectedCb(ClientSafeHandle client, MqttPluginClientDisconnectedCb cb);
+ }
+)__cs_cb";
+
+constexpr char CB_INTEROP_CONNECTION_RESULT[] =
+R"__cs_cb(
+ internal static partial class MqttPluginConnectionResult
+ {
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_connection_result_get_status")]
+ internal static extern ErrorCode MqttPluginConnectionResultGetStatus(IntPtr result, out ConnectionStatus status);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_connection_result_get_reason")]
+ internal static extern ErrorCode MqttPluginConnectionResultGetReason(IntPtr result, out string reason);
+ }
+)__cs_cb";
+
+constexpr char CB_INTEROP_GROUP[] =
+R"__cs_cb(
+ internal static partial class MqttPluginGroup
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MqttPluginGroupPayloadReceivedCb(IntPtr group, IntPtr peerInfo, IntPtr payload, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MqttPluginGroupJoinedCb(string topicName, IntPtr peerInfo, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MqttPluginGroupLeftCb(string topicName, IntPtr peerInfo, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_group_create")]
+ internal static extern ErrorCode MqttPluginGroupCreate(out GroupSafeHandle group, string topicName, string brokerIp, int brokerPort, string userName, string password);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_group_destroy")]
+ internal static extern ErrorCode MqttPluginGroupDestroy(IntPtr group);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_group_subscribe")]
+ internal static extern ErrorCode MqttPluginGroupSubscribe(GroupSafeHandle group);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_group_unsubscribe")]
+ internal static extern ErrorCode MqttPluginGroupUnsubscribe(GroupSafeHandle group);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_group_publish")]
+ internal static extern ErrorCode MqttPluginGroupPublish(GroupSafeHandle group, PayloadSafeHandle data);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_group_add_payload_received_cb")]
+ internal static extern ErrorCode MqttPluginGroupAddPayloadReceivedCb(GroupSafeHandle group, MqttPluginGroupPayloadReceivedCb cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_group_remove_payload_received_cb")]
+ internal static extern ErrorCode MqttPluginGroupRemovePayloadReceivedCb(GroupSafeHandle group, MqttPluginGroupPayloadReceivedCb cb);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_group_add_joined_cb")]
+ internal static extern ErrorCode MqttPluginGroupAddJoinedCb(GroupSafeHandle group, MqttPluginGroupJoinedCb cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_group_remove_joined_cb")]
+ internal static extern ErrorCode MqttPluginGroupRemoveJoinedCb(GroupSafeHandle group, MqttPluginGroupJoinedCb cb);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_group_add_left_cb")]
+ internal static extern ErrorCode MqttPluginGroupAddLeftCb(GroupSafeHandle group, MqttPluginGroupLeftCb cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_group_remove_left_cb")]
+ internal static extern ErrorCode MqttPluginGroupRemoveLeftCb(GroupSafeHandle group, MqttPluginGroupLeftCb cb);
+ }
+)__cs_cb";
+
+constexpr char CB_INTEROP_PAYLOAD[] =
+R"__cs_cb(
+ internal static partial class MqttPluginPayload
+ {
+ internal enum PayloadType : int
+ {
+ Data,
+ File,
+ }
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_payload_create")]
+ internal static extern ErrorCode MqttPluginPayloadCreate(out PayloadSafeHandle payload, PayloadType type);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_payload_destroy")]
+ internal static extern ErrorCode MqttPluginPayloadDestroy(IntPtr payload);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_payload_get_type")]
+ internal static extern ErrorCode MqttPluginPayloadGetType(IntPtr payload, out PayloadType type);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_payload_get_data")]
+ internal static extern ErrorCode MqttPluginPayloadGetData(PayloadSafeHandle payload, out IntPtr data, out int dataSize);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_payload_set_data")]
+ internal static extern ErrorCode MqttPluginPayloadSetData(PayloadSafeHandle payload, byte[] data, int dataSize);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_payload_save_as_file")]
+ internal static extern ErrorCode MqttPluginPayloadSaveAsFile(PayloadSafeHandle payload, string path);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_payload_get_received_file_name")]
+ internal static extern ErrorCode MqttPluginPayloadGetReceivedFileName(PayloadSafeHandle payload, out string path);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_payload_get_received_bytes")]
+ internal static extern ErrorCode MqttPluginPayloadGetReceivedBytes(PayloadSafeHandle payload, out UInt64 bytes);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_payload_get_total_bytes")]
+ internal static extern ErrorCode MqttPluginPayloadGetTotalBytes(PayloadSafeHandle payload, out UInt64 bytes);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_payload_set_file_path")]
+ internal static extern ErrorCode MqttPluginPayloadSetFilePath(PayloadSafeHandle payload, string path);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_payload_get_payload_id")]
+ internal static extern ErrorCode MqttPluginPayloadGetPayloadID(PayloadSafeHandle payload, out string id);
+ }
+)__cs_cb";
+
+constexpr char CB_INTEROP_PAYLOAD_ASYNC_RESULT[] =
+R"__cs_cb(
+ internal static partial class MqttPluginPayloadAsyncResult
+ {
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_payload_async_result_get_result")]
+ internal static extern ErrorCode MqttPluginPayloadAsyncResultGetResult(IntPtr result, out int code);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_payload_async_result_get_peer_info")]
+ internal static extern ErrorCode MqttPluginPayloadAsyncResultGetPeerInfo(IntPtr result, out IntPtr peerInfo);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_payload_async_result_get_payload_id")]
+ internal static extern ErrorCode MqttPluginPayloadAsyncResultGetPayloadID(IntPtr result, out string payloadID);
+ }
+)__cs_cb";
+
+constexpr char CB_INTEROP_PEER_INFO[] =
+R"__cs_cb(
+ internal static partial class MqttPluginPeerInfo
+ {
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_peer_info_clone")]
+ internal static extern ErrorCode MqttPluginPeerInfoClone(IntPtr peerInfo, out PeerInfoSafeHandle peerInfoClone);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_peer_info_destroy")]
+ internal static extern ErrorCode MqttPluginPeerInfoDestroy(IntPtr peerInfo);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_peer_info_get_device_id")]
+ internal static extern ErrorCode MqttPluginPeerInfoGetDeviceId(PeerInfoSafeHandle peerInfo, out string deviceId);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_peer_info_get_device_name")]
+ internal static extern ErrorCode MqttPluginPeerInfoGetDeviceName(PeerInfoSafeHandle peerInfo, out string deviceName);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_peer_info_get_device_platform")]
+ internal static extern ErrorCode MqttPluginPeerInfoGetDevicePlatform(PeerInfoSafeHandle peerInfo, out string devicePlatform);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_peer_info_get_device_platform_version")]
+ internal static extern ErrorCode MqttPluginPeerInfoGetDevicePlatformVersion(PeerInfoSafeHandle peerInfo, out string devicePlatformVersion);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_peer_info_get_device_type")]
+ internal static extern ErrorCode MqttPluginPeerInfoGetDeviceType(PeerInfoSafeHandle peerInfo, out string deviceType);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_peer_info_get_app_id")]
+ internal static extern ErrorCode MqttPluginPeerInfoGetAppId(PeerInfoSafeHandle peerInfo, out string appId);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_peer_info_get_app_version")]
+ internal static extern ErrorCode MqttPluginPeerInfoGetAppVersion(PeerInfoSafeHandle peerInfo, out string appVersion);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_peer_info_get_uuid")]
+ internal static extern ErrorCode MqttPluginPeerInfoGetUuid(PeerInfoSafeHandle peerInfo, out string uuid);
+ }
+)__cs_cb";
+
+constexpr char CB_INTEROP_SERVER[] =
+R"__cs_cb(
+ internal static partial class MqttPluginServer
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate bool MqttPluginServerPeerInfoIterator(IntPtr peerInfo, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MqttPluginServerPayloadAsyncResultCb(IntPtr result, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MqttPluginServerConnectionResultCb(string serviceName, IntPtr peerInfo, IntPtr result, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MqttPluginServerDataReceivedCb(string serviceName, IntPtr peerInfo, IntPtr data, int dataSize, out IntPtr returnData, out int returnDataSize, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MqttPluginServerPayloadReceivedCb(string serviceName, IntPtr peerInfo, IntPtr payload, int status, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MqttPluginServerConnectionRequestCb(string serviceName, IntPtr peerInfo, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MqttPluginServerErrorReportedCb(string serviceName, IntPtr peerInfo, int error, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void MqttPluginServerDisconnectedCb(string serviceName, IntPtr peerInfo, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_create")]
+ internal static extern ErrorCode MqttPluginServerCreate(out ServerSafeHandle server, string serviceName, string displayName, string brokerIp, int brokerPort, string userName, string password);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_destroy")]
+ internal static extern ErrorCode MqttPluginServerDestroy(IntPtr server);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_listen")]
+ internal static extern ErrorCode MqttPluginServerListen(ServerSafeHandle server, MqttPluginServerConnectionRequestCb cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_stop")]
+ internal static extern ErrorCode MqttPluginServerStop(ServerSafeHandle server);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_accept")]
+ internal static extern ErrorCode MqttPluginServerAccept(ServerSafeHandle server, PeerInfoSafeHandle peerInfo);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_reject")]
+ internal static extern ErrorCode MqttPluginServerReject(ServerSafeHandle server, PeerInfoSafeHandle peerInfo, string reason);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_disconnect")]
+ internal static extern ErrorCode MqttPluginServerDisconnect(ServerSafeHandle server, PeerInfoSafeHandle peerInfo);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_send_payload_async")]
+ internal static extern ErrorCode MqttPluginServerSendPayloadAsync(ServerSafeHandle server, PeerInfoSafeHandle peerInfo, PayloadSafeHandle payload, MqttPluginServerPayloadAsyncResultCb cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_foreach_connected_peer_info")]
+ internal static extern ErrorCode MqttPluginServerForeachConnectedPeerInfo(ServerSafeHandle server, MqttPluginServerPeerInfoIterator cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_add_connection_result_cb")]
+ internal static extern ErrorCode MqttPluginServerAddConnectionResultCb(ServerSafeHandle server, MqttPluginServerConnectionResultCb cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_remove_connection_result_cb")]
+ internal static extern ErrorCode MqttPluginServerRemoveConnectionResultCb(ServerSafeHandle server, MqttPluginServerConnectionResultCb cb);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_add_payload_received_cb")]
+ internal static extern ErrorCode MqttPluginServerAddPayloadReceivedCb(ServerSafeHandle server, MqttPluginServerPayloadReceivedCb cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_remove_payload_received_cb")]
+ internal static extern ErrorCode MqttPluginServerRemovePayloadReceivedCb(ServerSafeHandle server, MqttPluginServerPayloadReceivedCb cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_set_data_received_cb")]
+ internal static extern ErrorCode MqttPluginServerSetDataReceivedCb(ServerSafeHandle server, MqttPluginServerDataReceivedCb cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_unset_data_received_cb")]
+ internal static extern ErrorCode MqttPluginServerUnsetDataReceivedCb(ServerSafeHandle server, MqttPluginServerDataReceivedCb cb);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_add_disconnected_cb")]
+ internal static extern ErrorCode MqttPluginServerAddDisconnectedCb(ServerSafeHandle server, MqttPluginServerDisconnectedCb cb, IntPtr userData);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_remove_disconnected_cb")]
+ internal static extern ErrorCode MqttPluginServerRemoveDisconnectedCb(ServerSafeHandle server, MqttPluginServerDisconnectedCb cb);
+
+ [DllImport(Libraries.MqttPlugin, EntryPoint = "mqtt_plugin_server_set_display_name")]
+ internal static extern ErrorCode MqttPluginServerSetDisplayName(ServerSafeHandle server, string displayName);
+ }
+)__cs_cb";
+
+#endif // IDLC_GEN_MQTT_PLUGIN_MQTT_PLUGIN_CS_INTEROP_GEN_CB_H_
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_cs_transportable.cc b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_transportable.cc
new file mode 100644
index 0000000..342c194
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_transportable.cc
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_cs_transportable.h"
+
+#include <utility>
+
+#include "idlc/gen/replace_all.h"
+
+namespace {
+
+constexpr const char __USING[] =
+R"__cs_cb(
+using System;
+using System.Collections.Generic;
+using Tizen.Applications;
+using Tizen.Applications.MqttPlugin;
+using Tizen.Applications.RPCPort;
+)__cs_cb";
+
+constexpr const char __FILE_SEND[] =
+R"__cs_cb(if (path == null)
+ throw new ArgumentException("Invalid path");
+
+ Payload fp = new FilePayload(<FILE_PATH>);
+ base.SendPayloadAsync(fp);
+)__cs_cb";
+
+constexpr const char __CLIENT_CTOR[] =
+R"__cs_cb(
+ public ##(string serviceName, string brokerIp, int brokerPort, string userName, string password) : base(serviceName, brokerIp, brokerPort, userName, password)
+ {
+ ServiceName = serviceName;
+ }
+)__cs_cb";
+
+constexpr const char __GROUP_CTOR[] =
+R"__cs_cb(
+ public ##(string topicName, string brokerIp, int brokerPort, string userName, string password) : base(topicName, brokerIp, brokerPort, userName, password)
+ {
+ TopicName = topicName;
+ try
+ {
+ base.Subscribe();
+ }
+ catch
+ {
+ throw;
+ }
+ }
+)__cs_cb";
+
+constexpr const char __SERVER_CTOR[] =
+R"__cs_cb(
+ public ##(string serviceName, string displayName, string brokerIp, int brokerPort, string userName, string password) : base(serviceName, displayName, brokerIp, brokerPort, userName, password)
+ {
+ }
+)__cs_cb";
+
+} // namespace
+
+namespace tidl {
+
+std::string MqttPluginCsTransportable::GenInclude() const {
+ return __USING;
+}
+
+std::string MqttPluginCsTransportable::GenFileSend(std::string path) const {
+ return std::string(ReplaceAll(__FILE_SEND, {
+ { "<FILE_PATH>", path } }));
+}
+
+std::string MqttPluginCsTransportable::GenGroupType() const {
+ return "GroupBase";
+}
+
+std::string MqttPluginCsTransportable::GenPayloadTransferStatusType() const {
+ return "PayloadTransferStatus";
+}
+
+std::string MqttPluginCsTransportable::GenPeerInfoType() const {
+ return "PeerInfo";
+}
+
+std::string MqttPluginCsTransportable::GenPayloadType() const {
+ return "Payload";
+}
+
+std::string MqttPluginCsTransportable::GenClientType() const {
+ return "ClientBase";
+}
+
+std::string MqttPluginCsTransportable::GenServerType() const {
+ return "ServerBase";
+}
+
+std::string MqttPluginCsTransportable::GenClientExtraHeader() const {
+ return "";
+}
+
+std::string MqttPluginCsTransportable::GenClientExtraBody() const {
+ return "";
+}
+
+std::string MqttPluginCsTransportable::GenServerExtraHeader() const {
+ return "";
+}
+
+std::string MqttPluginCsTransportable::GenServerExtraBody() const {
+ return "";
+}
+
+std::string MqttPluginCsTransportable::GenPayloadTypeData() const {
+ return "PayloadType.DataPayload";
+}
+
+std::string MqttPluginCsTransportable::GenPayloadTypeFile() const {
+ return "PayloadType.FilePayload";
+}
+
+std::string MqttPluginCsTransportable::GenClientBaseCtor(
+ const Interface& iface) const {
+ std::string ctor(ReplaceAll(__CLIENT_CTOR, "##", iface.GetID()));
+ return ctor;
+}
+
+std::string MqttPluginCsTransportable::GenGroupBaseCtor(
+ const Interface& iface) const {
+ std::string ctor(ReplaceAll(__GROUP_CTOR, "##", iface.GetID()));
+ return ctor;
+}
+
+std::string MqttPluginCsTransportable::GenServerBaseCtor(
+ const Interface& iface) const {
+ std::string ctor(ReplaceAll(__SERVER_CTOR, "##", iface.GetID()));
+ return ctor;
+}
+
+} // namespace tidl
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_cs_transportable.h b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_transportable.h
new file mode 100644
index 0000000..056094f
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_cs_transportable.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_MQTT_PLUGIN_MQTT_PLUGIN_CS_TRANSPORTABLE_H_
+#define IDLC_GEN_MQTT_PLUGIN_MQTT_PLUGIN_CS_TRANSPORTABLE_H_
+
+#include <string>
+
+#include "idlc/gen_cion/cs_transportable.h"
+
+namespace tidl {
+
+class MqttPluginCsTransportable : public CsTransportable {
+ public:
+ virtual ~MqttPluginCsTransportable() = default;
+ std::string GenInclude() const override;
+ std::string GenFileSend(std::string path) const override;
+ std::string GenGroupType() const override;
+ std::string GenPayloadTransferStatusType() const override;
+ std::string GenPeerInfoType() const override;
+ std::string GenPayloadType() const override;
+ std::string GenClientType() const override;
+ std::string GenServerType() const override;
+ std::string GenClientExtraHeader() const override;
+ std::string GenClientExtraBody() const override;
+ std::string GenServerExtraHeader() const override;
+ std::string GenServerExtraBody() const override;
+ std::string GenPayloadTypeData() const override;
+ std::string GenPayloadTypeFile() const override;
+ std::string GenClientBaseCtor(const Interface& iface) const override;
+ std::string GenGroupBaseCtor(const Interface& iface) const override;
+ std::string GenServerBaseCtor(const Interface& iface) const override;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_MQTT_PLUGIN_MQTT_PLUGIN_CS_TRANSPORTABLE_H_
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen.cc b/idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen.cc
new file mode 100644
index 0000000..fb20a73
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen.cc
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen.h"
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen_cb.h"
+
+namespace tidl {
+
+MqttPluginInternalBodyGen::MqttPluginInternalBodyGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : CCionBodyGeneratorBase(doc, trans) {
+}
+
+void MqttPluginInternalBodyGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenGNUSourceDefinition(stream);
+ GenIncludeHeader(stream);
+ GenLogTag(stream, std::string("MQTT_PLUGIN_INTERNAL"));
+ GenLogDefinition(stream);
+ GenBody(stream);
+ GenPluginInit(stream);
+}
+
+
+void MqttPluginInternalBodyGen::GenPluginInit(std::ofstream& stream) {
+ stream << CB_PLUGIN_INIT_BASE;
+}
+
+void MqttPluginInternalBodyGen::GenIncludeHeader(std::ofstream& stream) {
+ stream << tidl::ReplaceAll(CB_INTERNAL_HEADER, "<FILENAME>", GetFileNamespace());
+}
+
+void MqttPluginInternalBodyGen::GenLoadModule(std::ofstream& stream) {
+ std::string code;
+ code = CB_LOAD_MOUDLE_BASE;
+ code += CB_LOAD_MOUDLE_PAYLOAD;
+ code += CB_LOAD_MOUDLE_PEERINFO;
+ code += CB_LOAD_MOUDLE_CONNECTION;
+
+ switch (GetChannelType()) {
+ case ChannelType::TYPE_PROXY:
+ {
+ code += CB_LOAD_MOUDLE_CLIENT;
+ break;
+ }
+ case ChannelType::TYPE_STUB:
+ {
+ code += CB_LOAD_MOUDLE_SERVER;
+ break;
+ }
+ case ChannelType::TYPE_GROUP:
+ {
+ code += CB_LOAD_MOUDLE_GROUP;
+ break;
+ }
+ default:
+ break;
+ }
+ code += CB_LOAD_MOUDLE_BASE_RETURN;
+
+ stream << tidl::ReplaceAll(code, "<PREFIX>", GetHandlePrefix());
+}
+
+void MqttPluginInternalBodyGen::GenBody(std::ofstream& stream) {
+ stream << tidl::ReplaceAll(CB_BODY_BASE, "<PREFIX>", GetHandlePrefix());
+ switch (GetChannelType()) {
+ case ChannelType::TYPE_PROXY:
+ {
+ stream << tidl::ReplaceAll(CB_BODY_CLIENT, "<PREFIX>", GetHandlePrefix());
+ break;
+ }
+ case ChannelType::TYPE_STUB:
+ {
+ stream << tidl::ReplaceAll(CB_BODY_SERVER, "<PREFIX>", GetHandlePrefix());
+ break;
+ }
+ case ChannelType::TYPE_GROUP:
+ {
+ stream << tidl::ReplaceAll(CB_BODY_GROUP, "<PREFIX>", GetHandlePrefix());
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ GenLoadModule(stream);
+}
+
+void MqttPluginInternalBodyGen::OnFiniGen(std::ofstream& stream) {
+}
+
+} // namespace tidl
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen.h b/idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen.h
new file mode 100644
index 0000000..a0bd005
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_MQTT_PLUGIN_C_INTERNAL_BODY_GEN_H_
+#define IDLC_MQTT_PLUGIN_C_INTERNAL_BODY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/c_cion_body_gen_base.h"
+
+namespace tidl {
+
+class MqttPluginInternalBodyGen : public CCionBodyGeneratorBase {
+ public:
+ explicit MqttPluginInternalBodyGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~MqttPluginInternalBodyGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenPluginInit(std::ofstream& stream);
+ void GenIncludeHeader(std::ofstream& stream);
+ void GenLoadModule(std::ofstream& stream);
+ void GenBody(std::ofstream& stream);
+};
+
+} // namespace tidl
+
+#endif // IDLC_MQTT_PLUGIN_C_INTERNAL_BODY_GEN_H_
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen_cb.h b/idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen_cb.h
new file mode 100644
index 0000000..7f47ecf
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen_cb.h
@@ -0,0 +1,523 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_MQTT_PLUGIN_GEN_INTERNAL_BODY_GEN_CB_H_
+#define IDLC_C_MQTT_PLUGIN_GEN_INTERNAL_BODY_GEN_CB_H_
+
+constexpr const char CB_INTERNAL_HEADER[] =
+R"__c_cb(
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <dlog.h>
+
+#include "<FILENAME>.h"
+
+)__c_cb";
+
+constexpr const char CB_LOAD_MOUDLE_SERVER[] =
+R"__c_cb(
+ if (!__load_server_channel())
+ goto out;
+)__c_cb";
+
+constexpr const char CB_LOAD_MOUDLE_PAYLOAD[] =
+R"__c_cb(
+ if (!__load_payload())
+ goto out;
+)__c_cb";
+
+constexpr const char CB_LOAD_MOUDLE_PEERINFO[] =
+R"__c_cb(
+ if (!__load_peerinfo())
+ goto out;
+)__c_cb";
+
+constexpr const char CB_LOAD_MOUDLE_CONNECTION[] =
+R"__c_cb(
+ if (!__load_connection())
+ goto out;
+)__c_cb";
+
+constexpr const char CB_LOAD_MOUDLE_CLIENT[] =
+R"__c_cb(
+ if (!__load_client_channel())
+ goto out;
+)__c_cb";
+
+constexpr const char CB_LOAD_MOUDLE_GROUP[] =
+R"__c_cb(
+ if (!__load_group_channel())
+ goto out;
+)__c_cb";
+
+constexpr const char CB_PLUGIN_INIT_BASE[] =
+R"__c_cb(
+PLUGIN_CTOR static void _plugin_init(void)
+{
+ __load_module();
+}
+)__c_cb";
+
+constexpr const char CB_LOAD_MOUDLE_BASE[] =
+R"__c_cb(
+static void __load_module() {
+ plugin_handle = dlopen(LIBMQTT_PLUGIN_INFO, RTLD_LAZY | RTLD_GLOBAL);
+ if (!plugin_handle) {
+ LOGE("Failed to load - %s", dlerror());
+ return;
+ }
+)__c_cb";
+
+constexpr const char CB_LOAD_MOUDLE_BASE_RETURN[] =
+R"__c_cb(
+ return;
+
+out:
+
+ dlclose(plugin_handle);
+}
+)__c_cb";
+
+constexpr const char CB_BODY_BASE[] =
+R"__c_cb(
+
+#define LIBMQTT_PLUGIN_INFO "/usr/lib/libcion-mqtt-plugin.so.1"
+static void *plugin_handle;
+
+#define PLUGIN_CTOR __attribute__((constructor))
+
+static bool __load_payload() {
+ <PREFIX>_payload_create = dlsym(plugin_handle,
+ "mqtt_plugin_payload_create");
+ if (!<PREFIX>_payload_create) {
+ LOGE("Failed to find plugin_payload_create");
+ return false;
+ }
+
+ <PREFIX>_payload_destroy = dlsym(plugin_handle,
+ "mqtt_plugin_payload_destroy");
+ if (!<PREFIX>_payload_destroy) {
+ LOGE("Failed to find plugin_payload_destroy");
+ return false;
+ }
+
+ <PREFIX>_payload_get_type = dlsym(plugin_handle,
+ "mqtt_plugin_payload_get_type");
+ if (!<PREFIX>_payload_get_type) {
+ LOGE("Failed to find plugin_payload_get_type");
+ return false;
+ }
+
+ <PREFIX>_payload_get_data = dlsym(plugin_handle,
+ "mqtt_plugin_payload_get_data");
+ if (!<PREFIX>_payload_get_data) {
+ LOGE("Failed to find plugin_payload_get_data");
+ return false;
+ }
+
+ <PREFIX>_payload_set_data = dlsym(plugin_handle,
+ "mqtt_plugin_payload_set_data");
+ if (!<PREFIX>_payload_set_data) {
+ LOGE("Failed to find plugin_payload_set_data");
+ return false;
+ }
+
+ <PREFIX>_payload_save_as_file = dlsym(plugin_handle,
+ "mqtt_plugin_payload_save_as_file");
+ if (!<PREFIX>_payload_save_as_file) {
+ LOGE("Failed to find plugin_payload_save_as_file");
+ return false;
+ }
+
+ <PREFIX>_payload_get_received_file_name = dlsym(plugin_handle,
+ "mqtt_plugin_payload_get_received_file_name");
+ if (!<PREFIX>_payload_get_received_file_name) {
+ LOGE("Failed to find plugin_payload_get_received_file_name");
+ return false;
+ }
+
+ <PREFIX>_payload_get_received_bytes = dlsym(plugin_handle,
+ "mqtt_plugin_payload_get_received_bytes");
+ if (!<PREFIX>_payload_get_received_bytes) {
+ LOGE("Failed to init plugin_payload_get_received_bytes");
+ return false;
+ }
+
+ <PREFIX>_payload_get_total_bytes = dlsym(plugin_handle,
+ "mqtt_plugin_payload_get_total_bytes");
+ if (!<PREFIX>_payload_get_total_bytes) {
+ LOGE("Failed to find plugin_payload_get_total_bytes");
+ return false;
+ }
+
+ <PREFIX>_payload_set_file_path = dlsym(plugin_handle,
+ "mqtt_plugin_payload_set_file_path");
+ if (!<PREFIX>_payload_set_file_path) {
+ LOGE("Failed to find plugin_payload_set_file_path");
+ return false;
+ }
+
+ <PREFIX>_payload_get_payload_id = dlsym(plugin_handle,
+ "mqtt_plugin_payload_get_payload_id");
+ if (!<PREFIX>_payload_get_payload_id) {
+ LOGE("Failed to find plugin_payload_get_payload_id");
+ return false;
+ }
+
+ return true;
+}
+
+static bool __load_peerinfo() {
+ <PREFIX>_peer_info_clone = dlsym(plugin_handle,
+ "mqtt_plugin_peer_info_clone");
+ if (!<PREFIX>_peer_info_clone) {
+ LOGE("Failed to find plugin_peer_info_clone");
+ return false;
+ }
+
+ <PREFIX>_peer_info_destroy = dlsym(plugin_handle,
+ "mqtt_plugin_peer_info_destroy");
+ if (!<PREFIX>_peer_info_destroy) {
+ LOGE("Failed to find plugin_peer_info_destroy");
+ return false;
+ }
+
+ <PREFIX>_peer_info_get_device_id = dlsym(plugin_handle,
+ "mqtt_plugin_peer_info_get_device_id");
+ if (!<PREFIX>_peer_info_get_device_id) {
+ LOGE("Failed to find plugin_peer_info_get_device_id");
+ return false;
+ }
+
+ <PREFIX>_peer_info_get_device_name = dlsym(plugin_handle,
+ "mqtt_plugin_peer_info_get_device_name");
+ if (!<PREFIX>_peer_info_get_device_name) {
+ LOGE("Failed to find plugin_peer_info_get_device_name");
+ return false;
+ }
+
+ <PREFIX>_peer_info_get_device_platform = dlsym(plugin_handle,
+ "mqtt_plugin_peer_info_get_device_platform");
+ if (!<PREFIX>_peer_info_get_device_platform) {
+ LOGE("Failed to find plugin_peer_info_get_device_platform");
+ return false;
+ }
+
+ <PREFIX>_peer_info_get_device_platform_version = dlsym(plugin_handle,
+ "mqtt_plugin_peer_info_get_device_platform_version");
+ if (!<PREFIX>_peer_info_get_device_platform_version) {
+ LOGE("Failed to find plugin_peer_info_get_device_platform_version");
+ return false;
+ }
+
+ <PREFIX>_peer_info_get_device_type = dlsym(plugin_handle,
+ "mqtt_plugin_peer_info_get_device_type");
+ if (!<PREFIX>_peer_info_get_device_type) {
+ LOGE("Failed to find plugin_peer_info_get_device_type");
+ return false;
+ }
+
+ <PREFIX>_peer_info_get_app_id = dlsym(plugin_handle,
+ "mqtt_plugin_peer_info_get_app_id");
+ if (!<PREFIX>_peer_info_get_app_id) {
+ LOGE("Failed to init plugin_peer_info_get_app_id");
+ return false;
+ }
+
+ <PREFIX>_peer_info_get_app_version = dlsym(plugin_handle,
+ "mqtt_plugin_peer_info_get_app_version");
+ if (!<PREFIX>_peer_info_get_app_version) {
+ LOGE("Failed to find plugin_peer_info_get_app_version");
+ return false;
+ }
+
+ <PREFIX>_peer_info_get_uuid = dlsym(plugin_handle,
+ "mqtt_plugin_peer_info_get_uuid");
+ if (!<PREFIX>_peer_info_get_uuid) {
+ LOGE("Failed to find plugin_peer_info_get_uuid");
+ return false;
+ }
+
+ <PREFIX>_peer_info_get_display_name = dlsym(plugin_handle,
+ "mqtt_plugin_peer_info_get_display_name");
+ if (!<PREFIX>_peer_info_get_display_name) {
+ LOGE("Failed to find plugin_peer_info_get_display_name");
+ return false;
+ }
+
+ return true;
+}
+
+static bool __load_connection() {
+ <PREFIX>_connection_result_get_status = dlsym(plugin_handle,
+ "mqtt_plugin_connection_result_get_status");
+ if (!<PREFIX>_connection_result_get_status) {
+ LOGE("Failed to find plugin_connection_result_get_status");
+ return false;
+ }
+
+ <PREFIX>_connection_result_get_reason = dlsym(plugin_handle,
+ "mqtt_plugin_connection_result_get_reason");
+ if (!<PREFIX>_connection_result_get_reason) {
+ LOGE("Failed to find plugin_connection_result_get_reason");
+ return false;
+ }
+
+ return true;
+}
+)__c_cb";
+
+constexpr const char CB_BODY_GROUP[] =
+R"__c_cb(
+static bool __load_group_channel() {
+ <PREFIX>_group_create = dlsym(plugin_handle, "mqtt_plugin_group_create");
+ if (!<PREFIX>_group_create) {
+ LOGE("Failed to find plugin_group_create");
+ return false;
+ }
+
+ <PREFIX>_group_destroy = dlsym(plugin_handle,
+ "mqtt_plugin_group_destroy");
+ if (!<PREFIX>_group_destroy) {
+ LOGE("Failed to find plugin_group_destroy");
+ return false;
+ }
+
+ <PREFIX>_group_subscribe = dlsym(plugin_handle,
+ "mqtt_plugin_group_subscribe");
+ if (!<PREFIX>_group_subscribe) {
+ LOGE("Failed to find plugin_group_subscribe");
+ return false;
+ }
+
+ <PREFIX>_group_unsubscribe = dlsym(plugin_handle,
+ "mqtt_plugin_group_unsubscribe");
+ if (!<PREFIX>_group_unsubscribe) {
+ LOGE("Failed to find plugin_group_unsubscribe");
+ return false;
+ }
+
+ <PREFIX>_group_publish = dlsym(plugin_handle,
+ "mqtt_plugin_group_publish");
+ if (!<PREFIX>_group_publish) {
+ LOGE("Failed to find plugin_group_publish");
+ return false;
+ }
+
+ <PREFIX>_group_add_payload_received_cb = dlsym(plugin_handle,
+ "mqtt_plugin_group_add_payload_received_cb");
+ if (!<PREFIX>_group_add_payload_received_cb) {
+ LOGE("Failed to find plugin_group_add_payload_received_cb");
+ return false;
+ }
+
+ <PREFIX>_group_add_joined_cb = dlsym(plugin_handle,
+ "mqtt_plugin_group_add_joined_cb");
+ if (!<PREFIX>_group_add_joined_cb) {
+ LOGE("Failed to find plugin_group_add_joined_cb");
+ return false;
+ }
+
+ <PREFIX>_group_add_left_cb = dlsym(plugin_handle,
+ "mqtt_plugin_group_add_left_cb");
+ if (!<PREFIX>_group_add_left_cb) {
+ LOGE("Failed to init plugin_group_add_left_cb");
+ return false;
+ }
+
+ return true;
+}
+)__c_cb";
+
+constexpr const char CB_BODY_CLIENT[] =
+R"__c_cb(
+static bool __load_client_channel() {
+ <PREFIX>_client_create = dlsym(plugin_handle, "mqtt_plugin_client_create");
+ if (!<PREFIX>_client_create) {
+ LOGE("Failed to find plugin_client_create");
+ return false;
+ }
+
+ <PREFIX>_client_destroy = dlsym(plugin_handle,
+ "mqtt_plugin_client_destroy");
+ if (!<PREFIX>_client_destroy) {
+ LOGE("Failed to find plugin_client_destroy");
+ return false;
+ }
+
+ <PREFIX>_client_try_discovery = dlsym(plugin_handle,
+ "mqtt_plugin_client_try_discovery");
+ if (!<PREFIX>_client_try_discovery) {
+ LOGE("Failed to find plugin_client_try_discovery");
+ return false;
+ }
+
+ <PREFIX>_client_stop_discovery = dlsym(plugin_handle,
+ "mqtt_plugin_client_stop_discovery");
+ if (!<PREFIX>_client_stop_discovery) {
+ LOGE("Failed to find plugin_client_stop_discovery");
+ return false;
+ }
+
+ <PREFIX>_client_connect = dlsym(plugin_handle,
+ "mqtt_plugin_client_connect");
+ if (!<PREFIX>_client_connect) {
+ LOGE("Failed to find plugin_client_connect");
+ return false;
+ }
+
+ <PREFIX>_client_disconnect = dlsym(plugin_handle,
+ "mqtt_plugin_client_disconnect");
+ if (!<PREFIX>_client_disconnect) {
+ LOGE("Failed to find plugin_client_disconnect");
+ return false;
+ }
+
+ <PREFIX>_client_send_data = dlsym(plugin_handle,
+ "mqtt_plugin_client_send_data");
+ if (!<PREFIX>_client_send_data) {
+ LOGE("Failed to find plugin_client_send_data");
+ return false;
+ }
+
+ <PREFIX>_client_send_payload_async = dlsym(plugin_handle,
+ "mqtt_plugin_client_send_payload_async");
+ if (!<PREFIX>_client_send_payload_async) {
+ LOGE("Failed to init plugin_client_send_payload_async");
+ return false;
+ }
+
+ <PREFIX>_client_add_connection_result_cb = dlsym(plugin_handle,
+ "mqtt_plugin_client_add_connection_result_cb");
+ if (!<PREFIX>_client_add_connection_result_cb) {
+ LOGE("Failed to find plugin_client_add_connection_result_cb");
+ return false;
+ }
+
+ <PREFIX>_client_add_payload_received_cb = dlsym(plugin_handle,
+ "mqtt_plugin_client_add_payload_received_cb");
+ if (!<PREFIX>_client_add_payload_received_cb) {
+ LOGE("Failed to find plugin_client_add_payload_received_cb");
+ return false;
+ }
+
+ <PREFIX>_client_add_disconnected_cb = dlsym(plugin_handle,
+ "mqtt_plugin_client_add_disconnected_cb");
+ if (!<PREFIX>_client_add_disconnected_cb) {
+ LOGE("Failed to find plugin_client_add_disconnected_cb");
+ return false;
+ }
+
+ return true;
+}
+)__c_cb";
+
+constexpr const char CB_BODY_SERVER[] =
+R"__c_cb(
+static bool __load_server_channel() {
+ <PREFIX>_server_create = dlsym(plugin_handle, "mqtt_plugin_server_create");
+ if (!<PREFIX>_server_create) {
+ LOGE("Failed to find plugin_server_create");
+ return false;
+ }
+
+ <PREFIX>_server_add_connection_result_cb = dlsym(plugin_handle,
+ "mqtt_plugin_server_add_connection_result_cb");
+ if (!<PREFIX>_server_add_connection_result_cb) {
+ LOGE("Failed to find plugin_server_add_connection_result_cb");
+ return false;
+ }
+
+ <PREFIX>_server_add_payload_received_cb = dlsym(plugin_handle,
+ "mqtt_plugin_server_add_payload_received_cb");
+ if (!<PREFIX>_server_add_payload_received_cb) {
+ LOGE("Failed to find plugin_server_add_payload_received_cb");
+ return false;
+ }
+
+ <PREFIX>_server_add_disconnected_cb = dlsym(plugin_handle,
+ "mqtt_plugin_server_add_disconnected_cb");
+ if (!<PREFIX>_server_add_disconnected_cb) {
+ LOGE("Failed to find plugin_server_add_disconnected_cb");
+ return false;
+ }
+
+ <PREFIX>_server_set_data_received_cb = dlsym(plugin_handle,
+ "mqtt_plugin_server_set_data_received_cb");
+ if (!<PREFIX>_server_set_data_received_cb) {
+ LOGE("Failed to find plugin_server_set_data_received_cb");
+ return false;
+ }
+
+ <PREFIX>_server_listen = dlsym(plugin_handle, "mqtt_plugin_server_listen");
+ if (!<PREFIX>_server_listen) {
+ LOGE("Failed to find plugin_server_listen");
+ return false;
+ }
+
+ <PREFIX>_server_foreach_connected_peer_info = dlsym(plugin_handle,
+ "mqtt_plugin_server_foreach_connected_peer_info");
+ if (!<PREFIX>_server_foreach_connected_peer_info) {
+ LOGE("Failed to find <PREFIX>_server_foreach_connected_peer_info");
+ return false;
+ }
+
+ <PREFIX>_server_accept = dlsym(plugin_handle, "mqtt_plugin_server_accept");
+ if (!<PREFIX>_server_accept) {
+ LOGE("Failed to init plugin_server_accept");
+ return false;
+ }
+
+ <PREFIX>_server_reject = dlsym(plugin_handle, "mqtt_plugin_server_reject");
+ if (!<PREFIX>_server_reject) {
+ LOGE("Failed to find plugin_server_reject");
+ return false;
+ }
+
+ <PREFIX>_server_set_display_name = dlsym(plugin_handle,
+ "mqtt_plugin_server_set_display_name");
+ if (!<PREFIX>_server_set_display_name) {
+ LOGE("Failed to find plugin_server_set_display_name");
+ return false;
+ }
+
+ <PREFIX>_server_send_payload_async = dlsym(plugin_handle,
+ "mqtt_plugin_server_send_payload_async");
+ if (!<PREFIX>_server_send_payload_async) {
+ LOGE("Failed to find plugin_server_send_payload_async");
+ return false;
+ }
+
+ <PREFIX>_server_destroy = dlsym(plugin_handle,
+ "mqtt_plugin_server_destroy");
+ if (!<PREFIX>_server_destroy) {
+ LOGE("Failed to find plugin_server_destroy");
+ return false;
+ }
+
+ <PREFIX>_server_disconnect = dlsym(plugin_handle,
+ "mqtt_plugin_server_disconnect");
+ if (!<PREFIX>_server_disconnect) {
+ LOGE("Failed to find plugin_server_disconnect");
+ return false;
+ }
+
+ return true;
+}
+)__c_cb";
+
+#endif // IDLC_C_MQTT_PLUGIN_GEN_INTERNAL_BODY_GEN_CB_H_
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen.cc b/idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen.cc
new file mode 100644
index 0000000..00b890e
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen.cc
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen.h"
+
+namespace {
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen_cb.h"
+}
+
+namespace tidl {
+
+MqttPluginInternalHeaderGen::MqttPluginInternalHeaderGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans)
+ : CCionHeaderGeneratorBase(doc, trans) {}
+
+void MqttPluginInternalHeaderGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+
+ stream << tidl::ReplaceAll(CB_HEADER_START, "<PREFIX>", GetHandlePrefix());
+ stream << tidl::ReplaceAll(CB_HEADER_DEF_COMMON, "<PREFIX>", GetHandlePrefix());
+
+ switch (GetChannelType()) {
+ case ChannelType::TYPE_PROXY:
+ {
+ stream << tidl::ReplaceAll(CB_HEADER_DEF_CLIENT, "<PREFIX>", GetHandlePrefix());
+ stream << tidl::ReplaceAll(CB_HEADER_FUN_CLIENT, "<PREFIX>", GetHandlePrefix());
+ break;
+ }
+ case ChannelType::TYPE_STUB:
+ {
+ stream << tidl::ReplaceAll(CB_HEADER_DEF_SERVER, "<PREFIX>", GetHandlePrefix());
+ stream << tidl::ReplaceAll(CB_HEADER_FUN_SERVER, "<PREFIX>", GetHandlePrefix());
+ break;
+ }
+ case ChannelType::TYPE_GROUP:
+ {
+ stream << tidl::ReplaceAll(CB_HEADER_DEF_GROUP, "<PREFIX>", GetHandlePrefix());
+ stream << tidl::ReplaceAll(CB_HEADER_FUN_GROUP, "<PREFIX>", GetHandlePrefix());
+ break;
+ }
+ default:
+ break;
+ }
+
+ stream << tidl::ReplaceAll(CB_HEADER_FUN_COMMOM, "<PREFIX>", GetHandlePrefix());
+}
+
+void MqttPluginInternalHeaderGen::OnFiniGen(std::ofstream& stream) {
+ GenExplicitLinkageClose(stream);
+}
+
+} // namespace tidl
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen.h b/idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen.h
new file mode 100644
index 0000000..cbc43b9
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_MQTT_PLUGIN_C_INTERNAL_HEADER_GEN_H_
+#define IDLC_MQTT_PLUGIN_C_INTERNAL_HEADER_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/c_cion_header_gen_base.h"
+
+namespace tidl {
+
+class MqttPluginInternalHeaderGen : public CCionHeaderGeneratorBase {
+ public:
+ explicit MqttPluginInternalHeaderGen(std::shared_ptr<Document> doc, std::shared_ptr<tidl::Transportable> trans);
+ virtual ~MqttPluginInternalHeaderGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+};
+
+} // namespace tidl
+
+#endif // IDLC_MQTT_PLUGIN_C_INTERNAL_HEADER_GEN_H_ \ No newline at end of file
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen_cb.h b/idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen_cb.h
new file mode 100644
index 0000000..49e1bab
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen_cb.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_MQTT_PLUGIN_GEN_INTERNAL_HEADER_GEN_CB_H_
+#define IDLC_C_MQTT_PLUGIN_GEN_INTERNAL_HEADER_GEN_CB_H_
+constexpr const char CB_HEADER_START[] =
+R"__c_cb(
+
+#pragma once
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <tizen.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum _<PREFIX>_transfer_status_e {
+ SUCCESS, /**< Transfer is success **/
+ FAILURE, /**< Transfer is failed **/
+ IN_PROGRESS, /**< Transfer is in progress **/
+} <PREFIX>_transfer_status_e;
+
+typedef enum _<PREFIX>_payload_type_e {
+ MQTT_PLUGIN_PAYLOAD_TYPE_DATA, /**< Data type payload **/
+ MQTT_PLUGIN_PAYLOAD_TYPE_FILE, /**< File type payload **/
+} <PREFIX>_payload_type_e;
+
+typedef enum _<PREFIX>_connection_status_e {
+ CONNECTION_STATUS_OK, /**< Connection is ok **/
+ CONNECTION_STATUS_REJECTED, /**< Connection is rejected **/
+ CONNECTION_STATUS_ERROR, /**< Connection error occurs **/
+} <PREFIX>_connection_status_e;
+)__c_cb";
+
+constexpr const char CB_HEADER_DEF_COMMON[] =
+R"__c_cb(
+typedef void *<PREFIX>_peer_info_h;
+typedef void *<PREFIX>_connection_result_h;
+typedef void *<PREFIX>_payload_h;
+typedef void *<PREFIX>_payload_async_result_h;
+)__c_cb";
+
+constexpr const char CB_HEADER_DEF_SERVER[] =
+R"__c_cb(
+typedef void *<PREFIX>_server_h;
+
+typedef void (*<PREFIX>_server_connection_result_cb)(
+ const char *service_name, const <PREFIX>_peer_info_h peer_info,
+ const <PREFIX>_connection_result_h result, void *user_data);
+typedef void (*<PREFIX>_server_payload_received_cb)(const char *service_name,
+ const <PREFIX>_peer_info_h peer_info, const <PREFIX>_payload_h payload,
+ <PREFIX>_transfer_status_e status, void *user_data);
+typedef void (*<PREFIX>_server_connection_request_cb)(const char *service_name,
+ const <PREFIX>_peer_info_h peer_info, void *user_data);
+typedef void (*<PREFIX>_server_disconnected_cb)(const char *service_name,
+ const <PREFIX>_peer_info_h peer_info, void *user_data);
+typedef void (*<PREFIX>_server_data_received_cb)(const char *service_name,
+ const <PREFIX>_peer_info_h peer_info, const unsigned char *data,
+ unsigned int data_size, unsigned char **return_data,
+ unsigned int *return_data_size, void *user_data);
+typedef bool (*<PREFIX>_server_connected_peer_info_cb)(
+ const <PREFIX>_peer_info_h peer_info, void *user_data);
+typedef void (*<PREFIX>_server_payload_async_result_cb)(
+ const <PREFIX>_payload_async_result_h result, void *user_data);
+)__c_cb";
+
+constexpr const char CB_HEADER_DEF_GROUP[] =
+R"__c_cb(
+typedef void *<PREFIX>_group_h;
+
+typedef void (*<PREFIX>_group_payload_received_cb)(const char *topic_name,
+ const <PREFIX>_peer_info_h peer_info, <PREFIX>_payload_h payload,
+ void *user_data);
+typedef void (*<PREFIX>_group_joined_cb)(const char *topic_name,
+ const <PREFIX>_peer_info_h peer_info, void *user_data);
+
+typedef void (*<PREFIX>_group_left_cb)(const char *topic_name,
+ const <PREFIX>_peer_info_h peer_info, void *user_data);
+)__c_cb";
+
+constexpr const char CB_HEADER_DEF_CLIENT[] =
+R"__c_cb(
+typedef void *<PREFIX>_client_h;
+
+typedef void (*<PREFIX>_client_server_discovered_cb)(const char *service_name,
+ const <PREFIX>_peer_info_h peer_info, void *user_data);
+typedef void (*<PREFIX>_client_connection_result_cb)(
+ const char *service_name, const <PREFIX>_peer_info_h peer_info,
+ const <PREFIX>_connection_result_h result, void *user_data);
+typedef void (*<PREFIX>_client_payload_async_result_cb)(
+ const <PREFIX>_payload_async_result_h result, void *user_data);
+typedef void (*<PREFIX>_client_payload_received_cb)(const char *service_name,
+ const <PREFIX>_peer_info_h peer_info, const <PREFIX>_payload_h payload,
+ <PREFIX>_transfer_status_e status, void *user_data);
+typedef void (*<PREFIX>_client_disconnected_cb)(const char *service_name,
+ const <PREFIX>_peer_info_h peer_info, void *user_data);
+)__c_cb";
+
+constexpr const char CB_HEADER_FUN_GROUP[] =
+R"__c_cb(
+int (*<PREFIX>_group_create)(<PREFIX>_group_h *, const char *,
+ const char *, int , const char *, const char *);
+int (*<PREFIX>_group_destroy)(<PREFIX>_group_h);
+int (*<PREFIX>_group_subscribe)(<PREFIX>_group_h);
+int (*<PREFIX>_group_unsubscribe)(<PREFIX>_group_h);
+int (*<PREFIX>_group_publish)(<PREFIX>_group_h, <PREFIX>_payload_h);
+int (*<PREFIX>_group_add_payload_received_cb)(<PREFIX>_group_h,
+ <PREFIX>_group_payload_received_cb, void *);
+int (*<PREFIX>_group_add_joined_cb)(<PREFIX>_group_h,
+ <PREFIX>_group_joined_cb, void *);
+int (*<PREFIX>_group_add_left_cb)(<PREFIX>_group_h,
+ <PREFIX>_group_left_cb, void *);
+)__c_cb";
+
+constexpr const char CB_HEADER_FUN_CLIENT[] =
+R"__c_cb(
+int (*<PREFIX>_client_create)(<PREFIX>_client_h *, const char *,
+ const char *, int , const char *, const char *);
+int (*<PREFIX>_client_destroy)(<PREFIX>_client_h);
+int (*<PREFIX>_client_try_discovery)(<PREFIX>_client_h,
+ <PREFIX>_client_server_discovered_cb, void *);
+int (*<PREFIX>_client_stop_discovery)(<PREFIX>_client_h);
+int (*<PREFIX>_client_connect)(<PREFIX>_client_h, const <PREFIX>_peer_info_h);
+int (*<PREFIX>_client_disconnect)(<PREFIX>_client_h);
+int (*<PREFIX>_client_send_data)(<PREFIX>_client_h, unsigned char *,
+ unsigned int, int, unsigned char **, unsigned int *);
+int (*<PREFIX>_client_send_payload_async)(<PREFIX>_client_h,
+ <PREFIX>_payload_h, <PREFIX>_client_payload_async_result_cb, void *);
+int (*<PREFIX>_client_add_connection_result_cb)(<PREFIX>_client_h,
+ <PREFIX>_client_connection_result_cb, void *);
+int (*<PREFIX>_client_add_payload_received_cb)(<PREFIX>_client_h,
+ <PREFIX>_client_payload_received_cb, void *);
+int (*<PREFIX>_client_add_disconnected_cb)(<PREFIX>_client_h,
+ <PREFIX>_client_disconnected_cb, void *);
+)__c_cb";
+
+constexpr const char CB_HEADER_FUN_SERVER[] =
+R"__c_cb(
+int (*<PREFIX>_server_create)(<PREFIX>_server_h *, const char *,
+ const char *, const char *, int ,const char *, const char *);
+int (*<PREFIX>_server_add_connection_result_cb)(<PREFIX>_server_h,
+ <PREFIX>_server_connection_result_cb, void *);
+int (*<PREFIX>_server_add_payload_received_cb)(<PREFIX>_server_h,
+ <PREFIX>_server_payload_received_cb, void *);
+int (*<PREFIX>_server_add_disconnected_cb)(<PREFIX>_server_h,
+ <PREFIX>_server_disconnected_cb, void *);
+int (*<PREFIX>_server_set_data_received_cb)(<PREFIX>_server_h,
+ <PREFIX>_server_data_received_cb , void *);
+int (*<PREFIX>_server_destroy)(<PREFIX>_server_h);
+int (*<PREFIX>_server_listen)(<PREFIX>_server_h,
+ <PREFIX>_server_connection_request_cb, void *);
+int (*<PREFIX>_server_foreach_connected_peer_info)(<PREFIX>_server_h,
+ <PREFIX>_server_connected_peer_info_cb, void *);
+int (*<PREFIX>_server_accept)(<PREFIX>_server_h, const <PREFIX>_peer_info_h);
+int (*<PREFIX>_server_reject)(<PREFIX>_server_h,const <PREFIX>_peer_info_h,
+ const char *);
+int (*<PREFIX>_server_set_display_name)(<PREFIX>_server_h, const char *);
+int (*<PREFIX>_server_send_payload_async)(<PREFIX>_server_h,
+ <PREFIX>_peer_info_h, <PREFIX>_payload_h,
+ <PREFIX>_server_payload_async_result_cb, void *);
+int (*<PREFIX>_server_disconnect)(<PREFIX>_server_h, <PREFIX>_peer_info_h);
+)__c_cb";
+
+constexpr const char CB_HEADER_FUN_COMMOM[] =
+R"__c_cb(
+int (*<PREFIX>_payload_create)(<PREFIX>_payload_h *, <PREFIX>_payload_type_e);
+int (*<PREFIX>_payload_destroy)(<PREFIX>_payload_h);
+int (*<PREFIX>_payload_get_type)(<PREFIX>_payload_h, <PREFIX>_payload_type_e *);
+int (*<PREFIX>_payload_get_data)(<PREFIX>_payload_h, unsigned char **, unsigned int *);
+int (*<PREFIX>_payload_set_data)(<PREFIX>_payload_h, const unsigned char *, unsigned int);
+int (*<PREFIX>_payload_save_as_file)(<PREFIX>_payload_h, const char *);
+int (*<PREFIX>_payload_get_received_file_name)(<PREFIX>_payload_h, char **);
+int (*<PREFIX>_payload_get_received_bytes)(<PREFIX>_payload_h, uint64_t *);
+int (*<PREFIX>_payload_get_total_bytes)(<PREFIX>_payload_h, uint64_t *);
+int (*<PREFIX>_payload_set_file_path)(<PREFIX>_payload_h, const char *);
+int (*<PREFIX>_payload_get_payload_id)(<PREFIX>_payload_h, char **);
+
+int (*<PREFIX>_peer_info_clone)(const <PREFIX>_peer_info_h, <PREFIX>_peer_info_h *);
+int (*<PREFIX>_peer_info_destroy)(<PREFIX>_peer_info_h);
+int (*<PREFIX>_peer_info_get_device_id)(<PREFIX>_peer_info_h, char **);
+int (*<PREFIX>_peer_info_get_device_name)(<PREFIX>_peer_info_h, char **);
+int (*<PREFIX>_peer_info_get_device_platform)(<PREFIX>_peer_info_h, char **);
+int (*<PREFIX>_peer_info_get_device_platform_version)(<PREFIX>_peer_info_h, char **);
+int (*<PREFIX>_peer_info_get_device_type)(<PREFIX>_peer_info_h, char **);
+int (*<PREFIX>_peer_info_get_app_id)(<PREFIX>_peer_info_h, char **);
+int (*<PREFIX>_peer_info_get_app_version)(<PREFIX>_peer_info_h, char **);
+int (*<PREFIX>_peer_info_get_uuid)(<PREFIX>_peer_info_h, char **);
+int (*<PREFIX>_peer_info_get_display_name)(<PREFIX>_peer_info_h, char **);
+
+int (*<PREFIX>_connection_result_get_status)(const <PREFIX>_connection_result_h, <PREFIX>_connection_status_e *);
+int (*<PREFIX>_connection_result_get_reason)(const <PREFIX>_connection_result_h, char **reason);
+)__c_cb";
+
+#endif // IDLC_C_MQTT_PLUGIN_GEN_INTERNAL_HEADER_GEN_CB_H_
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_java_transportable.cc b/idlc/gen_mqtt_plugin/mqtt_plugin_java_transportable.cc
new file mode 100644
index 0000000..c621d9c
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_java_transportable.cc
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_java_transportable.h"
+
+#include <utility>
+
+#include "idlc/gen/replace_all.h"
+
+namespace {
+
+std::string ParamsToString(std::vector<std::string> params) {
+ std::string res;
+ for (auto it = params.begin(); it != params.end(); it++) {
+ res += *it;
+ if ((it + 1) != params.end())
+ res += ", ";
+ }
+
+ return res;
+}
+
+constexpr const char __CLIENT_BASE_CONSTRUCTOR[] =
+R"__java_cb(
+ /**
+ * Constructor
+ * @param mContext The Context
+ * @param serviceName Service name
+ */
+ public ClientBase(Context mContext, String serviceName, String brokerIp) {
+ mClient = new <CLIENT_CHANNEL>(mContext, serviceName, brokerIp);
+ this.mContext = mContext;
+ }
+)__java_cb";
+
+constexpr const char __SERVER_BASE_CONSTRUCTOR[] =
+R"__java_cb(
+ /**
+ * Constructor
+ * @param mContext Context
+ * @param mServiceName Service name
+ * @param mDisplayName Display name
+ */
+ public ServerBase(Context mContext, String mServiceName, String mDisplayName, String brokerIp) {
+ mServer = new <SERVER_CHANNEL>(mContext, mServiceName, mDisplayName, brokerIp);
+ this.mContext = mContext;
+ this.mServiceName = mServiceName;
+ this.mDisplayName = mDisplayName;
+ }
+)__java_cb";
+
+constexpr const char __GROUP_BASE_CONSTRUCTOR[] =
+R"__java_cb(
+ /**
+ * Constructor
+ * @param mContext The Context
+ * @param topicName Topic name
+ */
+ public GroupBase(Context mContext, String topicName, String brokerIp) {
+ mGroup = new <GROUP_CHANNEL>(mContext, topicName, brokerIp);
+ this.mContext = mContext;
+ }
+)__java_cb";
+
+constexpr const char __ON_LEFT_EVENT_METHOD[] =
+R"__java_cb(
+ @Override
+ public void onLeft(<PEER_INFO_T> peerInfo, String topic_name) {
+ }
+)__java_cb";
+
+constexpr const char __ON_JOINED_EVENT_METHOD[] =
+R"__java_cb(
+ @Override
+ public void onJoined(<PEER_INFO_T> peerInfo, String topic_name) {
+ }
+)__java_cb";
+
+constexpr const char __INHERITED_CLASS_CONSTRUCTOR[] =
+R"__java_cb(
+public $$(<PARAMETERS>, String brokerIp) {
+ super(<BASE_CLASS_PARAMETERS>, brokerIp);
+ <EXTRA_OPERATION>
+}
+)__java_cb";
+
+} // namespace
+
+namespace tidl {
+
+std::string MqttPluginJavaTransportable::GenInclude() const {
+ return "import org.tizen.mqtt.*;";
+}
+
+std::string MqttPluginJavaTransportable::GenParcelInclude() const {
+ return "import org.tizen.mqtt.MqttParcel;";
+}
+
+std::string MqttPluginJavaTransportable::GenParcel() const {
+ return "MqttParcel";
+}
+
+std::string MqttPluginJavaTransportable::GenClientBaseConstructor() const {
+ return __CLIENT_BASE_CONSTRUCTOR;
+}
+
+std::string MqttPluginJavaTransportable::GenServerBaseConstructor() const {
+ return __SERVER_BASE_CONSTRUCTOR;
+}
+
+std::string MqttPluginJavaTransportable::GenGroupBaseConstructor() const {
+ return __GROUP_BASE_CONSTRUCTOR;
+}
+
+std::string MqttPluginJavaTransportable::GenOnLeftEventMethod() const {
+ return __ON_LEFT_EVENT_METHOD;
+}
+
+std::string MqttPluginJavaTransportable::GenOnJoinedEventMethod() const {
+ return __ON_JOINED_EVENT_METHOD;
+}
+
+std::string MqttPluginJavaTransportable::GenInheritedClassConstructor(
+ std::vector<std::string> params, std::vector<std::string> base_class_params,
+ std::string extra_operation) const {
+ return std::string(ReplaceAll(__INHERITED_CLASS_CONSTRUCTOR, {
+ { "<PARAMETERS>", ParamsToString(params) },
+ { "<BASE_CLASS_PARAMETERS>", ParamsToString(base_class_params) },
+ { "<EXTRA_OPERATION>", extra_operation }
+ }));
+}
+
+} // namespace tidl
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_java_transportable.h b/idlc/gen_mqtt_plugin/mqtt_plugin_java_transportable.h
new file mode 100644
index 0000000..f0a9cb3
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_java_transportable.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_MQTT_PLUGIN_JAVA_TRANSPORTABLE_H_
+#define IDLC_GEN_MQTT_PLUGIN_JAVA_TRANSPORTABLE_H_
+
+#include <string>
+
+#include "idlc/gen_cion/default_java_transportable.h"
+
+namespace tidl {
+
+class MqttPluginJavaTransportable : public DefaultJavaTransportable {
+ public:
+ std::string GenInclude() const override;
+ std::string GenParcelInclude() const override;
+ std::string GenParcel() const override;
+ std::string GenClientBaseConstructor() const override;
+ std::string GenServerBaseConstructor() const override;
+ std::string GenGroupBaseConstructor() const override;
+ std::string GenOnLeftEventMethod() const override;
+ std::string GenOnJoinedEventMethod() const override;
+ std::string GenInheritedClassConstructor(std::vector<std::string> params,
+ std::vector<std::string> base_class_params,
+ std::string extra_operation) const override;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_MQTT_PLUGIN_JAVA_TRANSPORTABLE_H_
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_loader.cc b/idlc/gen_mqtt_plugin/mqtt_plugin_loader.cc
new file mode 100644
index 0000000..bcb6749
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_loader.cc
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_loader.h"
+
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_c_transportable.h"
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_cs_transportable.h"
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_java_transportable.h"
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_cpp_transportable.h"
+#include "idlc/gen_cion/default_cpp_transportable.h"
+#include "idlc/gen_cion/default_java_transportable.h"
+#include "idlc/gen_cion/default_cs_transportable.h"
+
+namespace tidl {
+
+MqttPluginLoader::MqttPluginLoader(const std::string& plugin_path) {
+ if (plugin_path.empty()) {
+ C_.reset(new MqttPluginCTransportable());
+ Cs_.reset(new MqttPluginCsTransportable());
+ Cpp_.reset(new MqttPluginCppTransportable());
+ Java_.reset(new MqttPluginJavaTransportable());
+ } else {
+ // TODO
+ }
+}
+
+const CTransportable& MqttPluginLoader::C() {
+ return *C_;
+}
+
+const CppTransportable& MqttPluginLoader::Cpp() {
+ return *Cpp_;
+}
+
+const CsTransportable& MqttPluginLoader::Cs() {
+ return *Cs_;
+
+}
+
+const JavaTransportable& MqttPluginLoader::Java() {
+ return *Java_;
+}
+
+const DartTransportable& MqttPluginLoader::Dart() {
+ return *Dart_;
+}
+
+} // namespace tidl
diff --git a/idlc/gen_mqtt_plugin/mqtt_plugin_loader.h b/idlc/gen_mqtt_plugin/mqtt_plugin_loader.h
new file mode 100644
index 0000000..9b3e40c
--- /dev/null
+++ b/idlc/gen_mqtt_plugin/mqtt_plugin_loader.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_MQTT_PLUGIN_LOADER_H_
+#define IDLC_GEN_MQTT_PLUGIN_LOADER_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/transportable.h"
+
+namespace tidl {
+
+class MqttPluginLoader : public Transportable {
+ public:
+ explicit MqttPluginLoader(const std::string& plugin_path);
+
+ const CTransportable& C() override;
+ const CppTransportable& Cpp() override;
+ const CsTransportable& Cs() override;
+ const JavaTransportable& Java() override;
+ const DartTransportable& Dart() override;
+
+ private:
+ std::unique_ptr<CTransportable> C_;
+ std::unique_ptr<CppTransportable> Cpp_;
+ std::unique_ptr<CsTransportable> Cs_;
+ std::unique_ptr<JavaTransportable> Java_;
+ std::unique_ptr<DartTransportable> Dart_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_MQTT_PLUGIN_LOADER_H_ \ No newline at end of file
diff --git a/idlc/main.cc b/idlc/main.cc
index 2b9cbb7..63ddb84 100644
--- a/idlc/main.cc
+++ b/idlc/main.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,79 +14,54 @@
* limitations under the License.
*/
-
-#include <iostream>
#include <cstring>
+#include <functional>
+#include <iostream>
#include <memory>
+#include <utility>
#include "idlc/ast/parser.h"
-#include "idlc/gen/cs_proxy_gen.h"
-#include "idlc/gen/cs_stub_gen.h"
-#include "idlc/gen/cs_lib_gen.h"
-#include "idlc/gen/c_proxy_header_gen.h"
-#include "idlc/gen/c_proxy_body_gen.h"
-#include "idlc/gen/c_stub_header_gen.h"
-#include "idlc/gen/c_stub_body_gen.h"
-#include "idlc/gen/cpp_proxy_header_gen.h"
-#include "idlc/gen/cpp_proxy_body_gen.h"
-#include "idlc/gen/cpp_stub_header_gen.h"
-#include "idlc/gen/cpp_stub_body_gen.h"
+#include "idlc/cion_generator.hh"
+#include "idlc/code_generator.hh"
+#include "idlc/default_generator.hh"
+#include "idlc/mqtt_generator.hh"
#include "idlc/options.h"
+#include "idlc/version2_default_generator.hh"
+
+namespace {
+
+void GenerateCodes(std::shared_ptr<tidl::Options> options,
+ const tidl::Parser& ps) {
+ std::shared_ptr<tidl::CodeGenerator> generator;
+ if (options->IsCion()) {
+ generator.reset(new tidl::CionGenerator());
+ } else if (options->IsMqtt()) {
+ generator.reset(new tidl::MqttGenerator());
+ } else {
+ if (ps.GetVersion() == 2)
+ generator.reset(new tidl::version2::DefaultGenerator());
+ else
+ generator.reset(new tidl::DefaultGenerator());
+ }
+
+ generator->Generate(std::move(options), ps);
+}
+
+} // namespace
int main(int argc, char** argv) {
std::shared_ptr<tidl::Options> options = tidl::Options::Parse(argc, argv);
if (!options)
exit(1);
- tidl::Parser ps(options->IsBetaEnabled());
+ tidl::Parser ps(options->IsBetaEnabled(), options->IsCion(),
+ options->IsMqtt(),
+ options->GetType() == tidl::Options::Type::TYPE_GROUP ? true : false);
std::string path(options->GetInput());
if (!ps.ParseFromFile(path))
exit(1);
- if (options->IsProxy()) {
- if (options->GetLanguage() == "C#") {
- tidl::CsProxyGen proxy(ps.GetDoc());
- proxy.Run(options->GetOutput() + ".cs");
- if (options->HasRpcPortLib()) {
- tidl::CsLibGen lib(ps.GetDoc());
- lib.Run("rpc-port.cs");
- }
- } else if (options->GetLanguage() == "C++") {
- tidl::CppProxyHeaderGen proxy_header(ps.GetDoc());
- proxy_header.Run(options->GetOutput() + ".h");
- tidl::CppProxyBodyGen proxy_body(ps.GetDoc());
- proxy_body.Run(options->GetOutput() + ".cc");
- } else if (options->GetLanguage() == "C") {
- tidl::CProxyHeaderGen proxy_header(ps.GetDoc());
- proxy_header.EnableNamespace(options->HasNamespace());
- proxy_header.Run(options->GetOutput() + ".h");
- tidl::CProxyBodyGen proxy_body(ps.GetDoc());
- proxy_body.EnableNamespace(options->HasNamespace());
- proxy_body.Run(options->GetOutput() + ".c");
- }
- } else {
- if (options->GetLanguage() == "C#") {
- tidl::CsStubGen stub(ps.GetDoc());
- stub.Run(options->GetOutput() + ".cs");
- if (options->HasRpcPortLib()) {
- tidl::CsLibGen lib(ps.GetDoc());
- lib.Run("rpc-port.cs");
- }
- } else if (options->GetLanguage() == "C++") {
- tidl::CppStubHeaderGen stub_header(ps.GetDoc(), options);
- stub_header.Run(options->GetOutput() + ".h");
- tidl::CppStubBodyGen stub_body(ps.GetDoc(), options);
- stub_body.Run(options->GetOutput() + ".cc");
- } else if (options->GetLanguage() == "C") {
- tidl::CStubHeaderGen stub_header(ps.GetDoc());
- stub_header.EnableNamespace(options->HasNamespace());
- stub_header.Run(options->GetOutput() + ".h");
- tidl::CStubBodyGen stub_body(ps.GetDoc(), options);
- stub_body.EnableNamespace(options->HasNamespace());
- stub_body.Run(options->GetOutput() + ".c");
- }
- }
-
+ GenerateCodes(options, ps);
return 0;
}
diff --git a/idlc/mqtt_generator.cc b/idlc/mqtt_generator.cc
new file mode 100644
index 0000000..35d1a55
--- /dev/null
+++ b/idlc/mqtt_generator.cc
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/mqtt_generator.hh"
+
+#include <utility>
+
+#include "idlc/gen_cion/c_cion_group_body_gen.h"
+#include "idlc/gen_cion/c_cion_group_header_gen.h"
+#include "idlc/gen_cion/c_cion_proxy_body_gen.h"
+#include "idlc/gen_cion/c_cion_proxy_header_gen.h"
+#include "idlc/gen_cion/c_cion_stub_body_gen.h"
+#include "idlc/gen_cion/c_cion_stub_header_gen.h"
+#include "idlc/gen_cion/cpp_cion_group_body_gen.h"
+#include "idlc/gen_cion/cpp_cion_group_header_gen.h"
+#include "idlc/gen_cion/cpp_cion_proxy_body_gen.h"
+#include "idlc/gen_cion/cpp_cion_proxy_header_gen.h"
+#include "idlc/gen_cion/cpp_cion_stub_body_gen.h"
+#include "idlc/gen_cion/cpp_cion_stub_header_gen.h"
+#include "idlc/gen_cion/cs_cion_group_gen.h"
+#include "idlc/gen_cion/cs_cion_proxy_gen.h"
+#include "idlc/gen_cion/cs_cion_stub_gen.h"
+#include "idlc/gen_cion/dart_cion_group_gen.h"
+#include "idlc/gen_cion/dart_cion_proxy_gen.h"
+#include "idlc/gen_cion/dart_cion_stub_gen.h"
+#include "idlc/gen_cion/java_cion_common_gen.h"
+#include "idlc/gen_cion/java_cion_group_gen.h"
+#include "idlc/gen_cion/java_cion_group_repo_gen.h"
+#include "idlc/gen_cion/java_cion_proxy_gen.h"
+#include "idlc/gen_cion/java_cion_proxy_repo_gen.h"
+#include "idlc/gen_cion/java_cion_structure_gen.h"
+#include "idlc/gen_cion/java_cion_stub_gen.h"
+#include "idlc/gen_cion/java_cion_stub_repo_gen.h"
+#include "idlc/gen_cion/java_cion_utility_gen.h"
+#include "idlc/gen_cion/plugin_loader.h"
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_c_transportable.h"
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_cpp_transportable.h"
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_cs_base_gen.h"
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_cs_interop_gen.h"
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen.h"
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen.h"
+#include "idlc/gen_mqtt_plugin/mqtt_plugin_loader.h"
+
+namespace tidl {
+
+MqttGenerator::MqttGenerator() {
+ mqtt_funcs_ = {
+ // Stub
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_C),
+ std::bind(&MqttGenerator::GenMqttCStubCode, this, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_CPP),
+ std::bind(&MqttGenerator::GenMqttCppStubCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_CSHARP),
+ std::bind(&MqttGenerator::GenMqttCsharpStubCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_JAVA),
+ std::bind(&MqttGenerator::GenMqttJavaStubCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+
+ // Proxy
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_C),
+ std::bind(&MqttGenerator::GenMqttCProxyCode, this, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_CPP),
+ std::bind(&MqttGenerator::GenMqttCppProxyCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_CSHARP),
+ std::bind(&MqttGenerator::GenMqttCsharpProxyCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_JAVA),
+ std::bind(&MqttGenerator::GenMqttJavaProxyCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+
+ // Group
+ {std::make_pair(Options::Type::TYPE_GROUP, Options::LANGUAGE_TYPE_C),
+ std::bind(&MqttGenerator::GenMqttCGroupCode, this, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_GROUP, Options::LANGUAGE_TYPE_CPP),
+ std::bind(&MqttGenerator::GenMqttCppGroupCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_GROUP, Options::LANGUAGE_TYPE_CSHARP),
+ std::bind(&MqttGenerator::GenMqttCsharpGroupCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ {std::make_pair(Options::Type::TYPE_GROUP, Options::LANGUAGE_TYPE_JAVA),
+ std::bind(&MqttGenerator::GenMqttJavaGroupCode, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3)},
+ };
+}
+
+void MqttGenerator::Generate(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ auto found = mqtt_funcs_.find(
+ std::make_pair(options->GetType(), options->GetLanguage()));
+ if (found == mqtt_funcs_.end()) return;
+
+ auto trans = std::shared_ptr<Transportable>(new MqttPluginLoader(""));
+ auto& func = found->second;
+ func(std::move(options), ps, std::move(trans));
+}
+
+void MqttGenerator::GenMqttCStubCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ MqttPluginInternalHeaderGen internal_header(ps.GetDoc(), trans);
+ internal_header.EnableNamespace(options->HasNamespace());
+ internal_header.EnableGeneratedAPI(true);
+ internal_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ internal_header.Run(options->GetOutput() + "_internal.h");
+
+ MqttPluginInternalBodyGen internal_body(ps.GetDoc(), trans);
+ internal_body.EnableNamespace(options->HasNamespace());
+ internal_body.EnableGeneratedAPI(true);
+ internal_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ internal_body.Run(options->GetOutput() + "_internal.c");
+
+ CCionStubHeaderGen stub_header(ps.GetDoc(), trans);
+ stub_header.EnableNamespace(options->HasNamespace());
+ stub_header.EnableGeneratedAPI(true);
+ stub_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ stub_header.Run(options->GetOutput() + ".h");
+
+ CCionStubBodyGen stub_body(ps.GetDoc(), options, trans);
+ stub_body.EnableNamespace(options->HasNamespace());
+ stub_body.EnableGeneratedAPI(true);
+ stub_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ stub_body.Run(options->GetOutput() + ".c");
+}
+
+void MqttGenerator::GenMqttCppStubCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ MqttPluginInternalHeaderGen internal_header(ps.GetDoc(), trans);
+ internal_header.EnableNamespace(options->HasNamespace());
+ internal_header.EnableGeneratedAPI(true);
+ internal_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ internal_header.Run(options->GetOutput() + "_internal.h");
+
+ MqttPluginInternalBodyGen internal_body(ps.GetDoc(), trans);
+ internal_body.EnableNamespace(options->HasNamespace());
+ internal_body.EnableGeneratedAPI(true);
+ internal_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ internal_body.Run(options->GetOutput() + "_internal.c");
+
+ CppCionStubHeaderGen stub_header(ps.GetDoc(), options, trans);
+ stub_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ stub_header.EnableGeneratedAPI(true);
+ stub_header.EnableNamespace(options->HasNamespace());
+ stub_header.Run(options->GetOutput() + ".h");
+
+ CppCionStubBodyGen stub_body(ps.GetDoc(), options, trans);
+ stub_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ stub_body.EnableGeneratedAPI(true);
+ stub_body.EnableNamespace(options->HasNamespace());
+ stub_body.Run(options->GetOutput() + ".cc");
+}
+
+void MqttGenerator::GenMqttCsharpStubCode(
+ std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ MqttPluginCsInteropGen interop(ps.GetDoc(), trans);
+ interop.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ interop.Run("Interop.MqttPlugin.cs");
+
+ MqttPluginCsBaseGen base(ps.GetDoc(), trans);
+ base.SetChannelType(static_cast<Generator::ChannelType>(options->GetType()));
+ base.Run("MqttPluginBase.cs");
+
+ CsCionStubGen stub(ps.GetDoc(), trans);
+ stub.Run(options->GetOutput() + ".cs");
+}
+
+void MqttGenerator::GenMqttJavaStubCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ JavaCionStubRepoGen repo(ps.GetDoc(), trans);
+ repo.Run(options->GetOutput(), true);
+
+ JavaCionStubGen view_model(ps.GetDoc(), trans);
+ view_model.Run(options->GetOutput(), true);
+
+ JavaCionUtilityGen utilities(ps.GetDoc(), trans);
+ utilities.Run(options->GetOutput(), true);
+
+ JavaCionStructureGen structures(ps.GetDoc(), trans);
+ structures.Run(options->GetOutput(), true);
+
+ JavaCionCommonGen cgen(ps.GetDoc(), trans);
+ cgen.Run(options->GetOutput(), true);
+}
+
+void MqttGenerator::GenMqttCProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ MqttPluginInternalHeaderGen internal_header(ps.GetDoc(), trans);
+ internal_header.EnableNamespace(options->HasNamespace());
+ internal_header.EnableGeneratedAPI(true);
+ internal_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ internal_header.Run(options->GetOutput() + "_internal.h");
+
+ MqttPluginInternalBodyGen internal_body(ps.GetDoc(), trans);
+ internal_body.EnableNamespace(options->HasNamespace());
+ internal_body.EnableGeneratedAPI(true);
+ internal_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ internal_body.Run(options->GetOutput() + "_internal.c");
+
+ CCionProxyHeaderGen proxy_header(ps.GetDoc(), trans);
+ proxy_header.EnableNamespace(options->HasNamespace());
+ proxy_header.EnableGeneratedAPI(true);
+ proxy_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ proxy_header.Run(options->GetOutput() + ".h");
+
+ CCionProxyBodyGen proxy_body(ps.GetDoc(), options, trans);
+ proxy_body.EnableNamespace(options->HasNamespace());
+ proxy_body.EnableGeneratedAPI(true);
+ proxy_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ proxy_body.Run(options->GetOutput() + ".c");
+}
+
+void MqttGenerator::GenMqttCppProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ MqttPluginInternalHeaderGen internal_header(ps.GetDoc(), trans);
+ internal_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ internal_header.EnableNamespace(options->HasNamespace());
+ internal_header.EnableGeneratedAPI(true);
+ internal_header.Run(options->GetOutput() + "_internal.h");
+
+ MqttPluginInternalBodyGen internal_body(ps.GetDoc(), trans);
+ internal_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ internal_body.EnableNamespace(options->HasNamespace());
+ internal_body.EnableGeneratedAPI(true);
+ internal_body.Run(options->GetOutput() + "_internal.c");
+
+ CppCionProxyHeaderGen proxy_header(ps.GetDoc(), trans);
+ proxy_header.EnableNamespace(options->HasNamespace());
+ proxy_header.EnableGeneratedAPI(true);
+ proxy_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ proxy_header.Run(options->GetOutput() + ".h");
+
+ CppCionProxyBodyGen proxy_body(ps.GetDoc(), trans);
+ proxy_body.EnableNamespace(options->HasNamespace());
+ proxy_body.EnableGeneratedAPI(true);
+ proxy_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ proxy_body.Run(options->GetOutput() + ".cc");
+}
+
+void MqttGenerator::GenMqttCsharpProxyCode(
+ std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ MqttPluginCsInteropGen interop(ps.GetDoc(), trans);
+ interop.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ interop.Run("Interop.MqttPlugin.cs");
+
+ MqttPluginCsBaseGen base(ps.GetDoc(), trans);
+ base.SetChannelType(static_cast<Generator::ChannelType>(options->GetType()));
+ base.Run("MqttPluginBase.cs");
+
+ CsCionProxyGen proxy(ps.GetDoc(), trans);
+ proxy.Run(options->GetOutput() + ".cs");
+}
+
+void MqttGenerator::GenMqttJavaProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ JavaCionProxyRepoGen base_files(ps.GetDoc(), trans);
+ base_files.Run(options->GetOutput(), true);
+
+ JavaCionProxyGen view_model(ps.GetDoc(), trans);
+ view_model.Run(options->GetOutput(), true);
+
+ JavaCionUtilityGen utilities(ps.GetDoc(), trans);
+ utilities.Run(options->GetOutput(), true);
+
+ JavaCionStructureGen structures(ps.GetDoc(), trans);
+ structures.Run(options->GetOutput(), true);
+
+ JavaCionCommonGen cgen(ps.GetDoc(), trans);
+ cgen.Run(options->GetOutput(), true);
+}
+
+void MqttGenerator::GenMqttCGroupCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ MqttPluginInternalHeaderGen internal_header(ps.GetDoc(), trans);
+ internal_header.EnableNamespace(options->HasNamespace());
+ internal_header.EnableGeneratedAPI(true);
+ internal_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ internal_header.Run(options->GetOutput() + "_internal.h");
+
+ MqttPluginInternalBodyGen internal_body(ps.GetDoc(), trans);
+ internal_body.EnableNamespace(options->HasNamespace());
+ internal_body.EnableGeneratedAPI(true);
+ internal_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ internal_body.Run(options->GetOutput() + "_internal.c");
+
+ CCionGroupHeaderGen group_header(ps.GetDoc(), trans);
+ group_header.EnableNamespace(options->HasNamespace());
+ group_header.EnableGeneratedAPI(true);
+ group_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ group_header.EnableGeneratedAPI(true);
+ group_header.Run(options->GetOutput() + ".h");
+
+ CCionGroupBodyGen group_body(ps.GetDoc(), options, trans);
+ group_body.EnableNamespace(options->HasNamespace());
+ group_body.EnableGeneratedAPI(true);
+ group_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ group_body.EnableGeneratedAPI(true);
+ group_body.Run(options->GetOutput() + ".c");
+}
+
+void MqttGenerator::GenMqttCppGroupCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ MqttPluginInternalHeaderGen internal_header(ps.GetDoc(), trans);
+ internal_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ internal_header.EnableNamespace(options->HasNamespace());
+ internal_header.EnableGeneratedAPI(true);
+ internal_header.Run(options->GetOutput() + "_internal.h");
+
+ MqttPluginInternalBodyGen internal_body(ps.GetDoc(), trans);
+ internal_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ internal_body.EnableNamespace(options->HasNamespace());
+ internal_body.EnableGeneratedAPI(true);
+ internal_body.Run(options->GetOutput() + "_internal.c");
+
+ CppCionGroupHeaderGen group_header(ps.GetDoc(), trans);
+ group_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ group_header.EnableNamespace(options->HasNamespace());
+ group_header.EnableGeneratedAPI(true);
+ group_header.Run(options->GetOutput() + ".h");
+
+ CppCionGroupBodyGen group_body(ps.GetDoc(), trans);
+ group_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ group_body.EnableNamespace(options->HasNamespace());
+ group_body.EnableGeneratedAPI(true);
+ group_body.Run(options->GetOutput() + ".cc");
+}
+
+void MqttGenerator::GenMqttCsharpGroupCode(
+ std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ MqttPluginCsInteropGen interop(ps.GetDoc(), trans);
+ interop.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ interop.Run("Interop.MqttPlugin.cs");
+
+ MqttPluginCsBaseGen base(ps.GetDoc(), trans);
+ base.SetChannelType(static_cast<Generator::ChannelType>(options->GetType()));
+ base.Run("MqttPluginBase.cs");
+
+ CsCionGroupGen group(ps.GetDoc(), trans);
+ group.Run(options->GetOutput() + ".cs");
+}
+
+void MqttGenerator::GenMqttJavaGroupCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans) {
+ JavaCionGroupRepoGen repo(ps.GetDoc(), trans);
+ repo.Run(options->GetOutput(), true);
+
+ JavaCionGroupGen view_model(ps.GetDoc(), trans);
+ view_model.Run(options->GetOutput(), true);
+
+ JavaCionUtilityGen utilities(ps.GetDoc(), trans);
+ utilities.Run(options->GetOutput(), true);
+
+ JavaCionStructureGen structures(ps.GetDoc(), trans);
+ structures.Run(options->GetOutput(), true);
+
+ JavaCionCommonGen cgen(ps.GetDoc(), trans);
+ cgen.Run(options->GetOutput(), true);
+}
+
+} // namespace tidl
diff --git a/idlc/mqtt_generator.hh b/idlc/mqtt_generator.hh
new file mode 100644
index 0000000..c1db9ec
--- /dev/null
+++ b/idlc/mqtt_generator.hh
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_MQTT_GENERATOR_HH_
+#define IDLC_MQTT_GENERATOR_HH_
+
+#include <functional>
+#include <memory>
+#include <unordered_map>
+
+#include "idlc/code_generator.hh"
+#include "idlc/gen_cion/transportable.h"
+
+namespace tidl {
+
+class MqttGenerator : public CodeGenerator {
+ public:
+ MqttGenerator();
+ virtual ~MqttGenerator() = default;
+
+ void Generate(std::shared_ptr<Options> options, const Parser& ps) override;
+
+ private:
+ using GeneratorMqttFunc = std::function<void(
+ std::shared_ptr<Options>, const Parser&, std::shared_ptr<Transportable>)>;
+
+ /// Stub
+ void GenMqttCStubCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenMqttCppStubCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenMqttCsharpStubCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenMqttJavaStubCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+
+ /// Proxy
+ void GenMqttCProxyCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenMqttCppProxyCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenMqttCsharpProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenMqttJavaProxyCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+
+ /// Group
+ void GenMqttCGroupCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenMqttCppGroupCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenMqttCsharpGroupCode(std::shared_ptr<Options> options,
+ const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+ void GenMqttJavaGroupCode(std::shared_ptr<Options> options, const Parser& ps,
+ std::shared_ptr<Transportable> trans);
+
+ private:
+ std::unordered_map<GeneratorCond, GeneratorMqttFunc, PairHash> mqtt_funcs_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_MQTT_GENERATOR_HH_
diff --git a/idlc/options.cc b/idlc/options.cc
index 435eb44..2d819a6 100644
--- a/idlc/options.cc
+++ b/idlc/options.cc
@@ -17,6 +17,7 @@
#include <getopt.h>
#include <fstream>
+#include <algorithm>
#include "idlc/options.h"
@@ -31,17 +32,20 @@ Help Options:
-h, --help Show help options
Additional Options:
- -l, --language=LANGUAGE Select generating language (C, C++, C#).
+ -l, --language=LANGUAGE Select generating language (C, C++, C#, Java(CION & MQTT only), Dart).
-i, --input=INPUT A tidl interface file.
-o, --output=OUTPUT The generated interface file.
-n, --namespace Add the prefix in the funtion name as output file name (C language only).
-r, --rpclib Generate C# library for rpc-port (C# language only).
-b, --beta Use beta version (Support private file sharing).
-t, --thread Generate thread code (Stub only).
+ -c, --cion Generate CION code.
+ -m, --mqtt Generate MQTT code.
Application Options:
-p, --proxy Generate proxy code
-s, --stub Generate stub code
+ -g, --group Generate group code (CION and MQTT only)
-v, --version Show version information
)__option_cb";
}
@@ -58,6 +62,22 @@ void Options::PrintSample() {
std::cerr << "tidlc -p -l C++ -i test.tidl -o CppTestProxy " << std::endl;
}
+Options::LanguageType ConvertStr2LanguageType(std::string str_type) {
+ std::transform(str_type.begin(), str_type.end(), str_type.begin(), ::tolower);
+ if (str_type == "java")
+ return Options::LANGUAGE_TYPE_JAVA;
+ else if ((str_type == "c++") || (str_type == "cpp"))
+ return Options::LANGUAGE_TYPE_CPP;
+ else if ((str_type == "c#") || (str_type == "csharp"))
+ return Options::LANGUAGE_TYPE_CSHARP;
+ else if (str_type == "c")
+ return Options::LANGUAGE_TYPE_C;
+ else if (str_type == "dart")
+ return Options::LANGUAGE_TYPE_DART;
+
+ return Options::LANGUAGE_TYPE_UNKNOWN;
+}
+
std::shared_ptr<Options> Options::Parse(int argc, char** argv) {
int cmd[CMD_MAX] = { 0, };
int opt[OPT_MAX] = { 0, };
@@ -67,6 +87,7 @@ std::shared_ptr<Options> Options::Parse(int argc, char** argv) {
struct option long_options[] = {
{"proxy", no_argument, NULL, 'p'},
{"stub", no_argument, NULL, 's'},
+ {"group", no_argument, NULL, 'g'},
{"version", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{"language", required_argument, NULL, 'l'},
@@ -76,11 +97,13 @@ std::shared_ptr<Options> Options::Parse(int argc, char** argv) {
{"rpclib", no_argument, NULL, 'r'},
{"beta", no_argument, NULL, 'b'},
{"thread", no_argument, NULL, 't'},
+ {"cion", no_argument, NULL, 'c'},
+ {"mqtt", no_argument, NULL, 'm'},
{0, 0, 0, 0}
};
while (true) {
- int c = getopt_long(argc, argv, "tbpsvhl:i:o:nr", long_options,
+ int c = getopt_long(argc, argv, "tcbpsgvhml:i:o:nr", long_options,
&option_index);
if (c == -1)
break;
@@ -90,11 +113,15 @@ std::shared_ptr<Options> Options::Parse(int argc, char** argv) {
break;
case 'p':
- cmd[CMD_PROXY] = 1;
+ options->type_ = TYPE_PROXY;
break;
case 's':
- cmd[CMD_STUB] = 1;
+ options->type_ = TYPE_STUB;
+ break;
+
+ case 'g':
+ options->type_ = TYPE_GROUP;
break;
case 'v':
@@ -114,8 +141,7 @@ std::shared_ptr<Options> Options::Parse(int argc, char** argv) {
break;
case 'l':
- opt[OPT_LANGUAGE] = 1;
- options->language_ = optarg;
+ options->language_ = ConvertStr2LanguageType(optarg);
break;
case 'i':
@@ -136,6 +162,14 @@ std::shared_ptr<Options> Options::Parse(int argc, char** argv) {
options->isThreadEnabled_ = true;
break;
+ case 'c':
+ options->isCion_ = true;
+ break;
+
+ case 'm':
+ options->isMqtt_ = true;
+ break;
+
default:
cmd[CMD_HELP] = 1;
}
@@ -151,16 +185,37 @@ std::shared_ptr<Options> Options::Parse(int argc, char** argv) {
return std::shared_ptr<Options>(nullptr);
}
- if (!cmd[CMD_PROXY] && !cmd[CMD_STUB]) {
- std::cerr << "Stub or proxy must be specified." << std::endl;
+ if (options->isCion_ && options->isMqtt_) {
+ std::cerr << "Only one of cion and mqtt is allowed." << std::endl;
+ return std::shared_ptr<Options>(nullptr);
+ }
+ switch (static_cast<int>(options->type_)) {
+ case TYPE_UNKNOWN:
+ std::cerr <<
+ "Stub or proxy or group must be specified." << std::endl;
options->PrintSample();
return std::shared_ptr<Options>(nullptr);
+ default:
+ break;
}
- if (!opt[OPT_LANGUAGE]) {
- std::cerr << "Select a language (C, C++, C#).." << std::endl;
+ switch (static_cast<int>(options->language_)) {
+ case LANGUAGE_TYPE_UNKNOWN:
+ std::cerr <<
+ "Select a language (C, C++, C#, Java(CION & MQTT only)).." << std::endl;
options->PrintSample();
return std::shared_ptr<Options>(nullptr);
+ case LANGUAGE_TYPE_JAVA:
+ if (!options->isCion_ && !options->isMqtt_) {
+ std::cerr <<
+ "Java language is only allowed for the CION and "
+ "MQTT codes." << std::endl;
+ options->PrintSample();
+ return std::shared_ptr<Options>(nullptr);
+ }
+ break;
+ default:
+ break;
}
if (!opt[OPT_INPUT]) {
@@ -183,7 +238,6 @@ std::shared_ptr<Options> Options::Parse(int argc, char** argv) {
return std::shared_ptr<Options>(nullptr);
}
- options->isProxy_ = cmd[CMD_PROXY] ? true : false;
options->hasNamespace_ = opt[OPT_NAMESPACE] ? true : false;
options->hasRpcPortLib_ = opt[OPT_RPCLIB] ? true : false;
diff --git a/idlc/options.h b/idlc/options.h
index d0d2536..1478f25 100644
--- a/idlc/options.h
+++ b/idlc/options.h
@@ -24,14 +24,32 @@
namespace tidl {
class Options {
public:
+ enum Type {
+ TYPE_UNKNOWN = 0,
+ TYPE_PROXY,
+ TYPE_STUB,
+ TYPE_GROUP
+ };
+
+ enum LanguageType {
+ LANGUAGE_TYPE_UNKNOWN = 0,
+ LANGUAGE_TYPE_C,
+ LANGUAGE_TYPE_CPP,
+ LANGUAGE_TYPE_CSHARP,
+ LANGUAGE_TYPE_JAVA,
+ LANGUAGE_TYPE_DART
+ };
+
Options();
~Options() = default;
static std::shared_ptr<Options> Parse(int argc, char** argv);
- bool IsProxy() const { return isProxy_; }
+ bool IsCion() const { return isCion_; }
+ bool IsMqtt() const { return isMqtt_; }
+ Type GetType() const { return type_; }
bool IsBetaEnabled() const { return isBetaEnabled_; }
bool IsThreadEnabled() const { return isThreadEnabled_; }
- std::string GetLanguage() const { return language_; }
+ LanguageType GetLanguage() const { return language_; }
std::string GetInput() const { return input_; }
std::string GetOutput() const { return output_; }
bool HasNamespace() const { return hasNamespace_; }
@@ -39,15 +57,12 @@ class Options {
private:
enum Cmd {
- CMD_PROXY,
- CMD_STUB,
CMD_VERSION,
CMD_HELP,
CMD_MAX
};
enum Opt {
- OPT_LANGUAGE,
OPT_INPUT,
OPT_OUTPUT,
OPT_NAMESPACE,
@@ -60,8 +75,9 @@ class Options {
void PrintSample();
private:
- bool isProxy_ = false;
- std::string language_;
+ bool isCion_ = false;
+ bool isMqtt_ = false;
+ LanguageType language_;
std::string input_;
std::string output_;
std::string help_;
@@ -69,6 +85,7 @@ class Options {
bool hasRpcPortLib_ = false;
bool isBetaEnabled_ = false;
bool isThreadEnabled_ = false;
+ Type type_;
};
} // namespace tidl
diff --git a/idlc/version2_default_generator.cc b/idlc/version2_default_generator.cc
new file mode 100644
index 0000000..2c52c58
--- /dev/null
+++ b/idlc/version2_default_generator.cc
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/version2_default_generator.hh"
+
+#include <utility>
+
+#include "idlc/ast/parser.h"
+#include "idlc/gen/version2/c_group_body_generator.hh"
+#include "idlc/gen/version2/c_group_header_generator.hh"
+#include "idlc/gen/version2/c_proxy_body_generator.hh"
+#include "idlc/gen/version2/c_proxy_header_generator.hh"
+#include "idlc/gen/version2/c_stub_body_generator.hh"
+#include "idlc/gen/version2/c_stub_header_generator.hh"
+#include "idlc/gen/version2/cpp_group_body_generator.hh"
+#include "idlc/gen/version2/cpp_group_header_generator.hh"
+#include "idlc/gen/version2/cpp_proxy_body_generator.hh"
+#include "idlc/gen/version2/cpp_proxy_header_generator.hh"
+#include "idlc/gen/version2/cpp_stub_body_generator.hh"
+#include "idlc/gen/version2/cpp_stub_header_generator.hh"
+#include "idlc/gen/version2/cs_group_generator.h"
+#include "idlc/gen/version2/cs_proxy_generator.h"
+#include "idlc/gen/version2/cs_stub_generator.h"
+#include "idlc/options.h"
+
+namespace tidl {
+namespace version2 {
+
+DefaultGenerator::DefaultGenerator() {
+ funcs_ = {
+ // Stub
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_C),
+ std::bind(&DefaultGenerator::GenCStubCode, this, std::placeholders::_1,
+ std::placeholders::_2)},
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_CPP),
+ std::bind(&DefaultGenerator::GenCppStubCode, this, std::placeholders::_1,
+ std::placeholders::_2)},
+ {std::make_pair(Options::Type::TYPE_STUB, Options::LANGUAGE_TYPE_CSHARP),
+ std::bind(&DefaultGenerator::GenCsharpStubCode, this,
+ std::placeholders::_1, std::placeholders::_2)},
+
+ // Proxy
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_C),
+ std::bind(&DefaultGenerator::GenCProxyCode, this, std::placeholders::_1,
+ std::placeholders::_2)},
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_CPP),
+ std::bind(&DefaultGenerator::GenCppProxyCode, this,
+ std::placeholders::_1, std::placeholders::_2)},
+ {std::make_pair(Options::Type::TYPE_PROXY, Options::LANGUAGE_TYPE_CSHARP),
+ std::bind(&DefaultGenerator::GenCsharpProxyCode, this,
+ std::placeholders::_1, std::placeholders::_2)},
+
+ // Group
+ {std::make_pair(Options::Type::TYPE_GROUP, Options::LANGUAGE_TYPE_C),
+ std::bind(&DefaultGenerator::GenCGroupCode, this, std::placeholders::_1,
+ std::placeholders::_2)},
+ {std::make_pair(Options::Type::TYPE_GROUP, Options::LANGUAGE_TYPE_CPP),
+ std::bind(&DefaultGenerator::GenCppGroupCode, this,
+ std::placeholders::_1, std::placeholders::_2)},
+ {std::make_pair(Options::Type::TYPE_GROUP, Options::LANGUAGE_TYPE_CSHARP),
+ std::bind(&DefaultGenerator::GenCsharpGroupCode, this,
+ std::placeholders::_1, std::placeholders::_2)},
+ };
+}
+
+void DefaultGenerator::Generate(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ auto found = funcs_.find(
+ std::make_pair(options->GetType(), options->GetLanguage()));
+ if (found == funcs_.end()) return;
+
+ auto& func = found->second;
+ func(std::move(options), ps);
+}
+
+void DefaultGenerator::GenCStubCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CStubHeaderGenerator stub_header(ps.GetDoc());
+ stub_header.EnableNamespace(options->HasNamespace());
+ stub_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ stub_header.EnableProxy(false);
+ stub_header.Run(options->GetOutput() + ".h");
+
+ CStubBodyGenerator stub_body(ps.GetDoc(), options);
+ stub_body.EnableNamespace(options->HasNamespace());
+ stub_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ stub_body.EnableProxy(false);
+ stub_body.Run(options->GetOutput() + ".c");
+}
+
+void DefaultGenerator::GenCppStubCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CppStubHeaderGenerator stub_header(ps.GetDoc(), options);
+ stub_header.Run(options->GetOutput() + ".h");
+
+ CppStubBodyGenerator stub_body(ps.GetDoc(), options);
+ stub_body.Run(options->GetOutput() + ".cc");
+}
+
+void DefaultGenerator::GenCsharpStubCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CsStubGen stub(ps.GetDoc());
+ stub.Run(options->GetOutput() + ".cs");
+}
+
+void DefaultGenerator::GenCProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CProxyHeaderGenerator proxy_header(ps.GetDoc());
+ proxy_header.EnableNamespace(options->HasNamespace());
+ proxy_header.EnableProxy(true);
+ proxy_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ proxy_header.Run(options->GetOutput() + ".h");
+
+ CProxyBodyGenerator proxy_body(ps.GetDoc(), options);
+ proxy_body.EnableNamespace(options->HasNamespace());
+ proxy_body.EnableProxy(true);
+ proxy_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ proxy_body.Run(options->GetOutput() + ".c");
+}
+
+void DefaultGenerator::GenCppProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CppProxyHeaderGenerator proxy_header(ps.GetDoc(), options);
+ proxy_header.Run(options->GetOutput() + ".h");
+
+ CppProxyBodyGenerator proxy_body(ps.GetDoc(), options);
+ proxy_body.Run(options->GetOutput() + ".cc");
+}
+
+void DefaultGenerator::GenCsharpProxyCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CsProxyGen proxy(ps.GetDoc());
+ proxy.Run(options->GetOutput() + ".cs");
+}
+
+void DefaultGenerator::GenCGroupCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CGroupHeaderGenerator group_header(ps.GetDoc());
+ group_header.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ group_header.Run(options->GetOutput() + ".h");
+
+ CGroupBodyGenerator group_body(ps.GetDoc());
+ group_body.SetChannelType(
+ static_cast<Generator::ChannelType>(options->GetType()));
+ group_body.Run(options->GetOutput() + ".c");
+}
+
+void DefaultGenerator::GenCppGroupCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CppGroupHeaderGenerator group_header(ps.GetDoc());
+ group_header.Run(options->GetOutput() + ".h");
+
+ CppGroupBodyGenerator group_body(ps.GetDoc());
+ group_body.Run(options->GetOutput() + ".cc");
+}
+
+void DefaultGenerator::GenCsharpGroupCode(std::shared_ptr<Options> options,
+ const Parser& ps) {
+ CsGroupGen group(ps.GetDoc());
+ group.Run(options->GetOutput() + ".cs");
+}
+
+} // namespace version2
+} // namespace tidl
diff --git a/idlc/version2_default_generator.hh b/idlc/version2_default_generator.hh
new file mode 100644
index 0000000..44d5d63
--- /dev/null
+++ b/idlc/version2_default_generator.hh
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_VERSION2_DEFAULT_GENERATOR_HH_
+#define IDLC_VERSION2_DEFAULT_GENERATOR_HH_
+
+#include <functional>
+#include <memory>
+#include <unordered_map>
+
+#include "idlc/code_generator.hh"
+
+namespace tidl {
+namespace version2 {
+
+class DefaultGenerator : public CodeGenerator {
+ public:
+ DefaultGenerator();
+ virtual ~DefaultGenerator() = default;
+
+ void Generate(std::shared_ptr<Options> options, const Parser& ps) override;
+
+ private:
+ using GeneratorFunc =
+ std::function<void(std::shared_ptr<Options>, const Parser&)>;
+
+ /// Stub
+ void GenCStubCode(std::shared_ptr<Options> options, const Parser& ps);
+ void GenCppStubCode(std::shared_ptr<Options> options, const Parser& ps);
+ void GenCsharpStubCode(std::shared_ptr<Options> options, const Parser& ps);
+
+ /// Proxy
+ void GenCProxyCode(std::shared_ptr<Options> options, const Parser& ps);
+ void GenCppProxyCode(std::shared_ptr<Options> options, const Parser& ps);
+ void GenCsharpProxyCode(std::shared_ptr<Options> options, const Parser& ps);
+
+ /// Group
+ void GenCGroupCode(std::shared_ptr<Options> options, const Parser& ps);
+ void GenCppGroupCode(std::shared_ptr<Options> options, const Parser& ps);
+ void GenCsharpGroupCode(std::shared_ptr<Options> options, const Parser& ps);
+
+ private:
+ std::unordered_map<GeneratorCond, GeneratorFunc, PairHash> funcs_;
+};
+
+} // namespace version2
+} // namespace tidl
+
+#endif // IDLC_VERSION2_DEFAULT_GENERATOR_HH_
diff --git a/package/build.linux b/package/build.linux
index b6f2c36..169726d 100755
--- a/package/build.linux
+++ b/package/build.linux
@@ -1,4 +1,7 @@
#!/bin/bash
+
+VERSION=9.0
+
# clean
clean()
{
@@ -31,8 +34,8 @@ install()
then
INSTALL_DIR=${SRCDIR}/package/${package_name}.package.${platform}
- mkdir -p ${INSTALL_DIR}/data/platforms/tizen-6.5/common/tidl
- cp ${SRCDIR}/build/idlc/tidlc ${INSTALL_DIR}/data/platforms/tizen-6.5/common/tidl/
+ mkdir -p ${INSTALL_DIR}/data/platforms/tizen-${VERSION}/common/tidl
+ cp ${SRCDIR}/build/idlc/tidlc ${INSTALL_DIR}/data/platforms/tizen-${VERSION}/common/tidl/
fi
done
}
diff --git a/package/build.macos b/package/build.macos
index f2223d6..7df6564 100755
--- a/package/build.macos
+++ b/package/build.macos
@@ -1,4 +1,7 @@
#!/bin/bash
+
+VERSION=9.0
+
# clean
clean()
{
@@ -19,9 +22,9 @@ install()
{
echo "TARGET_OS: ${TARGET_OS}"
echo "=========================================INSTALL============================================"
- INSTALL_DIR=${SRCDIR}/package/6.5-tidlc.package.macos-64
- mkdir -p ${INSTALL_DIR}/data/platforms/tizen-6.5/common/tidl
- cp ${SRCDIR}/build/idlc/tidlc ${INSTALL_DIR}/data/platforms/tizen-6.5/common/tidl/
+ INSTALL_DIR=${SRCDIR}/package/${VERSION}-tidlc.package.macos-64
+ mkdir -p ${INSTALL_DIR}/data/platforms/tizen-${VERSION}/common/tidl
+ cp ${SRCDIR}/build/idlc/tidlc ${INSTALL_DIR}/data/platforms/tizen-${VERSION}/common/tidl/
}
[ "$1" = "clean" ] && clean
diff --git a/package/build.windows b/package/build.windows
index fa98e72..5e5eb50 100644
--- a/package/build.windows
+++ b/package/build.windows
@@ -1,4 +1,7 @@
#!/bin/bash
+
+VERSION=9.0
+
# clean
clean()
{
@@ -19,9 +22,9 @@ install()
{
echo "TARGET_OS: ${TARGET_OS}"
echo "=========================================INSTALL============================================"
- INSTALL_DIR=${SRCDIR}/package/6.5-tidlc.package.${TARGET_OS}
- mkdir -p ${INSTALL_DIR}/data/platforms/tizen-6.5/common/tidl
- cp ${SRCDIR}/release/${TARGET_OS}/tidlc.exe ${INSTALL_DIR}/data/platforms/tizen-6.5/common/tidl/
+ INSTALL_DIR=${SRCDIR}/package/${VERSION}-tidlc.package.${TARGET_OS}
+ mkdir -p ${INSTALL_DIR}/data/platforms/tizen-${VERSION}/common/tidl
+ cp ${SRCDIR}/release/${TARGET_OS}/tidlc.exe ${INSTALL_DIR}/data/platforms/tizen-${VERSION}/common/tidl/
}
[ "$1" = "clean" ] && clean
diff --git a/package/pkginfo.manifest b/package/pkginfo.manifest
index fdee1ad..9b7f2dd 100644
--- a/package/pkginfo.manifest
+++ b/package/pkginfo.manifest
@@ -1,28 +1,28 @@
-Version:1.4.5
+Version:2.0.7
Source:tidlc
Maintainer:JungHoon Park <jh9216.park@samsung.com>, Hwankyu Jhun <h.jhun@samsung.com>, Inkyun Kil <inkyun.kil@samsung.com>, Ju-Sung Son <jusung07.son@samsung.com>, Hyunho Kang <hhstark.kang@samsung.com>
-Package:6.5-tidlc
+Package:9.0-tidlc
OS:ubuntu-32
Build-host-os:ubuntu-32
Description:Compiler for making stub or proxy code block from TIDL file
-Package:6.5-tidlc
+Package:9.0-tidlc
OS:windows-32
Build-host-os:windows-32
Description:Compiler for making stub or proxy code block from TIDL file
-Package:6.5-tidlc
+Package:9.0-tidlc
OS:ubuntu-64
Build-host-os:ubuntu-64
Description:Compiler for making stub or proxy code block from TIDL file
-Package:6.5-tidlc
+Package:9.0-tidlc
OS:windows-64
Build-host-os:windows-64
Description:Compiler for making stub or proxy code block from TIDL file
-Package:6.5-tidlc
+Package:9.0-tidlc
OS:macos-64
Build-host-os:macos-64
Description:Compiler for making stub or proxy code block from TIDL file
diff --git a/package/tidlc.install.linux b/package/tidlc.install.linux
index ebff926..967b49d 100755
--- a/package/tidlc.install.linux
+++ b/package/tidlc.install.linux
@@ -6,7 +6,7 @@ if [ "x${s}" = "x" ] ; then
cat >> ${HOME}/.bashrc << END
## Tizen SDK configuration
# This is generated by Tizen SDK. Please do not modify by yourself.
-export PATH=\$PATH:${INSTALLED_PATH}/platforms/tizen-6.5/common/tidl
+export PATH=\$PATH:${INSTALLED_PATH}/platforms/tizen-9.0/common/tidl
## End Tizen SDK configuration
END
fi
diff --git a/package/tidlc.install.macos b/package/tidlc.install.macos
index 0c35719..4735f2f 100755
--- a/package/tidlc.install.macos
+++ b/package/tidlc.install.macos
@@ -6,7 +6,7 @@ if [ "x${s}" = "x" ] ; then
cat >> ${HOME}/.bashrc << END
## Tizen SDK configuration
# This is generated by Tizen SDK. Please do not modify by yourself.
-export PATH=\$PATH:${INSTALLED_PATH}/platforms/tizen-6.5/common/tidl
+export PATH=\$PATH:${INSTALLED_PATH}/platforms/tizen-9.0/common/tidl
## End Tizen SDK configuration
END
fi
diff --git a/package/tidlc.install.windows b/package/tidlc.install.windows
index c647121..3c68553 100644
--- a/package/tidlc.install.windows
+++ b/package/tidlc.install.windows
@@ -1,6 +1,6 @@
@echo off
-set TIDL_PATH=%INSTALLED_PATH%\platforms\tizen-6.5\common\tidl
+set TIDL_PATH=%INSTALLED_PATH%\platforms\tizen-9.0\common\tidl
echo adding tidl path...
setx -m PATH "%path%;%TIDL_PATH%"
diff --git a/package/tidlc.remove.windows b/package/tidlc.remove.windows
index 066925d..9b45dc2 100644
--- a/package/tidlc.remove.windows
+++ b/package/tidlc.remove.windows
@@ -1,6 +1,6 @@
@echo off
-set TIDL_PATH=%INSTALLED_PATH%\platforms\tizen-6.5\common\tidl
+set TIDL_PATH=%INSTALLED_PATH%\platforms\tizen-9.0\common\tidl
del %TIDL_PATH%\tidlc.exe
echo removing tidl path...
diff --git a/packaging/tidl.spec b/packaging/tidl.spec
index a283444..76a6507 100644
--- a/packaging/tidl.spec
+++ b/packaging/tidl.spec
@@ -1,6 +1,6 @@
Name: tidl
Summary: Tizen Interface Definition Language
-Version: 1.4.5
+Version: 2.0.7
Release: 1
Group: Application Framework/Building
License: Apache-2.0
@@ -15,7 +15,7 @@ BuildRequires: cmake
BuildRequires: flex
BuildRequires: bison
BuildRequires: gtest-devel
-BuildRequires: pkgconfig(glib-2.0)
+
%if 0%{?gcov:1}
BuildRequires: lcov
%endif
@@ -50,10 +50,10 @@ MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
%__make %{?_smp_mflags}
%check
-ctest --output-on-failure %{?_smp_mflags}
+ctest -V %{?_smp_mflags}
%if 0%{?gcov:1}
-lcov -c --ignore-errors graph --no-external -q -d . -o gcov.info
-genhtml gcov.info
+lcov -c --ignore-errors mismatch,graph,unused --no-external -b . -d . -o %{name}.info
+genhtml %{name}.info -o out --legend --show-details
%endif
%install
diff --git a/release/windows-32/tidlc.exe b/release/windows-32/tidlc.exe
index 0054de9..93f8c5f 100755
--- a/release/windows-32/tidlc.exe
+++ b/release/windows-32/tidlc.exe
Binary files differ
diff --git a/release/windows-64/tidlc.exe b/release/windows-64/tidlc.exe
index 8d40a8a..2f01881 100755
--- a/release/windows-64/tidlc.exe
+++ b/release/windows-64/tidlc.exe
Binary files differ
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 0000000..c6c2ffa
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,4 @@
+IF(NOT DEFINED MINIMUM_BUILD)
+ADD_SUBDIRECTORY(unit_tests)
+ADD_DEPENDENCIES(${TIDL_UNIT_TESTS} ${PROJECT_NAME})
+ENDIF(NOT DEFINED MINIMUM_BUILD)
diff --git a/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt
index 96849aa..c5ff08d 100644
--- a/unit_tests/CMakeLists.txt
+++ b/tests/unit_tests/CMakeLists.txt
@@ -6,7 +6,7 @@ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wno-unused-function -Wno-sign-compare")
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIE")
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++11")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++17")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}")
FIND_PACKAGE(GTest REQUIRED)
@@ -14,27 +14,31 @@ INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS})
LINK_DIRECTORIES(${GTEST_LIBRARY_DIRS})
SET(TIDLC_SOURCES
- ${CMAKE_SOURCE_DIR}/idlc/ast/document.cc
- ${CMAKE_SOURCE_DIR}/idlc/ast/declaration.cc
- ${CMAKE_SOURCE_DIR}/idlc/ast/interface.cc
- ${CMAKE_SOURCE_DIR}/idlc/ast/type.cc
- ${CMAKE_SOURCE_DIR}/idlc/ast/parameter.cc
- ${CMAKE_SOURCE_DIR}/idlc/ast/element.cc
- ${CMAKE_SOURCE_DIR}/idlc/ast/structure.cc
- ${CMAKE_SOURCE_DIR}/idlc/ast/block.cc
- ${CMAKE_SOURCE_DIR}/idlc/gen/generator.cc
- ${CMAKE_SOURCE_DIR}/idlc/ast/parser.cc
- ${CMAKE_SOURCE_DIR}/idlc/ast/attribute.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/document.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/declaration.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/interface.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/type.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/parameter.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/element.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/structure.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/block.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/gen/generator.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/parser.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/attribute.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/enum.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/preprocessor.cc
)
ADD_DEFINITIONS("-DFULLVER=\"${FULLVER}\"")
AUX_SOURCE_DIRECTORY(. UNIT_TESTS_SOURCES)
AUX_SOURCE_DIRECTORY(cs_gen CS_GEN_UNIT_TESTS_SOURCES)
-AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/idlc/gen CS_GEN_SOURCES)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/gen CS_GEN_SOURCES)
-FLEX_TARGET(TIDLC ${CMAKE_SOURCE_DIR}/idlc/ast/tidlc.ll ${CMAKE_SOURCE_DIR}/idlc/ast/tidlc_l.cpp)
-BISON_TARGET(TIDLC ${CMAKE_SOURCE_DIR}/idlc/ast/tidlc.yy ${CMAKE_SOURCE_DIR}/idlc/ast/tidlc_y.cpp)
+FLEX_TARGET(TIDLC ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/tidlc.ll
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/tidlc_l.cpp)
+BISON_TARGET(TIDLC ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/tidlc.yy
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../idlc/ast/tidlc_y.cpp)
ADD_EXECUTABLE(${TIDL_UNIT_TESTS}
${BISON_TIDLC_OUTPUTS}
diff --git a/unit_tests/attribute_unittest.cc b/tests/unit_tests/attribute_unittest.cc
index e001f4c..3274e6b 100644
--- a/unit_tests/attribute_unittest.cc
+++ b/tests/unit_tests/attribute_unittest.cc
@@ -47,7 +47,7 @@ TEST_F(AttributeTest, Attribute_GetValue) {
}
TEST_F(AttributeTest, Attribute_GetLine) {
- unsigned line = __LINE__;
+ unsigned int line = __LINE__;
tidl::Attribute* attr = new tidl::Attribute("key", "value", line);
EXPECT_NE(attr, nullptr);
EXPECT_EQ(attr->GetLine(), line);
@@ -67,28 +67,28 @@ TEST_F(AttributesTest, Attributes_Constructor) {
}
TEST_F(AttributesTest, Attributes_Add) {
- tidl::Attributes* attrs = new tidl::Attributes();
- EXPECT_NE(attrs, nullptr);
- attrs->Add(new tidl::Attribute("key", "value", __LINE__));
+ tidl::Attributes attrs;
+ attrs.Add(std::unique_ptr<tidl::Attribute>(new tidl::Attribute(
+ "key", "value", __LINE__)));
bool flag = false;
- for (auto& attr : attrs->GetAttrs()) {
+ for (const auto& attr : attrs) {
if (attr->GetKey() == "key" &&
attr->GetValue() == "value")
flag = true;
}
EXPECT_EQ(flag, true);
- delete attrs;
}
-TEST_F(AttributesTest, Attributes_GetAttrs) {
- tidl::Attributes* attrs = new tidl::Attributes();
- EXPECT_NE(attrs, nullptr);
- attrs->Add(new tidl::Attribute("key1", "value1", __LINE__));
- attrs->Add(new tidl::Attribute("key2", "value2", __LINE__));
+TEST_F(AttributesTest, Attributes_range_for) {
+ tidl::Attributes attrs;
+ attrs.Add(std::unique_ptr<tidl::Attribute>(new tidl::Attribute(
+ "key1", "value1", __LINE__)));
+ attrs.Add(std::unique_ptr<tidl::Attribute>(new tidl::Attribute(
+ "key2", "value2", __LINE__)));
int count = 0;
- for (auto& attr : attrs->GetAttrs()) {
+ for (const auto& attr : attrs) {
if (attr->GetKey() == "key1" &&
attr->GetValue() == "value1")
count++;
@@ -97,16 +97,12 @@ TEST_F(AttributesTest, Attributes_GetAttrs) {
count++;
}
EXPECT_EQ(count, 2);
- delete attrs;
}
TEST_F(AttributesTest, Attributes_Exist) {
- tidl::Attributes* attrs = new tidl::Attributes();
- EXPECT_NE(attrs, nullptr);
- attrs->Add(new tidl::Attribute("key", "value", __LINE__));
- tidl::Attribute* attr = new tidl::Attribute("key", "value", __LINE__);
- EXPECT_NE(attr, nullptr);
- EXPECT_EQ(attrs->Exist(attr), true);
- delete attr;
- delete attrs;
+ tidl::Attributes attrs;
+ attrs.Add(std::unique_ptr<tidl::Attribute>(new tidl::Attribute(
+ "key", "value", __LINE__)));
+ tidl::Attribute attr("key", "value", __LINE__);
+ EXPECT_EQ(attrs.Exist(attr), true);
}
diff --git a/unit_tests/block_unittest.cc b/tests/unit_tests/block_unittest.cc
index 0659344..1362047 100644
--- a/unit_tests/block_unittest.cc
+++ b/tests/unit_tests/block_unittest.cc
@@ -26,7 +26,7 @@ class BlockTest : public testing::Test {
virtual void SetUp() {
testBlock = new tidl::Block("TestBlock", tidl::Block::TYPE_INTERFACE,
- "", 28);
+ new tidl::Enums(), "", 28);
}
virtual void TearDown() {
delete testBlock;
@@ -35,7 +35,7 @@ class BlockTest : public testing::Test {
TEST_F(BlockTest, Block_Constructor) {
tidl::Block* block = new tidl::Block("StructureBlock",
- tidl::Block::TYPE_STRUCTURE, "", __LINE__);
+ tidl::Block::TYPE_STRUCTURE, new tidl::Enums(), "", __LINE__);
EXPECT_NE(block, nullptr);
delete block;
}
@@ -55,7 +55,7 @@ TEST_F(BlockTest, Block_GetLine) {
TEST_F(BlockTest, Block_GetComments) {
std::string comments = "Test Block";
tidl::Block* block = new tidl::Block("StructureBlock",
- tidl::Block::TYPE_STRUCTURE, comments, __LINE__);
+ tidl::Block::TYPE_STRUCTURE, new tidl::Enums(), comments, __LINE__);
EXPECT_NE(block, nullptr);
EXPECT_EQ(block->GetComments(), comments);
delete block;
diff --git a/unit_tests/cs_gen/cs_proxy_gen_unittest.cc b/tests/unit_tests/cs_gen/cs_proxy_gen_unittest.cc
index fd247cf..fd247cf 100644
--- a/unit_tests/cs_gen/cs_proxy_gen_unittest.cc
+++ b/tests/unit_tests/cs_gen/cs_proxy_gen_unittest.cc
diff --git a/unit_tests/cs_gen/cs_stub_gen_unittest.cc b/tests/unit_tests/cs_gen/cs_stub_gen_unittest.cc
index 512c6de..512c6de 100644
--- a/unit_tests/cs_gen/cs_stub_gen_unittest.cc
+++ b/tests/unit_tests/cs_gen/cs_stub_gen_unittest.cc
diff --git a/tests/unit_tests/declaration_unittest.cc b/tests/unit_tests/declaration_unittest.cc
new file mode 100644
index 0000000..1dbb67e
--- /dev/null
+++ b/tests/unit_tests/declaration_unittest.cc
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <iostream>
+
+#include "idlc/ast/declaration.h"
+#include "idlc/ast/type.h"
+#include "idlc/ast/parameter.h"
+
+class DeclarationTest : public testing::Test {
+ public:
+ std::unique_ptr<tidl::Parameters> params;
+
+ virtual void SetUp() {
+ params = std::unique_ptr<tidl::Parameters>(new tidl::Parameters());
+ EXPECT_NE(params, nullptr);
+ params->Add(std::unique_ptr<tidl::Parameter>(new tidl::Parameter("test1",
+ new tidl::ParameterType(new tidl::BaseType("int", "")), __LINE__)));
+ params->Add(std::unique_ptr<tidl::Parameter>(new tidl::Parameter("test2",
+ new tidl::ParameterType(new tidl::BaseType("int", "")), __LINE__)));
+ }
+ virtual void TearDown() {}
+};
+
+TEST_F(DeclarationTest, Declaration_Constructor) {
+ tidl::Declaration decl("test",
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("int", "")),
+ std::move(params), "", __LINE__);
+}
+
+TEST_F(DeclarationTest, Declaration_GetID) {
+ tidl::Declaration decl("test",
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("int", "")),
+ std::move(params), "", __LINE__);
+ EXPECT_EQ(decl.GetID(), "test");
+}
+
+TEST_F(DeclarationTest, Declaration_GetType) {
+ tidl::Declaration decl("test",
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("int", "")),
+ std::move(params), "", __LINE__);
+ EXPECT_EQ(decl.GetType().ToString(), "int");
+}
+
+TEST_F(DeclarationTest, Declaration_GetParameters) {
+ tidl::Declaration decl("test",
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("int", "")),
+ std::move(params), "", __LINE__);
+
+ int count = 0;
+ for (const auto& param : decl.GetParameters()) {
+ if (param->GetID() == "test1" &&
+ param->GetParameterType().GetBaseType().ToString() == "int")
+ count++;
+ if (param->GetID() == "test2" &&
+ param->GetParameterType().GetBaseType().ToString() == "int")
+ count++;
+ }
+ EXPECT_EQ(count, 2);
+}
+
+TEST_F(DeclarationTest, Declaration_GetMethodType) {
+ tidl::Declaration decl("test",
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("int", "")),
+ std::move(params), "", __LINE__,
+ tidl::Declaration::MethodType::DELEGATE);
+ EXPECT_EQ(decl.GetMethodType(), tidl::Declaration::MethodType::DELEGATE);
+}
+
+TEST_F(DeclarationTest, Declaration_GetComments) {
+ std::string comments = "Test Declaration";
+ tidl::Declaration decl("test",
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("int", "")),
+ std::move(params), comments, __LINE__);
+ EXPECT_EQ(decl.GetComments(), comments);
+}
+
+TEST_F(DeclarationTest, Declaration_GetLine) {
+ unsigned int line = __LINE__;
+ tidl::Declaration decl("test",
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("int", "")),
+ std::move(params), "", line);
+ EXPECT_EQ(decl.GetLine(), line);
+}
+
+class DeclarationsTest : public testing::Test {
+ public:
+ virtual void SetUp() {}
+ virtual void TestDown() {}
+ std::unique_ptr<tidl::Declaration> PrepareDeclaration() {
+ tidl::Parameters* params = new tidl::Parameters();
+ EXPECT_NE(params, nullptr);
+ params->Add(std::unique_ptr<tidl::Parameter>(new tidl::Parameter("test1",
+ new tidl::ParameterType(new tidl::BaseType("int", "")), __LINE__)));
+ params->Add(std::unique_ptr<tidl::Parameter>(new tidl::Parameter("test2",
+ new tidl::ParameterType(new tidl::BaseType("int", "")), __LINE__)));
+ auto decl = std::unique_ptr<tidl::Declaration>(new tidl::Declaration(
+ "test",
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("int", "")),
+ std::unique_ptr<tidl::Parameters>(params), "", __LINE__));
+ EXPECT_NE(decl, nullptr);
+ return decl;
+ }
+};
+
+TEST_F(DeclarationsTest, Declarations_Constructor) {
+ tidl::Declarations decls;
+}
+
+TEST_F(DeclarationsTest, Declarations_Add) {
+ tidl::Declarations decls;
+ decls.Add(PrepareDeclaration());
+
+ bool flag = false;
+ for (const auto& d : decls) {
+ if (d->GetID() == "test")
+ flag = true;
+ }
+ EXPECT_EQ(flag, true);
+}
+
+TEST_F(DeclarationsTest, Declarations_range_for) {
+ tidl::Declarations decls;
+ decls.Add(PrepareDeclaration());
+
+ bool flag = false;
+ for (auto& d : decls) {
+ if (d->GetID() == "test")
+ flag = true;
+ }
+ EXPECT_EQ(flag, true);
+}
+
+TEST_F(DeclarationsTest, Declarations_Exist) {
+ tidl::Declarations decls;
+ decls.Add(PrepareDeclaration());
+ tidl::Parameters* testParams = new tidl::Parameters();
+ EXPECT_NE(testParams, nullptr);
+ testParams->Add(std::unique_ptr<tidl::Parameter>(new tidl::Parameter("test1",
+ new tidl::ParameterType(new tidl::BaseType("int", "")), __LINE__)));
+ tidl::Declaration testDecl("test",
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("int", "")),
+ std::unique_ptr<tidl::Parameters>(testParams), "", __LINE__);
+ EXPECT_EQ(decls.Exist(testDecl), true);
+}
diff --git a/unit_tests/document_unittest.cc b/tests/unit_tests/document_unittest.cc
index 31e6c1b..e223bc9 100644
--- a/unit_tests/document_unittest.cc
+++ b/tests/unit_tests/document_unittest.cc
@@ -29,7 +29,7 @@ class DocumentTest : public testing::Test {
virtual void SetUp() {
document = new tidl::Document();
block = new tidl::Block("TestBlock", tidl::Block::TYPE_INTERFACE,
- "", __LINE__);
+ new tidl::Enums(), "", __LINE__);
}
virtual void TearDown() {
}
@@ -64,7 +64,7 @@ TEST_F(DocumentTest, Document_GetBlocks) {
TEST_F(DocumentTest, Document_ExistBlock) {
document->AddBlock(block);
tidl::Block* testBlock = new tidl::Block("TestBlock",
- tidl::Block::TYPE_INTERFACE, "", __LINE__);
+ tidl::Block::TYPE_INTERFACE, new tidl::Enums(), "", __LINE__);
EXPECT_NE(testBlock, nullptr);
EXPECT_EQ(document->ExistBlock(testBlock), true);
delete testBlock;
diff --git a/tests/unit_tests/element_unittest.cc b/tests/unit_tests/element_unittest.cc
new file mode 100644
index 0000000..d001c47
--- /dev/null
+++ b/tests/unit_tests/element_unittest.cc
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <iostream>
+
+#include "idlc/ast/element.h"
+
+class ElementTest : public testing::Test {
+ public:
+ virtual void SetUp() {}
+ virtual void TearDown() {}
+};
+
+TEST_F(ElementTest, Element_Contstructor) {
+ tidl::Element elm("test", new tidl::BaseType("int", ""), "", __LINE__);
+}
+
+TEST_F(ElementTest, Element_GetID) {
+ tidl::Element elm("test", new tidl::BaseType("int", ""), "", __LINE__);
+ EXPECT_EQ(elm.GetID(), "test");
+}
+
+TEST_F(ElementTest, Element_GetType) {
+ tidl::Element elm("test", new tidl::BaseType("int", ""), "", __LINE__);
+ EXPECT_EQ(elm.GetType().ToString(), "int");
+}
+
+TEST_F(ElementTest, Element_GetLine) {
+ unsigned int line = __LINE__;
+ tidl::Element elm("test", new tidl::BaseType("int", ""), "", line);
+ EXPECT_EQ(elm.GetLine(), line);
+}
+
+TEST_F(ElementTest, Element_GetComments) {
+ std::string comments = "Test comments";
+ tidl::Element elm("test", new tidl::BaseType("int", ""), comments, __LINE__);
+ EXPECT_EQ(elm.GetComments(), comments);
+}
+
+class ElementsTest : public testing::Test {
+ public:
+ virtual void SetUp() {}
+ virtual void TearDown() {}
+};
+
+TEST_F(ElementsTest, Elements_Constructor) {
+ tidl::Elements elms;
+}
+
+TEST_F(ElementsTest, Elements_Add) {
+ tidl::Elements elms;
+ elms.Add(std::unique_ptr<tidl::Element>(
+ new tidl::Element("test", new tidl::BaseType("int", ""), "", __LINE__)));
+
+ bool flag = false;
+ for (const auto& elm : elms) {
+ if (elm->GetID() == "test" &&
+ elm->GetType().ToString() == "int")
+ flag = true;
+ }
+ EXPECT_EQ(flag, true);
+}
+
+TEST_F(ElementsTest, Elements_range_for) {
+ tidl::Elements elms;
+ elms.Add(std::unique_ptr<tidl::Element>(new tidl::Element(
+ "test1", new tidl::BaseType("int", ""), "", __LINE__)));
+ elms.Add(std::unique_ptr<tidl::Element>(new tidl::Element(
+ "test2", new tidl::BaseType("char *", ""), "", __LINE__)));
+
+ int count = 0;
+ for (auto& elm : elms) {
+ if (elm->GetID() == "test1" &&
+ elm->GetType().ToString() == "int")
+ count++;
+ if (elm->GetID() == "test2" &&
+ elm->GetType().ToString() == "char *")
+ count++;
+ }
+ EXPECT_EQ(count, 2);
+}
+
+TEST_F(ElementsTest, Elements_Exist) {
+ tidl::Elements elms;
+ elms.Add(std::unique_ptr<tidl::Element>(new tidl::Element("test",
+ new tidl::BaseType("int", ""), "", __LINE__)));
+ tidl::Element elm2("test", new tidl::BaseType("int", ""), "", __LINE__);
+ EXPECT_EQ(elms.Exist(elm2), true);
+}
diff --git a/unit_tests/generator_unittest.cc b/tests/unit_tests/generator_unittest.cc
index 7573025..7573025 100644
--- a/unit_tests/generator_unittest.cc
+++ b/tests/unit_tests/generator_unittest.cc
diff --git a/unit_tests/interface_unittest.cc b/tests/unit_tests/interface_unittest.cc
index 780aca5..de732aa 100644
--- a/unit_tests/interface_unittest.cc
+++ b/tests/unit_tests/interface_unittest.cc
@@ -27,34 +27,35 @@ class InterfaceTest : public testing::Test {
virtual void SetUp() {
tidl::Parameters* params = new tidl::Parameters();
EXPECT_NE(params, nullptr);
- params->Add(new tidl::Parameter("test1",
- new tidl::ParameterType(new tidl::BaseType("int", "")), __LINE__));
- params->Add(new tidl::Parameter("test2",
- new tidl::ParameterType(new tidl::BaseType("int", "")), __LINE__));
+ params->Add(std::unique_ptr<tidl::Parameter>(new tidl::Parameter("test1",
+ new tidl::ParameterType(new tidl::BaseType("int", "")), __LINE__)));
+ params->Add(std::unique_ptr<tidl::Parameter>(new tidl::Parameter("test2",
+ new tidl::ParameterType(new tidl::BaseType("int", "")), __LINE__)));
tidl::Declaration* decl = new tidl::Declaration("test",
- new tidl::BaseType("int", ""), params, "", __LINE__);
+ std::unique_ptr<tidl::BaseType>(new tidl::BaseType("int", "")),
+ std::unique_ptr<tidl::Parameters>(params), "", __LINE__);
EXPECT_NE(decl, nullptr);
decls = new tidl::Declarations();
EXPECT_NE(decls, nullptr);
- decls->Add(decl);
+ decls->Add(std::unique_ptr<tidl::Declaration>(decl));
}
virtual void TearDown() {}
};
TEST_F(InterfaceTest, Interface_Constructor) {
tidl::Interface* interface = new tidl::Interface("TestInterface", decls,
- "", new tidl::Attributes(), __LINE__);
+ new tidl::Enums(), "", new tidl::Attributes(), __LINE__);
EXPECT_NE(interface, nullptr);
delete interface;
}
TEST_F(InterfaceTest, Interface_GetDeclrations) {
tidl::Interface* interface = new tidl::Interface("TestInterface", decls,
- "", new tidl::Attributes(), __LINE__);
+ new tidl::Enums(), "", new tidl::Attributes(), __LINE__);
EXPECT_NE(interface, nullptr);
bool flag = false;
- for (auto& d : interface->GetDeclarations().GetDecls()) {
+ for (const auto& d : interface->GetDeclarations()) {
if (d->GetID() == "test")
flag = true;
}
@@ -64,7 +65,7 @@ TEST_F(InterfaceTest, Interface_GetDeclrations) {
TEST_F(InterfaceTest, Interface_GetID) {
tidl::Interface* interface = new tidl::Interface("TestInterface", decls,
- "", new tidl::Attributes(), __LINE__);
+ new tidl::Enums(), "", new tidl::Attributes(), __LINE__);
EXPECT_NE(interface, nullptr);
EXPECT_EQ(interface->GetID(), "TestInterface");
delete interface;
@@ -72,7 +73,7 @@ TEST_F(InterfaceTest, Interface_GetID) {
TEST_F(InterfaceTest, Interface_GetType) {
tidl::Interface* interface = new tidl::Interface("TestInterface", decls,
- "", new tidl::Attributes(), __LINE__);
+ new tidl::Enums(), "", new tidl::Attributes(), __LINE__);
EXPECT_NE(interface, nullptr);
EXPECT_EQ(interface->GetType(), tidl::Interface::TYPE_INTERFACE);
delete interface;
@@ -81,7 +82,7 @@ TEST_F(InterfaceTest, Interface_GetType) {
TEST_F(InterfaceTest, Interface_GetLine) {
unsigned line = __LINE__;
tidl::Interface* interface = new tidl::Interface("TestInterface", decls,
- "", new tidl::Attributes(), line);
+ new tidl::Enums(), "", new tidl::Attributes(), line);
EXPECT_NE(interface, nullptr);
EXPECT_EQ(interface->GetLine(), line);
delete interface;
@@ -90,7 +91,7 @@ TEST_F(InterfaceTest, Interface_GetLine) {
TEST_F(InterfaceTest, Interface_GetComments) {
std::string comments = "Test Interface";
tidl::Interface* interface = new tidl::Interface("TestInterface", decls,
- comments, new tidl::Attributes(), __LINE__);
+ new tidl::Enums(), comments, new tidl::Attributes(), __LINE__);
EXPECT_NE(interface, nullptr);
EXPECT_EQ(interface->GetComments(), comments);
delete interface;
diff --git a/unit_tests/main.cc b/tests/unit_tests/main.cc
index a2e3a75..a2e3a75 100644
--- a/unit_tests/main.cc
+++ b/tests/unit_tests/main.cc
diff --git a/unit_tests/parser_unittest.cc b/tests/unit_tests/parser_unittest.cc
index 748e33a..748e33a 100644
--- a/unit_tests/parser_unittest.cc
+++ b/tests/unit_tests/parser_unittest.cc
diff --git a/unit_tests/structure_unittest.cc b/tests/unit_tests/structure_unittest.cc
index 4e68e98..cf57261 100644
--- a/unit_tests/structure_unittest.cc
+++ b/tests/unit_tests/structure_unittest.cc
@@ -27,28 +27,28 @@ class StructureTest : public testing::Test {
virtual void SetUp() {
elms = new tidl::Elements();
EXPECT_NE(elms, nullptr);
- elms->Add(new tidl::Element("test1", new tidl::BaseType("int", ""),
- "", __LINE__));
- elms->Add(new tidl::Element("test2", new tidl::BaseType("char *", ""),
- "", __LINE__));
+ elms->Add(std::unique_ptr<tidl::Element>(new tidl::Element("test1",
+ new tidl::BaseType("int", ""), "", __LINE__)));
+ elms->Add(std::unique_ptr<tidl::Element>(new tidl::Element("test2",
+ new tidl::BaseType("char *", ""), "", __LINE__)));
}
virtual void TearDown() {}
};
TEST_F(StructureTest, Structure_Constructor) {
tidl::Structure* structure = new tidl::Structure("TestStructure", elms,
- "", __LINE__);
+ new tidl::Enums(), "", __LINE__);
EXPECT_NE(structure, nullptr);
delete structure;
}
TEST_F(StructureTest, Structure_GetElements) {
tidl::Structure* structure = new tidl::Structure("TestStructure", elms,
- "", __LINE__);
+ new tidl::Enums(), "", __LINE__);
EXPECT_NE(structure, nullptr);
int count = 0;
- for (auto& elm : elms->GetElms()) {
+ for (const auto& elm : *elms) {
if (elm->GetID() == "test1" &&
elm->GetType().ToString() == "int")
count++;
@@ -62,7 +62,7 @@ TEST_F(StructureTest, Structure_GetElements) {
TEST_F(StructureTest, Structure_GetID) {
tidl::Structure* structure = new tidl::Structure("TestStructure", elms,
- "", __LINE__);
+ new tidl::Enums(), "", __LINE__);
EXPECT_NE(structure, nullptr);
EXPECT_EQ(structure->GetID(), "TestStructure");
delete structure;
@@ -70,7 +70,7 @@ TEST_F(StructureTest, Structure_GetID) {
TEST_F(StructureTest, Structure_GetType) {
tidl::Structure* structure = new tidl::Structure("TestStructure", elms,
- "", __LINE__);
+ new tidl::Enums(), "", __LINE__);
EXPECT_NE(structure, nullptr);
EXPECT_EQ(structure->GetType(), tidl::Structure::TYPE_STRUCTURE);
delete structure;
@@ -79,7 +79,7 @@ TEST_F(StructureTest, Structure_GetType) {
TEST_F(StructureTest, Structure_GetLine) {
unsigned line = __LINE__;
tidl::Structure* structure = new tidl::Structure("TestStructure", elms,
- "", line);
+ new tidl::Enums(), "", line);
EXPECT_NE(structure, nullptr);
EXPECT_EQ(structure->GetLine(), line);
delete structure;
@@ -88,7 +88,7 @@ TEST_F(StructureTest, Structure_GetLine) {
TEST_F(StructureTest, Structure_GetComments) {
std::string comments = "Test Structure";
tidl::Structure* structure = new tidl::Structure("TestStructure", elms,
- comments, __LINE__);
+ new tidl::Enums(), comments, __LINE__);
EXPECT_NE(structure, nullptr);
EXPECT_EQ(structure->GetComments(), comments);
delete structure;
diff --git a/unit_tests/test.tidl b/tests/unit_tests/test.tidl
index 2624814..2624814 100644
--- a/unit_tests/test.tidl
+++ b/tests/unit_tests/test.tidl
diff --git a/unit_tests/test_error.tidl b/tests/unit_tests/test_error.tidl
index ca6475d..ca6475d 100644
--- a/unit_tests/test_error.tidl
+++ b/tests/unit_tests/test_error.tidl
diff --git a/unit_tests/type_unittest.cc b/tests/unit_tests/type_unittest.cc
index f08e7b3..677e096 100644
--- a/unit_tests/type_unittest.cc
+++ b/tests/unit_tests/type_unittest.cc
@@ -61,6 +61,7 @@ TEST_F(BaseTypeTest, BaseType_Constructor) {
TEST_F(BaseTypeTest, BaseType_SetMetaType) {
tidl::BaseType* customType = new tidl::BaseType("CustomType", "", true);
customType->SetMetaType(new tidl::BaseType("int", ""));
+ EXPECT_NE(customType->GetMetaType(), nullptr);
EXPECT_EQ(customType->GetMetaType()->ToString(), "int");
delete customType;
}
@@ -68,6 +69,7 @@ TEST_F(BaseTypeTest, BaseType_SetMetaType) {
TEST_F(BaseTypeTest, BaseType_GetMetaType) {
tidl::BaseType* customType = new tidl::BaseType("CustomType", "", true);
customType->SetMetaType(new tidl::BaseType("string", ""));
+ EXPECT_NE(customType->GetMetaType(), nullptr);
EXPECT_EQ(customType->GetMetaType()->ToString(), "string");
delete customType;
}
diff --git a/unit_tests/unit_tests.sh b/tests/unit_tests/unit_tests.sh
index 36fce76..36fce76 100755
--- a/unit_tests/unit_tests.sh
+++ b/tests/unit_tests/unit_tests.sh
diff --git a/unit_tests/declaration_unittest.cc b/unit_tests/declaration_unittest.cc
deleted file mode 100644
index 776341d..0000000
--- a/unit_tests/declaration_unittest.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <iostream>
-
-#include "idlc/ast/declaration.h"
-#include "idlc/ast/type.h"
-#include "idlc/ast/parameter.h"
-
-class DeclarationTest : public testing::Test {
- public:
- tidl::Parameters* params;
-
- virtual void SetUp() {
- params = new tidl::Parameters();
- EXPECT_NE(params, nullptr);
- params->Add(new tidl::Parameter("test1",
- new tidl::ParameterType(new tidl::BaseType("int", "")), __LINE__));
- params->Add(new tidl::Parameter("test2",
- new tidl::ParameterType(new tidl::BaseType("int", "")), __LINE__));
- }
- virtual void TearDown() {}
-};
-
-TEST_F(DeclarationTest, Declaration_Constructor) {
- tidl::Declaration* decl = new tidl::Declaration("test",
- new tidl::BaseType("int", ""), params, "", __LINE__);
- EXPECT_NE(decl, nullptr);
- delete decl;
-}
-
-TEST_F(DeclarationTest, Declaration_GetID) {
- tidl::Declaration* decl = new tidl::Declaration("test",
- new tidl::BaseType("int", ""), params, "", __LINE__);
- EXPECT_NE(decl, nullptr);
- EXPECT_EQ(decl->GetID(), "test");
- delete decl;
-}
-
-TEST_F(DeclarationTest, Declaration_GetType) {
- tidl::Declaration* decl = new tidl::Declaration("test",
- new tidl::BaseType("int", ""), params, "", __LINE__);
- EXPECT_NE(decl, nullptr);
- EXPECT_EQ(decl->GetType().ToString(), "int");
- delete decl;
-}
-
-TEST_F(DeclarationTest, Declaration_GetParameters) {
- tidl::Declaration* decl = new tidl::Declaration("test",
- new tidl::BaseType("int", ""), params, "", __LINE__);
- EXPECT_NE(decl, nullptr);
-
- int count = 0;
- for (auto& param : decl->GetParameters().GetParams()) {
- if (param->GetID() == "test1" &&
- param->GetParameterType().GetBaseType().ToString() == "int")
- count++;
- if (param->GetID() == "test2" &&
- param->GetParameterType().GetBaseType().ToString() == "int")
- count++;
- }
- EXPECT_EQ(count, 2);
-
- delete decl;
-}
-
-TEST_F(DeclarationTest, Declaration_GetMethodType) {
- tidl::Declaration* decl = new tidl::Declaration("test",
- new tidl::BaseType("int", ""), params, "", __LINE__,
- tidl::Declaration::MethodType::DELEGATE);
- EXPECT_NE(decl, nullptr);
- EXPECT_EQ(decl->GetMethodType(), tidl::Declaration::MethodType::DELEGATE);
- delete decl;
-}
-
-TEST_F(DeclarationTest, Declaration_GetComments) {
- std::string comments = "Test Declaration";
- tidl::Declaration* decl = new tidl::Declaration("test",
- new tidl::BaseType("int", ""), params, comments, __LINE__);
- EXPECT_NE(decl, nullptr);
- EXPECT_EQ(decl->GetComments(), comments);
- delete decl;
-}
-
-TEST_F(DeclarationTest, Declaration_GetLine) {
- unsigned line = __LINE__;
- tidl::Declaration* decl = new tidl::Declaration("test",
- new tidl::BaseType("int", ""), params, "", line);
- EXPECT_NE(decl, nullptr);
- EXPECT_EQ(decl->GetLine(), line);
- delete decl;
-}
-
-class DeclarationsTest : public testing::Test {
- public:
- tidl::Declaration* decl;
-
- virtual void SetUp() {}
- virtual void TestDown() {}
- void PrepareDeclaration() {
- tidl::Parameters* params = new tidl::Parameters();
- EXPECT_NE(params, nullptr);
- params->Add(new tidl::Parameter("test1",
- new tidl::ParameterType(new tidl::BaseType("int", "")), __LINE__));
- params->Add(new tidl::Parameter("test2",
- new tidl::ParameterType(new tidl::BaseType("int", "")), __LINE__));
- decl = new tidl::Declaration("test",
- new tidl::BaseType("int", ""), params, "", __LINE__);
- EXPECT_NE(decl, nullptr);
- }
-};
-
-TEST_F(DeclarationsTest, Declarations_Constructor) {
- tidl::Declarations* decls = new tidl::Declarations();
- EXPECT_NE(decls, nullptr);
- delete decls;
-}
-
-TEST_F(DeclarationsTest, Declarations_Add) {
- tidl::Declarations* decls = new tidl::Declarations();
- EXPECT_NE(decls, nullptr);
- PrepareDeclaration();
- decls->Add(decl);
-
- bool flag = false;
- for (auto& d : decls->GetDecls()) {
- if (d->GetID() == "test")
- flag = true;
- }
- EXPECT_EQ(flag, true);
- delete decls;
-}
-
-TEST_F(DeclarationsTest, Declarations_GetDecls) {
- tidl::Declarations* decls = new tidl::Declarations();
- EXPECT_NE(decls, nullptr);
- PrepareDeclaration();
- decls->Add(decl);
-
- bool flag = false;
- for (auto& d : decls->GetDecls()) {
- if (d->GetID() == "test")
- flag = true;
- }
- EXPECT_EQ(flag, true);
- delete decls;
-}
-
-TEST_F(DeclarationsTest, Declarations_Exist) {
- tidl::Declarations* decls = new tidl::Declarations();
- EXPECT_NE(decls, nullptr);
- PrepareDeclaration();
- decls->Add(decl);
- tidl::Parameters* testParams = new tidl::Parameters();
- EXPECT_NE(testParams, nullptr);
- testParams->Add(new tidl::Parameter("test1",
- new tidl::ParameterType(new tidl::BaseType("int", "")), __LINE__));
- tidl::Declaration* testDecl = new tidl::Declaration("test",
- new tidl::BaseType("int", ""), testParams, "", __LINE__);
- EXPECT_NE(testDecl, nullptr);
- EXPECT_EQ(decls->Exist(testDecl), true);
- delete testDecl;
- delete decls;
-}
diff --git a/unit_tests/element_unittest.cc b/unit_tests/element_unittest.cc
deleted file mode 100644
index 8ef351c..0000000
--- a/unit_tests/element_unittest.cc
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <iostream>
-
-#include "idlc/ast/element.h"
-
-class ElementTest : public testing::Test {
- public:
- virtual void SetUp() {}
- virtual void TearDown() {}
-};
-
-TEST_F(ElementTest, Element_Contstructor) {
- tidl::Element* elm = new tidl::Element("test",
- new tidl::BaseType("int", ""), "", __LINE__);
- EXPECT_NE(elm, nullptr);
- delete elm;
-}
-
-TEST_F(ElementTest, Element_GetID) {
- tidl::Element* elm = new tidl::Element("test",
- new tidl::BaseType("int", ""), "", __LINE__);
- EXPECT_NE(elm, nullptr);
- EXPECT_EQ(elm->GetID(), "test");
- delete elm;
-}
-
-TEST_F(ElementTest, Element_GetType) {
- tidl::Element* elm = new tidl::Element("test",
- new tidl::BaseType("int", ""), "", __LINE__);
- EXPECT_NE(elm, nullptr);
- EXPECT_EQ(elm->GetType().ToString(), "int");
- delete elm;
-}
-
-TEST_F(ElementTest, Element_GetLine) {
- unsigned line = __LINE__;
- tidl::Element* elm = new tidl::Element("test",
- new tidl::BaseType("int", ""), "", line);
- EXPECT_NE(elm, nullptr);
- EXPECT_EQ(elm->GetLine(), line);
- delete elm;
-}
-
-TEST_F(ElementTest, Element_GetComments) {
- std::string comments = "Test comments";
- tidl::Element* elm = new tidl::Element("test",
- new tidl::BaseType("int", ""), comments, __LINE__);
- EXPECT_NE(elm, nullptr);
- EXPECT_EQ(elm->GetComments(), comments);
- delete elm;
-}
-
-class ElementsTest : public testing::Test {
- public:
- virtual void SetUp() {}
- virtual void TearDown() {}
-};
-
-TEST_F(ElementsTest, Elements_Constructor) {
- tidl::Elements* elms = new tidl::Elements();
- EXPECT_NE(elms, nullptr);
- delete elms;
-}
-
-TEST_F(ElementsTest, Elements_Add) {
- tidl::Element* elm = new tidl::Element("test",
- new tidl::BaseType("int", ""), "", __LINE__);
- EXPECT_NE(elm, nullptr);
- tidl::Elements* elms = new tidl::Elements();
- EXPECT_NE(elms, nullptr);
- elms->Add(elm);
-
- bool flag = false;
- for (auto& elm : elms->GetElms()) {
- if (elm->GetID() == "test" &&
- elm->GetType().ToString() == "int")
- flag = true;
- }
- EXPECT_EQ(flag, true);
- delete elms;
-}
-
-TEST_F(ElementsTest, Elements_Getelms) {
- tidl::Elements* elms = new tidl::Elements();
- EXPECT_NE(elms, nullptr);
- elms->Add(new tidl::Element("test1", new tidl::BaseType("int", ""),
- "", __LINE__));
- elms->Add(new tidl::Element("test2", new tidl::BaseType("char *", ""),
- "", __LINE__));
-
- int count = 0;
- for (auto& elm : elms->GetElms()) {
- if (elm->GetID() == "test1" &&
- elm->GetType().ToString() == "int")
- count++;
- if (elm->GetID() == "test2" &&
- elm->GetType().ToString() == "char *")
- count++;
- }
- EXPECT_EQ(count, 2);
- delete elms;
-}
-
-TEST_F(ElementsTest, Elements_Exist) {
- tidl::Element* elm = new tidl::Element("test",
- new tidl::BaseType("int", ""), "", __LINE__);
- EXPECT_NE(elm, nullptr);
- tidl::Elements* elms = new tidl::Elements();
- EXPECT_NE(elms, nullptr);
- elms->Add(elm);
- tidl::Element* elm2 = new tidl::Element("test",
- new tidl::BaseType("int", ""), "", __LINE__);
- EXPECT_NE(elm, nullptr);
- EXPECT_EQ(elms->Exist(elm2), true);
- delete elm2;
- delete elms;
-}