Implement C++ Generator (Structure Part) 58/168958/5
authorInkyun Kil <inkyun.kil@samsung.com>
Thu, 1 Feb 2018 10:44:53 +0000 (19:44 +0900)
committerInkyun Kil <inkyun.kil@samsung.com>
Tue, 13 Feb 2018 06:23:20 +0000 (15:23 +0900)
Change-Id: Iad229d72ffe5f672e35e0e12c626f3f48ea851cd
Signed-off-by: Inkyun Kil <inkyun.kil@samsung.com>
idlc/cpp_gen/cpp_gen_base.cc
idlc/cpp_gen/cpp_gen_base.h
idlc/cpp_gen/cpp_proxy_body_gen.cc
idlc/cpp_gen/cpp_proxy_body_gen.h
idlc/cpp_gen/cpp_proxy_header_gen.cc
idlc/cpp_gen/cpp_proxy_header_gen.h
idlc/cpp_gen/cpp_stub_body_gen.cc
idlc/cpp_gen/cpp_stub_body_gen.h
idlc/cpp_gen/cpp_stub_header_gen.cc
idlc/cpp_gen/cpp_stub_header_gen.h

index 887c523..611f897 100644 (file)
  */
 
 #include <vector>
+#include <utility>
 
 #include "idlc/cpp_gen/cpp_gen_base.h"
 
 namespace tidl {
 
 CppGeneratorBase::CppGeneratorBase(std::shared_ptr<Document> doc)
-    : Generator(doc) {}
+    : Generator(doc) {
+  type_map_ = {
+      {"char", "char"}, {"int", "int"}, {"short", "short"},
+      {"long", "long"}, {"string", "std::string"}, {"bool", "bool"},
+      {"list", "std::list"}, {"float","float"}, {"double", "double"},
+      {"bundle", "bundle*"}, {"void", "void"}
+  };
+
+  parcel_type_map_ = {
+    {"char", "byte"},
+    {"int", "int32"},
+    {"short", "int16"},
+    {"long", "int64"},
+    {"string", "string"},
+    {"bool", "bool"},
+    {"float", "float"},
+    {"double", "double"},
+    {"bundle", "bundle"},
+  };
+}
+
+void CppGeneratorBase::GenStructuresForHeader(std::ofstream& stream) {
+  for (auto& i : GetDocument().GetBlocks()) {
+    if (i->GetType() != Block::TYPE_STRUCTURE)
+      continue;
+    Structure& st = static_cast<Structure&>(*i);
+    GenStructureForHeader(stream, st);
+    stream << std::endl;
+  }
+}
+
+void CppGeneratorBase::GenStructureForHeader(std::ofstream& stream, const Structure& st) {
+  std::vector<std::string> p;
+  std::vector<std::string> v;
+  std::vector<std::string> lv;
+  const char ctor[] = "    $$();\n" \
+                      "    $$($$);\n";
+  const char dtor[] = "    ~$$();\n";
+  const char setget[] = "$$";
+  const char variable[] = "$$\n";
+
+  stream << "  class " << st.GetID() << " final ";
+
+  for (auto& i : st.GetElements().GetElms()) {
+    if (i->GetType().GetMetaType() != nullptr) {
+      lv.push_back(ConvertTypeToString(i->GetType()) + " " + i->GetID());
+    }
+    else {
+      if (i->GetType().IsUserDefinedType())
+        p.push_back(i->GetType().ToString() + " " + i->GetID());
+      else
+        p.push_back(ConvertTypeToString(i->GetType()) + " " + i->GetID());
+
+      v.push_back(ConvertTypeToString(i->GetType()) + " " + i->GetID());
+    }
+  }
+
+  GenBrace(stream, TAB_SIZE, [&]() {
+    stream << Tab(1) << "public:" << NLine(1);
+    GenTemplate(ctor, stream,
+      [&]()->std::string {
+        return st.GetID();
+      },
+      [&]()->std::string {
+        return st.GetID();
+      },
+      [&]()->std::string {
+        std::string str;
+        for (auto& i : p) {
+          str += i;
+
+          if (i != p.back())
+            str += ", ";
+        }
+        return str;
+      }
+    );
+
+    GenTemplate(dtor, stream,
+      [&]()->std::string {
+        return st.GetID();
+      }
+    );
+
+    stream << NLine(1);
+
+    GenTemplate(setget, stream,
+      [&]()->std::string {
+        std::string str;
+        for (auto& i : st.GetElements().GetElms()) {
+          if (i->GetType().IsUserDefinedType()) {
+            str += Tab(2) + "void Set" + i->GetID() + "("
+                   + ConvertTypeToString(i->GetType()) + " " + i->GetID() + ")";
+            str += "{ " + i->GetID() + "_ = " + i->GetID() + "; " + "}";
+            str += NLine(1);
+            str += Tab(2) + ConvertTypeToString(i->GetType()) + "& Get" + i->GetID()
+                   + "() const " + "{ return *" + i->GetID() + "_ }";
+          } else if (i->GetType().GetMetaType() != nullptr) {
+            str += Tab(2) + "void Set" + i->GetID() + "("
+                   + ConvertTypeToString(i->GetType()) + " " + i->GetID() + ")";
+            str += "{ " + i->GetID() + "_ = " + i->GetID() + "; " + "}";
+            str += NLine(1);
+            str += Tab(2) + ConvertTypeToString(i->GetType()) + "& Get" + i->GetID()
+                   + "() const " + "{ return " + i->GetID() + "_ }";
+          }
+          else {
+            str += Tab(2) + "void Set" + i->GetID() + "("
+                   + ConvertTypeToString(i->GetType()) + " " + i->GetID() + ")";
+            str += "{ " + i->GetID() + "_ = " + i->GetID() + "; " + "}";
+            str += NLine(1);
+            str += Tab(2) + ConvertTypeToString(i->GetType()) + " Get" + i->GetID()
+                   + "() const " + "{ return " + i->GetID() + "_ }";
+          }
+
+          str += NLine(1);
+        }
+        return str;
+      }
+    );
+
+    stream << NLine(1);
+    stream << Tab(1) << "private:";
+    GenTemplate(variable, stream,
+      [&]()->std::string {
+        std::string str;
+        for (auto& i : v) {
+            str += "\n" + Tab(2) + i + "_;";
+        }
+        for (auto& i : lv) {
+            str += "\n" + Tab(2) + i + "_;";
+        }
+        return str;
+      }
+    );
+  }, false);
+}
+
+void CppGeneratorBase::GenStructuresForBody(std::ofstream& stream) {
+  for (auto& i : GetDocument().GetBlocks()) {
+    if (i->GetType() != Block::TYPE_STRUCTURE)
+      continue;
+    Structure& st = static_cast<Structure&>(*i);
+    GenStructureForBody(stream, st);
+    stream << std::endl;
+  }
+}
+
+void CppGeneratorBase::GenStructureForBody(std::ofstream& stream, const Structure& st) {
+  std::vector<std::pair<std::string, std::string>> v;
+  const char ctor[] = "  $$::$$() {}\n" \
+                      "  $$::$$($$)\n" \
+                      "    : $$ {}";
+  const char dtor[] = "  $$::~$$() $$";
+
+  for (auto& i : st.GetElements().GetElms()) {
+    if (i->GetType().GetMetaType() == nullptr) {
+      std::pair<std::string, std::string> p;
+      if (i->GetType().IsUserDefinedType()) {
+        p.first = i->GetType().ToString();
+        p.second = i->GetID();
+      }
+      else  {
+        p.first = ConvertTypeToString(i->GetType());
+        p.second = i->GetID();
+      }
+      v.push_back(p);
+    }
+  }
+
+  GenTemplate(ctor, stream,
+    [&]()->std::string {
+      return st.GetID();
+    },
+    [&]()->std::string {
+      return st.GetID();
+    },
+    [&]()->std::string {
+      return st.GetID();
+    },
+    [&]()->std::string {
+      return st.GetID();
+    },
+    [&]()->std::string {
+      std::string str;
+      for (auto& i : v) {
+        str += i.first + " " + i.second ;
+
+        if (i != v.back())
+          str += ", ";
+      }
+      return str;
+    },
+    [&]()->std::string {
+      std::string str;
+      for (auto& i : v) {
+        if (i.first == "std::string")
+          str += i.second + "_(std::move(" + i.second + "))";
+        else
+          str += i.second + "_(" + i.second + ")";
+
+        if (i != v.back())
+          str += ", ";
+      }
+      return str;
+    }
+  );
+
+  stream <<  NLine(1);
+  GenTemplate(dtor, stream,
+    [&]()->std::string {
+      return st.GetID();
+    },
+    [&]()->std::string {
+      return st.GetID();
+    },
+    [&]()->std::string {
+      std::string str;
+      str += "{" + NLine(1);
+      for (auto& i : v) {
+        if (i.first == "bundle*") {
+          str += Tab(2) + "if (" + i.second + "_) {" + NLine(1);
+          str += Tab(3) + "bundle_free(" + i.second + "_);" + NLine(1);
+          str += Tab(2) + "}" + NLine(1);
+        }
+      }
+      str += Tab(1) + "}" + NLine(1);
+      return str;
+    }
+  );
+}
+
+void CppGeneratorBase::GenSerializer(std::ofstream& stream) {
+  for (auto& i : GetDocument().GetBlocks()) {
+    if (i->GetType() != Block::TYPE_STRUCTURE)
+      continue;
+    Structure& st = static_cast<Structure&>(*i);
+    GenSerializer(stream, st);
+    stream << std::endl;
+  }
+}
+
+void CppGeneratorBase::GenSerializer(std::ofstream& stream, const Structure& st) {
+  const char parcel_str[] = "rpc_port_parcel_h";
+
+  stream << Tab(1) << parcel_str << " operater << ("
+         << parcel_str << " h, const " << st.GetID() << "& param) ";
+  GenBrace(stream, TAB_SIZE, [&]() {
+    for (auto& i : st.GetElements().GetElms()) {
+       if (i->GetType().ToString() == "list") {
+        stream << Tab(2) << "rpc_port_parcel_write_array_count(h, param."
+               << i->GetID() << "_.size());" << NLine(1);
+        stream << Tab(2) << "for (auto& i : param." << i->GetID() << "_) ";
+        GenBrace(stream, TAB_SIZE * 2, [&] {
+          stream << Tab(3) << "h << *i;" << NLine(1);
+        }, false);
+      } else if (i->GetType().ToString() == "string") {
+        stream << Tab(2) << "rpc_port_parcel_write_"
+               << parcel_type_map_[i->GetType().ToString()]
+               << "(h, &" << i->GetID() << "_.c_str());"
+               << NLine(1);
+      } else if (i->GetType().ToString() == "bundle") {
+        stream << Tab(2) << "if (param." << i->GetID() << "_) ";
+        GenBrace(stream, TAB_SIZE * 2, [&] {
+          stream << Tab(3) << "rpc_port_parcel_write_bundle(h, param."
+                 << i->GetType().ToString() << "_);" << NLine(1);
+        }, false);
+        stream << Tab(2) << "else ";
+        GenBrace(stream, TAB_SIZE * 2, [&] {
+          stream << Tab(3) << "bundle* b = bundle_create();" << NLine(1)
+                 << Tab(3) << "rpc_port_parcel_write_bundle(h, b);" << NLine(1)
+                 << Tab(3) << "bundle_free(b);" << NLine(1);
+        }, false);
+      } else {
+        stream << Tab(2) << "rpc_port_parcel_write_"
+               << parcel_type_map_[i->GetType().ToString()]
+               << "(h, param." << i->GetID() << "_);"
+               << NLine(1);
+      }
+    }
+  }, false);
+}
+
+
+void CppGeneratorBase::GenDeSerializer(std::ofstream& stream) {
+  for (auto& i : GetDocument().GetBlocks()) {
+    if (i->GetType() != Block::TYPE_STRUCTURE)
+      continue;
+    Structure& st = static_cast<Structure&>(*i);
+    GenDeSerializer(stream, st);
+    stream << std::endl;
+  }
+}
+
+void CppGeneratorBase::GenDeSerializer(std::ofstream& stream, const Structure& st) {
+  const char parcel_str[] = "rpc_port_parcel_h";
+
+  stream << Tab(1) << parcel_str << " operater >> ("
+         << parcel_str << " h, " << st.GetID() << "& param) ";
+
+  GenBrace(stream, TAB_SIZE, [&]() {
+    for (auto& i : st.GetElements().GetElms()) {
+      if (i->GetType().ToString() == "string") {
+        stream << Tab(2) << "char* " << i->GetID() << " = nullptr;";
+        stream << NLine(1);
+      } else if (i->GetType().ToString() == "list") {
+        stream << Tab(2) << "int l = 0;";
+        stream << NLine(1);
+      }
+    }
+
+    stream << NLine(1);
+
+    for (auto& i : st.GetElements().GetElms()) {
+      if (i->GetType().ToString() == "string") {
+        stream << Tab(2) << "rpc_port_parcel_read_"
+               << parcel_type_map_[i->GetType().ToString()]
+               << "(h, &" << i->GetID() << ");"
+               << NLine(1);
+        stream << Tab(2) << "param." << i->GetID() << "_ = " << i->GetID() << ";"
+               << NLine(1);
+        stream << Tab(2) << "free(" << i->GetID() << ");"
+               << NLine(1);
+      } else if (i->GetType().ToString() == "list") {
+        stream << Tab(2) << "for (int i = 0; i < l; i++) ";
+        GenBrace(stream, TAB_SIZE * 2, [&] {
+          stream << Tab(3) << i->GetType().GetMetaType()->ToString() << "* value = new "
+                 << i->GetType().GetMetaType()->ToString() << "();"
+                 << NLine(1);
+          stream << NLine(1);
+          stream << Tab(3) << "h >> *value;"
+                 << NLine(1);
+          stream << Tab(3) << "param." << i->GetID() << "_.emplace_back(value);"
+                 << NLine(1);
+        }, false);
+      } else {
+        stream << Tab(2) << "rpc_port_parcel_read_"
+               << parcel_type_map_[i->GetType().ToString()]
+               << "(h, &param." << i->GetID() << "_);"
+               << NLine(1);
+      }
+    }
+  }, false);
+}
+
+std::string CppGeneratorBase::ConvertTypeToString(const BaseType& type) {
+  if (type.IsUserDefinedType())
+    return "std::unique_ptr<" + type.ToString() + ">";
+
+  if (type.GetMetaType() != nullptr)
+    return type_map_[type.ToString()] + "<" +
+        ConvertTypeToString(*(type.GetMetaType())) + ">";
+
+  return type_map_[type.ToString()];
+}
+
+std::string CppGeneratorBase::Tab(int cnt) {
+  std::string t(cnt * 2, ' ');
+
+  return t;
+}
+
+std::string CppGeneratorBase::NLine(int cnt) {
+  std::string t(cnt, '\n');
+
+  return t;
+}
 
 }  // namespace tidl
