[cion] Implement C++ group generator 68/268968/18
authorSangyoon Jang <jeremy.jang@samsung.com>
Wed, 5 Jan 2022 10:22:58 +0000 (19:22 +0900)
committerSangyoon Jang <jeremy.jang@samsung.com>
Wed, 12 Jan 2022 06:00:11 +0000 (15:00 +0900)
Change-Id: Ice1de40ddb75fb9619811924ff88412359e2cdae
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
16 files changed:
idlc/ast/parameter.cc
idlc/gen_cion/c_cion_group_body_gen.cc
idlc/gen_cion/c_cion_group_body_gen.h
idlc/gen_cion/c_cion_group_body_gen_cb.h
idlc/gen_cion/c_cion_group_header_gen.cc
idlc/gen_cion/c_cion_group_header_gen.h
idlc/gen_cion/c_cion_group_header_gen_cb.h
idlc/gen_cion/cpp_cion_gen_base.cc
idlc/gen_cion/cpp_cion_gen_base.h
idlc/gen_cion/cpp_cion_group_body_gen.cc [new file with mode: 0644]
idlc/gen_cion/cpp_cion_group_body_gen.h [new file with mode: 0644]
idlc/gen_cion/cpp_cion_group_body_gen_cb.h [new file with mode: 0644]
idlc/gen_cion/cpp_cion_group_header_gen.cc [new file with mode: 0644]
idlc/gen_cion/cpp_cion_group_header_gen.h [new file with mode: 0644]
idlc/gen_cion/cpp_cion_group_header_gen_cb.h [new file with mode: 0644]
idlc/main.cc

index 7e673e1bc59e84e3db1037cd66947630a6ff2fbb..bce4a9481a71efdc7871c30e8e0ea0f971dce56f 100644 (file)
@@ -68,4 +68,3 @@ std::list<std::unique_ptr<Parameter>>::const_iterator Parameters::end() const {
 }
 
 }  // namespace tidl
-
index 63620aad358ab346a34b0813fc353641e6ec297c..41265af2f8f89419bacc69f132c329a28e6cc5d0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * 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.
index 326e62f25d5cfe6530c156c76bfb8d646abab6de..c75015b9c973ceb6e18e19e1c80b35be408e8d80 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * 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.
index 06fae166fce11d1892c27f699ceed781c5cb3cbf..5aca04f4417db34b5743d3660124792e429cca7d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * 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.
index 065aa0cbb700d1675f190ec9536ac97bca7ff7ab..c5bd08d1b6db31803a20e7c8f413ae3c616ea565 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * 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.
index 3661510990968b1b59b26da1dacdb8d7597f5b49..2025b36b3321b75df6a4ee42571db196965d7feb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * 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.
index 75ee1363158b673aee3a94dafac7669edc454938..f8b3859009d1906a3a4a5d45b12c800a2f9d4f04 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * 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.
index de424ff714d19fe0c255d8a11e7915c43829e646..734e5c1fe0da66a8d4554e1734c3a2684a6bcf85 100644 (file)
@@ -60,9 +60,14 @@ CppCionGeneratorBase::CppCionGeneratorBase(std::shared_ptr<Document> doc)
   };
 }
 
