Refactor C++ and C# generator 44/172744/3
authorJunghoon Park <jh9216.park@samsung.com>
Thu, 15 Mar 2018 12:56:41 +0000 (21:56 +0900)
committerJunghoon Park <jh9216.park@samsung.com>
Fri, 16 Mar 2018 01:07:40 +0000 (10:07 +0900)
- Add code block header files
- Remove unused code
- Improve readability
- Fix a bug

Change-Id: I8900f514c28ecad78c5a1b28f0ed87e6e0e800c8
Signed-off-by: Junghoon Park <jh9216.park@samsung.com>
20 files changed:
idlc/cpp_gen/cpp_gen_base.cc
idlc/cpp_gen/cpp_gen_base.h
idlc/cpp_gen/cpp_gen_base_cb.h
idlc/cpp_gen/cpp_proxy_body_gen.cc
idlc/cpp_gen/cpp_proxy_body_gen_cb.h
idlc/cpp_gen/cpp_proxy_header_gen.cc
idlc/cpp_gen/cpp_stub_body_gen.cc
idlc/cpp_gen/cpp_stub_body_gen_cb.h
idlc/cpp_gen/cpp_stub_header_gen.cc
idlc/cs_gen/cs_cb_copyright.h
idlc/cs_gen/cs_cb_interop.h
idlc/cs_gen/cs_cb_proxy_interop.h
idlc/cs_gen/cs_cb_stub_interop.h
idlc/cs_gen/cs_gen_base.cc
idlc/cs_gen/cs_gen_base.h
idlc/cs_gen/cs_gen_base_cb.h [new file with mode: 0644]
idlc/cs_gen/cs_proxy_gen.cc
idlc/cs_gen/cs_proxy_gen_cb.h [new file with mode: 0644]
idlc/cs_gen/cs_stub_gen.cc
idlc/cs_gen/cs_stub_gen_cb.h [new file with mode: 0644]

index 0336cd4..5af8eb8 100644 (file)
@@ -398,7 +398,6 @@ void CppGeneratorBase::GenListSerializer(std::ofstream& stream,
     }, false);
     stream << Tab(1) << "return h;" << NLine(1);
   }, false);