index fa92ddf..1b77539 100644 (file)
@@ -31,6 +31,26 @@ class CppGeneratorBase : public Generator {
  public:
   explicit CppGeneratorBase(std::shared_ptr<Document> doc);
   virtual ~CppGeneratorBase() = default;
+
+  void GenStructuresForHeader(std::ofstream& stream);
+  void GenStructureForHeader(std::ofstream& stream, const Structure& st);
+  void GenStructuresForBody(std::ofstream& stream);
+  void GenStructureForBody(std::ofstream& stream, const Structure& st);
+  void GenSerializer(std::ofstream& stream);
+  void GenSerializer(std::ofstream& stream, const Structure& st);
+  void GenDeSerializer(std::ofstream& stream);
+  void GenDeSerializer(std::ofstream& stream, const Structure& st);
+
+  std::string ConvertTypeToString(const BaseType& type);
+  std::string Tab(int cnt);
+  std::string NLine(int cnt);
+
+ protected:
+  const int TAB_SIZE = 2;
+
+ private:
+  std::map<std::string, std::string> type_map_;
+  std::map<std::string, std::string> parcel_type_map_;
 };
 
 }  // namespace tidl
index 4472a76..84dd56d 100644 (file)
@@ -22,9 +22,36 @@ CppProxyBodyGen::CppProxyBodyGen(std::shared_ptr<Document> doc)
     : CppGeneratorBase(doc) {}
 
 void CppProxyBodyGen::OnInitGen(std::ofstream& stream) {
+  stream << "#include <string>" << NLine(1)
+         << "#include <memory>" << NLine(1)
+         << "#include <stdlib>" << NLine(1)
+         << "#include <assert>" << NLine(1)
+         <<  NLine(1)
+         << "#include <rpc-port-parcel.h>" << NLine(1)
+         << "#include <rpc-port.h>" << NLine(1);
+  stream <<  NLine(1);
+  GenNamespace(stream);
 }
 
 void CppProxyBodyGen::OnFiniGen(std::ofstream& stream) {
 }
 
