Refactor C generator 78/172878/4
authorJunghoon Park <jh9216.park@samsung.com>
Fri, 16 Mar 2018 11:45:40 +0000 (20:45 +0900)
committerJunghoon Park <jh9216.park@samsung.com>
Mon, 19 Mar 2018 04:26:01 +0000 (13:26 +0900)
- Add code block header files
- Fix some bugs

Change-Id: I32bf717a8d6f3e39398d4b9f90518e83ad81aafd
Signed-off-by: Junghoon Park <jh9216.park@samsung.com>
14 files changed:
idlc/c_gen/c_body_gen_base.cc
idlc/c_gen/c_body_gen_base_cb.h [new file with mode: 0644]
idlc/c_gen/c_gen_base.cc
idlc/c_gen/c_gen_base_cb.h [new file with mode: 0644]
idlc/c_gen/c_header_gen_base.cc
idlc/c_gen/c_header_gen_base_cb.h [new file with mode: 0644]
idlc/c_gen/c_proxy_body_gen.cc
idlc/c_gen/c_proxy_body_gen_cb.h [new file with mode: 0644]
idlc/c_gen/c_proxy_header_gen.cc
idlc/c_gen/c_proxy_header_gen_cb.h [new file with mode: 0644]
idlc/c_gen/c_stub_body_gen.cc
idlc/c_gen/c_stub_body_gen_cb.h [new file with mode: 0644]
idlc/c_gen/c_stub_header_gen.cc
idlc/c_gen/c_stub_header_gen_cb.h [new file with mode: 0644]

index 5e8dfeb..fd8191c 100644 (file)
 
 #include "idlc/c_gen/c_body_gen_base.h"
 
