From 6f2f0f4b8120ea4708a7e711570058ffc6caa1af Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Thu, 15 Mar 2018 21:56:41 +0900 Subject: [PATCH] Refactor C++ and C# generator - Add code block header files - Remove unused code - Improve readability - Fix a bug Change-Id: I8900f514c28ecad78c5a1b28f0ed87e6e0e800c8 Signed-off-by: Junghoon Park --- idlc/cpp_gen/cpp_gen_base.cc | 188 ++++++++++++----------------------- idlc/cpp_gen/cpp_gen_base.h | 1 + idlc/cpp_gen/cpp_gen_base_cb.h | 80 ++++++++++++++- idlc/cpp_gen/cpp_proxy_body_gen.cc | 45 ++------- idlc/cpp_gen/cpp_proxy_body_gen_cb.h | 47 ++++++++- idlc/cpp_gen/cpp_proxy_header_gen.cc | 2 +- idlc/cpp_gen/cpp_stub_body_gen.cc | 10 +- idlc/cpp_gen/cpp_stub_body_gen_cb.h | 3 +- idlc/cpp_gen/cpp_stub_header_gen.cc | 2 +- idlc/cs_gen/cs_cb_copyright.h | 18 +++- idlc/cs_gen/cs_cb_interop.h | 18 +++- idlc/cs_gen/cs_cb_proxy_interop.h | 18 +++- idlc/cs_gen/cs_cb_stub_interop.h | 18 +++- idlc/cs_gen/cs_gen_base.cc | 171 ++++++++++--------------------- idlc/cs_gen/cs_gen_base.h | 6 +- idlc/cs_gen/cs_gen_base_cb.h | 109 ++++++++++++++++++++ idlc/cs_gen/cs_proxy_gen.cc | 171 +++---------------------------- idlc/cs_gen/cs_proxy_gen_cb.h | 171 +++++++++++++++++++++++++++++++ idlc/cs_gen/cs_stub_gen.cc | 181 +++------------------------------ idlc/cs_gen/cs_stub_gen_cb.h | 182 +++++++++++++++++++++++++++++++++ 20 files changed, 815 insertions(+), 626 deletions(-) create mode 100644 idlc/cs_gen/cs_gen_base_cb.h create mode 100644 idlc/cs_gen/cs_proxy_gen_cb.h create mode 100644 idlc/cs_gen/cs_stub_gen_cb.h diff --git a/idlc/cpp_gen/cpp_gen_base.cc b/idlc/cpp_gen/cpp_gen_base.cc index 0336cd4..5af8eb8 100644 --- a/idlc/cpp_gen/cpp_gen_base.cc +++ b/idlc/cpp_gen/cpp_gen_base.cc @@ -398,7 +398,6 @@ void CppGeneratorBase::GenListSerializer(std::ofstream& stream, }, false); stream << Tab(1) << "return h;" << NLine(1); }, false); - stream << NLine(1); } void CppGeneratorBase::GenListSerializer(std::ofstream& stream, bool proto) { @@ -434,8 +433,8 @@ void CppGeneratorBase::GenMethodId(std::ofstream& stream, stream << Tab(1) << "enum class MethodId : int "; GenBrace(stream, TAB_SIZE, [&]() { int cnt = 2; - stream << Tab(2) << "Result = 0," << NLine(1); - stream << Tab(2) << "Callback = 1," << NLine(1); + stream << Tab(2) << "__Result = 0," << NLine(1); + stream << Tab(2) << "__Callback = 1," << NLine(1); for (auto& i : iface.GetDeclarations().GetDecls()) { if (i->GetMethodType() == Declaration::MethodType::DELEGATE) continue; @@ -463,10 +462,15 @@ void CppGeneratorBase::GenDelegateId(std::ofstream& stream, void CppGeneratorBase::GenParameters(std::ofstream& stream, const Parameters& ps) { + stream << GetParameters(ps); +} + +std::string CppGeneratorBase::GetParameters(const Parameters& ps) { bool first = true; + std::string ret; for (auto& i : ps.GetParams()) { if (!first) { - stream << ", "; + ret += ", "; } std::string ref; @@ -476,10 +480,12 @@ void CppGeneratorBase::GenParameters(std::ofstream& stream, ref = "&"; } - stream << ConvertTypeToString(i->GetParameterType().GetBaseType()) - << ref << " " << i->GetID(); + ret += ConvertTypeToString(i->GetParameterType().GetBaseType()) + + ref + " " + i->GetID(); first = false; } + + return ret; } void CppGeneratorBase::GenDeclaration(std::ofstream& stream, @@ -574,30 +580,17 @@ std::string CppGeneratorBase::ConvertTypeToDeserializer( void CppGeneratorBase::GenBodyCallbacks(std::ofstream& stream, const Interface& iface, bool is_proxy) { GenTemplate(CB_CALLBACK_BASE, stream, - [&]()->std::string { - return iface.GetID(); - }, - [&]()->std::string { - return iface.GetID(); - }, - [&]()->std::string { - return iface.GetID(); - }, - [&]()->std::string { - return iface.GetID(); - }, - [&]()->std::string { - return iface.GetID(); - }, - [&]()->std::string { - return iface.GetID(); - } + [&]()->std::string { return iface.GetID(); }, + [&]()->std::string { return iface.GetID(); }, + [&]()->std::string { return iface.GetID(); }, + [&]()->std::string { return iface.GetID(); }, + [&]()->std::string { return iface.GetID(); }, + [&]()->std::string { return iface.GetID(); } ); for (auto& i : iface.GetDeclarations().GetDecls()) { if (i->GetMethodType() != Declaration::MethodType::DELEGATE) continue; - stream << NLine(1); GenBodyCallback(stream, iface, *i, is_proxy); } } @@ -605,110 +598,71 @@ void CppGeneratorBase::GenBodyCallbacks(std::ofstream& stream, void CppGeneratorBase::GenBodyCallback(std::ofstream& stream, const Interface& iface, const Declaration& decl, bool is_proxy) { if (!is_proxy) { - const char method[] = "void $$::$$::Invoke("; - - - GenTemplate(method, stream, + GenTemplate(CB_CALLBACK_INVOKE_METHOD, stream, [&]()->std::string { return iface.GetID(); }, [&]()->std::string { return decl.GetID(); + }, + [&]()->std::string { + return GetParameters(decl.GetParameters()); + }, + [&]()->std::string { + std::string m; + for (auto& i : decl.GetParameters().GetParams()) { + auto& pt = i->GetParameterType(); + m += AddIndent(TAB_SIZE, + ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p")); + } + return m; } ); - GenParameters(stream, decl.GetParameters()); - stream << ") "; - GenBrace(stream, 0, [&]() { - const char* pre = - "if (port_ == nullptr)\n" \ - " throw NotConnectedSocketException();\n" \ - "if (service_.lock().get() == nullptr)\n" \ - " throw NotConnectedSocketException();\n" \ - "\n" \ - "rpc_port_parcel_h p;\n" \ - "rpc_port_parcel_create(&p);\n" \ - "rpc_port_parcel_write_int32(p, static_cast(MethodId::Callback));\n" \ - "p << *this;\n"; - - const char* mid = - "// Send\n" \ - "rpc_port_parcel_send(p, port_);\n" \ - "rpc_port_parcel_destroy(p);\n"; - - stream << AddIndent(TAB_SIZE, pre); - std::string m; - for (auto& i : decl.GetParameters().GetParams()) { - auto& pt = i->GetParameterType(); - m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p"); - } - - stream << AddIndent(TAB_SIZE, m) << NLine(1); - stream << AddIndent(TAB_SIZE, mid); - }, false); } else { - const char cb[] = "void $$::$$::OnReceivedEvent(rpc_port_parcel_h parcel) "; - - GenTemplate(cb, stream, + GenTemplate(CB_CALLBACK_ON_RECEIVED_EVENT_METHOD, stream, [&]()->std::string { return iface.GetID(); }, [&]()->std::string { return decl.GetID(); - } - ); - GenBrace(stream, 0, [&]() { - 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"); - stream << AddIndent(TAB_SIZE, c) << NLine(1); - cnt++; - } + }, + [&]()->std::string { + int cnt = 1; + std::string ret; + for (auto& i : decl.GetParameters().GetParams()) { + std::string v = "param" + std::to_string(cnt); + std::string c = ConvertTypeToDeserializer( + i->GetParameterType().GetBaseType(), v, "parcel"); + ret += AddIndent(TAB_SIZE, c) + NLine(1); + cnt++; + } - cnt = 1; - stream << Tab(1) << "OnReceived("; - for (int i = 0; i < decl.GetParameters().GetParams().size(); i++) { - if (cnt != 1) { - stream << ", "; + cnt = 1; + ret += Tab(1) + "OnReceived("; + for (int i = 0; i < decl.GetParameters().GetParams().size(); i++) { + if (cnt != 1) { + ret += ", "; + } + ret += "std::move(param" + std::to_string(cnt) + ")"; + cnt++; } - stream << "std::move(param" << std::to_string(cnt) << ")"; - cnt++; + ret += ");"; + + return ret; } - stream << ");" << NLine(1); - }, false); + ); } } void CppGeneratorBase::GenHeaderCallbacks(std::ofstream& stream, const Interface& iface, bool is_proxy) { - const char block1[] = - "class CallbackBase {\n" \ - " public:\n" \ - " CallbackBase(int delegate_id);\n" \ - " virtual ~CallbackBase() = default;\n" \ - "\n"; - - const char block2[] = - " int GetId() const;\n" \ - " int GetSeqId() const;\n" \ - "\n" \ - " private:\n" \ - " friend rpc_port_parcel_h operator << (rpc_port_parcel_h h, const CallbackBase& cb);\n" \ - " friend rpc_port_parcel_h operator >> (rpc_port_parcel_h h, CallbackBase& cb);\n" \ - "\n" \ - " static int seq_num_;\n" \ - " int id_;\n" \ - " int seq_id_;\n" \ - "};\n"; - - stream << AddIndent(TAB_SIZE, block1) << NLine(1); + stream << CB_CALLBACK_BASE_HEADER_FRONT; if (is_proxy) { stream << Tab(1) << " virtual void OnReceivedEvent(rpc_port_parcel_h port) = 0;" << NLine(1); } - stream << AddIndent(TAB_SIZE, block2) << NLine(1); + stream << CB_CALLBACK_BASE_HEADER_BACK << NLine(1); for (auto& i : iface.GetDeclarations().GetDecls()) { if (i->GetMethodType() != Declaration::MethodType::DELEGATE) @@ -723,19 +677,9 @@ void CppGeneratorBase::GenHeaderCallback(std::ofstream& stream, stream << Tab(1) << "class " << decl.GetID() << " : public CallbackBase "; GenBrace(stream, TAB_SIZE, [&]() { - const char ctor1[] = - "$$(rpc_port_parcel_h port, std::weak_ptr service)\n" \ - " : CallbackBase(static_cast(DelegateId::$$)) {\n" \ - " port_ = port;\n" \ - " service_ = std::move(service);\n" \ - "}\n"; - const char ctor2[] = - "$$()\n" \ - " : CallbackBase(static_cast(DelegateId::$$)) {}\n"; - - stream << Tab(1) << " public:" << NLine(1); + stream << Tab(1) << " public:"; if (!is_proxy) { - GenTemplate(AddIndent(TAB_SIZE * 2, ctor1), stream, + GenTemplate(CB_CALLBACK_CTOR_STUB, stream, [&]()->std::string { return decl.GetID(); }, @@ -744,7 +688,7 @@ void CppGeneratorBase::GenHeaderCallback(std::ofstream& stream, } ); } else { - GenTemplate(AddIndent(TAB_SIZE * 2, ctor2), stream, + GenTemplate(CB_CALLBACK_CTOR_PROXY, stream, [&]()->std::string { return decl.GetID(); }, @@ -764,14 +708,12 @@ void CppGeneratorBase::GenHeaderCallback(std::ofstream& stream, stream << ");" << NLine(2); } - stream << Tab(1) << " private:" << NLine(1); - if (is_proxy) { - stream << Tab(2) << "void OnReceivedEvent(rpc_port_parcel_h port) override;" - << NLine(1); + stream << Tab(1) << " private:"; + if (!is_proxy) { + stream << CB_CALLBACK_PRIVATE_STUB; + } else { + stream << CB_CALLBACK_PRIVATE_PROXY; } - stream << Tab(2) << "rpc_port_parcel_h port_;" << NLine(1); - if (!is_proxy) - stream << Tab(2) << "std::weak_ptr service_;" << NLine(1); }, false, false); stream << ";" << NLine(2); } diff --git a/idlc/cpp_gen/cpp_gen_base.h b/idlc/cpp_gen/cpp_gen_base.h index 0106d3a..6b93ec4 100644 --- a/idlc/cpp_gen/cpp_gen_base.h +++ b/idlc/cpp_gen/cpp_gen_base.h @@ -57,6 +57,7 @@ class CppGeneratorBase : public Generator { bool make_new_type = true); std::string ConvertTypeToSerializer(const BaseType& type, std::string id, std::string parcel); + std::string GetParameters(const Parameters& ps); private: void GenSetter(std::ofstream& stream, const Element& ele); diff --git a/idlc/cpp_gen/cpp_gen_base_cb.h b/idlc/cpp_gen/cpp_gen_base_cb.h index 4b42319..e9a9818 100644 --- a/idlc/cpp_gen/cpp_gen_base_cb.h +++ b/idlc/cpp_gen/cpp_gen_base_cb.h @@ -86,11 +86,10 @@ rpc_port_parcel_h operator >> (rpc_port_parcel_h h, $$::CallbackBase& cb) { return h; } - )__cpp_cb"; const char CB_COPYRIGHT[] = -R"__cs_cb(/* +R"__cpp_cb(/* * Generated by tidlc $$. * * Copyright (c) $$ Samsung Electronics Co., Ltd. @@ -107,4 +106,79 @@ R"__cs_cb(/* * See the License for the specific language governing permissions and * limitations under the License. */ -)__cs_cb"; +)__cpp_cb"; + +const char CB_CALLBACK_BASE_HEADER_FRONT[] = +R"__cpp_cb( + class CallbackBase { + public: + CallbackBase(int delegate_id); + virtual ~CallbackBase() = default; +)__cpp_cb"; + +const char CB_CALLBACK_BASE_HEADER_BACK[] = +R"__cpp_cb( + int GetId() const; + int GetSeqId() const; + + private: + friend rpc_port_parcel_h operator << (rpc_port_parcel_h h, const CallbackBase& cb); + friend rpc_port_parcel_h operator >> (rpc_port_parcel_h h, CallbackBase& cb); + + static int seq_num_; + int id_; + int seq_id_; + }; +)__cpp_cb"; + +const char CB_CALLBACK_CTOR_STUB[] = +R"__cpp_cb( + $$(rpc_port_parcel_h port, std::weak_ptr service) + : CallbackBase(static_cast(DelegateId::$$)) { + port_ = port; + service_ = std::move(service); + } +)__cpp_cb"; + +const char CB_CALLBACK_CTOR_PROXY[] = +R"__cpp_cb( + $$() + : CallbackBase(static_cast(DelegateId::$$)) {} +)__cpp_cb"; + +const char CB_CALLBACK_PRIVATE_PROXY[] = +R"__cpp_cb( + void OnReceivedEvent(rpc_port_parcel_h port) override; +)__cpp_cb"; + +const char CB_CALLBACK_PRIVATE_STUB[] = +R"__cpp_cb( + rpc_port_parcel_h port_; + std::weak_ptr service_; +)__cpp_cb"; + +const char CB_CALLBACK_INVOKE_METHOD[] = +R"__cpp_cb( +void $$::$$::Invoke($$) { + if (port_ == nullptr) + throw NotConnectedSocketException(); + if (service_.lock().get() == nullptr) + throw NotConnectedSocketException(); + + rpc_port_parcel_h p; + rpc_port_parcel_create(&p); + rpc_port_parcel_write_int32(p, static_cast(MethodId::__Callback)); + p << *this; +$$ + // Send + rpc_port_parcel_send(p, port_); + rpc_port_parcel_destroy(p); +} +)__cpp_cb"; + +const char CB_CALLBACK_ON_RECEIVED_EVENT_METHOD[] = +R"__cpp_cb( +void $$::$$::OnReceivedEvent(rpc_port_parcel_h parcel) { +$$ +} +)__cpp_cb"; diff --git a/idlc/cpp_gen/cpp_proxy_body_gen.cc b/idlc/cpp_gen/cpp_proxy_body_gen.cc index 3974fca..07467f7 100644 --- a/idlc/cpp_gen/cpp_proxy_body_gen.cc +++ b/idlc/cpp_gen/cpp_proxy_body_gen.cc @@ -93,13 +93,7 @@ void CppProxyBodyGen::GenConstructor(std::ofstream& stream, void CppProxyBodyGen::GenDestructor(std::ofstream& stream, const Interface& iface) { - const char cb[] = - "$$::~$$() {\n" \ - " if (proxy_)\n" \ - " rpc_port_proxy_destroy(proxy_);\n" \ - "}\n"; - - GenTemplate(cb, stream, + GenTemplate(CB_DTOR, stream, [&]()->std::string { return iface.GetID(); }, @@ -111,7 +105,6 @@ void CppProxyBodyGen::GenDestructor(std::ofstream& stream, void CppProxyBodyGen::GenHelperMethods(std::ofstream& stream, const Interface& iface) { - GenTemplate(CB_PROXY_HELPER_METHODS, stream, [&]()->std::string { return iface.GetID(); }, [&]()->std::string { return iface.GetID(); }, @@ -150,18 +143,7 @@ void CppProxyBodyGen::GenMethods(std::ofstream& stream, } void CppProxyBodyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) { - const char* pre = - "if (port_ == nullptr)\n" \ - " throw NotConnectedSocketException();\n" \ - "\n" \ - "rpc_port_parcel_h p;\n" \ - "rpc_port_parcel_create(&p);\n"; - - const char* mid = - "// Send\n" \ - "rpc_port_parcel_send(p, port_);\n"; - - stream << AddIndent(TAB_SIZE, pre); + stream << CB_INVOCATION_PRE; // Serialize stream << Tab(1) @@ -174,8 +156,9 @@ void CppProxyBodyGen::GenInvocation(std::ofstream& stream, const Declaration& de if (pt.GetDirection() == ParameterType::Direction::OUT) continue; m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p"); - if (IsDelegateType(pt.GetBaseType().ToString())) + if (IsDelegateType(pt.GetBaseType().ToString())) { l += "delegate_list_.emplace_back(" + i->GetID() + ".release());\n"; + } } stream << AddIndent(TAB_SIZE, m) << NLine(1); @@ -186,15 +169,15 @@ void CppProxyBodyGen::GenInvocation(std::ofstream& stream, const Declaration& de stream << Tab(2) << "std::lock_guard lock(mutex_);" << NLine(2); if (!l.empty()) - stream << AddIndent(TAB_SIZE * 2, l) << NLine(1); - stream << AddIndent(TAB_SIZE * 2, mid) << NLine(1); + stream << AddIndent(TAB_SIZE * 2, l); + stream << CB_INVOCATION_MID << NLine(1); if (decl.GetMethodType() == Declaration::MethodType::SYNC) { stream << Tab(2) << "// Receive" << NLine(1); stream << Tab(2) << "ConsumeCommand(&parcel_received, port_);" << NLine(1); } }, false, false); - stream << " while (false);" << NLine(2); + stream << " while (false);" << NLine(1); // Deserialize if (decl.GetMethodType() == Declaration::MethodType::ASYNC) { @@ -203,12 +186,7 @@ void CppProxyBodyGen::GenInvocation(std::ofstream& stream, const Declaration& de return; } - const char* receive_block = - "if (parcel_received == nullptr) {\n" \ - " throw InvalidProtocolException();\n" \ - "}\n"; - stream << AddIndent(TAB_SIZE, receive_block) << NLine(1); - + stream << CB_INVOCATION_RECEIVE << NLine(1); for (auto& i : decl.GetParameters().GetParams()) { if (i->GetParameterType().GetDirection() == ParameterType::Direction::IN) { continue; @@ -227,12 +205,7 @@ void CppProxyBodyGen::GenInvocation(std::ofstream& stream, const Declaration& de "ret", "parcel_received")); } - stream << Tab(1) << "rpc_port_parcel_destroy(p);" - << NLine(1); - stream << Tab(1) << "rpc_port_parcel_destroy(parcel_received);" - << NLine(1); - - stream << Tab(1) << "return ret;" << NLine(1); + stream << CB_INVOCATION_END; } } // namespace tidl diff --git a/idlc/cpp_gen/cpp_proxy_body_gen_cb.h b/idlc/cpp_gen/cpp_proxy_body_gen_cb.h index 4d80427..e19bdc6 100644 --- a/idlc/cpp_gen/cpp_proxy_body_gen_cb.h +++ b/idlc/cpp_gen/cpp_proxy_body_gen_cb.h @@ -14,6 +14,43 @@ * limitations under the License. */ +const char CB_DTOR[] = +R"__cpp_cb( +$$::~$$() { + if (proxy_) + rpc_port_proxy_destroy(proxy_); +} +)__cpp_cb"; + +const char CB_INVOCATION_PRE[] = +R"__cpp_cb( if (port_ == nullptr) + throw NotConnectedSocketException(); + + rpc_port_parcel_h p; + rpc_port_parcel_create(&p); +)__cpp_cb"; + +const char CB_INVOCATION_MID[] = +R"__cpp_cb( + // Send + rpc_port_parcel_send(p, port_); +)__cpp_cb"; + +const char CB_INVOCATION_RECEIVE[] = +R"__cpp_cb( + if (parcel_received == nullptr) { + throw InvalidProtocolException(); + } +)__cpp_cb"; + +const char CB_INVOCATION_END[] = +R"__cpp_cb( + rpc_port_parcel_destroy(p); + rpc_port_parcel_destroy(parcel_received); + + return ret; +)__cpp_cb"; + const char CB_PROXY_HELPER_METHODS[] = R"__cpp_cb( int $$::Connect() { @@ -22,13 +59,13 @@ int $$::Connect() { void $$::ProcessReceivedEvent(rpc_port_parcel_h parcel) { int id = 0; - int seqId = 0; + int seq_id = 0; rpc_port_parcel_read_int32(parcel, &id); - rpc_port_parcel_read_int32(parcel, &seqId); + rpc_port_parcel_read_int32(parcel, &seq_id); for (auto& i : delegate_list_) { - if (i->GetId() == id && i->GetSeqId() == seqId) { + if (i->GetId() == id && i->GetSeqId() == seq_id) { i->OnReceivedEvent(parcel); break; } @@ -44,7 +81,7 @@ void $$::ConsumeCommand(rpc_port_parcel_h* parcel, rpc_port_h port) { if (ret != 0) break; rpc_port_parcel_read_int32(p, &cmd); - if (cmd == static_cast(MethodId::Result)) { + if (cmd == static_cast(MethodId::__Result)) { *parcel = p; return; } @@ -84,7 +121,7 @@ void $$::OnReceivedCB(const char *ep, const char *port_name, void *data) { } while (false); rpc_port_parcel_read_int32(parcel_received, &cmd); - if (cmd != static_cast(MethodId::Callback)) { + if (cmd != static_cast(MethodId::__Callback)) { rpc_port_parcel_destroy(parcel_received); throw InvalidProtocolException(); } diff --git a/idlc/cpp_gen/cpp_proxy_header_gen.cc b/idlc/cpp_gen/cpp_proxy_header_gen.cc index 224cdbd..501ebd2 100644 --- a/idlc/cpp_gen/cpp_proxy_header_gen.cc +++ b/idlc/cpp_gen/cpp_proxy_header_gen.cc @@ -59,7 +59,7 @@ void CppProxyHeaderGen::GenNamespace(std::ofstream& stream) { } void CppProxyHeaderGen::GenExceptions(std::ofstream& stream) { - stream << CB_EXCEPTIONS << NLine(1); + stream << CB_EXCEPTIONS; } void CppProxyHeaderGen::GenInterfaces(std::ofstream& stream) { diff --git a/idlc/cpp_gen/cpp_stub_body_gen.cc b/idlc/cpp_gen/cpp_stub_body_gen.cc index 74187bb..ddbc6f7 100644 --- a/idlc/cpp_gen/cpp_stub_body_gen.cc +++ b/idlc/cpp_gen/cpp_stub_body_gen.cc @@ -120,7 +120,6 @@ void CppStubBodyGen::GenDefaultMethods(std::ofstream& stream, [&]()->std::string { return iface.GetID(); }, [&]()->std::string { return iface.GetID(); } ); - stream << NLine(1); } void CppStubBodyGen::GenReceivedEvent(std::ofstream& stream, @@ -166,6 +165,7 @@ void CppStubBodyGen::GenInvocation(std::ofstream& stream, const Declaration& dec // Invoke cnt = 1; std::string m; + std::string d; bool hasRet = false; if (decl.GetType().ToString() != "void") { @@ -181,9 +181,8 @@ void CppStubBodyGen::GenInvocation(std::ofstream& stream, const Declaration& dec std::string v = "param" + std::to_string(cnt); auto& pt = i->GetParameterType(); - if (pt.GetDirection() == ParameterType::Direction::OUT || - pt.GetDirection() == ParameterType::Direction::REF) { - m += ConvertTypeToString(pt.GetBaseType()) + "& "; + if (pt.GetDirection() == ParameterType::Direction::OUT) { + d += ConvertTypeToString(pt.GetBaseType()) + " " + v + ";\n"; } if (IsDelegateType(pt.GetBaseType().ToString())) { m += "std::move("; @@ -196,6 +195,7 @@ void CppStubBodyGen::GenInvocation(std::ofstream& stream, const Declaration& dec } m += ");\n"; + stream << AddIndent(TAB_SIZE * 3, d); stream << AddIndent(TAB_SIZE * 3, m); // Serialize @@ -203,7 +203,7 @@ void CppStubBodyGen::GenInvocation(std::ofstream& stream, const Declaration& dec return; cnt = 0; - m = "rpc_port_parcel_write_int32(result, static_cast(MethodId::Result));\n"; + m = "rpc_port_parcel_write_int32(result, static_cast(MethodId::__Result));\n"; for (auto& i : decl.GetParameters().GetParams()) { auto& pt = i->GetParameterType(); cnt++; diff --git a/idlc/cpp_gen/cpp_stub_body_gen_cb.h b/idlc/cpp_gen/cpp_stub_body_gen_cb.h index b921ed9..6476ae7 100644 --- a/idlc/cpp_gen/cpp_stub_body_gen_cb.h +++ b/idlc/cpp_gen/cpp_stub_body_gen_cb.h @@ -58,7 +58,8 @@ void $$::OnDisconnectedCB(const char* sender, const char* instance, void *data) )__cpp_cb"; const char CB_ON_RECEIVED_CB_FRONT[] = -R"__cpp_cb(int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void *data) +R"__cpp_cb( +int $$::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void *data) { auto* cxt = static_cast<$$*>(data); rpc_port_parcel_h p; diff --git a/idlc/cpp_gen/cpp_stub_header_gen.cc b/idlc/cpp_gen/cpp_stub_header_gen.cc index 4dba3b4..6b7cbfd 100644 --- a/idlc/cpp_gen/cpp_stub_header_gen.cc +++ b/idlc/cpp_gen/cpp_stub_header_gen.cc @@ -58,7 +58,7 @@ void CppStubHeaderGen::GenNamespace(std::ofstream& stream) { } void CppStubHeaderGen::GenExceptions(std::ofstream& stream) { - stream << CB_EXCEPTIONS << NLine(1); + stream << CB_EXCEPTIONS; } void CppStubHeaderGen::GenInterfaces(std::ofstream& stream) { diff --git a/idlc/cs_gen/cs_cb_copyright.h b/idlc/cs_gen/cs_cb_copyright.h index 2aae148..ece17d6 100644 --- a/idlc/cs_gen/cs_cb_copyright.h +++ b/idlc/cs_gen/cs_cb_copyright.h @@ -1,4 +1,19 @@ -namespace { +/* + * Copyright (c) 2018 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. + */ + const char cs_cb_copyright[] = R"__cs_cb(/* * Generated by tidlc $$. @@ -18,4 +33,3 @@ R"__cs_cb(/* * limitations under the License. */ )__cs_cb"; -} diff --git a/idlc/cs_gen/cs_cb_interop.h b/idlc/cs_gen/cs_cb_interop.h index 1fcb088..83b112d 100644 --- a/idlc/cs_gen/cs_cb_interop.h +++ b/idlc/cs_gen/cs_cb_interop.h @@ -1,4 +1,19 @@ -namespace { +/* + * Copyright (c) 2018 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. + */ + const char cs_cb_interop[] = R"__cs_cb( internal static partial class Interop @@ -112,5 +127,4 @@ $$ } } )__cs_cb"; -} diff --git a/idlc/cs_gen/cs_cb_proxy_interop.h b/idlc/cs_gen/cs_cb_proxy_interop.h index 42865d4..15261a6 100644 --- a/idlc/cs_gen/cs_cb_proxy_interop.h +++ b/idlc/cs_gen/cs_cb_proxy_interop.h @@ -1,4 +1,19 @@ -namespace { +/* + * Copyright (c) 2018 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. + */ + const char cs_cb_proxy_interop[] = R"__cs_cb( internal static partial class Proxy @@ -48,4 +63,3 @@ R"__cs_cb( internal static extern int AddReceivedEventCb(IntPtr handle, ReceivedEventCallback cb, IntPtr data); } )__cs_cb"; -} diff --git a/idlc/cs_gen/cs_cb_stub_interop.h b/idlc/cs_gen/cs_cb_stub_interop.h index 5d3dc98..c931c59 100644 --- a/idlc/cs_gen/cs_cb_stub_interop.h +++ b/idlc/cs_gen/cs_cb_stub_interop.h @@ -1,4 +1,19 @@ -namespace { +/* + * Copyright (c) 2018 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. + */ + const char cs_cb_stub_interop[] = R"__cs_cb( internal static partial class Stub @@ -44,4 +59,3 @@ R"__cs_cb( internal static extern int AddPrivilege(IntPtr handle, string privilege); } )__cs_cb"; -} diff --git a/idlc/cs_gen/cs_gen_base.cc b/idlc/cs_gen/cs_gen_base.cc index 2b5d9a3..d38d9fa 100644 --- a/idlc/cs_gen/cs_gen_base.cc +++ b/idlc/cs_gen/cs_gen_base.cc @@ -18,7 +18,11 @@ #include #include "idlc/cs_gen/cs_gen_base.h" + +namespace { #include "idlc/cs_gen/cs_cb_copyright.h" +#include "idlc/cs_gen/cs_gen_base_cb.h" +} namespace tidl { @@ -56,16 +60,11 @@ void CsGeneratorBase::GenStructures(std::ofstream& stream) { void CsGeneratorBase::GenStructure(std::ofstream& stream, const Structure& st) { std::vector v; - const char property[] = " public $$ $$ { get; set; }\n"; - const char ctor[] = " public $$()\n" \ - " {\n" \ - "$$" \ - " }\n"; stream << Tab(1) <<"public sealed class " << st.GetID() << NLine(1); GenBrace(stream, TAB_SIZE, [&]() { for (auto& i : st.GetElements().GetElms()) { - GenTemplate(property, stream, + GenTemplate(CB_PROPERTY, stream, [&]()->std::string { return ConvertTypeToString(i->GetType()); }, @@ -78,7 +77,7 @@ void CsGeneratorBase::GenStructure(std::ofstream& stream, const Structure& st) { } } - GenTemplate(ctor, stream, + GenTemplate(CB_CTOR, stream, [&]()->std::string { return st.GetID(); }, @@ -94,7 +93,7 @@ void CsGeneratorBase::GenStructure(std::ofstream& stream, const Structure& st) { } void CsGeneratorBase::GenSerializer(std::ofstream& stream, const Structure& st) { - stream << Tab(3) << "private static void Serialize(IntPtr h, " + stream << NLine(1) << Tab(3) << "private static void Serialize(IntPtr h, " << st.GetID() << " param)" << NLine(1); GenBrace(stream, TAB_SIZE * 3, [&]() { for (auto& i : st.GetElements().GetElms()) { @@ -146,7 +145,6 @@ void CsGeneratorBase::GenSerializer(std::ofstream& stream, const Structure& st) } }); - stream << NLine(1); } void CsGeneratorBase::GenSerializer(std::ofstream& stream) { @@ -166,7 +164,7 @@ void CsGeneratorBase::AddSerializerList(const BaseType& type) { } void CsGeneratorBase::GenListSerializer(std::ofstream& stream, const BaseType& type) { - stream << Tab(3) << "private static void Serialize(IntPtr h, " + stream << NLine(1) << Tab(3) << "private static void Serialize(IntPtr h, " << ConvertTypeToString(type) << " param)" << NLine(1); GenBrace(stream, TAB_SIZE * 3, [&]() { stream << Tab(4) @@ -210,7 +208,6 @@ void CsGeneratorBase::GenListSerializer(std::ofstream& stream, const BaseType& t stream << Tab(5) << "param.Add(v);" << NLine(1); }); }); - stream << NLine(1); } void CsGeneratorBase::GenListSerializer(std::ofstream& stream) { @@ -344,17 +341,7 @@ std::string CsGeneratorBase::NLine(int cnt) { } void CsGeneratorBase::GenWriteBundle(std::ofstream& stream, const std::string& id) { - const char block[] = - "if (param.$$ != null)\n" \ - "{\n" \ - " Interop.LibRPCPort.Parcel.WriteBundle(h, param.$$.SafeBundleHandle.DangerousGetHandle());\n" \ - "}\n" \ - "else\n" \ - "{\n" \ - " Interop.LibRPCPort.Parcel.WriteBundle(h, new Bundle().SafeBundleHandle.DangerousGetHandle());\n" \ - "}\n"; - - GenTemplate(AddIndent(TAB_SIZE * 4, block), stream, + GenTemplate(CB_WRITE_BUNDLE, stream, [&]()->std::string { return id; }, @@ -368,8 +355,8 @@ 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); + 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; @@ -377,7 +364,6 @@ void CsGeneratorBase::GenMethodId(std::ofstream& stream, const Interface& iface) << i->GetID() << " = " << cnt++ << "," << NLine(1); } }); - stream << NLine(1); } void CsGeneratorBase::GenDelegateId(std::ofstream& stream, const Interface& iface) { @@ -406,89 +392,51 @@ void CsGeneratorBase::GenDeclaration(std::ofstream& 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) { - stream << ", "; + ret += ", "; } auto dir = i->GetParameterType().GetDirection(); if (dir == ParameterType::Direction::OUT) { - stream << "out "; + ret += "out "; } else if (dir == ParameterType::Direction::REF) { - stream << "ref "; + ret += "ref "; } - stream << ConvertTypeToString(i->GetParameterType().GetBaseType()) << " " - << i->GetID(); + ret += ConvertTypeToString(i->GetParameterType().GetBaseType()) + + " " + i->GetID(); first = false; } + + return ret; } void CsGeneratorBase::GenCallbacks(std::ofstream& stream, - const Interface& iface) { - const char block[] = - "public abstract class CallbackBase\n" \ - "{\n" \ - " internal int Id;\n" \ - " internal int SeqId;\n" \ - " private static int _seqNum = 0;\n" \ - "\n" \ - " public CallbackBase(int delegateId)\n" \ - " {\n" \ - " Id = delegateId;\n" \ - " SeqId = _seqNum++;\n" \ - " }\n" \ - "\n" \ - " internal abstract void OnReceivedEvent(IntPtr port);\n" \ - "\n" \ - " internal static void Serialize(IntPtr h, CallbackBase param)\n" \ - " {\n" \ - " Interop.LibRPCPort.Parcel.WriteInt32(h, (int)param.Id);\n" \ - " Interop.LibRPCPort.Parcel.WriteInt32(h, (int)param.SeqId);\n" \ - " }\n" \ - "\n" \ - " internal static void Deserialize(IntPtr h, CallbackBase param)\n" \ - " {\n" \ - " Interop.LibRPCPort.Parcel.ReadInt32(h, out var id);\n" \ - " param.Id = id;\n" \ - " Interop.LibRPCPort.Parcel.ReadInt32(h, out var seqId);\n" \ - " param.SeqId = seqId;\n" \ - " }\n" \ - "}\n"; - stream << AddIndent(TAB_SIZE * 3, block) << NLine(1); + 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()); + GenCallback(stream, *i, iface.GetID(), is_proxy); } } void CsGeneratorBase::GenCallback(std::ofstream& stream, const Declaration& decl, - const std::string& id) { + const std::string& id, bool is_proxy) { stream << Tab(3) << "public sealed class " << decl.GetID() << " : CallbackBase" << NLine(1); GenBrace(stream, TAB_SIZE * 3, [&]() { - const char ctor[] = - "public $$() : base((int)DelegateId.$$)\n" \ - "{\n" \ - "}\n" \ - "\n" \ - "internal $$(IntPtr port, WeakReference service) : base((int)DelegateId.$$)\n" \ - "{\n" \ - " _port = port;\n" \ - " _service = service;\n" \ - "}\n"; - - GenTemplate(AddIndent(TAB_SIZE * 4, ctor), stream, - [&]()->std::string { - return decl.GetID(); - }, - [&]()->std::string { - return decl.GetID(); - }, + GenTemplate( + is_proxy ? CB_CALLBACK_CTOR_PROXY : CB_CALLBACK_CTOR_STUB, stream, [&]()->std::string { return decl.GetID(); }, @@ -498,15 +446,16 @@ void CsGeneratorBase::GenCallback(std::ofstream& stream, ); stream << NLine(1); - stream << Tab(4) << "private IntPtr _port;" << NLine(1); - stream << Tab(4) << "private WeakReference _service;" << NLine(1); - 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); - GenInvokeMethod(stream, decl, id); + 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); } @@ -544,35 +493,19 @@ void CsGeneratorBase::GenReceivedEvent(std::ofstream& stream, void CsGeneratorBase::GenInvokeMethod(std::ofstream& stream, const Declaration& decl, const std::string& id) { - const char* pre = - "if (_port == IntPtr.Zero || _service == null)\n" \ - " throw new InvalidOperationException(\"Not connected!\");\n" \ - "if (!_service.IsAlive)\n" \ - " throw new InvalidOperationException(\"Invalid delegate object!\");\n" \ - "\n" \ - "Interop.LibRPCPort.Parcel.Create(out IntPtr p);\n" \ - "Interop.LibRPCPort.Parcel.WriteInt32(p, (int)MethodId.Callback);\n" \ - "Serialize(p, this);\n"; - - const char* mid = - "// Send\n" \ - "Interop.LibRPCPort.Parcel.Send(p, _port);\n" \ - "Interop.LibRPCPort.Parcel.Destroy(p);\n"; - - stream << Tab(4) << "public void Invoke("; - GenParameters(stream, decl.GetParameters()); - stream << ")" << NLine(1); - GenBrace(stream, TAB_SIZE * 4, [&]() { - stream << AddIndent(TAB_SIZE * 5, pre); - std::string m; - for (auto& i : decl.GetParameters().GetParams()) { - auto& pt = i->GetParameterType(); - m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p", id); - } - - stream << AddIndent(TAB_SIZE * 5, m) << NLine(1); - stream << AddIndent(TAB_SIZE * 5, mid); - }); + 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 * 5, m); + } + ); } bool CsGeneratorBase::IsDelegateType(const std::string type_name) { diff --git a/idlc/cs_gen/cs_gen_base.h b/idlc/cs_gen/cs_gen_base.h index 05e1f4a..e3bab0a 100644 --- a/idlc/cs_gen/cs_gen_base.h +++ b/idlc/cs_gen/cs_gen_base.h @@ -44,7 +44,8 @@ class CsGeneratorBase : public Generator { void GenDeclaration(std::ofstream& stream, const Declaration& decl, bool semicol = true); void GenParameters(std::ofstream& stream, const Parameters& ps); - void GenCallbacks(std::ofstream& stream, const Interface& iface); + void GenCallbacks(std::ofstream& stream, const Interface& iface, + bool is_proxy); std::string ConvertTypeToString(const BaseType& type); std::string ConvertTypeToDeserializer(const BaseType& type, @@ -55,6 +56,7 @@ class CsGeneratorBase : public Generator { std::string id, std::string parcel, const std::string iface_id = ""); std::string ConvertTypeToParcelType(const std::string& key); + std::string GetParameters(const Parameters& ps); bool IsDelegateType(const std::string type_name); std::string Tab(int cnt); std::string NLine(int cnt); @@ -66,7 +68,7 @@ class CsGeneratorBase : public Generator { void GenWriteBundle(std::ofstream& stream, const std::string& id); void AddSerializerList(const BaseType& type); void GenCallback(std::ofstream& stream, const Declaration& decl, - const std::string& id); + const std::string& id, bool is_proxy); void GenReceivedEvent(std::ofstream& stream, const Declaration& decl, const std::string& id); void GenInvokeMethod(std::ofstream& stream, const Declaration& decl, diff --git a/idlc/cs_gen/cs_gen_base_cb.h b/idlc/cs_gen/cs_gen_base_cb.h new file mode 100644 index 0000000..841d197 --- /dev/null +++ b/idlc/cs_gen/cs_gen_base_cb.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2018 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. + */ + +const char CB_CALLBACK_BASE[] = +R"__cs_cb( + public abstract class CallbackBase + { + internal int Id; + internal int SeqId; + private static int _seqNum = 0; + + public CallbackBase(int delegateId) + { + Id = delegateId; + SeqId = _seqNum++; + } + + internal virtual void OnReceivedEvent(IntPtr port) {} + + internal static void Serialize(IntPtr h, CallbackBase param) + { + Interop.LibRPCPort.Parcel.WriteInt32(h, (int)param.Id); + Interop.LibRPCPort.Parcel.WriteInt32(h, (int)param.SeqId); + } + + internal static void Deserialize(IntPtr h, CallbackBase param) + { + Interop.LibRPCPort.Parcel.ReadInt32(h, out var id); + param.Id = id; + Interop.LibRPCPort.Parcel.ReadInt32(h, out var seqId); + param.SeqId = seqId; + } + } + +)__cs_cb"; + +const char CB_CALLBACK_CTOR_PROXY[] = +R"__cs_cb( public $$() : base((int)DelegateId.$$) + { + } +)__cs_cb"; + +const char CB_CALLBACK_CTOR_STUB[] = +R"__cs_cb( internal $$(IntPtr port, WeakReference service) : base((int)DelegateId.$$) + { + _port = port; + _service = service; + } +)__cs_cb"; + +const char CB_CALLBACK_STUB_MEMBERS[] = +R"__cs_cb( private IntPtr _port; + private WeakReference _service; + +)__cs_cb"; + +const char CB_CALLBACK_INVOKE_METHOD[] = +R"__cs_cb( + public void Invoke($$) + { + if (_port == IntPtr.Zero || _service == null) + throw new InvalidOperationException("Not connected!"); + if (!_service.IsAlive) + throw new InvalidOperationException("Invalid delegate object!"); + + Interop.LibRPCPort.Parcel.Create(out IntPtr p); + Interop.LibRPCPort.Parcel.WriteInt32(p, (int)MethodId.__Callback); + Serialize(p, this); +$$ + // Send + Interop.LibRPCPort.Parcel.Send(p, _port); + Interop.LibRPCPort.Parcel.Destroy(p); + } +)__cs_cb"; + +const char CB_PROPERTY[] = R"__cs_cb( public $$ $$ { get; set; } +)__cs_cb"; + +const char CB_CTOR[] = R"__cs_cb( + public $$() + { +$$ + } +)__cs_cb"; + +const char CB_WRITE_BUNDLE[] = +R"__cs_cb( + if (param.$$ != null) + { + Interop.LibRPCPort.Parcel.WriteBundle(h, param.$$.SafeBundleHandle.DangerousGetHandle()); + } + else + { + Interop.LibRPCPort.Parcel.WriteBundle(h, new Bundle().SafeBundleHandle.DangerousGetHandle()); + } +)__cs_cb"; diff --git a/idlc/cs_gen/cs_proxy_gen.cc b/idlc/cs_gen/cs_proxy_gen.cc index 92e50c8..a72e74e 100644 --- a/idlc/cs_gen/cs_proxy_gen.cc +++ b/idlc/cs_gen/cs_proxy_gen.cc @@ -15,8 +15,12 @@ */ #include "idlc/cs_gen/cs_proxy_gen.h" + +namespace { #include "idlc/cs_gen/cs_cb_interop.h" #include "idlc/cs_gen/cs_cb_proxy_interop.h" +#include "idlc/cs_gen/cs_proxy_gen_cb.h" +} namespace tidl { @@ -67,105 +71,15 @@ void CsProxyGen::GenInterfaces(std::ofstream& stream) { } void CsProxyGen::GenInterface(std::ofstream& stream, const Interface& iface) { - const char* prop = - "public event EventHandler Connected;\n" \ - "public event EventHandler Disconnected;\n" \ - "public event EventHandler Rejected;\n" \ - "\n" \ - "private IntPtr _proxy;\n" \ - "private IntPtr _port;\n" \ - "private bool _online = false;\n" \ - "private string _appId;\n" \ - "private Object _lock = new Object();\n" \ - "private List _delegateList = new List();\n" \ - "private Interop.LibRPCPort.Proxy.ConnectedEventCallback _connectedEventCallback;\n" \ - "private Interop.LibRPCPort.Proxy.DisconnectedEventCallback _disconnectedEventCallback;\n" \ - "private Interop.LibRPCPort.Proxy.RejectedEventCallback _rejectedEventCallback;\n" \ - "private Interop.LibRPCPort.Proxy.ReceivedEventCallback _receivedEventCallback;\n"; - - const char* eventMethods = - "private void OnConnectedEvent(string endPoint, string port_name, IntPtr port, IntPtr data)\n" \ - "{\n" \ - " _port = port;\n" \ - " _online = true;\n" \ - " Connected?.Invoke(this, null);\n" \ - "}\n" \ - "\n" \ - "private void OnDisconnectedEvent(string endPoint, string port_name, IntPtr data)\n" \ - "{\n" \ - " Disconnected?.Invoke(this, null);\n" \ - "}\n" \ - "\n" \ - "private void OnRejectedEvent(string endPoint, string port_name, IntPtr data)\n" \ - "{\n" \ - " Rejected?.Invoke(this, null);\n" \ - "}\n" \ - "\n" \ - "private void ProcessReceivedEvent(IntPtr parcel)\n" \ - "{\n" \ - " Interop.LibRPCPort.Parcel.ReadInt32(parcel, out int id);\n" \ - " Interop.LibRPCPort.Parcel.ReadInt32(parcel, out int seqId);\n" \ - "\n" \ - " foreach (var i in _delegateList)\n" \ - " {\n" \ - " if ((int)i.Id == id && i.SeqId == seqId)\n" \ - " {\n" \ - " i.OnReceivedEvent(parcel);\n" \ - " break;\n" \ - " }\n" \ - " }\n" \ - "}\n" \ - "\n" \ - "private void OnReceivedEvent(string endPoint, string port_name, IntPtr data)\n" \ - "{\n" \ - " IntPtr parcel_received;\n" \ - " lock (_lock)\n" \ - " {\n" \ - " if (Interop.LibRPCPort.Parcel.CreateFromPort(out parcel_received, _port) != 0)\n" \ - " return;\n" \ - " }\n" \ - "\n" \ - " Interop.LibRPCPort.Parcel.ReadInt32(parcel_received, out int cmd);\n" \ - " if (cmd != (int)MethodId.Callback)\n" \ - " {\n" \ - " Interop.LibRPCPort.Parcel.Destroy(parcel_received);\n" \ - " throw new InvalidOperationException(\"Invalid protocol\");\n" \ - " }\n" \ - "\n" \ - " ProcessReceivedEvent(parcel_received);\n" \ - " Interop.LibRPCPort.Parcel.Destroy(parcel_received);\n" \ - "}\n" \ - "\n" \ - "private void ConsumeCommand(out IntPtr parcel, IntPtr port)\n" \ - "{\n" \ - " do\n" \ - " {\n" \ - " int ret = Interop.LibRPCPort.Parcel.CreateFromPort(out IntPtr p, port);\n" \ - "\n" \ - " if (ret != 0)\n" \ - " break;\n" \ - " Interop.LibRPCPort.Parcel.ReadInt32(p, out int cmd);\n" \ - " if (cmd == (int)MethodId.Result)\n" \ - " {\n" \ - " parcel = p;\n" \ - " return;\n" \ - " }\n" \ - "\n" \ - " ProcessReceivedEvent(p);\n" \ - " Interop.LibRPCPort.Parcel.Destroy(p);\n" \ - " parcel = IntPtr.Zero;\n" \ - " } while (true);\n" \ - " parcel = IntPtr.Zero;\n" \ - "}\n"; stream << Tab(2) << "public class " << iface.GetID() << " : IDisposable" << NLine(1); GenBrace(stream, TAB_SIZE * 2, [&]() { - stream << AddIndent(TAB_SIZE * 3, prop) << NLine(1); - GenCallbacks(stream, iface); + stream << CB_DATA_MEMBERS; + GenCallbacks(stream, iface, true); GenDelegateId(stream, iface); GenMethodId(stream, iface); - stream << AddIndent(TAB_SIZE * 3, eventMethods) << NLine(1); + stream << CB_EVENT_METHODS; GenSerializer(stream); GenListSerializer(stream); GenCtor(stream, iface); @@ -178,32 +92,16 @@ void CsProxyGen::GenInterface(std::ofstream& stream, const Interface& iface) { void CsProxyGen::GenCtor(std::ofstream& stream, const Interface& iface) { const char* m = "public $$(string appId) => _appId = appId;\n"; + stream << NLine(1); GenTemplate(AddIndent(TAB_SIZE * 3, m), stream, [&]()->std::string { return iface.GetID(); } ); - stream << NLine(1); } void CsProxyGen::GenConnectMethod(std::ofstream& stream, const Interface& iface) { - const char* m = - "public void Connect()\n" \ - "{\n" \ - " Interop.LibRPCPort.Proxy.Create(out _proxy);\n" \ - " _connectedEventCallback = new Interop.LibRPCPort.Proxy.ConnectedEventCallback(OnConnectedEvent);\n" \ - " _disconnectedEventCallback = new Interop.LibRPCPort.Proxy.DisconnectedEventCallback(OnDisconnectedEvent);\n" \ - " _rejectedEventCallback = new Interop.LibRPCPort.Proxy.RejectedEventCallback(OnRejectedEvent);\n" \ - " _receivedEventCallback = new Interop.LibRPCPort.Proxy.ReceivedEventCallback(OnReceivedEvent);\n" \ - " Interop.LibRPCPort.Proxy.AddConnectedEventCb(_proxy, _connectedEventCallback, IntPtr.Zero);\n" \ - " Interop.LibRPCPort.Proxy.AddDisconnectedEventCb(_proxy, _disconnectedEventCallback, IntPtr.Zero);\n" \ - " Interop.LibRPCPort.Proxy.AddRejectedEventCb(_proxy, _rejectedEventCallback, IntPtr.Zero);\n" \ - " Interop.LibRPCPort.Proxy.AddReceivedEventCb(_proxy, _receivedEventCallback, IntPtr.Zero);\n" \ - " if (Interop.LibRPCPort.Proxy.Connect(_proxy, _appId, \"$$\") != 0)\n" \ - " throw new InvalidOperationException(\"Connection failed\");\n" \ - "}"; - - GenTemplate(AddIndent(TAB_SIZE * 3, m), stream, + GenTemplate(CB_CONNECT_METHOD, stream, [&]()->std::string { return iface.GetID(); } @@ -229,17 +127,7 @@ void CsProxyGen::GenMethods(std::ofstream& stream, const Interface& iface) { } void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) { - const char* pre = - "if (!_online)\n" \ - " throw new InvalidOperationException(\"Not connected!\");\n" \ - "\n" \ - "Interop.LibRPCPort.Parcel.Create(out IntPtr p);\n"; - - const char* mid = - "// Send\n" \ - "Interop.LibRPCPort.Parcel.Send(p, _port);\n"; - - stream << AddIndent(TAB_SIZE * 4, pre); + stream << CB_INVOCATION_PRE; // Serialize stream << Tab(4) @@ -252,8 +140,9 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) { if (pt.GetDirection() == ParameterType::Direction::OUT) continue; m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p"); - if (IsDelegateType(pt.GetBaseType().ToString())) + if (IsDelegateType(pt.GetBaseType().ToString())) { l += "_delegateList.Add(" + i->GetID() + ");\n"; + } } stream << AddIndent(TAB_SIZE * 4, m) << NLine(1); @@ -263,7 +152,7 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) { GenBrace(stream, TAB_SIZE * 4, [&]() { if (!l.empty()) stream << AddIndent(TAB_SIZE * 5, l) << NLine(1); - stream << AddIndent(TAB_SIZE * 5, mid) << NLine(1); + stream << CB_INVOCATION_MID << NLine(1); if (decl.GetMethodType() == Declaration::MethodType::SYNC) { stream << Tab(5) << "// Receive" << NLine(1); stream << Tab(5) @@ -308,47 +197,15 @@ void CsProxyGen::GenInvocation(std::ofstream& stream, const Declaration& decl) { << NLine(1); stream << Tab(4) << "Interop.LibRPCPort.Parcel.Destroy(parcel_received);" << NLine(1); - stream << Tab(4) << "return ret;" << NLine(1); } void CsProxyGen::GenDisposable(std::ofstream& stream, const Interface& iface) { - const char* m = - "#region IDisposable Support\n" \ - "private bool disposedValue = false;\n" \ - "\n" \ - "protected virtual void Dispose(bool disposing)\n" \ - "{\n" \ - " if (!disposedValue)\n" \ - " {\n" \ - " if (disposing)\n" \ - " {\n" \ - " }\n" \ - "\n" \ - " if (_proxy != IntPtr.Zero)\n" \ - " Interop.LibRPCPort.Proxy.Destroy(_proxy);\n" \ - "\n" \ - " disposedValue = true;\n" \ - " }\n" \ - "}\n" \ - "\n" \ - "~$$() {\n" \ - " Dispose(false);\n" \ - "}\n" \ - "\n" \ - "public void Dispose()\n" \ - "{\n" \ - " Dispose(true);\n" \ - " GC.SuppressFinalize(this);\n" \ - "}\n" \ - "#endregion\n"; - - GenTemplate(AddIndent(TAB_SIZE * 3, m), stream, + GenTemplate(CB_DISPOSABLE, stream, [&]()->std::string { return iface.GetID(); } ); - } } // namespace tidl diff --git a/idlc/cs_gen/cs_proxy_gen_cb.h b/idlc/cs_gen/cs_proxy_gen_cb.h new file mode 100644 index 0000000..960897a --- /dev/null +++ b/idlc/cs_gen/cs_proxy_gen_cb.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2018 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. + */ + +const char CB_DATA_MEMBERS[] = +R"__cs_cb( public event EventHandler Connected; + public event EventHandler Disconnected; + public event EventHandler Rejected; + + private IntPtr _proxy; + private IntPtr _port; + private bool _online = false; + private string _appId; + private Object _lock = new Object(); + private List _delegateList = new List(); + private Interop.LibRPCPort.Proxy.ConnectedEventCallback _connectedEventCallback; + private Interop.LibRPCPort.Proxy.DisconnectedEventCallback _disconnectedEventCallback; + private Interop.LibRPCPort.Proxy.RejectedEventCallback _rejectedEventCallback; + private Interop.LibRPCPort.Proxy.ReceivedEventCallback _receivedEventCallback; +)__cs_cb"; + +const char CB_EVENT_METHODS[] = +R"__cs_cb( + private void OnConnectedEvent(string endPoint, string port_name, IntPtr port, IntPtr data) + { + _port = port; + _online = true; + Connected?.Invoke(this, null); + } + + private void OnDisconnectedEvent(string endPoint, string port_name, IntPtr data) + { + Disconnected?.Invoke(this, null); + } + + private void OnRejectedEvent(string endPoint, string port_name, IntPtr data) + { + Rejected?.Invoke(this, null); + } + + private void ProcessReceivedEvent(IntPtr parcel) + { + Interop.LibRPCPort.Parcel.ReadInt32(parcel, out int id); + Interop.LibRPCPort.Parcel.ReadInt32(parcel, out int seqId); + + foreach (var i in _delegateList) + { + if ((int)i.Id == id && i.SeqId == seqId) + { + i.OnReceivedEvent(parcel); + break; + } + } + } + + private void OnReceivedEvent(string endPoint, string port_name, IntPtr data) + { + IntPtr parcel_received; + lock (_lock) + { + if (Interop.LibRPCPort.Parcel.CreateFromPort(out parcel_received, _port) != 0) + return; + } + + Interop.LibRPCPort.Parcel.ReadInt32(parcel_received, out int cmd); + if (cmd != (int)MethodId.__Callback) + { + Interop.LibRPCPort.Parcel.Destroy(parcel_received); + throw new InvalidOperationException("Invalid protocol"); + } + + ProcessReceivedEvent(parcel_received); + Interop.LibRPCPort.Parcel.Destroy(parcel_received); + } + + private void ConsumeCommand(out IntPtr parcel, IntPtr port) + { + do + { + int ret = Interop.LibRPCPort.Parcel.CreateFromPort(out IntPtr p, port); + + if (ret != 0) + break; + Interop.LibRPCPort.Parcel.ReadInt32(p, out int cmd); + if (cmd == (int)MethodId.__Result) + { + parcel = p; + return; + } + + ProcessReceivedEvent(p); + Interop.LibRPCPort.Parcel.Destroy(p); + parcel = IntPtr.Zero; + } while (true); + parcel = IntPtr.Zero; + } +)__cs_cb"; + +const char CB_CONNECT_METHOD[] = +R"__cs_cb( + public void Connect() + { + Interop.LibRPCPort.Proxy.Create(out _proxy); + _connectedEventCallback = new Interop.LibRPCPort.Proxy.ConnectedEventCallback(OnConnectedEvent); + _disconnectedEventCallback = new Interop.LibRPCPort.Proxy.DisconnectedEventCallback(OnDisconnectedEvent); + _rejectedEventCallback = new Interop.LibRPCPort.Proxy.RejectedEventCallback(OnRejectedEvent); + _receivedEventCallback = new Interop.LibRPCPort.Proxy.ReceivedEventCallback(OnReceivedEvent); + Interop.LibRPCPort.Proxy.AddConnectedEventCb(_proxy, _connectedEventCallback, IntPtr.Zero); + Interop.LibRPCPort.Proxy.AddDisconnectedEventCb(_proxy, _disconnectedEventCallback, IntPtr.Zero); + Interop.LibRPCPort.Proxy.AddRejectedEventCb(_proxy, _rejectedEventCallback, IntPtr.Zero); + Interop.LibRPCPort.Proxy.AddReceivedEventCb(_proxy, _receivedEventCallback, IntPtr.Zero); + if (Interop.LibRPCPort.Proxy.Connect(_proxy, _appId, "$$") != 0) + throw new InvalidOperationException("Connection failed"); + } +)__cs_cb"; + +const char CB_DISPOSABLE[] = +R"__cs_cb( + #region IDisposable Support + private bool disposedValue = false; + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + } + + if (_proxy != IntPtr.Zero) + Interop.LibRPCPort.Proxy.Destroy(_proxy); + + disposedValue = true; + } + } + + ~$$() { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion +)__cs_cb"; + +const char CB_INVOCATION_PRE[] = +R"__cs_cb( if (!_online) + throw new InvalidOperationException("Not connected!"); + + Interop.LibRPCPort.Parcel.Create(out IntPtr p); +)__cs_cb"; + +const char CB_INVOCATION_MID[] = +R"__cs_cb( // Send + Interop.LibRPCPort.Parcel.Send(p, _port); +)__cs_cb"; diff --git a/idlc/cs_gen/cs_stub_gen.cc b/idlc/cs_gen/cs_stub_gen.cc index 6747838..12897bb 100644 --- a/idlc/cs_gen/cs_stub_gen.cc +++ b/idlc/cs_gen/cs_stub_gen.cc @@ -15,8 +15,12 @@ */ #include "idlc/cs_gen/cs_stub_gen.h" + +namespace { #include "idlc/cs_gen/cs_cb_interop.h" #include "idlc/cs_gen/cs_cb_stub_interop.h" +#include "idlc/cs_gen/cs_stub_gen_cb.h" +} namespace tidl { @@ -69,19 +73,9 @@ void CsStubGen::GenInterface(std::ofstream& stream, const Interface& iface) { stream << Tab(2) << "public sealed class " << iface.GetID() << " : IDisposable" << NLine(1); GenBrace(stream, TAB_SIZE * 2, [&]() { - stream << Tab(3) << "private IntPtr _stub;" << NLine(1); - stream << Tab(3) - << "private List _services = new List();" - << NLine(1); - stream << Tab(3) << "private Type _serviceType;" << NLine(1); - stream << Tab(3) << "private Interop.LibRPCPort.Stub.ConnectedEventCallback _connectedEventCallback;" - << NLine(1); - stream << Tab(3) << "private Interop.LibRPCPort.Stub.DisconnectedEventCallback _disconnectedEventCallback;" - << NLine(1); - stream << Tab(3) << "private Interop.LibRPCPort.Stub.ReceivedEventCallback _receivedEventCallback;" - << NLine(2); + stream << CB_DATA_MEMBERS; GenServiceBase(stream, iface); - GenCallbacks(stream, iface); + GenCallbacks(stream, iface, false); GenDelegateId(stream, iface); GenMethodId(stream, iface); GenSerializer(stream); @@ -96,30 +90,10 @@ void CsStubGen::GenInterface(std::ofstream& stream, const Interface& iface) { } void CsStubGen::GenServiceBase(std::ofstream& stream, const Interface& iface) { - const char cls[] = - "public abstract class ServiceBase\n" \ - "{\n" \ - " public string Sender\n" \ - " {\n" \ - " get; internal set;\n" \ - " }\n" \ - "\n" \ - " public string Instance\n" \ - " {\n" \ - " get; internal set;\n" \ - " }\n" \ - "\n" \ - " protected ServiceBase()\n" \ - " {\n" \ - " }\n" \ - "\n" \ - " public abstract void OnCreate();\n" \ - " public abstract void OnTerminate();\n"; - stream << AddIndent(TAB_SIZE * 3, cls); + stream << CB_SERVICE_BASE_FRONT; GenDeclarations(stream, iface.GetDeclarations()); stream << NLine(1); stream << AddIndent(TAB_SIZE * 3, "}\n"); - stream << NLine(1); } void CsStubGen::GenDeclarations(std::ofstream& stream, @@ -134,45 +108,7 @@ void CsStubGen::GenDeclarations(std::ofstream& stream, } void CsStubGen::GenReceivedEvent(std::ofstream& stream, const Interface& iface) { - const char method_front[] = - "private int OnReceivedEvent(string sender, string instance, IntPtr port, IntPtr data)\n" \ - "{\n" \ - " int ret = Interop.LibRPCPort.Parcel.CreateFromPort(out IntPtr p, port);\n" \ - "\n" \ - " if (ret != 0)\n" \ - " return ret;\n" \ - "\n" \ - " Interop.LibRPCPort.Parcel.Create(out IntPtr result);\n" \ - " Interop.LibRPCPort.Parcel.ReadInt32(p, out int cmd);\n" \ - " ServiceBase b = null;\n" \ - "\n" \ - " foreach (var i in _services)\n" \ - " {\n" \ - " if (i.Instance.Equals(instance))\n" \ - " {\n" \ - " b = i;\n" \ - " break;\n" \ - " }\n" \ - " }\n" \ - "\n" \ - " if (b == null)\n" \ - " return -1;\n" \ - "\n" - " switch ((MethodId)cmd)\n" \ - " {\n"; - - const char method_back[] = - " default:\n" \ - " return -1;\n" \ - " }\n" \ - "\n" \ - " Interop.LibRPCPort.Parcel.Destroy(p);\n" \ - " Interop.LibRPCPort.Parcel.Destroy(result);\n" \ - "\n" \ - " return 0;\n" \ - "}\n"; - - stream << AddIndent(TAB_SIZE * 3, method_front); + stream << CB_ON_RECEIVED_EVENT_FRONT; for (auto& i : iface.GetDeclarations().GetDecls()) { if (i->GetMethodType() == Declaration::MethodType::DELEGATE) continue; @@ -182,7 +118,7 @@ void CsStubGen::GenReceivedEvent(std::ofstream& stream, const Interface& iface) stream << Tab(7) << "break;" << NLine(1); }); } - stream << AddIndent(TAB_SIZE * 3, method_back) << NLine(1); + stream << CB_ON_RECEIVED_EVENT_BACK; } void CsStubGen::GenInvocation(std::ofstream& stream, const Declaration& decl) { @@ -237,7 +173,7 @@ void CsStubGen::GenInvocation(std::ofstream& stream, const Declaration& decl) { return; cnt = 0; - m = "Interop.LibRPCPort.Parcel.WriteInt32(result, (int)MethodId.Result);\n"; + m = "Interop.LibRPCPort.Parcel.WriteInt32(result, (int)MethodId.__Result);\n"; for (auto& i : decl.GetParameters().GetParams()) { auto& pt = i->GetParameterType(); cnt++; @@ -256,48 +192,15 @@ void CsStubGen::GenInvocation(std::ofstream& stream, const Declaration& decl) { } void CsStubGen::GenConnectedEvent(std::ofstream& stream) { - const char method[] = - "private void OnConnectedEvent(string sender, string instance, IntPtr data)\n" \ - "{\n" \ - " ServiceBase s = Activator.CreateInstance(_serviceType) as ServiceBase;\n" \ - " s.Sender = sender;\n" \ - " s.Instance = instance;\n" \ - " s.OnCreate();\n" \ - " _services.Add(s);\n" \ - "}\n"; - stream << AddIndent(TAB_SIZE * 3, method) << NLine(1); + stream << CB_ON_CONNECTED_EVENT; } void CsStubGen::GenDisconnectedEvent(std::ofstream& stream) { - const char method[] = - "private void OnDisconnectedEvent(string sender, string instance, IntPtr data)\n" \ - "{\n" \ - " foreach (var i in _services)\n" \ - " {\n" \ - " if (i.Instance.Equals(instance))\n" \ - " {\n" \ - " i.OnTerminate();\n" \ - " _services.Remove(i);\n" \ - " break;\n" \ - " }\n" \ - " }\n" \ - "}\n"; - stream << AddIndent(TAB_SIZE * 3, method) << NLine(1); + stream << CB_ON_DISCONNECTED_EVENT; } void CsStubGen::GenCtor(std::ofstream& stream, const Interface& iface) { - const char ctor[] = - "public $$()\n" \ - "{\n" \ - " Interop.LibRPCPort.Stub.Create(out _stub, \"$$\");\n" \ - " _connectedEventCallback = new Interop.LibRPCPort.Stub.ConnectedEventCallback(OnConnectedEvent);\n" \ - " _disconnectedEventCallback = new Interop.LibRPCPort.Stub.DisconnectedEventCallback(OnDisconnectedEvent);\n" \ - " _receivedEventCallback = new Interop.LibRPCPort.Stub.ReceivedEventCallback(OnReceivedEvent);\n" \ - " Interop.LibRPCPort.Stub.AddReceivedEventCb(_stub, _receivedEventCallback, IntPtr.Zero);\n" \ - " Interop.LibRPCPort.Stub.AddConnectedEventCb(_stub, _connectedEventCallback, IntPtr.Zero);\n" \ - " Interop.LibRPCPort.Stub.AddDisconnectedEventCb(_stub, _disconnectedEventCallback, IntPtr.Zero);\n"; - - GenTemplate(AddIndent(TAB_SIZE * 3, ctor), stream, + GenTemplate(CB_CTOR_FRONT, stream, [&]()->std::string { return iface.GetID(); }, @@ -312,71 +215,19 @@ void CsStubGen::GenCtor(std::ofstream& stream, const Interface& iface) { << i->GetValue() << "\");" << NLine(1); } } - stream << Tab(3) << "}" << NLine(2); + stream << Tab(3) << "}" << NLine(1); } void CsStubGen::GenCommonMethods(std::ofstream& stream) { - const char method_listen[] = - "public void Listen(Type serviceType)\n" \ - "{\n" \ - " if (!typeof(ServiceBase).IsAssignableFrom(serviceType))\n" \ - " throw new InvalidOperationException(\"Invalid type\");\n" \ - " _serviceType = serviceType;\n" \ - " Interop.LibRPCPort.Stub.Listen(_stub);\n" \ - "}\n"; - - const char method_get_services[] = - "public IEnumerable GetServices()\n" \ - "{\n" \ - " return _services;\n" \ - "}\n"; - - stream << AddIndent(TAB_SIZE * 3, method_listen) << NLine(1); - stream << AddIndent(TAB_SIZE * 3, method_get_services); + stream << CB_COMMON_METHODS; } void CsStubGen::GenDisposable(std::ofstream& stream, const Interface& iface) { - const char* m = - "#region IDisposable Support\n" \ - "private bool disposedValue = false;\n" \ - "\n" \ - "private void Dispose(bool disposing)\n" \ - "{\n" \ - " if (!disposedValue)\n" \ - " {\n" \ - " if (disposing)\n" \ - " {\n" \ - " }\n" \ - "\n" \ - " foreach (var i in _services)\n" \ - " {\n" \ - " i.OnTerminate();\n" \ - " }\n" \ - "\n" \ - " _services = null;\n" \ - " if (_stub != IntPtr.Zero)\n" \ - " Interop.LibRPCPort.Stub.Destroy(_stub);\n" \ - " disposedValue = true;\n" \ - " }\n" \ - "}\n" \ - "\n" \ - "~$$() {\n" \ - " Dispose(false);\n" \ - "}\n" \ - "\n" \ - "public void Dispose()\n" \ - "{\n" \ - " Dispose(true);\n" \ - " GC.SuppressFinalize(this);\n" \ - "}\n" \ - "#endregion\n"; - - GenTemplate(AddIndent(TAB_SIZE * 3, m), stream, + GenTemplate(CB_DISPOSABLE, stream, [&]()->std::string { return iface.GetID(); } ); - } } // namespace tidl diff --git a/idlc/cs_gen/cs_stub_gen_cb.h b/idlc/cs_gen/cs_stub_gen_cb.h new file mode 100644 index 0000000..29d0656 --- /dev/null +++ b/idlc/cs_gen/cs_stub_gen_cb.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2018 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. + */ + +const char CB_DATA_MEMBERS[] = +R"__cs_cb( private IntPtr _stub; + private List _services = new List(); + private Type _serviceType; + private Interop.LibRPCPort.Stub.ConnectedEventCallback _connectedEventCallback; + private Interop.LibRPCPort.Stub.DisconnectedEventCallback _disconnectedEventCallback; + private Interop.LibRPCPort.Stub.ReceivedEventCallback _receivedEventCallback; +)__cs_cb"; + +const char CB_SERVICE_BASE_FRONT[] = +R"__cs_cb( + public abstract class ServiceBase + { + public string Sender + { + get; internal set; + } + + public string Instance + { + get; internal set; + } + + protected ServiceBase() + { + } + + public abstract void OnCreate(); + public abstract void OnTerminate(); +)__cs_cb"; + +const char CB_ON_RECEIVED_EVENT_FRONT[] = +R"__cs_cb( + private int OnReceivedEvent(string sender, string instance, IntPtr port, IntPtr data) + { + int ret = Interop.LibRPCPort.Parcel.CreateFromPort(out IntPtr p, port); + + if (ret != 0) + return ret; + + Interop.LibRPCPort.Parcel.Create(out IntPtr result); + Interop.LibRPCPort.Parcel.ReadInt32(p, out int cmd); + ServiceBase b = null; + + foreach (var i in _services) + { + if (i.Instance.Equals(instance)) + { + b = i; + break; + } + } + + if (b == null) + return -1; + + switch ((MethodId)cmd) + { +)__cs_cb"; + +const char CB_ON_RECEIVED_EVENT_BACK[] = +R"__cs_cb( + default: + return -1; + } + + Interop.LibRPCPort.Parcel.Destroy(p); + Interop.LibRPCPort.Parcel.Destroy(result); + + return 0; + } +)__cs_cb"; + +const char CB_ON_CONNECTED_EVENT[] = +R"__cs_cb( + private void OnConnectedEvent(string sender, string instance, IntPtr data) + { + ServiceBase s = Activator.CreateInstance(_serviceType) as ServiceBase; + s.Sender = sender; + s.Instance = instance; + s.OnCreate(); + _services.Add(s); + } +)__cs_cb"; + +const char CB_ON_DISCONNECTED_EVENT[] = + R"__cs_cb( + private void OnDisconnectedEvent(string sender, string instance, IntPtr data) + { + foreach (var i in _services) + { + if (i.Instance.Equals(instance)) + { + i.OnTerminate(); + _services.Remove(i); + break; + } + } + } +)__cs_cb"; + +const char CB_CTOR_FRONT[] = +R"__cs_cb( + public $$() + { + Interop.LibRPCPort.Stub.Create(out _stub, "$$"); + _connectedEventCallback = new Interop.LibRPCPort.Stub.ConnectedEventCallback(OnConnectedEvent); + _disconnectedEventCallback = new Interop.LibRPCPort.Stub.DisconnectedEventCallback(OnDisconnectedEvent); + _receivedEventCallback = new Interop.LibRPCPort.Stub.ReceivedEventCallback(OnReceivedEvent); + Interop.LibRPCPort.Stub.AddReceivedEventCb(_stub, _receivedEventCallback, IntPtr.Zero); + Interop.LibRPCPort.Stub.AddConnectedEventCb(_stub, _connectedEventCallback, IntPtr.Zero); + Interop.LibRPCPort.Stub.AddDisconnectedEventCb(_stub, _disconnectedEventCallback, IntPtr.Zero); +)__cs_cb"; + +const char CB_COMMON_METHODS[] = +R"__cs_cb( + public void Listen(Type serviceType) + { + if (!typeof(ServiceBase).IsAssignableFrom(serviceType)) + throw new InvalidOperationException("Invalid type"); + _serviceType = serviceType; + Interop.LibRPCPort.Stub.Listen(_stub); + } + + public IEnumerable GetServices() + { + return _services; + } +)__cs_cb"; + +const char CB_DISPOSABLE[] = +R"__cs_cb( + #region IDisposable Support + private bool disposedValue = false; + + private void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + } + + foreach (var i in _services) + { + i.OnTerminate(); + } + + _services = null; + if (_stub != IntPtr.Zero) + Interop.LibRPCPort.Stub.Destroy(_stub); + disposedValue = true; + } + } + + ~$$() { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion +)__cs_cb"; -- 2.7.4