summaryrefslogtreecommitdiff
path: root/idlc/gen/cs_gen_base.cc
diff options
context:
space:
mode:
Diffstat (limited to 'idlc/gen/cs_gen_base.cc')
-rw-r--r--idlc/gen/cs_gen_base.cc507
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