+void CppProxyBodyGen::GenNamespace(std::ofstream& stream) {
+  stream << "namespace rpc_port ";
+  GenBrace(stream, 0, [&]() {
+    GenStructuresForBody(stream);
+    GenSerializer(stream);
+    GenDeSerializer(stream);
+    stream << Tab(1) << "namespace proxy ";
+    GenBrace(stream, TAB_SIZE, [&]() {
+//      GenInterfaces(stream);
+    }, false);
+  }, false);
+}
+
+void CppProxyBodyGen::GenConstructor(std::ofstream& stream) {
+
+}
+
+
 }  // namespace tidl
index d02e035..eeacd33 100644 (file)
@@ -32,6 +32,11 @@ class CppProxyBodyGen : public CppGeneratorBase {
   void OnInitGen(std::ofstream& stream) override;
   void OnFiniGen(std::ofstream& stream) override;
 
+ private:
+  void GenNamespace(std::ofstream& stream);
+  void GenStructures(std::ofstream& stream);
+  void GenConstructor(std::ofstream& stream);
+  void GenDestructor(std::ofstream& stream);
 };
 
 }  // namespace tidl
index da27c03..a82be74 100644 (file)
@@ -22,9 +22,30 @@ CppProxyHeaderGen::CppProxyHeaderGen(std::shared_ptr<Document> doc)
     : CppGeneratorBase(doc) {}
 
 void CppProxyHeaderGen::OnInitGen(std::ofstream& stream) {
+  stream << "#pragma once" << NLine(1)
+         <<  NLine(1)
+         << "#include <string>" << NLine(1)
+         << "#include <memory>" << NLine(1)
+         << "#include <list>" << NLine(1)
+         <<  NLine(1)
+         << "#include <rpc-port-parcel.h>" << NLine(1)
+         << "#include <rpc-port.h>" << NLine(1);
+  stream <<  NLine(1);
+  GenNamespace(stream);
 }
 
 void CppProxyHeaderGen::OnFiniGen(std::ofstream& stream) {
 }
 
