From: Sangyoon Jang Date: Thu, 13 Jan 2022 03:33:37 +0000 (+0900) Subject: [cion] Implement C# group generator X-Git-Tag: accepted/tizen/unified/20220216.010312~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F33%2F269433%2F12;p=platform%2Fcore%2Fappfw%2Ftidl.git [cion] Implement C# group generator Change-Id: I2059365150a1b27316caf17173d13014e5e9b0fb Signed-off-by: Sangyoon Jang --- diff --git a/idlc/gen_cion/cs_cion_gen_base.cc b/idlc/gen_cion/cs_cion_gen_base.cc index 86d679f..73cb338 100644 --- a/idlc/gen_cion/cs_cion_gen_base.cc +++ b/idlc/gen_cion/cs_cion_gen_base.cc @@ -441,12 +441,15 @@ void CsCionGeneratorBase::GenWriteBundle(std::ofstream& stream, } void CsCionGeneratorBase::GenMethodId(std::ofstream& stream, - const Interface& iface) { + const Interface& iface, bool is_group) { 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); + int cnt = 0; + if (!is_group) { + stream << Tab(4) << "__Result = 0," << NLine(1); + stream << Tab(4) << "__Callback = 1," << NLine(1); + cnt = 2; + } for (const auto& i : iface.GetDeclarations()) { if (i->GetMethodType() == Declaration::MethodType::DELEGATE) continue; diff --git a/idlc/gen_cion/cs_cion_gen_base.h b/idlc/gen_cion/cs_cion_gen_base.h index b9c0685..57e04d4 100644 --- a/idlc/gen_cion/cs_cion_gen_base.h +++ b/idlc/gen_cion/cs_cion_gen_base.h @@ -40,7 +40,7 @@ class CsCionGeneratorBase : public Generator { void GenListSerializer(std::ofstream& stream); void GenListSerializer(std::ofstream& stream, const BaseType& type); void GenShareFile(std::ofstream& stream, const Interface& iface, bool is_proxy); - void GenMethodId(std::ofstream& stream, const Interface& iface); + void GenMethodId(std::ofstream& stream, const Interface& iface, bool is_group = false); void GenDelegateId(std::ofstream& stream, const Interface& iface); void GenDeclaration(std::ofstream& stream, const Declaration& decl, bool semicol = true); diff --git a/idlc/gen_cion/cs_cion_group_gen.cc b/idlc/gen_cion/cs_cion_group_gen.cc new file mode 100644 index 0000000..99e72f1 --- /dev/null +++ b/idlc/gen_cion/cs_cion_group_gen.cc @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2022 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 "idlc/gen_cion/cs_cion_group_gen.h" + +namespace { +#include "idlc/gen_cion/cs_cion_group_gen_cb.h" +} + +namespace tidl { + +CsCionGroupGen::CsCionGroupGen(std::shared_ptr doc) + : CsCionGeneratorBase(doc) {} + +void CsCionGroupGen::OnInitGen(std::ofstream& stream) { + GenVersion(stream); + stream << "using System;" << NLine(1) + << "using System.Collections.Generic;" << NLine(1) + << "using System.Threading;" << NLine(1) + << "using Tizen.Applications;" << NLine(1) + << "using Tizen.Applications.RPCPort;" << NLine(1) + << "using Tizen.Applications.Cion;" << NLine(1); + GenNamespace(stream); +} + +void CsCionGroupGen::OnFiniGen(std::ofstream& stream) { +} + +void CsCionGroupGen::GenNamespace(std::ofstream& stream) { + stream << NLine(1); + stream << "namespace Cion" << NLine(1); + GenBrace(stream, 0, [&]() { + stream << "namespace " << GetFileNamespace() << NLine(1); + GenBrace(stream, 0, [&]() { + GenStructures(stream); + stream << Tab(1) << "namespace Group" << NLine(1); + GenBrace(stream, TAB_SIZE, [&]() { + GenInterfaces(stream); + }); + }); + }); +} + +void CsCionGroupGen::GenInterfaces(std::ofstream& stream) { + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() != Block::TYPE_INTERFACE) + continue; + Interface& iface = static_cast(*i); + GenInterface(stream, iface); + stream << NLine(1); + } +} + +void CsCionGroupGen::GenInterface(std::ofstream& stream, const Interface& iface) { + stream << Tab(2) << "public class " << iface.GetID() + << " : GroupBase" << NLine(1); + GenBrace(stream, TAB_SIZE * 2, [&]() { + stream << ReplaceAll(CB_DATA_MEMBERS, "", FULLVER); + GenEvents(stream, iface); + stream << NLine(1); + GenMethodId(stream, iface, true); + stream << CB_EVENT_METHODS; + GenSerializer(stream); + GenListSerializer(stream); + GenCtor(stream, iface); + GenFinalizer(stream, iface); + GenCionPayloadReceivedEvent(stream, iface); + GenMethods(stream, iface); + }); +} + +void CsCionGroupGen::GenEvents(std::ofstream& stream, const Interface& iface) { + stream << NLine(1); + for (const auto& decl : iface.GetDeclarations()) + GenEvent(stream, *decl); +} + +void CsCionGroupGen::GenEvent(std::ofstream& stream, const Declaration& decl) { + stream << Tab(3) << "public delegate void " << decl.GetID() + << "EventHandler(object sender, PeerInfo peer"; + for (const auto& i : decl.GetParameters()) { + auto& pt = i->GetParameterType(); + if (pt.GetDirection() == ParameterType::Direction::OUT) + continue; + stream << ", " << i->GetParameterType().GetBaseType().ToString() << " " + << i->GetID(); + } + stream << ");" << NLine(1); + stream << Tab(3) << "public event " << decl.GetID() << "EventHandler " + << decl.GetID() << "Event;" << NLine(1); +} + +void CsCionGroupGen::GenCtor(std::ofstream& stream, const Interface& iface) { + bool securityCheck = false; + stream << NLine(1); + std::string m = + "/// \n" + "/// Constructor for this class\n" + "/// \n" + "/// http://tizen.org/privilege/d2d.datasharing\n" + "/// http://tizen.org/privilege/internet\n" + "/// The maximum length of topic name is 512.\n" + "/// \n" + "/// Thrown when the given topic name is too long.\n" + "/// \n" + "/// \n" + "/// Thrown when an application does not have the privilege.\n" + "/// \n" + "public ##(string topicName) : base(topicName, new SecurityInfo {"; + + for (const auto& attr : iface.GetAttributes()) { + if (attr->GetKey() == "ca_path") { + m += "CaPath = \"" + attr->GetValue() + "\", "; + securityCheck = true; + } else if (attr->GetKey() == "cert_path") { + m += "CertPath = \"" + attr->GetValue() + "\", "; + securityCheck = true; + } else if (attr->GetKey() == "private_key") { + m += "PrivateKeyPath = \"" + attr->GetValue() + "\", "; + securityCheck = true; + } + } + + auto const pos = m.find_last_of(','); + m = m.substr(0, pos); + + if (securityCheck) + m += "})";/* base(serviceName, new SecurityInfo {CertPath = xxx, ... ) */ + else + m += ")"; /* base(serviceName) */ + m = AddIndent(TAB_SIZE * 3, m); + m.pop_back(); + m += CB_CTOR_BODY; + + stream << ReplaceAll(m, "##", iface.GetID()); +} + +void CsCionGroupGen::GenFinalizer(std::ofstream& stream, + const Interface& iface) { + stream << ReplaceAll(CB_FINALIZER, "##", iface.GetID()); +} + +void CsCionGroupGen::GenMethods(std::ofstream& stream, const Interface& iface) { + auto& decls = iface.GetDeclarations(); + + for (const auto& i : decls) { + if (i->GetMethodType() == Declaration::MethodType::DELEGATE) + continue; + + stream << NLine(1); + if (!i->GetComments().empty()) + stream << AddIndent(TAB_SIZE * 3, i->GetComments()); + + stream << Tab(3) << "public "; + GenDeclaration(stream, *i, false); + stream << NLine(1); + GenBrace(stream, TAB_SIZE * 3, [&]() { + GenInvocation(stream, *i); + }); + } +} + +void CsCionGroupGen::GenInvocation(std::ofstream& stream, + const Declaration& decl) { + GenTemplate(CB_INVOCATION_PRE, stream, + [&]()->std::string { + std::string st; + st += Tab(5) + "p.WriteInt((int)MethodId." + decl.GetID() + ");" + + NLine(1); + std::string m; + std::string l; + for (const auto& i : decl.GetParameters()) { + auto& pt = i->GetParameterType(); + if (pt.GetDirection() == ParameterType::Direction::OUT) + continue; + m += ConvertTypeToSerializer(pt.GetBaseType(), i->GetID(), "p"); + } + + st += AddIndent(TAB_SIZE * 5, m) + NLine(1); + + st += Tab(5) + "lock (_lock)" + NLine(1); + st += Tab(5) + "{" + NLine(1); + if (!l.empty()) + st += AddIndent(TAB_SIZE * 6, l) + NLine(1); + + // Deserialize + st += CB_ASYNC_INVOCATION_MID; + st += Tab(5) + "}"; + + return st; + }); +} + +void CsCionGroupGen::GenCionPayloadReceivedEvent(std::ofstream& stream, + const Interface& iface) { + stream << CB_ON_PAYLOAD_RECEIVED_FRONT; + + for (const auto& i : iface.GetDeclarations()) { + if (i->GetMethodType() == Declaration::MethodType::DELEGATE || + i->GetMethodType() == Declaration::MethodType::SYNC) + continue; + stream << Tab(6) << "case (int)MethodId." << i->GetID() << ":" << NLine(1); + GenBrace(stream, TAB_SIZE * 6, [&]() { + GenHandlerInvocation(stream, *i); + stream << Tab(7) << "break;" << NLine(1); + }); + } + + stream << CB_ON_PAYLOAD_RECEIVED_BACK << NLine(1); +} + +void CsCionGroupGen::GenHandlerInvocation(std::ofstream& stream, + const Declaration& decl) { + int cnt = 1; + // Deserialize + for (const auto& i : decl.GetParameters()) { + std::string v = "param" + std::to_string(cnt); + std::string c = ConvertTypeToDeserializer( + i->GetParameterType().GetBaseType(), v, "parcelReceived"); + stream << AddIndent(TAB_SIZE * 7, c); + cnt++; + } + + // Invoke + std::string m; + m += decl.GetID() + "Event?.Invoke(this, peerInfo"; + cnt = 1; + for (auto i = decl.GetParameters().begin(); + i != decl.GetParameters().end(); ++i) { + m += ", param" + std::to_string(cnt++); + } + + m += ");\n"; + stream << AddIndent(TAB_SIZE * 7, m); +} + +} // namespace tidl diff --git a/idlc/gen_cion/cs_cion_group_gen.h b/idlc/gen_cion/cs_cion_group_gen.h new file mode 100644 index 0000000..61bb288 --- /dev/null +++ b/idlc/gen_cion/cs_cion_group_gen.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 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. + */ + +#ifndef IDLC_CS_CION_GEN_CS_GROUP_GEN_H_ +#define IDLC_CS_CION_GEN_CS_GROUP_GEN_H_ + +#include +#include + +#include "idlc/gen_cion/cs_cion_gen_base.h" + +namespace tidl { + +class CsCionGroupGen : public CsCionGeneratorBase { + public: + explicit CsCionGroupGen(std::shared_ptr doc); + virtual ~CsCionGroupGen() = default; + + void OnInitGen(std::ofstream& stream) override; + void OnFiniGen(std::ofstream& stream) override; + + private: + void GenNamespace(std::ofstream& stream); + void GenInterfaces(std::ofstream& stream); + void GenInterface(std::ofstream& stream, const Interface& iface); + void GenEvents(std::ofstream& stream, const Interface& iface); + void GenEvent(std::ofstream& stream, const Declaration& decl); + void GenCtor(std::ofstream& stream, const Interface& iface); + void GenFinalizer(std::ofstream& stream, const Interface& iface); + void GenMethods(std::ofstream& stream, const Interface& iface); + void GenInvocation(std::ofstream& stream, const Declaration& decl); + void GenCionPayloadReceivedEvent(std::ofstream& stream, + const Interface& iface); + void GenHandlerInvocation(std::ofstream& stream, + const Declaration& decl); +}; + +} // namespace tidl + +#endif // IDLC_CS_CION_GEN_CS_GROUP_GEN_H_ \ No newline at end of file diff --git a/idlc/gen_cion/cs_cion_group_gen_cb.h b/idlc/gen_cion/cs_cion_group_gen_cb.h new file mode 100644 index 0000000..ef8c40e --- /dev/null +++ b/idlc/gen_cion/cs_cion_group_gen_cb.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2022 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. + */ + +#ifndef IDLC_CS_CION_GEN_CS_GROUP_GEN_CB_H_ +#define IDLC_CS_CION_GEN_CS_GROUP_GEN_CB_H_ + +/** + * Version of TIDL Compiler. + */ +const char CB_DATA_MEMBERS[] = +R"__cs_cb( public delegate void JoinedHandler(object sender, PeerInfo peerInfo); + public delegate void LeftHandler(object sender, PeerInfo peerInfo); + + /// + /// This event will be invoked when the peer group app is joined to the topic. + /// + public event JoinedHandler Joined; + + /// + /// This event will be invoked after the peer group app was left from the topic. + /// + public event LeftHandler Left; + + public string TopicName; + + private Object _lock = new Object(); +)__cs_cb"; + +const char CB_CTOR_BODY[] = +R"__cs_cb( + { + TopicName = topicName; + try + { + base.Subscribe(); + } + catch + { + throw; + } + } +)__cs_cb"; + +const char CB_FINALIZER[] = +R"__cs_cb( + ~##() + { + base.Unsubscribe(); + } +)__cs_cb"; + +const char CB_EVENT_METHODS[] = +R"__cs_cb( + protected override void OnJoined(PeerInfo peerInfo) + { + Joined?.Invoke(this, peerInfo); + } + + protected override void OnLeft(PeerInfo peerInfo) + { + Left?.Invoke(this, peerInfo); + } +)__cs_cb"; + +const char CB_ON_PAYLOAD_RECEIVED_FRONT[] = +R"__cs_cb( + protected override void OnPayloadReceived(Payload payload, PeerInfo peerInfo) + { + Parcel parcelReceived; + + try + { + parcelReceived = new Parcel(((DataPayload)payload).Data); + } + catch (InvalidIOException) + { + return; + } + + using (parcelReceived) + { + int cmd = parcelReceived.ReadInt(); + switch (cmd) + { +)__cs_cb"; + +const char CB_ON_PAYLOAD_RECEIVED_BACK[] = +R"__cs_cb( + default: + // log here? + break; + } + } + } +)__cs_cb"; + +const char CB_INVOCATION_PRE[] = +R"__cs_cb( using (Parcel p = new Parcel()) + { +$$ + } +)__cs_cb"; + +const char CB_ASYNC_INVOCATION_MID[] = +R"__cs_cb( // Send + DataPayload dp = new DataPayload(p.ToBytes()); + base.Publish(dp); +)__cs_cb"; + +#endif // IDLC_CS_CION_GEN_CS_PROXY_GEN_CB_H_ diff --git a/idlc/main.cc b/idlc/main.cc index b0a0666..6dad213 100644 --- a/idlc/main.cc +++ b/idlc/main.cc @@ -39,6 +39,7 @@ #include "idlc/gen_cion/c_cion_group_body_gen.h" #include "idlc/gen_cion/cs_cion_proxy_gen.h" #include "idlc/gen_cion/cs_cion_stub_gen.h" +#include "idlc/gen_cion/cs_cion_group_gen.h" #include "idlc/gen_cion/cpp_cion_proxy_header_gen.h" #include "idlc/gen_cion/cpp_cion_proxy_body_gen.h" #include "idlc/gen_cion/cpp_cion_stub_header_gen.h" @@ -266,7 +267,11 @@ void GenerateGroupCodes(std::shared_ptr options, break; } case tidl::Options::LANGUAGE_TYPE_CSHARP: + { + tidl::CsCionGroupGen group(ps.GetDoc()); + group.Run(options->GetOutput() + ".cs"); break; + } case tidl::Options::LANGUAGE_TYPE_JAVA: break;