From 0ebad1b119fd779617d18bb079c02a64a99d67b1 Mon Sep 17 00:00:00 2001 From: "jh9216.park" Date: Thu, 14 Oct 2021 02:31:08 -0400 Subject: [PATCH] Implement java generator Change-Id: I5bb1bf6a2e08fc6e8e1d153806222a4466218988 Signed-off-by: jh9216.park --- idlc/CMakeLists.txt | 2 +- idlc/gen/generator.cc | 16 +- idlc/gen/generator.h | 2 +- idlc/gen_cion/java_cion_data_gen.cc | 76 +++ idlc/gen_cion/java_cion_data_gen.h | 41 ++ idlc/gen_cion/java_cion_gen_base.cc | 172 +++++- idlc/gen_cion/java_cion_gen_base.h | 21 +- idlc/gen_cion/java_cion_gen_cb.h | 716 +++++++++++++++++++++++ idlc/gen_cion/java_cion_interface_gen.cc | 81 +++ idlc/gen_cion/java_cion_interface_gen.h | 40 ++ idlc/gen_cion/java_cion_proxy_gen.cc | 212 +++++++ idlc/gen_cion/java_cion_proxy_gen.h | 45 ++ idlc/gen_cion/java_cion_proxy_repo_gen.cc | 67 +++ idlc/gen_cion/java_cion_proxy_repo_gen.h | 39 ++ idlc/gen_cion/java_cion_structure_gen.cc | 200 +++++++ idlc/gen_cion/java_cion_structure_gen.h | 50 ++ idlc/gen_cion/java_cion_stub_base_service_gen.cc | 90 +++ idlc/gen_cion/java_cion_stub_base_service_gen.h | 43 ++ idlc/gen_cion/java_cion_stub_gen.cc | 325 ++++++++++ idlc/gen_cion/java_cion_stub_gen.h | 46 ++ idlc/gen_cion/java_cion_stub_repo_gen.cc | 67 +++ idlc/gen_cion/java_cion_stub_repo_gen.h | 39 ++ idlc/gen_cion/java_cion_utility_gen.cc | 66 +++ idlc/gen_cion/java_cion_utility_gen.h | 41 ++ idlc/main.cc | 52 ++ 25 files changed, 2533 insertions(+), 16 deletions(-) create mode 100644 idlc/gen_cion/java_cion_data_gen.cc create mode 100644 idlc/gen_cion/java_cion_data_gen.h create mode 100644 idlc/gen_cion/java_cion_gen_cb.h create mode 100644 idlc/gen_cion/java_cion_interface_gen.cc create mode 100644 idlc/gen_cion/java_cion_interface_gen.h create mode 100644 idlc/gen_cion/java_cion_proxy_gen.cc create mode 100644 idlc/gen_cion/java_cion_proxy_gen.h create mode 100644 idlc/gen_cion/java_cion_proxy_repo_gen.cc create mode 100644 idlc/gen_cion/java_cion_proxy_repo_gen.h create mode 100644 idlc/gen_cion/java_cion_structure_gen.cc create mode 100644 idlc/gen_cion/java_cion_structure_gen.h create mode 100644 idlc/gen_cion/java_cion_stub_base_service_gen.cc create mode 100644 idlc/gen_cion/java_cion_stub_base_service_gen.h create mode 100644 idlc/gen_cion/java_cion_stub_gen.cc create mode 100644 idlc/gen_cion/java_cion_stub_gen.h create mode 100644 idlc/gen_cion/java_cion_stub_repo_gen.cc create mode 100644 idlc/gen_cion/java_cion_stub_repo_gen.h create mode 100644 idlc/gen_cion/java_cion_utility_gen.cc create mode 100644 idlc/gen_cion/java_cion_utility_gen.h diff --git a/idlc/CMakeLists.txt b/idlc/CMakeLists.txt index 375f58d..415b43b 100644 --- a/idlc/CMakeLists.txt +++ b/idlc/CMakeLists.txt @@ -17,7 +17,7 @@ ENDIF(DEFINED BUILD_WIN) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror") SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wno-unused-function -Wno-sign-compare") SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++14") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++17") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}") SET(CMAKE_EXE_LINKER_FLAGS "-static-libstdc++ -static-libgcc") SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") diff --git a/idlc/gen/generator.cc b/idlc/gen/generator.cc index 2f04cf0..cb4c290 100644 --- a/idlc/gen/generator.cc +++ b/idlc/gen/generator.cc @@ -27,13 +27,17 @@ namespace tidl { Generator::Generator(std::shared_ptr doc) : doc_(doc) {} -void Generator::Run(const std::string& file_name) { +void Generator::Run(const std::string& file_name, bool divide_interface) { FileName = file_name; - out_file_.open(FileName); - - OnInitGen(out_file_); - OnFiniGen(out_file_); - out_file_.close(); + if (!divide_interface) { + out_file_.open(FileName); + OnInitGen(out_file_); + OnFiniGen(out_file_); + out_file_.close(); + } else { + OnInitGen(out_file_); + OnFiniGen(out_file_); + } } std::string Generator::AddIndent(int indent, std::string lines, bool space) { diff --git a/idlc/gen/generator.h b/idlc/gen/generator.h index 2f50374..9eba127 100755 --- a/idlc/gen/generator.h +++ b/idlc/gen/generator.h @@ -34,7 +34,7 @@ class Generator { explicit Generator(std::shared_ptr doc); virtual ~Generator() = default; - void Run(const std::string& file_name); + void Run(const std::string& file_name, bool divide_interface = false); std::string AddIndent(int indent, std::string lines, bool space = true); std::string GetFileNamespace() const; std::string ReplaceAll(std::string str, diff --git a/idlc/gen_cion/java_cion_data_gen.cc b/idlc/gen_cion/java_cion_data_gen.cc new file mode 100644 index 0000000..170d1b4 --- /dev/null +++ b/idlc/gen_cion/java_cion_data_gen.cc @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2021 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/java_cion_data_gen.h" +#include "idlc/gen_cion/java_cion_gen_cb.h" + +#include +#include + +#include +#include +#include + +namespace tidl { + +JavaCionDataGen::JavaCionDataGen( + std::shared_ptr doc) : Generator(doc) { +} + +void JavaCionDataGen::OnInitGen(std::ofstream& stream) { + std::string fname = "./java/org/tizen/gen/" + FileName + "/data"; + if (access(fname.c_str(), F_OK) != 0) { + if (!std::filesystem::create_directories(fname)) { + std::cout << "fail to create folder " << fname << std::endl; + return; + } + } + + stream.open(fname + "/ReceivedPayloadInfo.java"); + stream << "package org.tizen.gen." << FileName + ".data;" << NLine(2); + stream << RECEIVED_PAYLOAD_INFO_CLASS; + stream.close(); + + stream.open(fname + "/ReceivedDataInfo.java"); + stream << "package org.tizen.gen." << FileName + ".data;" << NLine(2); + stream << RECEIVED_DATA_INFO_CLASS; + stream.close(); + + stream.open(fname + "/ConnectedPeer.java"); + stream << "package org.tizen.gen." << FileName + ".data;" << NLine(2); + stream << CONNECTED_PEER; + stream.close(); + + stream.open(fname + "/DiscoveredPeer.java"); + stream << "package org.tizen.gen." << FileName + ".data;" << NLine(2); + stream << DISCOVERED_PEER; + stream.close(); +} + +void JavaCionDataGen::OnFiniGen(std::ofstream& stream) { +} + +std::string JavaCionDataGen::NLine(int cnt) { + std::string t; + + for (int i = 0; i < cnt; i++) { + t += "\n"; + } + + return t; +} + +} // namespace tidl diff --git a/idlc/gen_cion/java_cion_data_gen.h b/idlc/gen_cion/java_cion_data_gen.h new file mode 100644 index 0000000..fe8c466 --- /dev/null +++ b/idlc/gen_cion/java_cion_data_gen.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 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_GEN_CION_JAVA_CION_DATA_GEN_H_ +#define IDLC_GEN_CION_JAVA_CION_DATA_GEN_H_ + +#include +#include +#include + +#include "idlc/ast/type.h" +#include "idlc/ast/structure.h" +#include "idlc/gen/generator.h" + +namespace tidl { + +class JavaCionDataGen : public Generator { + public: + explicit JavaCionDataGen(std::shared_ptr doc); + virtual ~JavaCionDataGen() = default; + + void OnInitGen(std::ofstream& stream) override; + void OnFiniGen(std::ofstream& stream) override; + std::string NLine(int cnt); +}; + +} // namespace tidl +#endif // IDLC_GEN_CION_JAVA_CION_DATA_GEN_H_ diff --git a/idlc/gen_cion/java_cion_gen_base.cc b/idlc/gen_cion/java_cion_gen_base.cc index eabea30..b828734 100644 --- a/idlc/gen_cion/java_cion_gen_base.cc +++ b/idlc/gen_cion/java_cion_gen_base.cc @@ -25,15 +25,15 @@ JavaCionGeneratorBase::JavaCionGeneratorBase(std::shared_ptr doc) : Generator(doc) { type_map_ = { {"char", "byte"}, {"int", "int"}, {"short", "short"}, - {"long", "long"}, {"string", "string"}, {"bool", "bool"}, - {"list", "LinkedList"}, {"array", "List"}, {"float", "float"}, + {"long", "long"}, {"string", "String"}, {"bool", "bool"}, + {"list", "LinkedList"}, {"array", "ArrayList"}, {"float", "float"}, {"double", "double"}, {"bundle", "Bundle"}, {"void", "void"}, - {"file", "string"} + {"file", "String"} }; - parcel_type_map_ = { + meta_type_map_ = { {"char", "Byte"}, - {"int", "Int"}, + {"int", "Integer"}, {"short", "Short"}, {"long", "Long"}, {"string", "String"}, @@ -43,6 +43,168 @@ JavaCionGeneratorBase::JavaCionGeneratorBase(std::shared_ptr doc) {"bundle", "Bundle"}, {"file", "String"} }; + + parcel_reader_map_ = { + {"char", "readByte()"}, + {"int", "readInt()"}, + {"short", "readShort()"}, + {"long", "readLong()"}, + {"string", "readString()"}, + {"bool", "readBoolean()"}, + {"float", "readFloat()"}, + {"double", "readDouble()"}, + {"bundle", "readBundle()"}, + {"file", "readString()"} + }; +} + +void JavaCionGeneratorBase::GenMethodId(std::ofstream& stream, + const Interface& iface) { + int cnt = 2; + stream << Tab(1) << "public static final int __RESULT = 0;" << NLine(1); + stream << Tab(1) << "public static final int __CALLBACK = 1;" << NLine(1); + for (auto& i : iface.GetDeclarations().GetDecls()) { + if (i->GetMethodType() == Declaration::MethodType::DELEGATE) + continue; + stream << Tab(1) + << "public static final int __" + << i->GetID() << " = " << cnt++ << ";" << NLine(1); + } +} + +void JavaCionGeneratorBase::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 JavaCionGeneratorBase::GenParameters(std::ofstream& stream, + const Parameters& ps) { + stream << GetParameters(ps); +} + +std::string JavaCionGeneratorBase::ConvertTypeToString( + const BaseType& type, bool is_meta) { + if (type.IsUserDefinedType()) + return type.ToString(); + + if (type.GetMetaType() != nullptr) + return type_map_[type.ToString()] + "<" + + ConvertTypeToString(*(type.GetMetaType()), true) + ">"; + + if (is_meta) + return meta_type_map_[type.ToString()]; + + return type_map_[type.ToString()]; +} + +std::string JavaCionGeneratorBase::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()); + if (dir == ParameterType::Direction::OUT + || dir == ParameterType::Direction::REF) + ret += ">"; + + ret += " " + i->GetID(); + first = false; + } + + return ret; +} + +std::string JavaCionGeneratorBase::GetViewModelName(std::string id) { + return id + FileName + "ViewModel"; +} + +std::string JavaCionGeneratorBase::GetRepoClassName(std::string id) { + return id + FileName + "Repo"; +} + +std::string JavaCionGeneratorBase::GetServiceBaseClassName(std::string id) { + return id + FileName + "ServiceBase"; +} + +std::string JavaCionGeneratorBase::GetParcelReader( + const BaseType& type, std::string parcel_name, + std::string variable_name, int tab_size, bool assign) { + std::string ret_str = ""; + if (type.IsUserDefinedType()) { + ret_str += Tab(tab_size) + ConvertTypeToString(type); + ret_str += " " + variable_name + " = "; + ret_str += "new " + ConvertTypeToString(type) + "();" + NLine(1); + ret_str += Tab(tab_size) + parcel_name + " = " + + variable_name + ".deserialize(" + parcel_name + ");" + NLine(1); + return ret_str; + } + + if (type.GetMetaType() != nullptr) { + ret_str += Tab(tab_size) + "int " + variable_name + "_size = " + + parcel_name + ".readInt();" + NLine(1); + ret_str += Tab(tab_size) + ConvertTypeToString(type); + ret_str += " " + variable_name + " = "; + ret_str += "new " + ConvertTypeToString(type) + "();" + NLine(1); + ret_str += Tab(tab_size) + "for (int i = 0; i < " + + variable_name + "_size; i++) {" + NLine(1); + if (type.GetMetaType()->IsUserDefinedType()) { + ret_str += GetParcelReader(*(type.GetMetaType()), + parcel_name, "temp", tab_size +1, false) + NLine(1); + ret_str += Tab(tab_size + 1) + variable_name + ".add(temp);" + NLine(1); + } else { + ret_str += Tab(tab_size + 1) + variable_name + ".add(" + + GetParcelReader(*(type.GetMetaType()), + parcel_name, variable_name, 0, false) + ");" + NLine(1); + } + ret_str += Tab(tab_size) + "}" + NLine(1); + return ret_str; + } + + if (assign) { + ret_str += Tab(tab_size) + ConvertTypeToString(type); + ret_str += " " + variable_name + " = " + parcel_name + "." + + parcel_reader_map_[type.ToString()] + ";"; + } else { + ret_str += Tab(tab_size) + parcel_name + "." + + parcel_reader_map_[type.ToString()]; + } + + return ret_str; +} + +std::string JavaCionGeneratorBase::Tab(int cnt) { + std::string t; + + for (int i = 0; i < cnt; i++) { + t += " "; + } + + return t; +} + +std::string JavaCionGeneratorBase::NLine(int cnt) { + std::string t; + + for (int i = 0; i < cnt; i++) { + t += "\n"; + } + + return t; } } // namespace tidl diff --git a/idlc/gen_cion/java_cion_gen_base.h b/idlc/gen_cion/java_cion_gen_base.h index aa17b28..3af02f6 100644 --- a/idlc/gen_cion/java_cion_gen_base.h +++ b/idlc/gen_cion/java_cion_gen_base.h @@ -31,16 +31,31 @@ class JavaCionGeneratorBase : public Generator { public: explicit JavaCionGeneratorBase(std::shared_ptr doc); virtual ~JavaCionGeneratorBase() = default; + void GenMethodId(std::ofstream& stream, + const Interface& iface); + void GenDeclaration(std::ofstream& stream, + const Declaration& decl, bool semicol); + void GenParameters(std::ofstream& stream, const Parameters& ps); + std::string ConvertTypeToString(const BaseType& type, bool is_meta = false); + std::string GetParameters(const Parameters& ps); + std::string GetParcelReader(const BaseType& type, std::string parcel_name, + std::string variable_name, int tab_size, bool assign = true); + + std::string GetRepoClassName(std::string id); + std::string GetServiceBaseClassName(std::string id); + std::string GetViewModelName(std::string id); + + std::string Tab(int cnt); + std::string NLine(int cnt); protected: const int TAB_SIZE = 4; private: std::map type_map_; - std::map parcel_type_map_; - std::map serializer_list_; + std::map meta_type_map_; + std::map parcel_reader_map_; }; } // namespace tidl - #endif // IDLC_GEN_CION_JAVA_CION_GEN_BASE_H_ diff --git a/idlc/gen_cion/java_cion_gen_cb.h b/idlc/gen_cion/java_cion_gen_cb.h new file mode 100644 index 0000000..832af7c --- /dev/null +++ b/idlc/gen_cion/java_cion_gen_cb.h @@ -0,0 +1,716 @@ +/* + * Copyright (c) 2021 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_GEN_CION_JAVA_CION_GEN_CB_H_ +#define IDLC_GEN_CION_JAVA_CION_GEN_CB_H_ + +const char DEFAULT_STUB_FUNCTIONS[] = +R"__java_cb( + + public void acceptRequest(ConnectedPeer peer) { + repo.acceptRequest(peer); + } + + public void rejectRequest(ConnectedPeer peer, String reason) { + repo.rejectRequest(peer, reason); + } + + public void disconnectPeer(ConnectedPeer peer) { + repo.disconnect(peer); + } + + public void listen() { + repo.listen(); + } + + public LiveData> getConnectedPeerLiveData() { + return connectedPeerLiveData; + } + + public LiveData getLogsLiveData() { + return logsLiveData; + } + + public LiveData getReceivedDataLiveData() { + return receivedDataLiveData; + } + + public LiveData getReceivedPayloadLiveData() { + return receivedPayloadLiveData; + } + + public void setSyncResponse(byte[] data) { + repo.setSyncResponse(data); + } + + public void registerService(## service) { + this.service = service; + } + +)__java_cb"; + + +const char DEFAULT_PROXY_FUNCTIONS[] = +R"__java_cb( + private void sendAsync(FilePayload payload) { + repo.sendAsync(payload); + } + + private void sendAsync(DataPayload payload) { + repo.sendAsync(payload); + } + + private byte[] sendData(byte[] data) { + return repo.sendData(data); + } + + public void tryDiscovery() { + repo.tryDiscovery(); + } + + public void tryConnect(DiscoveredPeer peer) { + repo.tryConnect(peer); + } + + public void disconnect(DiscoveredPeer peer) { + repo.disconnect(peer); + } + + public LiveData> getDiscoveredPeerLiveData() { + return discoveredPeerLiveData; + } + + public LiveData getReceivedPayloadInfoLiveData() { + return receivedPayloadInfoLiveData; + } + + public void processReceivedEvent(CionParcel parcel) { + int method = parcel.readInt(); + if (method != __CALLBACK) + return; + + int id = parcel.readInt(); + int seq_id = parcel.readInt(); + boolean once = (parcel.readByte() == 1); + for (int i = 0; i < delegators.size(); i++) { + if (id == delegators.get(i).getDelegateId() + && seq_id == delegators.get(i).getSequenceId()) { + delegators.get(i).onInvoked(parcel); + if (once) + delegators.remove(i); + break; + } + } + } + + public LiveData getLogsLiveData() { + return logsLiveData; + } +)__java_cb"; + +const char DEFAULT_PROXY_REPO[] = +R"__java_cb( + +import android.content.Context; +import androidx.lifecycle.MutableLiveData; + +import org.tizen.cion.ClientChannel; +import org.tizen.cion.ClientConnectionLifecycleCallback; +import org.tizen.cion.ConnectionResult; +import org.tizen.cion.DataPayload; +import org.tizen.cion.DiscoveryCallback; +import org.tizen.cion.FilePayload; +import org.tizen.cion.IPayload; +import org.tizen.cion.PayloadAsyncResult; +import org.tizen.cion.PayloadAsyncResultCallback; +import org.tizen.cion.PayloadTransferStatus; +import org.tizen.cion.PeerInfo; + +import java.net.SocketTimeoutException; +import java.util.ArrayList; + +public class ## { + private ClientChannel client; + private MutableLiveData> discoveredPeerLiveData; + private MutableLiveData receivedPayloadInfoLiveData; + private static volatile ## instance; + private Context context; + private MutableLiveData logsLiveData; + + private ##(Context context, String serviceName) { + discoveredPeerLiveData = new MutableLiveData<>(); + discoveredPeerLiveData.setValue(new ArrayList()); + logsLiveData = new MutableLiveData<>(); + logsLiveData.setValue(""); + client = new ClientChannel(context, serviceName); + this.context = context; + } + + public static ## getInstance(Context context, String serviceName) { + if (instance == null) { + synchronized (##.class) { + instance = new ##(context, serviceName); + } + } + return instance; + } + + public void disconnect(DiscoveredPeer peer) { + client.disconnect(); + } + + public void writeLog(String log) { + String logs = logsLiveData.getValue(); + if (!logs.isEmpty()) + logs += "\n"; + logs += log; + logsLiveData.postValue(logs); + } + + public void tryConnect(DiscoveredPeer peer) { + client.tryConnect(peer.getPeerInfo(), new ClientConnectionLifecycleCallback() { + @Override + public void onConnectionResult(PeerInfo info, ConnectionResult result) { + writeLog("Peer : " + info.getUuid() + ", Connection result : " + result); + ArrayList peers = discoveredPeerLiveData.getValue(); + for (int i = 0; i < peers.size(); i++) { + if (peers.get(i).equals(peer)) { + peer.setIsConnected(result.status == ConnectionResult.ConnectionStatus.CONNECTION_OK); + peers.set(i, peer); + break; + } + } + discoveredPeerLiveData.postValue(peers); + } + + @Override + public void onDisconnected(PeerInfo info) { + writeLog("Peer disconnected : " + info.getUuid()); + ArrayList peers = discoveredPeerLiveData.getValue(); + for (int i = 0; i < peers.size(); i++) { + if (peers.get(i).getPeerInfo().getUuid() == info.getUuid()) { + peer.setIsConnected(false); + peers.set(i, peer); + break; + } + } + discoveredPeerLiveData.postValue(peers); + } + + @Override + public void onPayloadReceived(IPayload data, PayloadTransferStatus status) { + writeLog("onPayloadReceived " + status); + receivedPayloadInfoLiveData.postValue(new ReceivedPayloadInfo(data, status)); + } + }); + } + + public void tryDiscovery() { + writeLog("Try discovery !!"); + client.tryDiscovery(new DiscoveryCallback() { + @Override + public void onDiscovered(PeerInfo info) { + ArrayList peers = discoveredPeerLiveData.getValue(); + peers.add(new DiscoveredPeer(info, false)); + discoveredPeerLiveData.postValue(peers); + writeLog("Peer discovered :" + info.getUuid()); + } + }); + } + + public void sendAsync(DataPayload payload) { + client.sendPayloadAsync(payload, new PayloadAsyncResultCallback() { + @Override + public void onResultReceived(PayloadAsyncResult result) { + writeLog("Async result " + result.toString()); + } + }); + } + + public void sendAsync(FilePayload payload) { + client.sendPayloadAsync(payload, new PayloadAsyncResultCallback() { + @Override + public void onResultReceived(PayloadAsyncResult result) { + writeLog("Async result " + result.toString()); + } + }); + } + + public byte[] sendData(byte[] data) { + try { + return client.sendData(data, 5000); + } catch (SocketTimeoutException e) { + e.printStackTrace(); + } + return null; + } + + public MutableLiveData> getDiscoveredPeerLiveData() { + return discoveredPeerLiveData; + } + + public MutableLiveData getReceivedPayloadInfoLiveData() { + return receivedPayloadInfoLiveData; + } + + public MutableLiveData getLogsLiveData() { + return logsLiveData; + } +} + +)__java_cb"; + +const char DEFAULT_STUB_REPO[] = +R"__java_cb( +import android.content.Context; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; + +import org.tizen.cion.ConnectionResult; +import org.tizen.cion.DataPayload; +import org.tizen.cion.IPayload; +import org.tizen.cion.PayloadAsyncResult; +import org.tizen.cion.PayloadAsyncResultCallback; +import org.tizen.cion.PayloadTransferStatus; +import org.tizen.cion.PeerInfo; +import org.tizen.cion.ServerChannel; +import org.tizen.cion.ServerConnectionLifecycleCallback; + +import java.util.ArrayList; +import java.util.concurrent.BlockingDeque; +import java.util.concurrent.TimeUnit; + +public class ## { + private ServerChannel server; + private MutableLiveData> connectedPeerLiveData; + private MutableLiveData receivedPayloadInfoLiveData; + private MutableLiveData receivedDataInfoLiveData; + private static volatile ## instance; + private Context context; + private MutableLiveData logsLiveData; + private BlockingDeque syncCallRespQue; + + private ##(Context context, String serviceName, String displayName) { + connectedPeerLiveData = new MutableLiveData<>(); + connectedPeerLiveData.setValue(new ArrayList()); + logsLiveData = new MutableLiveData<>(); + logsLiveData.setValue(""); + server = new ServerChannel(context, serviceName, displayName); + this.context = context; + } + + public LiveData getReceivedDataInfoLiveData() { + return receivedDataInfoLiveData; + } + + public LiveData getReceivedPayloadInfoLiveData() { + return receivedPayloadInfoLiveData; + } + + public void writeLog(String log) { + String logs = logsLiveData.getValue(); + if (!logs.isEmpty()) + logs += "\n"; + logs += log; + logsLiveData.postValue(logs); + } + + public static ## getInstance( + Context context, String serviceName, String displayName) { + if (instance == null) { + synchronized (##.class) { + instance = new ##(context, serviceName, displayName); + } + } + return instance; + } + + public void setSyncResponse(byte[] response) { + try { + syncCallRespQue.offer(response, 5000, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public void acceptRequest(ConnectedPeer peer) { + ArrayList peers = connectedPeerLiveData.getValue(); + for (int i = 0; i < peers.size(); i++) { + if (peers.get(i).equals(peer)) { + peer.setIsConnected(true); + peers.set(i, peer); + writeLog("Accept peer: " + peer.isConnected()); + break; + } + } + connectedPeerLiveData.postValue(peers); + server.acceptRequest(peer.getPeerInfo()); + writeLog("Accept peer: " + peer.isConnected()); + } + + public void rejectRequest(ConnectedPeer peer, String reason) { + ArrayList peers = connectedPeerLiveData.getValue(); + for (int i = 0; i < peers.size(); i++) { + if (peers.get(i).equals(peer)) { + peer.setIsConnected(false); + peers.set(i, peer); + break; + } + } + connectedPeerLiveData.postValue(peers); + server.rejectRequest(peer.getPeerInfo(), reason); + writeLog("Reject peer: " + peer.isConnected()); + } + + public void disconnect(ConnectedPeer peer) { + ArrayList peers = connectedPeerLiveData.getValue(); + for (int i = 0; i < peers.size(); i++) { + if (peers.get(i).equals(peer)) { + peer.setIsConnected(false); + peers.set(i, peer); + break; + } + } + connectedPeerLiveData.postValue(peers); + server.disconnect(peer.getPeerInfo()); + writeLog("Disconnect peer: " + peer.isConnected()); + } + + public void listen() { + server.listen(new ServerConnectionLifecycleCallback() { + @Override + public void onConnectionRequest(PeerInfo info) { + writeLog("OnConnection request from " + info.getUuid()); + ArrayList peers = connectedPeerLiveData.getValue(); + peers.add(new ConnectedPeer(info, false)); + connectedPeerLiveData.postValue(peers); + } + + @Override + public void onConnectionResult(PeerInfo info, ConnectionResult result) { + writeLog("OnConnectionResult " + result + ", uuid :" + info.getUuid()); + writeLog("Connection result: " + info.getDeviceName() + " : " + result.status); + } + + @Override + public void onPayloadReceived(PeerInfo info, IPayload data, PayloadTransferStatus status) { + writeLog("onPayloadReceived " + status + ", uuid :" + info.getUuid()); + receivedPayloadInfoLiveData.postValue(new ReceivedPayloadInfo(info, data, status)); + } + + @Override + public byte[] onDataReceived(PeerInfo info, byte[] data) { + writeLog("Payload received : " + new String(data)); + writeLog("onDataReceived length : " + data.length + ", uuid :" + info.getUuid()); + receivedDataInfoLiveData.postValue(new ReceivedDataInfo(info, data)); + byte[] ret = null; + try { + // block until response data is filled + ret = syncCallRespQue.take(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return ret; + } + }); + writeLog("Listen start"); + } + + public MutableLiveData> getConnectedPeerLiveData() { + return connectedPeerLiveData; + } + + public MutableLiveData getLogsLiveData() { + return logsLiveData; + } + + public void sendAsync(DataPayload payload) { + server.sendPayloadAsync(payload, new PayloadAsyncResultCallback() { + @Override + public void onResultReceived(PayloadAsyncResult result) { + writeLog("Async result " + result.toString()); + } + }); + } +} + +)__java_cb"; + +const char OUT_CLASS[] = +R"__java_cb( + +public class Out { + T s; + public void set(T value){ + s = value; + } + + public T get(){ + return s; + } + + public Out() { + } +} + +)__java_cb"; + +const char REF_CLASS[] = +R"__java_cb( + +class Ref { + T s; + public void set(T value) { + s = value; + } + + public T get() { + return s; + } + + public Ref(T value) { + s = value; + } +} + +)__java_cb"; + +const char RECEIVED_PAYLOAD_INFO_CLASS[] = +R"__java_cb( + +import org.tizen.cion.IPayload; +import org.tizen.cion.PayloadTransferStatus; +import org.tizen.cion.PeerInfo; + +public class ReceivedPayloadInfo { + private PeerInfo info; + private IPayload data; + private PayloadTransferStatus status; + + public ReceivedPayloadInfo(PeerInfo info, IPayload data, PayloadTransferStatus status) { + this.info = info; + this.data = data; + this.status = status; + } + + public ReceivedPayloadInfo(IPayload data, PayloadTransferStatus status) { + this.data = data; + this.status = status; + } + + public PeerInfo getInfo() { + return info; + } + + public IPayload getData() { + return data; + } + + public PayloadTransferStatus getStatus() { + return status; + } +} + +)__java_cb"; + +const char RECEIVED_DATA_INFO_CLASS[] = +R"__java_cb( + +import org.tizen.cion.PeerInfo; + +public class ReceivedDataInfo { + private PeerInfo info; + private byte[] data; + + public ReceivedDataInfo(PeerInfo info, byte[] data) { + this.info = info; + this.data = data; + } + + public PeerInfo getInfo() { + return info; + } + public byte[] getData() { + return data; + } +} + +)__java_cb"; + + +const char PROXY_DELEGATOR_TOP[] = +R"__java_cb( + +import org.tizen.cion.CionParcel; + +public abstract class ProxyDelegator { + private int delegateId; + private boolean once; + private static int sequenceId = 0; + + )__java_cb"; + +const char PROXY_DELEGATOR_BOTTOM[] = +R"__java_cb( + public ProxyDelegator(int delegateId, boolean once) { + this.delegateId = delegateId; + this.once = once; + this.sequenceId++; + } + public abstract void onInvoked(CionParcel parcel); + + public int getDelegateId() { + return delegateId; + } + + public boolean isOnce() { + return once; + } + + public int getSequenceId() { + return sequenceId; + } + + public CionParcel serialize(CionParcel parcel) { + parcel.write(delegateId); + parcel.write(once); + parcel.write(sequenceId); + return parcel; + } +} + +)__java_cb"; + +const char CONNECTED_PEER[] = +R"__java_cb( +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.tizen.cion.PeerInfo; + +public final class ConnectedPeer { + + @NonNull + private final PeerInfo info; + + @NonNull + private boolean isConnected; + + public ConnectedPeer(@NonNull PeerInfo info, @NonNull boolean isConnected) { + this.info = info; + this.isConnected = isConnected; + } + + public void setIsConnected(boolean isConnected) { this.isConnected = isConnected; } + + public boolean isConnected() { return isConnected; } + + public PeerInfo getPeerInfo() { return info; } + + public String getPeerDeviceName() { + return info.getDeviceName(); + } + + public String getPeerDevicePlatform() { + return info.getDevicePlatform(); + } + + public int getPeerChannelId() { + return info.getChannelId(); + } + + @NonNull + @Override + public String toString() { + return info.getUuid(); + } + + @Override + public boolean equals(@Nullable Object obj) { + return obj instanceof ConnectedPeer + && this.info.getUuid().equals(((ConnectedPeer) obj).info.getUuid()); + } + + @Override + protected Object clone() { + return new DiscoveredPeer(info, isConnected); + } +} + +)__java_cb"; + + +const char DISCOVERED_PEER[] = +R"__java_cb( +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.tizen.cion.PeerInfo; + +public final class DiscoveredPeer { + + @NonNull + private final PeerInfo info; + + @NonNull + private boolean isConnected; + + public DiscoveredPeer(@NonNull PeerInfo info, @NonNull boolean isConnected) { + this.info = info; + this.isConnected = isConnected; + } + + public void setIsConnected(boolean isConnected) { this.isConnected = isConnected; } + + public boolean isConnected() { return isConnected; } + + public PeerInfo getPeerInfo() { return info; } + + public String getPeerDeviceName() { + return info.getDeviceName(); + } + + public String getPeerDevicePlatform() { + return info.getDevicePlatform(); + } + + public int getPeerChannelId() { + return info.getChannelId(); + } + + @NonNull + @Override + public String toString() { + return info.getUuid(); + } + + @Override + public boolean equals(@Nullable Object obj) { + return obj instanceof DiscoveredPeer + && this.info.getUuid().equals(((DiscoveredPeer) obj).info.getUuid()); + } + + @Override + protected Object clone() { + return new DiscoveredPeer(info, isConnected); + } +} + +)__java_cb"; + + +#endif // IDLC_GEN_CION_JAVA_CION_GEN_CB_H_ diff --git a/idlc/gen_cion/java_cion_interface_gen.cc b/idlc/gen_cion/java_cion_interface_gen.cc new file mode 100644 index 0000000..139f0b7 --- /dev/null +++ b/idlc/gen_cion/java_cion_interface_gen.cc @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2021 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/java_cion_interface_gen.h" +#include "idlc/gen_cion/java_cion_gen_cb.h" + +#include +#include + +#include +#include +#include + +namespace tidl { + +JavaCionInterfaceGen::JavaCionInterfaceGen( + std::shared_ptr doc) : JavaCionGeneratorBase(doc) { +} + +void JavaCionInterfaceGen::OnInitGen(std::ofstream& stream) { + std::string fname = "./java/org/tizen/gen/" + FileName + "/interfaces"; + if (access(fname.c_str(), F_OK) != 0) { + if (!std::filesystem::create_directories(fname)) { + std::cout << "fail to create folder " << fname << std::endl; + return; + } + } + + stream.open(fname + "/ProxyDelegator.java"); + stream << "package org.tizen.gen." << FileName + ".interfaces;" << NLine(1); + stream << PROXY_DELEGATOR_TOP; + GenDelegateId(stream); + stream << PROXY_DELEGATOR_BOTTOM; + stream.close(); +} + +void JavaCionInterfaceGen::GenDelegateId(std::ofstream& stream) { + int id = 0; + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() != Block::TYPE_INTERFACE) + continue; + + Interface& iface = static_cast(*i); + for (auto& d : iface.GetDeclarations().GetDecls()) { + if (d->GetMethodType() != Declaration::MethodType::DELEGATE) + continue; + + stream << Tab(1) << "public static final int " << + i->GetID() << "_" << d->GetID() << "__ = " << id++ << ";" << NLine(1); + } + } +} + + +void JavaCionInterfaceGen::OnFiniGen(std::ofstream& stream) { +} + +std::string JavaCionInterfaceGen::NLine(int cnt) { + std::string t; + + for (int i = 0; i < cnt; i++) { + t += "\n"; + } + + return t; +} + +} // namespace tidl diff --git a/idlc/gen_cion/java_cion_interface_gen.h b/idlc/gen_cion/java_cion_interface_gen.h new file mode 100644 index 0000000..45c6a85 --- /dev/null +++ b/idlc/gen_cion/java_cion_interface_gen.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 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_GEN_CION_JAVA_CION_INTERFACE_GEN_H_ +#define IDLC_GEN_CION_JAVA_CION_INTERFACE_GEN_H_ + +#include +#include +#include + +#include "idlc/gen_cion/java_cion_gen_base.h" + +namespace tidl { + +class JavaCionInterfaceGen : public JavaCionGeneratorBase { + public: + explicit JavaCionInterfaceGen(std::shared_ptr doc); + virtual ~JavaCionInterfaceGen() = default; + + void OnInitGen(std::ofstream& stream) override; + void OnFiniGen(std::ofstream& stream) override; + void GenDelegateId(std::ofstream& stream); + std::string NLine(int cnt); +}; + +} // namespace tidl +#endif // IDLC_GEN_CION_JAVA_CION_INTERFACE_GEN_H_ diff --git a/idlc/gen_cion/java_cion_proxy_gen.cc b/idlc/gen_cion/java_cion_proxy_gen.cc new file mode 100644 index 0000000..d6eec47 --- /dev/null +++ b/idlc/gen_cion/java_cion_proxy_gen.cc @@ -0,0 +1,212 @@ +/* + * 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 "idlc/gen_cion/java_cion_proxy_gen.h" +#include "idlc/gen_cion/java_cion_gen_cb.h" + +#include +#include + +#include +#include + +namespace tidl { + +JavaCionProxyGen::JavaCionProxyGen(std::shared_ptr doc) + : JavaCionGeneratorBase(doc) {} + +void JavaCionProxyGen::OnInitGen(std::ofstream& stream) { + std::string fname = "./java/org/tizen/gen/" + FileName + "/viewmodel"; + if (access(fname.c_str(), F_OK) != 0) { + if (!std::filesystem::create_directories(fname)) { + std::cout << "fail to create folder " << fname << std::endl; + return; + } + } + + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() != Block::TYPE_INTERFACE) + continue; + + Interface& iface = static_cast(*i); + stream.open(fname + "/" + GetViewModelName(i->GetID()) + ".java"); + stream << "package org.tizen.gen." << FileName << ".viewmodel;" << NLine(1); + stream << NLine(1); + stream << "import androidx.lifecycle.LiveData;" << NLine(1); + stream << "import androidx.lifecycle.ViewModel;" << NLine(1); + stream << "import org.tizen.cion.CionParcel;" << NLine(1); + stream << "import org.tizen.cion.DataPayload;" << NLine(1); + stream << "import org.tizen.cion.FilePayload;" << NLine(1); + stream << "import java.util.ArrayList;" << NLine(1); + stream << NLine(1); + GenInterface(stream, iface); + stream.close(); + } +} + +void JavaCionProxyGen::OnFiniGen(std::ofstream& stream) { +} + +void JavaCionProxyGen::GenInterface( + std::ofstream& stream, const Interface& iface) { + stream << "public class " << GetViewModelName(iface.GetID()) + << " extends ViewModel " << NLine(1); + GenBrace(stream, TAB_SIZE * 0, [&]() { + stream << Tab(1) << "private " << GetRepoClassName(iface.GetID()) + << " repo; " << NLine(1); + stream << Tab(1) << + "private LiveData> discoveredPeerLiveData;" + << NLine(1); + stream << Tab(1) << "private LiveData logsLiveData;" << NLine(1); + stream << Tab(1) + << "private LiveData receivedPayloadInfoLiveData;" + << NLine(1); + stream << Tab(1) << "private ArrayList delegators;" << NLine(1); + stream << NLine(1); + GenCtor(stream, iface); + GenMethodId(stream, iface); + GenMethods(stream, iface); + stream << DEFAULT_PROXY_FUNCTIONS; + stream << NLine(1); + }); +} + +void JavaCionProxyGen::GenMethods( + std::ofstream& stream, const Interface& iface) { + auto& decls = iface.GetDeclarations(); + + for (auto& i : decls.GetDecls()) { + if (i->GetMethodType() == Declaration::MethodType::DELEGATE) + continue; + + if (!i->GetComments().empty()) + stream << AddIndent(TAB_SIZE * 1, i->GetComments()); + + stream << Tab(1) << "public "; + GenDeclaration(stream, *i, false); + stream << " throws IOException "; + GenBrace(stream, TAB_SIZE * 1, [&]() { + GenInvocation(stream, *i); + }, false); + stream << NLine(1); + } +} + +void JavaCionProxyGen::GenInvocation( + std::ofstream& stream, const Declaration& decl) { + stream << Tab(2) << "CionParcel parcel = new CionParcel();"; + stream << NLine(1); + stream << Tab(2) << "parcel.write(__" << decl.GetID() << ");"; + stream << NLine(1); + for (auto& i : decl.GetParameters().GetParams()) { + auto& pt = i->GetParameterType(); + if (pt.GetDirection() == ParameterType::Direction::OUT || + pt.GetDirection() == ParameterType::Direction::REF) + continue; + + if (pt.GetBaseType().IsUserDefinedType()) + stream << Tab(2) << "parcel = " << i->GetID() << ".serialize(parcel);"; + else + stream << Tab(2) << "parcel.write(" << i->GetID() << ");"; + stream << NLine(1); + } + + if (decl.GetMethodType() == Declaration::MethodType::SYNC) { + stream << Tab(2) + << "byte[] ret = sendData(parcel.toByteArray());" << NLine(1); + stream << Tab(2) + << "CionParcel ret_parcel = new CionParcel(ret);" << NLine(1); + stream << Tab(2) << "int cmd = ret_parcel.readInt();" << NLine(1); + stream << Tab(2) << "if (cmd != __RESULT)" << NLine(1); + stream << Tab(3) << "throw new IOException();" << NLine(1); + + for (auto& i : decl.GetParameters().GetParams()) { + auto& pt = i->GetParameterType(); + if (pt.GetDirection() != ParameterType::Direction::OUT && + pt.GetDirection() != ParameterType::Direction::REF) + continue; + if (pt.GetBaseType().IsUserDefinedType()) { + if (pt.GetDirection() == ParameterType::Direction::OUT) { + stream << Tab(2) << i->GetID() << ".set(new " + << pt.GetBaseType().ToString() << "());" << NLine(1); + + stream << Tab(2) << "ret_parcel = " << i->GetID() + << ".get().deserialize(ret_parcel);" << NLine(1); + } else { + stream << Tab(2) << "ret_parcel = " << i->GetID() + << ".get().deserialize(ret_parcel);" << NLine(1); + } + } else { + stream << Tab(2) << i->GetID() + << ".set(" << i->GetID() << ".read" + << ConvertTypeToString(pt.GetBaseType(), true) + << "());" << NLine(1); + } + stream << NLine(1); + } + + if (decl.GetType().IsUserDefinedType()) { + stream << Tab(2) << decl.GetType().ToString() + << " ret_val = new " << decl.GetType().ToString() + << "();" << NLine(1); + stream << Tab(2) << "ret_val.deserialize(ret_parcel);" << NLine(1); + stream << Tab(2) << "return ret_val;" << NLine(1); + } else { + stream << Tab(2) << ConvertTypeToString(decl.GetType()) + << " ret_val = ret_parcel.read" + << ConvertTypeToString(decl.GetType(), true) + << "();" << NLine(1); + stream << Tab(2) << "return ret_val;" << NLine(1); + } + } else { + stream << Tab(2) << + "sendAsync(new DataPayload(parcel.toByteArray()));" << NLine(1); + } + + for (auto& i : decl.GetParameters().GetParams()) { + auto& pt = i->GetParameterType(); + if (pt.GetDirection() == ParameterType::Direction::OUT || + pt.GetDirection() == ParameterType::Direction::REF) + continue; + + if (pt.GetBaseType().ToString() == "file") { + stream << NLine(1); + stream << Tab(2) << "FilePayload " << i->GetID() + << "Payload = new FilePayload();" << NLine(1); + stream << Tab(2) << i->GetID() << "Payload.setFilePath(" + << i->GetID() << ");" << NLine(1); + stream << Tab(2) << "sendAsync(" << i->GetID() << "Payload);" << NLine(1); + } + } +} + +void JavaCionProxyGen::GenCtor(std::ofstream& stream, const Interface& iface) { + stream << Tab(1) << "public " << GetViewModelName(iface.GetID()) << + "(" << GetRepoClassName(iface.GetID()) << " repo) "; + GenBrace(stream, TAB_SIZE * 1, [&]() { + stream << Tab(2) << "super();" << NLine(1); + stream << Tab(2) << "this.repo = repo;" << NLine(1); + stream << Tab(2) << + "discoveredPeerLiveData = repo.getDiscoveredPeerLiveData();" + << NLine(1); + stream << Tab(2) << + "receivedPayloadInfoLiveData = repo.getReceivedPayloadInfoLiveData();" + << NLine(1); + stream << Tab(2) << "logsLiveData = repo.getLogsLiveData();" << NLine(1); + }); +} + +} // namespace tidl diff --git a/idlc/gen_cion/java_cion_proxy_gen.h b/idlc/gen_cion/java_cion_proxy_gen.h new file mode 100644 index 0000000..5e7e152 --- /dev/null +++ b/idlc/gen_cion/java_cion_proxy_gen.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 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_GEN_CION_JAVA_CION_PROXY_GEN_H_ +#define IDLC_GEN_CION_JAVA_CION_PROXY_GEN_H_ + +#include +#include + +#include "idlc/gen_cion/java_cion_gen_base.h" + +namespace tidl { + +class JavaCionProxyGen : public JavaCionGeneratorBase { + public: + explicit JavaCionProxyGen(std::shared_ptr doc); + virtual ~JavaCionProxyGen() = default; + + void OnInitGen(std::ofstream& stream) override; + void OnFiniGen(std::ofstream& stream) override; + + private: + void GenNamespace(std::ofstream& stream); + void GenInterface(std::ofstream& stream, const Interface& iface); + void GenCtor(std::ofstream& stream, const Interface& iface); + void GenMethods(std::ofstream& stream, const Interface& iface); + void GenInvocation(std::ofstream& stream, const Declaration& decl); +}; + +} // namespace tidl + +#endif // IDLC_GEN_CION_JAVA_CION_PROXY_GEN_H_ diff --git a/idlc/gen_cion/java_cion_proxy_repo_gen.cc b/idlc/gen_cion/java_cion_proxy_repo_gen.cc new file mode 100644 index 0000000..2b741a3 --- /dev/null +++ b/idlc/gen_cion/java_cion_proxy_repo_gen.cc @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 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/java_cion_proxy_repo_gen.h" +#include "idlc/gen_cion/java_cion_gen_cb.h" + +#include +#include + +#include +#include +#include + +namespace tidl { + +JavaCionProxyRepoGen::JavaCionProxyRepoGen( + std::shared_ptr doc) : JavaCionGeneratorBase(doc) { +} + +void JavaCionProxyRepoGen::OnInitGen(std::ofstream& stream) { + std::string fname = "./java/org/tizen/gen/" + FileName + "/data"; + if (access(fname.c_str(), F_OK) != 0) { + if (!std::filesystem::create_directories(fname)) { + std::cout << "fail to create folder " << fname << std::endl; + return; + } + } + + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() != Block::TYPE_INTERFACE) + continue; + + stream.open(fname + "/" + GetRepoClassName(i->GetID()) + ".java"); + stream << "package org.tizen.gen." << FileName + ".data;" << NLine(2); + stream << ReplaceAll(DEFAULT_PROXY_REPO, "##", GetRepoClassName(i->GetID())) + << NLine(1); + stream.close(); + } +} + +void JavaCionProxyRepoGen::OnFiniGen(std::ofstream& stream) { +} + +std::string JavaCionProxyRepoGen::NLine(int cnt) { + std::string t; + + for (int i = 0; i < cnt; i++) { + t += "\n"; + } + + return t; +} + +} // namespace tidl diff --git a/idlc/gen_cion/java_cion_proxy_repo_gen.h b/idlc/gen_cion/java_cion_proxy_repo_gen.h new file mode 100644 index 0000000..fc9d697 --- /dev/null +++ b/idlc/gen_cion/java_cion_proxy_repo_gen.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 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_GEN_CION_JAVA_CION_PROXY_REPO_GEN_H_ +#define IDLC_GEN_CION_JAVA_CION_PROXY_REPO_GEN_H_ + +#include +#include +#include + +#include "idlc/gen_cion/java_cion_gen_base.h" + +namespace tidl { + +class JavaCionProxyRepoGen : public JavaCionGeneratorBase { + public: + explicit JavaCionProxyRepoGen(std::shared_ptr doc); + virtual ~JavaCionProxyRepoGen() = default; + + void OnInitGen(std::ofstream& stream) override; + void OnFiniGen(std::ofstream& stream) override; + std::string NLine(int cnt); +}; + +} // namespace tidl +#endif // IDLC_GEN_CION_JAVA_CION_PROXY_REPO_GEN_H_ diff --git a/idlc/gen_cion/java_cion_structure_gen.cc b/idlc/gen_cion/java_cion_structure_gen.cc new file mode 100644 index 0000000..3609423 --- /dev/null +++ b/idlc/gen_cion/java_cion_structure_gen.cc @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2021 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/java_cion_structure_gen.h" +#include "idlc/gen_cion/java_cion_gen_cb.h" + +#include +#include + +#include +#include +#include + +namespace tidl { + +JavaCionStructureGen::JavaCionStructureGen( + std::shared_ptr doc) : JavaCionGeneratorBase(doc) { +} + +void JavaCionStructureGen::OnInitGen(std::ofstream& stream) { + std::string fname = "./java/org/tizen/gen/" + FileName + "/data"; + if (access(fname.c_str(), F_OK) != 0) { + if (!std::filesystem::create_directories(fname)) { + std::cout << "fail to create folder " << fname << std::endl; + return; + } + } + + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() != Block::TYPE_STRUCTURE) + continue; + Structure& st = static_cast(*i); + stream.open(fname + "/" + st.GetID() + ".java"); + stream << "package org.tizen.gen." << FileName + ".data;" << NLine(2); + GenStructure(stream, st); + stream << std::endl; + stream.close(); + } +} + +void JavaCionStructureGen::GenStructure(std::ofstream& stream, + const Structure& st) { + const char variable[] = "$$\n"; + + stream << "import org.tizen.cion.CionParcel;" << NLine(1); + stream << "import java.util.ArrayList;" << NLine(1); + stream << "import java.util.LinkedList;" << NLine(1); + stream << NLine(1); + stream << "public class " << st.GetID() << " "; + GenBrace(stream, 0, [&]() { + stream << NLine(1); + for (auto& i : st.GetElements().GetElms()) { + GenSetter(stream, *i); + GenGetter(stream, *i); + stream << NLine(1); + } + + GenSerializer(stream, st); + stream << NLine(1); + GenDeserializer(stream, st); + + GenTemplate(variable, stream, + [&]()->std::string { + std::string str; + for (auto& i : st.GetElements().GetElms()) { + str += NLine(1) + Tab(1); + if (i->GetType().GetMetaType() == nullptr) { + str += ConvertTypeToString(i->GetType()) + " " + + i->GetID() + "_;"; + } else { + str += ConvertTypeToString(i->GetType()) + " " + + i->GetID() + "_ = new " + + ConvertTypeToString(i->GetType()) + "();"; + } + } + str += NLine(1); + return str; + }); + }, false, false); + stream << NLine(1); +} + +void JavaCionStructureGen::GenSerializer(std::ofstream& stream, + const Structure& st) { + + stream << Tab(1) << "public CionParcel serialize(CionParcel parcel) "; + GenBrace(stream, TAB_SIZE * 1, [&]() { + for (auto& i : st.GetElements().GetElms()) { + stream << NLine(1); + if (i->GetType().GetMetaType() == nullptr) { + stream << Tab(2) << "parcel.write(" + i->GetID() + "_);" + NLine(1); + } else { + stream << Tab(2) << + "parcel.write(" + i->GetID() + "_.size());" + NLine(1); + stream << Tab(2) << "for (int i = 0; i < " + i->GetID() + + "_.size(); i++) {" + NLine(1); + if (!i->GetType().GetMetaType()->IsUserDefinedType()) { + stream << Tab(3) + "parcel.write(" + i->GetID() + "_.get(i)." + + ConvertTypeToString(*i->GetType().GetMetaType()) + + "Value());" + NLine(1); + } else { + stream << Tab(3) + "parcel = " + i->GetID() + + "_.get(i).serialize(parcel);" + NLine(1); + } + stream << Tab(2) << "}" + NLine(1); + } + } + stream << Tab(2) << "return parcel;" + NLine(1); + }, false, false); + stream << NLine(1); +} + +void JavaCionStructureGen::GenDeserializer(std::ofstream& stream, + const Structure& st) { + std::string parcel_name = "parcel"; + stream << Tab(1) << "public CionParcel deserialize(CionParcel " + << parcel_name << ") "; + GenBrace(stream, TAB_SIZE * 1, [&]() { + for (auto& i : st.GetElements().GetElms()) { + stream << NLine(1); + stream << GetParcelReader(i->GetType(), + parcel_name, i->GetID(), 2) + NLine(1); + } + stream << Tab(2) << "return " << parcel_name << ";" + NLine(1); + }, false, false); + stream << NLine(1); +} + +void JavaCionStructureGen::GenSetter(std::ofstream& stream, + const Element& ele) { + const char setter[] = + "public void Set$$($$ $$) {\n" \ + " $$_ = $$;\n" \ + "}\n"; + + GenTemplate(AddIndent(TAB_SIZE, setter, true), stream, + [&]()->std::string { + return ele.GetID(); + }, + [&]()->std::string { + return ConvertTypeToString(ele.GetType()); + }, + [&]()->std::string { + return ele.GetID(); + }, + [&]()->std::string { + return ele.GetID(); + }, + [&]()->std::string { + return ele.GetID(); + }); + stream << NLine(1); +} + +void JavaCionStructureGen::GenGetter(std::ofstream& stream, + const Element& ele) { + const char getter[] = + "public $$ Get$$() {\n" \ + " return $$_;\n" \ + "}\n"; + + GenTemplate(AddIndent(TAB_SIZE, getter, true), stream, + [&]()->std::string { + return ConvertTypeToString(ele.GetType()); + }, + [&]()->std::string { + return ele.GetID(); + }, + [&]()->std::string { + return ele.GetID(); + }); +} + +void JavaCionStructureGen::OnFiniGen(std::ofstream& stream) { +} + +std::string JavaCionStructureGen::NLine(int cnt) { + std::string t; + + for (int i = 0; i < cnt; i++) { + t += "\n"; + } + + return t; +} + +} // namespace tidl diff --git a/idlc/gen_cion/java_cion_structure_gen.h b/idlc/gen_cion/java_cion_structure_gen.h new file mode 100644 index 0000000..7c87b2c --- /dev/null +++ b/idlc/gen_cion/java_cion_structure_gen.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 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_GEN_CION_JAVA_CION_STRUCTURE_GEN_H_ +#define IDLC_GEN_CION_JAVA_CION_STRUCTURE_GEN_H_ + +#include +#include +#include + +#include "idlc/gen_cion/java_cion_gen_base.h" + +namespace tidl { + +class JavaCionStructureGen : public JavaCionGeneratorBase { + public: + explicit JavaCionStructureGen(std::shared_ptr doc); + virtual ~JavaCionStructureGen() = default; + + void OnInitGen(std::ofstream& stream) override; + void OnFiniGen(std::ofstream& stream) override; + void GenStructure(std::ofstream& stream, + const Structure& st); + void GenSetter(std::ofstream& stream, const Element& ele); + void GenGetter(std::ofstream& stream, const Element& ele); + void GenSerializer(std::ofstream& stream, + const Structure& st); + void GenDeserializer(std::ofstream& stream, + const Structure& st); + std::string NLine(int cnt); + + private: + const int TAB_SIZE = 4; +}; + +} // namespace tidl +#endif // IDLC_GEN_CION_JAVA_CION_STRUCTURE_GEN_H_ diff --git a/idlc/gen_cion/java_cion_stub_base_service_gen.cc b/idlc/gen_cion/java_cion_stub_base_service_gen.cc new file mode 100644 index 0000000..0c39385 --- /dev/null +++ b/idlc/gen_cion/java_cion_stub_base_service_gen.cc @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2021 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/java_cion_stub_base_service_gen.h" + +#include +#include + +#include +#include +#include + +namespace tidl { + +JavaCionStubBaseServiceGen::JavaCionStubBaseServiceGen( + std::shared_ptr doc) : JavaCionGeneratorBase(doc) { +} + +void JavaCionStubBaseServiceGen::OnInitGen(std::ofstream& stream) { + std::string fname = "./java/org/tizen/gen/" + FileName + "/interfaces"; + if (access(fname.c_str(), F_OK) != 0) { + if (!std::filesystem::create_directories(fname)) { + std::cout << "fail to create folder " << fname << std::endl; + return; + } + } + + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() != Block::TYPE_INTERFACE) + continue; + + Interface& iface = static_cast(*i); + stream.open(fname + "/" + GetServiceBaseClassName(i->GetID()) + ".java"); + stream << "package org.tizen.gen." << FileName + ".interfaces;" << NLine(2); + stream << "import java.util.LinkedList;" << NLine(1); + stream << "import java.util.ArrayList;" << NLine(1); + stream << NLine(1); + stream << "public abstract class " << GetServiceBaseClassName(i->GetID()) << " "; + GenBrace(stream, TAB_SIZE * 0, [&]() { + GenMethods(stream, iface); + stream << std::endl; + }, false); + stream.close(); + } +} + +void JavaCionStubBaseServiceGen::GenMethods( + std::ofstream& stream, const Interface& iface) { + auto& decls = iface.GetDeclarations(); + + for (auto& i : decls.GetDecls()) { + if (i->GetMethodType() == Declaration::MethodType::DELEGATE) + continue; + + if (!i->GetComments().empty()) + stream << AddIndent(TAB_SIZE * 1, i->GetComments()); + + stream << Tab(1) << "abstract public "; + GenDeclaration(stream, *i, false); + stream << ";" << NLine(1); + } +} + +void JavaCionStubBaseServiceGen::OnFiniGen(std::ofstream& stream) { +} + +std::string JavaCionStubBaseServiceGen::NLine(int cnt) { + std::string t; + + for (int i = 0; i < cnt; i++) { + t += "\n"; + } + + return t; +} + +} // namespace tidl diff --git a/idlc/gen_cion/java_cion_stub_base_service_gen.h b/idlc/gen_cion/java_cion_stub_base_service_gen.h new file mode 100644 index 0000000..ca3940a --- /dev/null +++ b/idlc/gen_cion/java_cion_stub_base_service_gen.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 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_GEN_CION_JAVA_CION_STUB_BASE_SERVICE_GEN_H_ +#define IDLC_GEN_CION_JAVA_CION_STUB_BASE_SERVICE_GEN_H_ + +#include +#include +#include + +#include "idlc/gen_cion/java_cion_gen_base.h" + +namespace tidl { + +class JavaCionStubBaseServiceGen : public JavaCionGeneratorBase { + public: + explicit JavaCionStubBaseServiceGen(std::shared_ptr doc); + virtual ~JavaCionStubBaseServiceGen() = default; + + void OnInitGen(std::ofstream& stream) override; + void OnFiniGen(std::ofstream& stream) override; + void GenMethods(std::ofstream& stream, const Interface& iface); + std::string NLine(int cnt); + + private: + const int TAB_SIZE = 4; +}; + +} // namespace tidl +#endif // IDLC_GEN_CION_JAVA_CION_STUB_BASE_SERVICE_GEN_H_ diff --git a/idlc/gen_cion/java_cion_stub_gen.cc b/idlc/gen_cion/java_cion_stub_gen.cc new file mode 100644 index 0000000..4c618c5 --- /dev/null +++ b/idlc/gen_cion/java_cion_stub_gen.cc @@ -0,0 +1,325 @@ +/* + * 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 "idlc/gen_cion/java_cion_stub_gen.h" +#include "idlc/gen_cion/java_cion_gen_cb.h" + +#include +#include + +#include +#include + +namespace tidl { + +JavaCionStubGen::JavaCionStubGen(std::shared_ptr doc) + : JavaCionGeneratorBase(doc) {} + +void JavaCionStubGen::OnInitGen(std::ofstream& stream) { + std::string fname = "./java/org/tizen/gen/" + FileName + "/viewmodel"; + if (access(fname.c_str(), F_OK) != 0) { + if (!std::filesystem::create_directories(fname)) { + std::cout << "fail to create folder " << fname << std::endl; + return; + } + } + + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() != Block::TYPE_INTERFACE) + continue; + + Interface& iface = static_cast(*i); + stream.open(fname + "/" + GetViewModelName(i->GetID()) + ".java"); + stream << "package org.tizen.gen." << FileName << ".viewmodel;" << NLine(2); + stream << "import androidx.lifecycle.LiveData;" << NLine(1); + stream << "import androidx.lifecycle.ViewModel;" << NLine(1); + stream << "import org.tizen.cion.CionParcel;" << NLine(1); + stream << "import org.tizen.cion.DataPayload;" << NLine(1); + stream << "import org.tizen.cion.FilePayload;" << NLine(1); + stream << "import java.util.ArrayList;" << NLine(1); + stream << NLine(1); + GenInterface(stream, iface); + stream.close(); + } +} + +void JavaCionStubGen::OnFiniGen(std::ofstream& stream) { +} + +void JavaCionStubGen::GenInterface( + std::ofstream& stream, const Interface& iface) { + stream << "public class " << GetViewModelName(iface.GetID()) + << " extends ViewModel " << NLine(1); + GenBrace(stream, TAB_SIZE * 0, [&]() { + stream << Tab(1) << "private " << GetRepoClassName(iface.GetID()) << " repo; " << NLine(1); + stream << Tab(1) << + "private LiveData> connectedPeerLiveData;" + << NLine(1); + stream << Tab(1) << "private LiveData logsLiveData;" << NLine(1); + stream << Tab(1) + << "private LiveData receivedPayloadLiveData;" + << NLine(1); + stream << Tab(1) + << "private LiveData receivedDataLiveData;" + << NLine(1); + stream << Tab(1) + << "private " << GetServiceBaseClassName(iface.GetID()) << " service;" + << NLine(1); + stream << NLine(1); + GenMethodId(stream, iface); + stream << NLine(1); + GenCtor(stream, iface); + stream << NLine(1); + GenSyncReceiver(stream, iface); + stream << NLine(1); + GenAsyncReceiver(stream, iface); + stream << ReplaceAll(DEFAULT_STUB_FUNCTIONS, + "##", GetServiceBaseClassName(iface.GetID())) << NLine(1); + stream << NLine(1); + }); +} + +void JavaCionStubGen::GenSyncReceiver( + std::ofstream& stream, const Interface& iface) { + stream << Tab(1) << "public void processReceivedData(byte[] data) "; + GenBrace(stream, TAB_SIZE * 1, [&]() { + std::string parcel_name = "parcel"; + std::string ret_parcel_name = "ret_parcel"; + stream << Tab(2) + << "CionParcel " << parcel_name + << " = new CionParcel(data);" << NLine(1); + stream << Tab(2) + << "CionParcel " << ret_parcel_name + << " = new CionParcel();" << NLine(1); + stream << Tab(2) << "int methodID = " << parcel_name + << ".readInt();" << NLine(1); + stream << Tab(2) << "switch (methodID) "; + GenBrace(stream, TAB_SIZE * 2, [&]() { + auto& decls = iface.GetDeclarations(); + for (auto& i : decls.GetDecls()) { + if (i->GetMethodType() != Declaration::MethodType::SYNC) + continue; + + stream << Tab(2) << + "case " << "__" << i->GetID() << " : "; + GenBrace(stream, 0, [&]() { + std::string params_str = ""; + for (auto& param : i->GetParameters().GetParams()) { + if (!params_str.empty()) + params_str += ", "; + auto& pt = param->GetParameterType(); + if (pt.GetDirection() == ParameterType::Direction::OUT) { + stream << Tab(3) + << "Out<" << ConvertTypeToString(pt.GetBaseType()) + << "> " << param->GetID() << " = null;" << NLine(1); + } else if (pt.GetDirection() == ParameterType::Direction::REF) { + stream << Tab(3) << ConvertTypeToString(pt.GetBaseType()) + << " " << param->GetID() << "Raw = new " + << ConvertTypeToString(pt.GetBaseType()) << "();" << NLine(1); + stream << Tab(3) + << "Ref<" << ConvertTypeToString(pt.GetBaseType()) + << "> " << param->GetID() << " = new Ref<" + << ConvertTypeToString(pt.GetBaseType()) << ">(" + << param->GetID() <<"Raw);" << NLine(1); + } else { + stream << GetParcelReader(pt.GetBaseType(), + parcel_name, param->GetID(), 3) << NLine(1); + } + params_str += param->GetID(); + } + + stream << Tab(3) << ConvertTypeToString(i->GetType()) + << " ret_" << i->GetID() << " = " << "service." << i->GetID() + << "(" << params_str << ");" << NLine(1); + if (i->GetType().IsUserDefinedType()) { + stream << Tab(3) << ret_parcel_name + << " = ret_" << i->GetID() << ".deserialize(" + << ret_parcel_name << ");" << NLine(1); + } else { + stream << Tab(3) + << ret_parcel_name + << ".write(ret_" << i->GetID() << ");" << NLine(1); + } + + stream << Tab(3) + << "setSyncResponse(" + << ret_parcel_name << ".toByteArray());" << NLine(1); + stream << Tab(3) << "break;" << NLine(1); + }, false); + } + }, false); + }, false); +} + +void JavaCionStubGen::GenAsyncReceiver( + std::ofstream& stream, const Interface& iface) { + std::string parcel_name = "parcel"; + stream << Tab(1) + << "public void processReceivedPayload(CionParcel " + << parcel_name << ") "; + GenBrace(stream, TAB_SIZE * 1, [&]() { + stream << Tab(2) << "int methodID = " + << parcel_name << ".readInt();" << NLine(1); + stream << Tab(2) << "switch (methodID) "; + GenBrace(stream, TAB_SIZE * 2, [&]() { + auto& decls = iface.GetDeclarations(); + for (auto& i : decls.GetDecls()) { + if (i->GetMethodType() != Declaration::MethodType::ASYNC) + continue; + + stream << Tab(2) + << "case " << "__" << i->GetID() << " : " << NLine(1); + std::string params_str = ""; + for (auto& param : i->GetParameters().GetParams()) { + if (!params_str.empty()) + params_str += ", "; + auto& pt = param->GetParameterType(); + if (pt.GetDirection() == ParameterType::Direction::OUT) { + stream << Tab(3) + << "Out<" << ConvertTypeToString(pt.GetBaseType()) + << "> " << param->GetID() << " = null;" << NLine(1); + } else if (pt.GetDirection() == ParameterType::Direction::REF) { + stream << Tab(3) << ConvertTypeToString(pt.GetBaseType()) + << " " << param->GetID() << "Raw = new " + << ConvertTypeToString(pt.GetBaseType()) << "();" << NLine(1); + stream << Tab(3) + << "Ref<" << ConvertTypeToString(pt.GetBaseType()) + << "> " << param->GetID() << " = new Ref<" + << ConvertTypeToString(pt.GetBaseType()) << ">(" + << param->GetID() <<"Raw);" << NLine(1); + } else { + stream << GetParcelReader(pt.GetBaseType(), + parcel_name, param->GetID(), 3) << NLine(1); + } + + params_str += param->GetID(); + } + stream << Tab(3) << "service." << i->GetID() + << "(" << params_str << ");" << NLine(1); + + stream << Tab(3) << "break;" << NLine(1); + } + stream << Tab(2) << "default" << " : " << NLine(1); + stream << Tab(3) << "break;" << NLine(1); + }, false); + }, false); +} + +void JavaCionStubGen::GenInvocation( + std::ofstream& stream, const Declaration& decl) { + stream << Tab(2) << "CionParcel parcel = new CionParcel();"; + stream << NLine(1); + stream << Tab(2) << "parcel.write(__" << decl.GetID() << ");"; + stream << NLine(1); + for (auto& i : decl.GetParameters().GetParams()) { + auto& pt = i->GetParameterType(); + if (pt.GetDirection() == ParameterType::Direction::OUT || + pt.GetDirection() == ParameterType::Direction::REF) + continue; + + if (pt.GetBaseType().IsUserDefinedType()) + stream << Tab(2) << "parcel = " << i->GetID() << ".serialize(parcel);"; + else + stream << Tab(2) << "parcel.write(" << i->GetID() << ");"; + stream << NLine(1); + } + + if (decl.GetMethodType() == Declaration::MethodType::SYNC) { + stream << Tab(2) + << "byte[] ret = sendData(parcel.toByteArray());" << NLine(1); + stream << Tab(2) + << "CionParcel ret_parcel = new CionParcel(ret);" << NLine(1); + stream << Tab(2) << "int cmd = ret_parcel.readInt();" << NLine(1); + stream << Tab(2) << "if (cmd != __RESULT)" << NLine(1); + stream << Tab(3) << "throw new IOException();" << NLine(1); + + for (auto& i : decl.GetParameters().GetParams()) { + auto& pt = i->GetParameterType(); + if (pt.GetDirection() != ParameterType::Direction::OUT && + pt.GetDirection() != ParameterType::Direction::REF) + continue; + if (pt.GetBaseType().IsUserDefinedType()) { + if (pt.GetDirection() == ParameterType::Direction::OUT) { + stream << Tab(2) << i->GetID() << ".set(new " + << pt.GetBaseType().ToString() << "());" << NLine(1); + + stream << Tab(2) << "ret_parcel = " << i->GetID() + << ".get().deserialize(ret_parcel);" << NLine(1); + } else { + stream << Tab(2) << "ret_parcel = " << i->GetID() + << ".get().deserialize(ret_parcel);" << NLine(1); + } + } else { + stream << Tab(2) << i->GetID() + << ".set(" << i->GetID() << ".read" + << ConvertTypeToString(pt.GetBaseType(), true) + << "());" << NLine(1); + } + stream << NLine(1); + } + + if (decl.GetType().IsUserDefinedType()) { + stream << Tab(2) << decl.GetType().ToString() + << " ret_val = new " << decl.GetType().ToString() + << "();" << NLine(1); + stream << Tab(2) << "ret_val.deserialize(ret_parcel);" << NLine(1); + stream << Tab(2) << "return ret_val;" << NLine(1); + } else { + stream << Tab(2) << ConvertTypeToString(decl.GetType()) + << " ret_val = ret_parcel.read" + << ConvertTypeToString(decl.GetType(), true) + << "();" << NLine(1); + stream << Tab(2) << "return ret_val;" << NLine(1); + } + } else { + stream << Tab(2) << + "sendAsync(new DataPayload(parcel.toByteArray()));" << NLine(1); + } + + for (auto& i : decl.GetParameters().GetParams()) { + auto& pt = i->GetParameterType(); + if (pt.GetDirection() == ParameterType::Direction::OUT || + pt.GetDirection() == ParameterType::Direction::REF) + continue; + + if (pt.GetBaseType().ToString() == "file") { + stream << NLine(1); + stream << Tab(2) << "FilePayload " << i->GetID() + << "Payload = new FilePayload();" << NLine(1); + stream << Tab(2) << i->GetID() << "Payload.setFilePath(" + << i->GetID() << ");" << NLine(1); + stream << Tab(2) << "sendAsync(" << i->GetID() << "Payload);" << NLine(1); + } + } +} + +void JavaCionStubGen::GenCtor(std::ofstream& stream, const Interface& iface) { + stream << Tab(1) << "public " << GetViewModelName(iface.GetID()) << + "(" << GetRepoClassName(iface.GetID()) << " repo) "; + GenBrace(stream, TAB_SIZE * 1, [&]() { + stream << Tab(2) << "super();" << NLine(1); + stream << Tab(2) << "this.repo = repo;" << NLine(1); + stream << Tab(2) << + "connectedPeerLiveData = repo.getConnectedPeerLiveData();" + << NLine(1); + stream << Tab(2) << + "receivedPayloadLiveData = repo.getReceivedPayloadInfoLiveData();" + << NLine(1); + stream << Tab(2) << "logsLiveData = repo.getLogsLiveData();" << NLine(1); + }); +} + +} // namespace tidl diff --git a/idlc/gen_cion/java_cion_stub_gen.h b/idlc/gen_cion/java_cion_stub_gen.h new file mode 100644 index 0000000..1ad43f0 --- /dev/null +++ b/idlc/gen_cion/java_cion_stub_gen.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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_GEN_CION_JAVA_CION_STUB_GEN_H_ +#define IDLC_GEN_CION_JAVA_CION_STUB_GEN_H_ + +#include +#include + +#include "idlc/gen_cion/java_cion_gen_base.h" + +namespace tidl { + +class JavaCionStubGen : public JavaCionGeneratorBase { + public: + explicit JavaCionStubGen(std::shared_ptr doc); + virtual ~JavaCionStubGen() = default; + + void OnInitGen(std::ofstream& stream) override; + void OnFiniGen(std::ofstream& stream) override; + + private: + void GenNamespace(std::ofstream& stream); + void GenInterface(std::ofstream& stream, const Interface& iface); + void GenCtor(std::ofstream& stream, const Interface& iface); + void GenAsyncReceiver(std::ofstream& stream, const Interface& iface); + void GenSyncReceiver(std::ofstream& stream, const Interface& iface); + void GenInvocation(std::ofstream& stream, const Declaration& decl); +}; + +} // namespace tidl + +#endif // IDLC_GEN_CION_JAVA_CION_STUB_GEN_H_ diff --git a/idlc/gen_cion/java_cion_stub_repo_gen.cc b/idlc/gen_cion/java_cion_stub_repo_gen.cc new file mode 100644 index 0000000..91e16a9 --- /dev/null +++ b/idlc/gen_cion/java_cion_stub_repo_gen.cc @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 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/java_cion_stub_repo_gen.h" +#include "idlc/gen_cion/java_cion_gen_cb.h" + +#include +#include + +#include +#include +#include + +namespace tidl { + +JavaCionStubRepoGen::JavaCionStubRepoGen( + std::shared_ptr doc) : JavaCionGeneratorBase(doc) { +} + +void JavaCionStubRepoGen::OnInitGen(std::ofstream& stream) { + std::string fname = "./java/org/tizen/gen/" + FileName + "/data"; + if (access(fname.c_str(), F_OK) != 0) { + if (!std::filesystem::create_directories(fname)) { + std::cout << "fail to create folder " << fname << std::endl; + return; + } + } + + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() != Block::TYPE_INTERFACE) + continue; + + stream.open(fname + "/" + GetRepoClassName(i->GetID()) + ".java"); + stream << "package org.tizen.gen." << FileName << ".data;" << NLine(2); + stream << ReplaceAll(DEFAULT_STUB_REPO, + "##", GetRepoClassName(i->GetID())) << NLine(1); + stream.close(); + } +} + +void JavaCionStubRepoGen::OnFiniGen(std::ofstream& stream) { +} + +std::string JavaCionStubRepoGen::NLine(int cnt) { + std::string t; + + for (int i = 0; i < cnt; i++) { + t += "\n"; + } + + return t; +} + +} // namespace tidl diff --git a/idlc/gen_cion/java_cion_stub_repo_gen.h b/idlc/gen_cion/java_cion_stub_repo_gen.h new file mode 100644 index 0000000..2e4e6e9 --- /dev/null +++ b/idlc/gen_cion/java_cion_stub_repo_gen.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 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_GEN_CION_JAVA_CION_STUB_REPO_GEN_H_ +#define IDLC_GEN_CION_JAVA_CION_STUB_REPO_GEN_H_ + +#include +#include +#include + +#include "idlc/gen_cion/java_cion_gen_base.h" + +namespace tidl { + +class JavaCionStubRepoGen : public JavaCionGeneratorBase { + public: + explicit JavaCionStubRepoGen(std::shared_ptr doc); + virtual ~JavaCionStubRepoGen() = default; + + void OnInitGen(std::ofstream& stream) override; + void OnFiniGen(std::ofstream& stream) override; + std::string NLine(int cnt); +}; + +} // namespace tidl +#endif // IDLC_GEN_CION_JAVA_CION_STUB_REPO_GEN_H_ diff --git a/idlc/gen_cion/java_cion_utility_gen.cc b/idlc/gen_cion/java_cion_utility_gen.cc new file mode 100644 index 0000000..52f8bcd --- /dev/null +++ b/idlc/gen_cion/java_cion_utility_gen.cc @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021 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/java_cion_utility_gen.h" +#include "idlc/gen_cion/java_cion_gen_cb.h" + +#include +#include + +#include +#include +#include + +namespace tidl { + +JavaCionUtilityGen::JavaCionUtilityGen( + std::shared_ptr doc) : Generator(doc) { +} + +void JavaCionUtilityGen::OnInitGen(std::ofstream& stream) { + std::string fname = "./java/org/tizen/gen/" + FileName + "/utility"; + if (access(fname.c_str(), F_OK) != 0) { + if (!std::filesystem::create_directories(fname)) { + std::cout << "fail to create folder " << fname << std::endl; + return; + } + } + + stream.open(fname + "/Out.java"); + stream << "package org.tizen.gen." << FileName << ".utility;" << NLine(2); + stream << OUT_CLASS; + stream.close(); + + stream.open(fname + "/Ref.java"); + stream << "package org.tizen.gen." << FileName << ".utility;" << NLine(2); + stream << REF_CLASS; + stream.close(); +} + +void JavaCionUtilityGen::OnFiniGen(std::ofstream& stream) { +} + +std::string JavaCionUtilityGen::NLine(int cnt) { + std::string t; + + for (int i = 0; i < cnt; i++) { + t += "\n"; + } + + return t; +} + +} // namespace tidl diff --git a/idlc/gen_cion/java_cion_utility_gen.h b/idlc/gen_cion/java_cion_utility_gen.h new file mode 100644 index 0000000..2bb02cd --- /dev/null +++ b/idlc/gen_cion/java_cion_utility_gen.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 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_GEN_CION_JAVA_CION_UTILITY_GEN_H_ +#define IDLC_GEN_CION_JAVA_CION_UTILITY_GEN_H_ + +#include +#include +#include + +#include "idlc/ast/type.h" +#include "idlc/ast/structure.h" +#include "idlc/gen/generator.h" + +namespace tidl { + +class JavaCionUtilityGen : public Generator { + public: + explicit JavaCionUtilityGen(std::shared_ptr doc); + virtual ~JavaCionUtilityGen() = default; + + void OnInitGen(std::ofstream& stream) override; + void OnFiniGen(std::ofstream& stream) override; + std::string NLine(int cnt); +}; + +} // namespace tidl +#endif // IDLC_GEN_CION_JAVA_CION_UTILITY_GEN_H_ diff --git a/idlc/main.cc b/idlc/main.cc index 878280f..a8e8fe1 100644 --- a/idlc/main.cc +++ b/idlc/main.cc @@ -38,6 +38,17 @@ #include "idlc/options.h" + +#include "idlc/gen_cion/java_cion_stub_gen.h" +#include "idlc/gen_cion/java_cion_stub_repo_gen.h" +#include "idlc/gen_cion/java_cion_proxy_gen.h" +#include "idlc/gen_cion/java_cion_proxy_repo_gen.h" +#include "idlc/gen_cion/java_cion_utility_gen.h" +#include "idlc/gen_cion/java_cion_structure_gen.h" +#include "idlc/gen_cion/java_cion_data_gen.h" +#include "idlc/gen_cion/java_cion_interface_gen.h" +#include "idlc/gen_cion/java_cion_stub_base_service_gen.h" + void GenerateStubCodes(std::shared_ptr options, tidl::Parser& ps) { if (options->IsCion()) { @@ -59,7 +70,29 @@ void GenerateStubCodes(std::shared_ptr options, case tidl::Options::LANGUAGE_TYPE_CSHARP: break; case tidl::Options::LANGUAGE_TYPE_JAVA: + { + tidl::JavaCionStubRepoGen repo(ps.GetDoc()); + repo.Run(options->GetOutput(), true); + + tidl::JavaCionStubGen view_model(ps.GetDoc()); + view_model.Run(options->GetOutput(), true); + + tidl::JavaCionUtilityGen utilities(ps.GetDoc()); + utilities.Run(options->GetOutput(), true); + + tidl::JavaCionStructureGen structures(ps.GetDoc()); + structures.Run(options->GetOutput(), true); + + tidl::JavaCionDataGen data(ps.GetDoc()); + data.Run(options->GetOutput(), true); + + tidl::JavaCionInterfaceGen ifgen(ps.GetDoc()); + ifgen.Run(options->GetOutput(), true); + + tidl::JavaCionStubBaseServiceGen sb_service(ps.GetDoc()); + sb_service.Run(options->GetOutput(), true); break; + } default: break; @@ -124,7 +157,26 @@ void GenerateProxyCodes(std::shared_ptr options, case tidl::Options::LANGUAGE_TYPE_CSHARP: break; case tidl::Options::LANGUAGE_TYPE_JAVA: + { + tidl::JavaCionProxyRepoGen base_files(ps.GetDoc()); + base_files.Run(options->GetOutput(), true); + + tidl::JavaCionProxyGen view_model(ps.GetDoc()); + view_model.Run(options->GetOutput(), true); + + tidl::JavaCionUtilityGen utilities(ps.GetDoc()); + utilities.Run(options->GetOutput(), true); + + tidl::JavaCionStructureGen structures(ps.GetDoc()); + structures.Run(options->GetOutput(), true); + + tidl::JavaCionDataGen data(ps.GetDoc()); + data.Run(options->GetOutput(), true); + + tidl::JavaCionInterfaceGen ifgen(ps.GetDoc()); + ifgen.Run(options->GetOutput(), true); break; + } default: break; -- 2.7.4