-void CppCionGeneratorBase::GenStructuresForHeader(std::ofstream& stream) {
-  stream << CB_BUNDLE;
-  stream << CB_FILE;
+void CppCionGeneratorBase::GenStructuresForHeader(std::ofstream& stream,
+    bool is_group) {
+  // FIXME: need to check whether the interface use bundle/file instead of
+  // 'is_group'
+  if (!is_group) {
+    stream << CB_BUNDLE;
+    stream << CB_FILE;
+  }
   for (auto& i : GetDocument().GetBlocks()) {
     if (i->GetType() != Block::TYPE_STRUCTURE)
       continue;
@@ -426,12 +431,15 @@ void CppCionGeneratorBase::GenListSerializer(std::ofstream& stream, bool proto)
 }
 
 void CppCionGeneratorBase::GenMethodId(std::ofstream& stream,
-                                   const Interface& iface) {
+                                   const Interface& iface, bool is_group) {
   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);
+    int cnt = 0;
+    if (!is_group) {
+      cnt = 2;
+      stream << Tab(2) << "__Result = 0," << NLine(1);
+      stream << Tab(2) << "__Callback = 1," << NLine(1);
+    }
     for (const auto& i : iface.GetDeclarations()) {
       if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
         continue;
index d710c77b9f20ddf3ae580cf8eacb07b422529c6c..38f3c2182209d702c916e2e466253860bdd3b675 100644 (file)
@@ -33,13 +33,14 @@ class CppCionGeneratorBase : public Generator {
   virtual ~CppCionGeneratorBase() = default;
 
   void GenVersion(std::ofstream& stream);
-  void GenStructuresForHeader(std::ofstream& stream);
+  void GenStructuresForHeader(std::ofstream& stream, bool is_group = false);
   void GenStructuresForBody(std::ofstream& stream);
   void GenSerializer(std::ofstream& stream);
   void GenDeSerializer(std::ofstream& stream);
   void GenListSerializer(std::ofstream& stream, bool proto = false);
   void GenPrototype(std::ofstream& stream);
-  void GenMethodId(std::ofstream& stream, const Interface& iface);
+  void GenMethodId(std::ofstream& stream, const Interface& iface,
+                   bool is_group = false);
   void GenDelegateId(std::ofstream& stream, const Interface& iface);
   void GenParameters(std::ofstream& stream, const Parameters& ps);
   void GenDeclaration(std::ofstream& stream, const Interface& iface,
diff --git a/idlc/gen_cion/cpp_cion_group_body_gen.cc b/idlc/gen_cion/cpp_cion_group_body_gen.cc
new file mode 100644 (file)
index 0000000..ac016be
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/cpp_cion_group_body_gen.h"
+
+namespace {
+#include "idlc/gen_cion/cpp_cion_group_body_gen_cb.h"
+}
+
+namespace tidl {
+
+CppCionGroupBodyGen::CppCionGroupBodyGen(std::shared_ptr<Document> doc)
+    : CppCionGeneratorBase(doc) {}
+
+void CppCionGroupBodyGen::OnInitGen(std::ofstream& stream) {
+  std::string key(".cc");
+  std::string header_file = FileName;
+
+  std::size_t found = header_file.rfind(key);
+  if (found != std::string::npos)
+    header_file.replace(found, key.length(), ".h");
+
+  GenVersion(stream);
+  stream << NLine(1);
+  stream << "#include <stdlib.h>" << NLine(1)
+         << "#include <assert.h>" << NLine(1)
+         << "#include <dlog.h>" << NLine(1)
+         <<  NLine(1)
+         << "#include \"" << header_file << "\"" << NLine(2);
+  GenLogTag(stream, "CION_GROUP");
+  GenLogDefinition(stream);
+  stream << NLine(1);
+  GenNamespace(stream);
+}
+
+void CppCionGroupBodyGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void CppCionGroupBodyGen::GenNamespace(std::ofstream& stream) {
+  stream << "namespace cion ";
+  GenBrace(stream, 0, [&]() {
+    stream << "namespace " << GetFileNamespace() << " ";
+    GenBrace(stream, 0, [&]() {
+      stream <<  NLine(1);
+      GenStructuresForBody(stream);
+      stream << "namespace group ";
+      GenBrace(stream, 0, [&]() {
+        GenPrototype(stream);
+        GenSerializer(stream);
+        GenDeSerializer(stream);
+        GenListSerializer(stream);
+        GenInterfaces(stream);
+      }, false, false);
+      stream << "  // namespace group" + NLine(1);
+    }, false, false);
+    stream << "  // namespace " + GetFileNamespace() + NLine(1);
+  }, false, false);
+  stream << "  // namespace rpc_port" + NLine(1);
+}
+
+void CppCionGroupBodyGen::GenInterfaces(std::ofstream& stream) {
+  for (auto& i : GetDocument().GetBlocks()) {
+    if (i->GetType() != Block::TYPE_INTERFACE)
+      continue;
+    Interface& iface = static_cast<Interface&>(*i);
+    GenInterface(stream, iface);
+  }
+}
+
+void CppCionGroupBodyGen::GenInterface(std::ofstream& stream,
+    const Interface& iface) {
+  GenConstructor(stream, iface);
+  GenDestructor(stream, iface);
+  GenMethods(stream, iface);
+  GenCionPayloadReceivedEvent(stream, iface);
+}
+
+void CppCionGroupBodyGen::GenConstructor(std::ofstream& stream,
+    const Interface& iface) {
+  stream << ReplaceAll(CB_GROUP_INTERFACE_CTOR, "<CLS_NAME>", iface.GetID())
+         << NLine(1);
+}
+
+void CppCionGroupBodyGen::GenDestructor(std::ofstream& stream,
+    const Interface& iface) {
+  stream << ReplaceAll(CB_DTOR, "<CLS_NAME>", iface.GetID()) << NLine(1);
+}
+
+void CppCionGroupBodyGen::GenCionPayloadReceivedEvent(std::ofstream& stream,
+    const Interface& iface) {
+  stream << ReplaceAll(CB_GROUP_ON_PAYLOAD_RECEIVED_CB_FRONT, "<CLS_NAME>",
+      iface.GetID());
+
+  for (const auto& i : iface.GetDeclarations()) {
+    if (i->GetMethodType() == Declaration::MethodType::DELEGATE ||
+        i->GetMethodType() == Declaration::MethodType::SYNC)
+      continue;
+    stream << Tab(2) << "case static_cast<int>(MethodId::"
+           << i->GetID() << "): ";
+    GenBrace(stream, TAB_SIZE * 2, [&]() {
+      GenHandlerInvocation(stream, *i);
+      stream << Tab(3) << "break;" << NLine(1);
+    }, false);
+  }
+
+  stream << CB_GROUP_ON_PAYLOAD_RECEIVED_CB_BACK << NLine(1);
+}
+
+void CppCionGroupBodyGen::GenHandlerInvocation(std::ofstream& stream,
+    const Declaration& decl) {
+  int cnt = 1;
+  // Deserialize
+  for (const auto& i : decl.GetParameters()) {
+    std::string v = "param" + std::to_string(cnt);
+    std::string c = ConvertTypeToDeserializer(
+        i->GetParameterType().GetBaseType(), v, "parcel_received");
+    stream << AddIndent(TAB_SIZE * 3, c);
+    cnt++;
+  }
+
+  // Invoke
+  std::string m;
+  m += "On" + decl.GetID() + "(";
+  cnt = 1;
+  for (auto i = decl.GetParameters().begin();
+      i != decl.GetParameters().end(); ++i) {
+    if (cnt != 1)
+      m += ", ";
+    m += "param" + std::to_string(cnt++);
+  }
+
+  m += ");\n";
+  stream << AddIndent(TAB_SIZE * 3, m);
+}
+
+void CppCionGroupBodyGen::GenMethods(std::ofstream& stream,
+    const Interface& iface) {
+  auto& decls = iface.GetDeclarations();
+
+  for (const auto& i : decls) {
+    if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+      continue;
+
+    GenDeclaration(stream, iface, *i);
+    GenBrace(stream, 0, [&]() {
+      GenInvocation(stream, *i);
+    }, false);
+    stream << NLine(1);
+  }
+}
+
+void CppCionGroupBodyGen::GenInvocation(std::ofstream& stream,
+    const Declaration& decl) {
+  stream << CB_INVOCATION_PRE;
+
+  // Serialize
+  stream << Tab(1)
+         << "rpc_port_parcel_write_int32(p, static_cast<int>(MethodId::"
+         << decl.GetID() << "));" << NLine(1);
+  std::string m;
+  std::string l;
+  for (const auto& i : decl.GetParameters()) {
+    auto& pt = i->GetParameterType();
+    m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p");
+    if (IsDelegateType(pt.GetBaseType())) {
+      l += "delegate_list_.emplace_back(" + i->GetID() + ".release());\n";
+    }
+  }
+  stream << AddIndent(TAB_SIZE, m) << NLine(1);
+
+  stream << Tab(1) << "do ";
+  GenBrace(stream, TAB_SIZE, [&]() {
+    stream << Tab(2) << "std::lock_guard<std::recursive_mutex> lock(mutex_);"
+           << NLine(2);
+    if (!l.empty())
+      stream << AddIndent(TAB_SIZE * 2, l);
+    else if (decl.GetMethodType() == Declaration::MethodType::ASYNC)
+      stream << CB_INVOCATION_ASYNC_MID << NLine(1);
+  }, false, false);
+  stream << " while (false);" << NLine(1);
+
+  if (decl.GetMethodType() == Declaration::MethodType::ASYNC) {
+    stream << Tab(1) << "rpc_port_parcel_destroy(p);"
+           << NLine(1);
+    return;
+  }
+
+  stream << CB_INVOCATION_END;
+}
+
+}  // namespace tidl
diff --git a/idlc/gen_cion/cpp_cion_group_body_gen.h b/idlc/gen_cion/cpp_cion_group_body_gen.h
new file mode 100644 (file)
index 0000000..2a49d7a
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_CION_GEN_CPP_GROUP_BODY_GEN_H_
+#define IDLC_CPP_CION_GEN_CPP_GROUP_BODY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/cpp_cion_gen_base.h"
+
+namespace tidl {
+
+class CppCionGroupBodyGen : public CppCionGeneratorBase {
+ public:
+  explicit CppCionGroupBodyGen(std::shared_ptr<Document> doc);
+  virtual ~CppCionGroupBodyGen() = default;
+
+  void OnInitGen(std::ofstream& stream) override;
+  void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+  void GenNamespace(std::ofstream& stream);
+  void GenStructures(std::ofstream& stream);
+  void GenInterfaces(std::ofstream& stream);
+  void GenInterface(std::ofstream& stream, const Interface& iface);
+  void GenConstructor(std::ofstream& stream, const Interface& iface);
+  void GenDestructor(std::ofstream& stream, const Interface& iface);
+  void GenCionPayloadReceivedEvent(std::ofstream& stream,
+      const Interface& iface);
+  void GenMethods(std::ofstream& stream, const Interface& iface);
+  void GenInvocation(std::ofstream& stream, const Declaration& decl);
+  void GenHandlerInvocation(std::ofstream& stream, const Declaration& decl);
+};
+
+}  // namespace tidl
+
+#endif  // IDLC_CPP_CION_GEN_CPP_GROUP_BODY_GEN_H_
diff --git a/idlc/gen_cion/cpp_cion_group_body_gen_cb.h b/idlc/gen_cion/cpp_cion_group_body_gen_cb.h
new file mode 100644 (file)
index 0000000..ec7fae8
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_GEN_CION_CPP_GROUP_BODY_GEN_CB_H_
+#define IDLC_CPP_GEN_CION_CPP_GROUP_BODY_GEN_CB_H_
+
+const char CB_DTOR[] =
+R"__cpp_cb(
+<CLS_NAME>::~<CLS_NAME>() {
+  if (cion_group_ != nullptr) {
+    int ret = cion_group_unsubscribe(cion_group_);
+    if (ret != CION_ERROR_NONE)
+      _E("Failed to unsubscribe. error(%d)", ret);
+      cion_group_destroy(cion_group_);
+  }
+
+  if (cion_security_ != nullptr)
+    cion_security_destroy(cion_security_);
+}
+)__cpp_cb";
+
+const char CB_INVOCATION_PRE[] =
+R"__cpp_cb(  rpc_port_parcel_h p;
+  rpc_port_parcel_create(&p);
+)__cpp_cb";
+
+const char CB_INVOCATION_ASYNC_MID[] =
+R"__cpp_cb(
+    // Publish
+    unsigned int size;
+    char *data;
+
+    int ret = rpc_port_parcel_get_raw(p, (void **)&data, &size);
+    if (ret != RPC_PORT_ERROR_NONE) {
+      _E("Failed to get raw. error(%d)", ret);
+      rpc_port_parcel_destroy(p);
+      throw InvalidIOException();
+    }
+
+    cion_payload_h pl;
+    ret = cion_payload_create(&pl, CION_PAYLOAD_TYPE_DATA);
+    if (ret != CION_ERROR_NONE) {
+      _E("Failed to cion_payload_create : %d", ret);
+      rpc_port_parcel_destroy(p);
+      throw InvalidIOException();
+    }
+
+    ret = cion_payload_set_data(pl, (const unsigned char*)data, size);
+    if (ret != CION_ERROR_NONE) {
+      _E("Failed to cion_payload_set_data : %d", ret);
+      rpc_port_parcel_destroy(p);
+      cion_payload_destroy(pl);
+      throw InvalidIOException();
+    }
+
+    ret = cion_group_publish(cion_group_, pl);
+    if (ret != CION_ERROR_NONE) {
+      _E("Failed to cion_group_publish : %d", ret);
+      rpc_port_parcel_destroy(p);
+      cion_payload_destroy(pl);
+      throw InvalidIOException();
+    }
+
+    cion_payload_destroy(pl);
+)__cpp_cb";
+
+const char CB_INVOCATION_END[] =
+R"__cpp_cb(
+  rpc_port_parcel_destroy(p);
+
+  return ret;
+)__cpp_cb";
+
+const char CB_GROUP_ON_PAYLOAD_RECEIVED_CB_FRONT[] =
+R"__cpp_cb(
+void <CLS_NAME>::OnPayloadReceivedCB(const cion_peer_info_h peer_info,
+    const cion_payload_h payload) {
+  cion_payload_type_e type;
+  int ret = cion_payload_get_type(payload, &type);
+  if (ret != CION_ERROR_NONE) {
+    _E("Failed to cion_payload_get_type. error(%d)", ret);
+    return;
+  }
+
+  if (type != CION_PAYLOAD_TYPE_DATA) {
+    _E("Wrong payload type, only data payload is available");
+    return;
+  }
+
+  unsigned char *data;
+  unsigned int size;
+  ret = cion_payload_get_data(payload, &data, &size);
+  if (ret != CION_ERROR_NONE) {
+    _E("Failed to cion_payload_get_data. error(%d)", ret);
+    return;
+  }
+
+  rpc_port_parcel_h parcel_received;
+  rpc_port_parcel_create_from_raw(&parcel_received, data, size);
+  free(data);
+
+  int cmd;
+  rpc_port_parcel_read_int32(parcel_received, &cmd);
+
+  switch (cmd) {
+)__cpp_cb";
+
+const char CB_GROUP_ON_PAYLOAD_RECEIVED_CB_BACK[] =
+R"__cpp_cb(
+    default:
+      _E("Unknown command(%d)", cmd);
+  }
+
+  rpc_port_parcel_destroy(parcel_received);
+}
+)__cpp_cb";
+
+const char CB_GROUP_INTERFACE_CTOR[] =
+R"__cpp_cb(
+<CLS_NAME>::<CLS_NAME>(std::string topic) : topic_name_(std::move(topic)) {
+  cion_security_h security;
+  int ret = cion_security_create(&security);
+  if (ret != CION_ERROR_NONE) {
+    _E("Failed to create security handle. error(%d)", ret);
+    throw InvalidIOException();
+  }
+  auto security_auto = std::unique_ptr<
+      std::remove_pointer<cion_security_h>::type, decltype(cion_security_destroy)*>(
+          security, cion_security_destroy);
+
+  cion_group_h group = nullptr;
+  ret = cion_group_create(&group, topic_name_.c_str(), security);
+  if (ret != CION_ERROR_NONE) {
+    _E("Failed to create handle. error(%d)", ret);
+    throw InvalidIOException();
+  }
+  auto group_auto = std::unique_ptr<
+      std::remove_pointer<cion_group_h>::type, decltype(cion_group_destroy)*>(
+          group, cion_group_destroy);
+
+  ret = cion_group_add_joined_cb(group,
+      [](const char *topic_name, const cion_peer_info_h peer_info,
+          void *user_data) {
+            <CLS_NAME> *gr = static_cast<<CLS_NAME>*>(user_data);
+            gr->OnJoined(peer_info);
+          },
+      this);
+  if (ret != CION_ERROR_NONE) {
+    _E("Failed to cion_group_add_joined_cb. error(%d)", ret);
+    throw InvalidIOException();
+  }
+
+  ret = cion_group_add_left_cb(group,
+      [](const char *topic_name, const cion_peer_info_h peer_info,
+          void *user_data) {
+            <CLS_NAME> *gr = static_cast<<CLS_NAME>*>(user_data);
+            gr->OnLeft(peer_info);
+          },
+      this);
+  if (ret != CION_ERROR_NONE) {
+    _E("Failed to cion_group_add_left_cb. error(%d)", ret);
+    throw InvalidIOException();
+  }
+
+  ret = cion_group_add_payload_received_cb(group,
+      [](const char *topic_name, const cion_peer_info_h peer_info,
+          const cion_payload_h payload, void *user_data) {
+            <CLS_NAME> *gr = static_cast<<CLS_NAME>*>(user_data);
+            gr->OnPayloadReceivedCB(peer_info, payload);
+          },
+      this);
+  if (ret != CION_ERROR_NONE) {
+    _E("Failed to cion_group_add_payload_received_cb. error(%d)", ret);
+    throw InvalidIOException();
+  }
+
+  ret = cion_group_subscribe(group);
+  if (ret != CION_ERROR_NONE) {
+    _E("Failed to subscribe. error(%d)", ret);
+    switch(ret) {
+    case CION_ERROR_PERMISSION_DENIED :
+      throw UnauthorizedAccessException();
+      break;
+    case CION_ERROR_INVALID_PARAMETER :
+      throw NotConnectedSocketException();
+      break;
+    default :
+      throw InvalidIOException();
+    }
+  }
+
+  cion_security_ = security_auto.release();
+  cion_group_ = group_auto.release();
+}
+)__cpp_cb";
+
+#endif  // IDLC_CPP_GEN_CION_CPP_GROUP_BODY_GEN_CB_H_
diff --git a/idlc/gen_cion/cpp_cion_group_header_gen.cc b/idlc/gen_cion/cpp_cion_group_header_gen.cc
new file mode 100644 (file)
index 0000000..486a151
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/cpp_cion_group_header_gen.h"
+
+namespace {
+#include "idlc/gen_cion/cpp_cion_group_header_gen_cb.h"
+}
+
+namespace tidl {
+
+CppCionGroupHeaderGen::CppCionGroupHeaderGen(std::shared_ptr<Document> doc)
+    : CppCionGeneratorBase(doc) {}
+
+void CppCionGroupHeaderGen::OnInitGen(std::ofstream& stream) {
+  GenVersion(stream);
+  stream << CB_HEADER;
+  GenNamespace(stream);
+}
+
+void CppCionGroupHeaderGen::OnFiniGen(std::ofstream& stream) {
+}
+
+void CppCionGroupHeaderGen::GenNamespace(std::ofstream& stream) {
+  stream << "namespace cion ";
+  GenBrace(stream, 0, [&]() {
+    stream << "namespace " << GetFileNamespace() << " ";
+    GenBrace(stream, 0, [&]() {
+      stream << NLine(1);
+      GenStructuresForHeader(stream, true);
+      stream << "namespace group ";
+      GenBrace(stream, 0, [&]() {
+        GenExceptions(stream);
+        GenInterfaces(stream);
+      }, false, false);
+      stream << "  // namespace group" + NLine(1);
+    }, false, false);
+    stream << "  // namespace " + GetFileNamespace() + NLine(1);
+  }, false, false);
+  stream << "  // namespace cion" + NLine(1);
+}
+
+void CppCionGroupHeaderGen::GenExceptions(std::ofstream& stream) {
+  stream << CB_EXCEPTIONS;
+}
+
+void CppCionGroupHeaderGen::GenInterfaces(std::ofstream& stream) {
+  for (auto& i : GetDocument().GetBlocks()) {
+    if (i->GetType() != Block::TYPE_INTERFACE)
+      continue;
+    Interface& iface = static_cast<Interface&>(*i);
+    GenInterface(stream, iface);
+  }
+  stream << NLine(1);
+}
+
+void CppCionGroupHeaderGen::GenInterface(std::ofstream& stream,
+    const Interface& iface) {
+  stream << NLine(1) << "class " << iface.GetID() << " ";
+  GenBrace(stream, 0, [&]() {
+    stream << " public:" << NLine(1);
+    stream << ReplaceAll(CB_PUBLIC_MEMBERS, "<CLS_NAME>", iface.GetID())
+           << NLine(1);
+    GenMethods(stream, iface);
+    GenMethodHandlers(stream, iface);
+    stream << NLine(1) << " private:" << NLine(1);
+    GenMethodId(stream, iface, true);
+    stream << CB_PRIVATE_MEMBERS;
+  }, false, false);
+  stream << ";" << NLine(1);
+}
+
+void CppCionGroupHeaderGen::GenMethods(std::ofstream& stream,
+    const Interface& iface) {
+  auto& decls = iface.GetDeclarations();
+
+  for (const auto& i : decls) {
+    if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+      continue;
+
+    GenDeclaration(stream, *i);
+  }
+}
+
+void CppCionGroupHeaderGen::GenMethodHandlers(std::ofstream& stream,
+    const Interface& iface) {
+  auto& decls = iface.GetDeclarations();
+
+  for (const auto& i : decls) {
+    stream << Tab(1) << "virtual " << ConvertTypeToString(i->GetType()) << " On"
+           << i->GetID() << "(";
+    GenParameters(stream, i->GetParameters());
+    stream << ") = 0;" << NLine(1);
+  }
+}
+
+void CppCionGroupHeaderGen::GenDeclaration(std::ofstream& stream,
+    const Declaration& decl) {
+  if (!decl.GetComments().empty())
+    stream << NLine(1) << AddIndent(TAB_SIZE, decl.GetComments());
+
+  stream << Tab(1) << ConvertTypeToString(decl.GetType()) << " "
+         << decl.GetID() << "(";
+  GenParameters(stream, decl.GetParameters());
+  stream << ");" << NLine(1);
+}
+}  // namespace tidl
diff --git a/idlc/gen_cion/cpp_cion_group_header_gen.h b/idlc/gen_cion/cpp_cion_group_header_gen.h
new file mode 100644 (file)
index 0000000..297f666
--- /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_CPP_CION_GEN_CPP_GROUP_HEADER_GEN_H_
+#define IDLC_CPP_CION_GEN_CPP_GROUP_HEADER_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/cpp_cion_gen_base.h"
+
+namespace tidl {
+
+class CppCionGroupHeaderGen : public CppCionGeneratorBase {
+ public:
+  explicit CppCionGroupHeaderGen(std::shared_ptr<Document> doc);
+  virtual ~CppCionGroupHeaderGen() = default;
+
+  void OnInitGen(std::ofstream& stream) override;
+  void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+  void GenNamespace(std::ofstream& stream);
+  void GenExceptions(std::ofstream& stream);
+  void GenInterfaces(std::ofstream& stream);
+  void GenInterface(std::ofstream& stream, const Interface& iface);
+  void GenMethods(std::ofstream& stream, const Interface& iface);
+  void GenMethodHandlers(std::ofstream& stream, const Interface& iface);
+  void GenDeclaration(std::ofstream& stream, const Declaration& decl);
+};
+
+}  // namespace tidl
+
+#endif  // IDLC_CPP_CION_GEN_CPP_GROUP_HEADER_GEN_H_
diff --git a/idlc/gen_cion/cpp_cion_group_header_gen_cb.h b/idlc/gen_cion/cpp_cion_group_header_gen_cb.h
new file mode 100644 (file)
index 0000000..41b3025
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_CPP_CION_GEN_CPP_GROUP_HEADER_GEN_CB_H_
+#define IDLC_CPP_CION_GEN_CPP_GROUP_HEADER_GEN_CB_H_
+
+const char CB_EXCEPTIONS[] =
+R"__cpp_cb(
+class Exception {};
+class NotConnectedSocketException : public Exception {};
+class InvalidProtocolException : public Exception {};
+class InvalidIOException : public Exception {};
+class UnauthorizedAccessException : public Exception {};
+)__cpp_cb";
+
+const char CB_PUBLIC_MEMBERS[] =
+R"__cpp_cb(  /// <summary>
+  /// Constructor for this class
+  /// </summary>
+  /// <param name="topic_name">The topic name to subscribe</param>
+  /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege>
+  /// <privilege>http://tizen.org/privilege/internet</privilege>
+  /// <exception cref="UnauthorizedAccessException">
+  /// Thrown when an application does not have the privilege to access this method.
+  /// </exception>
+  /// <exception cref="InvalidIOException">
+  /// Thrown when internal I/O error happen.
+  /// </exception>
+  explicit <CLS_NAME>(std::string topic_name);
+
+  /// <summary>
+  /// Destructor for this class
+  /// </summary>
+  virtual ~<CLS_NAME>();
+
+  /// <summary>
+  /// This method will be invoked when the peer group app is joined to the topic.
+  /// </summary>
+  virtual void OnJoined(const cion_peer_info_h peer_info) = 0;
+
+  /// <summary>
+  /// This method will be invoked after the peer group app was left from the tpoic.
+  /// </summary>
+  virtual void OnLeft(const cion_peer_info_h peer_info) = 0;
+
+)__cpp_cb";
+
+const char CB_PRIVATE_MEMBERS[] =
+R"__cpp_cb(  void OnPayloadReceivedCB(const cion_peer_info_h peer_info,
+      const cion_payload_h payload);
+  cion_client_h cion_group_ = nullptr;
+  cion_security_h cion_security_ = nullptr;
+  std::string topic_name_;
+  std::recursive_mutex mutex_;
+)__cpp_cb";
+
+const char CB_HEADER[] =
+R"__cpp_cb(
+#pragma once
+
+#include <cion.h>
+#include <rpc-port-parcel.h>
+
+#include <atomic>
+#include <list>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <vector>
+
+)__cpp_cb";
+
+#endif  // IDLC_CPP_CION_GEN_CPP_GROUP_HEADER_GEN_CB_H_
index b4b68d2ca1707ce8b94e0091a93459c6ffcf65ed..b0a06660e63b7a0c7b8613874e56b41f7698f8cd 100644 (file)
@@ -43,6 +43,8 @@
 #include "idlc/gen_cion/cpp_cion_proxy_body_gen.h"
 #include "idlc/gen_cion/cpp_cion_stub_header_gen.h"
 #include "idlc/gen_cion/cpp_cion_stub_body_gen.h"
+#include "idlc/gen_cion/cpp_cion_group_header_gen.h"
+#include "idlc/gen_cion/cpp_cion_group_body_gen.h"
 #include "idlc/options.h"
 
 
@@ -256,7 +258,13 @@ void GenerateGroupCodes(std::shared_ptr<tidl::Options> options,
       break;
     }
     case tidl::Options::LANGUAGE_TYPE_CPP:
+    {
+      tidl::CppCionGroupHeaderGen group_header(ps.GetDoc());
+      group_header.Run(options->GetOutput() + ".h");
+      tidl::CppCionGroupBodyGen group_body(ps.GetDoc());
+      group_body.Run(options->GetOutput() + ".cc");
       break;
+    }
     case tidl::Options::LANGUAGE_TYPE_CSHARP:
       break;
     case tidl::Options::LANGUAGE_TYPE_JAVA:
@@ -264,7 +272,7 @@ void GenerateGroupCodes(std::shared_ptr<tidl::Options> options,
 
     default:
       break;
-  }
+    }
   }
 }