+void CppProxyHeaderGen::GenNamespace(std::ofstream& stream) {
+  stream << "namespace rpc_port ";
+  GenBrace(stream, 0, [&]() {
+    GenStructuresForHeader(stream);
+    stream << Tab(1) << "namespace proxy ";
+    GenBrace(stream, TAB_SIZE, [&]() {
+//      GenInterfaces(stream);
+    }, false);
+  }, false);
+}
+
 }  // namespace tidl
index 927cbcd..dc4b8df 100644 (file)
@@ -31,6 +31,9 @@ class CppProxyHeaderGen : public CppGeneratorBase {
 
   void OnInitGen(std::ofstream& stream) override;
   void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+  void GenNamespace(std::ofstream& stream);
 };
 
 }  // namespace tidl
index a2e89e3..8fd1a82 100644 (file)
@@ -22,8 +22,30 @@ CppStubBodyGen::CppStubBodyGen(std::shared_ptr<Document> doc)
     : CppGeneratorBase(doc) {}
 
 void CppStubBodyGen::OnInitGen(std::ofstream& stream) {
+  stream << "#include <string>" << NLine(1)
+         << "#include <memory>" << NLine(1)
+         << "#include <stdlib>" << NLine(1)
+         << "#include <assert>" << NLine(1)
+         <<  NLine(1)
+         << "#include <rpc-port-parcel.h>" << NLine(1)
+         << "#include <rpc-port.h>" << NLine(1);
+  stream <<  NLine(1);
+  GenNamespace(stream);
 }
 
 void CppStubBodyGen::OnFiniGen(std::ofstream& stream) {}
 
