diff options
Diffstat (limited to 'idlc/gen/cs_gen_base.cc')
-rw-r--r-- | idlc/gen/cs_gen_base.cc | 507 |
1 files changed, 507 insertions, 0 deletions
diff --git a/idlc/gen/cs_gen_base.cc b/idlc/gen/cs_gen_base.cc new file mode 100644 index 0000000..bb1e5bb --- /dev/null +++ b/idlc/gen/cs_gen_base.cc @@ -0,0 +1,507 @@ +/* + * Copyright (c) 2017 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 <ctime> +#include <vector> + +#include "idlc/gen/cs_gen_base.h" + +namespace { +#include "idlc/gen/cs_cb_version.h" +#include "idlc/gen/cs_gen_base_cb.h" +#include "idlc/gen/cs_cb_rpc_port.h" +} + +namespace tidl { + +CsGeneratorBase::CsGeneratorBase(std::shared_ptr<Document> doc) + : Generator(doc) { + type_map_ = { + {"char", "byte"}, {"int", "int"}, {"short", "short"}, + {"long", "long"}, {"string", "string"}, {"bool", "bool"}, + {"list", "LinkedList"}, {"array", "List"}, {"float", "float"}, + {"double", "double"}, {"bundle", "Bundle"}, {"void", "void"} + }; + + parcel_type_map_ = { + {"char", "Byte"}, + {"int", "Int"}, + {"short", "Short"}, + {"long", "Long"}, + {"string", "String"}, + {"bool", "Bool"}, + {"float", "Float"}, + {"double", "Double"}, + {"bundle", "Bundle"}, + }; +} + +void CsGeneratorBase::GenStructures(std::ofstream& stream) { + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() != Block::TYPE_STRUCTURE) + continue; + Structure& st = static_cast<Structure&>(*i); + GenStructure(stream, st); + stream << std::endl; + } +} + +void CsGeneratorBase::GenStructure(std::ofstream& stream, const Structure& st) { + std::vector<std::string> v; + + stream << Tab(1) <<"public sealed class " << st.GetID() << NLine(1); + GenBrace(stream, TAB_SIZE, [&]() { + for (auto& i : st.GetElements().GetElms()) { + GenTemplate(CB_PROPERTY, stream, + [&]()->std::string { + return ConvertTypeToString(i->GetType()); + }, + [&]()->std::string { + return i->GetID(); + }); + if (i->GetType().ToString() == "bundle") { + v.push_back(i->GetID() + " = " + "new Bundle()"); + } + } + + GenTemplate(CB_CTOR, stream, + [&]()->std::string { + return st.GetID(); + }, + [&]()->std::string { + std::string str; + for (auto& i : v) { + str += " " + i + ";\n"; + } + return str; + }); + }); +} + +void CsGeneratorBase::GenSerializer(std::ofstream& stream, + const Structure& st) { + stream << NLine(1) << Tab(3) << "private static void Serialize(Parcel h, " + << st.GetID() << " param)" << NLine(1); + GenBrace(stream, TAB_SIZE * 3, [&]() { + for (auto& i : st.GetElements().GetElms()) { + auto& t = i->GetType(); + if (!t.IsUserDefinedType() && t.GetMetaType() == nullptr) { + stream << Tab(4) << "h.Write" + << ConvertTypeToParcelType(t.ToString()) + << "(param." + << i->GetID() + << ");" << NLine(1); + } else { + stream << Tab(4) << "Serialize(h, param." << i->GetID() + << ");" << NLine(1); + } + } + }); + stream << NLine(1); + + stream << Tab(3) << "private static void Deserialize(Parcel h, " + << st.GetID() << " param)" << NLine(1); + GenBrace(stream, TAB_SIZE * 3, [&]() { + for (auto& i : st.GetElements().GetElms()) { + auto& t = i->GetType(); + if (!t.IsUserDefinedType() && t.GetMetaType() == nullptr) { + stream << Tab(4) << "var " << i->GetID() << " = " + << "h.Read" + << ConvertTypeToParcelType(t.ToString()) + << "();" << NLine(1); + stream << Tab(4) << "param." << i->GetID() << " = " << i->GetID() + << ";" << NLine(1); + } else { + stream << Tab(4) << "param." << i->GetID() << " = new " + << ConvertTypeToString(t) + << "();" << NLine(1); + stream << Tab(4) << "Deserialize(h, param." << i->GetID() + << ");" << NLine(1); + } + } + }); +} + +void CsGeneratorBase::GenSerializer(std::ofstream& stream) { + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() == Block::TYPE_STRUCTURE) { + const Structure& st = static_cast<const Structure&>(*i); + GenSerializer(stream, st); + } + } +} + +void CsGeneratorBase::AddSerializerList(const BaseType& type) { + if (type.GetMetaType() != nullptr) { + serializer_list_[ConvertTypeToString(type)] = &type; + AddSerializerList(*type.GetMetaType()); + } +} + +void CsGeneratorBase::GenListSerializer(std::ofstream& stream, + const BaseType& type) { + stream << NLine(1) << Tab(3) << "private static void Serialize(Parcel h, " + << ConvertTypeToString(type) << " param)" << NLine(1); + GenBrace(stream, TAB_SIZE * 3, [&]() { + stream << Tab(4) + << "h.WriteArrayCount(param.Count);" + << NLine(1); + stream << Tab(4) << "foreach (var i in param)" << NLine(1); + GenBrace(stream, TAB_SIZE * 4, [&]() { + auto& mt = *type.GetMetaType(); + if (!mt.IsUserDefinedType() && mt.GetMetaType() == nullptr) { + stream << Tab(5) << "h.Write" + << ConvertTypeToParcelType(mt.ToString()) + << "(i);" << NLine(1); + } else { + stream << Tab(5) << "Serialize(h, i);" << NLine(1); + } + }); + }); + stream << NLine(1); + + stream << Tab(3) << "private static void Deserialize(Parcel h, " + << ConvertTypeToString(type) << " param)" << NLine(1); + GenBrace(stream, TAB_SIZE * 3, [&]() { + stream << Tab(4) + << "int l = h.ReadArrayCount();" + << NLine(1); + stream << Tab(4) << "for (int i = 0; i < l; i++)" << NLine(1); + GenBrace(stream, TAB_SIZE * 4, [&]() { + auto& mt = *type.GetMetaType(); + if (!mt.IsUserDefinedType() && mt.GetMetaType() == nullptr) { + stream << Tab(5) << "var v = h.Read" + << ConvertTypeToParcelType(mt.ToString()) + << "();" << NLine(1); + } else { + stream << Tab(5) << "var v = new " << ConvertTypeToString(mt) + << "();" << NLine(1); + stream << Tab(5) << "Deserialize(h, v);" << NLine(1); + } + if (type.ToString() == "list") + stream << Tab(5) << "param.AddLast(v);" << NLine(1); + else + stream << Tab(5) << "param.Add(v);" << NLine(1); + }); + }); +} + +void CsGeneratorBase::GenListSerializer(std::ofstream& stream) { + serializer_list_.clear(); + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() == Block::TYPE_STRUCTURE) { + const Structure& st = static_cast<const Structure&>(*i); + for (auto& j : st.GetElements().GetElms()) { + auto& t = j->GetType(); + AddSerializerList(t); + } + } else if (i->GetType() == Block::TYPE_INTERFACE) { + const Interface& iface = static_cast<const Interface&>(*i); + for (auto& j : iface.GetDeclarations().GetDecls()) { + auto& t = j->GetType(); + AddSerializerList(t); + for (auto& k : j->GetParameters().GetParams()) { + auto& t1 = k->GetParameterType().GetBaseType(); + AddSerializerList(t1); + } + } + } + } + + for (auto& p : serializer_list_) { + const BaseType* t = p.second; + GenListSerializer(stream, *t); + } +} + +std::string CsGeneratorBase::ConvertTypeToString(const BaseType& type) { + if (type.IsUserDefinedType()) + return type.ToString(); + + if (type.GetMetaType() != nullptr) + return type_map_[type.ToString()] + "<" + + ConvertTypeToString(*(type.GetMetaType())) + ">"; + + return type_map_[type.ToString()]; +} + +std::string CsGeneratorBase::ConvertTypeToParcelType(const std::string& key) { + return parcel_type_map_[key]; +} + +std::string CsGeneratorBase::ConvertTypeToDeserializer( + const BaseType& type, std::string id, std::string parcel, + bool make_new_type, std::string iface_id) { + if (type.IsUserDefinedType() || + type.GetMetaType() != nullptr) { + std::string n; + + if (type.GetMetaType() != nullptr) + n = ConvertTypeToString(type); + else + n = type.ToString(); + + std::string ret; + + if (make_new_type) + ret = n + " "; + + if (IsDelegateType(type)) { + ret += id + " = new " + n + + "(GetPort(Port.Type.Callback, instance), new WeakReference(b));\n"; + ret += "CallbackBase."; + } else { + ret += id + " = new " + n +"();\n"; + } + if (iface_id != "") + ret += iface_id + "."; + ret += "Deserialize(" + parcel + ", " + id +");\n"; + return ret; + } + + std::string ret; + if (make_new_type) { + ret = ConvertTypeToString(type) + " " + + id + " = " + parcel + ".Read" + + parcel_type_map_[type.ToString()] + + "();\n"; + } else { + ret = id + " = " + parcel + ".Read" + + parcel_type_map_[type.ToString()] + + "();\n"; + } + + return ret; +} + +std::string CsGeneratorBase::ConvertTypeToSerializer( + const BaseType& type, std::string id, std::string parcel, + std::string iface_id) { + std::string ret; + + if (type.IsUserDefinedType() || + type.GetMetaType() != nullptr) { + if (IsDelegateType(type)) + return "CallbackBase.Serialize(" + parcel + ", " + id + ");\n"; + if (iface_id != "") + ret += iface_id + "."; + ret += "Serialize(" + parcel + ", " + id + ");\n"; + return ret; + } + + ret += parcel + ".Write" + + parcel_type_map_[type.ToString()] + "(" + id + ");\n"; + + return ret; +} + +std::string CsGeneratorBase::Tab(int cnt) { + std::string t; + + for (int i = 0; i < cnt; i++) { + t += " "; + } + + return t; +} + +std::string CsGeneratorBase::NLine(int cnt) { + std::string t; + + for (int i = 0; i < cnt; i++) { + t += "\n"; + } + + return t; +} + +void CsGeneratorBase::GenWriteBundle(std::ofstream& stream, + const std::string& id) { + GenTemplate(CB_WRITE_BUNDLE, stream, + [&]()->std::string { + return id; + }, + [&]()->std::string { + return id; + }); +} + +void CsGeneratorBase::GenMethodId(std::ofstream& stream, + const Interface& iface) { + 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); + for (auto& i : iface.GetDeclarations().GetDecls()) { + if (i->GetMethodType() == Declaration::MethodType::DELEGATE) + continue; + stream << Tab(4) + << i->GetID() << " = " << cnt++ << "," << NLine(1); + } + }); +} + +void CsGeneratorBase::GenDelegateId(std::ofstream& stream, + const Interface& iface) { + stream << Tab(3) << "private enum DelegateId : int" << NLine(1); + GenBrace(stream, TAB_SIZE * 3, [&]() { + int cnt = 1; + for (auto& i : iface.GetDeclarations().GetDecls()) { + if (i->GetMethodType() != Declaration::MethodType::DELEGATE) + continue; + stream << Tab(4) + << i->GetID() << " = " << cnt++ << "," << NLine(1); + } + }); + stream << NLine(1); +} + +void CsGeneratorBase::GenDeclaration(std::ofstream& stream, + const Declaration& decl, bool semicol) { + stream << ConvertTypeToString(decl.GetType()) << " " + << decl.GetID() << "("; + GenParameters(stream, decl.GetParameters()); + if (semicol) + stream << ");"; + else + stream << ")"; +} + +void CsGeneratorBase::GenParameters(std::ofstream& stream, + const Parameters& ps) { + stream << GetParameters(ps); +} + +std::string CsGeneratorBase::GetParameters(const Parameters& ps) { + bool first = true; + std::string ret; + for (auto& i : ps.GetParams()) { + if (!first) { + ret += ", "; + } + + auto dir = i->GetParameterType().GetDirection(); + if (dir == ParameterType::Direction::OUT) { + ret += "out "; + } else if (dir == ParameterType::Direction::REF) { + ret += "ref "; + } + + ret += ConvertTypeToString(i->GetParameterType().GetBaseType()) + + " " + i->GetID(); + first = false; + } + + return ret; +} + +void CsGeneratorBase::GenCallbacks(std::ofstream& stream, + const Interface& iface, bool is_proxy) { + stream << CB_CALLBACK_BASE; + + for (auto& i : iface.GetDeclarations().GetDecls()) { + if (i->GetMethodType() != Declaration::MethodType::DELEGATE) + continue; + GenCallback(stream, *i, iface.GetID(), is_proxy); + } +} + +void CsGeneratorBase::GenCallback(std::ofstream& stream, + const Declaration& decl, + const std::string& id, bool is_proxy) { + stream << Tab(3) << "public sealed class " << decl.GetID() + << " : CallbackBase" << NLine(1); + GenBrace(stream, TAB_SIZE * 3, [&]() { + GenTemplate( + is_proxy ? CB_CALLBACK_CTOR_PROXY : CB_CALLBACK_CTOR_STUB, stream, + [&]()->std::string { + return decl.GetID(); + }, + [&]()->std::string { + return decl.GetID(); + }); + stream << NLine(1); + + if (is_proxy) { + stream << Tab(4) << "public delegate void Callback("; + GenParameters(stream, decl.GetParameters()); + stream << ");" << NLine(1); + stream << Tab(4) << "public event Callback Received;" << NLine(2); + GenReceivedEvent(stream, decl, id); + } else { + stream << CB_CALLBACK_STUB_MEMBERS; + GenInvokeMethod(stream, decl, id); + } + }); + stream << NLine(1); +} + +void CsGeneratorBase::GenReceivedEvent(std::ofstream& stream, + const Declaration& decl, + const std::string& id) { + stream << Tab(4) << "internal override void OnReceivedEvent(Parcel parcel)" + << NLine(1); + GenBrace(stream, TAB_SIZE * 4, [&]() { + int cnt = 1; + for (auto& i : decl.GetParameters().GetParams()) { + std::string v = "param" + std::to_string(cnt); + std::string c = ConvertTypeToDeserializer( + i->GetParameterType().GetBaseType(), v, "parcel", true, id); + stream << AddIndent(TAB_SIZE * 5, c); + cnt++; + } + + cnt = 1; + stream << Tab(5) << "Received?.Invoke("; + for (int i = 0; i < decl.GetParameters().GetParams().size(); i++) { + if (cnt != 1) { + stream << ", "; + } + std::string v = "param" + std::to_string(cnt); + stream << v; + cnt++; + } + stream << ");" << NLine(1); + }); + stream << NLine(1); +} + +void CsGeneratorBase::GenInvokeMethod(std::ofstream& stream, + const Declaration& decl, + const std::string& id) { + GenTemplate(CB_CALLBACK_INVOKE_METHOD, stream, + [&]()->std::string { + return GetParameters(decl.GetParameters()); + }, + [&]()->std::string { + std::string m; + for (auto& i : decl.GetParameters().GetParams()) { + auto& pt = i->GetParameterType(); + m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p", id); + } + return AddIndent(TAB_SIZE * 6, m); + }); +} + +void CsGeneratorBase::GenVersion(std::ofstream& stream) { + GenTemplate(::cs_cb_version, stream, + [&]()->std::string { + return FULLVER; + }); + stream << NLine(1); +} +} // namespace tidl |