[cion] Implement C# group generator 33/269433/12
authorSangyoon Jang <jeremy.jang@samsung.com>
Thu, 13 Jan 2022 03:33:37 +0000 (12:33 +0900)
committerSangyoon Jang <jeremy.jang@samsung.com>
Mon, 24 Jan 2022 01:55:00 +0000 (01:55 +0000)
Change-Id: I2059365150a1b27316caf17173d13014e5e9b0fb
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
idlc/gen_cion/cs_cion_gen_base.cc
idlc/gen_cion/cs_cion_gen_base.h
idlc/gen_cion/cs_cion_group_gen.cc [new file with mode: 0644]
idlc/gen_cion/cs_cion_group_gen.h [new file with mode: 0644]
idlc/gen_cion/cs_cion_group_gen_cb.h [new file with mode: 0644]
idlc/main.cc

index 86d679f..73cb338 100644 (file)
@@ -441,12 +441,15 @@ void CsCionGeneratorBase::GenWriteBundle(std::ofstream& stream,
 }
 
 void CsCionGeneratorBase::GenMethodId(std::ofstream& stream,
-    const Interface& iface) {
+    const Interface& iface, bool is_group) {
   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);
+    int cnt = 0;
+    if (!is_group) {
+      stream << Tab(4) << "__Result = 0," << NLine(1);
+      stream << Tab(4) << "__Callback = 1," << NLine(1);
+      cnt = 2;
+    }
     for (const auto& i : iface.GetDeclarations()) {
       if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
         continue;
index b9c0685..57e04d4 100644 (file)
@@ -40,7 +40,7 @@ class CsCionGeneratorBase : public Generator {
   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 GenMethodId(std::ofstream& stream, const Interface& iface, bool is_group = false);
   void GenDelegateId(std::ofstream& stream, const Interface& iface);
   void GenDeclaration(std::ofstream& stream,
                       const Declaration& decl, bool semicol = true);
diff --git a/idlc/gen_cion/cs_cion_group_gen.cc b/idlc/gen_cion/cs_cion_group_gen.cc
new file mode 100644 (file)
index 0000000..99e72f1
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/cs_cion_group_gen.h"
+
+namespace {
+#include "idlc/gen_cion/cs_cion_group_gen_cb.h"
+}
+
+namespace tidl {
+
+CsCionGroupGen::CsCionGroupGen(std::shared_ptr<Document> doc)
+    : CsCionGeneratorBase(doc) {}
+
+void CsCionGroupGen::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 CsCionGroupGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void CsCionGroupGen::GenNamespace(std::ofstream& stream) {
+  stream << NLine(1);
+  stream << "namespace Cion" << NLine(1);
+  GenBrace(stream, 0, [&]() {
+    stream << "namespace " << GetFileNamespace() << NLine(1);
+    GenBrace(stream, 0, [&]() {
+      GenStructures(stream);
+      stream << Tab(1) << "namespace Group" << NLine(1);
+      GenBrace(stream, TAB_SIZE, [&]() {
+        GenInterfaces(stream);
+      });
+    });
+  });
+}
+
+void CsCionGroupGen::GenInterfaces(std::ofstream& stream) {
+  for (auto& i : GetDocument().GetBlocks()) {
+    if (i->GetType() != Block::TYPE_INTERFACE)
+      continue;
+    Interface& iface = static_cast<Interface&>(*i);
+    GenInterface(stream, iface);
+    stream << NLine(1);
+  }
+}
+
+void CsCionGroupGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+  stream << Tab(2) << "public class " << iface.GetID()
+         << " : GroupBase" << NLine(1);
+  GenBrace(stream, TAB_SIZE * 2, [&]() {
+    stream << ReplaceAll(CB_DATA_MEMBERS, "<VERSION>", FULLVER);
+    GenEvents(stream, iface);
+    stream << NLine(1);
+    GenMethodId(stream, iface, true);
+    stream << CB_EVENT_METHODS;
+    GenSerializer(stream);
+    GenListSerializer(stream);
+    GenCtor(stream, iface);
+    GenFinalizer(stream, iface);
+    GenCionPayloadReceivedEvent(stream, iface);
+    GenMethods(stream, iface);
+  });
+}
+
+void CsCionGroupGen::GenEvents(std::ofstream& stream, const Interface& iface) {
+  stream << NLine(1);
+  for (const auto& decl : iface.GetDeclarations())
+    GenEvent(stream, *decl);
+}
+
+void CsCionGroupGen::GenEvent(std::ofstream& stream, const Declaration& decl) {
+  stream << Tab(3) << "public delegate void " << decl.GetID()
+         << "EventHandler(object sender, PeerInfo peer";
+  for (const auto& i : decl.GetParameters()) {
+    auto& pt = i->GetParameterType();
+    if (pt.GetDirection() == ParameterType::Direction::OUT)
+      continue;
+    stream << ", " << i->GetParameterType().GetBaseType().ToString() << " "
+           << i->GetID();
+  }
+  stream << ");" << NLine(1);
+  stream << Tab(3) << "public event " << decl.GetID() << "EventHandler "
+         << decl.GetID() << "Event;" << NLine(1);
+}
+
+void CsCionGroupGen::GenCtor(std::ofstream& stream, const Interface& iface) {
+  bool securityCheck = false;
+  stream << NLine(1);
+  std::string m =
+      "/// <summary>\n"
+      "/// Constructor for this class\n"
+      "/// </summary>\n"
+      "/// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege>\n"
+      "/// <privilege>http://tizen.org/privilege/internet</privilege>\n"
+      "/// <remarks>The maximum length of topic name is 512.</remarks>\n"
+      "/// <exception cref=\"ArgumentException\">\n"
+      "/// Thrown when the given topic name is too long.\n"
+      "/// </exception>\n"
+      "/// <exception cref=\"UnauthorizedAccessException\">\n"
+      "/// Thrown when an application does not have the privilege.\n"
+      "/// </exception>\n"
+      "public ##(string topicName) : base(topicName, new SecurityInfo {";
+
+  for (const auto& attr : iface.GetAttributes()) {
+    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 = AddIndent(TAB_SIZE * 3, m);
+  m.pop_back();
+  m += CB_CTOR_BODY;
+
+  stream << ReplaceAll(m, "##", iface.GetID());
+}
+
+void CsCionGroupGen::GenFinalizer(std::ofstream& stream,
+    const Interface& iface) {
+  stream << ReplaceAll(CB_FINALIZER, "##", iface.GetID());
+}
+
+void CsCionGroupGen::GenMethods(std::ofstream& stream, const Interface& iface) {
+  auto& decls = iface.GetDeclarations();
+
+  for (const auto& i : decls) {
+    if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+      continue;
+
+    stream << NLine(1);
+    if (!i->GetComments().empty())
+      stream << AddIndent(TAB_SIZE * 3, i->GetComments());
+
+    stream << Tab(3) << "public ";
+    GenDeclaration(stream, *i, false);
+    stream << NLine(1);
+    GenBrace(stream, TAB_SIZE * 3, [&]() {
+      GenInvocation(stream, *i);
+    });
+  }
+}
+
+void CsCionGroupGen::GenInvocation(std::ofstream& stream,
+    const Declaration& decl) {
+  GenTemplate(CB_INVOCATION_PRE, stream,
+    [&]()->std::string {
+      std::string st;
+      st += Tab(5) + "p.WriteInt((int)MethodId." + decl.GetID() + ");" +
+                NLine(1);
+      std::string m;
+      std::string l;
+      for (const auto& i : decl.GetParameters()) {
+        auto& pt = i->GetParameterType();
+        if (pt.GetDirection() == ParameterType::Direction::OUT)
+          continue;
+        m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p");
+      }
+
+      st += AddIndent(TAB_SIZE * 5, m) + NLine(1);
+
+      st += Tab(5) + "lock (_lock)" + NLine(1);
+      st += Tab(5) + "{" + NLine(1);
+      if (!l.empty())
+        st += AddIndent(TAB_SIZE * 6, l) + NLine(1);
+
+      // Deserialize
+      st += CB_ASYNC_INVOCATION_MID;
+      st += Tab(5) + "}";
+
+      return st;
+    });
+}
+
+void CsCionGroupGen::GenCionPayloadReceivedEvent(std::ofstream& stream,
+    const Interface& iface) {
+  stream << CB_ON_PAYLOAD_RECEIVED_FRONT;
+
+  for (const auto& i : iface.GetDeclarations()) {
+    if (i->GetMethodType() == Declaration::MethodType::DELEGATE ||
+        i->GetMethodType() == Declaration::MethodType::SYNC)
+      continue;
+    stream << Tab(6) << "case (int)MethodId." << i->GetID() << ":" << NLine(1);
+    GenBrace(stream, TAB_SIZE * 6, [&]() {
+      GenHandlerInvocation(stream, *i);
+      stream << Tab(7) << "break;" << NLine(1);
+    });
+  }
+
+  stream << CB_ON_PAYLOAD_RECEIVED_BACK << NLine(1);
+}
+
+void CsCionGroupGen::GenHandlerInvocation(std::ofstream& stream,
+    const Declaration& decl) {
+  int cnt = 1;
+  // Deserialize
+  for (const auto& i : decl.GetParameters()) {
+    std::string v = "param" + std::to_string(cnt);
+    std::string c = ConvertTypeToDeserializer(
+        i->GetParameterType().GetBaseType(), v, "parcelReceived");
+    stream << AddIndent(TAB_SIZE * 7, c);
+    cnt++;
+  }
+
+  // Invoke
+  std::string m;
+  m += decl.GetID() + "Event?.Invoke(this, peerInfo";
+  cnt = 1;
+  for (auto i = decl.GetParameters().begin();
+      i != decl.GetParameters().end(); ++i) {
+    m += ", param" + std::to_string(cnt++);
+  }
+
+  m += ");\n";
+  stream << AddIndent(TAB_SIZE * 7, m);
+}
+
+}  // namespace tidl
diff --git a/idlc/gen_cion/cs_cion_group_gen.h b/idlc/gen_cion/cs_cion_group_gen.h
new file mode 100644 (file)
index 0000000..61bb288
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_GROUP_GEN_H_
+#define IDLC_CS_CION_GEN_CS_GROUP_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/cs_cion_gen_base.h"
+
+namespace tidl {
+
+class CsCionGroupGen : public CsCionGeneratorBase {
+ public:
+  explicit CsCionGroupGen(std::shared_ptr<Document> doc);
+  virtual ~CsCionGroupGen() = default;
+
+  void OnInitGen(std::ofstream& stream) override;
+  void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+  void GenNamespace(std::ofstream& stream);
+  void GenInterfaces(std::ofstream& stream);
+  void GenInterface(std::ofstream& stream, const Interface& iface);
+  void GenEvents(std::ofstream& stream, const Interface& iface);
+  void GenEvent(std::ofstream& stream, const Declaration& decl);
+  void GenCtor(std::ofstream& stream, const Interface& iface);
+  void GenFinalizer(std::ofstream& stream, const Interface& iface);
+  void GenMethods(std::ofstream& stream, const Interface& iface);
+  void GenInvocation(std::ofstream& stream, const Declaration& decl);
+  void GenCionPayloadReceivedEvent(std::ofstream& stream,
+      const Interface& iface);
+  void GenHandlerInvocation(std::ofstream& stream,
+    const Declaration& decl);
+};
+
+}  // namespace tidl
+
+#endif  // IDLC_CS_CION_GEN_CS_GROUP_GEN_H_
\ No newline at end of file
diff --git a/idlc/gen_cion/cs_cion_group_gen_cb.h b/idlc/gen_cion/cs_cion_group_gen_cb.h
new file mode 100644 (file)
index 0000000..ef8c40e
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CS_CION_GEN_CS_GROUP_GEN_CB_H_
+#define IDLC_CS_CION_GEN_CS_GROUP_GEN_CB_H_
+
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
+const char CB_DATA_MEMBERS[] =
+R"__cs_cb(            public delegate void JoinedHandler(object sender, PeerInfo peerInfo);
+            public delegate void LeftHandler(object sender, PeerInfo peerInfo);
+
+            /// <summary>
+            /// This event will be invoked when the peer group app is joined to the topic.
+            /// </summary>
+            public event JoinedHandler Joined;
+
+            /// <summary>
+            /// This event will be invoked after the peer group app was left from the topic.
+            /// </summary>
+            public event LeftHandler Left;
+
+            public string TopicName;
+
+            private Object _lock = new Object();
+)__cs_cb";
+
+const char CB_CTOR_BODY[] =
+R"__cs_cb(
+            {
+                TopicName = topicName;
+                try
+                {
+                    base.Subscribe();
+                }
+                catch
+                {
+                    throw;
+                }
+            }
+)__cs_cb";
+
+const char CB_FINALIZER[] =
+R"__cs_cb(
+            ~##()
+            {
+                base.Unsubscribe();
+            }
+)__cs_cb";
+
+const char CB_EVENT_METHODS[] =
+R"__cs_cb(
+            protected override void OnJoined(PeerInfo peerInfo)
+            {
+                Joined?.Invoke(this, peerInfo);
+            }
+
+            protected override void OnLeft(PeerInfo peerInfo)
+            {
+                Left?.Invoke(this, peerInfo);
+            }
+)__cs_cb";
+
+const char CB_ON_PAYLOAD_RECEIVED_FRONT[] =
+R"__cs_cb(
+            protected override void OnPayloadReceived(Payload payload, PeerInfo peerInfo)
+            {
+                Parcel parcelReceived;
+
+                try
+                {
+                    parcelReceived = new Parcel(((DataPayload)payload).Data);
+                }
+                catch (InvalidIOException)
+                {
+                    return;
+                }
+
+                using (parcelReceived)
+                {
+                    int cmd = parcelReceived.ReadInt();
+                    switch (cmd)
+                    {
+)__cs_cb";
+
+const char CB_ON_PAYLOAD_RECEIVED_BACK[] =
+R"__cs_cb(
+                        default:
+                            // log here?
+                            break;
+                    }
+                }
+            }
+)__cs_cb";
+
+const char CB_INVOCATION_PRE[] =
+R"__cs_cb(                using (Parcel p = new Parcel())
+                {
+$$
+                }
+)__cs_cb";
+
+const char CB_ASYNC_INVOCATION_MID[] =
+R"__cs_cb(                        // Send
+                        DataPayload dp = new DataPayload(p.ToBytes());
+                        base.Publish(dp);
+)__cs_cb";
+
+#endif  // IDLC_CS_CION_GEN_CS_PROXY_GEN_CB_H_
index b0a0666..6dad213 100644 (file)
@@ -39,6 +39,7 @@
 #include "idlc/gen_cion/c_cion_group_body_gen.h"
 #include "idlc/gen_cion/cs_cion_proxy_gen.h"
 #include "idlc/gen_cion/cs_cion_stub_gen.h"
+#include "idlc/gen_cion/cs_cion_group_gen.h"
 #include "idlc/gen_cion/cpp_cion_proxy_header_gen.h"
 #include "idlc/gen_cion/cpp_cion_proxy_body_gen.h"
 #include "idlc/gen_cion/cpp_cion_stub_header_gen.h"
@@ -266,7 +267,11 @@ void GenerateGroupCodes(std::shared_ptr<tidl::Options> options,
       break;
     }
     case tidl::Options::LANGUAGE_TYPE_CSHARP:
+    {
+      tidl::CsCionGroupGen group(ps.GetDoc());
+      group.Run(options->GetOutput() + ".cs");
       break;
+    }
     case tidl::Options::LANGUAGE_TYPE_JAVA:
       break;