+void CppStubBodyGen::GenNamespace(std::ofstream& stream) {
+  stream << "namespace rpc_port ";
+  GenBrace(stream, 0, [&]() {
+    GenStructuresForBody(stream);
+    GenSerializer(stream);
+    GenDeSerializer(stream);
+    stream << Tab(1) << "namespace stub ";
+    GenBrace(stream, TAB_SIZE, [&]() {
+//      GenInterfaces(stream);
+    }, false);
+  }, false);
+}
+
 }  // namespace tidl
index 5195efb..47a4944 100644 (file)
@@ -31,6 +31,9 @@ class CppStubBodyGen : public CppGeneratorBase {
 
   void OnInitGen(std::ofstream& stream) override;
   void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+  void GenNamespace(std::ofstream& stream);
 };
 
 }  // namespace tidl
index 47a8d1c..db1a4bf 100644 (file)
@@ -22,8 +22,29 @@ CppStubHeaderGen::CppStubHeaderGen(std::shared_ptr<Document> doc)
     : CppGeneratorBase(doc) {}
 
 void CppStubHeaderGen::OnInitGen(std::ofstream& stream) {
+  stream << "#pragma once" << NLine(1)
+         <<  NLine(1)
+         << "#include <string>" << NLine(1)
+         << "#include <memory>" << NLine(1)
+         << "#include <list>" << NLine(1)
+         <<  NLine(1)
+         << "#include <rpc-port-parcel.h>" << NLine(1)
+         << "#include <rpc-port.h>" << NLine(1);
+  stream <<  NLine(1);
+  GenNamespace(stream);
 }
 
-void CppStubHeaderGen::OnFiniGen(std::ofstream& stream) {}
+void CppStubHeaderGen::OnFiniGen(std::ofstream& stream) {
+}
 
+void CppStubHeaderGen::GenNamespace(std::ofstream& stream) {
+  stream << "namespace rpc_port ";
+  GenBrace(stream, 0, [&]() {
+    GenStructuresForHeader(stream);
+    stream << Tab(1) << "namespace stub ";
+    GenBrace(stream, TAB_SIZE, [&]() {
+//      GenInterfaces(stream);
+    }, false);
+  }, false);
+}
 }  // namespace tidl
index 7ad6674..5dd1326 100644 (file)
@@ -31,6 +31,9 @@ class CppStubHeaderGen : public CppGeneratorBase {
 
   void OnInitGen(std::ofstream& stream) override;
   void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+  void GenNamespace(std::ofstream& stream);
 };
 
 }  // namespace tidl