From ca84640de2ca4cc4c1a1950da5db6bf1fff0bb4d Mon Sep 17 00:00:00 2001 From: Inkyun Kil Date: Thu, 1 Feb 2018 19:44:53 +0900 Subject: [PATCH] Implement C++ Generator (Structure Part) Change-Id: Iad229d72ffe5f672e35e0e12c626f3f48ea851cd Signed-off-by: Inkyun Kil --- idlc/cpp_gen/cpp_gen_base.cc | 368 ++++++++++++++++++++++++++++++++++- idlc/cpp_gen/cpp_gen_base.h | 20 ++ idlc/cpp_gen/cpp_proxy_body_gen.cc | 27 +++ idlc/cpp_gen/cpp_proxy_body_gen.h | 5 + idlc/cpp_gen/cpp_proxy_header_gen.cc | 21 ++ idlc/cpp_gen/cpp_proxy_header_gen.h | 3 + idlc/cpp_gen/cpp_stub_body_gen.cc | 22 +++ idlc/cpp_gen/cpp_stub_body_gen.h | 3 + idlc/cpp_gen/cpp_stub_header_gen.cc | 23 ++- idlc/cpp_gen/cpp_stub_header_gen.h | 3 + 10 files changed, 493 insertions(+), 2 deletions(-) diff --git a/idlc/cpp_gen/cpp_gen_base.cc b/idlc/cpp_gen/cpp_gen_base.cc index 887c523..611f897 100644 --- a/idlc/cpp_gen/cpp_gen_base.cc +++ b/idlc/cpp_gen/cpp_gen_base.cc @@ -15,12 +15,378 @@ */ #include +#include #include "idlc/cpp_gen/cpp_gen_base.h" namespace tidl { CppGeneratorBase::CppGeneratorBase(std::shared_ptr 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(*i); + GenStructureForHeader(stream, st); + stream << std::endl; + } +} + +void CppGeneratorBase::GenStructureForHeader(std::ofstream& stream, const Structure& st) { + std::vector p; + std::vector v; + std::vector 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(*i); + GenStructureForBody(stream, st); + stream << std::endl; + } +} + +void CppGeneratorBase::GenStructureForBody(std::ofstream& stream, const Structure& st) { + std::vector> v; + const char ctor[] = " $$::$$() {}\n" \ + " $$::$$($$)\n" \ + " : $$ {}"; + const char dtor[] = " $$::~$$() $$"; + + for (auto& i : st.GetElements().GetElms()) { + if (i->GetType().GetMetaType() == nullptr) { + std::pair 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(*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(*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, ¶m." << 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 diff --git a/idlc/cpp_gen/cpp_gen_base.h b/idlc/cpp_gen/cpp_gen_base.h index fa92ddf..1b77539 100644 --- a/idlc/cpp_gen/cpp_gen_base.h +++ b/idlc/cpp_gen/cpp_gen_base.h @@ -31,6 +31,26 @@ class CppGeneratorBase : public Generator { public: explicit CppGeneratorBase(std::shared_ptr 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 type_map_; + std::map parcel_type_map_; }; } // namespace tidl diff --git a/idlc/cpp_gen/cpp_proxy_body_gen.cc b/idlc/cpp_gen/cpp_proxy_body_gen.cc index 4472a76..84dd56d 100644 --- a/idlc/cpp_gen/cpp_proxy_body_gen.cc +++ b/idlc/cpp_gen/cpp_proxy_body_gen.cc @@ -22,9 +22,36 @@ CppProxyBodyGen::CppProxyBodyGen(std::shared_ptr doc) : CppGeneratorBase(doc) {} void CppProxyBodyGen::OnInitGen(std::ofstream& stream) { + stream << "#include " << NLine(1) + << "#include " << NLine(1) + << "#include " << NLine(1) + << "#include " << NLine(1) + << NLine(1) + << "#include " << NLine(1) + << "#include " << 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 diff --git a/idlc/cpp_gen/cpp_proxy_body_gen.h b/idlc/cpp_gen/cpp_proxy_body_gen.h index d02e035..eeacd33 100644 --- a/idlc/cpp_gen/cpp_proxy_body_gen.h +++ b/idlc/cpp_gen/cpp_proxy_body_gen.h @@ -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 diff --git a/idlc/cpp_gen/cpp_proxy_header_gen.cc b/idlc/cpp_gen/cpp_proxy_header_gen.cc index da27c03..a82be74 100644 --- a/idlc/cpp_gen/cpp_proxy_header_gen.cc +++ b/idlc/cpp_gen/cpp_proxy_header_gen.cc @@ -22,9 +22,30 @@ CppProxyHeaderGen::CppProxyHeaderGen(std::shared_ptr doc) : CppGeneratorBase(doc) {} void CppProxyHeaderGen::OnInitGen(std::ofstream& stream) { + stream << "#pragma once" << NLine(1) + << NLine(1) + << "#include " << NLine(1) + << "#include " << NLine(1) + << "#include " << NLine(1) + << NLine(1) + << "#include " << NLine(1) + << "#include " << 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 diff --git a/idlc/cpp_gen/cpp_proxy_header_gen.h b/idlc/cpp_gen/cpp_proxy_header_gen.h index 927cbcd..dc4b8df 100644 --- a/idlc/cpp_gen/cpp_proxy_header_gen.h +++ b/idlc/cpp_gen/cpp_proxy_header_gen.h @@ -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 diff --git a/idlc/cpp_gen/cpp_stub_body_gen.cc b/idlc/cpp_gen/cpp_stub_body_gen.cc index a2e89e3..8fd1a82 100644 --- a/idlc/cpp_gen/cpp_stub_body_gen.cc +++ b/idlc/cpp_gen/cpp_stub_body_gen.cc @@ -22,8 +22,30 @@ CppStubBodyGen::CppStubBodyGen(std::shared_ptr doc) : CppGeneratorBase(doc) {} void CppStubBodyGen::OnInitGen(std::ofstream& stream) { + stream << "#include " << NLine(1) + << "#include " << NLine(1) + << "#include " << NLine(1) + << "#include " << NLine(1) + << NLine(1) + << "#include " << NLine(1) + << "#include " << 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 diff --git a/idlc/cpp_gen/cpp_stub_body_gen.h b/idlc/cpp_gen/cpp_stub_body_gen.h index 5195efb..47a4944 100644 --- a/idlc/cpp_gen/cpp_stub_body_gen.h +++ b/idlc/cpp_gen/cpp_stub_body_gen.h @@ -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 diff --git a/idlc/cpp_gen/cpp_stub_header_gen.cc b/idlc/cpp_gen/cpp_stub_header_gen.cc index 47a8d1c..db1a4bf 100644 --- a/idlc/cpp_gen/cpp_stub_header_gen.cc +++ b/idlc/cpp_gen/cpp_stub_header_gen.cc @@ -22,8 +22,29 @@ CppStubHeaderGen::CppStubHeaderGen(std::shared_ptr doc) : CppGeneratorBase(doc) {} void CppStubHeaderGen::OnInitGen(std::ofstream& stream) { + stream << "#pragma once" << NLine(1) + << NLine(1) + << "#include " << NLine(1) + << "#include " << NLine(1) + << "#include " << NLine(1) + << NLine(1) + << "#include " << NLine(1) + << "#include " << 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 diff --git a/idlc/cpp_gen/cpp_stub_header_gen.h b/idlc/cpp_gen/cpp_stub_header_gen.h index 7ad6674..5dd1326 100644 --- a/idlc/cpp_gen/cpp_stub_header_gen.h +++ b/idlc/cpp_gen/cpp_stub_header_gen.h @@ -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 -- 2.7.4