-  stream << NLine(1);
 }
 
 void CppGeneratorBase::GenListSerializer(std::ofstream& stream, bool proto) {
@@ -434,8 +433,8 @@ void CppGeneratorBase::GenMethodId(std::ofstream& stream,
   stream << Tab(1) << "enum class MethodId : int ";
   GenBrace(stream, TAB_SIZE, [&]() {
     int cnt = 2;
-    stream << Tab(2) << "Result = 0," << NLine(1);
-    stream << Tab(2) << "Callback = 1," << NLine(1);
+    stream << Tab(2) << "__Result = 0," << NLine(1);
+    stream << Tab(2) << "__Callback = 1," << NLine(1);
     for (auto& i : iface.GetDeclarations().GetDecls()) {
       if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
         continue;
@@ -463,10 +462,15 @@ void CppGeneratorBase::GenDelegateId(std::ofstream& stream,
 
 void CppGeneratorBase::GenParameters(std::ofstream& stream,
                                      const Parameters& ps) {
+  stream << GetParameters(ps);
+}
+
+std::string CppGeneratorBase::GetParameters(const Parameters& ps) {
   bool first = true;
+  std::string ret;
   for (auto& i : ps.GetParams()) {
     if (!first) {
-      stream << ", ";
+      ret += ", ";
     }
 
     std::string ref;
@@ -476,10 +480,12 @@ void CppGeneratorBase::GenParameters(std::ofstream& stream,
       ref = "&";
     }
 
-    stream << ConvertTypeToString(i->GetParameterType().GetBaseType())
-           << ref << " " << i->GetID();
+    ret += ConvertTypeToString(i->GetParameterType().GetBaseType())
+        + ref + " " + i->GetID();
     first = false;
   }
+
+  return ret;
 }
 
 void CppGeneratorBase::GenDeclaration(std::ofstream& stream,
@@ -574,30 +580,17 @@ std::string CppGeneratorBase::ConvertTypeToDeserializer(
 void CppGeneratorBase::GenBodyCallbacks(std::ofstream& stream,
                                    const Interface& iface, bool is_proxy) {
   GenTemplate(CB_CALLBACK_BASE, stream,
-    [&]()->std::string {
-      return iface.GetID();
-    },
-    [&]()->std::string {
-      return iface.GetID();
-    },
-    [&]()->std::string {
-      return iface.GetID();
-    },
-    [&]()->std::string {
-      return iface.GetID();
-    },
-    [&]()->std::string {
-      return iface.GetID();
-    },
-    [&]()->std::string {
-      return iface.GetID();
-    }
+    [&]()->std::string { return iface.GetID(); },
+    [&]()->std::string { return iface.GetID(); },
+    [&]()->std::string { return iface.GetID(); },
+    [&]()->std::string { return iface.GetID(); },
+    [&]()->std::string { return iface.GetID(); },
+    [&]()->std::string { return iface.GetID(); }
   );
 
   for (auto& i : iface.GetDeclarations().GetDecls()) {
     if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
           continue;
-    stream << NLine(1);
     GenBodyCallback(stream, iface, *i, is_proxy);
   }
 }
@@ -605,110 +598,71 @@ void CppGeneratorBase::GenBodyCallbacks(std::ofstream& stream,
 void CppGeneratorBase::GenBodyCallback(std::ofstream& stream,
     const Interface& iface, const Declaration& decl, bool is_proxy) {
   if (!is_proxy) {
-    const char method[] = "void $$::$$::Invoke(";
-
-
-    GenTemplate(method, stream,
+    GenTemplate(CB_CALLBACK_INVOKE_METHOD, stream,
       [&]()->std::string {
         return iface.GetID();
       },
       [&]()->std::string {
         return decl.GetID();
+      },
+      [&]()->std::string {
+        return GetParameters(decl.GetParameters());
+      },
+      [&]()->std::string {
+        std::string m;
+        for (auto& i : decl.GetParameters().GetParams()) {
+          auto& pt = i->GetParameterType();
+          m += AddIndent(TAB_SIZE,
+              ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p"));
+        }
+        return m;
       }
     );
-    GenParameters(stream, decl.GetParameters());
-    stream << ") ";
-    GenBrace(stream, 0, [&]() {
-      const char* pre =
-          "if (port_ == nullptr)\n" \
-          "    throw NotConnectedSocketException();\n" \
-          "if (service_.lock().get() == nullptr)\n" \
-          "    throw NotConnectedSocketException();\n" \
-          "\n" \
-          "rpc_port_parcel_h p;\n" \
-          "rpc_port_parcel_create(&p);\n" \
-          "rpc_port_parcel_write_int32(p, static_cast<int>(MethodId::Callback));\n" \
-          "p << *this;\n";
-
-      const char* mid =
-          "// Send\n" \
-          "rpc_port_parcel_send(p, port_);\n" \
-          "rpc_port_parcel_destroy(p);\n";
-
-      stream << AddIndent(TAB_SIZE, pre);
-      std::string m;
-      for (auto& i : decl.GetParameters().GetParams()) {
-        auto& pt = i->GetParameterType();
-        m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p");
-      }
-
-      stream << AddIndent(TAB_SIZE, m) << NLine(1);
-      stream << AddIndent(TAB_SIZE, mid);
-    }, false);
   } else {
-    const char cb[] = "void $$::$$::OnReceivedEvent(rpc_port_parcel_h parcel) ";
-
-    GenTemplate(cb, stream,
+    GenTemplate(CB_CALLBACK_ON_RECEIVED_EVENT_METHOD, stream,
       [&]()->std::string {
         return iface.GetID();
       },
       [&]()->std::string {
         return decl.GetID();
-      }
-    );
-    GenBrace(stream, 0, [&]() {
-      int cnt = 1;
-      for (auto& i : decl.GetParameters().GetParams()) {
-        std::string v = "param" + std::to_string(cnt);
-        std::string c = ConvertTypeToDeserializer(
-            i->GetParameterType().GetBaseType(), v, "parcel");
-        stream << AddIndent(TAB_SIZE, c) << NLine(1);
-        cnt++;
-      }
+      },
+      [&]()->std::string {
+        int cnt = 1;
+        std::string ret;
+        for (auto& i : decl.GetParameters().GetParams()) {
+          std::string v = "param" + std::to_string(cnt);
+          std::string c = ConvertTypeToDeserializer(
+              i->GetParameterType().GetBaseType(), v, "parcel");
+          ret += AddIndent(TAB_SIZE, c) + NLine(1);
+          cnt++;
+        }
 
-      cnt = 1;
-      stream << Tab(1) << "OnReceived(";
-      for (int i = 0; i < decl.GetParameters().GetParams().size(); i++) {
-        if (cnt != 1) {
-          stream << ", ";
+        cnt = 1;
+        ret += Tab(1) + "OnReceived(";
+        for (int i = 0; i < decl.GetParameters().GetParams().size(); i++) {
+          if (cnt != 1) {
+            ret += ", ";
+          }
+          ret += "std::move(param" + std::to_string(cnt) + ")";
+          cnt++;
         }
-        stream << "std::move(param" << std::to_string(cnt) << ")";
-        cnt++;
+        ret += ");";
+
+        return ret;
       }
-      stream << ");" << NLine(1);
-    }, false);
+    );
   }
 }
 
 void CppGeneratorBase::GenHeaderCallbacks(std::ofstream& stream,
                                           const Interface& iface,
                                           bool is_proxy) {
-  const char block1[] =
-      "class CallbackBase {\n" \
-      " public:\n" \
-      "  CallbackBase(int delegate_id);\n" \
-      "  virtual ~CallbackBase() = default;\n" \
-      "\n";
-
-  const char block2[] =
-      "  int GetId() const;\n" \
-      "  int GetSeqId() const;\n" \
-      "\n" \
-      " private:\n" \
-      "  friend rpc_port_parcel_h operator << (rpc_port_parcel_h h, const CallbackBase& cb);\n" \
-      "  friend rpc_port_parcel_h operator >> (rpc_port_parcel_h h, CallbackBase& cb);\n" \
-      "\n" \
-      "  static int seq_num_;\n" \
-      "  int id_;\n" \
-      "  int seq_id_;\n" \
-      "};\n";
-
-  stream << AddIndent(TAB_SIZE, block1) << NLine(1);
+  stream << CB_CALLBACK_BASE_HEADER_FRONT;
   if (is_proxy) {
     stream << Tab(1) << "  virtual void OnReceivedEvent(rpc_port_parcel_h port) = 0;"
            << NLine(1);
   }
-  stream << AddIndent(TAB_SIZE, block2) << NLine(1);
+  stream << CB_CALLBACK_BASE_HEADER_BACK << NLine(1);
 
   for (auto& i : iface.GetDeclarations().GetDecls()) {
     if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
@@ -723,19 +677,9 @@ void CppGeneratorBase::GenHeaderCallback(std::ofstream& stream,
   stream << Tab(1) << "class " << decl.GetID()
          << " : public CallbackBase ";
   GenBrace(stream, TAB_SIZE, [&]() {
-    const char ctor1[] =
-      "$$(rpc_port_parcel_h port, std::weak_ptr<ServiceBase> service)\n" \
-      "    : CallbackBase(static_cast<int>(DelegateId::$$)) {\n" \
-      "  port_ = port;\n" \
-      "  service_ = std::move(service);\n" \
-      "}\n";
-    const char ctor2[] =
-      "$$()\n" \
-      "    : CallbackBase(static_cast<int>(DelegateId::$$)) {}\n";
-
-    stream << Tab(1) << " public:" << NLine(1);
+    stream << Tab(1) << " public:";
     if (!is_proxy) {
-      GenTemplate(AddIndent(TAB_SIZE * 2, ctor1), stream,
+      GenTemplate(CB_CALLBACK_CTOR_STUB, stream,
         [&]()->std::string {
           return decl.GetID();
         },
@@ -744,7 +688,7 @@ void CppGeneratorBase::GenHeaderCallback(std::ofstream& stream,
         }
       );
     } else {
-      GenTemplate(AddIndent(TAB_SIZE * 2, ctor2), stream,
+      GenTemplate(CB_CALLBACK_CTOR_PROXY, stream,
         [&]()->std::string {
           return decl.GetID();
         },
@@ -764,14 +708,12 @@ void CppGeneratorBase::GenHeaderCallback(std::ofstream& stream,
       stream << ");" << NLine(2);
     }
 
-    stream << Tab(1) << " private:" << NLine(1);
-    if (is_proxy) {
-      stream << Tab(2) << "void OnReceivedEvent(rpc_port_parcel_h port) override;"
-             << NLine(1);
+    stream << Tab(1) << " private:";
+    if (!is_proxy) {
+      stream << CB_CALLBACK_PRIVATE_STUB;
+    } else {
+      stream << CB_CALLBACK_PRIVATE_PROXY;
     }
-    stream << Tab(2) << "rpc_port_parcel_h port_;" << NLine(1);
-    if (!is_proxy)
-      stream << Tab(2) << "std::weak_ptr<ServiceBase> service_;" << NLine(1);
   }, false, false);
   stream << ";" << NLine(2);
 }
index 0106d3a..6b93ec4 100644 (file)
@@ -57,6 +57,7 @@ class CppGeneratorBase : public Generator {
                                         bool make_new_type = true);
   std::string ConvertTypeToSerializer(const BaseType& type,
                                       std::string id, std::string parcel);
+  std::string GetParameters(const Parameters& ps);
 
  private:
   void GenSetter(std::ofstream& stream, const Element& ele);
index 4b42319..e9a9818 100644 (file)
@@ -86,11 +86,10 @@ rpc_port_parcel_h operator >> (rpc_port_parcel_h h, $$::CallbackBase& cb) {
 
   return h;
 }
-
 )__cpp_cb";
 
 const char CB_COPYRIGHT[] =
-R"__cs_cb(/*
+R"__cpp_cb(/*
  * Generated by tidlc $$.
  *
  * Copyright (c) $$ Samsung Electronics Co., Ltd.
@@ -107,4 +106,79 @@ R"__cs_cb(/*
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-)__cs_cb";
+)__cpp_cb";
+
+const char CB_CALLBACK_BASE_HEADER_FRONT[] =
+R"__cpp_cb(
+  class CallbackBase {
+   public:
+    CallbackBase(int delegate_id);
+    virtual ~CallbackBase() = default;
+)__cpp_cb";
+
+const char CB_CALLBACK_BASE_HEADER_BACK[] =
+R"__cpp_cb(
+    int GetId() const;
+    int GetSeqId() const;
+
+   private:
+    friend rpc_port_parcel_h operator << (rpc_port_parcel_h h, const CallbackBase& cb);
+    friend rpc_port_parcel_h operator >> (rpc_port_parcel_h h, CallbackBase& cb);
+
+    static int seq_num_;
+    int id_;
+    int seq_id_;
+  };
+)__cpp_cb";
+
+const char CB_CALLBACK_CTOR_STUB[] =
+R"__cpp_cb(
+    $$(rpc_port_parcel_h port, std::weak_ptr<ServiceBase> service)
+        : CallbackBase(static_cast<int>(DelegateId::$$)) {
+      port_ = port;
+      service_ = std::move(service);
+    }
+)__cpp_cb";
+
+const char CB_CALLBACK_CTOR_PROXY[] =
+R"__cpp_cb(
+    $$()
+        : CallbackBase(static_cast<int>(DelegateId::$$)) {}
+)__cpp_cb";
+
+const char CB_CALLBACK_PRIVATE_PROXY[] =
+R"__cpp_cb(
+    void OnReceivedEvent(rpc_port_parcel_h port) override;
+)__cpp_cb";
+
+const char CB_CALLBACK_PRIVATE_STUB[] =
+R"__cpp_cb(
+    rpc_port_parcel_h port_;
+    std::weak_ptr<ServiceBase> service_;
+)__cpp_cb";
+
+const char CB_CALLBACK_INVOKE_METHOD[] =
+R"__cpp_cb(
+void $$::$$::Invoke($$) {
+  if (port_ == nullptr)
+      throw NotConnectedSocketException();
+  if (service_.lock().get() == nullptr)
+      throw NotConnectedSocketException();
+
+  rpc_port_parcel_h p;
+  rpc_port_parcel_create(&p);
+  rpc_port_parcel_write_int32(p, static_cast<int>(MethodId::__Callback));
+  p << *this;
+$$
+  // Send
+  rpc_port_parcel_send(p, port_);
+  rpc_port_parcel_destroy(p);
+}
+)__cpp_cb";
+
+const char CB_CALLBACK_ON_RECEIVED_EVENT_METHOD[] =
+R"__cpp_cb(
+void $$::$$::OnReceivedEvent(rpc_port_parcel_h parcel) {
+$$
+}
+)__cpp_cb";
index 3974fca..07467f7 100644 (file)
@@ -93,13 +93,7 @@ void CppProxyBodyGen::GenConstructor(std::ofstream& stream,
 
 void CppProxyBodyGen::GenDestructor(std::ofstream& stream,
                                     const Interface& iface) {
-  const char cb[] =
-    "$$::~$$() {\n" \
-    " if (proxy_)\n" \
-    "   rpc_port_proxy_destroy(proxy_);\n" \
-    "}\n";
-
-  GenTemplate(cb, stream,
+  GenTemplate(CB_DTOR, stream,
     [&]()->std::string {
       return iface.GetID();
     },
@@ -111,7 +105,6 @@ void CppProxyBodyGen::GenDestructor(std::ofstream& stream,
 
 void CppProxyBodyGen::GenHelperMethods(std::ofstream& stream,
                                        const Interface& iface) {
-
   GenTemplate(CB_PROXY_HELPER_METHODS, stream,
     [&]()->std::string { return iface.GetID(); },
     [&]()->std::string { return iface.GetID(); },
@@ -150,18 +143,7 @@ void CppProxyBodyGen::GenMethods(std::ofstream& stream,
 }
 
 void CppProxyBodyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
-  const char* pre =
-      "if (port_ == nullptr)\n" \
-      "    throw NotConnectedSocketException();\n" \
-      "\n" \
-      "rpc_port_parcel_h p;\n" \
-      "rpc_port_parcel_create(&p);\n";
-
-  const char* mid =
-      "// Send\n" \
-      "rpc_port_parcel_send(p, port_);\n";
-
-  stream << AddIndent(TAB_SIZE, pre);
+  stream << CB_INVOCATION_PRE;
 
   // Serialize
   stream << Tab(1)
@@ -174,8 +156,9 @@ void CppProxyBodyGen::GenInvocation(std::ofstream& stream, const Declaration& de
     if (pt.GetDirection() == ParameterType::Direction::OUT)
       continue;
     m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p");
-    if (IsDelegateType(pt.GetBaseType().ToString()))
+    if (IsDelegateType(pt.GetBaseType().ToString())) {
       l += "delegate_list_.emplace_back(" + i->GetID() + ".release());\n";
+    }
   }
   stream << AddIndent(TAB_SIZE, m) << NLine(1);
 
@@ -186,15 +169,15 @@ void CppProxyBodyGen::GenInvocation(std::ofstream& stream, const Declaration& de
     stream << Tab(2) << "std::lock_guard<std::recursive_mutex> lock(mutex_);"
            << NLine(2);
     if (!l.empty())
-      stream << AddIndent(TAB_SIZE * 2, l) << NLine(1);
-    stream << AddIndent(TAB_SIZE * 2, mid) << NLine(1);
+      stream << AddIndent(TAB_SIZE * 2, l);
+    stream << CB_INVOCATION_MID << NLine(1);
     if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
       stream << Tab(2) << "// Receive" << NLine(1);
       stream << Tab(2)
              << "ConsumeCommand(&parcel_received, port_);" << NLine(1);
     }
   }, false, false);
-  stream << " while (false);" << NLine(2);
+  stream << " while (false);" << NLine(1);
 
   // Deserialize
   if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
@@ -203,12 +186,7 @@ void CppProxyBodyGen::GenInvocation(std::ofstream& stream, const Declaration& de
     return;
   }
 
-  const char* receive_block =
-      "if (parcel_received == nullptr) {\n" \
-      "    throw InvalidProtocolException();\n" \
-      "}\n";
-  stream << AddIndent(TAB_SIZE, receive_block) << NLine(1);
-
+  stream << CB_INVOCATION_RECEIVE << NLine(1);
   for (auto& i : decl.GetParameters().GetParams()) {
     if (i->GetParameterType().GetDirection() == ParameterType::Direction::IN) {
       continue;
@@ -227,12 +205,7 @@ void CppProxyBodyGen::GenInvocation(std::ofstream& stream, const Declaration& de
                                                 "ret", "parcel_received"));
   }
 
-  stream << Tab(1) << "rpc_port_parcel_destroy(p);"
-         << NLine(1);
-  stream << Tab(1) << "rpc_port_parcel_destroy(parcel_received);"
-         << NLine(1);
-
-  stream << Tab(1) << "return ret;" << NLine(1);
+  stream << CB_INVOCATION_END;
 }
 
 }  // namespace tidl
index 4d80427..e19bdc6 100644 (file)
  * limitations under the License.
  */
 
+const char CB_DTOR[] =
+R"__cpp_cb(
+$$::~$$() {
+  if (proxy_)
+    rpc_port_proxy_destroy(proxy_);
+}
+)__cpp_cb";
+
+const char CB_INVOCATION_PRE[] =
+R"__cpp_cb(  if (port_ == nullptr)
+    throw NotConnectedSocketException();
+
+  rpc_port_parcel_h p;
+  rpc_port_parcel_create(&p);
+)__cpp_cb";
+
+const char CB_INVOCATION_MID[] =
+R"__cpp_cb(
+    // Send
+    rpc_port_parcel_send(p, port_);
+)__cpp_cb";
+
+const char CB_INVOCATION_RECEIVE[] =
+R"__cpp_cb(
+  if (parcel_received == nullptr) {
+    throw InvalidProtocolException();
+  }
+)__cpp_cb";
+
+const char CB_INVOCATION_END[] =
+R"__cpp_cb(
+  rpc_port_parcel_destroy(p);
+  rpc_port_parcel_destroy(parcel_received);
+
+  return ret;
+)__cpp_cb";
+
 const char CB_PROXY_HELPER_METHODS[] =
 R"__cpp_cb(
 int $$::Connect() {
@@ -22,13 +59,13 @@ int $$::Connect() {
 
 void $$::ProcessReceivedEvent(rpc_port_parcel_h parcel) {
   int id = 0;
-  int seqId = 0;
+  int seq_id = 0;
 
   rpc_port_parcel_read_int32(parcel, &id);
-  rpc_port_parcel_read_int32(parcel, &seqId);
+  rpc_port_parcel_read_int32(parcel, &seq_id);
 
   for (auto& i : delegate_list_) {
-    if (i->GetId() == id && i->GetSeqId() == seqId) {
+    if (i->GetId() == id && i->GetSeqId() == seq_id) {
       i->OnReceivedEvent(parcel);
       break;
     }
@@ -44,7 +81,7 @@ void $$::ConsumeCommand(rpc_port_parcel_h* parcel, rpc_port_h port) {
     if (ret != 0)
       break;
     rpc_port_parcel_read_int32(p, &cmd);
-    if (cmd == static_cast<int>(MethodId::Result)) {
+    if (cmd == static_cast<int>(MethodId::__Result)) {
       *parcel = p;
       return;
     }
@@ -84,7 +121,7 @@ void $$::OnReceivedCB(const char *ep, const char *port_name, void *data) {
   } while (false);
 
   rpc_port_parcel_read_int32(parcel_received, &cmd);
-  if (cmd != static_cast<int>(MethodId::Callback)) {
+  if (cmd != static_cast<int>(MethodId::__Callback)) {
     rpc_port_parcel_destroy(parcel_received);
     throw InvalidProtocolException();
   }
index 224cdbd..501ebd2 100644 (file)
@@ -59,7 +59,7 @@ void CppProxyHeaderGen::GenNamespace(std::ofstream& stream) {
 }
 
 void CppProxyHeaderGen::GenExceptions(std::ofstream& stream) {
-  stream << CB_EXCEPTIONS << NLine(1);
+  stream << CB_EXCEPTIONS;
 }
 
 void CppProxyHeaderGen::GenInterfaces(std::ofstream& stream) {
index 74187bb..ddbc6f7 100644 (file)
@@ -120,7 +120,6 @@ void CppStubBodyGen::GenDefaultMethods(std::ofstream& stream,
     [&]()->std::string { return iface.GetID(); },
     [&]()->std::string { return iface.GetID(); }
   );
-  stream << NLine(1);
 }
 
 void CppStubBodyGen::GenReceivedEvent(std::ofstream& stream,
@@ -166,6 +165,7 @@ void CppStubBodyGen::GenInvocation(std::ofstream& stream, const Declaration& dec
   // Invoke
   cnt = 1;
   std::string m;
+  std::string d;
   bool hasRet = false;
 
   if (decl.GetType().ToString() != "void") {
@@ -181,9 +181,8 @@ void CppStubBodyGen::GenInvocation(std::ofstream& stream, const Declaration& dec
 
     std::string v = "param" + std::to_string(cnt);
     auto& pt = i->GetParameterType();
-    if (pt.GetDirection() == ParameterType::Direction::OUT ||
-        pt.GetDirection() == ParameterType::Direction::REF) {
-      m += ConvertTypeToString(pt.GetBaseType()) + "& ";
+    if (pt.GetDirection() == ParameterType::Direction::OUT) {
+      d += ConvertTypeToString(pt.GetBaseType()) + " " + v + ";\n";
     }
     if (IsDelegateType(pt.GetBaseType().ToString())) {
       m += "std::move(";
@@ -196,6 +195,7 @@ void CppStubBodyGen::GenInvocation(std::ofstream& stream, const Declaration& dec
   }
 
   m += ");\n";
+  stream << AddIndent(TAB_SIZE * 3, d);
   stream << AddIndent(TAB_SIZE * 3, m);
 
   // Serialize
@@ -203,7 +203,7 @@ void CppStubBodyGen::GenInvocation(std::ofstream& stream, const Declaration& dec
     return;
 
   cnt = 0;
-  m = "rpc_port_parcel_write_int32(result, static_cast<int>(MethodId::Result));\n";
+  m = "rpc_port_parcel_write_int32(result, static_cast<int>(MethodId::__Result));\n";
   for (auto& i : decl.GetParameters().GetParams()) {
     auto& pt = i->GetParameterType();
     cnt++;
index b921ed9..6476ae7 100644 (file)
@@ -58,7 +58,8 @@ void $$::OnDisconnectedCB(const char* sender, const char* instance, void *data)
 )__cpp_cb";
 
 const char CB_ON_RECEIVED_CB_FRONT[] =
-R"__cpp_cb(int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void *data)
+R"__cpp_cb(
+int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void *data)
 {
   auto* cxt = static_cast<$$*>(data);
   rpc_port_parcel_h p;
index 4dba3b4..6b7cbfd 100644 (file)
@@ -58,7 +58,7 @@ void CppStubHeaderGen::GenNamespace(std::ofstream& stream) {
 }
 
 void CppStubHeaderGen::GenExceptions(std::ofstream& stream) {
-  stream << CB_EXCEPTIONS << NLine(1);
+  stream << CB_EXCEPTIONS;
 }
 
 void CppStubHeaderGen::GenInterfaces(std::ofstream& stream) {
index 2aae148..ece17d6 100644 (file)
@@ -1,4 +1,19 @@
-namespace {
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 cs_cb_copyright[] =
 R"__cs_cb(/*
  * Generated by tidlc $$.
@@ -18,4 +33,3 @@ R"__cs_cb(/*
  * limitations under the License.
  */
 )__cs_cb";
-}
index 1fcb088..83b112d 100644 (file)
@@ -1,4 +1,19 @@
-namespace {
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 cs_cb_interop[] =
 R"__cs_cb(
 internal static partial class Interop
@@ -112,5 +127,4 @@ $$
     }
 }
 )__cs_cb";
-}
 
index 42865d4..15261a6 100644 (file)
@@ -1,4 +1,19 @@
-namespace {
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 cs_cb_proxy_interop[] =
 R"__cs_cb(
         internal static partial class Proxy
@@ -48,4 +63,3 @@ R"__cs_cb(
             internal static extern int AddReceivedEventCb(IntPtr handle, ReceivedEventCallback cb, IntPtr data);
         }
 )__cs_cb";
-}
index 5d3dc98..c931c59 100644 (file)
@@ -1,4 +1,19 @@
-namespace {
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 cs_cb_stub_interop[] =
 R"__cs_cb(
         internal static partial class Stub
@@ -44,4 +59,3 @@ R"__cs_cb(
             internal static extern int AddPrivilege(IntPtr handle, string privilege);
         }
 )__cs_cb";
-}
index 2b5d9a3..d38d9fa 100644 (file)
 #include <vector>
 
 #include "idlc/cs_gen/cs_gen_base.h"
+
+namespace {
 #include "idlc/cs_gen/cs_cb_copyright.h"
+#include "idlc/cs_gen/cs_gen_base_cb.h"
+}
 
 namespace tidl {
 
@@ -56,16 +60,11 @@ void CsGeneratorBase::GenStructures(std::ofstream& stream) {
 
 void CsGeneratorBase::GenStructure(std::ofstream& stream, const Structure& st) {
   std::vector<std::string> v;
-  const char property[] = "        public $$ $$ { get; set; }\n";
-  const char ctor[] = "        public $$()\n" \
-                      "        {\n" \
-                      "$$" \
-                      "        }\n";
 
   stream << Tab(1) <<"public sealed class " << st.GetID() << NLine(1);
   GenBrace(stream, TAB_SIZE, [&]() {
     for (auto& i : st.GetElements().GetElms()) {
-      GenTemplate(property, stream,
+      GenTemplate(CB_PROPERTY, stream,
         [&]()->std::string {
           return ConvertTypeToString(i->GetType());
         },
@@ -78,7 +77,7 @@ void CsGeneratorBase::GenStructure(std::ofstream& stream, const Structure& st) {
       }
     }
 
-    GenTemplate(ctor, stream,
+    GenTemplate(CB_CTOR, stream,
       [&]()->std::string {
         return st.GetID();
       },
@@ -94,7 +93,7 @@ void CsGeneratorBase::GenStructure(std::ofstream& stream, const Structure& st) {
 }
 
 void CsGeneratorBase::GenSerializer(std::ofstream& stream, const Structure& st) {
-  stream << Tab(3) << "private static void Serialize(IntPtr h, "
+  stream << NLine(1) << Tab(3) << "private static void Serialize(IntPtr h, "
                    << st.GetID() << " param)" << NLine(1);
   GenBrace(stream, TAB_SIZE * 3, [&]() {
     for (auto& i : st.GetElements().GetElms()) {
@@ -146,7 +145,6 @@ void CsGeneratorBase::GenSerializer(std::ofstream& stream, const Structure& st)
 
     }
   });
-  stream << NLine(1);
 }
 
 void CsGeneratorBase::GenSerializer(std::ofstream& stream) {
@@ -166,7 +164,7 @@ void CsGeneratorBase::AddSerializerList(const BaseType& type) {
 }
 
 void CsGeneratorBase::GenListSerializer(std::ofstream& stream, const BaseType& type) {
-  stream << Tab(3) << "private static void Serialize(IntPtr h, "
+  stream << NLine(1) << Tab(3) << "private static void Serialize(IntPtr h, "
                    << ConvertTypeToString(type) << " param)" << NLine(1);
   GenBrace(stream, TAB_SIZE * 3, [&]() {
     stream << Tab(4)
@@ -210,7 +208,6 @@ void CsGeneratorBase::GenListSerializer(std::ofstream& stream, const BaseType& t
         stream << Tab(5) << "param.Add(v);" << NLine(1);
     });
   });
-  stream << NLine(1);
 }
 
 void CsGeneratorBase::GenListSerializer(std::ofstream& stream) {
@@ -344,17 +341,7 @@ std::string CsGeneratorBase::NLine(int cnt) {
 }
 
 void CsGeneratorBase::GenWriteBundle(std::ofstream& stream, const std::string& id) {
-  const char block[] =
-      "if (param.$$ != null)\n" \
-      "{\n" \
-      "    Interop.LibRPCPort.Parcel.WriteBundle(h, param.$$.SafeBundleHandle.DangerousGetHandle());\n" \
-      "}\n" \
-      "else\n" \
-      "{\n" \
-      "    Interop.LibRPCPort.Parcel.WriteBundle(h, new Bundle().SafeBundleHandle.DangerousGetHandle());\n" \
-      "}\n";
-
-  GenTemplate(AddIndent(TAB_SIZE * 4, block), stream,
+  GenTemplate(CB_WRITE_BUNDLE, stream,
     [&]()->std::string {
       return id;
     },
@@ -368,8 +355,8 @@ void CsGeneratorBase::GenMethodId(std::ofstream& stream, const Interface& iface)
   stream << Tab(3) << "private enum MethodId : int" << NLine(1);
   GenBrace(stream, TAB_SIZE * 3, [&]() {
     int cnt = 2;
-    stream << Tab(4) << "Result = 0," << NLine(1);
-    stream << Tab(4) << "Callback = 1," << NLine(1);
+    stream << Tab(4) << "__Result = 0," << NLine(1);
+    stream << Tab(4) << "__Callback = 1," << NLine(1);
     for (auto& i : iface.GetDeclarations().GetDecls()) {
       if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
         continue;
@@ -377,7 +364,6 @@ void CsGeneratorBase::GenMethodId(std::ofstream& stream, const Interface& iface)
              << i->GetID() << " = " << cnt++ << "," << NLine(1);
     }
   });
-  stream << NLine(1);
 }
 
 void CsGeneratorBase::GenDelegateId(std::ofstream& stream, const Interface& iface) {
@@ -406,89 +392,51 @@ void CsGeneratorBase::GenDeclaration(std::ofstream& stream,
 }
 
 void CsGeneratorBase::GenParameters(std::ofstream& stream, const Parameters& ps) {
+  stream << GetParameters(ps);
+}
+
+std::string CsGeneratorBase::GetParameters(const Parameters& ps) {
   bool first = true;
+  std::string ret;
   for (auto& i : ps.GetParams()) {
     if (!first) {
-      stream << ", ";
+      ret += ", ";
     }
 
     auto dir = i->GetParameterType().GetDirection();
     if (dir == ParameterType::Direction::OUT) {
-      stream << "out ";
+      ret += "out ";
     } else if (dir == ParameterType::Direction::REF) {
-      stream << "ref ";
+      ret += "ref ";
     }
 
-    stream << ConvertTypeToString(i->GetParameterType().GetBaseType()) << " "
-           << i->GetID();
+    ret += ConvertTypeToString(i->GetParameterType().GetBaseType())
+        + " " + i->GetID();
     first = false;
   }
+
+  return ret;
 }
 
 void CsGeneratorBase::GenCallbacks(std::ofstream& stream,
-                                   const Interface& iface) {
-  const char block[] =
-      "public abstract class CallbackBase\n" \
-      "{\n" \
-      "    internal int Id;\n" \
-      "    internal int SeqId;\n" \
-      "    private static int _seqNum = 0;\n" \
-      "\n" \
-      "    public CallbackBase(int delegateId)\n" \
-      "    {\n" \
-      "        Id = delegateId;\n" \
-      "        SeqId = _seqNum++;\n" \
-      "    }\n" \
-      "\n" \
-      "    internal abstract void OnReceivedEvent(IntPtr port);\n" \
-      "\n" \
-      "    internal static void Serialize(IntPtr h, CallbackBase param)\n" \
-      "    {\n" \
-      "        Interop.LibRPCPort.Parcel.WriteInt32(h, (int)param.Id);\n" \
-      "        Interop.LibRPCPort.Parcel.WriteInt32(h, (int)param.SeqId);\n" \
-      "    }\n" \
-      "\n" \
-      "    internal static void Deserialize(IntPtr h, CallbackBase param)\n" \
-      "    {\n" \
-      "        Interop.LibRPCPort.Parcel.ReadInt32(h, out var id);\n" \
-      "        param.Id = id;\n" \
-      "        Interop.LibRPCPort.Parcel.ReadInt32(h, out var seqId);\n" \
-      "        param.SeqId = seqId;\n" \
-      "    }\n" \
-      "}\n";
-  stream << AddIndent(TAB_SIZE * 3, block) << NLine(1);
+                                   const Interface& iface, bool is_proxy) {
+  stream << CB_CALLBACK_BASE;
 
   for (auto& i : iface.GetDeclarations().GetDecls()) {
     if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
           continue;
-    GenCallback(stream, *i, iface.GetID());
+    GenCallback(stream, *i, iface.GetID(), is_proxy);
   }
 }
 
 void CsGeneratorBase::GenCallback(std::ofstream& stream,
                                   const Declaration& decl,
-                                  const std::string& id) {
+                                  const std::string& id, bool is_proxy) {
   stream << Tab(3) << "public sealed class " << decl.GetID()
          << " : CallbackBase" << NLine(1);
   GenBrace(stream, TAB_SIZE * 3, [&]() {
-    const char ctor[] =
-      "public $$() : base((int)DelegateId.$$)\n" \
-      "{\n" \
-      "}\n" \
-      "\n" \
-      "internal $$(IntPtr port, WeakReference service) : base((int)DelegateId.$$)\n" \
-      "{\n" \
-      "    _port = port;\n" \
-      "    _service = service;\n" \
-      "}\n";
-
-    GenTemplate(AddIndent(TAB_SIZE * 4, ctor), stream,
-      [&]()->std::string {
-        return decl.GetID();
-      },
-      [&]()->std::string {
-        return decl.GetID();
-      },
+    GenTemplate(
+      is_proxy ? CB_CALLBACK_CTOR_PROXY : CB_CALLBACK_CTOR_STUB, stream,
       [&]()->std::string {
         return decl.GetID();
       },
@@ -498,15 +446,16 @@ void CsGeneratorBase::GenCallback(std::ofstream& stream,
     );
     stream << NLine(1);
 
-    stream << Tab(4) << "private IntPtr _port;" << NLine(1);
-    stream << Tab(4) << "private WeakReference _service;" << NLine(1);
-    stream << Tab(4) << "public delegate void Callback(";
-    GenParameters(stream, decl.GetParameters());
-    stream << ");" << NLine(1);
-    stream << Tab(4) << "public event Callback Received;" << NLine(2);
-
-    GenReceivedEvent(stream, decl, id);
-    GenInvokeMethod(stream, decl, id);
+    if (is_proxy) {
+      stream << Tab(4) << "public delegate void Callback(";
+      GenParameters(stream, decl.GetParameters());
+      stream << ");" << NLine(1);
+      stream << Tab(4) << "public event Callback Received;" << NLine(2);
+      GenReceivedEvent(stream, decl, id);
+    } else {
+      stream << CB_CALLBACK_STUB_MEMBERS;
+      GenInvokeMethod(stream, decl, id);
+    }
   });
   stream << NLine(1);
 }
@@ -544,35 +493,19 @@ void CsGeneratorBase::GenReceivedEvent(std::ofstream& stream,
 void CsGeneratorBase::GenInvokeMethod(std::ofstream& stream,
                                       const Declaration& decl,
                                       const std::string& id) {
-  const char* pre =
-      "if (_port == IntPtr.Zero || _service == null)\n" \
-      "    throw new InvalidOperationException(\"Not connected!\");\n" \
-      "if (!_service.IsAlive)\n" \
-      "    throw new InvalidOperationException(\"Invalid delegate object!\");\n" \
-      "\n" \
-      "Interop.LibRPCPort.Parcel.Create(out IntPtr p);\n" \
-      "Interop.LibRPCPort.Parcel.WriteInt32(p, (int)MethodId.Callback);\n" \
-      "Serialize(p, this);\n";
-
-  const char* mid =
-      "// Send\n" \
-      "Interop.LibRPCPort.Parcel.Send(p, _port);\n" \
-      "Interop.LibRPCPort.Parcel.Destroy(p);\n";
-
-  stream << Tab(4) << "public void Invoke(";
-  GenParameters(stream, decl.GetParameters());
-  stream << ")" << NLine(1);
-  GenBrace(stream, TAB_SIZE * 4, [&]() {
-    stream << AddIndent(TAB_SIZE * 5, pre);
-    std::string m;
-    for (auto& i : decl.GetParameters().GetParams()) {
-      auto& pt = i->GetParameterType();
-      m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p", id);
-    }
-
-    stream << AddIndent(TAB_SIZE * 5, m) << NLine(1);
-    stream << AddIndent(TAB_SIZE * 5, mid);
-  });
+  GenTemplate(CB_CALLBACK_INVOKE_METHOD, stream,
+      [&]()->std::string {
+        return GetParameters(decl.GetParameters());
+      },
+      [&]()->std::string {
+        std::string m;
+        for (auto& i : decl.GetParameters().GetParams()) {
+          auto& pt = i->GetParameterType();
+          m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p", id);
+        }
+        return AddIndent(TAB_SIZE * 5, m);
+      }
+  );
 }
 
 bool CsGeneratorBase::IsDelegateType(const std::string type_name) {
index 05e1f4a..e3bab0a 100644 (file)
@@ -44,7 +44,8 @@ class CsGeneratorBase : public Generator {
   void GenDeclaration(std::ofstream& stream,
                       const Declaration& decl, bool semicol = true);
   void GenParameters(std::ofstream& stream, const Parameters& ps);
-  void GenCallbacks(std::ofstream& stream, const Interface& iface);
+  void GenCallbacks(std::ofstream& stream, const Interface& iface,
+                    bool is_proxy);
 
   std::string ConvertTypeToString(const BaseType& type);
   std::string ConvertTypeToDeserializer(const BaseType& type,
@@ -55,6 +56,7 @@ class CsGeneratorBase : public Generator {
                                       std::string id, std::string parcel,
                                       const std::string iface_id = "");
   std::string ConvertTypeToParcelType(const std::string& key);
+  std::string GetParameters(const Parameters& ps);
   bool IsDelegateType(const std::string type_name);
   std::string Tab(int cnt);
   std::string NLine(int cnt);
@@ -66,7 +68,7 @@ class CsGeneratorBase : public Generator {
   void GenWriteBundle(std::ofstream& stream, const std::string& id);
   void AddSerializerList(const BaseType& type);
   void GenCallback(std::ofstream& stream, const Declaration& decl,
-                   const std::string& id);
+                   const std::string& id, bool is_proxy);
   void GenReceivedEvent(std::ofstream& stream, const Declaration& decl,
                         const std::string& id);
   void GenInvokeMethod(std::ofstream& stream, const Declaration& decl,
diff --git a/idlc/cs_gen/cs_gen_base_cb.h b/idlc/cs_gen/cs_gen_base_cb.h
new file mode 100644 (file)
index 0000000..841d197
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CALLBACK_BASE[] =
+R"__cs_cb(
+            public abstract class CallbackBase
+            {
+                internal int Id;
+                internal int SeqId;
+                private static int _seqNum = 0;
+
+                public CallbackBase(int delegateId)
+                {
+                    Id = delegateId;
+                    SeqId = _seqNum++;
+                }
+
+                internal virtual void OnReceivedEvent(IntPtr port) {}
+
+                internal static void Serialize(IntPtr h, CallbackBase param)
+                {
+                    Interop.LibRPCPort.Parcel.WriteInt32(h, (int)param.Id);
+                    Interop.LibRPCPort.Parcel.WriteInt32(h, (int)param.SeqId);
+                }
+
+                internal static void Deserialize(IntPtr h, CallbackBase param)
+                {
+                    Interop.LibRPCPort.Parcel.ReadInt32(h, out var id);
+                    param.Id = id;
+                    Interop.LibRPCPort.Parcel.ReadInt32(h, out var seqId);
+                    param.SeqId = seqId;
+                }
+            }
+
+)__cs_cb";
+
+const char CB_CALLBACK_CTOR_PROXY[] =
+R"__cs_cb(                public $$() : base((int)DelegateId.$$)
+                {
+                }
+)__cs_cb";
+
+const char CB_CALLBACK_CTOR_STUB[] =
+R"__cs_cb(                internal $$(IntPtr port, WeakReference service) : base((int)DelegateId.$$)
+                {
+                    _port = port;
+                    _service = service;
+                }
+)__cs_cb";
+
+const char CB_CALLBACK_STUB_MEMBERS[] =
+R"__cs_cb(                private IntPtr _port;
+                private WeakReference _service;
+
+)__cs_cb";
+
+const char CB_CALLBACK_INVOKE_METHOD[] =
+R"__cs_cb(
+                public void Invoke($$)
+                {
+                    if (_port == IntPtr.Zero || _service == null)
+                        throw new InvalidOperationException("Not connected!");
+                    if (!_service.IsAlive)
+                        throw new InvalidOperationException("Invalid delegate object!");
+
+                    Interop.LibRPCPort.Parcel.Create(out IntPtr p);
+                    Interop.LibRPCPort.Parcel.WriteInt32(p, (int)MethodId.__Callback);
+                    Serialize(p, this);
+$$
+                    // Send
+                    Interop.LibRPCPort.Parcel.Send(p, _port);
+                    Interop.LibRPCPort.Parcel.Destroy(p);
+                }
+)__cs_cb";
+
+const char CB_PROPERTY[] = R"__cs_cb(        public $$ $$ { get; set; }
+)__cs_cb";
+
+const char CB_CTOR[] = R"__cs_cb(
+        public $$()
+        {
+$$
+        }
+)__cs_cb";
+
+const char CB_WRITE_BUNDLE[] =
+R"__cs_cb(
+                if (param.$$ != null)
+                {
+                    Interop.LibRPCPort.Parcel.WriteBundle(h, param.$$.SafeBundleHandle.DangerousGetHandle());
+                }
+                else
+                {
+                    Interop.LibRPCPort.Parcel.WriteBundle(h, new Bundle().SafeBundleHandle.DangerousGetHandle());
+                }
+)__cs_cb";
index 92e50c8..a72e74e 100644 (file)
  */
 
 #include "idlc/cs_gen/cs_proxy_gen.h"
+
+namespace {
 #include "idlc/cs_gen/cs_cb_interop.h"
 #include "idlc/cs_gen/cs_cb_proxy_interop.h"
+#include "idlc/cs_gen/cs_proxy_gen_cb.h"
+}
 
 namespace tidl {
 
@@ -67,105 +71,15 @@ void CsProxyGen::GenInterfaces(std::ofstream& stream) {
 }
 
 void CsProxyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
-  const char* prop =
-      "public event EventHandler Connected;\n" \
-      "public event EventHandler Disconnected;\n" \
-      "public event EventHandler Rejected;\n" \
-      "\n" \
-      "private IntPtr _proxy;\n" \
-      "private IntPtr _port;\n" \
-      "private bool _online = false;\n" \
-      "private string _appId;\n" \
-      "private Object _lock = new Object();\n" \
-      "private List<CallbackBase> _delegateList = new List<CallbackBase>();\n" \
-      "private Interop.LibRPCPort.Proxy.ConnectedEventCallback _connectedEventCallback;\n" \
-      "private Interop.LibRPCPort.Proxy.DisconnectedEventCallback _disconnectedEventCallback;\n" \
-      "private Interop.LibRPCPort.Proxy.RejectedEventCallback _rejectedEventCallback;\n" \
-      "private Interop.LibRPCPort.Proxy.ReceivedEventCallback _receivedEventCallback;\n";
-
-  const char* eventMethods =
-      "private void OnConnectedEvent(string endPoint, string port_name, IntPtr port, IntPtr data)\n" \
-      "{\n" \
-      "    _port = port;\n" \
-      "    _online = true;\n" \
-      "    Connected?.Invoke(this, null);\n" \
-      "}\n" \
-      "\n" \
-      "private void OnDisconnectedEvent(string endPoint, string port_name, IntPtr data)\n" \
-      "{\n" \
-      "    Disconnected?.Invoke(this, null);\n" \
-      "}\n" \
-      "\n" \
-      "private void OnRejectedEvent(string endPoint, string port_name, IntPtr data)\n" \
-      "{\n" \
-      "    Rejected?.Invoke(this, null);\n" \
-      "}\n" \
-      "\n" \
-      "private void ProcessReceivedEvent(IntPtr parcel)\n" \
-      "{\n" \
-      "    Interop.LibRPCPort.Parcel.ReadInt32(parcel, out int id);\n" \
-      "    Interop.LibRPCPort.Parcel.ReadInt32(parcel, out int seqId);\n" \
-      "\n" \
-      "    foreach (var i in _delegateList)\n" \
-      "    {\n" \
-      "        if ((int)i.Id == id && i.SeqId == seqId)\n" \
-      "        {\n" \
-      "            i.OnReceivedEvent(parcel);\n" \
-      "            break;\n" \
-      "        }\n" \
-      "    }\n" \
-      "}\n" \
-      "\n" \
-      "private void OnReceivedEvent(string endPoint, string port_name, IntPtr data)\n" \
-      "{\n" \
-      "    IntPtr parcel_received;\n" \
-      "    lock (_lock)\n" \
-      "    {\n" \
-      "        if (Interop.LibRPCPort.Parcel.CreateFromPort(out parcel_received, _port) != 0)\n" \
-      "            return;\n" \
-      "    }\n" \
-      "\n" \
-      "    Interop.LibRPCPort.Parcel.ReadInt32(parcel_received, out int cmd);\n" \
-      "    if (cmd != (int)MethodId.Callback)\n" \
-      "    {\n" \
-      "        Interop.LibRPCPort.Parcel.Destroy(parcel_received);\n" \
-      "        throw new InvalidOperationException(\"Invalid protocol\");\n" \
-      "    }\n" \
-      "\n" \
-      "    ProcessReceivedEvent(parcel_received);\n" \
-      "    Interop.LibRPCPort.Parcel.Destroy(parcel_received);\n" \
-      "}\n" \
-      "\n" \
-      "private void ConsumeCommand(out IntPtr parcel, IntPtr port)\n" \
-      "{\n" \
-      "    do\n" \
-      "    {\n" \
-      "        int ret = Interop.LibRPCPort.Parcel.CreateFromPort(out IntPtr p, port);\n" \
-      "\n" \
-      "        if (ret != 0)\n" \
-      "            break;\n" \
-      "        Interop.LibRPCPort.Parcel.ReadInt32(p, out int cmd);\n" \
-      "        if (cmd == (int)MethodId.Result)\n" \
-      "        {\n" \
-      "            parcel = p;\n" \
-      "            return;\n" \
-      "        }\n" \
-      "\n" \
-      "        ProcessReceivedEvent(p);\n" \
-      "        Interop.LibRPCPort.Parcel.Destroy(p);\n" \
-      "        parcel = IntPtr.Zero;\n" \
-      "    } while (true);\n" \
-      "    parcel = IntPtr.Zero;\n" \
-      "}\n";
 
   stream << Tab(2) << "public class " << iface.GetID()
          << " : IDisposable" << NLine(1);
   GenBrace(stream, TAB_SIZE * 2, [&]() {
-    stream << AddIndent(TAB_SIZE * 3, prop) << NLine(1);
-    GenCallbacks(stream, iface);
+    stream << CB_DATA_MEMBERS;
+    GenCallbacks(stream, iface, true);
     GenDelegateId(stream, iface);
     GenMethodId(stream, iface);
-    stream << AddIndent(TAB_SIZE * 3, eventMethods) << NLine(1);
+    stream << CB_EVENT_METHODS;
     GenSerializer(stream);
     GenListSerializer(stream);
     GenCtor(stream, iface);
@@ -178,32 +92,16 @@ void CsProxyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
 void CsProxyGen::GenCtor(std::ofstream& stream, const Interface& iface) {
   const char* m = "public $$(string appId) => _appId = appId;\n";
 
+  stream << NLine(1);
   GenTemplate(AddIndent(TAB_SIZE * 3, m), stream,
     [&]()->std::string {
       return iface.GetID();
     }
   );
-  stream << NLine(1);
 }
 
 void CsProxyGen::GenConnectMethod(std::ofstream& stream, const Interface& iface) {
-  const char* m =
-    "public void Connect()\n" \
-    "{\n" \
-    "    Interop.LibRPCPort.Proxy.Create(out _proxy);\n" \
-    "    _connectedEventCallback = new Interop.LibRPCPort.Proxy.ConnectedEventCallback(OnConnectedEvent);\n" \
-    "    _disconnectedEventCallback = new Interop.LibRPCPort.Proxy.DisconnectedEventCallback(OnDisconnectedEvent);\n" \
-    "    _rejectedEventCallback = new Interop.LibRPCPort.Proxy.RejectedEventCallback(OnRejectedEvent);\n" \
-    "    _receivedEventCallback = new Interop.LibRPCPort.Proxy.ReceivedEventCallback(OnReceivedEvent);\n" \
-    "    Interop.LibRPCPort.Proxy.AddConnectedEventCb(_proxy, _connectedEventCallback, IntPtr.Zero);\n" \
-    "    Interop.LibRPCPort.Proxy.AddDisconnectedEventCb(_proxy, _disconnectedEventCallback, IntPtr.Zero);\n" \
-    "    Interop.LibRPCPort.Proxy.AddRejectedEventCb(_proxy, _rejectedEventCallback, IntPtr.Zero);\n" \
-    "    Interop.LibRPCPort.Proxy.AddReceivedEventCb(_proxy, _receivedEventCallback, IntPtr.Zero);\n" \
-    "    if (Interop.LibRPCPort.Proxy.Connect(_proxy, _appId, \"$$\") != 0)\n" \
-    "        throw new InvalidOperationException(\"Connection failed\");\n" \
-    "}";
-
-  GenTemplate(AddIndent(TAB_SIZE * 3, m), stream,
+  GenTemplate(CB_CONNECT_METHOD, stream,
     [&]()->std::string {
       return iface.GetID();
     }
@@ -229,17 +127,7 @@ void CsProxyGen::GenMethods(std::ofstream& stream, const Interface& iface) {
 }
 
 void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
-  const char* pre =
-      "if (!_online)\n" \
-      "    throw new InvalidOperationException(\"Not connected!\");\n" \
-      "\n" \
-      "Interop.LibRPCPort.Parcel.Create(out IntPtr p);\n";
-
-  const char* mid =
-      "// Send\n" \
-      "Interop.LibRPCPort.Parcel.Send(p, _port);\n";
-
-  stream << AddIndent(TAB_SIZE * 4, pre);
+  stream << CB_INVOCATION_PRE;
 
   // Serialize
   stream << Tab(4)
@@ -252,8 +140,9 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
     if (pt.GetDirection() == ParameterType::Direction::OUT)
       continue;
     m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p");
-    if (IsDelegateType(pt.GetBaseType().ToString()))
+    if (IsDelegateType(pt.GetBaseType().ToString())) {
       l += "_delegateList.Add(" + i->GetID() + ");\n";
+    }
   }
   stream << AddIndent(TAB_SIZE * 4, m) << NLine(1);
 
@@ -263,7 +152,7 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
   GenBrace(stream, TAB_SIZE * 4, [&]() {
     if (!l.empty())
       stream << AddIndent(TAB_SIZE * 5, l) << NLine(1);
-    stream << AddIndent(TAB_SIZE * 5, mid) << NLine(1);
+    stream << CB_INVOCATION_MID << NLine(1);
     if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
       stream << Tab(5) << "// Receive" << NLine(1);
       stream << Tab(5)
@@ -308,47 +197,15 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
          << NLine(1);
   stream << Tab(4) << "Interop.LibRPCPort.Parcel.Destroy(parcel_received);"
          << NLine(1);
-
   stream << Tab(4) << "return ret;" << NLine(1);
 }
 
 void CsProxyGen::GenDisposable(std::ofstream& stream, const Interface& iface) {
-  const char* m =
-    "#region IDisposable Support\n" \
-    "private bool disposedValue = false;\n" \
-    "\n" \
-    "protected virtual void Dispose(bool disposing)\n" \
-    "{\n" \
-    "    if (!disposedValue)\n" \
-    "    {\n" \
-    "        if (disposing)\n" \
-    "        {\n" \
-    "        }\n" \
-    "\n" \
-    "        if (_proxy != IntPtr.Zero)\n" \
-    "            Interop.LibRPCPort.Proxy.Destroy(_proxy);\n" \
-    "\n" \
-    "        disposedValue = true;\n" \
-    "    }\n" \
-    "}\n" \
-    "\n" \
-    "~$$() {\n" \
-    "    Dispose(false);\n" \
-    "}\n" \
-    "\n" \
-    "public void Dispose()\n" \
-    "{\n" \
-    "    Dispose(true);\n" \
-    "    GC.SuppressFinalize(this);\n" \
-    "}\n" \
-    "#endregion\n";
-
-  GenTemplate(AddIndent(TAB_SIZE * 3, m), stream,
+  GenTemplate(CB_DISPOSABLE, stream,
     [&]()->std::string {
       return iface.GetID();
     }
   );
-
 }
 
 }  // namespace tidl
diff --git a/idlc/cs_gen/cs_proxy_gen_cb.h b/idlc/cs_gen/cs_proxy_gen_cb.h
new file mode 100644 (file)
index 0000000..960897a
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_DATA_MEMBERS[] =
+R"__cs_cb(            public event EventHandler Connected;
+            public event EventHandler Disconnected;
+            public event EventHandler Rejected;
+
+            private IntPtr _proxy;
+            private IntPtr _port;
+            private bool _online = false;
+            private string _appId;
+            private Object _lock = new Object();
+            private List<CallbackBase> _delegateList = new List<CallbackBase>();
+            private Interop.LibRPCPort.Proxy.ConnectedEventCallback _connectedEventCallback;
+            private Interop.LibRPCPort.Proxy.DisconnectedEventCallback _disconnectedEventCallback;
+            private Interop.LibRPCPort.Proxy.RejectedEventCallback _rejectedEventCallback;
+            private Interop.LibRPCPort.Proxy.ReceivedEventCallback _receivedEventCallback;
+)__cs_cb";
+
+const char CB_EVENT_METHODS[] =
+R"__cs_cb(
+            private void OnConnectedEvent(string endPoint, string port_name, IntPtr port, IntPtr data)
+            {
+                _port = port;
+                _online = true;
+                Connected?.Invoke(this, null);
+            }
+
+            private void OnDisconnectedEvent(string endPoint, string port_name, IntPtr data)
+            {
+                Disconnected?.Invoke(this, null);
+            }
+
+            private void OnRejectedEvent(string endPoint, string port_name, IntPtr data)
+            {
+                Rejected?.Invoke(this, null);
+            }
+
+            private void ProcessReceivedEvent(IntPtr parcel)
+            {
+                Interop.LibRPCPort.Parcel.ReadInt32(parcel, out int id);
+                Interop.LibRPCPort.Parcel.ReadInt32(parcel, out int seqId);
+
+                foreach (var i in _delegateList)
+                {
+                    if ((int)i.Id == id && i.SeqId == seqId)
+                    {
+                        i.OnReceivedEvent(parcel);
+                        break;
+                    }
+                }
+            }
+
+            private void OnReceivedEvent(string endPoint, string port_name, IntPtr data)
+            {
+                IntPtr parcel_received;
+                lock (_lock)
+                {
+                    if (Interop.LibRPCPort.Parcel.CreateFromPort(out parcel_received, _port) != 0)
+                        return;
+                }
+
+                Interop.LibRPCPort.Parcel.ReadInt32(parcel_received, out int cmd);
+                if (cmd != (int)MethodId.__Callback)
+                {
+                    Interop.LibRPCPort.Parcel.Destroy(parcel_received);
+                    throw new InvalidOperationException("Invalid protocol");
+                }
+
+                ProcessReceivedEvent(parcel_received);
+                Interop.LibRPCPort.Parcel.Destroy(parcel_received);
+            }
+
+            private void ConsumeCommand(out IntPtr parcel, IntPtr port)
+            {
+                do
+                {
+                    int ret = Interop.LibRPCPort.Parcel.CreateFromPort(out IntPtr p, port);
+
+                    if (ret != 0)
+                        break;
+                    Interop.LibRPCPort.Parcel.ReadInt32(p, out int cmd);
+                    if (cmd == (int)MethodId.__Result)
+                    {
+                        parcel = p;
+                        return;
+                    }
+
+                    ProcessReceivedEvent(p);
+                    Interop.LibRPCPort.Parcel.Destroy(p);
+                    parcel = IntPtr.Zero;
+                } while (true);
+                parcel = IntPtr.Zero;
+            }
+)__cs_cb";
+
+const char CB_CONNECT_METHOD[] =
+R"__cs_cb(
+            public void Connect()
+            {
+                Interop.LibRPCPort.Proxy.Create(out _proxy);
+                _connectedEventCallback = new Interop.LibRPCPort.Proxy.ConnectedEventCallback(OnConnectedEvent);
+                _disconnectedEventCallback = new Interop.LibRPCPort.Proxy.DisconnectedEventCallback(OnDisconnectedEvent);
+                _rejectedEventCallback = new Interop.LibRPCPort.Proxy.RejectedEventCallback(OnRejectedEvent);
+                _receivedEventCallback = new Interop.LibRPCPort.Proxy.ReceivedEventCallback(OnReceivedEvent);
+                Interop.LibRPCPort.Proxy.AddConnectedEventCb(_proxy, _connectedEventCallback, IntPtr.Zero);
+                Interop.LibRPCPort.Proxy.AddDisconnectedEventCb(_proxy, _disconnectedEventCallback, IntPtr.Zero);
+                Interop.LibRPCPort.Proxy.AddRejectedEventCb(_proxy, _rejectedEventCallback, IntPtr.Zero);
+                Interop.LibRPCPort.Proxy.AddReceivedEventCb(_proxy, _receivedEventCallback, IntPtr.Zero);
+                if (Interop.LibRPCPort.Proxy.Connect(_proxy, _appId, "$$") != 0)
+                    throw new InvalidOperationException("Connection failed");
+            }
+)__cs_cb";
+
+const char CB_DISPOSABLE[] =
+R"__cs_cb(
+            #region IDisposable Support
+            private bool disposedValue = false;
+
+            protected virtual void Dispose(bool disposing)
+            {
+                if (!disposedValue)
+                {
+                    if (disposing)
+                    {
+                    }
+
+                    if (_proxy != IntPtr.Zero)
+                        Interop.LibRPCPort.Proxy.Destroy(_proxy);
+
+                    disposedValue = true;
+                }
+            }
+
+            ~$$() {
+                Dispose(false);
+            }
+
+            public void Dispose()
+            {
+                Dispose(true);
+                GC.SuppressFinalize(this);
+            }
+            #endregion
+)__cs_cb";
+
+const char CB_INVOCATION_PRE[] =
+R"__cs_cb(                if (!_online)
+                    throw new InvalidOperationException("Not connected!");
+
+                Interop.LibRPCPort.Parcel.Create(out IntPtr p);
+)__cs_cb";
+
+const char CB_INVOCATION_MID[] =
+R"__cs_cb(                    // Send
+                    Interop.LibRPCPort.Parcel.Send(p, _port);
+)__cs_cb";
index 6747838..12897bb 100644 (file)
  */
 
 #include "idlc/cs_gen/cs_stub_gen.h"
+
+namespace {
 #include "idlc/cs_gen/cs_cb_interop.h"
 #include "idlc/cs_gen/cs_cb_stub_interop.h"
+#include "idlc/cs_gen/cs_stub_gen_cb.h"
+}
 
 namespace tidl {
 
@@ -69,19 +73,9 @@ void CsStubGen::GenInterface(std::ofstream& stream, const Interface& iface) {
   stream << Tab(2) << "public sealed class " << iface.GetID()
          << " : IDisposable" << NLine(1);
   GenBrace(stream, TAB_SIZE * 2, [&]() {
-    stream << Tab(3) << "private IntPtr _stub;" << NLine(1);
-    stream << Tab(3)
-           << "private List<ServiceBase> _services = new List<ServiceBase>();"
-           << NLine(1);
-    stream << Tab(3) << "private Type _serviceType;" << NLine(1);
-    stream << Tab(3) << "private Interop.LibRPCPort.Stub.ConnectedEventCallback _connectedEventCallback;"
-           << NLine(1);
-    stream << Tab(3) << "private Interop.LibRPCPort.Stub.DisconnectedEventCallback _disconnectedEventCallback;"
-           << NLine(1);
-    stream << Tab(3) << "private Interop.LibRPCPort.Stub.ReceivedEventCallback _receivedEventCallback;"
-           << NLine(2);
+    stream << CB_DATA_MEMBERS;
     GenServiceBase(stream, iface);
-    GenCallbacks(stream, iface);
+    GenCallbacks(stream, iface, false);
     GenDelegateId(stream, iface);
     GenMethodId(stream, iface);
     GenSerializer(stream);
@@ -96,30 +90,10 @@ void CsStubGen::GenInterface(std::ofstream& stream, const Interface& iface) {
 }
 
 void CsStubGen::GenServiceBase(std::ofstream& stream, const Interface& iface) {
-  const char cls[] =
-            "public abstract class ServiceBase\n" \
-            "{\n" \
-            "    public string Sender\n" \
-            "    {\n" \
-            "        get; internal set;\n" \
-            "    }\n" \
-            "\n" \
-            "    public string Instance\n" \
-            "    {\n" \
-            "        get; internal set;\n" \
-            "    }\n" \
-            "\n" \
-            "    protected ServiceBase()\n" \
-            "    {\n" \
-            "    }\n" \
-            "\n" \
-            "    public abstract void OnCreate();\n" \
-            "    public abstract void OnTerminate();\n";
-  stream << AddIndent(TAB_SIZE * 3, cls);
+  stream << CB_SERVICE_BASE_FRONT;
   GenDeclarations(stream, iface.GetDeclarations());
   stream << NLine(1);
   stream << AddIndent(TAB_SIZE * 3, "}\n");
-  stream << NLine(1);
 }
 
 void CsStubGen::GenDeclarations(std::ofstream& stream,
@@ -134,45 +108,7 @@ void CsStubGen::GenDeclarations(std::ofstream& stream,
 }
 
 void CsStubGen::GenReceivedEvent(std::ofstream& stream, const Interface& iface) {
-  const char method_front[] =
-    "private int OnReceivedEvent(string sender, string instance, IntPtr port, IntPtr data)\n" \
-    "{\n" \
-    "    int ret = Interop.LibRPCPort.Parcel.CreateFromPort(out IntPtr p, port);\n" \
-    "\n" \
-    "    if (ret != 0)\n" \
-    "        return ret;\n" \
-    "\n" \
-    "    Interop.LibRPCPort.Parcel.Create(out IntPtr result);\n" \
-    "    Interop.LibRPCPort.Parcel.ReadInt32(p, out int cmd);\n" \
-    "    ServiceBase b = null;\n" \
-    "\n" \
-    "    foreach (var i in  _services)\n" \
-    "    {\n" \
-    "        if (i.Instance.Equals(instance))\n" \
-    "        {\n" \
-    "            b = i;\n" \
-    "            break;\n" \
-    "        }\n" \
-    "    }\n" \
-    "\n" \
-    "    if (b == null)\n" \
-    "        return -1;\n" \
-    "\n"
-    "    switch ((MethodId)cmd)\n" \
-    "    {\n";
-
-  const char method_back[] =
-    "        default:\n" \
-    "            return -1;\n" \
-    "    }\n" \
-    "\n" \
-    "    Interop.LibRPCPort.Parcel.Destroy(p);\n" \
-    "    Interop.LibRPCPort.Parcel.Destroy(result);\n" \
-    "\n" \
-    "    return 0;\n" \
-    "}\n";
-
-  stream << AddIndent(TAB_SIZE * 3, method_front);
+  stream << CB_ON_RECEIVED_EVENT_FRONT;
   for (auto& i : iface.GetDeclarations().GetDecls()) {
     if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
       continue;
@@ -182,7 +118,7 @@ void CsStubGen::GenReceivedEvent(std::ofstream& stream, const Interface& iface)
       stream << Tab(7) << "break;" << NLine(1);
     });
   }
-  stream << AddIndent(TAB_SIZE * 3, method_back) << NLine(1);
+  stream << CB_ON_RECEIVED_EVENT_BACK;
 }
 
 void CsStubGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
@@ -237,7 +173,7 @@ void CsStubGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
     return;
 
   cnt = 0;
-  m = "Interop.LibRPCPort.Parcel.WriteInt32(result, (int)MethodId.Result);\n";
+  m = "Interop.LibRPCPort.Parcel.WriteInt32(result, (int)MethodId.__Result);\n";
   for (auto& i : decl.GetParameters().GetParams()) {
     auto& pt = i->GetParameterType();
     cnt++;
@@ -256,48 +192,15 @@ void CsStubGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
 }
 
 void CsStubGen::GenConnectedEvent(std::ofstream& stream) {
-  const char method[] =
-      "private void OnConnectedEvent(string sender, string instance, IntPtr data)\n" \
-      "{\n" \
-      "    ServiceBase s = Activator.CreateInstance(_serviceType) as ServiceBase;\n" \
-      "    s.Sender = sender;\n" \
-      "    s.Instance = instance;\n" \
-      "    s.OnCreate();\n" \
-      "    _services.Add(s);\n" \
-      "}\n";
-  stream << AddIndent(TAB_SIZE * 3, method) << NLine(1);
+  stream << CB_ON_CONNECTED_EVENT;
 }
 
 void CsStubGen::GenDisconnectedEvent(std::ofstream& stream) {
-  const char method[] =
-      "private void OnDisconnectedEvent(string sender, string instance, IntPtr data)\n" \
-      "{\n" \
-      "    foreach (var i in _services)\n" \
-      "    {\n" \
-      "        if (i.Instance.Equals(instance))\n" \
-      "        {\n" \
-      "            i.OnTerminate();\n" \
-      "            _services.Remove(i);\n" \
-      "            break;\n" \
-      "        }\n" \
-      "    }\n" \
-      "}\n";
-  stream << AddIndent(TAB_SIZE * 3, method) << NLine(1);
+  stream << CB_ON_DISCONNECTED_EVENT;
 }
 
 void CsStubGen::GenCtor(std::ofstream& stream, const Interface& iface) {
-  const char ctor[] =
-      "public $$()\n" \
-      "{\n" \
-      "    Interop.LibRPCPort.Stub.Create(out _stub, \"$$\");\n" \
-      "    _connectedEventCallback = new Interop.LibRPCPort.Stub.ConnectedEventCallback(OnConnectedEvent);\n" \
-      "    _disconnectedEventCallback = new Interop.LibRPCPort.Stub.DisconnectedEventCallback(OnDisconnectedEvent);\n" \
-      "    _receivedEventCallback = new Interop.LibRPCPort.Stub.ReceivedEventCallback(OnReceivedEvent);\n" \
-      "    Interop.LibRPCPort.Stub.AddReceivedEventCb(_stub, _receivedEventCallback, IntPtr.Zero);\n" \
-      "    Interop.LibRPCPort.Stub.AddConnectedEventCb(_stub, _connectedEventCallback, IntPtr.Zero);\n" \
-      "    Interop.LibRPCPort.Stub.AddDisconnectedEventCb(_stub, _disconnectedEventCallback, IntPtr.Zero);\n";
-
-  GenTemplate(AddIndent(TAB_SIZE * 3, ctor), stream,
+  GenTemplate(CB_CTOR_FRONT, stream,
     [&]()->std::string {
       return iface.GetID();
     },
@@ -312,71 +215,19 @@ void CsStubGen::GenCtor(std::ofstream& stream, const Interface& iface) {
              << i->GetValue() << "\");" << NLine(1);
     }
   }
-  stream << Tab(3) << "}" << NLine(2);
+  stream << Tab(3) << "}" << NLine(1);
 }
 
 void CsStubGen::GenCommonMethods(std::ofstream& stream) {
-  const char method_listen[] =
-      "public void Listen(Type serviceType)\n" \
-      "{\n" \
-      "    if (!typeof(ServiceBase).IsAssignableFrom(serviceType))\n" \
-      "        throw new InvalidOperationException(\"Invalid type\");\n" \
-      "    _serviceType = serviceType;\n" \
-      "    Interop.LibRPCPort.Stub.Listen(_stub);\n" \
-      "}\n";
-
-  const char method_get_services[] =
-      "public IEnumerable<ServiceBase> GetServices()\n" \
-      "{\n" \
-      "    return _services;\n" \
-      "}\n";
-
-  stream << AddIndent(TAB_SIZE * 3, method_listen) << NLine(1);
-  stream << AddIndent(TAB_SIZE * 3, method_get_services);
+  stream << CB_COMMON_METHODS;
 }
 
 void CsStubGen::GenDisposable(std::ofstream& stream, const Interface& iface) {
-  const char* m =
-    "#region IDisposable Support\n" \
-    "private bool disposedValue = false;\n" \
-    "\n" \
-    "private void Dispose(bool disposing)\n" \
-    "{\n" \
-    "    if (!disposedValue)\n" \
-    "    {\n" \
-    "        if (disposing)\n" \
-    "        {\n" \
-    "        }\n" \
-    "\n" \
-    "        foreach (var i in _services)\n" \
-    "        {\n" \
-    "            i.OnTerminate();\n" \
-    "        }\n" \
-    "\n" \
-    "        _services = null;\n" \
-    "        if (_stub != IntPtr.Zero)\n" \
-    "            Interop.LibRPCPort.Stub.Destroy(_stub);\n" \
-    "        disposedValue = true;\n" \
-    "    }\n" \
-    "}\n" \
-    "\n" \
-    "~$$() {\n" \
-    "    Dispose(false);\n" \
-    "}\n" \
-    "\n" \
-    "public void Dispose()\n" \
-    "{\n" \
-    "    Dispose(true);\n" \
-    "    GC.SuppressFinalize(this);\n" \
-    "}\n" \
-    "#endregion\n";
-
-  GenTemplate(AddIndent(TAB_SIZE * 3, m), stream,
+  GenTemplate(CB_DISPOSABLE, stream,
     [&]()->std::string {
       return iface.GetID();
     }
   );
-
 }
 
 }  // namespace tidl
diff --git a/idlc/cs_gen/cs_stub_gen_cb.h b/idlc/cs_gen/cs_stub_gen_cb.h
new file mode 100644 (file)
index 0000000..29d0656
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_DATA_MEMBERS[] =
+R"__cs_cb(            private IntPtr _stub;
+            private List<ServiceBase> _services = new List<ServiceBase>();
+            private Type _serviceType;
+            private Interop.LibRPCPort.Stub.ConnectedEventCallback _connectedEventCallback;
+            private Interop.LibRPCPort.Stub.DisconnectedEventCallback _disconnectedEventCallback;
+            private Interop.LibRPCPort.Stub.ReceivedEventCallback _receivedEventCallback;
+)__cs_cb";
+
+const char CB_SERVICE_BASE_FRONT[] =
+R"__cs_cb(
+            public abstract class ServiceBase
+            {
+                public string Sender
+                {
+                    get; internal set;
+                }
+
+                public string Instance
+                {
+                    get; internal set;
+                }
+
+                protected ServiceBase()
+                {
+                }
+
+                public abstract void OnCreate();
+                public abstract void OnTerminate();
+)__cs_cb";
+
+const char CB_ON_RECEIVED_EVENT_FRONT[] =
+R"__cs_cb(
+            private int OnReceivedEvent(string sender, string instance, IntPtr port, IntPtr data)
+            {
+                int ret = Interop.LibRPCPort.Parcel.CreateFromPort(out IntPtr p, port);
+
+                if (ret != 0)
+                    return ret;
+
+                Interop.LibRPCPort.Parcel.Create(out IntPtr result);
+                Interop.LibRPCPort.Parcel.ReadInt32(p, out int cmd);
+                ServiceBase b = null;
+
+                foreach (var i in  _services)
+                {
+                    if (i.Instance.Equals(instance))
+                    {
+                        b = i;
+                        break;
+                    }
+                }
+
+                if (b == null)
+                    return -1;
+
+                switch ((MethodId)cmd)
+                {
+)__cs_cb";
+
+const char CB_ON_RECEIVED_EVENT_BACK[] =
+R"__cs_cb(
+                    default:
+                        return -1;
+                }
+
+                Interop.LibRPCPort.Parcel.Destroy(p);
+                Interop.LibRPCPort.Parcel.Destroy(result);
+
+                return 0;
+            }
+)__cs_cb";
+
+const char CB_ON_CONNECTED_EVENT[] =
+R"__cs_cb(
+            private void OnConnectedEvent(string sender, string instance, IntPtr data)
+            {
+                ServiceBase s = Activator.CreateInstance(_serviceType) as ServiceBase;
+                s.Sender = sender;
+                s.Instance = instance;
+                s.OnCreate();
+                _services.Add(s);
+            }
+)__cs_cb";
+
+const char CB_ON_DISCONNECTED_EVENT[] =
+  R"__cs_cb(
+            private void OnDisconnectedEvent(string sender, string instance, IntPtr data)
+            {
+                foreach (var i in _services)
+                {
+                    if (i.Instance.Equals(instance))
+                    {
+                        i.OnTerminate();
+                        _services.Remove(i);
+                        break;
+                    }
+                }
+            }
+)__cs_cb";
+
+const char CB_CTOR_FRONT[] =
+R"__cs_cb(
+            public $$()
+            {
+                Interop.LibRPCPort.Stub.Create(out _stub, "$$");
+                _connectedEventCallback = new Interop.LibRPCPort.Stub.ConnectedEventCallback(OnConnectedEvent);
+                _disconnectedEventCallback = new Interop.LibRPCPort.Stub.DisconnectedEventCallback(OnDisconnectedEvent);
+                _receivedEventCallback = new Interop.LibRPCPort.Stub.ReceivedEventCallback(OnReceivedEvent);
+                Interop.LibRPCPort.Stub.AddReceivedEventCb(_stub, _receivedEventCallback, IntPtr.Zero);
+                Interop.LibRPCPort.Stub.AddConnectedEventCb(_stub, _connectedEventCallback, IntPtr.Zero);
+                Interop.LibRPCPort.Stub.AddDisconnectedEventCb(_stub, _disconnectedEventCallback, IntPtr.Zero);
+)__cs_cb";
+
+const char CB_COMMON_METHODS[] =
+R"__cs_cb(
+            public void Listen(Type serviceType)
+            {
+                if (!typeof(ServiceBase).IsAssignableFrom(serviceType))
+                    throw new InvalidOperationException("Invalid type");
+                _serviceType = serviceType;
+                Interop.LibRPCPort.Stub.Listen(_stub);
+            }
+
+            public IEnumerable<ServiceBase> GetServices()
+            {
+                return _services;
+            }
+)__cs_cb";
+
+const char CB_DISPOSABLE[] =
+R"__cs_cb(
+            #region IDisposable Support
+            private bool disposedValue = false;
+
+            private void Dispose(bool disposing)
+            {
+                if (!disposedValue)
+                {
+                    if (disposing)
+                    {
+                    }
+
+                    foreach (var i in _services)
+                    {
+                        i.OnTerminate();
+                    }
+
+                    _services = null;
+                    if (_stub != IntPtr.Zero)
+                        Interop.LibRPCPort.Stub.Destroy(_stub);
+                    disposedValue = true;
+                }
+            }
+
+            ~$$() {
+                Dispose(false);
+            }
+
+            public void Dispose()
+            {
+                Dispose(true);
+                GC.SuppressFinalize(this);
+            }
+            #endregion
+)__cs_cb";