diff options
author | Hwankyu Jhun <h.jhun@samsung.com> | 2018-02-23 18:41:03 +0900 |
---|---|---|
committer | Hwankyu Jhun <h.jhun@samsung.com> | 2018-02-27 08:21:37 +0900 |
commit | 042283ab4e20d7203ed024248d50f9e661f144c9 (patch) | |
tree | 56972be8cee3ec5caf41ab64eb53ae1e483e6e28 | |
parent | 92e129cc86b84bcd8e449a3422dfca885d926ee4 (diff) | |
download | tidl-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.cc | 8 | ||||
-rw-r--r-- | idlc/c_gen/c_body_gen_base.h | 1 | ||||
-rw-r--r-- | idlc/c_gen/c_proxy_body_gen.cc | 764 | ||||
-rw-r--r-- | idlc/c_gen/c_proxy_body_gen.h | 46 | ||||
-rw-r--r-- | idlc/c_gen/c_proxy_header_gen.cc | 121 | ||||
-rw-r--r-- | idlc/c_gen/c_proxy_header_gen.h | 15 | ||||
-rw-r--r-- | idlc/c_gen/c_stub_body_gen.cc | 8 | ||||
-rw-r--r-- | idlc/c_gen/c_stub_body_gen.h | 1 |
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, |