stream << NLine(1);
}
+void CppGeneratorBase::GenExportAPI(std::ofstream& stream) {
+ stream << CB_EXPORT_API;
+ stream << NLine(1);
+}
+
std::string CppGeneratorBase::GenExceptions() {
std::string code = CB_HEADER_UNIT_MAP_DEF;
code += std::string(CB_EXCEPTIONS);
return code;
}
+std::string CppGeneratorBase::GenParameters(const Structure& st) {
+ std::string params;
+ if (st.GetBase() != nullptr)
+ params += GenParameters(*st.GetBase());
+
+ if (!params.empty())
+ params += ", ";
+
+ return params + GenParameters(st.GetElements());
+}
+
std::string CppGeneratorBase::GenStructuresForHeader(bool use_file) {
std::string code(CB_HEADER_BUNDLE);
code += NLine(1);
std::string CppGeneratorBase::GenStructureForHeader(const Structure& st) {
std::string code;
- if (st.GetElements().Empty()) {
+ std::string params = GenParameters(st);
+ if (params.empty()) {
if (st.GetBase() == nullptr) {
code = ReplaceAll(CB_HEADER_STRUCTURE_BASE_EMPTY)
.Change("<CLS_NAME>", st.GetID())
.Change("<MEMBERS>\n",
GenStructureMembersForHeader(st.GetElements()));
} else {
- std::string params = GenParameters(st.GetBase()->GetElements());
- if (!params.empty())
- params += ", ";
-
- params += GenParameters(st.GetElements());
code = ReplaceAll(CB_HEADER_INHERITED_STRUCTURE_BASE)
.Change("<CLS_NAME>", st.GetID())
.Change("<BASE_CLS_NAME>", st.GetBase()->GetID())
}
std::string CppGeneratorBase::GenStructure(const Structure& st) {
+ std::string params = GenParameters(st);
std::string code;
- if (st.GetElements().Empty()) {
+ if (params.empty()) {
code = ReplaceAll(CB_BODY_STRUCTURE_BASE_EMPTY)
.Change("<CLS_NAME>", st.GetID());
} else {
code =
ReplaceAll(CB_BODY_STRUCTURE_BASE)
.Change("<CLS_NAME>", st.GetID())
- .Change("<PARAMS>", GenParameters(st.GetElements()))
+ .Change("<PARAMS>", params)
.Change("<MEMBER_INIT>", GenStructureMemberInit(st.GetElements()))
.Change("<GETTER_SETTER>", GenStructureGetterSetter(st));
} else {
- std::string params = GenParameters(st.GetBase()->GetElements());
- if (!params.empty())
- params += ", ";
-
- params += GenParameters(st.GetElements());
code =
ReplaceAll(CB_BODY_INHERITED_STRUCTURE_BASE)
.Change("<CLS_NAME>", st.GetID())
.Change("<BASE_CLS_NAME>", st.GetBase()->GetID())
- .Change("<BASE_ARGS>",
- GenStructureBaseArgs(st.GetBase()->GetElements()))
+ .Change("<BASE_ARGS>", GenStructureBaseArgs(*st.GetBase()))
.Change("<PARAMS>", params)
.Change("<MEMBER_INIT>", GenStructureMemberInit(st.GetElements()))
.Change("<GETTER_SETTER>", GenStructureGetterSetter(st));
return code;
}
+std::string CppGeneratorBase::GenStructureBaseArgs(const Structure& st) {
+ std::string code;
+ if (st.GetBase() != nullptr)
+ code += GenStructureBaseArgs(*st.GetBase());
+
+ if (!code.empty())
+ code += ", ";
+
+ return code + GenStructureBaseArgs(st.GetElements());
+}
+
std::string CppGeneratorBase::GenStructureBaseArgs(const Elements& elms) {
std::string code;
for (auto& elm : elms) {
}
for (const auto& decl : iface.GetDeclarations()) {
+ AddUnitType("delegate",
+ BaseType(iface.GetID() + "::CallbackBase", "", true),
+ iface.GetID());
if (decl->GetMethodType() == Declaration::MethodType::DELEGATE) {
- AddUnitType("delegate",
- BaseType(iface.GetID() + "::CallbackBase", "", true),
- iface.GetID());
AddUnitType(decl->GetID(), BaseType(decl->GetID(), "", true),
iface.GetID());
} else if (decl->GetMethodType() == Declaration::MethodType::SYNC) {
void GenLogTag(std::ofstream& stream, const std::string& log_tag);
void GenLogDefinition(std::ofstream& stream);
void GenVersionDefinition(std::ofstream& stream);
+ void GenExportAPI(std::ofstream& stream);
std::string GenExceptions();
std::string GenStructuresForHeader(bool use_file = true);
private:
void AddTypeName(const Structure& st);
+ std::string GenParameters(const Structure& st);
std::string GenStructureForHeader(const Structure& st);
std::string GenStructureGetterSetterForHeader(const Elements& elms);
std::string GenStructureMembersForHeader(const Elements& elms);
std::string GenStructure(const Structure& st);
+ std::string GenStructureBaseArgs(const Structure& st);
std::string GenStructureBaseArgs(const Elements& elms);
std::string GenStructureMemberInit(const Elements& elms);
std::string GenStructureGetterSetter(const Structure& st);
constexpr const char CB_BODY_HEADER[] =
R"__cpp_cb(
+#include <app_common.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libgen.h>
#include <glib.h>
#include <dlog.h>
+#include <dlfcn.h>
#include <rpc-port.h>
#include <rpc-port-parcel.h>
+#include <unistd.h>
#include <map>
#include <memory>
#include <vector>
#include <unordered_map>
#include <unordered_set>
+#include <queue>
)__cpp_cb";
/**
<NAME>.Share(port_);
)__cpp_cb";
+/**
+ * <NAME> The parameter name.
+ */
constexpr const char CB_PRIVATE_SHARING_ARRAY[] =
R"__cpp_cb(
{
}
)__cpp_cb";
+constexpr const char CB_EXPORT_API[] =
+R"__cpp_cb(
+#undef EXPORT_API
+#define EXPORT_API extern "C" __attribute__ ((visibility("default")))
+)__cpp_cb";
+
} // namespace version2
} // namespace tidl
#include "idlc/gen/version2/cpp_proxy_body_generator.hh"
+#include <libgen.h>
+
#include <utility>
#include "idlc/gen/version2/cpp_generator_base_cb.hh"
namespace tidl {
namespace version2 {
-CppProxyBodyGenerator::CppProxyBodyGenerator(std::shared_ptr<Document> doc)
- : CppGeneratorBase(std::move(doc)) {}
+CppProxyBodyGenerator::CppProxyBodyGenerator(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options)
+ : CppGeneratorBase(std::move(doc)), options_(std::move(options)) {}
void CppProxyBodyGenerator::OnInitGen(std::ofstream& stream) {
GenVersion(stream);
GenLogTag(stream, "RPC_PORT_PROXY");
GenLogDefinition(stream);
GenVersionDefinition(stream);
+ GenExportAPI(stream);
+ GenLemAnonymousNamespace(stream);
GenNamespace(stream);
+ GenLemAPI(stream);
}
void CppProxyBodyGenerator::OnFiniGen(std::ofstream& stream) {}
void CppProxyBodyGenerator::GenNamespace(std::ofstream& stream) {
ReplaceAll(CB_NAMESPACE_PROXY)
.ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
- .Change("<STRUCTURES>", GenStructures())
+ .Change("<STRUCTURES>", GenLemBaseWithStructures())
.Change("<BASE_IMPL>", GenBaseImpl())
.Change("<INTERFACES>", GenInterfaces())
.Transform([&](std::string str) { return SmartIndent(str); })
.Out(stream);
}
+void CppProxyBodyGenerator::GenLemAnonymousNamespace(std::ofstream& stream) {
+ stream << SmartIndent(CB_LEM_ANONYMOUS_NAMESPACE);
+}
+
+void CppProxyBodyGenerator::GenLemAPI(std::ofstream& stream) {
+ std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
+ input = input.substr(0, input.find_last_of("."));
+ std::string code = NLine(1);
+ for (const auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<Interface&>(*block);
+ code += ReplaceAll(CB_LEM_API)
+ .Change("<CLS_NAME>", iface.GetID())
+ .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
+ .ChangeToLower("<INPUT_FILE>", input);
+ code += NLine(1);
+ }
+
+ stream << SmartIndent(code);
+}
+
+std::string CppProxyBodyGenerator::GenLemBaseWithStructures() {
+ std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
+ input = input.substr(0, input.find_last_of("."));
+ std::string code;
+ code += ReplaceAll(CB_LEM_BASE).ChangeToLower("<INPUT_FILE>", input);
+ code += NLine(1);
+ code += GenStructures();
+ return code;
+}
+
std::string CppProxyBodyGenerator::GenBaseImpl() {
std::string code = GenRemoteException();
code += GenUnitMap();
std::string CppProxyBodyGenerator::GenInterfaceCallbacks(
const Interface& iface) {
std::string code;
+ code += ReplaceAll(CB_INTERFACE_CALKBACBASE_BASE)
+ .Change("<IFACE_NAME>", iface.GetID());
+ code += NLine(1);
for (const auto& decl : iface.GetDeclarations()) {
if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
continue;
- if (code.empty()) {
- code += ReplaceAll(CB_INTERFACE_CALKBACBASE_BASE)
- .Change("<IFACE_NAME>", iface.GetID());
- code += NLine(1);
- }
-
code += ReplaceAll(CB_INTERFACE_CALLBACK)
.Change("<IFACE_NAME>", iface.GetID())
.Change("<CLS_NAME>", decl->GetID())
#include <string>
#include "idlc/gen/version2/cpp_generator_base.hh"
+#include "idlc/options.h"
namespace tidl {
namespace version2 {
class CppProxyBodyGenerator : public CppGeneratorBase {
public:
- explicit CppProxyBodyGenerator(std::shared_ptr<Document> doc);
+ explicit CppProxyBodyGenerator(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options);
virtual ~CppProxyBodyGenerator() = default;
void OnInitGen(std::ofstream& stream) override;
private:
void GenIncludeProxyBodyHeader(std::ofstream& stream);
void GenNamespace(std::ofstream& stream);
+ void GenLemAnonymousNamespace(std::ofstream& stream);
+ void GenLemAPI(std::ofstream& stream);
+ std::string GenLemBaseWithStructures();
std::string GenBaseImpl();
std::string GenInterfaces();
std::string GenInterface(const Interface& iface);
const Declaration& decl);
std::string GenInterfaceMethodSerialize(const Declaration& decl);
std::string GenInterfaceMethodDeserialize(const Declaration& decl);
+
+ private:
+ std::shared_ptr<Options> options_;
};
} // namespace version2
rpc_port_proxy_add_disconnected_event_cb(proxy_, OnDisconnectedCb, this);
rpc_port_proxy_add_rejected_event_cb(proxy_, OnRejectedCb, this);
rpc_port_proxy_add_received_event_cb(proxy_, OnReceivedCb, this);
+
+ if (GetAppId() == target_appid_) {
+ local_execution_ = std::make_unique<LocalExecution>("<CLS_NAME>", this);
+ local_execution_->LoadSymbols();
+ }
}
<CLS_NAME>::~<CLS_NAME>() {
}
void <CLS_NAME>::Connect(bool sync) {
+ if (local_execution_.get() != nullptr && local_execution_->LoadSymbols()) {
+ if (local_execution_->Connect())
+ return;
+ }
+
int ret;
if (sync)
ret = rpc_port_proxy_connect_sync(proxy_, target_appid_.c_str(), "<CLS_NAME>");
}
void <CLS_NAME>::Disconnect() {
+ if (local_execution_.get() != nullptr && local_execution_->IsConnected()) {
+ local_execution_->Disconnect();
+ return;
+ }
+
int ret = rpc_port_disconnect(port_);
if (ret != RPC_PORT_ERROR_NONE) {
_E("Failed to disconnect from <CLS_NAME>. error(%d)", ret);
<METHODS>
+void <CLS_NAME>::OnLocalConnected() {
+ listener_->OnConnected();
+}
+
+void <CLS_NAME>::OnLocalDisconnected() {
+ listener_->OnDisconnected();
+}
+
+void <CLS_NAME>::OnLocalReceived(rpc_port_parcel_h parcel) {
+ UnitMap map;
+ map.Deserialize(parcel);
+ ProcessReceivedEvent(map);
+}
+
void <CLS_NAME>::ProcessReceivedEvent(const UnitMap& unit_map) {
CallbackBase callback;
unit_map.Read("delegate", callback);
constexpr const char CB_INTERFACE_METHOD_ASYNC_BASE[] =
R"__cpp_cb(
void <IFACE_NAME>::<NAME>(<PARAMS>) {
- if (port_ == nullptr) {
+ if (port_ == nullptr && (local_execution_.get() == nullptr || !local_execution_->IsConnected())) {
_E("Not connected");
throw NotConnectedSocketException();
}
map_.Serialize(parcel_);;
std::lock_guard<std::recursive_mutex> lock(mutex_);
- int ret_ = rpc_port_parcel_send(parcel_, port_);
+ int ret_;
+ if (local_execution_.get() != nullptr && local_execution_->IsConnected())
+ ret_ = local_execution_->Send(parcel_, nullptr);
+ else
+ ret_ = rpc_port_parcel_send(parcel_, port_);
+
rpc_port_parcel_destroy(parcel_);
if (ret_ != RPC_PORT_ERROR_NONE) {
_E("Failed to send parcel. error(%d)", ret_);
constexpr const char CB_INTERFACE_METHOD_BASE[] =
R"__cpp_cb(
<RETURN_TYPE> <IFACE_NAME>::<NAME>(<PARAMS>) {
- if (port_ == nullptr) {
+ if (port_ == nullptr && (local_execution_.get() == nullptr || !local_execution_->IsConnected())) {
_E("Not connected");
throw NotConnectedSocketException();
}
map_.Serialize(parcel_);
std::lock_guard<std::recursive_mutex> lock(mutex_);
- int ret_ = rpc_port_parcel_send(parcel_, port_);
+ int ret_;
+ rpc_port_parcel_h result_parcel_ = nullptr;
+ if (local_execution_.get() != nullptr && local_execution_->IsConnected())
+ ret_ = local_execution_->Send(parcel_, &result_parcel_);
+ else
+ ret_ = rpc_port_parcel_send(parcel_, port_);
+
rpc_port_parcel_destroy(parcel_);
if (ret_ != RPC_PORT_ERROR_NONE) {
_E("Failed to send parcel. error(%d)", ret_);
<RETURN_TYPE> result_<SET_INIT_VALUE>;
UnitMap received_map_;
- ConsumeCommand(port_, seq_num_, received_map_);
+ if (local_execution_.get() != nullptr && local_execution_->IsConnected()) {
+ received_map_.Deserialize(result_parcel_);
+ rpc_port_parcel_destroy(result_parcel_);
+ } else {
+ ConsumeCommand(port_, seq_num_, received_map_);
+ }
+
if (received_map_.GetSize() == 0) {
_E("received map size is zero");
}
received_map_.Read("<NAME>", <NAME>);
)__cpp_cb";
+constexpr const char CB_LEM_ANONYMOUS_NAMESPACE[] =
+R"__cpp_cb(
+namespace {
+
+std::atomic<unsigned int> seq_ { 0 };
+std::string appid_;
+
+const std::string& GetAppId() {
+ if (getuid() < 5000)
+ return appid_;
+
+ if (appid_.empty()) {
+ char* id = nullptr;
+ app_get_id(&id);
+ if (id == nullptr) {
+ _E("Failed to get app id");
+ return appid_;
+ }
+
+ appid_ = std::string(id);
+ free(id);
+ }
+
+ return appid_;
+}
+
+rpc_port_parcel_h Clone(rpc_port_parcel_h parcel) {
+ void* raw = nullptr;
+ unsigned int size = 0;
+ if (rpc_port_parcel_get_raw(parcel, &raw, &size) != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get raw");
+ return nullptr;
+ }
+
+ rpc_port_parcel_h handle = nullptr;
+ rpc_port_parcel_create_from_raw(&handle, raw, size);
+ return handle;
+}
+
+} // namespace
+)__cpp_cb";
+
+/**
+ * <INPUT_FILE> The input file name.
+ */
+constexpr const char CB_LEM_BASE[] =
+R"__cpp_cb(
+LocalExecution::LocalExecution(std::string port_name, LocalExecution::IEvent* listener) : port_name_(std::move(port_name)), listener_(listener) {
+ instance_ = GetAppId() + "::" + std::to_string(seq_++);
+}
+
+LocalExecution::~LocalExecution() {
+ while (!result_queue_.empty()) {
+ auto parcel = result_queue_.front();
+ result_queue_.pop();
+ rpc_port_parcel_destroy(parcel);
+ }
+
+ while (!request_queue_.empty()) {
+ auto parcel = request_queue_.front();
+ request_queue_.pop();
+ rpc_port_parcel_destroy(parcel);
+ }
+}
+
+bool LocalExecution::Connect() {
+ if (connect_func_) {
+ if (connect_func_(this, GetAppId().c_str(), instance_.c_str()) != RPC_PORT_ERROR_NONE)
+ return false;
+ }
+
+ return true;
+}
+
+void LocalExecution::Disconnect() {
+ if (disconnect_func_)
+ disconnect_func_(this, GetAppId().c_str(), instance_.c_str());
+}
+
+int LocalExecution::Send(rpc_port_parcel_h request, rpc_port_parcel_h* result) {
+ if (send_func_) {
+ int ret = send_func_(this, request);
+ if (result != nullptr) {
+ int count = 0;
+ while (ResultQueueEmpty() && count++ < 100)
+ usleep(100 * 1000);
+
+ if (ResultQueueEmpty()) {
+ _E("Failed to get result from server");
+ return RPC_PORT_ERROR_IO_ERROR;
+ }
+
+ *result = ResultQueuePop();
+ }
+
+ return ret;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+void LocalExecution::OnConnected() {
+ connected_ = true;
+ if (listener_ != nullptr)
+ listener_->OnLocalConnected();
+}
+
+void LocalExecution::OnDisconnected() {
+ connected_ = false;
+ if (listener_ != nullptr)
+ listener_->OnLocalDisconnected();
+}
+
+void LocalExecution::OnReceived(rpc_port_parcel_h parcel) {
+ if (listener_ != nullptr)
+ listener_->OnLocalReceived(parcel);
+}
+
+bool LocalExecution::LoadSymbols() {
+ if (loaded_)
+ return true;
+
+ if (connect_func_ == nullptr) {
+ std::string symbol = "rpc_port_stub_<INPUT_FILE>_lem_" + port_name_ + "_connect";
+ connect_func_ = reinterpret_cast<StubConnectFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+ if (connect_func_ == nullptr) {
+ _E("Failed to find symbol(%s)", symbol.c_str());
+ return false;
+ }
+ }
+
+ if (disconnect_func_ == nullptr) {
+ std::string symbol = "rpc_port_stub_<INPUT_FILE>_lem_" + port_name_ + "_disconnect";
+ disconnect_func_ = reinterpret_cast<StubDisconnectFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+ if (disconnect_func_ == nullptr) {
+ _E("Failed to find symbol(%s)", symbol.c_str());
+ return false;
+ }
+ }
+
+ if (send_func_ == nullptr) {
+ std::string symbol = "rpc_port_stub_<INPUT_FILE>_lem_" + port_name_ + "_send";
+ send_func_ = reinterpret_cast<StubSendFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+ if (send_func_ == nullptr) {
+ _E("Failed to find symbol(%s)", symbol.c_str());
+ return false;
+ }
+ }
+
+ loaded_ = true;
+ return true;
+}
+
+void LocalExecution::ResultQueuePush(rpc_port_parcel_h parcel) {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ result_queue_.push(parcel);
+}
+
+rpc_port_parcel_h LocalExecution::ResultQueuePop() {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ auto parcel = result_queue_.front();
+ result_queue_.pop();
+ return parcel;
+}
+
+bool LocalExecution::ResultQueueEmpty() const {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ return result_queue_.empty();
+}
+
+void LocalExecution::RequestQueuePush(rpc_port_parcel_h parcel) {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ request_queue_.push(parcel);
+}
+
+rpc_port_parcel_h LocalExecution::RequestQueuePop() {
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+ auto parcel = request_queue_.front();
+ request_queue_.pop();
+ return parcel;
+}
+)__cpp_cb";
+
+/**
+ * <CLS_NAME> The interface name.
+ * <INPUT_FILE> The input file name.
+ * <FILE_NAMESPACE> The file namespace.
+ */
+constexpr const char CB_LEM_API[] =
+R"__cpp_cb(
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<CLS_NAME>_connect(void* h) {
+ auto* handle = static_cast<rpc_port::<FILE_NAMESPACE>::LocalExecution*>(h);
+ auto* ptr = new std::weak_ptr<rpc_port::<FILE_NAMESPACE>::LocalExecution>(handle->shared_from_this());
+ g_idle_add([](gpointer user_data) {
+ auto* wp = static_cast<std::weak_ptr<rpc_port::<FILE_NAMESPACE>::LocalExecution>*>(user_data);
+ auto p = wp->lock();
+ if (p != nullptr)
+ p->OnConnected();
+
+ delete wp;
+ return G_SOURCE_REMOVE;
+ }, ptr);
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<CLS_NAME>_disconnect(void* h) {
+ auto* handle = static_cast<rpc_port::<FILE_NAMESPACE>::LocalExecution*>(h);
+ auto* ptr = new std::weak_ptr<rpc_port::<FILE_NAMESPACE>::LocalExecution>(handle->shared_from_this());
+ g_idle_add([](gpointer user_data) {
+ auto* wp = static_cast<std::weak_ptr<rpc_port::<FILE_NAMESPACE>::LocalExecution>*>(user_data);
+ auto p = wp->lock();
+ if (p != nullptr)
+ p->OnDisconnected();
+
+ delete wp;
+ return G_SOURCE_REMOVE;
+ }, ptr);
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<CLS_NAME>_invoke_callback(void* h, rpc_port_parcel_h parcel) {
+ auto* handle = static_cast<rpc_port::<FILE_NAMESPACE>::LocalExecution*>(h);
+ auto* ptr = new std::weak_ptr<rpc_port::<FILE_NAMESPACE>::LocalExecution>(handle->shared_from_this());
+ rpc_port_parcel_h cloned_parcel = ::Clone(parcel);
+ handle->RequestQueuePush(cloned_parcel);
+ g_idle_add([](gpointer user_data) {
+ auto* wp = static_cast<std::weak_ptr<rpc_port::<FILE_NAMESPACE>::LocalExecution>*>(user_data);
+ auto p = wp->lock();
+ if (p != nullptr) {
+ rpc_port_parcel_h request = p->RequestQueuePop();
+ p->OnReceived(request);
+ rpc_port_parcel_destroy(request);
+ }
+
+ delete wp;
+ return G_SOURCE_REMOVE;
+ }, ptr);
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_proxy_<INPUT_FILE>_lem_<CLS_NAME>_send_result(void* h, rpc_port_parcel_h parcel) {
+ auto* handle = static_cast<rpc_port::<FILE_NAMESPACE>::LocalExecution*>(h);
+ rpc_port_parcel_h cloned_parcel = ::Clone(parcel);
+ handle->ResultQueuePush(cloned_parcel);
+ return RPC_PORT_ERROR_NONE;
+}
+)__cpp_cb";
} // namespace version2
} // namespace tidl
namespace tidl {
namespace version2 {
-CppProxyHeaderGenerator::CppProxyHeaderGenerator(std::shared_ptr<Document> doc)
- : CppGeneratorBase(std::move(doc)) {}
+CppProxyHeaderGenerator::CppProxyHeaderGenerator(
+ std::shared_ptr<Document> doc, std::shared_ptr<Options> options)
+ : CppGeneratorBase(std::move(doc)), options_(std::move(options)) {}
void CppProxyHeaderGenerator::OnInitGen(std::ofstream& stream) {
GenVersion(stream);
void CppProxyHeaderGenerator::GenNamespace(std::ofstream& stream) {
ReplaceAll(CB_NAMESPACE_PROXY)
.ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
- .Change("<STRUCTURES>", GenStructuresForHeader())
+ .Change("<STRUCTURES>", GenLemBaseWithStructures())
.Change("<BASE_IMPL>", GenBaseImpl())
.Change("<INTERFACES>", GenInterfaces())
.Transform([&](std::string str) { return SmartIndent(str); })
.Out(stream);
}
+std::string CppProxyHeaderGenerator::GenLemBaseWithStructures() {
+ std::string code = CB_LEM_BASE;
+ code += NLine(1);
+ code += GenStructuresForHeader();
+ return code;
+}
+
std::string CppProxyHeaderGenerator::GenBaseImpl() {
std::string code = GenExceptions();
code += GenRemoteExceptionForHeader();
std::string CppProxyHeaderGenerator::GenInterfaceCallbacks(
const Interface& iface) {
std::string code;
+ code += ReplaceAll(CB_INTERFACE_CALLBACK_BASE)
+ .Change("<IFACE_NAME>", iface.GetID());
+ code += NLine(1);
for (const auto& decl : iface.GetDeclarations()) {
if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
continue;
- if (code.empty()) {
- code += ReplaceAll(CB_INTERFACE_CALLBACK_BASE)
- .Change("<IFACE_NAME>", iface.GetID());
- code += NLine(1);
- }
-
code += ReplaceAll(CB_INTERFACE_CALLBACK)
.Change("<CLS_NAME>", decl->GetID())
.Change("<PARAMS>", GetParameters(decl->GetParameters()));
#include <string>
#include "idlc/gen/version2/cpp_generator_base.hh"
+#include "idlc/options.h"
namespace tidl {
namespace version2 {
class CppProxyHeaderGenerator : public CppGeneratorBase {
public:
- explicit CppProxyHeaderGenerator(std::shared_ptr<Document> doc);
+ explicit CppProxyHeaderGenerator(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options);
virtual ~CppProxyHeaderGenerator() = default;
void OnInitGen(std::ofstream& stream) override;
private:
void GenNamespace(std::ofstream& stream);
+ std::string GenLemBaseWithStructures();
std::string GenBaseImpl();
std::string GenInterfaces();
std::string GenInterface(const Interface& iface);
std::string GenInterfaceCallbacks(const Interface& iface);
std::string GenInterfaceMethods(const Interface& iface);
+
+ private:
+ std::shared_ptr<Options> options_;
};
} // namespace version2
*/
constexpr const char CB_INTERFACE_BASE[] =
R"__cpp_cb(
-class <CLS_NAME> {
+class <CLS_NAME> : public LocalExecution::IEvent {
public:
<ENUMS>
<CALLBACKS>
static void OnRejectedCb(const char* endpoint, const char* port_name, void* user_data);
static void OnReceivedCb(const char* endpoint, const char* port_name, void* user_data);
+ void OnLocalConnected() override;
+ void OnLocalDisconnected() override;
+ void OnLocalReceived(rpc_port_parcel_h parcel) override;
+
private:
rpc_port_h port_ = nullptr;
rpc_port_h callback_port_ = nullptr;
std::recursive_mutex mutex_;
std::list<std::unique_ptr<CallbackBase>> delegate_list_;
std::string target_appid_;
+ std::shared_ptr<LocalExecution> local_execution_;
};
)__cpp_cb";
<RETURN_TYPE> <NAME>(<PARAMS>);
)__cpp_cb";
+constexpr const char CB_LEM_BASE[] =
+R"__cpp_cb(
+class LocalExecution : public std::enable_shared_from_this<LocalExecution> {
+ public:
+ class IEvent {
+ public:
+ virtual ~IEvent() = default;
+ virtual void OnLocalConnected() = 0;
+ virtual void OnLocalDisconnected() = 0;
+ virtual void OnLocalReceived(rpc_port_parcel_h parcel) = 0;
+ };
+
+ LocalExecution(std::string port_name, IEvent* listener);
+ virtual ~LocalExecution();
+
+ bool Connect();
+ void Disconnect();
+ int Send(rpc_port_parcel_h request, rpc_port_parcel_h* result);
+
+ bool IsConnected() const { return connected_; }
+
+ void OnConnected();
+ void OnDisconnected();
+ void OnReceived(rpc_port_parcel_h parcel);
+
+ bool LoadSymbols();
+
+ void ResultQueuePush(rpc_port_parcel_h parcel);
+ rpc_port_parcel_h ResultQueuePop();
+ bool ResultQueueEmpty() const;
+
+ void RequestQueuePush(rpc_port_parcel_h parcel);
+ rpc_port_parcel_h RequestQueuePop();
+
+
+ private:
+ using StubConnectFunc = int (*)(void*, const char*, const char*);
+ using StubDisconnectFunc = void (*)(void*, const char*, const char*);
+ using StubSendFunc = int (*)(void*, rpc_port_parcel_h);
+
+ private:
+ std::string port_name_;
+ IEvent* listener_;
+ std::string instance_;
+ bool connected_ = false;
+ bool loaded_ = false;
+ StubConnectFunc connect_func_ = nullptr;
+ StubDisconnectFunc disconnect_func_ = nullptr;
+ StubSendFunc send_func_ = nullptr;
+ std::queue<rpc_port_parcel_h> result_queue_;
+ std::queue<rpc_port_parcel_h> request_queue_;
+ mutable std::recursive_mutex mutex_;
+};
+)__cpp_cb";
+
} // namespace version2
} // namespace tidl
#include "idlc/gen/version2/cpp_stub_body_generator.hh"
+#include <libgen.h>
+
#include <utility>
#include "idlc/gen/version2/cpp_generator_base_cb.hh"
GenLogTag(stream, "RPC_PORT_STUB");
GenLogDefinition(stream);
GenVersionDefinition(stream);
+ GenExportAPI(stream);
+ GenLemAnonymousNamespace(stream);
GenNamespace(stream);
+ GenLemAPI(stream);
}
void CppStubBodyGenerator::OnFiniGen(std::ofstream& stream) {}
void CppStubBodyGenerator::GenNamespace(std::ofstream& stream) {
ReplaceAll(CB_NAMESPACE_STUB)
.ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
- .Change("<STRUCTURES>", GenStructures())
+ .Change("<STRUCTURES>", GenLemBaseWithStructures())
.Change("<BASE_IMPL>", GenBaseImpl())
.Change("<INTERFACES>", GenInterfaces())
.Transform([&](std::string str) { return SmartIndent(str); })
.Out(stream);
}
+void CppStubBodyGenerator::GenLemAnonymousNamespace(std::ofstream& stream) {
+ ReplaceAll(CB_LEM_ANONYMOUS_NAMESPACE)
+ .Change("<LEM_CONTEXT>", GenLemContext())
+ .Transform([&](std::string code) { return SmartIndent(code); })
+ .Out(stream);
+}
+
+std::string CppStubBodyGenerator::GenLemContext() {
+ std::string code;
+ for (const auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<Interface&>(*block);
+ code += ReplaceAll(CB_LEM_CONTEXT)
+ .Change("<IFACE_NAME>", iface.GetID())
+ .ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace());
+ }
+
+ return RemoveLine(code);
+}
+
+void CppStubBodyGenerator::GenLemAPI(std::ofstream& stream) {
+ std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
+ input = input.substr(0, input.find_last_of("."));
+ std::string code = NLine(1);
+ for (const auto& block : GetDocument().GetBlocks()) {
+ if (block->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<Interface&>(*block);
+ code += ReplaceAll(CB_LEM_API)
+ .Change("<CLS_NAME>", iface.GetID())
+ .ChangeToLower("<INPUT_FILE>", input);
+ code += NLine(1);
+ }
+
+ stream << SmartIndent(code);
+}
+
+std::string CppStubBodyGenerator::GenLemBaseWithStructures() {
+ std::string input = basename(const_cast<char*>(options_->GetInput().c_str()));
+ input = input.substr(0, input.find_last_of("."));
+ std::string code;
+ code += ReplaceAll(CB_LEM_BASE).ChangeToLower("<INPUT_FILE>", input);
+ code += NLine(1);
+ code += GenStructures();
+ return code;
+}
+
std::string CppStubBodyGenerator::GenBaseImpl() {
std::string code = GenRemoteException();
code += GenUnitMap();
std::string CppStubBodyGenerator::GenInterfaceCallbacks(
const Interface& iface) {
std::string code;
+ code += ReplaceAll(CB_INTERFACE_CALKBACBASE_BASE)
+ .Change("<IFACE_NAME>", iface.GetID());
+ code += NLine(1);
for (const auto& decl : iface.GetDeclarations()) {
if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
continue;
- if (code.empty()) {
- code += ReplaceAll(CB_INTERFACE_CALKBACBASE_BASE)
- .Change("<IFACE_NAME>", iface.GetID());
- code += NLine(1);
- }
-
code += ReplaceAll(CB_INTERFACE_CALLBACK)
.Change("<IFACE_NAME>", iface.GetID())
.Change("<CLS_NAME>", decl->GetID())
private:
void GenIncludeStubBodyHeader(std::ofstream& stream);
+ void GenLemAnonymousNamespace(std::ofstream& stream);
+ std::string GenLemContext();
+ void GenLemAPI(std::ofstream& stream);
void GenNamespace(std::ofstream& stream);
+ std::string GenLemBaseWithStructures();
std::string GenBaseImpl();
std::string GenInterfaces();
std::string GenInterface(const Interface& iface);
std::string <IFACE_NAME>::CallbackBase::GetTag() const {
return std::to_string(id_) + "::" + std::to_string(seq_id_);
}
+
+void <IFACE_NAME>::CallbackBase::SetContext(void* context) {
+ context_ = context;
+}
+
+void* <IFACE_NAME>::CallbackBase::GetContext() const {
+ return context_;
+}
)__cpp_cb";
/**
constexpr const char CB_INTERFACE_CALLBACK[] =
R"__cpp_cb(
void <IFACE_NAME>::<CLS_NAME>::Invoke(<PARAMS>) {
- if (callback_port_ == nullptr)
+ if (callback_port_ == nullptr && GetContext() == nullptr)
throw NotConnectedSocketException();
if (service_.lock().get() == nullptr)
rpc_port_parcel_create(&parcel_);
unit_map_.Serialize(parcel_);
- set_last_result(rpc_port_parcel_send(parcel_, callback_port_));
+ if (GetContext() != nullptr) {
+ <IFACE_NAME>_context_->InvokeCallback(GetContext(), parcel_);
+ set_last_result(RPC_PORT_ERROR_NONE);
+ } else {
+ set_last_result(rpc_port_parcel_send(parcel_, callback_port_));
+ }
+
rpc_port_parcel_destroy(parcel_);
valid_ = false;
}
<IMPL_SERVICE_BASE_DISPATCH_FUNCS>
+void <CLS_NAME>::ServiceBase::SetContext(void* context) {
+ context_ = context;
+}
+
+void* <CLS_NAME>::ServiceBase::GetContext() const {
+ return context_;
+}
+
<CLS_NAME>::<CLS_NAME>() {
_W("<CLS_NAME> ctor");
int ret = rpc_port_stub_create(&stub_, "<CLS_NAME>");
rpc_port_stub_add_connected_event_cb(stub_, OnConnectedCb, this);
rpc_port_stub_add_disconnected_event_cb(stub_, OnDisconnectedCb, this);
rpc_port_stub_add_received_event_cb(stub_, OnReceivedCb, this);
+
+ <CLS_NAME>_context_ = std::make_unique<LocalExecution>("<CLS_NAME>", this);
}
<CLS_NAME>::~<CLS_NAME>() {
_W("<CLS_NAME> dtor");
+ <CLS_NAME>_context_.reset();
for (auto& service : services_)
service->OnTerminate();
if (ret == RPC_PORT_ERROR_INVALID_PARAMETER || ret == RPC_PORT_ERROR_IO_ERROR)
throw InvalidIOException();
}
+
+ <CLS_NAME>_context_->SetListening(true);
}
void <CLS_NAME>::OnConnectedCb(const char* sender, const char* instance, void* user_data) {
service->Dispatch(port, callback_port, parcel, service);
return ret;
}
+
+void <CLS_NAME>::OnLocalConnected(void* context, const std::string& sender, const std::string& instance) {
+ auto service = service_factory_->CreateService(sender, instance);
+ service->SetContext(context);
+ service->OnCreate();
+ services_.emplace_back(std::move(service));
+ <CLS_NAME>_context_->Connect(context);
+}
+
+void <CLS_NAME>::OnLocalDisconnected(void* context, const std::string& sender, const std::string& instance) {
+ auto iter = services_.begin();
+ while (iter != services_.end()) {
+ if ((*iter)->GetInstance() == instance) {
+ (*iter)->OnTerminate();
+ iter = services_.erase(iter);
+ break;
+ }
+
+ iter++;
+ }
+
+ <CLS_NAME>_context_->Disconnect(context);
+}
+
+void <CLS_NAME>::OnLocalReceived(void* context, rpc_port_parcel_h parcel) {
+ std::shared_ptr<ServiceBase> service;
+ for (auto& iter : services_) {
+ if (iter->GetContext() == context) {
+ service = iter;
+ break;
+ }
+ }
+
+ if (service.get() == nullptr) {
+ _E("Failed to find <CLS_NAME> context. context(%p)", context);
+ return;
+ }
+
+ rpc_port_parcel_h p = Clone(parcel);
+ service->Dispatch(nullptr, nullptr, p, service);
+}
)__cpp_cb";
/**
rpc_port_parcel_header_set_seq_num(header_, seq_num);
map_.Serialize(parcel_);
- rpc_port_parcel_send(parcel_, port);
+ if (GetContext() != nullptr)
+ <IFACE_NAME>_context_->SendResult(GetContext(), parcel_);
+ else
+ rpc_port_parcel_send(parcel_, port);
rpc_port_parcel_destroy(parcel_);
}
)__cpp_cb";
constexpr const char CB_INTERFACE_SERVICE_BASE_PARAM_DELEGATE[] =
R"__cpp_cb(
<TYPE> <NAME>(new <TYPE_NAME>(callback_port, std::weak_ptr<ServiceBase>(this->shared_from_this())));
+<NAME>->SetContext(GetContext());
)__cpp_cb";
/**
}
)__cpp_cb";
+/**
+ * <LEM_CONTEXT> The context of the local execution of the interface.
+ */
+constexpr const char CB_LEM_ANONYMOUS_NAMESPACE[] =
+R"__cpp_cb(
+namespace {
+
+rpc_port_parcel_h Clone(rpc_port_parcel_h parcel) {
+ void* raw = nullptr;
+ unsigned int size = 0;
+ rpc_port_parcel_get_raw(parcel, &raw, &size);
+
+ rpc_port_parcel_h handle = nullptr;
+ rpc_port_parcel_create_from_raw(&handle, raw, size);
+ return handle;
+}
+
+<LEM_CONTEXT>
+
+} // namespace
+)__cpp_cb";
+
+/**
+ * <FILE_NAMESPACE> The file namespace.
+ * <IFACE_NAME> The interface name.
+ */
+constexpr const char CB_LEM_CONTEXT[] =
+R"__cpp_cb(
+std::shared_ptr<rpc_port::<FILE_NAMESPACE>::LocalExecution> <IFACE_NAME>_context_;
+)__cpp_cb";
+
+/**
+ * <INPUT_FILE> The file namespace.
+ */
+constexpr const char CB_LEM_BASE[] =
+R"__cpp_cb(
+LocalExecution::LocalExecution(std::string port_name, LocalExecution::IEvent* listener) : port_name_(std::move(port_name)), listener_(listener) {
+ LoadSymbols();
+}
+
+void LocalExecution::Connect(void* context) {
+ if (connect_func_ != nullptr)
+ connect_func_(context);
+}
+
+void LocalExecution::Disconnect(void* context) {
+ if (disconnect_func_ != nullptr)
+ disconnect_func_(context);
+}
+
+void LocalExecution::SendResult(void* context, rpc_port_parcel_h parcel) {
+ if (send_result_func_ != nullptr)
+ send_result_func_(context, parcel);
+}
+
+void LocalExecution::InvokeCallback(void* context, rpc_port_parcel_h parcel) {
+ if (invoke_callback_func_ != nullptr)
+ invoke_callback_func_(context, parcel);
+}
+
+void LocalExecution::OnConnected(void* context, const std::string& sender, const std::string& instance) {
+ if (listener_ != nullptr)
+ listener_->OnLocalConnected(context, sender, instance);
+}
+
+void LocalExecution::OnDisconnected(void* context, const std::string& sender, const std::string& instance) {
+ if (listener_ != nullptr)
+ listener_->OnLocalDisconnected(context, sender, instance);
+}
+
+void LocalExecution::OnReceived(void* context, rpc_port_parcel_h parcel) {
+ if (listener_ != nullptr)
+ listener_->OnLocalReceived(context, parcel);
+}
+
+bool LocalExecution::LoadSymbols() {
+ if (loaded_)
+ return true;
+
+ std::string symbol = "rpc_port_proxy_<INPUT_FILE>_lem_" + port_name_ + "_connect";
+ connect_func_ = reinterpret_cast<ProxyConnectFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+ if (connect_func_ == nullptr) {
+ _E("Failed to find symbol");
+ return false;
+ }
+
+ symbol = "rpc_port_proxy_<INPUT_FILE>_lem_" + port_name_ + "_disconnect";
+ disconnect_func_ = reinterpret_cast<ProxyDisconnectFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+ if (disconnect_func_ == nullptr) {
+ _E("Failed to find symbol");
+ return false;
+ }
+
+ symbol = "rpc_port_proxy_<INPUT_FILE>_lem_" + port_name_ + "_send_result";
+ send_result_func_ = reinterpret_cast<ProxySendResultFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+ if (send_result_func_ == nullptr) {
+ _E("Failed to find symbol");
+ return false;
+ }
+
+ symbol = "rpc_port_proxy_<INPUT_FILE>_lem_" + port_name_ + "_invoke_callback";
+ invoke_callback_func_ = reinterpret_cast<ProxyInvokeCallbackFunc>(dlsym(RTLD_DEFAULT, symbol.c_str()));
+ if (invoke_callback_func_ == nullptr) {
+ _E("Failed to find symbol");
+ return false;
+ }
+
+ loaded_ = true;
+ return true;
+}
+
+void LocalExecution::SetListening(bool listening) {
+ listening_ = listening;
+}
+
+bool LocalExecution::IsListening() const {
+ return listening_;
+}
+)__cpp_cb";
+
+/**
+ * <INPUT_FILE> The input file name.
+ * <CLS_NAME> The interface name.
+ */
+constexpr const char CB_LEM_API[] =
+R"__cpp_cb(
+EXPORT_API int rpc_port_stub_<INPUT_FILE>_lem_<CLS_NAME>_connect(void* context, const char* sender, const char* instance) {
+ if (<CLS_NAME>_context_.get() == nullptr || !<CLS_NAME>_context_->IsListening()) {
+ _E("Server is not ready");
+ return RPC_PORT_ERROR_IO_ERROR;
+ }
+
+ <CLS_NAME>_context_->OnConnected(context, sender, instance);
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_stub_<INPUT_FILE>_lem_<CLS_NAME>_disconnect(void* context, const char* sender, const char* instance) {
+ if (<CLS_NAME>_context_.get() == nullptr || !<CLS_NAME>_context_->IsListening()) {
+ _E("Server is not ready");
+ return RPC_PORT_ERROR_IO_ERROR;
+ }
+
+ <CLS_NAME>_context_->OnDisconnected(context, sender, instance);
+ return RPC_PORT_ERROR_NONE;
+}
+
+EXPORT_API int rpc_port_stub_<INPUT_FILE>_lem_<CLS_NAME>_send(void* context, rpc_port_parcel_h parcel) {
+ if (<CLS_NAME>_context_.get() == nullptr || !<CLS_NAME>_context_->IsListening()) {
+ _E("Server is not ready");
+ return RPC_PORT_ERROR_IO_ERROR;
+ }
+
+ <CLS_NAME>_context_->OnReceived(context, parcel);
+ return RPC_PORT_ERROR_NONE;
+}
+)__cpp_cb";
+
} // namespace version2
} // namespace tidl
void CppStubHeaderGenerator::GenNamespace(std::ofstream& stream) {
ReplaceAll(CB_NAMESPACE_STUB)
.ChangeToLower("<FILE_NAMESPACE>", GetFileNamespace())
- .Change("<STRUCTURES>", GenStructuresForHeader())
+ .Change("<STRUCTURES>", GenLemBaseWithStructures())
.Change("<BASE_IMPL>", GenBaseImpl())
.Change("<INTERFACES>", GenInterfaces())
.Transform([&](std::string str) { return SmartIndent(str); })
.Out(stream);
}
+std::string CppStubHeaderGenerator::GenLemBaseWithStructures() {
+ std::string code = CB_LEM_BASE;
+ code += NLine(1);
+ code += GenStructuresForHeader();
+ return code;
+}
+
std::string CppStubHeaderGenerator::GenBaseImpl() {
std::string code = GenExceptions();
code += GenRemoteExceptionForHeader();
std::string CppStubHeaderGenerator::GenInterfaceCallbacks(
const Interface& iface) {
std::string code;
+ code += ReplaceAll(CB_INTERFACE_CALLBACK_BASE)
+ .Change("<IFACE_NAME>", iface.GetID());
+ code += NLine(1);
for (const auto& decl : iface.GetDeclarations()) {
if (decl->GetMethodType() != Declaration::MethodType::DELEGATE)
continue;
- if (code.empty()) {
- code += ReplaceAll(CB_INTERFACE_CALLBACK_BASE)
- .Change("<IFACE_NAME>", iface.GetID());
- code += NLine(1);
- }
-
code += ReplaceAll(CB_INTERFACE_CALLBACK)
.Change("<CLS_NAME>", decl->GetID())
.Change("<PARAMS>", GetParameters(decl->GetParameters()));
private:
void GenNamespace(std::ofstream& stream);
+ std::string GenLemBaseWithStructures();
std::string GenBaseImpl();
std::string GenInterfaces();
std::string GenInterface(const Interface& iface);
std::string GetTag() const;
+ void SetContext(void* context);
+ void* GetContext() const;
+
private:
static std::atomic<int> seq_num_;
int id_ = 0;
int seq_id_ = 0;
bool once_ = false;
+ void* context_ = nullptr;
};
)__cpp_cb";
*/
constexpr const char CB_INTERFACE_BASE[] =
R"__cpp_cb(
-class <CLS_NAME> {
+class <CLS_NAME> : public LocalExecution::IEvent {
public:
<ENUMS>
<CALLBACKS>
/// </summary>
virtual void OnTerminate() = 0;
+ void SetContext(void* context);
+ void* GetContext() const;
void Dispatch(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel, std::shared_ptr<ServiceBase> service);
void Dispatch(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel);
std::unordered_map<int, DispatchFunc> dispatch_funcs_;
std::unordered_map<int, std::vector<std::string>> privilege_map_;
std::unordered_set<std::string> privileges_;
+ void* context_ = nullptr;
};
<CLS_NAME>();
static void OnDisconnectedCb(const char* sender, const char* instance, void* user_data);
static int OnReceivedCb(const char* sender, const char* instance, rpc_port_h port, void* user_data);
+ void OnLocalConnected(void* context, const std::string& sender, const std::string& instance) override;
+ void OnLocalDisconnected(void* context, const std::string& sender, const std::string& instance) override;
+ void OnLocalReceived(void* context, rpc_port_parcel_h parcel) override;
+
private:
rpc_port_stub_h stub_ = nullptr;
std::shared_ptr<ServiceBase::Factory> service_factory_;
std::unique_ptr<ActiveObject> active_object_;
)__cpp_cb";
+constexpr const char CB_LEM_BASE[] =
+R"__cpp_cb(
+class LocalExecution {
+ public:
+ class IEvent {
+ public:
+ virtual ~IEvent() = default;
+ virtual void OnLocalConnected(void* context, const std::string& sender, const std::string& instance) = 0;
+ virtual void OnLocalDisconnected(void* context, const std::string& sender, const std::string& instance) = 0;
+ virtual void OnLocalReceived(void* context, rpc_port_parcel_h parcel) = 0;
+ };
+
+ LocalExecution(std::string port_name, IEvent* listener);
+ virtual ~LocalExecution() = default;
+
+ void Connect(void* context);
+ void Disconnect(void* context);
+ void SendResult(void* context, rpc_port_parcel_h parcel);
+ void InvokeCallback(void* context, rpc_port_parcel_h parcel);
+
+ void OnConnected(void* context, const std::string& sender, const std::string& instance);
+ void OnDisconnected(void* context, const std::string& sender, const std::string& instance);
+ void OnReceived(void* context, rpc_port_parcel_h parcel);
+
+ void SetListening(bool listening);
+ bool IsListening() const;
+
+ bool LoadSymbols();
+
+ private:
+ using ProxyConnectFunc = int (*)(void*);
+ using ProxyDisconnectFunc = int (*)(void*);
+ using ProxySendResultFunc = int (*)(void*, rpc_port_parcel_h);
+ using ProxyInvokeCallbackFunc = int (*)(void*, rpc_port_parcel_h);
+
+ private:
+ std::string port_name_;
+ IEvent* listener_;
+ bool listening_ = false;
+ bool loaded_ = false;
+ ProxyConnectFunc connect_func_ = nullptr;
+ ProxyDisconnectFunc disconnect_func_ = nullptr;
+ ProxySendResultFunc send_result_func_ = nullptr;
+ ProxyInvokeCallbackFunc invoke_callback_func_ = nullptr;
+};
+)__cpp_cb";
+
} // namespace version2
} // namespace tidl
void DefaultGenerator::GenCppProxyCode(std::shared_ptr<Options> options,
const Parser& ps) {
- CppProxyHeaderGenerator proxy_header(ps.GetDoc());
+ CppProxyHeaderGenerator proxy_header(ps.GetDoc(), options);
proxy_header.Run(options->GetOutput() + ".h");
- CppProxyBodyGenerator proxy_body(ps.GetDoc());
+ CppProxyBodyGenerator proxy_body(ps.GetDoc(), options);
proxy_body.Run(options->GetOutput() + ".cc");
}
FooPubsubCionGroupC.c
Message_v2ProxyC.c
Message_v2StubC.c
- Message_v2testProxyCpp.cc
- Message_v2testStubCpp.cc
Buffer_v2ProxyC.c
Buffer_v2StubC.c
Ex_v2ProxyC.c
Foo_v2StubC.c
Import_v2ProxyC.c
Import_v2StubC.c
+ Message_v2Proxy.cc
+ Message_v2Stub.cc
+ Buffer_v2Proxy.cc
+ Buffer_v2Stub.cc
+ Ex_v2Proxy.cc
+ Ex_v2Stub.cc
+ DataPort_v2Proxy.cc
+ DataPort_v2Stub.cc
+ Foo_v2Proxy.cc
+ Foo_v2Stub.cc
+ Import_v2Proxy.cc
+ Import_v2Stub.cc
)
ADD_CUSTOM_COMMAND(OUTPUT ${TIDL_GEN_SRCS} PRE_BUILD
OUTPUT="${FILES_V2[index]}StubC"
${TIDLC} -s -n -l C -i ${SCRIPT_DIR}/tidl/${INPUT} -o ${TARGET_DIR}/${OUTPUT}
- done
- INPUT="${FILES_V2[0]}test.tidl"
+ OUTPUT="${FILES_V2[index]}Proxy"
+ ${TIDLC} -p -n -l C++ -i ${SCRIPT_DIR}/tidl/${INPUT} -o ${TARGET_DIR}/${OUTPUT}
- OUTPUT="${FILES_V2[0]}testProxyCpp"
- ${TIDLC} -p -n -l C++ -i ${SCRIPT_DIR}/tidl/${INPUT} -o ${TARGET_DIR}/${OUTPUT}
+ OUTPUT="${FILES_V2[index]}Stub"
+ ${TIDLC} -s -n -l C++ -i ${SCRIPT_DIR}/tidl/${INPUT} -o ${TARGET_DIR}/${OUTPUT}
- OUTPUT="${FILES_V2[0]}testStubCpp"
- ${TIDLC} -s -n -l C++ -i ${SCRIPT_DIR}/tidl/${INPUT} -o ${TARGET_DIR}/${OUTPUT}
+ done
for index in ${!FILES_FOR_GROUP[*]}; do
echo "Generate ${FILES_FOR_GROUP[index]}"