*/
#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, ¶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