Implement C# generator for cion 11/265111/7
authorjusung <jusung07.son@samsung.com>
Sun, 10 Oct 2021 07:24:04 +0000 (16:24 +0900)
committerjusung <jusung07.son@samsung.com>
Tue, 12 Oct 2021 09:20:48 +0000 (18:20 +0900)
Change-Id: Ia50cd744c41dd388e1ddc2270f7ac2b412b5b930
Signed-off-by: jusung <jusung07.son@samsung.com>
idlc/gen_cion/cs_cion_cb_version.h [new file with mode: 0644]
idlc/gen_cion/cs_cion_gen_base.cc [new file with mode: 0644]
idlc/gen_cion/cs_cion_gen_base.h [new file with mode: 0644]
idlc/gen_cion/cs_cion_gen_base_cb.h [new file with mode: 0644]
idlc/gen_cion/cs_cion_proxy_gen.cc [new file with mode: 0644]
idlc/gen_cion/cs_cion_proxy_gen.h [new file with mode: 0644]
idlc/gen_cion/cs_cion_proxy_gen_cb.h [new file with mode: 0644]
idlc/gen_cion/cs_cion_stub_gen.cc [new file with mode: 0644]
idlc/gen_cion/cs_cion_stub_gen.h [new file with mode: 0644]
idlc/gen_cion/cs_cion_stub_gen_cb.h [new file with mode: 0644]
idlc/main.cc

