summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHwankyu Jhun <h.jhun@samsung.com>2018-02-23 18:41:03 +0900
committerHwankyu Jhun <h.jhun@samsung.com>2018-02-27 08:21:37 +0900
commit042283ab4e20d7203ed024248d50f9e661f144c9 (patch)
tree56972be8cee3ec5caf41ab64eb53ae1e483e6e28
parent92e129cc86b84bcd8e449a3422dfca885d926ee4 (diff)
downloadtidl-042283ab4e20d7203ed024248d50f9e661f144c9.tar.gz
tidl-042283ab4e20d7203ed024248d50f9e661f144c9.tar.bz2
tidl-042283ab4e20d7203ed024248d50f9e661f144c9.zip
Implement C Proxy Generator (Interface part)
Change-Id: I0d3419ee6da56834e73a858bf114c64bb1db2c0b Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
-rw-r--r--idlc/c_gen/c_body_gen_base.cc8
-rw-r--r--idlc/c_gen/c_body_gen_base.h1
-rw-r--r--idlc/c_gen/c_proxy_body_gen.cc764
-rw-r--r--idlc/c_gen/c_proxy_body_gen.h46
-rw-r--r--idlc/c_gen/c_proxy_header_gen.cc121
-rw-r--r--idlc/c_gen/c_proxy_header_gen.h15
-rw-r--r--idlc/c_gen/c_stub_body_gen.cc8
-rw-r--r--idlc/c_gen/c_stub_body_gen.h1
8 files changed, 955 insertions, 9 deletions
diff --git a/idlc/c_gen/c_body_gen_base.cc b/idlc/c_gen/c_body_gen_base.cc
index b674ea6..cddd737 100644
--- a/idlc/c_gen/c_body_gen_base.cc
+++ b/idlc/c_gen/c_body_gen_base.cc
@@ -1267,12 +1267,4 @@ void CBodyGeneratorBase::GenInterfaceMethodEnumeration(
);
}
-void CBodyGeneratorBase::GenTypedefStubMethod(std::ofstream& stream) {
- const char format[] =
- "typedef int (*stub_method)(rpc_port_h, rpc_port_parcel_h, void* data);\n";
-
- stream << NLine(1);
- stream << std::string(format);
-}
-
} // namespace tidl
diff --git a/idlc/c_gen/c_body_gen_base.h b/idlc/c_gen/c_body_gen_base.h
index 5628279..b65a505 100644
--- a/idlc/c_gen/c_body_gen_base.h
+++ b/idlc/c_gen/c_body_gen_base.h
@@ -33,7 +33,6 @@ class CBodyGeneratorBase : public CGeneratorBase {
void GenStructures(std::ofstream& stream);
void GenIncludeHeader(std::ofstream& stream);
void GenLogTag(std::ofstream& stream, const std::string& log_tag);
- void GenTypedefStubMethod(std::ofstream& stream);
void GenInterfaceEnumerations(std::ofstream& stream, const Interface& inf);
std::string GetParcelWriteFunctionString(const BaseType& type,
bool meta_type = false);
diff --git a/idlc/c_gen/c_proxy_body_gen.cc b/idlc/c_gen/c_proxy_body_gen.cc
index 3cd5cfb..a98f5f3 100644
--- a/idlc/c_gen/c_proxy_body_gen.cc
+++ b/idlc/c_gen/c_proxy_body_gen.cc
@@ -27,10 +27,774 @@ void CProxyBodyGen::OnInitGen(std::ofstream& stream) {
GenIncludeDefaultHeaders(stream);
GenIncludeHeader(stream);
GenLogTag(stream, std::string("RPC_PORT_PROXY"));
+ GenTypedefProxyDelegate(stream);
GenStructures(stream);
+ GenInterfaces(stream);
}
void CProxyBodyGen::OnFiniGen(std::ofstream& stream) {
}
+void CProxyBodyGen::GenTypedefProxyDelegate(std::ofstream& stream) {
+ const char format[] =
+ "typedef void (*proxy_delegate)(GList* list, rpc_port_parcel_h parcel, int seq_id);\n";
+ stream << NLine(1);
+ stream << std::string(format);
+}
+
+void CProxyBodyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &inf = static_cast<const Interface&>(*i);
+ GenInterface(stream, inf);
+ }
+}
+
+void CProxyBodyGen::GenInterface(std::ofstream& stream, const Interface& inf) {
+ GenInterfaceEnumerations(stream, inf);
+ GenInterfaceDeclaration(stream, inf);
+ GenInterfaceDelegators(stream, inf);
+ GenInterfaceDelegatorTable(stream, inf);
+ GenInterfaceDelegatorHandler(stream, inf);
+ GenInterfaceConsumeCommand(stream, inf);
+ GenInterfaceOnConnectedEventCB(stream, inf);
+ GenInterfaceOnDisconnectedEventCB(stream, inf);
+ GenInterfaceOnRejectedEventCB(stream, inf);
+ GenInterfaceOnReceivedEventCB(stream, inf);
+ GenInterfaceMethods(stream, inf);
+ GenInterfaceConstructor(stream, inf);
+ GenInterfaceDestructor(stream, inf);
+ GenInterfaceConnect(stream, inf);
+ GenInterfaceDisconnect(stream, inf);
+}
+
+void CProxyBodyGen::GenInterfaceDeclaration(std::ofstream& stream,
+ const Interface& inf) {
+ const char block[] =
+ "struct ##_s {\n" \
+ " char* stub_appid;\n" \
+ " rpc_port_proxy_h proxy;\n" \
+ " rpc_port_h port;\n" \
+ " rpc_port_proxy_##_callback_s callback;\n" \
+ " void* user_data;\n" \
+ " GList* delegates;\n" \
+ "};\n";
+ stream << NLine(1);
+ stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+}
+
+void CProxyBodyGen::GenInterfaceDelegators(std::ofstream& stream,
+ const Interface& inf) {
+ for (auto& i : inf.GetDeclarations().GetDecls()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+ GenInterfaceDelegator(stream, inf.GetID(), *i);
+ }
+}
+
+void CProxyBodyGen::GenInterfaceDelegator(std::ofstream& stream,
+ const std::string& id,
+ const Declaration& decl) {
+ GenInterfaceDelegatorDeclaration(stream, id, decl);
+ GenInterfaceDelegatorSerializer(stream, id, decl);
+ GenInterfaceDelegatorDeserializer(stream, id, decl);
+ GenInterfaceDelegatorConstructor(stream, id, decl);
+ GenInterfaceDelegatorInvoker(stream, id, decl);
+}
+
+void CProxyBodyGen::GenInterfaceDelegatorDeclaration(
+ std::ofstream& stream, const std::string& id, const Declaration& decl) {
+ const char block[] =
+ "struct ##_s {\n" \
+ " rpc_port_parcelable_t parcelable;\n" \
+ " int id;\n" \
+ " int seq_id;\n" \
+ " ## callback;\n" \
+ "};\n";
+ stream << NLine(1);
+ stream << SmartIndent(ReplaceAll(block, "##", decl.GetID()));
+}
+
+void CProxyBodyGen::GenInterfaceDelegatorSerializer(
+ std::ofstream& stream, const std::string& id, const Declaration& decl) {
+ const char block[] =
+ "static void __##_to(rpc_port_parcel_h parcel, void* data)\n" \
+ "{\n" \
+ " struct ##_s* handle = data;\n" \
+ "\n" \
+ " if (!handle) {\n" \
+ " LOGE(\"Invalid parameter\");\n" \
+ " return;\n" \
+ " }\n" \
+ "\n" \
+ " rpc_port_parcel_write_int32(parcel, handle->id);\n" \
+ " rpc_port_parcel_write_int32(parcel, handle->seq_id);\n" \
+ "}\n";
+ stream << NLine(1);
+ stream << SmartIndent(ReplaceAll(block, "##", decl.GetID()));
+}
+
+void CProxyBodyGen::GenInterfaceDelegatorDeserializer(
+ std::ofstream& stream, const std::string& id, const Declaration& decl) {
+ const char block[] =
+ "static void __##_from(rpc_port_parcel_h parcel, void* data)\n" \
+ "{\n" \
+ " struct ##_s* handle = data;\n" \
+ "\n" \
+ " if (!handle) {\n" \
+ " LOGE(\"Invalid parameter\");\n" \
+ " return;\n" \
+ " }\n" \
+ "\n" \
+ " rpc_port_parcel_read_int32(parcel, &handle->id);\n" \
+ " rpc_port_parcel_read_int32(parcel, &handle->seq_id);\n" \
+ "}\n";
+ stream << NLine(1);
+ stream << SmartIndent(ReplaceAll(block, "##", decl.GetID()));
+}
+
+void CProxyBodyGen::GenInterfaceDelegatorConstructor(
+ std::ofstream& stream, const std::string& id, const Declaration& decl) {
+ const char block[] =
+ "static struct ##_s* __create_##(## callback)\n" \
+ "{\n" \
+ " struct ##_s* handle;\n" \
+ " static int seq_num;\n" \
+ "\n" \
+ " handle = calloc(1, sizeof(struct ##_s));\n" \
+ " if (!handle) {\n" \
+ " LOGE(\"Out of memory\");\n" \
+ " return NULL;\n" \
+ " }\n" \
+ "\n" \
+ " handle->parcelable.to = __##_to;\n" \
+ " handle->parcelable.from= __##_from;\n" \
+ " handle->id = $$_DELEGATE_##;\n" \
+ " handle->seq_id = seq_num++;\n" \
+ " handle->callback = callback;\n" \
+ "\n" \
+ " return handle;\n" \
+ "}\n";
+ stream << NLine(1);
+ stream << SmartIndent(GenTemplateString(ReplaceAll(block, "##", decl.GetID()),
+ [&]()->std::string {
+ return id;
+ }
+ )
+ );
+}
+
+void CProxyBodyGen::GenInterfaceDelegatorInvoker(
+ std::ofstream& stream, const std::string& id, const Declaration& decl) {
+ const char parcel[] = "$$(parcel, $$);\n";
+ const char block[] =
+ "static void __$$_delegate_##(GList *list, rpc_port_parcel_h parcel, int seq_id)\n" \
+ "{\n" \
+ "$$" \
+ " do {\n" \
+ " struct ##_s* handle;\n" \
+ " GList* iter;\n" \
+ "\n" \
+ " iter = list;\n" \
+ " while (iter) {\n" \
+ " handle = (struct ##_s*)iter->data;\n" \
+ " if (handle->seq_id == seq_id) {\n" \
+ " $$" \
+ " break;\n" \
+ " }\n" \
+ " iter = g_list_next(iter);\n" \
+ " }\n" \
+ " } while (0);\n" \
+ "$$" \
+ "}\n";
+ stream << NLine(1);
+ stream << SmartIndent(GenTemplateString(ReplaceAll(block, "##", decl.GetID()),
+ [&]()->std::string {
+ return id;
+ },
+ [&]()->std::string {
+ std::string str;
+ int cnt = 0;
+ for (auto& i : decl.GetParameters().GetParams()) {
+ str += GetParcelParamTypeString(
+ i->GetParameterType().GetBaseType()) +
+ " " + i->GetID() + ";" + NLine(1);
+ cnt++;
+ }
+ if (cnt > 0)
+ str += NLine(1);
+ for (auto& i: decl.GetParameters().GetParams()) {
+ if (i->GetParameterType().GetBaseType().IsUserDefinedType() ||
+ i->GetParameterType().GetBaseType().ToString() == "list" ||
+ i->GetParameterType().GetBaseType().ToString() == "array") {
+ str += GetConstructorString(i->GetParameterType().GetBaseType(),
+ i->GetID());
+ }
+ str += GenTemplateString(parcel,
+ [&]()->std::string {
+ return GetParcelReadFunctionString(
+ i->GetParameterType().GetBaseType(), true);
+ },
+ [&]()->std::string {
+ if (i->GetParameterType().GetBaseType().IsUserDefinedType() ||
+ i->GetParameterType().GetBaseType().ToString() == "list" ||
+ i->GetParameterType().GetBaseType().ToString() == "array")
+ return "&" + i->GetID() + "->parcelable, " + i->GetID();
+ return "&" + i->GetID();
+ }
+ );
+ }
+ return str;
+ },
+ [&]()->std::string {
+ std::string str;
+ str += "handle->callback(";
+ int cnt = 1;
+ for (auto& i: decl.GetParameters().GetParams()) {
+ if (cnt != 1)
+ str += ", ";
+ str += i->GetID();
+ cnt++;
+ }
+ str += ");" + NLine(1);
+ return str;
+ },
+ [&]()->std::string {
+ std::string str;
+ for (auto& i: decl.GetParameters().GetParams()) {
+ str += GetDestructorString(i->GetParameterType().GetBaseType(),
+ i->GetID());
+ }
+ return str;
+ }
+ )
+ );
+}
+
+void CProxyBodyGen::GenInterfaceDelegatorTable(std::ofstream& stream,
+ const Interface& inf) {
+ const char block[] =
+ "static proxy_delegate __$$_delegate_table[] = {\n" \
+ "$$" \
+ "};\n";
+ const char delegate_format[] = "[$$] = $$,\n";
+ std::string str;
+ int cnt = 0;
+
+ for (auto& i : inf.GetDeclarations().GetDecls()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+ str += GenTemplateString(delegate_format,
+ [&]()->std::string {
+ return inf.GetID() + "_DELEGATE_" + i->GetID();
+ },
+ [&]()->std::string {
+ return "__" + inf.GetID() + "_delegate_" + i->GetID();
+ }
+ );
+ cnt++;
+ }
+
+ if (cnt == 0)
+ return;
+
+ stream << NLine(1);
+ stream << SmartIndent(GenTemplateString(block,
+ [&]()->std::string {
+ return inf.GetID();
+ },
+ [&]()->std::string {
+ return str;
+ }
+ )
+ );
+}
+
+void CProxyBodyGen::GenInterfaceDelegatorHandler(std::ofstream& stream,
+ const Interface& inf) {
+ const char block[] =
+ "static void __##_process_received_event(GList* list, rpc_port_parcel_h parcel)\n" \
+ "{\n" \
+ "$$" \
+ "}\n";
+ const char impl_block[] =
+ "int id;\n" \
+ "int seq_id;\n" \
+ "\n" \
+ "rpc_port_parcel_read_int32(parcel, &id);\n" \
+ "rpc_port_parcel_read_int32(parcel, &seq_id);\n" \
+ "\n" \
+ "if (id > 0 && id < (sizeof(__Message_delegate_table) / sizeof(__Message_delegate_table[0]))) {\n" \
+ " if (__Message_delegate_table[id])\n" \
+ " __Message_delegate_table[id](list, parcel, seq_id);\n" \
+ "} else {\n" \
+ " LOGW(\"Unknown id(%d)\", id);\n" \
+ "}\n";
+ std::string str;
+ int cnt = 0;
+
+ for (auto& i : inf.GetDeclarations().GetDecls()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+ cnt++;
+ }
+ stream << NLine(1);
+ stream << SmartIndent(GenTemplateString(ReplaceAll(block, "##", inf.GetID()),
+ [&]()->std::string {
+ if (cnt == 0)
+ return str;
+ return ReplaceAll(impl_block, "##", inf.GetID());
+ }
+ )
+ );
+}
+
+void CProxyBodyGen::GenInterfaceConsumeCommand(std::ofstream& stream,
+ const Interface& inf) {
+ const char block[] =
+ "static rpc_port_parcel_h __##_consume_command(rpc_port_proxy_##_h h)\n" \
+ "{\n" \
+ " rpc_port_parcel_h parcel = NULL;\n" \
+ " int cmd = -1;\n" \
+ "\n" \
+ " do {\n" \
+ " rpc_port_parcel_create_from_port(&parcel, h->port);\n" \
+ " if (!parcel)\n" \
+ " break;\n" \
+ "\n" \
+ " rpc_port_parcel_read_int32(parcel, &cmd);\n" \
+ " if (cmd == ##_METHOD_Result)\n" \
+ " return parcel;\n" \
+ "\n" \
+ " __##_process_received_event(h->delegates, parcel);\n" \
+ " rpc_port_parcel_destroy(parcel);\n" \
+ " parcel = NULL;\n" \
+ " } while (true);\n" \
+ "\n" \
+ " return NULL;\n" \
+ "}\n";
+ stream << NLine(1);
+ stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+}
+
+void CProxyBodyGen::GenInterfaceOnConnectedEventCB(std::ofstream& stream,
+ const Interface& inf) {
+ const char block[] =
+ "static void __##_on_connected(const char* endpoint, const char* port_name, rpc_port_h port, void* data)\n" \
+ "{\n" \
+ " rpc_port_proxy_##_h handle = data;\n" \
+ "\n" \
+ " handle->port = port;\n" \
+ " if (handle->callback.connected)\n" \
+ " handle->callback.connected(handle, handle->user_data);\n" \
+ " LOGI(\"[__RPC_PORT__] endpoint(%s), port_name(%s)\", endpoint, port_name);\n" \
+ "}\n";
+ stream << NLine(1);
+ stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+}
+
+void CProxyBodyGen::GenInterfaceOnDisconnectedEventCB(std::ofstream& stream,
+ const Interface& inf) {
+ const char block[] =
+ "static void __##_on_disconnected(const char* endpoint, const char* port_name, void* data)\n" \
+ "{\n" \
+ " rpc_port_proxy_##_h handle = data;\n" \
+ "\n" \
+ " handle->port = NULL;\n" \
+ " if (handle->callback.disconnected)\n" \
+ " handle->callback.disconnected(handle, handle->user_data);\n" \
+ " LOGI(\"[__RPC_PORT__] endpoint(%s), port_name(%s)\", endpoint, port_name);\n" \
+ "}\n";
+ stream << NLine(1);
+ stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+}
+
+void CProxyBodyGen::GenInterfaceOnRejectedEventCB(std::ofstream& stream,
+ const Interface& inf) {
+ const char block[] =
+ "static void __##_on_rejected(const char* endpoint, const char* port_name, void* data)\n" \
+ "{\n" \
+ " rpc_port_proxy_##_h handle = data;\n" \
+ "\n" \
+ " handle->port = NULL;\n" \
+ " if (handle->callback.rejected)\n" \
+ " handle->callback.rejected(handle, handle->user_data);\n" \
+ " LOGI(\"[__RPC_PORT__] endpoint(%s), port_name(%s)\", endpoint, port_name);\n" \
+ "}\n";
+ stream << NLine(1);
+ stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+}
+
+void CProxyBodyGen::GenInterfaceOnReceivedEventCB(std::ofstream& stream,
+ const Interface& inf) {
+ const char block[] =
+ "static void __##_on_received(const char* endpoint, const char* port_name, void* data)\n" \
+ "{\n" \
+ " rpc_port_proxy_##_h handle = data;\n" \
+ " rpc_port_parcel_h parcel_received;\n" \
+ " int cmd = -1;\n" \
+ "\n" \
+ " rpc_port_parcel_create_from_port(&parcel_received, handle->port);\n" \
+ " rpc_port_parcel_read_int32(parcel_received, &cmd);\n" \
+ " if (cmd != ##_METHOD_Callback) {\n" \
+ " LOGE(\"Invalid protocol\");\n" \
+ " rpc_port_parcel_destroy(parcel_received);\n" \
+ " return;\n" \
+ " }\n" \
+ "\n" \
+ " __##_process_received_event(handle->delegates, parcel_received);\n" \
+ " rpc_port_parcel_destroy(parcel_received);\n" \
+ " LOGI(\"[__RPC_PORT__] endpoint(%s), port_name(%s)\", endpoint, port_name);\n" \
+ "}\n";
+ stream << NLine(1);
+ stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+}
+
+void CProxyBodyGen::GenInterfaceMethods(std::ofstream& stream,
+ const Interface& inf) {
+ const char block[] =
+ "$$ rpc_port_proxy_##_invoke_$$(rpc_port_proxy_##_h h$$)\n" \
+ "{\n" \
+ " rpc_port_parcel_h parcel;\n" \
+ "$$" \
+ "\n" \
+ " if (!h$$) {\n" \
+ " LOGE(\"Invalid parameter\");\n" \
+ " return$$;\n" \
+ " }\n" \
+ "\n" \
+ " if (!h->port) {\n" \
+ " LOGE(\"Not connected\");\n" \
+ " return$$;\n" \
+ " }\n" \
+ "\n" \
+ " rpc_port_parcel_create(&parcel);\n" \
+ " rpc_port_parcel_write_int32(parcel, ##_METHOD_$$);\n" \
+ "$$" \
+ " rpc_port_parcel_send(parcel, h->port);\n" \
+ " rpc_port_parcel_destroy(parcel);\n" \
+ "$$" \
+ "}\n";
+ const char delegate_block[] =
+ "do {\n" \
+ " struct ##_s* handle;\n" \
+ "\n" \
+ " handle = __create_##($$);\n" \
+ " if (!handle)\n" \
+ " break;\n" \
+ "\n" \
+ " rpc_port_parcel_write(parcel, &handle->parcelable, handle);\n" \
+ " h->delegates = g_list_append(h->delegates, handle);\n" \
+ "} while (0);\n";
+ const char receive_block[] =
+ "do {\n" \
+ " rpc_port_parcel_h parcel_received;\n" \
+ "\n" \
+ " parcel_received = __$$_consume_command(h);\n" \
+ " if (!parcel_received) {\n" \
+ " LOGE(\"Invalid protocol\");\n" \
+ " break;\n" \
+ " }\n" \
+ "\n" \
+ "$$" \
+ " rpc_port_parcel_destroy(parcel_received);\n" \
+ "} while (0);\n";
+ const char parcel[] = "$$($$, $$);\n";
+ for (auto& i : inf.GetDeclarations().GetDecls()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+ stream << NLine(1);
+ stream << SmartIndent(GenTemplateString(ReplaceAll(block, "##", inf.GetID()),
+ [&]()->std::string {
+ return GetReturnTypeString(i->GetType());
+ },
+ [&]()->std::string {
+ return i->GetID();
+ },
+ [&]()->std::string {
+ std::string str;
+ for (auto& p : i->GetParameters().GetParams()) {
+ str += ", ";
+ if (TypeIsDelegator(inf, p->GetParameterType().GetBaseType())) {
+ str += p->GetParameterType().GetBaseType().ToString() + " " +
+ p->GetID();
+ } else {
+ str += ConvertTypeToString(p->GetParameterType().GetDirection(),
+ p->GetParameterType().GetBaseType()) + " " + p->GetID();
+ }
+ }
+ return str;
+ },
+ [&]()->std::string {
+ if (GetReturnTypeString(i->GetType()) != "void")
+ return GetReturnTypeString(i->GetType()) + " ret = 0;" + NLine(1);
+ return "";
+ },
+ [&]()->std::string {
+ std::string str;
+ for (auto& p : i->GetParameters().GetParams()) {
+ if (p->GetParameterType().GetDirection() == ParameterType::Direction::OUT ||
+ p->GetParameterType().GetBaseType().IsUserDefinedType() ||
+ p->GetParameterType().GetBaseType().ToString() == "list" ||
+ p->GetParameterType().GetBaseType().ToString() == "array" ||
+ p->GetParameterType().GetBaseType().ToString() == "string" ||
+ p->GetParameterType().GetBaseType().ToString() == "bundle")
+ str += " || !" + p->GetID();
+ }
+ return str;
+ },
+ [&]()->std::string {
+ if (GetReturnTypeString(i->GetType()) != "void")
+ return " ret";
+ return "";
+ },
+ [&]()->std::string {
+ if (GetReturnTypeString(i->GetType()) != "void")
+ return " ret";
+ return "";
+ },
+ [&]()->std::string {
+ return i->GetID();
+ },
+ [&]()->std::string {
+ std::string str;
+ for (auto& p : i->GetParameters().GetParams()) {
+ if (p->GetParameterType().GetDirection() == ParameterType::Direction::OUT)
+ continue;
+ if (TypeIsDelegator(inf, p->GetParameterType().GetBaseType())) {
+ str += GenTemplateString(ReplaceAll(delegate_block,
+ "##", p->GetParameterType().GetBaseType().ToString()),
+ [&]()->std::string {
+ return p->GetID();
+ }
+ );
+ } else {
+ str += GenTemplateString(parcel,
+ [&]()->std::string {
+ return GetParcelWriteFunctionString(
+ p->GetParameterType().GetBaseType(), true);
+ },
+ [&]()->std::string {
+ return "parcel";
+ },
+ [&]()->std::string {
+ if (p->GetParameterType().GetBaseType().IsUserDefinedType() ||
+ p->GetParameterType().GetBaseType().ToString() == "list" ||
+ p->GetParameterType().GetBaseType().ToString() == "array")
+ return "&" + p->GetID() + "->parcelable, " + p->GetID();
+ return p->GetID();
+ }
+ );
+ }
+ }
+ return str;
+ },
+ [&]()->std::string {
+ std::string str;
+ if (i->GetMethodType() != Declaration::MethodType::SYNC)
+ return str;
+ str += GenTemplateString(receive_block,
+ [&]()->std::string {
+ return inf.GetID();
+ },
+ [&]()->std::string {
+ std::string s;
+ for (auto& p : i->GetParameters().GetParams()) {
+ if (p->GetParameterType().GetDirection() != ParameterType::Direction::OUT)
+ continue;
+ if (p->GetParameterType().GetBaseType().IsUserDefinedType() ||
+ p->GetParameterType().GetBaseType().ToString() == "list" ||
+ p->GetParameterType().GetBaseType().ToString() == "array") {
+ s += GetConstructorString(p->GetParameterType().GetBaseType(),
+ p->GetID() + "[0]");
+ }
+ s += GenTemplateString(parcel,
+ [&]()->std::string {
+ return GetParcelReadFunctionString(
+ p->GetParameterType().GetBaseType(), true);
+ },
+ [&]()->std::string {
+ return "parcel_received";
+ },
+ [&]()->std::string {
+ if (p->GetParameterType().GetBaseType().IsUserDefinedType() ||
+ p->GetParameterType().GetBaseType().ToString() == "list" ||
+ p->GetParameterType().GetBaseType().ToString() == "array")
+ return "" + p->GetID() + "->parcelable, *" + p->GetID();
+ return p->GetID();
+ }
+ );
+ }
+ if (GetReturnTypeString(i->GetType()) != "void") {
+ if (i->GetType().IsUserDefinedType() ||
+ i->GetType().ToString() == "list" ||
+ i->GetType().ToString() == "array") {
+ s += GetConstructorString(i->GetType(), "ret");
+ }
+ s += GenTemplateString(parcel,
+ [&]()->std::string {
+ return GetParcelReadFunctionString(i->GetType(), false);
+ },
+ [&]()->std::string {
+ return "parcel_received";
+ },
+ [&]()->std::string {
+ if (i->GetType().IsUserDefinedType() ||
+ i->GetType().ToString() == "list" ||
+ i->GetType().ToString() == "array")
+ return "&ret->parcelable, ret";
+ return "&ret";
+ }
+ );
+ }
+ return s;
+ }
+ );
+ if (GetReturnTypeString(i->GetType()) != "void") {
+ str += NLine(1);
+ str += "return ret;" + NLine(1);;
+ }
+ return str;
+ }
+ )
+ );
+ }
+}
+
+void CProxyBodyGen::GenInterfaceConstructor(std::ofstream& stream,
+ const Interface& inf) {
+ const char block[] =
+ "static struct ##_s* __create_##(const char* stub_appid, rpc_port_proxy_##_callback_s* callback, void* user_data)\n" \
+ "{\n" \
+ " struct ##_s* handle;\n" \
+ "\n" \
+ " handle = calloc(1, sizeof(struct ##_s));\n" \
+ " if (!handle) {\n " \
+ " LOGE(\"Out of memory\");\n" \
+ " return NULL;\n" \
+ " }\n" \
+ "\n" \
+ " handle->stub_appid = strdup(stub_appid);\n" \
+ " if (!handle->stub_appid) {\n" \
+ " LOGE(\"Out of memory\");\n" \
+ " free(handle);\n" \
+ " return NULL;\n" \
+ " }\n" \
+ "\n" \
+ " rpc_port_proxy_create(&handle->proxy);\n" \
+ " if (!handle->proxy) {\n" \
+ " LOGE(\"Failed to create proxy\");\n" \
+ " free(handle->stub_appid);\n" \
+ " free(handle);\n" \
+ " return NULL;\n" \
+ " }\n" \
+ "\n" \
+ " handle->callback = *callback;\n" \
+ " handle->user_data = user_data;\n" \
+ "\n" \
+ " return handle;\n" \
+ "}\n";
+ stream << NLine(1);
+ stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+}
+
+void CProxyBodyGen::GenInterfaceDestructor(std::ofstream& stream,
+ const Interface& inf) {
+ const char block[] =
+ "static void __destroy_##(struct ##_s* h)\n" \
+ "{\n" \
+ " if (!h)\n" \
+ " return;\n" \
+ "\n" \
+ " if (h->delegates)\n" \
+ " g_list_free_full(h->delegates, free);\n" \
+ " if (h->proxy)\n" \
+ " rpc_port_proxy_destroy(h->proxy);\n" \
+ " if (h->stub_appid)\n" \
+ " free(h->stub_appid);\n" \
+ " free(h);\n" \
+ "}\n";
+ stream << NLine(1);
+ stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+}
+
+void CProxyBodyGen::GenInterfaceConnect(std::ofstream& stream,
+ const Interface& inf) {
+ const char block[] =
+ "int rpc_port_proxy_##_connect(const char* stub_appid, rpc_port_proxy_##_callback_s* callback, void* user_data, rpc_port_proxy_##_h* h)\n" \
+ "{\n" \
+ " struct ##_s* handle;\n" \
+ " int r;\n" \
+ "\n" \
+ " if (!stub_appid || !callback || !h) {\n" \
+ " LOGE(\"Invalid parameter\");\n" \
+ " return -1;\n" \
+ " }\n" \
+ "\n" \
+ " handle = __create_##(stub_appid, callback, user_data);\n" \
+ " if (!handle)\n" \
+ " return -1;\n" \
+ "\n" \
+ " r = rpc_port_proxy_add_connected_event_cb(handle->proxy, __##_on_connected, handle);\n" \
+ " if (r != 0) {\n" \
+ " LOGE(\"Failed to add connected event cb. err = %d\", r);\n" \
+ " __destroy_##(handle);\n" \
+ " return r;\n" \
+ " }\n" \
+ "\n" \
+ " r = rpc_port_proxy_add_disconnected_event_cb(handle->proxy, __##_on_disconnected, handle);\n" \
+ " if (r != 0) {\n" \
+ " LOGE(\"Failed to add disconnected event cb. err = %d\", r);\n" \
+ " __destroy_##(handle);\n" \
+ " return r;\n" \
+ " }\n" \
+ "\n" \
+ " r = rpc_port_proxy_add_rejected_event_cb(handle->proxy, __##_on_rejected, handle);\n" \
+ " if (r != 0) {\n" \
+ " LOGE(\"Failed to add rejected event cb. err = %d\", r);\n" \
+ " __destroy_##(handle);\n" \
+ " return r;\n" \
+ " }\n" \
+ "\n" \
+ " r = rpc_port_proxy_add_received_event_cb(handle->proxy, __##_on_received, handle);\n" \
+ " if (r != 0) {\n" \
+ " LOGE(\"Failed to add received event cb. err = %d\", r);\n" \
+ " __destroy_##(handle);\n" \
+ " return r;\n" \
+ " }\n" \
+ "\n" \
+ " r = rpc_port_proxy_connect(handle->proxy, stub_appid, \"##\");\n" \
+ " if (r != 0) {\n" \
+ " LOGE(\"Failed to connect ##(%s)\", stub_appid);\n" \
+ " __destroy_##(handle);\n" \
+ " return r;\n" \
+ " }\n" \
+ "\n" \
+ " *h = handle;\n" \
+ "\n" \
+ " return 0;\n" \
+ "}\n";
+ stream << NLine(1);
+ stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+}
+
+void CProxyBodyGen::GenInterfaceDisconnect(std::ofstream& stream,
+ const Interface& inf) {
+ const char block[] =
+ "int rpc_port_proxy_##_disconnect(rpc_port_proxy_##_h h)\n" \
+ "{\n" \
+ " if (!h) {\n" \
+ " LOGE(\"Invalid parameter\");\n" \
+ " return -1;\n" \
+ " }\n" \
+ "\n" \
+ " __destroy_##(h);\n" \
+ " return 0;\n" \
+ "}\n";
+ stream << NLine(1);
+ stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
+}
+
} // namespace tidl
diff --git a/idlc/c_gen/c_proxy_body_gen.h b/idlc/c_gen/c_proxy_body_gen.h
index ecf4166..418d6dc 100644
--- a/idlc/c_gen/c_proxy_body_gen.h
+++ b/idlc/c_gen/c_proxy_body_gen.h
@@ -31,6 +31,52 @@ class CProxyBodyGen : public CBodyGeneratorBase {
void OnInitGen(std::ofstream& stream) override;
void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenTypedefProxyDelegate(std::ofstream& stream);
+ void GenInterfaces(std::ofstream& stream);
+
+ private:
+ void GenInterface(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDeclaration(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDelegators(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDelegatorTable(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDelegatorHandler(std::ofstream& stream,
+ const Interface& inf);
+ void GenInterfaceConsumeCommand(std::ofstream& stream,
+ const Interface& inf);
+ void GenInterfaceOnConnectedEventCB(std::ofstream& stream,
+ const Interface& inf);
+ void GenInterfaceOnDisconnectedEventCB(std::ofstream& stream,
+ const Interface& inf);
+ void GenInterfaceOnRejectedEventCB(std::ofstream& stream,
+ const Interface& inf);
+ void GenInterfaceOnReceivedEventCB(std::ofstream& stream,
+ const Interface& inf);
+ void GenInterfaceMethods(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceConstructor(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDestructor(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceConnect(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDisconnect(std::ofstream& stream, const Interface& inf);
+
+ private:
+ void GenInterfaceDelegator(std::ofstream& stream, const std::string& id,
+ const Declaration& decl);
+ void GenInterfaceDelegatorDeclaration(std::ofstream& stream,
+ const std::string& id,
+ const Declaration& decl);
+ void GenInterfaceDelegatorSerializer(std::ofstream& stream,
+ const std::string& id,
+ const Declaration& decl);
+ void GenInterfaceDelegatorDeserializer(std::ofstream& stream,
+ const std::string& id,
+ const Declaration& decl);
+ void GenInterfaceDelegatorConstructor(std::ofstream& stream,
+ const std::string& id,
+ const Declaration& decl);
+ void GenInterfaceDelegatorInvoker(std::ofstream& stream,
+ const std::string& id,
+ const Declaration& decl);
};
} // namespace tidl
diff --git a/idlc/c_gen/c_proxy_header_gen.cc b/idlc/c_gen/c_proxy_header_gen.cc
index 6e9652b..e67de32 100644
--- a/idlc/c_gen/c_proxy_header_gen.cc
+++ b/idlc/c_gen/c_proxy_header_gen.cc
@@ -27,10 +27,131 @@ void CProxyHeaderGen::OnInitGen(std::ofstream& stream) {
GenIncludeDefaultHeaders(stream, false);
GenExplicitLinkageOpen(stream);
GenStructures(stream);
+ GenInterfaces(stream);
}
void CProxyHeaderGen::OnFiniGen(std::ofstream& stream) {
GenExplicitLinkageClose(stream);
}
+void CProxyHeaderGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &inf = static_cast<const Interface&>(*i);
+ GenInterface(stream, inf);
+ }
+}
+
+void CProxyHeaderGen::GenInterface(std::ofstream& stream,
+ const Interface& inf) {
+ GenInterfaceDelegators(stream, inf);
+ GenInterfaceDeclaration(stream, inf);
+ GenInterfaceConnect(stream, inf);
+ GenInterfaceDisconnect(stream, inf);
+ GenInterfaceMethods(stream, inf);
+}
+
+void CProxyHeaderGen::GenInterfaceDelegators(std::ofstream& stream,
+ const Interface& inf) {
+ for (auto& i : inf.GetDeclarations().GetDecls()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+ GenInterfaceDelegator(stream, inf.GetID(), *i);
+ }
+}
+
+void CProxyHeaderGen::GenInterfaceDelegator(std::ofstream& stream,
+ const std::string& id,
+ const Declaration& decl) {
+ const char format[] = "typedef $$ (*$$)($$);\n";
+ stream << NLine(1);
+ stream << GenTemplateString(format,
+ [&]()->std::string {
+ return GetReturnTypeString(decl.GetType());
+ },
+ [&]()->std::string {
+ return decl.GetID();
+ },
+ [&]()->std::string {
+ std::string str;
+ int cnt = 1;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ if (cnt != 1)
+ str += ", ";
+ str += ConvertTypeToString(p->GetParameterType().GetDirection(),
+ p->GetParameterType().GetBaseType()) + " " + p->GetID();
+ cnt++;
+ }
+ return str;
+ }
+ );
+}
+
+void CProxyHeaderGen::GenInterfaceDeclaration(std::ofstream& stream,
+ const Interface& inf) {
+ const char format[] =
+ "typedef struct ##_s* rpc_port_proxy_##_h;\n" \
+ "\n" \
+ "typedef struct {\n" \
+ " void (*connected)(rpc_port_proxy_##_h h, void* user_data);\n" \
+ " void (*disconnected)(rpc_port_proxy_##_h h, void* user_data);\n" \
+ " void (*rejected)(rpc_port_proxy_##_h h, void* user_data);\n" \
+ "} rpc_port_proxy_##_callback_s;\n";
+ stream << NLine(1);
+ stream << SmartIndent(ReplaceAll(format, "##", inf.GetID()));
+}
+
+void CProxyHeaderGen::GenInterfaceMethods(std::ofstream& stream,
+ const Interface& inf) {
+ const char format[] =
+ "$$ rpc_port_proxy_##_invoke_$$(rpc_port_proxy_##_h h$$);\n";
+ for (auto& i : inf.GetDeclarations().GetDecls()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+ stream << NLine(1);
+ stream << GenTemplateString(ReplaceAll(format, "##", inf.GetID()),
+ [&]()->std::string {
+ return GetReturnTypeString(i->GetType());
+ },
+ [&]()->std::string {
+ return i->GetID();
+ },
+ [&]()->std::string {
+ std::string str;
+ for (auto& p : i->GetParameters().GetParams()) {
+ str += ", ";
+ if (TypeIsDelegator(inf, p->GetParameterType().GetBaseType())) {
+ str += p->GetParameterType().GetBaseType().ToString() + " " +
+ p->GetID();
+ } else {
+ str += ConvertTypeToString(p->GetParameterType().GetDirection(),
+ p->GetParameterType().GetBaseType()) + " " + p->GetID();
+ }
+ }
+ return str;
+ }
+ );
+ }
+}
+
+void CProxyHeaderGen::GenInterfaceConnect(std::ofstream& stream,
+ const Interface& inf) {
+ const char format[] =
+ "int rpc_port_proxy_##_connect(const char* stub_appid, " \
+ "rpc_port_proxy_##_callback_s* callback, void* user_data, " \
+ "rpc_port_proxy_##_h* h);\n";
+ stream << NLine(1);
+ stream << ReplaceAll(format, "##", inf.GetID());
+}
+
+void CProxyHeaderGen::GenInterfaceDisconnect(std::ofstream& stream,
+ const Interface& inf) {
+ const char format[] =
+ "int rpc_port_proxy_##_disconnect(rpc_port_proxy_##_h h);\n";
+ stream << NLine(1);
+ stream << ReplaceAll(format, "##", inf.GetID());
+}
+
} // namespace tidl
diff --git a/idlc/c_gen/c_proxy_header_gen.h b/idlc/c_gen/c_proxy_header_gen.h
index 07dc168..5957e96 100644
--- a/idlc/c_gen/c_proxy_header_gen.h
+++ b/idlc/c_gen/c_proxy_header_gen.h
@@ -31,6 +31,21 @@ class CProxyHeaderGen : public CHeaderGeneratorBase {
void OnInitGen(std::ofstream& stream) override;
void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenInterfaces(std::ofstream& stream);
+
+ private:
+ void GenInterface(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDeclaration(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDelegators(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceMethods(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceConnect(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDisconnect(std::ofstream& stream, const Interface& inf);
+
+ private:
+ void GenInterfaceDelegator(std::ofstream& stream, const std::string& id,
+ const Declaration& decl);
};
} // namespace tidl
diff --git a/idlc/c_gen/c_stub_body_gen.cc b/idlc/c_gen/c_stub_body_gen.cc
index ddfdb06..69df78e 100644
--- a/idlc/c_gen/c_stub_body_gen.cc
+++ b/idlc/c_gen/c_stub_body_gen.cc
@@ -909,4 +909,12 @@ void CStubBodyGen::GenInterfaceContextPortExist(std::ofstream& stream,
stream << SmartIndent(ReplaceAll(block, "##", inf.GetID()));
}
+void CStubBodyGen::GenTypedefStubMethod(std::ofstream& stream) {
+ const char format[] =
+ "typedef int (*stub_method)(rpc_port_h, rpc_port_parcel_h, void* data);\n";
+
+ stream << NLine(1);
+ stream << std::string(format);
+}
+
} // namespace tidl
diff --git a/idlc/c_gen/c_stub_body_gen.h b/idlc/c_gen/c_stub_body_gen.h
index 11a7b60..88f3b76 100644
--- a/idlc/c_gen/c_stub_body_gen.h
+++ b/idlc/c_gen/c_stub_body_gen.h
@@ -35,6 +35,7 @@ class CStubBodyGen : public CBodyGeneratorBase {
private:
void GenInterfaces(std::ofstream& stream);
void GenInterface(std::ofstream& stream, const Interface& inf);
+ void GenTypedefStubMethod(std::ofstream& stream);
void GenInterfaceMethods(std::ofstream& stream, const Interface& inf);
void GenInterfaceMethodTable(std::ofstream& stream, const Interface& inf);
void GenInterfaceOnConnectedEventCB(std::ofstream& stream,