+namespace {
+#include "idlc/c_gen/c_body_gen_base_cb.h"
+}
+
 namespace tidl {
 
 CBodyGeneratorBase::CBodyGeneratorBase(std::shared_ptr<Document> doc)
@@ -65,25 +69,20 @@ void CBodyGeneratorBase::GenStructure(std::ofstream& stream,
 
 void CBodyGeneratorBase::GenStructureDeclaration(std::ofstream& stream,
                                                  const Structure& st) {
-  const char block[] =
-      "struct $$_s {\n" \
-      "    rpc_port_parcelable_t parcelable;\n" \
-      "    $$" \
-      "};\n";
-
-  stream << NLine(1);
-  stream << st.GetComments();
-  stream << SmartIndent(GenTemplateString(block,
+  stream << SmartIndent(GenTemplateString(CB_STRUCT_DECL,
+        [&]()->std::string {
+          return st.GetComments();
+        },
         [&]()->std::string {
           return st.GetID();
         },
         [&]()->std::string {
           std::string str;
           for (auto& i : st.GetElements().GetElms()) {
-            str += GetStringFromElementType(i->GetType()) +
-                i->GetID() + ";" + NLine(1);
+            str += NLine(1) + GetStringFromElementType(i->GetType()) +
+                i->GetID() + ";";
             if (i->GetType().ToString() == "array")
-              str += "int " + i->GetID() + "_size;" + NLine(1);
+              str += NLine(1) + "int " + i->GetID() + "_size;";
           }
           return str;
         }
@@ -93,20 +92,8 @@ void CBodyGeneratorBase::GenStructureDeclaration(std::ofstream& stream,
 
 void CBodyGeneratorBase::GenStructureParcelSerializer(std::ofstream& stream,
                                               const Structure& st) {
-  const char block[] =
-      "static void __##_to(rpc_port_parcel_h parcel, void *data)\n" \
-      "{\n" \
-      "    rpc_port_##_h h = data;\n" \
-      "\n" \
-      "    if (!parcel || !h) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return;\n" \
-      "    }\n" \
-      "$$" \
-      "}\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(GenTemplateString(ReplaceAll(block, "##", st.GetID()),
+  stream << SmartIndent(GenTemplateString(
+        ReplaceAll(CB_STRUCT_SERIALIZER, "##", st.GetID()),
         [&]()->std::string {
           std::string str;
           for (auto& i : st.GetElements().GetElms()) {
@@ -121,20 +108,8 @@ void CBodyGeneratorBase::GenStructureParcelSerializer(std::ofstream& stream,
 
 void CBodyGeneratorBase::GenStructureParcelDeserializer(std::ofstream& stream,
                                                 const Structure& st) {
-  const char block[] =
-      "static void __##_from(rpc_port_parcel_h parcel, void *data)\n" \
-      "{\n" \
-      "    rpc_port_##_h h = data;\n" \
-      "\n"
-      "    if (!parcel || !h) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG,\"Invalid parameter\");\n" \
-      "        return;\n" \
-      "    }\n" \
-      "$$" \
-      "}\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(GenTemplateString(ReplaceAll(block, "##", st.GetID()),
+  stream << SmartIndent(GenTemplateString(
+        ReplaceAll(CB_STRUCT_DESERIALIZER, "##", st.GetID()),
         [&]()->std::string {
           std::string str;
           for (auto& i : st.GetElements().GetElms()) {
@@ -149,52 +124,13 @@ void CBodyGeneratorBase::GenStructureParcelDeserializer(std::ofstream& stream,
 
 void CBodyGeneratorBase::GenStructureConstructor(std::ofstream& stream,
                                                  const Structure& st) {
-  const char block[] =
-      "int rpc_port_##_create(rpc_port_##_h *h)\n" \
-      "{\n" \
-      "    struct ##_s *handle;\n" \
-      "\n" \
-      "    if (!h) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    handle = calloc(1, sizeof(struct ##_s));\n" \
-      "    if (!handle) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Out of memory\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n"
-      "    handle->parcelable.to = __##_to;\n" \
-      "    handle->parcelable.from = __##_from;\n" \
-      "\n"
-      "    *h = handle;\n"
-      "\n"
-      "    return 0;\n" \
-      "}\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", st.GetID()));
+  stream << SmartIndent(ReplaceAll(CB_STRUCT_CTOR, "##", st.GetID()));
 }
 
 void CBodyGeneratorBase::GenStructureDestructor(std::ofstream& stream,
                                                 const Structure& st) {
-  const char block[] =
-      "int rpc_port_##_destroy(rpc_port_##_h h)\n" \
-      "{\n" \
-      "    if (!h) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "$$" \
-      "    free(h);\n" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(GenTemplateString(ReplaceAll(block, "##", st.GetID()),
+  stream << SmartIndent(GenTemplateString(
+        ReplaceAll(CB_STRUCT_DTOR, "##", st.GetID()),
         [&]()->std::string {
           std::string str;
           for (auto& i : st.GetElements().GetElms()) {
@@ -208,21 +144,8 @@ void CBodyGeneratorBase::GenStructureDestructor(std::ofstream& stream,
 
 void CBodyGeneratorBase::GenStructureSetter(std::ofstream& stream,
                                             const Structure& st) {
-  const char block[] =
-      "int rpc_port_$$_$$_$$(rpc_port_$$_h h, $$$$)\n" \
-      "{\n" \
-      "    if ($$) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "$$" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-
   for (auto& i : st.GetElements().GetElms()) {
-    stream << NLine(1);
-    stream << SmartIndent(GenTemplateString(block,
+    stream << SmartIndent(GenTemplateString(CB_STRUCT_SETTER,
           [&]()->std::string {
             return st.GetID();
           },
@@ -297,24 +220,11 @@ void CBodyGeneratorBase::GenStructureSetter(std::ofstream& stream,
 
 void CBodyGeneratorBase::GenStructureGetter(std::ofstream& stream,
                                             const Structure& st) {
-  const char block[] =
-      "int rpc_port_$$_get_$$(rpc_port_$$_h h, $$$$)\n" \
-      "{\n" \
-      "    if (!h || $$) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "$$" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-
   for (auto& i : st.GetElements().GetElms()) {
     if (i->GetType().ToString() == "list")
       continue;
 
-    stream << NLine(1);
-    stream << SmartIndent(GenTemplateString(block,
+    stream << SmartIndent(GenTemplateString(CB_STRUCT_GETTER,
           [&]()->std::string {
             return st.GetID();
           },
@@ -368,25 +278,11 @@ void CBodyGeneratorBase::GenStructureGetter(std::ofstream& stream,
 
 void CBodyGeneratorBase::GenStructureIterator(std::ofstream& stream,
                                               const Structure& st) {
-  const char block[] =
-      "int rpc_port_$$_foreach_$$(rpc_port_$$_h h, " \
-      "void (*callback)($$$$, void *user_data), void *user_data)\n" \
-      "{\n" \
-      "    if (!h || !callback) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "$$" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-
   for (auto& i : st.GetElements().GetElms()) {
     if (i->GetType().ToString() != "list")
       continue;
 
-    stream << NLine(1);
-    stream << SmartIndent(GenTemplateString(block,
+    stream << SmartIndent(GenTemplateString(CB_STRUCT_ITERATOR,
           [&]()->std::string {
             return st.GetID();
           },
@@ -421,30 +317,8 @@ void CBodyGeneratorBase::GenStructureIterator(std::ofstream& stream,
 
 void CBodyGeneratorBase::GenStructureCloner(std::ofstream& stream,
                                             const Structure& st) {
-  const char block[] =
-      "int rpc_port_##_clone(rpc_port_##_h h, rpc_port_##_h *clone)\n" \
-      "{\n" \
-      "    rpc_port_##_h handle = NULL;\n" \
-      "\n" \
-      "    if (!h || !clone) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    rpc_port_##_create(&handle);\n" \
-      "    if (!handle) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to create ## handle\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "$$" \
-      "\n" \
-      "    *clone = handle;\n" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(GenTemplateString(ReplaceAll(block, "##", st.GetID()),
+  stream << SmartIndent(GenTemplateString(
+        ReplaceAll(CB_STRUCT_CLONER, "##", st.GetID()),
         [&]()->std::string {
           std::string str;
           for (auto& i : st.GetElements().GetElms()) {
@@ -494,28 +368,7 @@ std::string CBodyGeneratorBase::GetParcelWriteFunctionString(
 std::string CBodyGeneratorBase::GetParcelWriteString(const std::string& id,
                                                      const BaseType& type) {
   std::string str;
-  const char parcel[] = "$$(parcel, $$);\n";
-  const char do_while_list[] =
-      "do {\n" \
-      "    GList *iter = $$;\n"
-      "    while (iter) {\n" \
-      "        $$value = iter->data;\n" \
-      "\n" \
-      "        iter = g_list_next(iter);\n" \
-      "        if (!value) {\n" \
-      "            dlog_print(DLOG_WARN, LOG_TAG, \"Warning: value is NULL\");\n" \
-      "            continue;\n" \
-      "        }\n" \
-      "\n" \
-      "        $$" \
-      "    }\n" \
-      "} while (0);\n";
-  const char do_while_array[] =
-      "do {\n" \
-      "    for (int i = 0; i < $$; i++) {\n" \
-      "$$"
-      "    }\n" \
-      "} while (0);\n";
+  const char parcel[] = "$$(parcel, $$);";
 
   str += GenTemplateString(parcel,
       [&]()->std::string {
@@ -533,7 +386,7 @@ std::string CBodyGeneratorBase::GetParcelWriteString(const std::string& id,
       );
 
   if (type.ToString() == "list") {
-    str += GenTemplateString(do_while_list,
+    str += GenTemplateString(CB_WRITE_LIST_BLOCK,
         [&]()->std::string {
           return "h->" + id;
         },
@@ -560,7 +413,7 @@ std::string CBodyGeneratorBase::GetParcelWriteString(const std::string& id,
         }
         );
   } else if (type.ToString() == "array") {
-    str += GenTemplateString(do_while_array,
+    str += GenTemplateString(CB_WRITE_ARRAY_BLOCK,
         [&]()->std::string {
           return "h->" + id + "_size";
         },
@@ -597,42 +450,10 @@ std::string CBodyGeneratorBase::GetParcelReadFunctionString(
 std::string CBodyGeneratorBase::GetParcelReadString(const std::string& id,
                                                     const BaseType& type) {
   std::string str;
-  const char parcel[] = "$$(parcel, $$);\n";
-  const char if_statement_with_braces[] =
-      "if ($$) {\n" \
-      "    $$" \
-      "}\n";
-  const char do_while_list[] =
-      "do {\n" \
-      "    int len = 0;\n" \
-      "\n" \
-      "    $$" \
-      "    for (int i = 0; i < len; i++) {\n" \
-      "        $$value = NULL;\n" \
-      "\n" \
-      "        $$" \
-      "        $$ = g_list_append($$, value);\n" \
-      "    }\n" \
-      "} while (0);\n";
-  const char do_while_array[] =
-      "do {\n" \
-      "    $$" \
-      "\n" \
-      "    h->## = calloc(h->##_size, sizeof(*h->##));\n" \
-      "    if (!h->##) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Out of memory\");\n" \
-      "        return;\n" \
-      "    }\n" \
-      "\n" \
-      "    for (int i = 0; i < h->##_size; i++) {\n" \
-      "        $$value = $$;\n" \
-      "\n" \
-      "        $$" \
-      "    }\n" \
-      "} while (0);\n";
+  const char parcel[] = "$$(parcel, $$);";
 
   if (type.ToString() == "list") {
-    str += GenTemplateString(do_while_list,
+    str += GenTemplateString(CB_READ_LIST_BLOCK,
         [&]()->std::string {
           return GenTemplateString(parcel,
               [&]()->std::string {
@@ -653,7 +474,7 @@ std::string CBodyGeneratorBase::GetParcelReadString(const std::string& id,
               type.GetMetaType()->ToString() == "list" ||
               type.GetMetaType()->ToString() == "array") {
             s += GetConstructorString(*type.GetMetaType(), "value");
-            s += GenTemplateString(if_statement_with_braces,
+            s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
                 [&]()->std::string {
                   return "!value";
                 },
@@ -685,7 +506,7 @@ std::string CBodyGeneratorBase::GetParcelReadString(const std::string& id,
                 );
           } else {
             s += "value = calloc(1, sizeof(*value));" + NLine(1);
-            s += GenTemplateString(if_statement_with_braces,
+            s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
                 [&]()->std::string {
                   return "!value";
                 },
@@ -717,7 +538,7 @@ std::string CBodyGeneratorBase::GetParcelReadString(const std::string& id,
         }
         );
   } else if (type.ToString() == "array") {
-    str += GenTemplateString(ReplaceAll(do_while_array, "##", id),
+    str += GenTemplateString(ReplaceAll(CB_READ_ARRAY_BLOCK, "##", id),
         [&]()->std::string {
           return GenTemplateString(parcel,
               [&]()->std::string {
@@ -740,7 +561,7 @@ std::string CBodyGeneratorBase::GetParcelReadString(const std::string& id,
               type.GetMetaType()->ToString() == "list" ||
               type.GetMetaType()->ToString() == "array") {
             s += GetConstructorString(*type.GetMetaType(), "value");
-            s += GenTemplateString(if_statement_with_braces,
+            s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
                 [&]()->std::string {
                   return "!value";
                 },
@@ -793,26 +614,6 @@ std::string CBodyGeneratorBase::GetParcelReadString(const std::string& id,
 std::string CBodyGeneratorBase::GetFinalizeString(const std::string& id,
                                                   const BaseType& type) {
   std::string str;
-  const char if_statement[] =
-      "if ($$)\n" \
-      "    $$";
-  const char do_while_list[] =
-      "do {\n" \
-      "    GList *iter = $$;\n" \
-      "    while (iter) {\n" \
-      "        $$value = iter->data;\n" \
-      "        $$" \
-      "        iter = g_list_next(iter);\n" \
-      "    }\n" \
-      "    g_list_free($$);\n" \
-      "} while (0);\n";
-  const char do_while_array[] =
-      "do {\n" \
-      "    for (int i = 0; i < $$; i++) {\n" \
-      "        $$" \
-      "    }\n" \
-      "    free($$);\n" \
-      "} while (0);\n";
 
   if (!type.IsUserDefinedType() &&
        type.ToString() != "list" &&
@@ -822,7 +623,7 @@ std::string CBodyGeneratorBase::GetFinalizeString(const std::string& id,
     return str;
 
   if (type.ToString() == "list") {
-    str += GenTemplateString(do_while_list,
+    str += GenTemplateString(CB_FINALIZE_LIST_BLOCK,
         [&]()->std::string {
           return "h->" + id;
         },
@@ -830,7 +631,7 @@ std::string CBodyGeneratorBase::GetFinalizeString(const std::string& id,
           return GetParcelParamTypeString(*type.GetMetaType());
         },
         [&]()->std::string {
-          return GenTemplateString(if_statement,
+          return GenTemplateString(CB_IF_STATEMENT,
               [&]()->std::string {
                 return "value";
               },
@@ -850,21 +651,21 @@ std::string CBodyGeneratorBase::GetFinalizeString(const std::string& id,
          type.GetMetaType()->ToString() != "array" &&
          type.GetMetaType()->ToString() != "string" &&
          type.GetMetaType()->ToString() != "bundle") {
-      return GenTemplateString(if_statement,
+      return GenTemplateString(CB_IF_STATEMENT,
               [&]()->std::string {
                 return "h->" + id;
               },
               [&]()->std::string {
-                return "free(h->" + id + ");" + NLine(1);
+                return "free(h->" + id + ");";
               }
               );
     }
-    str += GenTemplateString(do_while_array,
+    str += GenTemplateString(CB_FINALIZE_ARRAY_BLOCK,
         [&]()->std::string {
           return "h->" + id + "_size";
         },
         [&]()->std::string {
-          return GenTemplateString(if_statement,
+          return GenTemplateString(CB_IF_STATEMENT,
               [&]()->std::string {
                 return "h->" + id + "[i]";
               },
@@ -879,7 +680,7 @@ std::string CBodyGeneratorBase::GetFinalizeString(const std::string& id,
         }
         );
   } else {
-    str += GenTemplateString(if_statement,
+    str += GenTemplateString(CB_IF_STATEMENT,
         [&]()->std::string {
           return "h->" + id;
         },
@@ -896,36 +697,11 @@ std::string CBodyGeneratorBase::GetSetterString(const std::string& id,
                                                 const BaseType& type) {
   std::string str;
   const char setter[] = "$$ = $$;\n";
-  const char if_statement_with_braces[] =
-      "if ($$) {\n" \
-      "    $$" \
-      "}\n";
-  const char do_while_list[] =
-      "do {\n" \
-      "    $$value;\n" \
-      "\n" \
-      "    value = calloc(1, sizeof(*value));\n" \
-      "    $$" \
-      "    $$ = g_list_append($$, value);\n" \
-      "} while (0);\n";
-  const char do_while_array[] =
-      "do {\n" \
-      "    h->## = calloc(##_size, sizeof(*##));\n" \
-      "    if (!h->##) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Out of memory\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "    h->##_size = ##_size;\n" \
-      "\n" \
-      "    for (int i = 0; i < h->##_size; i++) {\n" \
-      "        $$" \
-      "    }\n" \
-      "} while (0);\n";
 
   if (type.IsUserDefinedType() ||
       type.ToString() == "string" ||
       type.ToString() == "bundle") {
-    str += GenTemplateString(if_statement_with_braces,
+    str += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
         [&]()->std::string {
           return "h->" + id;
         },
@@ -938,7 +714,7 @@ std::string CBodyGeneratorBase::GetSetterString(const std::string& id,
         );
     str += NLine(1);
     str += GetSetterString(type, "h->" + id, id);
-    str += GenTemplateString(if_statement_with_braces,
+    str += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
         [&]()->std::string {
           return "!h->" + id;
         },
@@ -964,13 +740,13 @@ std::string CBodyGeneratorBase::GetSetterString(const std::string& id,
           }
           );
     } else {
-      str += GenTemplateString(do_while_list,
+      str += GenTemplateString(CB_SETTER_LIST_BLOCK,
           [&]()->std::string {
             return GetParcelParamTypeString(*type.GetMetaType());
           },
           [&]()->std::string {
             std::string s;
-            s += GenTemplateString(if_statement_with_braces,
+            s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
                 [&]()->std::string {
                   return "!value";
                 },
@@ -997,7 +773,7 @@ std::string CBodyGeneratorBase::GetSetterString(const std::string& id,
     str += GetFinalizeString(id, type);
     str += GetSetterString("h->" + id, "NULL");
     str += NLine(1);
-    str += GenTemplateString(ReplaceAll(do_while_array, "##", id),
+    str += GenTemplateString(ReplaceAll(CB_SETTER_ARRAY_BLOCK, "##", id),
         [&]()->std::string {
           return GetSetterString(*type.GetMetaType(),
               "h->" + id + "[i]", id + "[i]");
@@ -1013,31 +789,9 @@ std::string CBodyGeneratorBase::GetSetterString(const std::string& id,
 std::string CBodyGeneratorBase::GetGetterString(const std::string& id,
                                                 const BaseType& type) {
   std::string str;
-  const char if_statement_with_braces[] =
-      "if ($$) {\n" \
-      "    $$" \
-      "}\n";
-  const char do_while_array[] =
-      "do {\n" \
-      "    if (h->##_size == 0) {\n" \
-      "        dlog_print(DLOG_WARN, LOG_TAG, \"## is empty\");\n" \
-      "        break;\n" \
-      "    }\n" \
-      "\n" \
-      "    *## = calloc(h->##_size, sizeof(*h->##));\n" \
-      "    if (!*##) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Out of memory\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "    *##_size = h->##_size;\n" \
-      "\n" \
-      "    for (int i = 0; i < h->##_size; i++) {\n" \
-      "        $$" \
-      "    }\n" \
-      "} while (0);\n";
 
   if (type.ToString() == "array") {
-    str += GenTemplateString(ReplaceAll(do_while_array, "##", id),
+    str += GenTemplateString(ReplaceAll(CB_GETTER_ARRAY_BLOCK, "##", id),
         [&]()->std::string {
            return GetSetterString(*type.GetMetaType(),
               "(*" + id + ")[i]", "h->" + id + "[i]");
@@ -1047,7 +801,7 @@ std::string CBodyGeneratorBase::GetGetterString(const std::string& id,
     if (type.IsUserDefinedType() ||
         type.ToString() == "string" ||
         type.ToString() == "bundle") {
-      str += GenTemplateString(if_statement_with_braces,
+      str += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
           [&]()->std::string {
             return "!h->" + id;
           },
@@ -1071,7 +825,7 @@ std::string CBodyGeneratorBase::GetGetterString(const std::string& id,
     if (type.IsUserDefinedType() ||
         type.ToString() == "string" ||
         type.ToString() == "bundle") {
-      str += GenTemplateString(if_statement_with_braces,
+      str += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
           [&]()->std::string {
             return "*" + id + " == NULL";
           },
@@ -1090,23 +844,8 @@ std::string CBodyGeneratorBase::GetGetterString(const std::string& id,
 std::string CBodyGeneratorBase::GetIteratorString(const std::string& id,
                                                   const BaseType& type) {
   std::string str;
-  const char iterator[] =
-      "do {\n" \
-      "   GList *iter = $$;\n" \
-      "   while (iter) {\n" \
-      "       $$value = iter->data;\n" \
-      "\n" \
-      "       iter = g_list_next(iter);\n" \
-      "       if (!value) {\n" \
-      "           dlog_print(DLOG_WARN, LOG_TAG, \"Warning: value is NULL\");\n" \
-      "           continue;\n" \
-      "       }\n" \
-      "\n" \
-      "       callback($$, user_data);\n" \
-      "   }\n" \
-      "} while (0);\n";
-
-  str += GenTemplateString(iterator,
+
+  str += GenTemplateString(CB_ITERATOR_BLOCK,
       [&]()->std::string {
         return "h->" + id;
       },
@@ -1132,58 +871,18 @@ std::string CBodyGeneratorBase::GetClonerString(const std::string& id,
                                                 const BaseType& type,
                                                 const Structure& st) {
   std::string str;
-  const char if_statement_with_braces[] =
-      "if ($$) {\n" \
-      "    $$" \
-      "}\n";
-  const char do_while_list[] =
-      "do {\n" \
-      "    GList *iter = $$;\n" \
-      "    while (iter) {\n" \
-      "        $$new_value;\n" \
-      "        $$value = iter->data;\n" \
-      "\n" \
-      "        if (!value) {\n" \
-      "            dlog_print(DLOG_ERROR, LOG_TAG, \"Error: value is NULL\");\n" \
-      "            rpc_port_$$_destroy(handle);\n"
-      "            return -1;\n" \
-      "        }\n" \
-      "\n" \
-      "        $$" \
-      "        $$ = g_list_append($$, new_value);\n" \
-      "        iter = g_list_next(iter);\n" \
-      "    }\n" \
-      "} while (0);\n";
-  const char do_while_array[] =
-      "do {\n" \
-      "    if (h->##_size == 0) {\n" \
-      "        dlog_print(DLOG_WARN, LOG_TAG, \"## is empty\");\n" \
-      "        break;\n" \
-      "    }\n" \
-      "\n" \
-      "    handle->## = calloc(h->##_size, sizeof(*h->##));\n" \
-      "    if (!handle->##) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Out of memory\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "    handle->##_size = h->##_size;\n" \
-      "\n" \
-      "    for (int i = 0; i < h->##_size; i++) {\n" \
-      "        $$" \
-      "    }\n" \
-      "} while (0);\n";
 
   if (type.IsUserDefinedType() ||
       type.ToString() == "string" ||
       type.ToString() == "bundle") {
-    str += GenTemplateString(if_statement_with_braces,
+    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(if_statement_with_braces,
+          s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
               [&]()->std::string {
                 return "!handle->" + id;
               },
@@ -1201,7 +900,7 @@ std::string CBodyGeneratorBase::GetClonerString(const std::string& id,
         }
         );
   } else  if (type.ToString() == "list") {
-    str += GenTemplateString(do_while_list,
+    str += GenTemplateString(CB_CLONER_LIST_BLOCK,
         [&]()->std::string {
           return "h->" + id;
         },
@@ -1223,7 +922,7 @@ std::string CBodyGeneratorBase::GetClonerString(const std::string& id,
               type.GetMetaType()->ToString() == "bundle") {
             s += GetSetterString(*type.GetMetaType(),
                 "new_value", "value");
-            s += GenTemplateString(if_statement_with_braces,
+            s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
                 [&]()->std::string {
                   return "!new_value";
                 },
@@ -1239,7 +938,7 @@ std::string CBodyGeneratorBase::GetClonerString(const std::string& id,
               );
           } else {
             s += "new_value = calloc(1, sizeof(*new_value));" + NLine(1);
-            s += GenTemplateString(if_statement_with_braces,
+            s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
                 [&]()->std::string {
                   return "!new_value";
                 },
@@ -1267,7 +966,7 @@ std::string CBodyGeneratorBase::GetClonerString(const std::string& id,
         }
         );
   } else if (type.ToString() == "array") {
-    str += GenTemplateString(ReplaceAll(do_while_array, "##", id),
+    str += GenTemplateString(ReplaceAll(CB_CLONER_ARRAY_BLOCK, "##", id),
         [&]()->std::string {
            return GetSetterString(*type.GetMetaType(),
               "handle->" + id + "[i]", "h->" + id + "[i]");
@@ -1347,15 +1046,7 @@ void CBodyGeneratorBase::GenIncludeHeader(std::ofstream& stream) {
 
 void CBodyGeneratorBase::GenLogTag(std::ofstream& stream,
                                    const std::string& log_tag) {
-  const char format[] =
-      "#ifdef LOG_TAG\n" \
-      "#undef LOG_TAG\n" \
-      "#endif\n" \
-      "\n" \
-      "#define LOG_TAG \"$$\"\n";
-
-  stream << NLine(1);
-  GenTemplate(format, stream,
+  GenTemplate(CB_LOG_TAG, stream,
       [&]()->std::string {
         return log_tag;
       }
@@ -1370,15 +1061,9 @@ void CBodyGeneratorBase::GenInterfaceEnumerations(std::ofstream& stream,
 
 void CBodyGeneratorBase::GenInterfaceDelegateEnumeration(
     std::ofstream& stream, const Interface& inf) {
-  const char enum_format[] = "$$_DELEGATE_$$ = $$,\n";
-  const char format[] =
-      "enum $$_delegate_e {\n" \
-      "$$" \
-      "};\n";
   int count = 1;
 
-  stream << NLine(1);
-  stream << SmartIndent(GenTemplateString(format,
+  stream << SmartIndent(GenTemplateString(CB_DELEGATE_ENUM,
         [&]()->std::string {
           return inf.GetID();
         },
@@ -1388,7 +1073,7 @@ void CBodyGeneratorBase::GenInterfaceDelegateEnumeration(
             if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
               continue;
 
-            str += GenTemplateString(enum_format,
+            str += GenTemplateString(CB_DELEGATE_ENUM_FORMAT,
                 [&]()->std::string {
                   return inf.GetID();
                 },
@@ -1408,16 +1093,7 @@ void CBodyGeneratorBase::GenInterfaceDelegateEnumeration(
 
 void CBodyGeneratorBase::GenInterfaceMethodEnumeration(
     std::ofstream& stream, const Interface& inf) {
-  const char enum_format[] = "$$_METHOD_$$,\n";
-  const char block[] =
-    "enum $$_method_e {\n" \
-    "    $$_METHOD_Result,\n" \
-    "    $$_METHOD_Callback,\n"
-    "$$" \
-    "};\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(GenTemplateString(block,
+  stream << SmartIndent(GenTemplateString(CB_METHOD_ENUM,
         [&]()->std::string {
           return inf.GetID();
         },
@@ -1432,7 +1108,7 @@ void CBodyGeneratorBase::GenInterfaceMethodEnumeration(
           for (auto& i : inf.GetDeclarations().GetDecls()) {
             if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
               continue;
-            str += GenTemplateString(enum_format,
+            str += GenTemplateString(CB_METHOD_ENUM_FORMAT,
                 [&]()->std::string {
                   return inf.GetID();
                 },
diff --git a/idlc/c_gen/c_body_gen_base_cb.h b/idlc/c_gen/c_body_gen_base_cb.h
new file mode 100644 (file)
index 0000000..bb4f46e
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ * 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.
+ */
+
+const char CB_STRUCT_DECL[] =
+R"__c_cb(
+$$struct $$_s {
+    rpc_port_parcelable_t parcelable;$$
+};
+)__c_cb";
+
+const char CB_STRUCT_SERIALIZER[] =
+R"__c_cb(
+static void __##_to(rpc_port_parcel_h parcel, void *data)
+{
+    rpc_port_##_h h = data;
+
+    if (!parcel || !h) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return;
+    }
+$$
+}
+)__c_cb";
+
+const char CB_STRUCT_DESERIALIZER[] =
+R"__c_cb(
+static void __##_from(rpc_port_parcel_h parcel, void *data)
+{
+    rpc_port_##_h h = data;
+
+    if (!parcel || !h) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return;
+    }
+$$
+}
+)__c_cb";
+
+const char CB_STRUCT_CTOR[] =
+R"__c_cb(
+int rpc_port_##_create(rpc_port_##_h *h)
+{
+    struct ##_s *handle;
+
+    if (!h) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+
+    handle = calloc(1, sizeof(struct ##_s));
+    if (!handle) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Out of memory");
+        return -1;
+    }
+
+    handle->parcelable.to = __##_to;
+    handle->parcelable.from = __##_from;
+
+    *h = handle;
+
+    return 0;
+}
+)__c_cb";
+
+const char CB_STRUCT_DTOR[] =
+R"__c_cb(
+int rpc_port_##_destroy(rpc_port_##_h h)
+{
+    if (!h) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+
+$$
+    free(h);
+
+    return 0;
+}
+)__c_cb";
+
+const char CB_STRUCT_SETTER[] =
+R"__c_cb(
+int rpc_port_$$_$$_$$(rpc_port_$$_h h, $$$$)
+{
+    if ($$) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+$$
+    return 0;
+}
+)__c_cb";
+
+const char CB_STRUCT_GETTER[] =
+R"__c_cb(
+int rpc_port_$$_get_$$(rpc_port_$$_h h, $$$$)
+{
+    if (!h || $$) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+$$
+    return 0;
+}
+)__c_cb";
+
+const char CB_STRUCT_ITERATOR[] =
+R"__c_cb(
+int rpc_port_$$_foreach_$$(rpc_port_$$_h h,
+        void (*callback)($$$$, void *user_data), void *user_data)
+{
+    if (!h || !callback) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+$$
+    return 0;
+}
+)__c_cb";
+
+const char CB_STRUCT_CLONER[] =
+R"__c_cb(
+int rpc_port_##_clone(rpc_port_##_h h, rpc_port_##_h *clone)
+{
+    rpc_port_##_h handle = NULL;
+
+    if (!h || !clone) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+
+    rpc_port_##_create(&handle);
+    if (!handle) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to create ## handle");
+        return -1;
+    }
+$$
+    *clone = handle;
+
+    return 0;
+}
+)__c_cb";
+
+const char CB_WRITE_LIST_BLOCK[] =
+R"__c_cb(do {
+    GList *iter = $$;
+    while (iter) {
+        $$value = iter->data;
+
+        iter = g_list_next(iter);
+        if (!value) {
+            dlog_print(DLOG_WARN, LOG_TAG, "Warning: value is NULL");
+            continue;
+        }
+        $$
+    }
+} while (0);
+)__c_cb";
+
+const char CB_WRITE_ARRAY_BLOCK[] =
+R"__c_cb(do {
+    for (int i = 0; i < $$; i++) {
+$$
+    }
+} while (0);
+)__c_cb";
+
+const char CB_READ_LIST_BLOCK[] =
+R"__c_cb(do {
+    int len = 0;
+
+    $$
+    for (int i = 0; i < len; i++) {
+        $$value = NULL;
+
+        $$
+        $$ = g_list_append($$, value);
+    }
+} while (0);
+)__c_cb";
+
+const char CB_READ_ARRAY_BLOCK[] =
+R"__c_cb(do {
+    $$
+
+    h->## = calloc(h->##_size, sizeof(*h->##));
+    if (!h->##) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Out of memory");
+        return;
+    }
+
+    for (int i = 0; i < h->##_size; i++) {
+        $$value = $$;
+
+        $$
+    }
+} while (0);
+)__c_cb";
+
+const char CB_FINALIZE_LIST_BLOCK[] =
+R"__c_cb(do {
+    GList *iter = $$;
+    while (iter) {
+        $$value = iter->data;
+        $$
+        iter = g_list_next(iter);
+    }
+    g_list_free($$);
+} while (0);
+)__c_cb";
+
+const char CB_FINALIZE_ARRAY_BLOCK[] =
+R"__c_cb(do {
+    for (int i = 0; i < $$; i++) {
+        $$
+    }
+    free($$);
+} while (0);
+)__c_cb";
+
+const char CB_SETTER_LIST_BLOCK[] =
+R"__c_cb(do {
+    $$value;
+
+    value = calloc(1, sizeof(*value));
+    $$
+    $$ = g_list_append($$, value);
+} while (0);
+)__c_cb";
+
+const char CB_SETTER_ARRAY_BLOCK[] =
+R"__c_cb(do {
+    h->## = calloc(##_size, sizeof(*##));
+    if (!h->##) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Out of memory");
+        return -1;
+    }
+    h->##_size = ##_size;
+
+    for (int i = 0; i < h->##_size; i++) {
+        $$
+    }
+} while (0);
+)__c_cb";
+
+const char CB_GETTER_ARRAY_BLOCK[] =
+R"__c_cb(do {
+    if (h->##_size == 0) {
+        dlog_print(DLOG_WARN, LOG_TAG, "## is empty");
+        break;
+    }
+
+    *## = calloc(h->##_size, sizeof(*h->##));
+    if (!*##) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Out of memory");
+        return -1;
+    }
+    *##_size = h->##_size;
+
+    for (int i = 0; i < h->##_size; i++) {
+        $$
+    }
+} while (0);
+)__c_cb";
+
+const char CB_ITERATOR_BLOCK[] =
+R"__c_cb(do {
+    GList *iter = $$;
+    while (iter) {
+        $$value = iter->data;
+
+        iter = g_list_next(iter);
+        if (!value) {
+            dlog_print(DLOG_WARN, LOG_TAG, "Warning: value is NULL");
+            continue;
+        }
+
+        callback($$, user_data);
+    }
+} while (0);
+)__c_cb";
+
+const char CB_CLONER_LIST_BLOCK[] =
+R"__c_cb(do {
+    GList *iter = $$;
+    while (iter) {
+        $$new_value;
+        $$value = iter->data;
+
+        if (!value) {
+            dlog_print(DLOG_ERROR, LOG_TAG, "Error: value is NULL");
+            rpc_port_$$_destroy(handle);
+            return -1;
+        }
+
+        $$
+        $$ = g_list_append($$, new_value);
+        iter = g_list_next(iter);
+    }
+} while (0);
+)__c_cb";
+
+const char CB_CLONER_ARRAY_BLOCK[] =
+R"__c_cb(do {
+    if (h->##_size == 0) {
+        dlog_print(DLOG_WARN, LOG_TAG, "## is empty");
+        break;
+    }
+
+    handle->## = calloc(h->##_size, sizeof(*h->##));
+    if (!handle->##) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Out of memory");
+        return -1;
+    }
+    handle->##_size = h->##_size;
+
+    for (int i = 0; i < h->##_size; i++) {
+        $$
+    }
+} while (0);
+)__c_cb";
+
+const char CB_IF_STATEMENT_WITH_BRACES[] =
+R"__c_cb(if ($$) {
+    $$
+}
+)__c_cb";
+
+const char CB_IF_STATEMENT[] =
+R"__c_cb(if ($$)
+    $$
+)__c_cb";
+
+const char CB_DELEGATE_ENUM_FORMAT[] = "\n$$_DELEGATE_$$ = $$,";
+
+const char CB_DELEGATE_ENUM[] =
+R"__c_cb(
+enum $$_delegate_e {$$
+};
+)__c_cb";
+
+const char CB_METHOD_ENUM_FORMAT[] = "\n$$_METHOD_$$,";
+
+const char CB_METHOD_ENUM[] =
+R"__c_cb(
+enum $$_method_e {
+    $$_METHOD_Result,
+    $$_METHOD_Callback,$$
+};
+)__c_cb";
+
+const char CB_LOG_TAG[] =
+R"__c_cb(
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "$$"
+)__c_cb";
index 1204f8f..b7aac13 100644 (file)
 
 #include "idlc/c_gen/c_gen_base.h"
 
+namespace {
+#include "idlc/c_gen/c_gen_base_cb.h"
+}
+
 namespace tidl {
 
 CGeneratorBase::CGeneratorBase(std::shared_ptr<Document> doc)
@@ -221,26 +225,7 @@ std::string CGeneratorBase::Trim(const std::string& str)
 }
 
 void CGeneratorBase::GenLicenseDescription(std::ofstream& stream) {
-  const char license[] =
-      "/*\n" \
-      " * Generated by tidlc $$.\n" \
-      " *\n" \
-      " * Copyright (c) $$ Samsung Electronics Co., Ltd.\n" \
-      " *\n" \
-      " * Licensed under the Apache License, Version 2.0 (the \"License\");\n" \
-      " * you may not use this file except in compliance with the License.\n" \
-      " * You may obtain a copy of the License at\n"  \
-      " *\n" \
-      " * http://www.apache.org/licenses/LICENSE-2.0\n" \
-      " *\n" \
-      " * Unless required by applicable law or agreed to in writing, software\n" \
-      " * distributed under the License is distributed on an \"AS IS\" BASIS,\n" \
-      " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" \
-      " * See the License for the specific language governing permissions and\n" \
-      " * limitations under the License.\n" \
-      " */\n";
-
-  GenTemplate(license, stream,
+  GenTemplate(CB_COPYRIGHT, stream,
       [&]()->std::string {
         return FULLVER;
       },
@@ -254,24 +239,11 @@ void CGeneratorBase::GenLicenseDescription(std::ofstream& stream) {
 
 void CGeneratorBase::GenIncludeDefaultHeaders(std::ofstream& stream,
                                               bool body) {
-  const char header[] =
-      "#include <stdbool.h>\n" \
-      "#include <bundle.h>\n";
-
-  const char body_header[] =
-      "#include <stdio.h>\n" \
-      "#include <string.h>\n" \
-      "#include <stdlib.h>\n" \
-      "#include <glib.h>\n" \
-      "#include <dlog.h>\n" \
-      "#include <rpc-port.h>\n" \
-      "#include <rpc-port-parcel.h>\n";
-
   stream << NLine(1);
   if (body) {
-    stream << std::string(body_header);
+    stream << CB_BODY_HEADER;
   } else {
-    stream << std::string(header);
+    stream << CB_HEADER;
   }
 }
 
diff --git a/idlc/c_gen/c_gen_base_cb.h b/idlc/c_gen/c_gen_base_cb.h
new file mode 100644 (file)
index 0000000..84f2081
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+const char CB_COPYRIGHT[] =
+R"__c_cb(/*
+ * Generated by tidlc $$.
+ *
+ * Copyright (c) $$ Samsung Electronics 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.
+ */
+)__c_cb";
+
+const char CB_HEADER[] =
+R"__c_cb(
+#include <stdbool.h>
+#include <bundle.h>
+)__c_cb";
+
+const char CB_BODY_HEADER[] =
+R"__c_cb(
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <dlog.h>
+#include <rpc-port.h>
+#include <rpc-port-parcel.h>
+)__c_cb";
index 5782eee..1bbe5dd 100644 (file)
 
 #include "idlc/c_gen/c_header_gen_base.h"
 
+namespace {
+#include "idlc/c_gen/c_header_gen_base_cb.h"
+}
+
 namespace tidl {
 
 CHeaderGeneratorBase::CHeaderGeneratorBase(std::shared_ptr<Document> doc)
@@ -31,23 +35,11 @@ void CHeaderGeneratorBase::GenPragmaOnce(std::ofstream& stream) {
 }
 
 void CHeaderGeneratorBase::GenExplicitLinkageOpen(std::ofstream& stream) {
-  const char format[] =
-      "#ifdef __cplusplus\n" \
-      "extern \"C\" {\n" \
-      "#endif\n";
-
-  stream << NLine(1);
-  stream << std::string(format);
+  stream << CB_EXPLICIT_LINKAGE_OPEN;
 }
 
 void CHeaderGeneratorBase::GenExplicitLinkageClose(std::ofstream& stream) {
-  const char format[] =
-      "#ifdef __cplusplus\n" \
-      "}\n" \
-      "#endif\n";
-
-  stream << NLine(1);
-  stream << std::string(format);
+  stream << CB_EXPLICIT_LINKAGE_CLOSE;
 }
 
 void CHeaderGeneratorBase::GenStructures(std::ofstream& stream) {
@@ -90,10 +82,7 @@ void CHeaderGeneratorBase::GenStructure(std::ofstream& stream,
 
 void CHeaderGeneratorBase::GenStructureDeclaration(std::ofstream& stream,
                                                    const Structure& st) {
-  const char format[] = "typedef struct $$_s *rpc_port_$$_h;\n";
-
-  stream << NLine(1);
-  GenTemplate(format, stream,
+  GenTemplate(CB_STRUCT_DECL, stream,
       [&]()->std::string {
         return st.GetID();
       },
@@ -105,10 +94,7 @@ void CHeaderGeneratorBase::GenStructureDeclaration(std::ofstream& stream,
 
 void CHeaderGeneratorBase::GenStructureConstructor(std::ofstream& stream,
                                                    const Structure& st) {
-  const char format[] = "int rpc_port_$$_create(rpc_port_$$_h *h);\n";
-
-  stream << NLine(1);
-  GenTemplate(format, stream,
+  GenTemplate(CB_STRUCT_CTOR, stream,
       [&]()->std::string {
         return st.GetID();
       },
@@ -120,10 +106,7 @@ void CHeaderGeneratorBase::GenStructureConstructor(std::ofstream& stream,
 
 void CHeaderGeneratorBase::GenStructureDestructor(std::ofstream& stream,
                                                   const Structure& st) {
-  const char format[] = "int rpc_port_$$_destroy(rpc_port_$$_h h);\n";
-
-  stream << NLine(1);
-  GenTemplate(format, stream,
+  GenTemplate(CB_STRUCT_DTOR, stream,
       [&]()->std::string {
         return st.GetID();
       },
@@ -135,11 +118,8 @@ void CHeaderGeneratorBase::GenStructureDestructor(std::ofstream& stream,
 
 void CHeaderGeneratorBase::GenStructureSetter(std::ofstream& stream,
                                               const Structure& st) {
-  const char format[] = "int rpc_port_$$_$$_$$(rpc_port_$$_h h, $$$$);\n";
-
   for (auto& i : st.GetElements().GetElms()) {
-    stream << NLine(1);
-    GenTemplate(format, stream,
+    GenTemplate(CB_STRUCT_SETTER, stream,
           [&]()->std::string {
             return st.GetID();
           },
@@ -192,14 +172,11 @@ void CHeaderGeneratorBase::GenStructureSetter(std::ofstream& stream,
 
 void CHeaderGeneratorBase::GenStructureGetter(std::ofstream& stream,
                                               const Structure& st) {
-  const char format[] = "int rpc_port_$$_get_$$(rpc_port_$$_h h, $$$$);\n";
-
   for (auto& i : st.GetElements().GetElms()) {
     if (i->GetType().ToString() == "list")
       continue;
 
-    stream << NLine(1);
-    GenTemplate(format, stream,
+    GenTemplate(CB_STRUCT_GETTER, stream,
         [&]()->std::string {
           return st.GetID();
         },
@@ -235,16 +212,11 @@ void CHeaderGeneratorBase::GenStructureGetter(std::ofstream& stream,
 
 void CHeaderGeneratorBase::GenStructureIterator(std::ofstream& stream,
                                                 const Structure& st) {
-  const char format[] =
-      "int rpc_port_$$_foreach_$$(rpc_port_$$_h h, " \
-      "void (*callback)($$$$, void *user_data), void *user_data);\n";
-
   for (auto& i : st.GetElements().GetElms()) {
     if (i->GetType().ToString() != "list")
       continue;
 
-    stream << NLine(1);
-    GenTemplate(format, stream,
+    GenTemplate(CB_STRUCT_ITERATOR, stream,
         [&]()->std::string {
           return st.GetID();
         },
@@ -272,11 +244,7 @@ void CHeaderGeneratorBase::GenStructureIterator(std::ofstream& stream,
 
 void CHeaderGeneratorBase::GenStructureCloner(std::ofstream& stream,
                                               const Structure& st) {
-  const char format[] =
-      "int rpc_port_$$_clone(rpc_port_$$_h h, rpc_port_$$_h *clone);\n";
-
-  stream << NLine(1);
-  GenTemplate(format, stream,
+  GenTemplate(CB_STRUCT_CLONER, stream,
       [&]()->std::string {
         return st.GetID();
       },
diff --git a/idlc/c_gen/c_header_gen_base_cb.h b/idlc/c_gen/c_header_gen_base_cb.h
new file mode 100644 (file)
index 0000000..40a0560
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+const char CB_EXPLICIT_LINKAGE_OPEN[] =
+R"__c_cb(
+#ifdef __cplusplus
+extern "C" {
+#endif
+)__c_cb";
+
+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[] =
+R"__c_cb(
+int rpc_port_$$_create(rpc_port_$$_h *h);
+)__c_cb";
+
+const char CB_STRUCT_DTOR[] =
+R"__c_cb(
+int rpc_port_$$_destroy(rpc_port_$$_h h);
+)__c_cb";
+
+const char CB_STRUCT_SETTER[] =
+R"__c_cb(
+int rpc_port_$$_$$_$$(rpc_port_$$_h h, $$$$);
+)__c_cb";
+
+const char CB_STRUCT_GETTER[] =
+R"__c_cb(
+int rpc_port_$$_get_$$(rpc_port_$$_h h, $$$$);
+)__c_cb";
+
+const char CB_STRUCT_ITERATOR[] =
+R"__c_cb(
+int rpc_port_$$_foreach_$$(rpc_port_$$_h h,
+        void (*callback)($$$$, void *user_data), void *user_data);
+)__c_cb";
+
+const char CB_STRUCT_CLONER[] =
+R"__c_cb(
+int rpc_port_$$_clone(rpc_port_$$_h h, rpc_port_$$_h *clone);
+)__c_cb";
index a03f4d9..c53b9f0 100644 (file)
 
 #include "idlc/c_gen/c_proxy_body_gen.h"
 
+namespace {
+#include "idlc/c_gen/c_proxy_body_gen_cb.h"
+}
+
 namespace tidl {
 
 CProxyBodyGen::CProxyBodyGen(std::shared_ptr<Document> doc)
@@ -72,17 +76,7 @@ void CProxyBodyGen::GenInterface(std::ofstream& stream, const Interface& inf) {
 
 void CProxyBodyGen::GenInterfaceDeclaration(std::ofstream& stream,
                                             const Interface& inf) {
-  const char block[] =
-      "struct ##_s {\n" \
-      "    char *stub_appid;\n" \
-      "    rpc_port_proxy_h proxy;\n" \
-      "    rpc_port_h port;\n" \
-      "    rpc_port_proxy_##_callback_s callback;\n" \
-      "    void *user_data;\n" \
-      "    GList *delegates;\n" \
-      "};\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(CB_INTERFACE_STRUCT, "##", inf.GetID()));
 }
 
 void CProxyBodyGen::GenInterfaceDelegators(std::ofstream& stream,
@@ -106,80 +100,26 @@ void CProxyBodyGen::GenInterfaceDelegator(std::ofstream& stream,
 
 void CProxyBodyGen::GenInterfaceDelegatorDeclaration(
     std::ofstream& stream, const std::string& id, const Declaration& decl) {
-  const char block[] =
-      "struct ##_s {\n" \
-      "    rpc_port_parcelable_t parcelable;\n" \
-      "    int id;\n" \
-      "    int seq_id;\n" \
-      "    ## callback;\n" \
-      "};\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", id + "_" + decl.GetID()));
+  stream << SmartIndent(ReplaceAll(
+      CB_DELEGATE_STRUCT, "##", id + "_" + decl.GetID()));
 }
 
 void CProxyBodyGen::GenInterfaceDelegatorSerializer(
     std::ofstream& stream, const std::string& id, const Declaration& decl) {
-  const char block[] =
-      "static void __##_to(rpc_port_parcel_h parcel, void *data)\n" \
-      "{\n" \
-      "    struct ##_s *handle = data;\n" \
-      "\n" \
-      "    if (!handle) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return;\n" \
-      "    }\n" \
-      "\n" \
-      "    rpc_port_parcel_write_int32(parcel, handle->id);\n" \
-      "    rpc_port_parcel_write_int32(parcel, handle->seq_id);\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", id + "_" + decl.GetID()));
+  stream << SmartIndent(
+      ReplaceAll(CB_DELEGATE_SERIALIZER, "##", id + "_" + decl.GetID()));
 }
 
 void CProxyBodyGen::GenInterfaceDelegatorDeserializer(
     std::ofstream& stream, const std::string& id, const Declaration& decl) {
-  const char block[] =
-      "static void __##_from(rpc_port_parcel_h parcel, void *data)\n" \
-      "{\n" \
-      "    struct ##_s *handle = data;\n" \
-      "\n" \
-      "    if (!handle) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return;\n" \
-      "    }\n" \
-      "\n" \
-      "    rpc_port_parcel_read_int32(parcel, &handle->id);\n" \
-      "    rpc_port_parcel_read_int32(parcel, &handle->seq_id);\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", id + "_" + decl.GetID()));
+  stream << SmartIndent(
+      ReplaceAll(CB_DELEGATE_DESERIALIZER, "##", id + "_" + decl.GetID()));
 }
 
 void CProxyBodyGen::GenInterfaceDelegatorConstructor(
     std::ofstream& stream, const std::string& id, const Declaration& decl) {
-  const char block[] =
-      "static struct ##_s *__create_##(## callback)\n" \
-      "{\n" \
-      "    struct ##_s *handle;\n" \
-      "    static int seq_num;\n" \
-      "\n" \
-      "    handle = calloc(1, sizeof(struct ##_s));\n" \
-      "    if (!handle) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Out of memory\");\n" \
-      "        return NULL;\n" \
-      "    }\n" \
-      "\n" \
-      "    handle->parcelable.to = __##_to;\n" \
-      "    handle->parcelable.from= __##_from;\n" \
-      "    handle->id = $$_DELEGATE_$$;\n" \
-      "    handle->seq_id = seq_num++;\n" \
-      "    handle->callback = callback;\n" \
-      "\n" \
-      "    return handle;\n" \
-      "}\n";
-  stream << NLine(1);
   stream << SmartIndent(GenTemplateString(
-        ReplaceAll(block, "##", id + "_" + decl.GetID()),
+        ReplaceAll(CB_DELEGATE_CTOR, "##", id + "_" + decl.GetID()),
         [&]()->std::string {
           return id;
         },
@@ -193,29 +133,8 @@ void CProxyBodyGen::GenInterfaceDelegatorConstructor(
 void CProxyBodyGen::GenInterfaceDelegatorInvoker(
     std::ofstream& stream, const std::string& id, const Declaration& decl) {
   const char parcel[] = "$$(parcel, $$);\n";
-  const char block[] =
-      "static void __$$_delegate_$$(GList *list, rpc_port_parcel_h parcel, int seq_id)\n" \
-      "{\n" \
-      "$$" \
-      "    do {\n" \
-      "        struct ##_s *handle;\n" \
-      "        GList *iter;\n" \
-      "\n" \
-      "        iter = list;\n" \
-      "        while (iter) {\n" \
-      "            handle = (struct ##_s *)iter->data;\n" \
-      "            if (handle->seq_id == seq_id) {\n" \
-      "                $$" \
-      "                break;\n" \
-      "            }\n" \
-      "            iter = g_list_next(iter);\n" \
-      "        }\n" \
-      "    } while (0);\n" \
-      "$$" \
-      "}\n";
-  stream << NLine(1);
   stream << SmartIndent(GenTemplateString(
-        ReplaceAll(block, "##", id + "_" + decl.GetID()),
+        ReplaceAll(CB_DELEGATE_INVOKER, "##", id + "_" + decl.GetID()),
         [&]()->std::string {
           return id;
         },
@@ -308,7 +227,6 @@ void CProxyBodyGen::GenInterfaceDelegatorTable(std::ofstream& stream,
   if (cnt == 0)
     return;
 
-  stream << NLine(1);
   stream << SmartIndent(GenTemplateString(block,
         [&]()->std::string {
           return inf.GetID();
@@ -322,24 +240,6 @@ void CProxyBodyGen::GenInterfaceDelegatorTable(std::ofstream& stream,
 
 void CProxyBodyGen::GenInterfaceDelegatorHandler(std::ofstream& stream,
                                                  const Interface& inf) {
-  const char block[] =
-      "static void __##_process_received_event(GList* list, rpc_port_parcel_h parcel)\n" \
-      "{\n" \
-      "$$" \
-      "}\n";
-  const char impl_block[] =
-      "int id;\n" \
-      "int seq_id;\n" \
-      "\n" \
-      "rpc_port_parcel_read_int32(parcel, &id);\n" \
-      "rpc_port_parcel_read_int32(parcel, &seq_id);\n" \
-      "\n" \
-      "if (id > 0 && id < (sizeof(__##_delegate_table) / sizeof(__##_delegate_table[0]))) {\n" \
-      "    if (__##_delegate_table[id])\n" \
-                       "        __##_delegate_table[id](list, parcel, seq_id);\n" \
-           "} else {\n" \
-                 "    dlog_print(DLOG_WARN, LOG_TAG, \"Unknown id(%d)\", id);\n" \
-           "}\n";
   std::string str;
   int cnt = 0;
 
@@ -348,12 +248,13 @@ void CProxyBodyGen::GenInterfaceDelegatorHandler(std::ofstream& stream,
       continue;
     cnt++;
   }
-  stream << NLine(1);
-  stream << SmartIndent(GenTemplateString(ReplaceAll(block, "##", inf.GetID()),
+
+  stream << SmartIndent(GenTemplateString(
+      ReplaceAll(CB_PROCESS_RECEIVED_EVENT, "##", inf.GetID()),
         [&]()->std::string {
           if (cnt == 0)
             return str;
-          return ReplaceAll(impl_block, "##", inf.GetID());
+          return ReplaceAll(CB_PROCESS_RECEIVED_EVENT_IMPL, "##", inf.GetID());
         }
         )
       );
@@ -361,136 +262,36 @@ void CProxyBodyGen::GenInterfaceDelegatorHandler(std::ofstream& stream,
 
 void CProxyBodyGen::GenInterfaceConsumeCommand(std::ofstream& stream,
                                                const Interface& inf) {
-  const char block[] =
-      "static rpc_port_parcel_h __##_consume_command(rpc_port_proxy_##_h h)\n" \
-      "{\n" \
-      "    rpc_port_parcel_h parcel = NULL;\n" \
-      "    int cmd = -1;\n" \
-      "\n" \
-      "    do {\n" \
-      "        rpc_port_parcel_create_from_port(&parcel, h->port);\n" \
-      "        if (!parcel)\n" \
-      "            break;\n" \
-      "\n" \
-      "        rpc_port_parcel_read_int32(parcel, &cmd);\n" \
-      "        if (cmd == ##_METHOD_Result)\n" \
-      "            return parcel;\n" \
-      "\n" \
-      "        __##_process_received_event(h->delegates, parcel);\n" \
-      "        rpc_port_parcel_destroy(parcel);\n" \
-      "        parcel = NULL;\n" \
-      "    } while (true);\n" \
-      "\n" \
-      "    return NULL;\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(CB_CONSUME_COMMAND, "##", inf.GetID()));
 }
 
 void CProxyBodyGen::GenInterfaceOnConnectedEventCB(std::ofstream& stream,
                                                    const Interface& inf) {
-  const char block[] =
-      "static void __##_on_connected(const char *endpoint, const char *port_name, rpc_port_h port, void *data)\n" \
-      "{\n" \
-      "    rpc_port_proxy_##_h handle = data;\n" \
-      "\n" \
-      "    handle->port = port;\n" \
-      "    if (handle->callback.connected)\n" \
-      "        handle->callback.connected(handle, handle->user_data);\n" \
-      "    dlog_print(DLOG_INFO, LOG_TAG, \"[__RPC_PORT__] endpoint(%s), port_name(%s)\", endpoint, port_name);\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(CB_ON_CONNECTED, "##", inf.GetID()));
 }
 
 void CProxyBodyGen::GenInterfaceOnDisconnectedEventCB(std::ofstream& stream,
                                                       const Interface& inf) {
-  const char block[] =
-      "static void __##_on_disconnected(const char *endpoint, const char *port_name, void *data)\n" \
-      "{\n" \
-      "    rpc_port_proxy_##_h handle = data;\n" \
-      "\n" \
-      "    handle->port = NULL;\n" \
-      "    if (handle->callback.disconnected)\n" \
-      "        handle->callback.disconnected(handle, handle->user_data);\n" \
-      "    dlog_print(DLOG_INFO, LOG_TAG, \"[__RPC_PORT__] endpoint(%s), port_name(%s)\", endpoint, port_name);\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(CB_ON_DISCONNECTED, "##", inf.GetID()));
 }
 
 void CProxyBodyGen::GenInterfaceOnRejectedEventCB(std::ofstream& stream,
                                                   const Interface& inf) {
-  const char block[] =
-      "static void __##_on_rejected(const char *endpoint, const char *port_name, void *data)\n" \
-      "{\n" \
-      "    rpc_port_proxy_##_h handle = data;\n" \
-      "\n" \
-      "    handle->port = NULL;\n" \
-      "    if (handle->callback.rejected)\n" \
-      "        handle->callback.rejected(handle, handle->user_data);\n" \
-      "    dlog_print(DLOG_INFO, LOG_TAG, \"[__RPC_PORT__] endpoint(%s), port_name(%s)\", endpoint, port_name);\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(CB_ON_REJECTED, "##", inf.GetID()));
 }
 
 void CProxyBodyGen::GenInterfaceOnReceivedEventCB(std::ofstream& stream,
                                                   const Interface& inf) {
-  const char block[] =
-      "static void __##_on_received(const char *endpoint, const char *port_name, void *data)\n" \
-      "{\n" \
-      "    rpc_port_proxy_##_h handle = data;\n" \
-      "    rpc_port_parcel_h parcel_received;\n" \
-      "    int cmd = -1;\n" \
-      "\n" \
-      "    rpc_port_parcel_create_from_port(&parcel_received, handle->port);\n" \
-      "    rpc_port_parcel_read_int32(parcel_received, &cmd);\n" \
-      "    if (cmd != ##_METHOD_Callback) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid protocol\");\n" \
-      "        rpc_port_parcel_destroy(parcel_received);\n" \
-      "        return;\n" \
-      "    }\n" \
-      "\n" \
-      "    __##_process_received_event(handle->delegates, parcel_received);\n" \
-      "    rpc_port_parcel_destroy(parcel_received);\n" \
-      "    dlog_print(DLOG_INFO, LOG_TAG, \"[__RPC_PORT__] endpoint(%s), port_name(%s)\", endpoint, port_name);\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(CB_ON_RECEIVED, "##", inf.GetID()));
 }
 
 void CProxyBodyGen::GenInterfaceMethods(std::ofstream& stream,
                                         const Interface& inf) {
-  const char block[] =
-      "$$rpc_port_proxy_##_invoke_$$(rpc_port_proxy_##_h h$$)\n" \
-      "{\n" \
-      "    rpc_port_parcel_h parcel;\n" \
-      "$$" \
-      "\n" \
-      "    if (!h$$) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return$$;\n" \
-      "    }\n" \
-      "\n" \
-      "    if (!h->port) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Not connected\");\n" \
-      "        return$$;\n" \
-      "    }\n" \
-      "\n" \
-      "    rpc_port_parcel_create(&parcel);\n" \
-      "    rpc_port_parcel_write_int32(parcel, ##_METHOD_$$);\n" \
-      "$$" \
-      "    rpc_port_parcel_send(parcel, h->port);\n" \
-      "    rpc_port_parcel_destroy(parcel);\n" \
-      "$$" \
-      "}\n";
-
   for (auto& i : inf.GetDeclarations().GetDecls()) {
     if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
       continue;
-    stream << NLine(1);
-    stream << SmartIndent(GenTemplateString(ReplaceAll(block, "##", inf.GetID()),
+    stream << SmartIndent(GenTemplateString(
+        ReplaceAll(CB_INTERFACE_METHODS, "##", inf.GetID()),
           [&]()->std::string {
             return GetReturnTypeString(i->GetType());
           },
@@ -557,158 +358,33 @@ void CProxyBodyGen::GenInterfaceMethods(std::ofstream& stream,
 
 void CProxyBodyGen::GenInterfaceConstructor(std::ofstream& stream,
                                             const Interface& inf) {
-  const char block[] =
-      "static struct ##_s *__create_##(const char *stub_appid, rpc_port_proxy_##_callback_s *callback, void *user_data)\n" \
-      "{\n" \
-      "    struct ##_s *handle;\n" \
-      "\n" \
-      "    handle = calloc(1, sizeof(struct ##_s));\n" \
-      "    if (!handle) {\n " \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Out of memory\");\n" \
-      "        return NULL;\n" \
-      "    }\n" \
-      "\n" \
-      "    handle->stub_appid = strdup(stub_appid);\n" \
-      "    if (!handle->stub_appid) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Out of memory\");\n" \
-      "        free(handle);\n" \
-      "        return NULL;\n" \
-      "    }\n" \
-      "\n" \
-      "    rpc_port_proxy_create(&handle->proxy);\n" \
-      "    if (!handle->proxy) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to create proxy\");\n" \
-      "        free(handle->stub_appid);\n" \
-      "        free(handle);\n" \
-      "        return NULL;\n" \
-      "    }\n" \
-      "\n" \
-      "    handle->callback = *callback;\n" \
-      "    handle->user_data = user_data;\n" \
-      "\n" \
-      "    return handle;\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(CB_INTERFACE_CTOR, "##", inf.GetID()));
 }
 
 void CProxyBodyGen::GenInterfaceDestructor(std::ofstream& stream,
                                            const Interface& inf) {
-  const char block[] =
-      "static void __destroy_##(struct ##_s *h)\n" \
-      "{\n" \
-      "    if (!h)\n" \
-      "        return;\n" \
-      "\n" \
-      "    if (h->delegates)\n" \
-      "        g_list_free_full(h->delegates, free);\n" \
-      "    if (h->proxy)\n" \
-      "        rpc_port_proxy_destroy(h->proxy);\n" \
-      "    if (h->stub_appid)\n" \
-      "        free(h->stub_appid);\n" \
-      "    free(h);\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(CB_INTERFACE_DTOR, "##", inf.GetID()));
 }
 
 void CProxyBodyGen::GenInterfaceConnect(std::ofstream& stream,
                                         const Interface& inf) {
-  const char block[] =
-      "int rpc_port_proxy_##_connect(const char *stub_appid, rpc_port_proxy_##_callback_s *callback, void *user_data, rpc_port_proxy_##_h *h)\n" \
-      "{\n" \
-      "    struct ##_s *handle;\n" \
-      "    int r;\n" \
-      "\n" \
-      "    if (!stub_appid || !callback || !h) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    handle = __create_##(stub_appid, callback, user_data);\n" \
-      "    if (!handle)\n" \
-      "        return -1;\n" \
-      "\n"  \
-      "    r = rpc_port_proxy_add_connected_event_cb(handle->proxy, __##_on_connected, handle);\n" \
-      "    if (r != 0) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to add connected event cb. err = %d\", r);\n" \
-      "        __destroy_##(handle);\n" \
-      "        return r;\n" \
-      "    }\n" \
-      "\n" \
-      "    r = rpc_port_proxy_add_disconnected_event_cb(handle->proxy, __##_on_disconnected, handle);\n" \
-      "    if (r != 0) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to add disconnected event cb. err = %d\", r);\n" \
-      "        __destroy_##(handle);\n" \
-      "        return r;\n" \
-      "    }\n" \
-      "\n" \
-      "    r = rpc_port_proxy_add_rejected_event_cb(handle->proxy, __##_on_rejected, handle);\n" \
-      "    if (r != 0) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to add rejected event cb. err = %d\", r);\n" \
-      "        __destroy_##(handle);\n" \
-      "        return r;\n" \
-      "    }\n" \
-      "\n" \
-      "    r = rpc_port_proxy_add_received_event_cb(handle->proxy, __##_on_received, handle);\n" \
-      "    if (r != 0) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to add received event cb. err = %d\", r);\n" \
-      "        __destroy_##(handle);\n" \
-      "        return r;\n" \
-      "    }\n" \
-      "\n" \
-      "    r = rpc_port_proxy_connect(handle->proxy, stub_appid, \"##\");\n" \
-      "    if (r != 0) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to connect ##(%s)\", stub_appid);\n" \
-      "        __destroy_##(handle);\n" \
-      "        return r;\n" \
-      "    }\n" \
-      "\n" \
-      "    *h = handle;\n" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(CB_INTERFACE_CONNECT, "##", inf.GetID()));
 }
 
 void CProxyBodyGen::GenInterfaceDisconnect(std::ofstream& stream,
                                            const Interface& inf) {
-  const char block[] =
-      "int rpc_port_proxy_##_disconnect(rpc_port_proxy_##_h h)\n" \
-      "{\n" \
-      "    if (!h) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    __destroy_##(h);\n" \
-      "    return 0;\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(CB_INTERFACE_DISCONNECT, "##", inf.GetID()));
 }
 
 std::string CProxyBodyGen::GetMethodWriteString(const Interface& inf,
                                                 const Declaration& decl) {
   const char setter[] = "$$($$, $$);\n";
-  const char delegate_block[] =
-      "do {\n" \
-      "    struct ##_s *handle;\n" \
-      "\n" \
-      "    handle = __create_##($$);\n" \
-      "    if (!handle)\n" \
-      "        break;\n" \
-      "\n" \
-      "    rpc_port_parcel_write(parcel, &handle->parcelable, handle);\n" \
-      "    h->delegates = g_list_append(h->delegates, handle);\n" \
-      "} while (0);\n";
   std::string str;
   for (auto& p : decl.GetParameters().GetParams()) {
     if (p->GetParameterType().GetDirection() == ParameterType::Direction::OUT)
       continue;
     if (TypeIsDelegator(inf, p->GetParameterType().GetBaseType())) {
-      str += GenTemplateString(ReplaceAll(delegate_block, "##",
+      str += GenTemplateString(ReplaceAll(CB_DELEGATE_BLOCK, "##",
           inf.GetID() + "_" + p->GetParameterType().GetBaseType().ToString()),
           [&]()->std::string {
             return p->GetID();
@@ -726,8 +402,13 @@ std::string CProxyBodyGen::GetMethodWriteString(const Interface& inf,
           [&]()->std::string {
             if (p->GetParameterType().GetBaseType().IsUserDefinedType() ||
                 p->GetParameterType().GetBaseType().ToString() == "list" ||
-                p->GetParameterType().GetBaseType().ToString() == "array")
-              return "&" + p->GetID() + "->parcelable, " + p->GetID();
+                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();
+            }
             return p->GetID();
           }
           );
@@ -739,24 +420,10 @@ std::string CProxyBodyGen::GetMethodWriteString(const Interface& inf,
 std::string CProxyBodyGen::GetMethodReadString(const Interface& inf,
                                                const Declaration& decl) {
   const char setter[] = "$$($$, $$);\n";
-  const char receive_block[] =
-      "do {\n" \
-      "    rpc_port_parcel_h parcel_received;\n" \
-      "$$"
-      "\n" \
-      "    parcel_received = __$$_consume_command(h);\n" \
-      "    if (!parcel_received) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid protocol\");\n" \
-      "        break;\n" \
-      "    }\n" \
-      "\n" \
-      "$$" \
-      "    rpc_port_parcel_destroy(parcel_received);\n" \
-      "} while (0);\n";
   std::string str;
   if (decl.GetMethodType() != Declaration::MethodType::SYNC)
     return str;
-  str += GenTemplateString(receive_block,
+  str += GenTemplateString(CB_RECEIVE_BLOCK,
       [&]()->std::string {
         std::string s;
         for (auto& p : decl.GetParameters().GetParams()) {
diff --git a/idlc/c_gen/c_proxy_body_gen_cb.h b/idlc/c_gen/c_proxy_body_gen_cb.h
new file mode 100644 (file)
index 0000000..1abf199
--- /dev/null
@@ -0,0 +1,404 @@
+/*
+ * 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.
+ */
+
+const char CB_INTERFACE_STRUCT[] =
+R"__c_cb(
+struct ##_s {
+    char *stub_appid;
+    rpc_port_proxy_h proxy;
+    rpc_port_h port;
+    rpc_port_proxy_##_callback_s callback;
+    void *user_data;
+    GList *delegates;
+};
+)__c_cb";
+
+const char CB_DELEGATE_STRUCT[] =
+R"__c_cb(
+struct ##_s {
+    rpc_port_parcelable_t parcelable;
+    int id;
+    int seq_id;
+    ## callback;
+};
+)__c_cb";
+
+const char CB_DELEGATE_SERIALIZER[] =
+R"__c_cb(
+static void __##_to(rpc_port_parcel_h parcel, void *data)
+{
+    struct ##_s *handle = data;
+
+    if (!handle) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return;
+    }
+
+    rpc_port_parcel_write_int32(parcel, handle->id);
+    rpc_port_parcel_write_int32(parcel, handle->seq_id);
+}
+)__c_cb";
+
+const char CB_DELEGATE_DESERIALIZER[] =
+R"__c_cb(
+static void __##_from(rpc_port_parcel_h parcel, void *data)
+{
+    struct ##_s *handle = data;
+
+    if (!handle) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return;
+    }
+
+    rpc_port_parcel_read_int32(parcel, &handle->id);
+    rpc_port_parcel_read_int32(parcel, &handle->seq_id);
+}
+)__c_cb";
+
+const char CB_DELEGATE_CTOR[] =
+R"__c_cb(
+static struct ##_s *__create_##(## callback)
+{
+    struct ##_s *handle;
+    static int seq_num;
+
+    handle = calloc(1, sizeof(struct ##_s));
+    if (!handle) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Out of memory");
+        return NULL;
+    }
+
+    handle->parcelable.to = __##_to;
+    handle->parcelable.from= __##_from;
+    handle->id = $$_DELEGATE_$$;
+    handle->seq_id = seq_num++;
+    handle->callback = callback;
+
+    return handle;
+}
+)__c_cb";
+
+const char CB_DELEGATE_INVOKER[] =
+R"__c_cb(
+static void __$$_delegate_$$(GList *list, rpc_port_parcel_h parcel, int seq_id)
+{
+$$
+    do {
+        struct ##_s *handle;
+        GList *iter;
+
+        iter = list;
+        while (iter) {
+            handle = (struct ##_s *)iter->data;
+            if (handle->seq_id == seq_id) {
+                $$
+                break;
+            }
+            iter = g_list_next(iter);
+        }
+    } while (0);
+$$
+}
+)__c_cb";
+
+const char CB_PROCESS_RECEIVED_EVENT[] =
+R"__c_cb(
+static void __##_process_received_event(GList* list, rpc_port_parcel_h parcel)
+{
+$$
+}
+)__c_cb";
+
+const char CB_PROCESS_RECEIVED_EVENT_IMPL[] =
+R"__c_cb(
+int id;
+int seq_id;
+
+rpc_port_parcel_read_int32(parcel, &id);
+rpc_port_parcel_read_int32(parcel, &seq_id);
+
+if (id > 0 && id < (sizeof(__##_delegate_table) / sizeof(__##_delegate_table[0]))) {
+    if (__##_delegate_table[id])
+        __##_delegate_table[id](list, parcel, seq_id);
+} else {
+    dlog_print(DLOG_WARN, LOG_TAG, "Unknown id(%d)", id);
+}
+)__c_cb";
+
+const char CB_CONSUME_COMMAND[] =
+R"__c_cb(
+static rpc_port_parcel_h __##_consume_command(rpc_port_proxy_##_h h)
+{
+    rpc_port_parcel_h parcel = NULL;
+    int cmd = -1;
+
+    do {
+        rpc_port_parcel_create_from_port(&parcel, h->port);
+        if (!parcel)
+            break;
+
+        rpc_port_parcel_read_int32(parcel, &cmd);
+        if (cmd == ##_METHOD_Result)
+            return parcel;
+
+        __##_process_received_event(h->delegates, parcel);
+        rpc_port_parcel_destroy(parcel);
+        parcel = NULL;
+    } while (true);
+
+    return NULL;
+}
+)__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)
+{
+    rpc_port_proxy_##_h handle = data;
+
+    handle->port = port;
+    if (handle->callback.connected)
+        handle->callback.connected(handle, handle->user_data);
+    dlog_print(DLOG_INFO, LOG_TAG, "[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
+}
+)__c_cb";
+
+const char CB_ON_DISCONNECTED[] =
+R"__c_cb(
+static void __##_on_disconnected(const char *endpoint, const char *port_name, void *data)
+{
+    rpc_port_proxy_##_h handle = data;
+
+    handle->port = NULL;
+    if (handle->callback.disconnected)
+        handle->callback.disconnected(handle, handle->user_data);
+    dlog_print(DLOG_INFO, LOG_TAG, "[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
+}
+)__c_cb";
+
+const char CB_ON_REJECTED[] =
+R"__c_cb(
+static void __##_on_rejected(const char *endpoint, const char *port_name, void *data)
+{
+    rpc_port_proxy_##_h handle = data;
+
+    handle->port = NULL;
+    if (handle->callback.rejected)
+        handle->callback.rejected(handle, handle->user_data);
+    dlog_print(DLOG_INFO, LOG_TAG, "[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
+}
+)__c_cb";
+
+const char CB_ON_RECEIVED[] =
+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;
+    int cmd = -1;
+
+    rpc_port_parcel_create_from_port(&parcel_received, handle->port);
+    rpc_port_parcel_read_int32(parcel_received, &cmd);
+    if (cmd != ##_METHOD_Callback) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid protocol");
+        rpc_port_parcel_destroy(parcel_received);
+        return;
+    }
+
+    __##_process_received_event(handle->delegates, parcel_received);
+    rpc_port_parcel_destroy(parcel_received);
+    dlog_print(DLOG_INFO, LOG_TAG, "[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
+}
+)__c_cb";
+
+const char CB_INTERFACE_METHODS[] =
+R"__c_cb(
+$$rpc_port_proxy_##_invoke_$$(rpc_port_proxy_##_h h$$)
+{
+    rpc_port_parcel_h parcel;
+$$
+
+    if (!h$$) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return$$;
+    }
+
+    if (!h->port) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Not connected");
+        return$$;
+    }
+
+    rpc_port_parcel_create(&parcel);
+    rpc_port_parcel_write_int32(parcel, ##_METHOD_$$);
+$$
+    rpc_port_parcel_send(parcel, h->port);
+    rpc_port_parcel_destroy(parcel);
+$$
+}
+)__c_cb";
+
+const char CB_INTERFACE_CTOR[] =
+R"__c_cb(
+static struct ##_s *__create_##(const char *stub_appid, rpc_port_proxy_##_callback_s *callback, void *user_data)
+{
+    struct ##_s *handle;
+
+    handle = calloc(1, sizeof(struct ##_s));
+    if (!handle) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Out of memory");
+        return NULL;
+    }
+
+    handle->stub_appid = strdup(stub_appid);
+    if (!handle->stub_appid) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Out of memory");
+        free(handle);
+        return NULL;
+    }
+
+    rpc_port_proxy_create(&handle->proxy);
+    if (!handle->proxy) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to create proxy");
+        free(handle->stub_appid);
+        free(handle);
+        return NULL;
+    }
+
+    handle->callback = *callback;
+    handle->user_data = user_data;
+
+    return handle;
+}
+)__c_cb";
+
+const char CB_INTERFACE_DTOR[] =
+R"__c_cb(
+static void __destroy_##(struct ##_s *h)
+{
+    if (!h)
+        return;
+
+    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);
+    free(h);
+}
+)__c_cb";
+
+const char CB_INTERFACE_CONNECT[] =
+R"__c_cb(
+int rpc_port_proxy_##_connect(const char *stub_appid, rpc_port_proxy_##_callback_s *callback, void *user_data, rpc_port_proxy_##_h *h)
+{
+    struct ##_s *handle;
+    int r;
+
+    if (!stub_appid || !callback || !h) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+
+    handle = __create_##(stub_appid, callback, user_data);
+    if (!handle)
+        return -1;
+
+    r = rpc_port_proxy_add_connected_event_cb(handle->proxy, __##_on_connected, handle);
+    if (r != 0) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to add connected event cb. err = %d", r);
+        __destroy_##(handle);
+        return r;
+    }
+
+    r = rpc_port_proxy_add_disconnected_event_cb(handle->proxy, __##_on_disconnected, handle);
+    if (r != 0) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to add disconnected event cb. err = %d", r);
+        __destroy_##(handle);
+        return r;
+    }
+
+    r = rpc_port_proxy_add_rejected_event_cb(handle->proxy, __##_on_rejected, handle);
+    if (r != 0) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to add rejected event cb. err = %d", r);
+        __destroy_##(handle);
+        return r;
+    }
+
+    r = rpc_port_proxy_add_received_event_cb(handle->proxy, __##_on_received, handle);
+    if (r != 0) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to add received event cb. err = %d", r);
+        __destroy_##(handle);
+        return r;
+    }
+
+    r = rpc_port_proxy_connect(handle->proxy, stub_appid, "##");
+    if (r != 0) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to connect ##(%s)", stub_appid);
+        __destroy_##(handle);
+        return r;
+    }
+
+    *h = handle;
+
+    return 0;
+}
+)__c_cb";
+
+const char CB_INTERFACE_DISCONNECT[] =
+R"__c_cb(
+int rpc_port_proxy_##_disconnect(rpc_port_proxy_##_h h)
+{
+    if (!h) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+
+    __destroy_##(h);
+    return 0;
+}
+)__c_cb";
+
+const char CB_DELEGATE_BLOCK[] =
+R"__c_cb(
+do {
+    struct ##_s *handle;
+
+    handle = __create_##($$);
+    if (!handle)
+        break;
+
+    rpc_port_parcel_write(parcel, &handle->parcelable, handle);
+    h->delegates = g_list_append(h->delegates, handle);
+} while (0);
+)__c_cb";
+
+const char CB_RECEIVE_BLOCK[] =
+R"__c_cb(
+do {
+    rpc_port_parcel_h parcel_received;
+$$
+
+    parcel_received = __$$_consume_command(h);
+    if (!parcel_received) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid protocol");
+        break;
+    }
+
+$$
+    rpc_port_parcel_destroy(parcel_received);
+} while (0);
+)__c_cb";
\ No newline at end of file
index 3ab73ab..caa7eb8 100644 (file)
 
 #include "idlc/c_gen/c_proxy_header_gen.h"
 
+namespace {
+#include "idlc/c_gen/c_proxy_header_gen_cb.h"
+}
+
 namespace tidl {
 
 CProxyHeaderGen::CProxyHeaderGen(std::shared_ptr<Document> doc)
@@ -65,9 +69,7 @@ void CProxyHeaderGen::GenInterfaceDelegators(std::ofstream& stream,
 void CProxyHeaderGen::GenInterfaceDelegator(std::ofstream& stream,
                                             const std::string& id,
                                             const Declaration& decl) {
-  const char format[] = "typedef $$(*$$)($$);\n";
-  stream << NLine(1);
-  stream << GenTemplateString(format,
+  stream << GenTemplateString(CB_INTERFACE_DELEGATOR,
       [&]()->std::string {
         return GetReturnTypeString(decl.GetType());
       },
@@ -91,27 +93,16 @@ void CProxyHeaderGen::GenInterfaceDelegator(std::ofstream& stream,
 
 void CProxyHeaderGen::GenInterfaceDeclaration(std::ofstream& stream,
                                               const Interface& inf) {
-  const char format[] =
-      "typedef struct ##_s *rpc_port_proxy_##_h;\n" \
-      "\n" \
-      "typedef struct {\n" \
-      "    void (*connected)(rpc_port_proxy_##_h h, void *user_data);\n" \
-      "    void (*disconnected)(rpc_port_proxy_##_h h, void *user_data);\n" \
-      "    void (*rejected)(rpc_port_proxy_##_h h, void *user_data);\n" \
-      "} rpc_port_proxy_##_callback_s;\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(format, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(CB_INTERFACE_DECL, "##", inf.GetID()));
 }
 
 void CProxyHeaderGen::GenInterfaceMethods(std::ofstream& stream,
                                           const Interface& inf) {
-  const char format[] =
-      "$$rpc_port_proxy_##_invoke_$$(rpc_port_proxy_##_h h$$);\n";
   for (auto& i : inf.GetDeclarations().GetDecls()) {
     if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
       continue;
-    stream << NLine(1);
-    stream << GenTemplateString(ReplaceAll(format, "##", inf.GetID()),
+    stream << GenTemplateString(
+        ReplaceAll(CB_INTERFACE_METHODS, "##", inf.GetID()),
         [&]()->std::string {
           return GetReturnTypeString(i->GetType());
         },
@@ -139,20 +130,12 @@ void CProxyHeaderGen::GenInterfaceMethods(std::ofstream& stream,
 
 void CProxyHeaderGen::GenInterfaceConnect(std::ofstream& stream,
                                           const Interface& inf) {
-  const char format[] =
-      "int rpc_port_proxy_##_connect(const char *stub_appid, " \
-      "rpc_port_proxy_##_callback_s *callback, void *user_data, " \
-      "rpc_port_proxy_##_h *h);\n";
-  stream << NLine(1);
-  stream << ReplaceAll(format, "##", inf.GetID());
+  stream << ReplaceAll(CB_INTERFACE_CONNECT, "##", inf.GetID());
 }
 
 void CProxyHeaderGen::GenInterfaceDisconnect(std::ofstream& stream,
                                              const Interface& inf) {
-  const char format[] =
-      "int rpc_port_proxy_##_disconnect(rpc_port_proxy_##_h h);\n";
-  stream << NLine(1);
-  stream << ReplaceAll(format, "##", inf.GetID());
+  stream << ReplaceAll(CB_INTERFACE_DISCONNECT, "##", inf.GetID());
 }
 
 }  // namespace tidl
diff --git a/idlc/c_gen/c_proxy_header_gen_cb.h b/idlc/c_gen/c_proxy_header_gen_cb.h
new file mode 100644 (file)
index 0000000..8569328
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+const char CB_INTERFACE_DECL[] =
+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;
+)__c_cb";
+
+const char CB_INTERFACE_CONNECT[] =
+R"__c_cb(
+int rpc_port_proxy_##_connect(const char *stub_appid,
+        rpc_port_proxy_##_callback_s *callback, void *user_data,
+        rpc_port_proxy_##_h *h);
+)__c_cb";
+
+const char CB_INTERFACE_DISCONNECT[] =
+R"__c_cb(
+int rpc_port_proxy_##_disconnect(rpc_port_proxy_##_h h);
+)__c_cb";
+
+const char CB_INTERFACE_METHODS[] =
+R"__c_cb(
+$$rpc_port_proxy_##_invoke_$$(rpc_port_proxy_##_h h$$);
+)__c_cb";
+
+const char CB_INTERFACE_DELEGATOR[] =
+R"__c_cb(
+typedef $$(*$$)($$);
+)__c_cb";
index 239374a..480dbf0 100644 (file)
 
 #include "idlc/c_gen/c_stub_body_gen.h"
 
+namespace {
+#include "idlc/c_gen/c_stub_body_gen_cb.h"
+}
+
 namespace tidl {
 
 CStubBodyGen::CStubBodyGen(std::shared_ptr<Document> doc)
@@ -61,21 +65,11 @@ void CStubBodyGen::GenInterface(std::ofstream& stream, const Interface& inf) {
 
 void CStubBodyGen::GenInterfaceMethods(std::ofstream& stream,
                                        const Interface& inf) {
-  const char block[] =
-      "static int __$$_method_$$(rpc_port_h port, rpc_port_parcel_h parcel, void *data)\n" \
-      "{\n" \
-      "    rpc_port_stub_$$_context_h context = data;\n" \
-      "$$" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-
   for (auto& i : inf.GetDeclarations().GetDecls()) {
     if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
       continue;
 
-    stream << NLine(1);
-    stream << SmartIndent(GenTemplateString(block,
+    stream << SmartIndent(GenTemplateString(CB_INTERFACE_METHOD,
           [&]()->std::string {
             return inf.GetID();
           },
@@ -95,18 +89,13 @@ void CStubBodyGen::GenInterfaceMethods(std::ofstream& stream,
 
 void CStubBodyGen::GenInterfaceMethodTable(std::ofstream& stream,
                                            const Interface& inf) {
-  const char block[] =
-      "static stub_method __$$_method_table[] = {\n" \
-      "$$" \
-      "};\n";
-  const char method_format[] = "[$$] = $$,\n";
   std::string str;
   int cnt = 0;
 
   for (auto& i : inf.GetDeclarations().GetDecls()) {
     if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
       continue;
-    str += GenTemplateString(method_format,
+    str += GenTemplateString(CB_INTERFACE_METHOD_FORMAT,
         [&]()->std::string {
           return inf.GetID() + "_METHOD_" + i->GetID();
         },
@@ -121,7 +110,7 @@ void CStubBodyGen::GenInterfaceMethodTable(std::ofstream& stream,
     return;
 
   stream << NLine(1);
-  stream << SmartIndent(GenTemplateString(block,
+  stream << SmartIndent(GenTemplateString(CB_INTERFACE_METHOD_TABLE,
         [&]()->std::string {
           return inf.GetID();
         },
@@ -134,195 +123,35 @@ void CStubBodyGen::GenInterfaceMethodTable(std::ofstream& stream,
 
 void CStubBodyGen::GenInterfaceOnConnectedEventCB(std::ofstream& stream,
                                                   const Interface& inf) {
-  const char block[] =
-      "static void __##_on_connected(const char *sender, const char *instance, void *data)\n" \
-      "{\n" \
-      "    rpc_port_stub_##_context_h context;\n" \
-      "\n" \
-      "    dlog_print(DLOG_INFO, LOG_TAG, \"[__RPC_PORT__] sender(%s), instance(%s)\", sender, instance);\n" \
-      "    context = __create_##_context(sender, instance);\n" \
-      "    if (!context)\n" \
-      "        return;\n" \
-      "\n" \
-      "    if (context->callback.create)\n" \
-      "        context->callback.create(context, context->user_data);\n" \
-      "    __##_contexts = g_list_append(__##_contexts, context);\n" \
-      "}\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(
+      ReplaceAll(CB_INTERFACE_ON_CONNECTED, "##", inf.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceOnDisconnectedEventCB(std::ofstream& stream,
                                                      const Interface& inf) {
-  const char block[] =
-      "static void __##_on_disconnected(const char *sender, const char *instance, void *data)\n" \
-      "{\n" \
-      "    rpc_port_stub_##_context_h context;\n" \
-      "\n" \
-           "    dlog_print(DLOG_INFO, LOG_TAG, \"[__RPC_PORT__] sender(%s), instance(%s)\", sender, instance);\n" \
-           "    context = __find_##_context(instance);\n" \
-           "    if (!context)\n" \
-                 "        return;\n" \
-      "\n" \
-           "    if (context->callback.terminate)\n" \
-                 "        context->callback.terminate(context, context->user_data);\n" \
-           "    __##_contexts = g_list_remove(__##_contexts, context);\n" \
-           "    __destroy_##_context(context);\n" \
-      "}\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(
+      ReplaceAll(CB_INTERFACE_ON_DISCONNECTED, "##", inf.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceOnReceivedEventCB(std::ofstream& stream,
                                                  const Interface& inf) {
-  const char block[] =
-      "static int __##_on_received(const char *sender, const char *instance, rpc_port_h port, void *data)\n" \
-      "{\n" \
-      "    rpc_port_stub_##_context_h context;\n" \
-      "    rpc_port_parcel_h parcel;\n" \
-      "    int cmd = -1;\n" \
-      "    int r;\n" \
-      "\n" \
-      "    dlog_print(DLOG_INFO, LOG_TAG, \"[__RPC_PORT__] sender(%s), instance(%s)\", sender, instance);\n" \
-      "    context = __find_##_context(instance);\n" \
-      "    if (!context) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to find ## context(%s)\", instance);\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "    context->port = port;\n" \
-      "\n" \
-      "    r = rpc_port_parcel_create_from_port(&parcel, port);\n" \
-      "    if (r != 0) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to create parcel from port\");\n" \
-      "        return r;\n" \
-      "    }\n" \
-      "\n" \
-      "    rpc_port_parcel_read_int32(parcel, &cmd);\n" \
-      "    if (cmd > 1 && cmd < (sizeof(__##_method_table) / sizeof(__##_method_table[0]))) {\n" \
-      "         if (__##_method_table[cmd])\n"
-      "             r = __##_method_table[cmd](port, parcel, context);\n" \
-      "    } else {\n" \
-      "         dlog_print(DLOG_ERROR, LOG_TAG, \"Unknown Command(%d)\", cmd);\n" \
-      "         r = -1;\n" \
-      "    }\n"
-      "\n" \
-      "    rpc_port_parcel_destroy(parcel);\n" \
-      "\n" \
-      "    return r;\n" \
-      "}\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(
+      ReplaceAll(CB_INTERFACE_ON_RECEIVED, "##", inf.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceRegister(std::ofstream& stream,
                                         const Interface& inf) {
-  const char block[] =
-      "int rpc_port_stub_##_register(rpc_port_stub_##_callback_s *callback, void *user_data)\n" \
-      "{\n" \
-      "    int r;\n" \
-      "\n" \
-      "    if (__##_stub) {\n" \
-      "        dlog_print(DLOG_WARN, LOG_TAG, \"Already exists\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    if (!callback) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    __##_callback = *callback;\n" \
-      "    __##_user_data = user_data;\n" \
-      "    r = rpc_port_stub_create(&__##_stub, \"##\");\n" \
-      "    if (r != 0) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to create stub handle\");\n" \
-      "        return r;\n" \
-      "    }\n" \
-      "\n" \
-      "    r = rpc_port_stub_add_received_event_cb(__##_stub, __##_on_received, NULL);\n" \
-      "    if (r != 0) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to add received event callback\");\n" \
-      "        rpc_port_stub_destroy(__##_stub);\n" \
-      "         __##_stub = NULL;\n" \
-      "        return r;\n" \
-      "    }\n" \
-      "\n" \
-      "    r = rpc_port_stub_add_connected_event_cb(__##_stub, __##_on_connected, NULL);\n" \
-      "    if (r != 0) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to add connected event callback\");\n" \
-      "        rpc_port_stub_destroy(__##_stub);\n" \
-      "        __##_stub = NULL;\n" \
-      "        return r;\n" \
-      "    }\n" \
-      "\n" \
-      "    r = rpc_port_stub_add_disconnected_event_cb(__##_stub, __##_on_disconnected, NULL);\n" \
-      "    if (r != 0) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to add disconnected event callback\");\n" \
-      "        rpc_port_stub_destroy(__##_stub);\n" \
-      "        __##_stub = NULL;\n" \
-      "        return r;\n" \
-      "    }\n" \
-      "\n" \
-      "    r = __##_add_privileges();\n" \
-      "    if (r != 0) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to add privileges\");\n" \
-      "        rpc_port_stub_destroy(__##_stub);\n" \
-      "        __##_stub = NULL;\n" \
-      "        return r;\n" \
-      "    }\n" \
-      "\n" \
-      "    r = rpc_port_stub_listen(__##_stub);\n" \
-      "    if (r != 0) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to listen stub\");\n" \
-      "        rpc_port_stub_destroy(__##_stub);\n" \
-      "        __##_stub = NULL;\n" \
-      "        return r;\n" \
-      "    }\n" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(CB_INTERFACE_REGISTER, "##", inf.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceUnregister(std::ofstream& stream,
                                           const Interface& inf) {
-  const char block[] =
-      "int rpc_port_stub_##_unregister(void)\n" \
-      "{\n" \
-      "    int r;\n" \
-      "\n" \
-      "    if (!__##_stub)\n" \
-      "        return -1;\n" \
-      "\n" \
-      "    if (__##_contexts) {\n" \
-      "        g_list_free_full(__##_contexts, __destroy_##_context);\n" \
-      "        __##_contexts = NULL;\n" \
-      "    }\n" \
-      "\n" \
-      "    r = rpc_port_stub_destroy(__##_stub);\n" \
-      "    __##_stub = NULL;\n" \
-      "    return r;\n"
-      "}\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(CB_INTERFACE_UNREGISTER, "##", inf.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceGlobalVariables(std::ofstream& stream,
                                                const Interface& inf) {
-  const char format[] =
-      "static rpc_port_stub_h __##_stub;\n" \
-      "static rpc_port_stub_##_callback_s __##_callback;\n" \
-      "static void *__##_user_data;\n" \
-      "static GList *__##_contexts;\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(format, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(CB_GLOBALS, "##", inf.GetID()));
 }
 
 std::string CStubBodyGen::GetMethodString(const Interface& inf,
@@ -481,15 +310,9 @@ std::string CStubBodyGen::GetMethodString(const Interface& inf,
 
 std::string CStubBodyGen::GetAddPrivilegeString(const std::string& id,
                                                 const Attribute& attr) {
-  const char format[] =
-      "r = $$;\n" \
-      "if (r != 0) {\n" \
-      "    dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to add privilege($$)\");\n" \
-      "    return r;\n" \
-      "}\n";
   std::string str;
 
-  str += GenTemplateString(format,
+  str += GenTemplateString(CB_INTERFACE_PRIVILEGE_BLOCK,
       [&]()->std::string {
         return "rpc_port_stub_add_privilege(__" + id +
             "_stub, \"" + attr.GetValue() + "\")";
@@ -526,15 +349,7 @@ void CStubBodyGen::GenInterfaceDelegator(std::ofstream& stream,
 void CStubBodyGen::GenInterfaceDelegatorDeclaration(std::ofstream& stream,
                                                     const std::string& id,
                                                     const Declaration& decl) {
-  const char block[] =
-      "struct $$_s {\n" \
-      "    rpc_port_parcelable_t parcelable;\n" \
-      "    rpc_port_h port;\n" \
-      "    int id;\n" \
-      "    int seq_id;\n" \
-      "};\n";
-  stream << NLine(1);
-  stream << SmartIndent(GenTemplateString(block,
+  stream << SmartIndent(GenTemplateString(CB_INTERFACE_DELEGATOR_DECL,
         [&]()->std::string {
           return id + "_" + decl.GetID();
         }
@@ -545,36 +360,8 @@ void CStubBodyGen::GenInterfaceDelegatorDeclaration(std::ofstream& stream,
 void CStubBodyGen::GenInterfaceDelegatorConstructor(std::ofstream& stream,
                                                     const std::string& id,
                                                     const Declaration& decl) {
-  const char block[] =
-      "int rpc_port_##_create(rpc_port_##_h *h)\n" \
-      "{\n" \
-      "    struct ##_s *handle;\n" \
-      "    static int seq_num;\n" \
-      "\n" \
-      "    if (!h) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    handle = calloc(1, sizeof(struct ##_s));\n" \
-      "    if (!handle) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Out of memory\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    handle->parcelable.to = __##_to;\n" \
-      "    handle->parcelable.from = __##_from;\n" \
-      "    handle->id = $$_DELEGATE_$$;\n" \
-      "    handle->seq_id = seq_num++;\n" \
-      "\n" \
-      "    *h = handle;\n" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-
-  stream << NLine(1);
   stream << SmartIndent(GenTemplateString(
-        ReplaceAll(block, "##", id + "_" + decl.GetID()),
+        ReplaceAll(CB_INTERFACE_DELEGATOR_CTOR, "##", id + "_" + decl.GetID()),
         [&]()->std::string {
           return id;
         },
@@ -588,134 +375,36 @@ void CStubBodyGen::GenInterfaceDelegatorConstructor(std::ofstream& stream,
 void CStubBodyGen::GenInterfaceDelegatorDestructor(std::ofstream& stream,
                                                    const std::string& id,
                                                    const Declaration& decl) {
-  const char block[] =
-      "int rpc_port_##_destroy(rpc_port_##_h h)\n" \
-      "{\n" \
-      "    if (!h) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    free(h);\n" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", id + "_" + decl.GetID()));
+  stream << SmartIndent(
+      ReplaceAll(CB_INTERFACE_DELEGATOR_DTOR, "##", id + "_" + decl.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceDelegatorSerializer(std::ofstream& stream,
                                                    const std::string& id,
                                                    const Declaration& decl) {
-  const char block[] =
-      "static void __##_to(rpc_port_parcel_h parcel, void *data)\n" \
-      "{\n" \
-      "    rpc_port_##_h handle = data;\n" \
-      "\n" \
-      "    if (!handle) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return;\n" \
-      "    }\n" \
-      "\n" \
-      "    rpc_port_parcel_write_int32(parcel, handle->id);\n" \
-      "    rpc_port_parcel_write_int32(parcel, handle->seq_id);\n" \
-      "}\n";
-
-    stream << NLine(1);
-    stream << SmartIndent(ReplaceAll(block, "##", id + "_" + decl.GetID()));
+  stream << SmartIndent(ReplaceAll(
+      CB_INTERFACE_DELEGATOR_SERIALIZER, "##", id + "_" + decl.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceDelegatorDeserializer(std::ofstream& stream,
                                                      const std::string& id,
                                                      const Declaration& decl) {
-  const char block[] =
-      "static void __##_from(rpc_port_parcel_h parcel, void *data)\n" \
-      "{\n" \
-      "    rpc_port_##_h handle = data;\n" \
-      "\n" \
-      "    if (!handle) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return;\n" \
-      "    }\n" \
-      "\n" \
-      "    rpc_port_parcel_read_int32(parcel, &handle->id);\n" \
-      "    rpc_port_parcel_read_int32(parcel, &handle->seq_id);\n" \
-      "}\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", id + "_" + decl.GetID()));
+  stream << SmartIndent(ReplaceAll(
+      CB_INTERFACE_DELEGATOR_DESERIALIZER, "##", id + "_" + decl.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceDelegatorCloner(std::ofstream& stream,
                                                const std::string& id,
                                                const Declaration& decl) {
-  const char block[] =
-      "int rpc_port_##_clone(rpc_port_##_h h, rpc_port_##_h *clone)\n" \
-      "{\n" \
-      "    rpc_port_##_h handle;\n" \
-      "\n" \
-      "    if (!h || !clone) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    handle = calloc(1, sizeof(struct ##_s));\n" \
-      "    if (!handle) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Out of memory\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    handle->parcelable = h->parcelable;\n" \
-      "    handle->port = h->port;\n" \
-      "    handle->id = h->id;\n" \
-      "    handle->seq_id = h->seq_id;\n" \
-      "\n" \
-      "    *clone = handle;\n" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", id + "_" + decl.GetID()));
+  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 block[] =
-      "int rpc_port_$$_invoke($$)\n" \
-      "{\n" \
-      "    rpc_port_parcel_h parcel = NULL;\n" \
-      "\n" \
-      "    if (!h || !h->port) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    if (!__$$_context_port_exist(h->port)) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Port doesn't exist\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    rpc_port_parcel_create(&parcel);\n" \
-      "    if (!parcel) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Failed to create parcel\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    rpc_port_parcel_write_int32(parcel, $$_METHOD_Callback);\n" \
-      "    rpc_port_parcel_write(parcel, &h->parcelable, h);\n" \
-      "$$" \
-      "    rpc_port_parcel_send(parcel, h->port);\n" \
-      "    rpc_port_parcel_destroy(parcel);\n" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(GenTemplateString(block,
+  stream << SmartIndent(GenTemplateString(CB_INTERFACE_DELEGATOR_INVOKER,
         [&]()->std::string {
           return id + "_" + decl.GetID();
         },
@@ -761,21 +450,8 @@ void CStubBodyGen::GenInterfaceDelegatorInvoker(std::ofstream& stream,
 void CStubBodyGen::GenInterfaceDelegatorPortSetter(std::ofstream& stream,
                                                    const std::string& id,
                                                    const Declaration& decl) {
-  const char block[] =
-      "int rpc_port_##_set_port(rpc_port_##_h h, rpc_port_h port)\n" \
-      "{\n" \
-      "    if (!h || !port) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    h->port = port;\n" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", id + "_" + decl.GetID()));
+  stream << SmartIndent(ReplaceAll(
+      CB_INTERFACE_DELEGATOR_PORT_SETTER, "##", id + "_" + decl.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceContext(std::ofstream& stream,
@@ -792,196 +468,59 @@ void CStubBodyGen::GenInterfaceContext(std::ofstream& stream,
 
 void CStubBodyGen::GenInterfaceContextDeclaration(std::ofstream& stream,
                                                   const Interface& inf) {
-  const char block[] =
-      "struct ##_context_s {\n" \
-      "    char *sender;\n" \
-      "    char *instance;\n" \
-      "    rpc_port_h port;\n" \
-      "    void *tag;\n" \
-      "    rpc_port_stub_##_callback_s callback;\n" \
-      "    void *user_data;\n" \
-      "};\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(
+      CB_INTERFACE_CONTEXT_DECL, "##", inf.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceContextConstructor(std::ofstream& stream,
                                                   const Interface& inf) {
-  const char block[] =
-      "static struct ##_context_s *__create_##_context(const char *sender, const char *instance)\n" \
-      "{\n" \
-      "    struct ##_context_s *handle;\n" \
-      "\n"
-      "    handle = calloc(1, sizeof(struct ##_context_s));\n" \
-      "    if (!handle) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Out of memory\");\n" \
-      "        return NULL;\n" \
-      "    }\n" \
-      "\n" \
-      "    handle->sender = strdup(sender);\n" \
-      "    if (!handle->sender) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Out of memory\");\n" \
-      "        free(handle);\n" \
-      "        return NULL;\n" \
-      "    }\n" \
-      "\n" \
-      "    handle->instance = strdup(instance);\n" \
-      "    if (!handle->instance) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Out of memory\");\n" \
-      "        free(handle->sender);\n" \
-      "        free(handle);\n" \
-      "        return NULL;\n" \
-      "    }\n" \
-      "\n" \
-      "    handle->callback = __##_callback;\n"\
-      "    handle->user_data = __##_user_data;\n" \
-      "\n" \
-      "    return handle;\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(
+      CB_INTERFACE_CONTEXT_CTOR, "##", inf.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceContextDestructor(std::ofstream& stream,
                                                  const Interface& inf) {
-  const char block[] =
-      "static void __destroy_##_context(gpointer data)\n" \
-      "{\n" \
-      "    struct ##_context_s *handle = data;\n" \
-      "\n" \
-      "    if (!handle) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Critical error!\");\n" \
-      "        return;\n" \
-      "    }\n" \
-      "\n" \
-      "    free(handle->instance);\n" \
-      "    free(handle->sender);\n" \
-      "    free(handle);\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(
+      CB_INTERFACE_CONTEXT_DTOR, "##", inf.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceContextFinder(std::ofstream& stream,
                                              const Interface& inf) {
-  const char block[] =
-      "static struct ##_context_s *__find_##_context(const char *instance)\n" \
-      "{\n" \
-      "    struct ##_context_s *handle;\n" \
-      "    GList *iter;\n" \
-      "\n" \
-      "    iter = __##_contexts;\n" \
-      "    while (iter) {\n" \
-      "        handle = (struct ##_context_s *)iter->data;\n" \
-      "        if (!strcmp(handle->instance, instance))\n" \
-      "            return handle;\n" \
-      "        iter = g_list_next(iter);\n" \
-      "    }\n" \
-      "\n" \
-      "    return NULL;\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(
+      CB_INTERFACE_CONTEXT_FINDER, "##", inf.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceContextTagSetter(std::ofstream& stream,
                                                 const Interface& inf) {
-  const char block[] =
-      "int rpc_port_stub_##_context_set_tag(rpc_port_stub_##_context_h ctx, void *tag)\n" \
-      "{\n" \
-      "    if (!ctx) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    ctx->tag = tag;\n" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(
+      CB_INTERFACE_CONTEXT_TAG_SETTER, "##", inf.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceContextTagGetter(std::ofstream& stream,
                                                 const Interface& inf) {
-  const char block[] =
-      "int rpc_port_stub_##_context_get_tag(rpc_port_stub_##_context_h ctx, void **tag)\n" \
-      "{\n" \
-      "    if (!ctx || !tag) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    *tag = ctx->tag;\n" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(
+      CB_INTERFACE_CONTEXT_TAG_GETTER, "##", inf.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceContextSenderGetter(std::ofstream& stream,
                                                    const Interface& inf) {
-  const char block[] =
-      "int rpc_port_stub_##_context_get_sender(rpc_port_stub_##_context_h ctx, char **sender)\n" \
-      "{\n" \
-      "    if (!ctx || !sender) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Invalid parameter\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    *sender = strdup(ctx->sender);\n" \
-      "    if (*sender == NULL) {\n" \
-      "        dlog_print(DLOG_ERROR, LOG_TAG, \"Out of memory\");\n" \
-      "        return -1;\n" \
-      "    }\n" \
-      "\n" \
-      "    return 0;\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(
+      CB_INTERFACE_CONTEXT_GET_SENDER, "##", inf.GetID()));
 }
 
 void CStubBodyGen::GenInterfaceContextPortExist(std::ofstream& stream,
                                                 const Interface& inf) {
-  const char block[] =
-      "static bool __##_context_port_exist(rpc_port_h port)\n" \
-      "{\n" \
-      "    struct ##_context_s *handle;\n" \
-      "    GList *iter;\n" \
-      "\n" \
-      "    iter = __##_contexts;\n" \
-      "    while (iter) {\n" \
-      "        handle = (struct ##_context_s *)iter->data;\n" \
-      "        if (handle->port == port)\n" \
-      "            return true;\n" \
-      "        iter = g_list_next(iter);\n" \
-      "    }\n" \
-      "\n" \
-      "    return false;\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+  stream << SmartIndent(ReplaceAll(
+      CB_INTERFACE_CONTEXT_PORT_EXIST, "##", inf.GetID()));
 }
 
 void CStubBodyGen::GenTypedefStubMethod(std::ofstream& stream) {
-  const char format[] =
-      "typedef int (*stub_method)(rpc_port_h, rpc_port_parcel_h, void *data);\n";
-
-  stream << NLine(1);
-  stream << std::string(format);
+  stream << CB_STUB_METHOD_TYPE;
 }
 
 void CStubBodyGen::GenInterfaceAddPrivileges(std::ofstream& stream,
                                              const Interface& inf) {
-  const char block[] =
-      "static int __$$_add_privileges(void)\n" \
-      "{\n" \
-      "$$" \
-      "    return 0;\n" \
-      "}\n";
-  stream << NLine(1);
-  stream << SmartIndent(GenTemplateString(block,
+  stream << SmartIndent(GenTemplateString(CB_INTERFACE_ADD_PRIVILEGE,
         [&]()->std::string {
           return inf.GetID();
         },
@@ -993,6 +532,9 @@ void CStubBodyGen::GenInterfaceAddPrivileges(std::ofstream& stream,
             str += GetAddPrivilegeString(inf.GetID(), *a);
             str += NLine(1);
           }
+
+          if (!str.empty())
+            str = SmartIndent("int r;\n\n") + str;
           return str;
         }
         )
diff --git a/idlc/c_gen/c_stub_body_gen_cb.h b/idlc/c_gen/c_stub_body_gen_cb.h
new file mode 100644 (file)
index 0000000..e21cf05
--- /dev/null
@@ -0,0 +1,538 @@
+/*
+ * 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.
+ */
+
+const char CB_INTERFACE_METHOD[] =
+R"__c_cb(
+static int __$$_method_$$(rpc_port_h port, rpc_port_parcel_h parcel, void *data)
+{
+    rpc_port_stub_$$_context_h context = data;
+$$
+    return 0;
+}
+)__c_cb";
+
+const char CB_INTERFACE_METHOD_TABLE[] =
+R"__c_cb(
+static stub_method __$$_method_table[] = {$$
+};
+)__c_cb";
+
+const char CB_INTERFACE_METHOD_FORMAT[] =
+R"__c_cb(
+[$$] = $$,)__c_cb";
+
+const char CB_INTERFACE_ON_CONNECTED[] =
+R"__c_cb(
+static void __##_on_connected(const char *sender, const char *instance, void *data)
+{
+    rpc_port_stub_##_context_h context;
+
+    dlog_print(DLOG_INFO, LOG_TAG, "[__RPC_PORT__] sender(%s), instance(%s)", sender, instance);
+    context = __create_##_context(sender, instance);
+    if (!context)
+        return;
+
+    if (context->callback.create)
+        context->callback.create(context, context->user_data);
+    __##_contexts = g_list_append(__##_contexts, context);
+}
+)__c_cb";
+
+const char CB_INTERFACE_ON_DISCONNECTED[] =
+R"__c_cb(
+static void __##_on_disconnected(const char *sender, const char *instance, void *data)
+{
+    rpc_port_stub_##_context_h context;
+
+    dlog_print(DLOG_INFO, LOG_TAG, "[__RPC_PORT__] sender(%s), instance(%s)", sender, instance);
+    context = __find_##_context(instance);
+    if (!context)
+        return;
+
+    if (context->callback.terminate)
+        context->callback.terminate(context, context->user_data);
+    __##_contexts = g_list_remove(__##_contexts, context);
+    __destroy_##_context(context);
+}
+)__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)
+{
+    rpc_port_stub_##_context_h context;
+    rpc_port_parcel_h parcel;
+    int cmd = -1;
+    int r;
+
+    dlog_print(DLOG_INFO, LOG_TAG, "[__RPC_PORT__] sender(%s), instance(%s)", sender, instance);
+    context = __find_##_context(instance);
+    if (!context) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to find ## context(%s)", instance);
+        return -1;
+    }
+    context->port = port;
+
+    r = rpc_port_parcel_create_from_port(&parcel, port);
+    if (r != 0) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to create parcel from port");
+        return r;
+    }
+
+    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 {
+         dlog_print(DLOG_ERROR, LOG_TAG, "Unknown Command(%d)", cmd);
+         r = -1;
+    }
+
+    rpc_port_parcel_destroy(parcel);
+
+    return r;
+}
+)__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 r;
+
+    if (__##_stub) {
+        dlog_print(DLOG_WARN, LOG_TAG, "Already exists");
+        return -1;
+    }
+
+    if (!callback) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+
+    __##_callback = *callback;
+    __##_user_data = user_data;
+    r = rpc_port_stub_create(&__##_stub, "##");
+    if (r != 0) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to create stub handle");
+        return r;
+    }
+
+    r = rpc_port_stub_add_received_event_cb(__##_stub, __##_on_received, NULL);
+    if (r != 0) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to add received event callback");
+        rpc_port_stub_destroy(__##_stub);
+        __##_stub = NULL;
+        return r;
+    }
+
+    r = rpc_port_stub_add_connected_event_cb(__##_stub, __##_on_connected, NULL);
+    if (r != 0) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to add connected event callback");
+        rpc_port_stub_destroy(__##_stub);
+        __##_stub = NULL;
+        return r;
+    }
+
+    r = rpc_port_stub_add_disconnected_event_cb(__##_stub, __##_on_disconnected, NULL);
+    if (r != 0) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to add disconnected event callback");
+        rpc_port_stub_destroy(__##_stub);
+        __##_stub = NULL;
+        return r;
+    }
+
+    r = __##_add_privileges();
+    if (r != 0) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to add privileges");
+        rpc_port_stub_destroy(__##_stub);
+        __##_stub = NULL;
+        return r;
+    }
+
+    r = rpc_port_stub_listen(__##_stub);
+    if (r != 0) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to listen stub");
+        rpc_port_stub_destroy(__##_stub);
+        __##_stub = NULL;
+        return r;
+    }
+
+    return 0;
+}
+)__c_cb";
+
+const char CB_INTERFACE_UNREGISTER[] =
+R"__c_cb(
+int rpc_port_stub_##_unregister(void)
+{
+    int r;
+
+    if (!__##_stub)
+        return -1;
+
+    if (__##_contexts) {
+        g_list_free_full(__##_contexts, __destroy_##_context);
+        __##_contexts = NULL;
+    }
+
+    r = rpc_port_stub_destroy(__##_stub);
+    __##_stub = NULL;
+
+    return r;
+}
+)__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";
+
+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;
+};
+)__c_cb";
+
+const char CB_INTERFACE_DELEGATOR_CTOR[] =
+R"__c_cb(
+int rpc_port_##_create(rpc_port_##_h *h)
+{
+    struct ##_s *handle;
+    static int seq_num;
+
+    if (!h) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+
+    handle = calloc(1, sizeof(struct ##_s));
+    if (!handle) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Out of memory");
+        return -1;
+    }
+
+    handle->parcelable.to = __##_to;
+    handle->parcelable.from = __##_from;
+    handle->id = $$_DELEGATE_$$;
+    handle->seq_id = seq_num++;
+
+    *h = handle;
+
+    return 0;
+}
+)__c_cb";
+
+const char CB_INTERFACE_DELEGATOR_DTOR[] =
+R"__c_cb(
+int rpc_port_##_destroy(rpc_port_##_h h)
+{
+    if (!h) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+
+    free(h);
+
+    return 0;
+}
+)__c_cb";
+
+const char CB_INTERFACE_DELEGATOR_SERIALIZER[] =
+R"__c_cb(
+static void __##_to(rpc_port_parcel_h parcel, void *data)
+{
+    rpc_port_##_h handle = data;
+
+    if (!handle) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return;
+    }
+
+    rpc_port_parcel_write_int32(parcel, handle->id);
+    rpc_port_parcel_write_int32(parcel, handle->seq_id);
+}
+)__c_cb";
+
+const char CB_INTERFACE_DELEGATOR_DESERIALIZER[] =
+R"__c_cb(
+static void __##_from(rpc_port_parcel_h parcel, void *data)
+{
+    rpc_port_##_h handle = data;
+
+    if (!handle) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return;
+    }
+
+    rpc_port_parcel_read_int32(parcel, &handle->id);
+    rpc_port_parcel_read_int32(parcel, &handle->seq_id);
+}
+)__c_cb";
+
+const char CB_INTERFACE_DELEGATOR_CLONER[] =
+R"__c_cb(
+int rpc_port_##_clone(rpc_port_##_h h, rpc_port_##_h *clone)
+{
+    rpc_port_##_h handle;
+
+    if (!h || !clone) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+
+    handle = calloc(1, sizeof(struct ##_s));
+    if (!handle) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Out of memory");
+        return -1;
+    }
+
+    handle->parcelable = h->parcelable;
+    handle->port = h->port;
+    handle->id = h->id;
+    handle->seq_id = h->seq_id;
+
+    *clone = handle;
+
+    return 0;
+}
+)__c_cb";
+
+const char CB_INTERFACE_DELEGATOR_INVOKER[] =
+R"__c_cb(
+int rpc_port_$$_invoke($$)
+{
+    rpc_port_parcel_h parcel = NULL;
+
+    if (!h || !h->port) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+
+    if (!__$$_context_port_exist(h->port)) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Port doesn't exist");
+        return -1;
+    }
+
+    rpc_port_parcel_create(&parcel);
+    if (!parcel) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Failed to create parcel");
+        return -1;
+    }
+
+    rpc_port_parcel_write_int32(parcel, $$_METHOD_Callback);
+    rpc_port_parcel_write(parcel, &h->parcelable, h);
+$$
+    rpc_port_parcel_send(parcel, h->port);
+    rpc_port_parcel_destroy(parcel);
+
+    return 0;
+}
+)__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)
+{
+    if (!h || !port) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+
+    h->port = port;
+
+    return 0;
+}
+)__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";
+
+const char CB_INTERFACE_CONTEXT_CTOR[] =
+R"__c_cb(
+static struct ##_context_s *__create_##_context(const char *sender, const char *instance)
+{
+    struct ##_context_s *handle;
+
+    handle = calloc(1, sizeof(struct ##_context_s));
+    if (!handle) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Out of memory");
+        return NULL;
+    }
+
+    handle->sender = strdup(sender);
+    if (!handle->sender) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Out of memory");
+        free(handle);
+        return NULL;
+    }
+
+    handle->instance = strdup(instance);
+    if (!handle->instance) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Out of memory");
+        free(handle->sender);
+        free(handle);
+        return NULL;
+    }
+
+    handle->callback = __##_callback;
+    handle->user_data = __##_user_data;
+
+    return handle;
+}
+)__c_cb";
+
+const char CB_INTERFACE_CONTEXT_DTOR[] =
+R"__c_cb(
+static void __destroy_##_context(gpointer data)
+{
+    struct ##_context_s *handle = data;
+
+    if (!handle) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Critical error!");
+        return;
+    }
+
+    free(handle->instance);
+    free(handle->sender);
+    free(handle);
+}
+)__c_cb";
+
+const char CB_INTERFACE_CONTEXT_FINDER[] =
+R"__c_cb(
+static struct ##_context_s *__find_##_context(const char *instance)
+{
+    struct ##_context_s *handle;
+    GList *iter;
+
+    iter = __##_contexts;
+    while (iter) {
+        handle = (struct ##_context_s *)iter->data;
+        if (!strcmp(handle->instance, instance))
+            return handle;
+        iter = g_list_next(iter);
+    }
+
+    return NULL;
+}
+)__c_cb";
+
+const char CB_INTERFACE_CONTEXT_TAG_SETTER[] =
+R"__c_cb(
+int rpc_port_stub_##_context_set_tag(rpc_port_stub_##_context_h ctx, void *tag)
+{
+    if (!ctx) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+
+    ctx->tag = tag;
+
+    return 0;
+}
+)__c_cb";
+
+const char CB_INTERFACE_CONTEXT_TAG_GETTER[] =
+R"__c_cb(
+int rpc_port_stub_##_context_get_tag(rpc_port_stub_##_context_h ctx, void **tag)
+{
+    if (!ctx || !tag) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+
+    *tag = ctx->tag;
+
+    return 0;
+}
+)__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)
+{
+    if (!ctx || !sender) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Invalid parameter");
+        return -1;
+    }
+
+    *sender = strdup(ctx->sender);
+    if (*sender == NULL) {
+        dlog_print(DLOG_ERROR, LOG_TAG, "Out of memory");
+        return -1;
+    }
+
+    return 0;
+}
+)__c_cb";
+
+const char CB_INTERFACE_CONTEXT_PORT_EXIST[] =
+R"__c_cb(
+static bool __##_context_port_exist(rpc_port_h port)
+{
+    struct ##_context_s *handle;
+    GList *iter;
+
+    iter = __##_contexts;
+    while (iter) {
+        handle = (struct ##_context_s *)iter->data;
+        if (handle->port == port)
+            return true;
+        iter = g_list_next(iter);
+    }
+
+    return false;
+}
+)__c_cb";
+
+const char CB_STUB_METHOD_TYPE[] =
+R"__c_cb(
+typedef int (*stub_method)(rpc_port_h, rpc_port_parcel_h, void *data);
+)__c_cb";
+
+const char CB_INTERFACE_ADD_PRIVILEGE[] =
+R"__c_cb(
+static int __$$_add_privileges(void)
+{
+$$
+    return 0;
+}
+)__c_cb";
+
+const char CB_INTERFACE_PRIVILEGE_BLOCK[] =
+R"__c_cb(r = $$;
+if (r != 0) {
+    dlog_print(DLOG_ERROR, LOG_TAG, "Failed to add privilege($$)");
+    return r;
+}
+)__c_cb";
index ca8847b..4c0927b 100644 (file)
 
 #include "idlc/c_gen/c_stub_header_gen.h"
 
+namespace {
+#include "idlc/c_gen/c_stub_header_gen_cb.h"
+}
+
 namespace tidl {
 
 CStubHeaderGen::CStubHeaderGen(std::shared_ptr<Document> doc)
@@ -55,21 +59,14 @@ void CStubHeaderGen::GenInterface(std::ofstream& stream,
 
 void CStubHeaderGen::GenInterfaceDeclaration(std::ofstream& stream,
                                              const Interface& inf) {
-  const char callback[] = "$$(*$$)(rpc_port_stub_$$_context_h context, $$void *user_data);\n";
-  const char block[] =
-      "typedef struct {\n" \
-      "    void (*create)(rpc_port_stub_##_context_h context, void *user_data);\n" \
-      "    void (*terminate)(rpc_port_stub_##_context_h context, void *user_data);\n" \
-      "    $$" \
-      "} rpc_port_stub_##_callback_s;\n";
-  stream << NLine(1);
-  stream << SmartIndent(GenTemplateString(ReplaceAll(block, "##", inf.GetID()),
+  stream << SmartIndent(GenTemplateString(ReplaceAll(
+        CB_INTERFACE_DECL, "##", inf.GetID()),
         [&]()->std::string {
           std::string str;
           for (auto& i: inf.GetDeclarations().GetDecls()) {
             if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
               continue;
-            str += GenTemplateString(callback,
+            str += GenTemplateString(CB_INTERFACE_CALLBACK,
                 [&]()->std::string {
                   return GetReturnTypeString(i->GetType());
                 },
@@ -112,33 +109,22 @@ void CStubHeaderGen::GenInterfaceContext(std::ofstream& stream,
 
 void CStubHeaderGen::GenInterfaceContextDeclaration(
     std::ofstream& stream, const Interface& inf) {
-  const char format[] = "typedef struct ##_context_s* rpc_port_stub_##_context_h;\n";
-  stream << NLine(1);
-  stream << ReplaceAll(format, "##", inf.GetID());
+  stream << ReplaceAll(CB_INTERFACE_CONTEXT_DECL, "##", inf.GetID());
 }
 
 void CStubHeaderGen::GenInterfaceContextTagSetter(
     std::ofstream& stream, const Interface& inf) {
-  const char format[] =
-      "int rpc_port_stub_##_context_set_tag(rpc_port_stub_##_context_h ctx, void *tag);\n";
-  stream << NLine(1);
-  stream << ReplaceAll(format, "##", inf.GetID());
+  stream << ReplaceAll(CB_INTERFACE_CONTEXT_SET_TAG, "##", inf.GetID());
 }
 
 void CStubHeaderGen::GenInterfaceContextTagGetter(
     std::ofstream& stream, const Interface& inf) {
-  const char format[] =
-      "int rpc_port_stub_##_context_get_tag(rpc_port_stub_##_context_h ctx, void **tag);\n";
-  stream << NLine(1);
-  stream << ReplaceAll(format, "##", inf.GetID());
+  stream << ReplaceAll(CB_INTERFACE_CONTEXT_GET_TAG, "##", inf.GetID());
 }
 
 void CStubHeaderGen::GenInterfaceContextSenderGetter(
     std::ofstream& stream, const Interface& inf) {
-  const char format[] =
-      "int rpc_port_stub_##_context_get_sender(rpc_port_stub_##_context_h ctx, char **sender);\n";
-  stream << NLine(1);
-  stream << ReplaceAll(format, "##", inf.GetID());
+  stream << ReplaceAll(CB_INTERFACE_CONTEXT_GET_SENDER, "##", inf.GetID());
 }
 
 void CStubHeaderGen::GenInterfaceDelegators(std::ofstream& stream,
@@ -161,33 +147,26 @@ void CStubHeaderGen::GenInterfaceDelegator(std::ofstream& stream,
 
 void CStubHeaderGen::GenInterfaceDelegatorDeclaration(
     std::ofstream& stream, const std::string& id, const Declaration& decl) {
-  const char format[] = "typedef struct ##_s *rpc_port_##_h;\n";
-  stream << NLine(1);
-  stream << ReplaceAll(format, "##", id + "_" + decl.GetID());
+  stream << ReplaceAll(
+      CB_INTERFACE_DELEGATOR_DECL, "##", id + "_" + decl.GetID());
 }
 
 void CStubHeaderGen::GenInterfaceDelegatorDestructor(
     std::ofstream& stream, const std::string& id, const Declaration& decl) {
-  const char format[] =
-      "int rpc_port_##_destroy(rpc_port_##_h h);\n";
-  stream << NLine(1);
-  stream << ReplaceAll(format, "##", id + "_" + decl.GetID());
+  stream << ReplaceAll(
+      CB_INTERFACE_DELEGATOR_DTOR, "##", id + "_" + decl.GetID());
 }
 
 void CStubHeaderGen::GenInterfaceDelegatorCloner(
     std::ofstream& stream, const std::string& id, const Declaration& decl) {
-  const char format[] =
-      "int rpc_port_##_clone(rpc_port_##_h h, rpc_port_##_h *clone);\n";
-  stream << NLine(1);
-  stream << ReplaceAll(format, "##", id + "_" + decl.GetID());
+  stream << ReplaceAll(
+      CB_INTERFACE_DELEGATOR_CLONER, "##", id + "_" + decl.GetID());
 }
 
 void CStubHeaderGen::GenInterfaceDelegatorInvoker(
     std::ofstream& stream, const std::string& id, const Declaration& decl) {
-  const char format[] =
-      "int rpc_port_##_invoke(rpc_port_##_h h$$);\n";
-  stream << NLine(1);
-  stream << GenTemplateString(ReplaceAll(format, "##", id + "_" + decl.GetID()),
+  stream << GenTemplateString(ReplaceAll(
+      CB_INTERFACE_DELEGATOR_INVOKER, "##", id + "_" + decl.GetID()),
       [&]()->std::string {
         std::string str;
         for (auto& i : decl.GetParameters().GetParams()) {
@@ -202,17 +181,12 @@ void CStubHeaderGen::GenInterfaceDelegatorInvoker(
 
 void CStubHeaderGen::GenInterfaceRegister(std::ofstream& stream,
                                           const Interface& inf) {
-  const char format[] =
-      "int rpc_port_stub_##_register(rpc_port_stub_##_callback_s *callback, void *user_data);\n";
-  stream << NLine(1);
-  stream << ReplaceAll(format, "##", inf.GetID());
+  stream << ReplaceAll(CB_INTERFACE_REGISTER, "##", inf.GetID());
 }
 
 void CStubHeaderGen::GenInterfaceUnregister(std::ofstream& stream,
                                             const Interface& inf) {
-  const char format[] = "int rpc_port_stub_##_unregister(void);\n";
-  stream << NLine(1);
-  stream << ReplaceAll(format, "##", inf.GetID());
+  stream << ReplaceAll(CB_INTERFACE_UNREGISTER, "##", inf.GetID());
 }
 
 }  // namespace tidl
diff --git a/idlc/c_gen/c_stub_header_gen_cb.h b/idlc/c_gen/c_stub_header_gen_cb.h
new file mode 100644 (file)
index 0000000..affa1f2
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+const char CB_INTERFACE_DECL[] =
+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;
+)__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[] =
+R"__c_cb(
+typedef struct ##_context_s* rpc_port_stub_##_context_h;
+)__c_cb";
+
+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";
+
+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";
+
+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";
+
+const char CB_INTERFACE_DELEGATOR_DECL[] =
+R"__c_cb(
+typedef struct ##_s *rpc_port_##_h;
+)__c_cb";
+
+const char CB_INTERFACE_DELEGATOR_DTOR[] =
+R"__c_cb(
+int rpc_port_##_destroy(rpc_port_##_h h);
+)__c_cb";
+
+const char CB_INTERFACE_DELEGATOR_CLONER[] =
+R"__c_cb(
+int rpc_port_##_clone(rpc_port_##_h h, rpc_port_##_h *clone);
+)__c_cb";
+
+const char CB_INTERFACE_DELEGATOR_INVOKER[] =
+R"__c_cb(
+int rpc_port_##_invoke(rpc_port_##_h h$$);
+)__c_cb";
+
+const char CB_INTERFACE_REGISTER[] =
+R"__c_cb(
+int rpc_port_stub_##_register(rpc_port_stub_##_callback_s *callback, void *user_data);
+)__c_cb";
+
+const char CB_INTERFACE_UNREGISTER[] =
+R"__c_cb(
+int rpc_port_stub_##_unregister(void);
+)__c_cb";