diff --git a/idlc/gen_cion/cs_cion_cb_version.h b/idlc/gen_cion/cs_cion_cb_version.h
new file mode 100644 (file)
index 0000000..2408488
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_CB_VERSION_H_
+#define IDLC_CS_CION_GEN_CS_CB_VERSION_H_
+
+const char cs_cion_cb_version[] =
+R"__cs_cb(/*
+ * Generated by tidlc $$.
+ */
+)__cs_cb";
+
+#endif  // IDLC_CS_CION_GEN_CS_CB_VERSION_H_
diff --git a/idlc/gen_cion/cs_cion_gen_base.cc b/idlc/gen_cion/cs_cion_gen_base.cc
new file mode 100644 (file)
index 0000000..42a3ba2
--- /dev/null
@@ -0,0 +1,635 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ctime>
+#include <vector>
+
+#include "idlc/gen_cion/cs_cion_gen_base.h"
+
+namespace {
+#include "idlc/gen_cion/cs_cion_cb_version.h"
+#include "idlc/gen_cion/cs_cion_gen_base_cb.h"
+}
+
+namespace tidl {
+
+CsCionGeneratorBase::CsCionGeneratorBase(std::shared_ptr<Document> doc)
+    : Generator(doc) {
+  type_map_ = {
+      {"char", "byte"}, {"int", "int"}, {"short", "short"},
+      {"long", "long"}, {"string", "string"}, {"bool", "bool"},
+      {"list", "LinkedList"}, {"array", "List"}, {"float", "float"},
+      {"double", "double"}, {"bundle", "Bundle"}, {"void", "void"},
+      {"file", "string"}
+  };
+
+  parcel_type_map_ = {
+    {"char", "Byte"},
+    {"int", "Int"},
+    {"short", "Short"},
+    {"long", "Long"},
+    {"string", "String"},
+    {"bool", "Bool"},
+    {"float", "Float"},
+    {"double", "Double"},
+    {"bundle", "Bundle"},
+    {"file", "String"}
+  };
+}
+
+void CsCionGeneratorBase::GenStructures(std::ofstream& stream) {
+  for (auto& i : GetDocument().GetBlocks()) {
+    if (i->GetType() != Block::TYPE_STRUCTURE)
+      continue;
+    Structure& st = static_cast<Structure&>(*i);
+    GenStructure(stream, st);
+    stream << std::endl;
+  }
+}
+
+void CsCionGeneratorBase::GenStructure(std::ofstream& stream, const Structure& st) {
+  std::vector<std::string> v;
+
+  stream << Tab(1) <<"public sealed class " << st.GetID() << NLine(1);
+  GenBrace(stream, TAB_SIZE, [&]() {
+    for (auto& i : st.GetElements().GetElms()) {
+      GenTemplate(CB_PROPERTY, stream,
+        [&]()->std::string {
+          return ConvertTypeToString(i->GetType());
+        },
+        [&]()->std::string {
+          return i->GetID();
+        });
+      if (i->GetType().ToString() == "bundle") {
+        v.push_back(i->GetID() + " = " + "new Bundle()");
+      }
+    }
+
+    GenTemplate(CB_CTOR, stream,
+      [&]()->std::string {
+        return st.GetID();
+      },
+      [&]()->std::string {
+        std::string str;
+        for (auto& i : v) {
+          str += "            " + i + ";\n";
+        }
+        return str;
+      });
+  });
+}
+
+void CsCionGeneratorBase::GenSerializer(std::ofstream& stream,
+    const Structure& st) {
+  stream << NLine(1) << Tab(3) << "private static void Serialize(Parcel h, "
+                   << st.GetID() << " param)" << NLine(1);
+  GenBrace(stream, TAB_SIZE * 3, [&]() {
+    for (auto& i : st.GetElements().GetElms()) {
+      auto& t = i->GetType();
+      if (!t.IsUserDefinedType() && t.GetMetaType() == nullptr) {
+        stream << Tab(4) << "h.Write"
+                         << ConvertTypeToParcelType(t.ToString())
+                         << "(param."
+                         << i->GetID()
+                         << ");" << NLine(1);
+      } else {
+        stream << Tab(4) << "Serialize(h, param." << i->GetID()
+                         << ");" << NLine(1);
+      }
+    }
+  });
+  stream << NLine(1);
+
+  stream << Tab(3) << "private static void Deserialize(Parcel h, "
+                   << st.GetID() << " param)" << NLine(1);
+  GenBrace(stream, TAB_SIZE * 3, [&]() {
+    for (auto& i : st.GetElements().GetElms()) {
+      auto& t = i->GetType();
+      if (!t.IsUserDefinedType() && t.GetMetaType() == nullptr) {
+        stream << Tab(4) << "var " << i->GetID() << " = "
+                         << "h.Read"
+                         << ConvertTypeToParcelType(t.ToString())
+                         << "();" << NLine(1);
+        stream << Tab(4) << "param." << i->GetID() << " = " << i->GetID()
+               << ";" << NLine(1);
+      } else {
+        stream << Tab(4) << "param." << i->GetID() << " = new "
+                         << ConvertTypeToString(t)
+                         << "();" << NLine(1);
+        stream << Tab(4) << "Deserialize(h, param." << i->GetID()
+                         << ");" << NLine(1);
+      }
+    }
+  });
+}
+
+void CsCionGeneratorBase::GenSerializer(std::ofstream& stream) {
+  for (auto& i : GetDocument().GetBlocks()) {
+    if (i->GetType() == Block::TYPE_STRUCTURE) {
+      const Structure& st = static_cast<const Structure&>(*i);
+      GenSerializer(stream, st);
+    }
+  }
+}
+
+std::string CsCionGeneratorBase::GetFullNameFromType(const BaseType& type,
+    const Interface& iface) {
+  std::string str;
+  if (IsDelegateType(iface, type))
+    str += iface.GetID() + "_";
+
+  str += type.ToString();
+
+  if (type.GetMetaType() != nullptr) {
+    str += "_";
+    str += GetFullNameFromType(*type.GetMetaType(), iface);
+  }
+
+  return str;
+}
+
+std::string CsCionGeneratorBase::GetFullNameFromType(const BaseType& type) {
+  std::string str;
+
+  str += type.ToString();
+
+  if (type.GetMetaType() != nullptr) {
+    str += "_";
+    str += GetFullNameFromType(*type.GetMetaType());
+  }
+
+  return str;
+}
+
+bool CsCionGeneratorBase::HasFile(const Interface& iface, const BaseType& type) {
+  if (type.ToString() == "list" || type.ToString() == "array") {
+     std::string name = GetFullNameFromType(type, iface);
+     if (name == "array_file" || name == "list_file" || name == "file")
+       return true;
+  } else if (type.ToString() == "file") {
+       return true;
+  }
+
+  return false;
+}
+
+bool CsCionGeneratorBase::HasFile(const BaseType& type) {
+  if (type.ToString() == "list" || type.ToString() == "array") {
+     std::string name = GetFullNameFromType(type);
+     if (name == "array_file" || name == "list_file" || name == "file")
+       return true;
+  } else if (type.ToString() == "file") {
+       return true;
+  }
+
+  return false;
+}
+
+bool CsCionGeneratorBase::HasFile(const Interface& iface, const Declaration& decl, bool is_proxy) {
+  for (auto& p : decl.GetParameters().GetParams()) {
+    auto& param_type = p->GetParameterType();
+    if (is_proxy) {
+      if (param_type.GetDirection() != ParameterType::Direction::IN)
+        continue;
+    } else if (decl.GetMethodType() == Declaration::MethodType::DELEGATE) {
+      if (param_type.GetDirection() != ParameterType::Direction::IN)
+        continue;
+    } else {
+      if (param_type.GetDirection() == ParameterType::Direction::IN)
+        continue;
+    }
+
+    if (HasFile(iface, param_type.GetBaseType()) == true)
+      return true;
+  }
+
+  if (is_proxy)
+    return false;
+
+  return HasFile(iface, decl.GetType());
+}
+
+
+void CsCionGeneratorBase::GenShareFile(std::ofstream& stream, const Interface& iface, bool is_proxy) {
+  bool hasFile = false;
+
+  for (auto& d : iface.GetDeclarations().GetDecls()) {
+    hasFile = HasFile(iface, *d, is_proxy);
+    if (hasFile == true)
+      break;
+  }
+
+  if (hasFile == false)
+    return;
+
+  stream << CB_SHARE_FILE_DEF << NLine(1);
+}
+
+void CsCionGeneratorBase::AddSerializerList(const BaseType& type) {
+  if (type.GetMetaType() != nullptr) {
+    serializer_list_[ConvertTypeToString(type)] = &type;
+    AddSerializerList(*type.GetMetaType());
+  }
+}
+
+void CsCionGeneratorBase::GenListSerializer(std::ofstream& stream,
+    const BaseType& type) {
+  stream << NLine(1) << Tab(3) << "private static void Serialize(Parcel h, "
+                   << ConvertTypeToString(type) << " param)" << NLine(1);
+  GenBrace(stream, TAB_SIZE * 3, [&]() {
+    stream << Tab(4)
+           << "h.WriteArrayCount(param.Count);"
+           << NLine(1);
+    stream << Tab(4) << "foreach (var i in param)" << NLine(1);
+    GenBrace(stream, TAB_SIZE * 4, [&]() {
+      auto* ptr = type.GetMetaType();
+      if (ptr == nullptr) return;
+
+      auto& mt = *ptr;
+      if (!mt.IsUserDefinedType() && mt.GetMetaType() == nullptr) {
+        stream << Tab(5) << "h.Write"
+                         << ConvertTypeToParcelType(mt.ToString())
+                         << "(i);" << NLine(1);
+      } else {
+        stream << Tab(5) << "Serialize(h, i);" << NLine(1);
+      }
+    });
+  });
+  stream << NLine(1);
+
+  stream << Tab(3) << "private static void Deserialize(Parcel h, "
+                   << ConvertTypeToString(type) << " param)" << NLine(1);
+  GenBrace(stream, TAB_SIZE * 3, [&]() {
+    stream << Tab(4)
+           << "int l = h.ReadArrayCount();"
+           << NLine(1);
+    stream << Tab(4) << "for (int i = 0; i < l; i++)" << NLine(1);
+    GenBrace(stream, TAB_SIZE * 4, [&]() {
+      auto* ptr = type.GetMetaType();
+      if (ptr == nullptr)
+        return;
+
+      auto& mt = *ptr;
+      if (!mt.IsUserDefinedType() && mt.GetMetaType() == nullptr) {
+        stream << Tab(5) << "var v = h.Read"
+                         << ConvertTypeToParcelType(mt.ToString())
+                         << "();" << NLine(1);
+      } else {
+        stream << Tab(5) << "var v = new " << ConvertTypeToString(mt)
+               << "();" << NLine(1);
+        stream << Tab(5) << "Deserialize(h, v);" << NLine(1);
+      }
+      if (type.ToString() == "list")
+        stream << Tab(5) << "param.AddLast(v);" << NLine(1);
+      else
+        stream << Tab(5) << "param.Add(v);" << NLine(1);
+    });
+  });
+}
+
+void CsCionGeneratorBase::GenListSerializer(std::ofstream& stream) {
+  serializer_list_.clear();
+  for (auto& i : GetDocument().GetBlocks()) {
+    if (i->GetType() == Block::TYPE_STRUCTURE) {
+      const Structure& st = static_cast<const Structure&>(*i);
+      for (auto& j : st.GetElements().GetElms()) {
+        auto& t = j->GetType();
+        AddSerializerList(t);
+      }
+    } else if (i->GetType() == Block::TYPE_INTERFACE) {
+      const Interface& iface = static_cast<const Interface&>(*i);
+      for (auto& j : iface.GetDeclarations().GetDecls()) {
+        auto& t = j->GetType();
+        AddSerializerList(t);
+        for (auto& k : j->GetParameters().GetParams()) {
+          auto& t1 = k->GetParameterType().GetBaseType();
+          AddSerializerList(t1);
+        }
+      }
+    }
+  }
+
+  for (auto& p : serializer_list_) {
+    const BaseType* t = p.second;
+    GenListSerializer(stream, *t);
+  }
+}
+
+std::string CsCionGeneratorBase::ConvertTypeToString(const BaseType& type) {
+  if (type.IsUserDefinedType())
+    return type.ToString();
+
+  if (type.GetMetaType() != nullptr)
+    return type_map_[type.ToString()] + "<" +
+        ConvertTypeToString(*(type.GetMetaType())) + ">";
+
+  return type_map_[type.ToString()];
+}
+
+std::string CsCionGeneratorBase::ConvertTypeToParcelType(const std::string& key) {
+  return parcel_type_map_[key];
+}
+
+std::string CsCionGeneratorBase::ConvertTypeToDeserializer(
+    const BaseType& type, std::string id, std::string parcel,
+    bool make_new_type, std::string iface_id) {
+  if (type.IsUserDefinedType() ||
+      type.GetMetaType() != nullptr) {
+    std::string n;
+
+    if (type.GetMetaType() != nullptr)
+      n = ConvertTypeToString(type);
+    else
+      n = type.ToString();
+
+    std::string ret;
+
+    if (make_new_type)
+      ret = n + " ";
+
+    if (IsDelegateType(type)) {
+      ret += id + " = new " + n
+          + "(peerInfo, new WeakReference(b));\n";
+      ret += "CallbackBase.";
+    } else {
+      ret += id + " = new " + n +"();\n";
+    }
+    if (iface_id != "")
+      ret += iface_id + ".";
+    ret += "Deserialize(" + parcel + ", " + id +");\n";
+    return ret;
+  }
+
+  std::string ret;
+  if (make_new_type) {
+    ret = ConvertTypeToString(type) + " "
+        + id + " = " + parcel + ".Read"
+        + parcel_type_map_[type.ToString()]
+        + "();\n";
+  } else {
+    ret = id + " = " + parcel + ".Read"
+        + parcel_type_map_[type.ToString()]
+        + "();\n";
+  }
+
+  return ret;
+}
+
+std::string CsCionGeneratorBase::ConvertTypeToSerializer(
+    const BaseType& type, std::string id, std::string parcel,
+    std::string iface_id) {
+  std::string ret;
+
+  if (type.IsUserDefinedType() ||
+      type.GetMetaType() != nullptr) {
+    if (IsDelegateType(type))
+      return "CallbackBase.Serialize(" + parcel + ", " + id + ");\n";
+    if (iface_id != "")
+      ret += iface_id + ".";
+    ret += "Serialize(" + parcel + ", " + id + ");\n";
+    return ret;
+  }
+
+  ret += parcel + ".Write"
+      + parcel_type_map_[type.ToString()] + "(" + id + ");\n";
+
+  return ret;
+}
+
+std::string CsCionGeneratorBase::Tab(int cnt) {
+  std::string t;
+
+  for (int i = 0; i < cnt; i++) {
+    t += "    ";
+  }
+
+  return t;
+}
+
+std::string CsCionGeneratorBase::NLine(int cnt) {
+  std::string t;
+
+  for (int i = 0; i < cnt; i++) {
+    t += "\n";
+  }
+
+  return t;
+}
+
+void CsCionGeneratorBase::GenWriteBundle(std::ofstream& stream,
+    const std::string& id) {
+  GenTemplate(CB_WRITE_BUNDLE, stream,
+    [&]()->std::string {
+      return id;
+    },
+    [&]()->std::string {
+      return id;
+    });
+}
+
+void CsCionGeneratorBase::GenMethodId(std::ofstream& stream,
+    const Interface& iface) {
+  stream << Tab(3) << "private enum MethodId : int" << NLine(1);
+  GenBrace(stream, TAB_SIZE * 3, [&]() {
+    int cnt = 2;
+    stream << Tab(4) << "__Result = 0," << NLine(1);
+    stream << Tab(4) << "__Callback = 1," << NLine(1);
+    for (auto& i : iface.GetDeclarations().GetDecls()) {
+      if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+        continue;
+      stream << Tab(4)
+             << i->GetID() << " = " << cnt++ << "," << NLine(1);
+    }
+  });
+}
+
+void CsCionGeneratorBase::GenDelegateId(std::ofstream& stream,
+    const Interface& iface) {
+  stream << Tab(3) << "private enum DelegateId : int" << NLine(1);
+  GenBrace(stream, TAB_SIZE * 3, [&]() {
+    int cnt = 1;
+    for (auto& i : iface.GetDeclarations().GetDecls()) {
+        if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+          continue;
+        stream << Tab(4)
+               << i->GetID() << " = " << cnt++ << "," << NLine(1);
+    }
+  });
+  stream << NLine(1);
+}
+
+void CsCionGeneratorBase::GenDeclaration(std::ofstream& stream,
+                                     const Declaration& decl, bool semicol) {
+  stream << ConvertTypeToString(decl.GetType()) << " "
+         << decl.GetID() << "(";
+  GenParameters(stream, decl.GetParameters());
+  if (semicol)
+    stream << ");";
+  else
+    stream << ")";
+}
+
+void CsCionGeneratorBase::GenParameters(std::ofstream& stream,
+    const Parameters& ps) {
+  stream << GetParameters(ps);
+}
+
+std::string CsCionGeneratorBase::GetParameters(const Parameters& ps) {
+  bool first = true;
+  std::string ret;
+  for (auto& i : ps.GetParams()) {
+    if (!first) {
+      ret += ", ";
+    }
+
+    auto dir = i->GetParameterType().GetDirection();
+    if (dir == ParameterType::Direction::OUT) {
+      ret += "out ";
+    } else if (dir == ParameterType::Direction::REF) {
+      ret += "ref ";
+    }
+
+    ret += ConvertTypeToString(i->GetParameterType().GetBaseType())
+        + " " + i->GetID();
+    first = false;
+  }
+
+  return ret;
+}
+
+void CsCionGeneratorBase::GenCallbacks(std::ofstream& stream,
+                                   const Interface& iface, bool is_proxy) {
+  stream << CB_CALLBACK_BASE;
+
+  for (auto& i : iface.GetDeclarations().GetDecls()) {
+    if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+          continue;
+    GenCallback(stream, *i, iface.GetID(), is_proxy);
+  }
+}
+
+void CsCionGeneratorBase::GenCallback(std::ofstream& stream,
+                                  const Declaration& decl,
+                                  const std::string& id, bool is_proxy) {
+  stream << Tab(3) << "public sealed class " << decl.GetID()
+         << " : CallbackBase" << NLine(1);
+  GenBrace(stream, TAB_SIZE * 3, [&]() {
+    if (is_proxy) {
+      GenTemplate(
+      CB_CALLBACK_CTOR_PROXY, stream,
+      [&]()->std::string {
+        return decl.GetID();
+      },
+      [&]()->std::string {
+        return decl.GetID();
+      });
+    } else {
+      GenTemplate(
+        CB_CALLBACK_CTOR_STUB, stream,
+        [&]()->std::string {
+          return decl.GetID();
+        },
+        [&]()->std::string {
+          return decl.GetID();
+        },
+        [&]()->std::string {
+          return id;
+      });
+    }
+    stream << NLine(1);
+
+    if (is_proxy) {
+      stream << Tab(4) << "public delegate void Callback(";
+      GenParameters(stream, decl.GetParameters());
+      stream << ");" << NLine(1);
+      stream << Tab(4) << "public event Callback Received;" << NLine(2);
+      GenReceivedEvent(stream, decl, id);
+    } else {
+      GenTemplate(
+        CB_CALLBACK_STUB_MEMBERS, stream,
+        [&]()->std::string {
+          return id;
+        });
+      GenInvokeMethod(stream, decl, id);
+    }
+  });
+  stream << NLine(1);
+}
+
+void CsCionGeneratorBase::GenReceivedEvent(std::ofstream& stream,
+                                       const Declaration& decl,
+                                       const std::string& id) {
+  stream << Tab(4) << "internal override void OnReceivedEvent(Parcel parcel)"
+         << NLine(1);
+  GenBrace(stream, TAB_SIZE * 4, [&]() {
+    int cnt = 1;
+    for (auto& i : decl.GetParameters().GetParams()) {
+      std::string v = "param" + std::to_string(cnt);
+      std::string c = ConvertTypeToDeserializer(
+          i->GetParameterType().GetBaseType(), v, "parcel", true, id);
+      stream << AddIndent(TAB_SIZE * 5, c);
+      cnt++;
+    }
+
+    cnt = 1;
+    stream << Tab(5) << "Received?.Invoke(";
+    for (int i = 0; i < decl.GetParameters().GetParams().size(); i++) {
+      if (cnt != 1) {
+        stream << ", ";
+      }
+      std::string v = "param" + std::to_string(cnt);
+        stream << v;
+      cnt++;
+    }
+    stream << ");" << NLine(1);
+  });
+  stream << NLine(1);
+}
+
+void CsCionGeneratorBase::GenInvokeMethod(std::ofstream& stream,
+                                      const Declaration& decl,
+                                      const std::string& id) {
+  GenTemplate(CB_CALLBACK_INVOKE_METHOD, stream,
+      [&]()->std::string {
+        return GetParameters(decl.GetParameters());
+      },
+      [&]()->std::string {
+        std::string m;
+        for (auto& i : decl.GetParameters().GetParams()) {
+          auto& pt = i->GetParameterType();
+          m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p", id);
+        }
+        return AddIndent(TAB_SIZE * 6, m);
+      },
+      [&]()->std::string {
+        std::string m;
+        for (auto& i : decl.GetParameters().GetParams()) {
+          auto& pt = i->GetParameterType();
+          if(HasFile(pt.GetBaseType()))
+            m += "_serverBase.ShareFile(" + i->GetID() + ");\n";
+        }
+        return AddIndent(TAB_SIZE * 6, m);
+      });
+}
+
+void CsCionGeneratorBase::GenVersion(std::ofstream& stream) {
+  GenTemplate(::cs_cion_cb_version, stream,
+    [&]()->std::string {
+      return FULLVER;
+    });
+  stream << NLine(1);
+}
+}  // namespace tidl
diff --git a/idlc/gen_cion/cs_cion_gen_base.h b/idlc/gen_cion/cs_cion_gen_base.h
new file mode 100644 (file)
index 0000000..b9c0685
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_GEN_BASE_H_
+#define IDLC_CS_CION_GEN_CS_GEN_BASE_H_
+
+#include <memory>
+#include <string>
+#include <map>
+
+#include "idlc/ast/type.h"
+#include "idlc/ast/structure.h"
+#include "idlc/gen/generator.h"
+
+namespace tidl {
+
+class CsCionGeneratorBase : public Generator {
+ public:
+  explicit CsCionGeneratorBase(std::shared_ptr<Document> doc);
+  virtual ~CsCionGeneratorBase() = default;
+
+  void GenVersion(std::ofstream& stream);
+  void GenStructures(std::ofstream& stream);
+  void GenStructure(std::ofstream& stream, const Structure& st);
+  void GenSerializer(std::ofstream& stream);
+  void GenSerializer(std::ofstream& stream, const Structure& st);
+  void GenListSerializer(std::ofstream& stream);
+  void GenListSerializer(std::ofstream& stream, const BaseType& type);
+  void GenShareFile(std::ofstream& stream, const Interface& iface, bool is_proxy);
+  void GenMethodId(std::ofstream& stream, const Interface& iface);
+  void GenDelegateId(std::ofstream& stream, const Interface& iface);
+  void GenDeclaration(std::ofstream& stream,
+                      const Declaration& decl, bool semicol = true);
+  void GenParameters(std::ofstream& stream, const Parameters& ps);
+  void GenCallbacks(std::ofstream& stream, const Interface& iface,
+                    bool is_proxy);
+
+  std::string GetFullNameFromType(const BaseType& type, const Interface& iface);
+  std::string GetFullNameFromType(const BaseType& type);
+  bool HasFile(const Interface& iface, const Declaration& decl, bool is_proxy);
+  bool HasFile(const Interface& iface, const BaseType& type);
+  bool HasFile(const BaseType& type);
+  std::string ConvertTypeToString(const BaseType& type);
+  std::string ConvertTypeToDeserializer(const BaseType& type,
+                                        std::string id, std::string parcel,
+                                        bool make_new_type = true,
+                                        const std::string iface_id = "");
+  std::string ConvertTypeToSerializer(const BaseType& type,
+                                      std::string id, std::string parcel,
+                                      const std::string iface_id = "");
+  std::string ConvertTypeToParcelType(const std::string& key);
+  std::string GetParameters(const Parameters& ps);
+  std::string Tab(int cnt);
+  std::string NLine(int cnt);
+
+ protected:
+  const int TAB_SIZE = 4;
+
+ private:
+  void GenWriteBundle(std::ofstream& stream, const std::string& id);
+  void AddSerializerList(const BaseType& type);
+  void GenCallback(std::ofstream& stream, const Declaration& decl,
+                   const std::string& id, bool is_proxy);
+  void GenReceivedEvent(std::ofstream& stream, const Declaration& decl,
+                        const std::string& id);
+  void GenInvokeMethod(std::ofstream& stream, const Declaration& decl,
+                       const std::string& id);
+
+ private:
+  std::map<std::string, std::string> type_map_;
+  std::map<std::string, std::string> parcel_type_map_;
+  std::map<std::string, const BaseType*> serializer_list_;
+};
+
+}  // namespace tidl
+
+#endif  // IDLC_CS_CION_GEN_CS_GEN_BASE_H_
\ No newline at end of file
diff --git a/idlc/gen_cion/cs_cion_gen_base_cb.h b/idlc/gen_cion/cs_cion_gen_base_cb.h
new file mode 100644 (file)
index 0000000..04a7cb5
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_BASE_CB_H_
+#define IDLC_CS_CION_BASE_CB_H_
+
+const char CB_CALLBACK_BASE[] =
+R"__cs_cb(
+            public abstract class CallbackBase
+            {
+                internal int Id;
+                internal int SeqId;
+                internal bool Once;
+                private static volatile int _seqNum = 0;
+
+                public string Tag
+                {
+                    get
+                    {
+                        return Id.ToString() + "::" + SeqId.ToString();
+                    }
+                }
+
+                public CallbackBase(int delegateId, bool once)
+                {
+                    Id = delegateId;
+                    SeqId = _seqNum++;
+                    Once = once;
+                }
+
+                internal virtual void OnReceivedEvent(Parcel p) {}
+
+                internal static void Serialize(Parcel h, CallbackBase param)
+                {
+                    h.WriteInt(param.Id);
+                    h.WriteInt(param.SeqId);
+                    h.WriteBool(param.Once);
+                }
+
+                internal static void Deserialize(Parcel h, CallbackBase param)
+                {
+                    param.Id = h.ReadInt();
+                    param.SeqId = h.ReadInt();
+                    param.Once = h.ReadBool();
+                }
+            }
+
+)__cs_cb";
+
+const char CB_CALLBACK_CTOR_PROXY[] =
+R"__cs_cb(                public $$(bool once = false) : base((int)DelegateId.$$, once)
+                {
+                }
+)__cs_cb";
+
+const char CB_CALLBACK_CTOR_STUB[] =
+R"__cs_cb(                internal $$(PeerInfo peerInfo, WeakReference service) : base((int)DelegateId.$$, false)
+                {
+                    _peerInfo = peerInfo;
+                    _service = service;
+                    _serverBase = ($$)service.Target;
+                }
+)__cs_cb";
+
+const char CB_CALLBACK_STUB_MEMBERS[] =
+R"__cs_cb(                private PeerInfo _peerInfo;
+                private WeakReference _service;
+                private bool _valid = true;
+                private $$ _serverBase;
+)__cs_cb";
+
+const char CB_CALLBACK_INVOKE_METHOD[] =
+R"__cs_cb(
+                public void Invoke($$)
+                {
+                    if (!_service.IsAlive)
+                        throw new InvalidProtocolException();
+                    if (Once && !_valid)
+                        throw new InvalidCallbackException();
+
+                    using (var p = new Parcel())
+                    {
+                        p.WriteInt((int)MethodId.__Callback);
+                        Serialize(p, this);
+$$
+                        // Send
+                        DataPayload dp = new DataPayload(p.ToBytes());
+                        _serverBase.SendPayloadAsync(dp);
+                        _valid = false;
+
+$$
+                    }
+                }
+)__cs_cb";
+
+const char CB_PROPERTY[] = R"__cs_cb(        public $$ $$ { get; set; }
+)__cs_cb";
+
+const char CB_CTOR[] = R"__cs_cb(
+        public $$()
+        {
+$$
+        }
+)__cs_cb";
+
+const char CB_WRITE_BUNDLE[] =
+R"__cs_cb(
+                if (param.$$ != null)
+                {
+                    h.WriteBundle(param.$$);
+                }
+                else
+                {
+                    h.WriteBundle(new Bundle());
+                }
+)__cs_cb";
+
+
+const char CB_SHARE_FILE_DEF[] =
+R"__cs_cb(
+            private void ShareFile(IEnumerable<string> paths)
+            {
+                if (paths == null)
+                    throw new ArgumentException("Invalid path");
+
+                foreach (string path in paths)
+                {
+                    ShareFile(path);
+                }
+
+            }
+
+            private void ShareFile(string path)
+            {
+                if (path == null)
+                    throw new ArgumentException("Invalid path");
+
+                FilePayload fp = new FilePayload(path);
+                base.SendPayloadAsync(fp);
+            }
+)__cs_cb";
+
+#endif  // IDLC_CS_CION_BASE_CB_H_
diff --git a/idlc/gen_cion/cs_cion_proxy_gen.cc b/idlc/gen_cion/cs_cion_proxy_gen.cc
new file mode 100644 (file)
index 0000000..a137bb7
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/cs_cion_proxy_gen.h"
+
+namespace {
+#include "idlc/gen_cion/cs_cion_proxy_gen_cb.h"
+}
+
+namespace tidl {
+
+CsCionProxyGen::CsCionProxyGen(std::shared_ptr<Document> doc)
+    : CsCionGeneratorBase(doc) {}
+
+void CsCionProxyGen::OnInitGen(std::ofstream& stream) {
+  GenVersion(stream);
+  stream << "using System;" << NLine(1)
+         << "using System.Collections.Generic;" << NLine(1)
+         << "using System.Threading;" << NLine(1)
+         << "using Tizen.Applications;" << NLine(1)
+         << "using Tizen.Applications.RPCPort;" << NLine(1)
+         << "using Tizen.Applications.Cion;" << NLine(1);
+  GenNamespace(stream);
+}
+
+void CsCionProxyGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void CsCionProxyGen::GenNamespace(std::ofstream& stream) {
+  stream << "namespace Cion" << NLine(1);
+  GenBrace(stream, 0, [&]() {
+    stream << "namespace " << GetFileNamespace() << NLine(1);
+    GenBrace(stream, 0, [&]() {
+      GenStructures(stream);
+      stream << Tab(1) << "namespace Proxy" << NLine(1);
+      GenBrace(stream, TAB_SIZE, [&]() {
+        GenInterfaces(stream);
+      });
+    });
+  });
+}
+
+void CsCionProxyGen::GenInterfaces(std::ofstream& stream) {
+  for (auto& i : GetDocument().GetBlocks()) {
+    if (i->GetType() != Block::TYPE_INTERFACE)
+      continue;
+    Interface& iface = static_cast<Interface&>(*i);
+    GenInterface(stream, iface);
+    stream << NLine(1);
+  }
+}
+
+void CsCionProxyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+  stream << Tab(2) << "public class " << iface.GetID()
+         << " : ClientBase" << NLine(1);
+  GenBrace(stream, TAB_SIZE * 2, [&]() {
+    stream << ReplaceAll(CB_DATA_MEMBERS, "<VERSION>", FULLVER);
+    GenCallbacks(stream, iface, true);
+    GenDelegateId(stream, iface);
+    GenMethodId(stream, iface);
+    stream << CB_EVENT_METHODS;
+    GenSerializer(stream);
+    GenListSerializer(stream);
+    GenShareFile(stream, iface, true);
+    GenCtor(stream, iface);
+    GenConnectMethod(stream, iface);
+    GenMethods(stream, iface);
+  });
+}
+
+void CsCionProxyGen::GenCtor(std::ofstream& stream, const Interface& iface) {
+  bool securityCheck = false;
+  std::string m = "public $$(string serviceName) : base(serviceName, new SecurityInfo {";
+
+  for (auto& attr : iface.GetAttributes().GetAttrs()) {
+    if (attr->GetKey() == "ca_path") {
+      m += "CaPath = \"" + attr->GetValue() + "\", ";
+      securityCheck = true;
+    } else if (attr->GetKey() == "cert_path") {
+      m += "CertPath = \"" + attr->GetValue() + "\", ";
+      securityCheck = true;
+    } else if (attr->GetKey() == "private_key") {
+      m += "PrivateKeyPath = \"" + attr->GetValue() + "\", ";
+      securityCheck = true;
+    }
+  }
+
+  auto const pos = m.find_last_of(',');
+  m = m.substr(0, pos);
+
+  if (securityCheck)
+    m += "})";/* base(serviceName, new SecurityInfo {CertPath = xxx, ... ) */
+   else
+    m += ")"; /* base(serviceName) */
+
+  m += NLine(1);
+  m += "{\n";
+  m += "    ServiceName = serviceName;\n";
+  m += "}";
+
+  GenTemplate(AddIndent(TAB_SIZE * 3, m), stream,
+    [&]()->std::string {
+      return iface.GetID();
+    });
+}
+
+void CsCionProxyGen::GenConnectMethod(std::ofstream& stream,
+    const Interface& iface) {
+  stream << CB_CONNECT_METHOD;
+  stream << NLine(1);
+}
+
+void CsCionProxyGen::GenMethods(std::ofstream& stream, const Interface& iface) {
+  auto& decls = iface.GetDeclarations();
+
+  for (auto& i : decls.GetDecls()) {
+    if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+      continue;
+
+    if (!i->GetComments().empty())
+      stream << AddIndent(TAB_SIZE * 3, i->GetComments());
+
+    stream << Tab(3) << "public ";
+    GenDeclaration(stream, *i, false);
+    stream << NLine(1);
+    GenBrace(stream, TAB_SIZE * 3, [&]() {
+      GenInvocation(stream, *i);
+    });
+    stream << NLine(1);
+  }
+}
+
+void CsCionProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) {
+  GenTemplate(CB_INVOCATION_PRE, stream,
+    [&]()->std::string {
+      std::string st;
+      st += Tab(5)
+         + "p.WriteInt((int)MethodId." + decl.GetID() + ");" + NLine(1);
+      std::string m;
+      std::string l;
+      for (auto& i : decl.GetParameters().GetParams()) {
+        auto& pt = i->GetParameterType();
+        if (pt.GetDirection() == ParameterType::Direction::OUT)
+          continue;
+        m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p");
+        if (IsDelegateType(pt.GetBaseType())) {
+          l += "_delegateList.Add(" + i->GetID() + ");\n";
+        }
+      }
+
+      st += AddIndent(TAB_SIZE * 5, m) + NLine(1);
+
+      st += Tab(5) + "lock (_lock)" + NLine(1);
+      st += Tab(5) + "{" + NLine(1);
+      if (!l.empty())
+        st += AddIndent(TAB_SIZE * 6, l) + NLine(1);
+
+      // Deserialize
+      if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
+        st += CB_ASYNC_INVOCATION_MID;
+      } else {
+        st += CB_SYNC_INVOCATION_MID;
+      }
+
+      for (auto& i : decl.GetParameters().GetParams()) {
+         auto& pt = i->GetParameterType();
+         if (pt.GetDirection() == ParameterType::Direction::OUT)
+           continue;
+
+         if (pt.GetBaseType().ToString() == "file" ||
+             (pt.GetBaseType().GetMetaType() != nullptr &&
+             pt.GetBaseType().GetMetaType()->ToString() == "file")) {
+           st += GenTemplateString(CB_SHARE_FILE, [&]()->std::string {
+             std::string str = "";
+             str += Tab(7) + "ShareFile(" + i->GetID() + ");";
+             return str;
+           });
+         }
+       }
+
+      // Deserialize
+      if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
+        st += Tab(5) + "}";
+        return st;
+      }
+
+      for (auto& i : decl.GetParameters().GetParams()) {
+        if (i->GetParameterType().GetDirection() ==
+            ParameterType::Direction::IN) {
+          continue;
+        }
+
+        std::string c = ConvertTypeToDeserializer(
+            i->GetParameterType().GetBaseType(),
+            i->GetID(), "parcelReceived", false);
+        if (c != "")
+          st += AddIndent(TAB_SIZE * 6, c);
+      }
+
+      if (decl.GetType().ToString() != "void") {
+        st += AddIndent(TAB_SIZE * 6,
+                        ConvertTypeToDeserializer(decl.GetType(),
+                                                  "ret", "parcelReceived"));
+      }
+
+      st += Tab(6) + "parcelReceived.Dispose();" + NLine(1);
+      st += NLine(1) + Tab(6) + "return ret;" + NLine(1);
+      st += Tab(5) + "}";
+
+      return st;
+    });
+}
+
+}  // namespace tidl
diff --git a/idlc/gen_cion/cs_cion_proxy_gen.h b/idlc/gen_cion/cs_cion_proxy_gen.h
new file mode 100644 (file)
index 0000000..df3eeec
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_PROXY_GEN_H_
+#define IDLC_CS_CION_GEN_CS_PROXY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/cs_cion_gen_base.h"
+
+namespace tidl {
+
+class CsCionProxyGen : public CsCionGeneratorBase {
+ public:
+  explicit CsCionProxyGen(std::shared_ptr<Document> doc);
+  virtual ~CsCionProxyGen() = default;
+
+  void OnInitGen(std::ofstream& stream) override;
+  void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+  void GenNamespace(std::ofstream& stream);
+  void GenInterfaces(std::ofstream& stream);
+  void GenInterface(std::ofstream& stream, const Interface& iface);
+  void GenCtor(std::ofstream& stream, const Interface& iface);
+  void GenConnectMethod(std::ofstream& stream, const Interface& iface);
+  void GenMethods(std::ofstream& stream, const Interface& iface);
+  void GenInvocation(std::ofstream& stream, const Declaration& decl);
+};
+
+}  // namespace tidl
+
+#endif  // IDLC_CS_CION_GEN_CS_PROXY_GEN_H_
\ No newline at end of file
diff --git a/idlc/gen_cion/cs_cion_proxy_gen_cb.h b/idlc/gen_cion/cs_cion_proxy_gen_cb.h
new file mode 100644 (file)
index 0000000..09f2551
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_PROXY_GEN_CB_H_
+#define IDLC_CS_CION_GEN_CS_PROXY_GEN_CB_H_
+
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
+const char CB_DATA_MEMBERS[] =
+R"__cs_cb(            public delegate void DiscoveredEvent(object sender, PeerInfo peerInfo);
+            public delegate void DisconnectedEvent(object sender);
+            public delegate void FileReceivedEvent(object sender, FilePayload payload, PayloadTransferStatus status);
+            public delegate void ConnectionResultEvent(object sender, ConnectionResult result);
+
+            public event DiscoveredEvent Discovered;
+            public event DisconnectedEvent Disconnected;
+            public event FileReceivedEvent FileReceived;
+            public event ConnectionResultEvent ConnectionResult;
+
+            public new string ServiceName;
+
+            private static readonly string _tidlVersion = "<VERSION>";
+            private bool _online = false;
+            private Object _lock = new Object();
+            private List<CallbackBase> _delegateList = new List<CallbackBase>();
+)__cs_cb";
+
+const char CB_EVENT_METHODS[] =
+R"__cs_cb(
+            protected override void OnConnectionResult(PeerInfo peerInfo, ConnectionResult result)
+            {
+               if (result.Status == ConnectionStatus.OK) {
+                    _online = true;
+               }
+
+                ConnectionResult?.Invoke(this, result);
+            }
+
+            protected override void OnDisconnected(PeerInfo peerInfo)
+            {
+                _online = false;
+                Disconnected?.Invoke(this);
+            }
+
+            protected override void OnDiscovered(PeerInfo peerInfo)
+            {
+                Discovered?.Invoke(this, peerInfo);
+            }
+
+             protected override void OnPayloadReceived(Payload payload, PayloadTransferStatus status)
+            {
+                if(payload.PayloadType == PayloadType.FilePayload) {
+                    FileReceived?.Invoke(this, (FilePayload)payload, status);
+                } else {
+                    Parcel parcelReceived;
+
+                    try
+                    {
+                        parcelReceived = new Parcel(((DataPayload)payload).Data);
+                    }
+                    catch (InvalidIOException)
+                    {
+                        return;
+                    }
+
+                    using (parcelReceived)
+                    {
+                        int cmd = parcelReceived.ReadInt();
+                        if (cmd != (int)MethodId.__Callback)
+                        {
+                            return;
+                        }
+
+                        ProcessReceivedEvent(parcelReceived);
+                    }
+                }
+            }
+
+            private void ProcessReceivedEvent(Parcel parcel)
+            {
+                int id = parcel.ReadInt();
+                int seqId = parcel.ReadInt();
+                bool once = parcel.ReadBool();
+
+                foreach (var i in _delegateList)
+                {
+                    if ((int)i.Id == id && i.SeqId == seqId)
+                    {
+                        i.OnReceivedEvent(parcel);
+                        if (i.Once)
+                            _delegateList.Remove(i);
+                        break;
+                    }
+                }
+            }
+)__cs_cb";
+
+const char CB_CONNECT_METHOD[] =
+R"__cs_cb(
+            /// <summary>
+            /// Starts discovering cion servers.
+            /// </summary>
+            /// <exception cref="InvalidOperationException">Thrown when the discovery operation is already in progress.</exception>
+            public new void TryDiscovery() {
+                base.TryDiscovery();
+            }
+
+            /// <summary>
+            /// Connects to the stub app.
+            /// </summary>
+            /// <param name="peer">The peer to connect.</param>
+            /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege>
+            /// <privilege>http://tizen.org/privilege/internet</privilege>
+            /// <exception cref="PermissionDeniedException">
+            /// Thrown when the permission is denied.
+            /// </exception>
+            /// <remark> If you want to use this method, you must add privileges.</remark>
+            public new void Connect(PeerInfo peer)
+            {
+                base.Connect(peer);
+            }
+
+            /// <summary>
+            /// Disconnects from the stub app.
+            /// </summary>
+            public new void Disconnect()
+            {
+                base.Disconnect();
+            }
+
+            /// <summary>
+            /// Disposes delegate objects in this interface
+            /// </summary>
+            /// <param name="tag">The tag string from delegate object</param>
+            void DisposeCallback(string tag)
+            {
+                foreach (var i in _delegateList)
+                {
+                    if (i.Tag.Equals(tag))
+                    {
+                        _delegateList.Remove(i);
+                        return;
+                    }
+                }
+            }
+)__cs_cb";
+
+const char CB_INVOCATION_PRE[] =
+R"__cs_cb(                if (!_online)
+                    throw new NotConnectedSocketException();
+
+                using (Parcel p = new Parcel())
+                {
+$$
+                }
+)__cs_cb";
+
+
+const char CB_SHARE_FILE[] =
+R"__cs_cb(
+                        try
+                        {
+$$
+                        }
+                        catch (InvalidIOException)
+                        {
+                            throw new InvalidIOException();
+                        }
+)__cs_cb";
+
+const char CB_ASYNC_INVOCATION_MID[] =
+R"__cs_cb(                        // Send
+                                               DataPayload dp = new DataPayload(p.ToBytes());
+                        base.SendPayloadAsync(dp);
+)__cs_cb";
+
+const char CB_SYNC_INVOCATION_MID[] =
+R"__cs_cb(                        // Send
+                        byte[] dataReceived = base.SendData(p.ToBytes(), 5 * 1000);
+
+                        Parcel parcelReceived = new Parcel(dataReceived);
+
+                        int cmd = parcelReceived.ReadInt();
+                        if (cmd != (int)MethodId.__Result)
+                            throw new InvalidProtocolException();
+)__cs_cb";
+#endif  // IDLC_CS_CION_GEN_CS_PROXY_GEN_CB_H_
diff --git a/idlc/gen_cion/cs_cion_stub_gen.cc b/idlc/gen_cion/cs_cion_stub_gen.cc
new file mode 100644 (file)
index 0000000..1374024
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/cs_cion_stub_gen.h"
+
+namespace {
+#include "idlc/gen_cion/cs_cion_stub_gen_cb.h"
+}
+
+namespace tidl {
+
+CsCionStubGen::CsCionStubGen(std::shared_ptr<Document> doc)
+    : CsCionGeneratorBase(doc) {}
+
+void CsCionStubGen::OnInitGen(std::ofstream& stream) {
+  GenVersion(stream);
+  stream << "using System;" << NLine(1)
+         << "using System.Collections.Generic;" << NLine(1)
+         << "using Tizen.Applications;" << NLine(1)
+         << "using Tizen.Applications.RPCPort;" << NLine(1)
+         << "using Tizen.Applications.Cion;" << NLine(1);
+
+  GenNamespace(stream);
+}
+
+void CsCionStubGen::OnFiniGen(std::ofstream& stream) {}
+
+void CsCionStubGen::GenNamespace(std::ofstream& stream) {
+  stream << "namespace Cion" << NLine(1);
+  GenBrace(stream, 0, [&]() {
+    stream << "namespace " << GetFileNamespace() << NLine(1);
+    GenBrace(stream, 0, [&]() {
+      GenStructures(stream);
+      stream << Tab(1) << "namespace Stub" << NLine(1);
+      GenBrace(stream, TAB_SIZE, [&]() {
+        GenInterfaces(stream);
+      });
+    });
+  });
+}
+
+void CsCionStubGen::GenInterfaces(std::ofstream& stream) {
+  for (auto& i : GetDocument().GetBlocks()) {
+    if (i->GetType() != Block::TYPE_INTERFACE)
+      continue;
+    Interface& iface = static_cast<Interface&>(*i);
+    GenInterface(stream, iface);
+    stream << std::endl;
+  }
+}
+
+void CsCionStubGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+  stream << Tab(2) << "public sealed class " << iface.GetID()
+         << " : ServerBase" << NLine(1);
+  GenBrace(stream, TAB_SIZE * 2, [&]() {
+    stream << ReplaceAll(CB_DATA_MEMBERS, "<VERSION>", FULLVER);
+    GenServiceBase(stream, iface);
+    GenCallbacks(stream, iface, false);
+    GenDelegateId(stream, iface);
+    GenMethodId(stream, iface);
+    GenSerializer(stream);
+    GenListSerializer(stream);
+    GenReceivedAsyncEvent(stream, iface);
+    GenReceivedSyncEvent(stream, iface);
+    GenConnectionRequestedEvent(stream);
+    GenDisconnectedEvent(stream);
+    GenConnectedEvent(stream);
+    GenShareFile(stream, iface, false);
+    GenCtor(stream, iface);
+    GenCommonMethods(stream);
+  });
+}
+
+void CsCionStubGen::GenServiceBase(std::ofstream& stream, const Interface& iface) {
+  stream << CB_SERVICE_BASE_FRONT;
+  GenDeclarations(stream, iface.GetDeclarations());
+  stream << NLine(1);
+  stream << AddIndent(TAB_SIZE * 3, "}\n");
+}
+
+void CsCionStubGen::GenDeclarations(std::ofstream& stream,
+                                const Declarations& decls) {
+  for (auto& i : decls.GetDecls()) {
+    if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+      continue;
+    if (!i->GetComments().empty())
+      stream << NLine(1) << AddIndent(TAB_SIZE * 4, i->GetComments());
+    stream << Tab(4) << "public abstract ";
+    GenDeclaration(stream, *i);
+    stream << NLine(1);
+  }
+}
+
+void CsCionStubGen::GenReceivedSyncEvent(std::ofstream& stream,
+    const Interface& iface) {
+  stream << CB_ON_RECEIVED_SYNC_EVENT_FRONT;
+  for (auto& i : iface.GetDeclarations().GetDecls()) {
+    if (i->GetMethodType() != Declaration::MethodType::SYNC)
+      continue;
+    stream << Tab(7) << "case MethodId." << i->GetID() << ":" << NLine(1);
+    GenBrace(stream, TAB_SIZE * 7, [&]() {
+      GenSyncInvocation(stream, *i);
+      stream << Tab(8) << "break;" << NLine(1);
+    });
+  }
+  stream << CB_ON_RECEIVED_SYNC_EVENT_BACK;
+}
+
+void CsCionStubGen::GenReceivedAsyncEvent(std::ofstream& stream,
+    const Interface& iface) {
+  stream << CB_ON_RECEIVED_ASYNC_EVENT_FRONT;
+  for (auto& i : iface.GetDeclarations().GetDecls()) {
+    if (i->GetMethodType() != Declaration::MethodType::ASYNC)
+      continue;
+    stream << Tab(6) << "case MethodId." << i->GetID() << ":" << NLine(1);
+    GenBrace(stream, TAB_SIZE * 6, [&]() {
+      GenAsyncInvocation(stream, *i);
+      stream << Tab(7) << "break;" << NLine(1);
+    });
+  }
+  stream << CB_ON_RECEIVED_ASYNC_EVENT_BACK;
+}
+
+void CsCionStubGen::GenSyncInvocation(std::ofstream& stream, const Declaration& decl) {
+  int cnt = 1;
+
+  // Deserialize
+  for (auto& i : decl.GetParameters().GetParams()) {
+    if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT) {
+      cnt++;
+      continue;
+    }
+
+    std::string v = "param" + std::to_string(cnt);
+    std::string c = ConvertTypeToDeserializer(
+        i->GetParameterType().GetBaseType(), v, "p");
+    stream << AddIndent(TAB_SIZE * 8, c);
+    cnt++;
+  }
+
+  // Invoke
+  cnt = 1;
+  std::string m;
+  bool hasRet = false;
+
+  if (decl.GetType().ToString() != "void") {
+    m += "var retVal = ";
+    hasRet = true;
+  }
+
+  m += "b." + decl.GetID() + "(";
+  for (auto& i : decl.GetParameters().GetParams()) {
+    if (cnt != 1) {
+      m += ", ";
+    }
+
+    std::string v = "param" + std::to_string(cnt);
+    auto& pt = i->GetParameterType();
+    if (pt.GetDirection() == ParameterType::Direction::OUT) {
+      m += "out " + ConvertTypeToString(pt.GetBaseType()) + " ";
+    } else if (pt.GetDirection() == ParameterType::Direction::REF) {
+      m += "ref ";
+    }
+    m += v;
+    cnt++;
+  }
+
+  m += ");\n";
+  stream << AddIndent(TAB_SIZE * 8, m);
+
+  // Serialize
+  cnt = 0;
+  m = CB_INVOCATION_RESULT_PRE;
+  for (auto& i : decl.GetParameters().GetParams()) {
+    auto& pt = i->GetParameterType();
+    cnt++;
+    if (pt.GetDirection() == ParameterType::Direction::IN)
+      continue;
+    m += ConvertTypeToSerializer(pt.GetBaseType(),
+                                "param" + std::to_string(cnt), "result");
+
+    if (HasFile(pt.GetBaseType())) {
+      m += "ShareFile(param" + std::to_string(cnt) + ");\n\n";
+    }
+  }
+
+  if (hasRet) {
+    m += ConvertTypeToSerializer(decl.GetType(), "retVal", "result");
+    if (HasFile(decl.GetType())) {
+      m += "ShareFile(retVal);\n";
+    }
+  }
+
+  m += "\nreturnData = result.ToBytes();\n";
+
+  stream << AddIndent(TAB_SIZE * 8, m);
+}
+
+void CsCionStubGen::GenAsyncInvocation(std::ofstream& stream, const Declaration& decl) {
+  int cnt = 1;
+
+  // Deserialize
+  for (auto& i : decl.GetParameters().GetParams()) {
+    if (i->GetParameterType().GetDirection() == ParameterType::Direction::OUT) {
+      cnt++;
+      continue;
+    }
+
+    std::string v = "param" + std::to_string(cnt);
+    std::string c = ConvertTypeToDeserializer(
+        i->GetParameterType().GetBaseType(), v, "p");
+    stream << AddIndent(TAB_SIZE * 7, c);
+    cnt++;
+  }
+
+  // Invoke
+  cnt = 1;
+  std::string m;
+  bool hasRet = false;
+
+  if (decl.GetType().ToString() != "void") {
+    m += "var retVal = ";
+    hasRet = true;
+  }
+
+  m += "b." + decl.GetID() + "(";
+  for (auto& i : decl.GetParameters().GetParams()) {
+    if (cnt != 1) {
+      m += ", ";
+    }
+
+    std::string v = "param" + std::to_string(cnt);
+    auto& pt = i->GetParameterType();
+    if (pt.GetDirection() == ParameterType::Direction::OUT) {
+      m += "out " + ConvertTypeToString(pt.GetBaseType()) + " ";
+    } else if (pt.GetDirection() == ParameterType::Direction::REF) {
+      m += "ref ";
+    }
+    m += v;
+    cnt++;
+  }
+
+  m += ");\n";
+  stream << AddIndent(TAB_SIZE * 7, m);
+}
+
+void CsCionStubGen::GenConnectionRequestedEvent(std::ofstream& stream) {
+  stream << CB_ON_CONNECTIONREQUESTED_EVENT;
+}
+
+void CsCionStubGen::GenConnectedEvent(std::ofstream& stream) {
+  stream << CB_ON_CONNECTED_EVENT;
+}
+
+void CsCionStubGen::GenDisconnectedEvent(std::ofstream& stream) {
+  stream << CB_ON_DISCONNECTED_EVENT;
+}
+
+void CsCionStubGen::GenCtor(std::ofstream& stream, const Interface& iface) {
+  bool securityCheck = false;
+  std::string m = "public $$(string serviceName, string displayName) : base(serviceName, displayName, new SecurityInfo {";
+
+  for (auto& attr : iface.GetAttributes().GetAttrs()) {
+    if (attr->GetKey() == "ca_path") {
+      m += "CaPath = \"" + attr->GetValue() + "\", ";
+      securityCheck = true;
+    } else if (attr->GetKey() == "cert_path") {
+      m += "CertPath = \"" + attr->GetValue() + "\", ";
+      securityCheck = true;
+    } else if (attr->GetKey() == "private_key") {
+      m += "PrivateKeyPath = \"" + attr->GetValue() + "\", ";
+      securityCheck = true;
+    }
+  }
+
+  auto const pos = m.find_last_of(',');
+  m = m.substr(0, pos);
+
+  if (securityCheck)
+    m += "})";/* base(serviceName, displayName, new SecurityInfo {CertPath = xxx, ... ) */
+   else
+    m += ")"; /* base(serviceName, displayName) */
+
+  m += NLine(1);
+  m += "{\n";
+  m += "}";
+
+  GenTemplate(AddIndent(TAB_SIZE * 3, m), stream,
+    [&]()->std::string {
+      return iface.GetID();
+    });
+}
+
+void CsCionStubGen::GenCommonMethods(std::ofstream& stream) {
+  stream << CB_COMMON_METHODS;
+}
+
+}  // namespace tidl
diff --git a/idlc/gen_cion/cs_cion_stub_gen.h b/idlc/gen_cion/cs_cion_stub_gen.h
new file mode 100644 (file)
index 0000000..eab7cb6
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_STUB_GEN_H_
+#define IDLC_CS_CION_GEN_CS_STUB_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/cs_cion_gen_base.h"
+
+namespace tidl {
+
+class CsCionStubGen : public CsCionGeneratorBase {
+ public:
+  explicit CsCionStubGen(std::shared_ptr<Document> doc);
+  virtual ~CsCionStubGen() = default;
+
+  void OnInitGen(std::ofstream& stream) override;
+  void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+  void GenNamespace(std::ofstream& stream);
+  void GenInterfaces(std::ofstream& stream);
+  void GenInterface(std::ofstream& stream, const Interface& iface);
+  void GenServiceBase(std::ofstream& stream, const Interface& iface);
+  void GenReceivedAsyncEvent(std::ofstream& stream, const Interface& iface);
+  void GenReceivedSyncEvent(std::ofstream& stream, const Interface& iface);
+  void GenConnectionRequestedEvent(std::ofstream& stream);
+  void GenConnectedEvent(std::ofstream& stream);
+  void GenDisconnectedEvent(std::ofstream& stream);
+  void GenCtor(std::ofstream& stream, const Interface& iface);
+  void GenCommonMethods(std::ofstream& stream);
+  void GenDeclarations(std::ofstream& stream, const Declarations& decls);
+  void GenSyncInvocation(std::ofstream& stream, const Declaration& decl);
+  void GenAsyncInvocation(std::ofstream& stream, const Declaration& decl);
+};
+
+}  // namespace tidl
+
+#endif  // IDLC_CS_CION_GEN_CS_STUB_GEN_H_
\ No newline at end of file
diff --git a/idlc/gen_cion/cs_cion_stub_gen_cb.h b/idlc/gen_cion/cs_cion_stub_gen_cb.h
new file mode 100644 (file)
index 0000000..3d5e5c9
--- /dev/null
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_STUB_GEN_CB_H_
+#define IDLC_CS_CION_GEN_CS_STUB_GEN_CB_H_
+
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
+const char CB_DATA_MEMBERS[] =
+R"__cs_cb(            private List<ServiceBase> _services = new List<ServiceBase>();
+            private Type _serviceType;
+            private static readonly string _tidlVersion = "<VERSION>";
+)__cs_cb";
+
+const char CB_SERVICE_BASE_FRONT[] =
+R"__cs_cb(
+            public abstract class ServiceBase
+            {
+                /// <summary>
+                /// The name of service
+                /// </summary>
+                public string ServiceName
+                {
+                    get; internal set;
+                }
+
+                /// <summary>
+                /// The display name of service
+                /// </summary>
+                public string DisplayName
+                {
+                     get; internal set;
+                }
+
+                /// <summary>
+                /// The PeerInfo of client
+                /// </summary>
+                public PeerInfo Client
+                {
+                    get;  internal set;
+                }
+
+                internal PeerInfo ConnectionRequestClient;
+
+                internal ServerBase ServerBase;
+
+                protected ServiceBase()
+                {
+                }
+
+                /// <summary>
+                /// Disconnects from the client app
+                /// </summary>
+                /// <exception cref="System.InvalidOperationException">
+                /// Thrown when an internal IO error occurrs.
+                /// </exception>
+                public void Disconnect()
+                {
+                    if (Client != null)
+                        ServerBase.Disconnect(Client);
+                }
+
+                /// <summary>
+                /// Accepts the connection request from the client.
+                /// </summary>
+                public void Accept()
+                {
+                    if (ConnectionRequestClient != null)
+                        ServerBase.Accept(ConnectionRequestClient);
+                }
+
+                /// <summary>
+                /// Rejects the connection request from the client.
+                /// </summary>
+                /// <param name="reason">The reason why reject the connection request.</param>
+                public void Reject(string reason)
+                {
+                    if (ConnectionRequestClient != null)
+                        ServerBase.Reject(ConnectionRequestClient, reason);
+                }
+
+                /// <summary>
+                /// This method will be called when connection requested from the client
+                /// </summary>
+                public abstract void OnConnentionRequest();
+
+                /// <summary>
+                /// This method will be called when received file payload.
+                /// </summary>
+                public abstract void OnFilePayloadReceived(FilePayload file, PayloadTransferStatus status);
+
+                /// <summary>
+                /// This method will be called when the client is disconnected
+                /// </summary>
+                public abstract void OnTerminate();
+
+                /// <summary>
+                /// This method will be called when the client is connected
+                /// </summary>
+                public abstract void OnConnected();
+)__cs_cb";
+
+const char CB_ON_RECEIVED_ASYNC_EVENT_FRONT[] =
+R"__cs_cb(
+            protected override void OnPayloadReceived(Payload data, PeerInfo peerInfo, PayloadTransferStatus status)
+            {
+                try
+                {
+                    Parcel p;
+                    ServiceBase b = null;
+
+                    foreach (var i in  _services)
+                    {
+                        if (i.Client == null)
+                            continue;
+
+                        if (i.Client.AppId.Equals(peerInfo.AppId) && i.Client.UUID.Equals(peerInfo.UUID))
+                        {
+                            b = i;
+                            break;
+                        }
+                    }
+
+                    if (b == null)
+                    {
+                        return;
+                    }
+
+                    if (data.PayloadType == PayloadType.FilePayload)
+                    {
+                        b.OnFilePayloadReceived((FilePayload)data, status);
+                        return;
+                    }
+
+                    DataPayload dp = (DataPayload)data;
+
+                    try
+                    {
+                        p = new Parcel(dp.Data);
+                    }
+                    catch (InvalidIOException)
+                    {
+                        return;
+                    }
+
+                    int cmd = p.ReadInt();
+                    switch ((MethodId)cmd)
+                    {
+)__cs_cb";
+
+const char CB_ON_RECEIVED_ASYNC_EVENT_BACK[] =
+R"__cs_cb(
+                        default:
+                            return;
+                    }
+                }
+                catch (InvalidIOException)
+                {
+                    return;
+                }
+            }
+)__cs_cb";
+
+
+
+const char CB_ON_RECEIVED_SYNC_EVENT_FRONT[] =
+R"__cs_cb(
+               protected override byte[] OnDataReceived(byte[] data, PeerInfo peerInfo)
+            {
+                Parcel p;
+                byte[] returnData = new byte[0];
+
+                try
+                {
+                    p = new Parcel(data);
+                }
+                catch (InvalidIOException)
+                {
+                    return returnData;
+                }
+
+                try
+                {
+                    ServiceBase b = null;
+
+                    foreach (var i in  _services)
+                    {
+                        if (i.Client == null)
+                            continue;
+
+                        if (i.Client.AppId.Equals(peerInfo.AppId) && i.Client.UUID.Equals(peerInfo.UUID))
+                        {
+                            b = i;
+                            break;
+                        }
+                    }
+
+                    if (b == null)
+                    {
+                        return returnData;
+                    }
+
+                    using (var result = new Parcel())
+                    {
+                        int cmd = p.ReadInt();
+
+                        switch ((MethodId)cmd)
+                        {
+)__cs_cb";
+
+const char CB_ON_RECEIVED_SYNC_EVENT_BACK[] =
+R"__cs_cb(
+                            default:
+                                return returnData;
+                        }
+                    }
+
+                    return returnData;
+                }
+                catch (InvalidIOException)
+                {
+                    return returnData;
+                }
+                finally
+                {
+                    p?.Dispose();
+                }
+            }
+)__cs_cb";
+
+
+const char CB_ON_CONNECTIONREQUESTED_EVENT[] =
+R"__cs_cb(
+            protected override void OnConnentionRequest(PeerInfo peerInfo)
+            {
+                ServiceBase s = Activator.CreateInstance(_serviceType) as ServiceBase;
+                s.ServiceName = base.ServiceName;
+                s.DisplayName = base.DisplayName;
+                s.ConnectionRequestClient = peerInfo;
+                s.ServerBase = this;
+                s.OnConnentionRequest();
+                _services.Add(s);
+            }
+)__cs_cb";
+
+const char CB_ON_CONNECTED_EVENT[] =
+R"__cs_cb(
+            protected override void OnConnectionResult(PeerInfo peerInfo, ConnectionResult result)
+            {
+                foreach (var i in _services)
+                {
+                    if (i.ConnectionRequestClient == null)
+                        continue;
+
+                    if (i.ConnectionRequestClient.AppId.Equals(peerInfo.AppId) && i.ConnectionRequestClient.UUID.Equals(peerInfo.UUID))
+                    {
+                        if (result.Status == ConnectionStatus.OK) {
+                            i.Client = i.ConnectionRequestClient;
+                            i.ConnectionRequestClient = null;
+                            i.OnConnected();
+                        } else {
+                            _services.Remove(i);
+                        }
+                        break;
+                    }
+                }
+            }
+)__cs_cb";
+
+const char CB_ON_DISCONNECTED_EVENT[] =
+R"__cs_cb(
+            protected override void OnDisconnected(PeerInfo peerInfo)
+            {
+                foreach (var i in _services)
+                {
+                    if (i.Client == null)
+                        continue;
+
+                    if (i.Client.AppId.Equals(peerInfo.AppId) && i.Client.UUID.Equals(peerInfo.UUID))
+                    {
+                        i.OnTerminate();
+                        _services.Remove(i);
+                        break;
+                    }
+                }
+            }
+)__cs_cb";
+
+const char CB_COMMON_METHODS[] =
+R"__cs_cb(
+            /// <summary>
+            /// Listens to client apps
+            /// </summary>
+            /// <param name="serviceType">The type object for making service instances</param>
+            /// <exception cref="InvalidIOException">
+            /// Thrown when internal I/O error happen.
+            /// </exception>
+            /// <exception cref="ArgumentException">
+            /// Thrown when serviceType is invalid.
+            /// </exception>
+            /// <exception cref="InvalidOperationException">
+            /// Thrown when the listen operation is already in progress.
+            /// </exception>
+            /// <exception cref="UnauthorizedAccessException">
+            /// Thrown when an application does not have the privilege to access this method.
+            /// </exception>
+            /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege>
+            /// <privilege>http://tizen.org/privilege/internet</privilege>
+            public void Listen(Type serviceType)
+            {
+                if (!typeof(ServiceBase).IsAssignableFrom(serviceType))
+                    throw new ArgumentException("Invalid type");
+                _serviceType = serviceType;
+                base.Listen();
+            }
+
+
+                       /// <summary>
+                       /// Stops the listen operation.
+                       /// </summary>
+                       /// <exception cref="InvalidOperationException">Thrown when the server is not listening.</exception>
+                       public new void Stop()
+                       {
+                               base.Stop();
+                               _services.Clear();
+                       }
+
+                       /// <summary>
+                       /// Sets ondemand launch enabled flag.
+                       /// </summary>
+                       /// <param name="enable">Whether ondemand launch is enabled or not.</param>
+                       /// <exception cref="UnauthorizedAccessException">
+                       /// Thrown when an application does not have the privilege to access this method.
+                       /// </exception>
+                       /// <privilege>http://tizen.org/privilege/d2d.remotelaunch</privilege>
+                       public new void SetOndemandLaunchEnabled(bool enable)
+                       {
+                           base.SetOndemandLaunchEnabled(enable);
+                       }
+
+            /// <summary>
+            /// Gets service objects which are connected
+            /// </summary>
+            /// <returns>The enumerable service objects which are connected</returns>
+            public IEnumerable<ServiceBase> GetServices()
+            {
+                return _services;
+            }
+)__cs_cb";
+
+
+constexpr const char CB_INVOCATION_RESULT_PRE[] =
+R"__cs_cb(
+result.WriteInt((int)MethodId.__Result);
+)__cs_cb";
+
+#endif  // IDLC_CS_CION_GEN_CS_STUB_GEN_CB_H_
index 878280f112c6f5e572f7c580e5117cdd7beb6ebe..6020d65ac98a26e95a3d48b8197b0b5ba406ece7 100644 (file)
@@ -35,6 +35,8 @@
 #include "idlc/gen_cion/c_cion_proxy_body_gen.h"
 #include "idlc/gen_cion/c_cion_stub_header_gen.h"
 #include "idlc/gen_cion/c_cion_stub_body_gen.h"
+#include "idlc/gen_cion/cs_cion_proxy_gen.h"
+#include "idlc/gen_cion/cs_cion_stub_gen.h"
 
 #include "idlc/options.h"
 
@@ -57,7 +59,11 @@ void GenerateStubCodes(std::shared_ptr<tidl::Options> options,
     case tidl::Options::LANGUAGE_TYPE_CPP:
       break;
     case tidl::Options::LANGUAGE_TYPE_CSHARP:
-      break;
+    {
+       tidl::CsCionStubGen stub(ps.GetDoc());
+       stub.Run(options->GetOutput() + ".cs");
+       break;
+    }
     case tidl::Options::LANGUAGE_TYPE_JAVA:
       break;
 
@@ -122,7 +128,11 @@ void GenerateProxyCodes(std::shared_ptr<tidl::Options> options,
     case tidl::Options::LANGUAGE_TYPE_CPP:
       break;
     case tidl::Options::LANGUAGE_TYPE_CSHARP:
+    {
+      tidl::CsCionProxyGen proxy(ps.GetDoc());
+      proxy.Run(options->GetOutput() + ".cs");
       break;
+    }
     case tidl::Options::LANGUAGE_TYPE_JAVA:
       break;