idlc/gen/c_proxy_header_gen.cc \
idlc/gen/c_stub_body_gen.cc \
idlc/gen/c_stub_header_gen.cc \
+ idlc/gen/c_group_body_gen.cc \
+ idlc/gen/c_group_header_gen.cc \
idlc/gen/cpp_gen_base.cc \
idlc/gen/cpp_proxy_body_gen.cc \
idlc/gen/cpp_proxy_header_gen.cc \
const std::map<std::string, std::unique_ptr<Structure>>& GetStructures();
void GenVersion(std::ofstream& stream);
- void GenIncludeDefaultHeaders(std::ofstream& stream, bool body = true);
+ virtual void GenIncludeDefaultHeaders(std::ofstream& stream, bool body = true);
void GenGNUSourceDefinition(std::ofstream& stream);
- std::string GetHandlePrefix();
+ virtual std::string GetHandlePrefix();
std::string RemoveLastSpaces(const std::string& str);
private:
--- /dev/null
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+
+#include "idlc/gen/c_group_body_gen.h"
+
+namespace {
+#include "idlc/gen/c_group_body_gen_cb.h"
+
+constexpr const char PREFIX_RPC_PORT_GROUP[] = "rpc_port_group";
+}
+
+namespace tidl {
+
+CGroupBodyGen::CGroupBodyGen(std::shared_ptr<Document> doc)
+ : CBodyGeneratorBase(doc) {
+}
+
+void CGroupBodyGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenGNUSourceDefinition(stream);
+ GenIncludeDefaultHeaders(stream, true);
+ GenIncludeHeader(stream);
+ GenLogTag(stream, std::string("RPC_PORT_GROUP"));
+ GenLogDefinition(stream);
+ GenVersionDefinition(stream);
+ GenBaseDefinition(stream);
+ GenInterfaceMethodHandlerType(stream);
+ GenInterfaceEnums(stream);
+ GenStructureDefs(stream);
+ GenInterfaceDefs(stream);
+ GenHelper(stream);
+ GenStructures(stream);
+ GenInterfaces(stream);
+}
+
+void CGroupBodyGen::OnFiniGen(std::ofstream& stream) {
+}
+
+std::string CGroupBodyGen::GetHandlePrefix() {
+ std::string prefix = PREFIX_RPC_PORT_GROUP;
+ if (!HasNamespace())
+ return prefix;
+
+ return prefix + "_" + GetFileNamespace();
+}
+
+void CGroupBodyGen::GenIncludeDefaultHeaders(std::ofstream& stream, bool body) {
+ CGeneratorBase::GenIncludeDefaultHeaders(stream, body);
+ stream << CB_INTERFACE_EXTRA_HEADER;
+}
+
+void CGroupBodyGen::GenHelper(std::ofstream& stream) {
+ stream << SmartIndent(CB_HELPER);
+}
+
+void CGroupBodyGen::GenInterfaceDefs(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterfaceDef(stream, iface);
+ }
+}
+
+void CGroupBodyGen::GenInterfaceDef(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_BASE_DEF)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+void CGroupBodyGen::GenInterfaceEnums(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceEnum(stream, iface);
+ }
+}
+
+// @see #CB_INTERFACE_METHOD_ENUM
+std::string CGroupBodyGen::GenMethodEnums(const Interface& iface) {
+ std::string method_enum(ReplaceAll(CB_INTERFACE_METHOD_ENUM, {
+ { "<UPPERCASE_PREFIX>", GetHandlePrefix() },
+ { "<UPPERCASE_NAME>", iface.GetID() },
+ { "<UPPERCASE_METHOD_NAME>", "RESULT_" }
+ }));
+
+ std::string method_enums = RemoveLine(method_enum);
+
+ method_enum = ReplaceAll(CB_INTERFACE_METHOD_ENUM, {
+ { "<UPPERCASE_PREFIX>", GetHandlePrefix() },
+ { "<UPPERCASE_NAME>", iface.GetID() },
+ { "<UPPERCASE_METHOD_NAME>", "CALLBACK_" }
+ });
+
+ method_enums += RemoveLine(method_enum);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ method_enum = ReplaceAll(CB_INTERFACE_METHOD_ENUM, {
+ { "<UPPERCASE_PREFIX>", GetHandlePrefix() },
+ { "<UPPERCASE_NAME>", iface.GetID() },
+ { "<UPPERCASE_METHOD_NAME>", d->GetID() }
+ });
+
+ method_enums += RemoveLine(method_enum);
+ }
+ std::transform(method_enums.begin(), method_enums.end(), method_enums.begin(),
+ ::toupper);
+
+ return method_enums;
+}
+
+void CGroupBodyGen::GenInterfaceEnum(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_ENUMS>", GenMethodEnums(iface) }
+ })
+ .Transform([&](std::string str){
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+void CGroupBodyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CGroupBodyGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ GenInterfaceMethodHandlerBase(stream, iface, *d);
+ }
+
+ GenInterfaceMethodTable(stream, iface);
+ GenInterfaceBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ GenInterfaceMethodBase(stream, iface, *d);
+ }
+}
+
+// @see #CB_INTERFACE_METHOD_TABLE
+void CGroupBodyGen::GenInterfaceMethodTable(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_METHOD_TABLE, {
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_HANDLERS>", GenMethodHandlers(iface) }
+ })
+ .Transform([&](std::string str){
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER
+std::string CGroupBodyGen::GenMethodHandlers(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string enum_value = GetHandlePrefix() + "_" + iface.GetID() +
+ "_METHOD_" + d->GetID();
+ std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
+ ::toupper);
+
+ std::string method_handler(ReplaceAll(CB_INTERFACE_METHOD_HANDLER, {
+ { "<ENUM_VALUE>", enum_value },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", d->GetID() }
+ }));
+
+ code += RemoveLine(method_handler);
+ }
+
+ return code;
+}
+
+// @see #CB_INTERFACE_BASE
+void CGroupBodyGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+ ReplaceAll(CB_INTERFACE_BASE)
+ .Change("<PREFIX>", prefix)
+ .Change("<NAME>", name)
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_TYPE
+void CGroupBodyGen::GenInterfaceMethodHandlerType(std::ofstream& stream) {
+ stream << SmartIndent(CB_INTERFACE_METHOD_HANDLER_TYPE);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_BASE
+void CGroupBodyGen::GenInterfaceMethodHandlerBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_HANDLER_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_HANDLER_ARGS_DECL>", GenMethodHandlerArgsDecl(iface, decl) },
+ { "<METHOD_HANDLER_PARCEL_READ>",
+ GenMethodHandlerParcelRead(iface, decl) },
+ { "<METHOD_HANDLER_CALLBACK_INVOKE>",
+ GenMethodHandlerCallbackInvoke(decl) },
+ { "<METHOD_HANDLER_ARGS_FREE>", GenMethodHandlerArgsFree(iface, decl) }
+ })
+ .Transform([&](std::string str){
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_INVOKE
+std::string CGroupBodyGen::GenMethodHandlerCallbackInvoke(
+ const Declaration& decl) {
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_INVOKE,
+ "<METHOD_NAME>", decl.GetID()));
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC)
+ code = ReplaceAll(code, "<RES_SET>", "res_ = ");
+ else
+ code = ReplaceAll(code, "<RES_SET>", "");
+
+ std::string args;
+ bool first = true;
+ for (const auto& p : decl.GetParameters()) {
+ if (!first)
+ args += ", ";
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ args += "&";
+
+ args += p->GetID();
+ first = false;
+ }
+ code = ReplaceAll(code, "<METHOD_ARGS>", args);
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_READ
+std::string CGroupBodyGen::GenMethodHandlerParcelRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ std::string parcel_read_code;
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_read_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>",
+ GetFullNameFromType(type, iface));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
+ }
+
+ code += parcel_read_code;
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CGroupBodyGen::GenMethodHandlerArgsDecl(const Interface& iface,
+ const Declaration& decl) {
+ std::string args_decl;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ args_decl += GetArgTypeString(type, iface) + p->GetID() + " = " +
+ GetErrorValue(type) + ";" + NLine(1);
+ }
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
+ args_decl += "rpc_port_parcel_h parcel_;" + NLine(1);
+ args_decl += GetArgTypeString(decl.GetType(), iface) + "res_ = " +
+ GetErrorValue(decl.GetType()) + ";" + NLine(1);
+ }
+
+ return args_decl;
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_FREE
+// @see #CB_INTERFACE_METHOD_BUNDLE_FREE
+// @see #CB_INTERFACE_METHOD_STRING_FREE
+std::string CGroupBodyGen::GenMethodHandlerArgsFree(const Interface& iface,
+ const Declaration& decl) {
+ std::string free_code;
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.ToString() == "bundle") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE,
+ "<ARG>", p->GetID());
+ } else {
+ free_code.clear();
+ }
+
+ code += free_code;
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CGroupBodyGen::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_WRITE
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_WRITE
+std::string CGroupBodyGen::GenMethodParcelWrite(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+
+ std::string parcel_write_code;
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE, "<ARG>",
+ p->GetID());
+ std::string name = GetFullNameFromType(type, iface);
+ parcel_write_code += GetPrivateSharingString(type, iface, "h->port",
+ p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ parcel_write_code += GetPrivateSharingString(type, iface, "h->port",
+ p->GetID());
+ } else {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ARG>",
+ p->GetID());
+ }
+
+ code += parcel_write_code;
+ }
+
+ return RemoveLine(code);
+}
+
+std::string CGroupBodyGen::GenMethodParamsCheck(const Interface& iface,
+ const Declaration& decl) {
+ std::string params_check;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array" ||
+ type.ToString() == "bundle" ||
+ type.ToString() == "string" ||
+ type.ToString() == "file")
+ params_check += " || " + p->GetID() + " == nullptr";
+ }
+
+ return params_check;
+}
+
+// @see #CB_INTERFACE_METHOD_ASYNC_BASE
+std::string CGroupBodyGen::GenMethodAsyncBase(const Interface& iface,
+ const Declaration& decl) {
+ std::string prefix = GetHandlePrefix();
+ std::string name = iface.GetID();
+ std::string method_name = decl.GetID();
+ std::string code(ReplaceAll(CB_INTERFACE_METHOD_ASYNC_BASE)
+ .Change("<PREFIX>", prefix)
+ .Change("<NAME>", name)
+ .Change("<METHOD_NAME>", method_name)
+ .Change("<METHOD_PARAMS>", GenMethodParams(iface, decl))
+ .Change("<METHOD_PARAMS_CHECK>", GenMethodParamsCheck(iface, decl))
+ .ChangeToUpper("<UPPERCASE_PREFIX>", prefix)
+ .ChangeToUpper("<UPPERCASE_NAME>", name)
+ .ChangeToUpper("<UPPERCASE_METHOD_NAME>", method_name)
+ .Change("<METHOD_PARCEL_WRITE>", GenMethodParcelWrite(iface, decl)));
+
+ return code;
+}
+
+std::string CGroupBodyGen::GenMethodArgs(const Interface& iface,
+ const Declaration& decl) {
+ std::string args_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ args_code += GetReturnTypeString(type) + "new_" + p->GetID() + ";";
+ args_code += NLine(1);
+ }
+
+ return args_code;
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_STRING_PARCEL_READ
+// @see #CB_INTERFACE_METHOD_BASE_PARCEL_READ
+std::string CGroupBodyGen::GenMethodParcelReadBase(const Interface& iface,
+ const BaseType& type, const std::string& param_name) {
+ std::string parcel_read_code;
+
+ if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ,
+ "<ARG>", param_name);
+ } else if (type.ToString() == "string") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_READ,
+ "<ARG>", param_name);
+ } else {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>",
+ param_name);
+ }
+
+ return parcel_read_code;
+}
+
+// @see #CB_INTERFACE_METHOD_VALUE_SET
+std::string CGroupBodyGen::GenMethodParcelRead(const Interface& iface,
+ const Declaration& decl) {
+ std::string code;
+ std::string parcel_read_code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ code += GenMethodParcelReadBase(iface, type, "new_" + p->GetID());
+ code += ReplaceAll(CB_INTERFACE_METHOD_PARAM_SET, "<PARAM>",
+ p->GetID());
+ }
+
+ // Return Value
+ auto& base_type = decl.GetType();
+ code += GenMethodParcelReadBase(iface, base_type, "ret_");
+ return RemoveLine(code);
+}
+
+void CGroupBodyGen::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ std::string code = GenMethodAsyncBase(iface, decl);
+ stream << SmartIndent(code);
+}
+
+} // namespace tidl
--- /dev/null
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_C_GROUP_BODY_GEN_H_
+#define IDLC_GEN_C_GROUP_BODY_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/c_body_gen_base.h"
+#include "idlc/options.h"
+
+namespace tidl {
+
+class CGroupBodyGen : public CBodyGeneratorBase {
+ public:
+ explicit CGroupBodyGen(std::shared_ptr<Document> doc);
+ virtual ~CGroupBodyGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+ std::string GetHandlePrefix() override;
+ void GenIncludeDefaultHeaders(std::ofstream& stream, bool body) override;
+
+ private:
+ void GenInterfaceDefs(std::ofstream& stream);
+ void GenInterfaceDef(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodHandlerType(std::ofstream& stream);
+ void GenInterfaceMethodHandlerBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl);
+ std::string GenMethodHandlerArgsDecl(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlerArgsFree(const Interface& iface,
+ const Declaration& decl);
+ void GenInterfaceMethodTable(std::ofstream& stream,
+ const Interface& iface);
+ std::string GenMethodHandlerCallbackInvoke(const Declaration& decl);
+ std::string GenMethodHandlerParcelRead(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodHandlers(const Interface& iface);
+ std::string GenMethodEnums(const Interface& iface);
+ void GenInterfaceEnums(std::ofstream& stream);
+ void GenInterfaceEnum(std::ofstream& stream, const Interface& iface);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodEnumBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+
+ std::string GenMethodAsyncBase(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+ bool GenMethodParamsFileCheck(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodParcelWrite(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodArgs(const Interface& iface, const Declaration& decl);
+ std::string GenMethodParcelReadBase(const Interface& iface,
+ const BaseType& type, const std::string& param_name);
+ std::string GenMethodParcelRead(const Interface& iface,
+ const Declaration& decl);
+ std::string GenMethodParamsCheck(const Interface& iface, const Declaration& decl);
+ void GenHelper(std::ofstream& stream);
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_C_GROUP_BODY_GEN_H_
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_C_GROUP_BODY_GEN_CB_H_
+#define IDLC_GEN_C_GROUP_BODY_GEN_CB_H_
+
+
+constexpr const char CB_INTERFACE_METHOD_HANDLER_TYPE[] =
+R"__c_cb(
+typedef int (*rpc_port_group_method_handler)(rpc_port_parcel_h parcel, void *data);
+)__c_cb";
+
+/**
+ * <METHOD_ENUMS> The enumeration declarations of methods.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM_BASE[] =
+R"__c_cb(
+typedef enum {
+ <METHOD_ENUMS>
+} <PREFIX>_<NAME>_method_e;
+)__c_cb";
+
+
+/**
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_ENUM[] =
+R"__c_cb(
+<UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>,
+)__c_cb";
+
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ int id;
+ int seq_id;
+ bool once;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback;
+ void *user_data;
+} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
+)__c_cb";
+
+/**
+ * <ENUM_VALUE> The enumeration value.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_TABLE_MEMBER[] =
+R"__c_cb(
+[<ENUM_VALUE>] = __<PREFIX>_<NAME>_<DELEGATE_NAME>_delegate_handler,
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ <PREFIX>_<NAME>_callback_s callback;
+ event_handler_h event_handler;
+ GRecMutex mutex;
+ void *user_data;
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_HANDLER_ARGS_DECL> The declarations for arguments of the method.
+ * <METHOD_HANDLER_PARCEL_READ> The implementation to read the parameter from the parcel.
+ * <METHOD_HANDLER_CALLBACK_INVOKE> The implementation to invoke the callback function of the method.
+ * <METHOD_HANDLER_PARCEL_WRITE> The implementation to write the result to the parcel.
+ * <METHOD_HANDLER_ARGS_FREE> The implementation to release arguments.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER_BASE[] =
+R"__c_cb(
+static int __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler(rpc_port_parcel_h parcel, void *user_data)
+{
+ <PREFIX>_<NAME>_t *h = user_data;
+ int ret_ = RPC_PORT_ERROR_NONE;
+
+ <METHOD_HANDLER_ARGS_DECL>
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ ret_ = RPC_PORT_ERROR_INVALID_PARAMETER;
+ goto out;
+ }
+ <METHOD_HANDLER_PARCEL_READ>
+ <METHOD_HANDLER_CALLBACK_INVOKE>
+
+ out:
+ <METHOD_HANDLER_ARGS_FREE>
+ return ret_;
+}
+)__c_cb";
+
+constexpr const char CB_HELPER[] =
+R"__c_cb(
+static rpc_port_parcel_h __get_parcel_from_bundle(bundle *b)
+{
+ void *raw = nullptr;
+ unsigned int size = 0;
+ rpc_port_parcel_h p;
+
+ int ret = bundle_get_byte(b, "TIDL_RAW", &raw, &size);
+ if (ret != BUNDLE_ERROR_NONE)
+ return nullptr;
+
+ ret = rpc_port_parcel_create_from_raw(&p, raw, size);
+ if (ret != RPC_PORT_ERROR_NONE)
+ return nullptr;
+
+ return p;
+}
+
+static bundle *__get_bundle_from_parcel(rpc_port_parcel_h p, bundle* b)
+{
+ void *raw = nullptr;
+ unsigned int size = 0;
+
+ int ret = rpc_port_parcel_get_raw(p, &raw, &size);
+ if (ret != RPC_PORT_ERROR_NONE)
+ return nullptr;
+
+ ret = bundle_add_byte(b, "TIDL_RAW", raw, size);
+ if (ret != BUNDLE_ERROR_NONE)
+ return nullptr;
+
+ return b;
+}
+
+static const char *__get_appid()
+{
+ static char *str = nullptr;
+
+ if (str)
+ return str;
+
+ char *id = nullptr;
+ int ret = app_get_id(&id);
+ if (ret != APP_ERROR_NONE)
+ id = strdup("system");
+
+ str = id;
+ return str;
+}
+
+static char *__get_event_name(const char *appid, const char *iface_name)
+{
+ size_t size = strlen(appid) + strlen(iface_name) + 19;
+ char *buf = calloc(1, size);
+ if (!buf)
+ return nullptr;
+ snprintf(buf, size, "event.%s.tidl_iface_%s", appid, iface_name);
+ return buf;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+
+static void __<NAME>_event_system_cb(const char *event_name, bundle *event_data, void *user_data)
+{
+ <PREFIX>_<NAME>_t *handle = (<PREFIX>_<NAME>_t *)(user_data);
+ rpc_port_parcel_h p = __get_parcel_from_bundle(event_data);
+ if (p == nullptr) {
+ _E("Invalid bundle");
+ return;
+ }
+
+ rpc_port_parcel_h header;
+ int seq_num = -1;
+ int cmd;
+ rpc_port_parcel_get_header(p, &header);
+ rpc_port_parcel_header_get_seq_num(header, &seq_num);
+
+ _W("[Sequence] %d", seq_num);
+ rpc_port_parcel_read_int32(p, &cmd);
+ if (cmd > 1 && cmd < ARRAY_SIZE(__<NAME>_method_table)) {
+ if (__<NAME>_method_table[cmd])
+ __<NAME>_method_table[cmd](p, handle);
+ } else {
+ _W("Invalid protocol. cmd(%d)", cmd);
+ }
+
+ rpc_port_parcel_destroy(p);
+}
+
+int <PREFIX>_<NAME>_create(const char *sender_appid, <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+ int ret;
+ char *ev_name;
+
+ if (sender_appid == nullptr || callback == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ g_rec_mutex_init(&handle->mutex);
+ handle->callback = *callback;
+ handle->user_data = user_data;
+
+ ev_name = __get_event_name(sender_appid, "<NAME>");
+ if (ev_name == nullptr)
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+
+ ret = event_add_event_handler(ev_name, __<NAME>_event_system_cb, handle, &handle->event_handler);
+ free(ev_name);
+
+ if (ret != EVENT_ERROR_NONE) {
+ _E("Failed to register events. result(%d)", ret);
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_create_for_sender(<PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ g_rec_mutex_init(&handle->mutex);
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ g_rec_mutex_unlock(&h->mutex);
+ g_rec_mutex_clear(&h->mutex);
+
+ if (h->event_handler)
+ event_remove_event_handler(h->event_handler);
+
+ free(h);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_PARAMS> The parameters of the method of the interface
+ * <METHOD_PARAMS_CHECK> The parameters check of the method.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_METHOD_NAME> The uppercase method name of the interface.
+ * <METHOD_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ */
+constexpr const char CB_INTERFACE_METHOD_ASYNC_BASE[] =
+R"__c_cb(
+void <PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
+{
+ rpc_port_parcel_h parcel_;
+ rpc_port_parcel_header_h header_;
+ int seq_num_ = -1;
+ int res_;
+ bundle* b;
+
+ if (h == nullptr<METHOD_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ res_ = rpc_port_parcel_create(&parcel_);
+ if (res_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", res_);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(res_);
+ return;
+ }
+
+ rpc_port_parcel_get_header(parcel_, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+ _W("[Version] \"%s\", [Sequence] %d", TIDL_VERSION, seq_num_);
+
+ rpc_port_parcel_write_int32(parcel_, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
+
+ <METHOD_PARCEL_WRITE>
+ b = bundle_create();
+ if (__get_bundle_from_parcel(parcel_, b) == nullptr) {
+ _E("Failed to make bundle from parcel");
+ bundle_free(b);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ int ret = event_publish_app_event(__get_event_name(__get_appid(), "<NAME>"), b);
+ if (ret != EVENT_ERROR_NONE) {
+ _E("Failed to publish event. result(%d)", ret);
+ bundle_free(b);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(RPC_PORT_ERROR_IO_ERROR);
+ return;
+ }
+
+ bundle_free(b);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel_, &<ARG>->parcelable, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+<PREFIX>_<NAME>_create(&<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to create handle");
+ ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ goto out;
+}
+
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+if (get_last_result() != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data");
+ <PREFIX>_<NAME>_destroy(<ARG>);
+ <ARG> = nullptr;
+ ret_ = get_last_result();
+ goto out;
+}
+)__c_cb";
+
+
+/**
+ * <ENUM_VALUE> The enumeration value of the method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER[] =
+R"__c_cb(
+[<ENUM_VALUE>] = __<PREFIX>_<NAME>_method_<METHOD_NAME>_handler,
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ <PREFIX>_<NAME>_destroy(<ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ bundle_free(<ARG>);
+)__c_cb";
+
+/**
+ * <RES_SET> The implemention to set the result of the callback function.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <METHOD_ARGS> The arguments of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_INVOKE[] =
+R"__c_cb(
+if (h->callback.<METHOD_NAME>)
+ <RES_SET>h->callback.<METHOD_NAME>(<METHOD_ARGS>, h->user_data);
+)__c_cb";
+
+
+/**
+ * <ARG> The argument.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface
+ */
+constexpr const char CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ[] =
+R"__c_cb(
+ret_ = <PREFIX>_<NAME>_create(&<ARG>);
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret_);
+ goto out;
+}
+
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+ret_ = get_last_result();
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret_);
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ free(<ARG>);
+)__c_cb";
+
+/**
+ * <NAME> The name of the interface.
+ * <METHOD_HANDLERS> The declarations of method handlers.
+ */
+constexpr const char CB_INTERFACE_METHOD_TABLE[] =
+R"__c_cb(
+static rpc_port_group_method_handler __<NAME>_method_table[] = {
+ <METHOD_HANDLERS>
+};
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+rpc_port_parcel_read_bundle(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ goto out;
+
+}
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_READ[] =
+R"__c_cb(
+<ARG> = nullptr;
+rpc_port_parcel_read_string(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ ret_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ goto out;
+}
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &<ARG>);
+)__c_cb";
+
+/**
+ * <PARAM> The name of the parameter.
+ */
+constexpr const char CB_INTERFACE_METHOD_PARAM_SET[] =
+R"__c_cb(
+*<PARAM> = new_<PARAM>;
+)__c_cb";
+
+constexpr const char CB_INTERFACE_EXTRA_HEADER[] =
+R"__c_cb(
+#include <app_common.h>
+#include <app_event.h>
+)__c_cb";
+
+#endif // IDLC_GEN_C_GROUP_BODY_GEN_CB_H_
--- /dev/null
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen/c_group_header_gen.h"
+
+namespace {
+#include "idlc/gen/c_group_header_gen_cb.h"
+
+constexpr const char PREFIX_RPC_PORT_GROUP[] = "rpc_port_group";
+}
+
+namespace tidl {
+
+CGroupHeaderGen::CGroupHeaderGen(std::shared_ptr<Document> doc)
+ : CHeaderGeneratorBase(doc) {}
+
+void CGroupHeaderGen::OnInitGen(std::ofstream& stream) {
+ GenVersion(stream);
+ GenPragmaOnce(stream);
+ GenIncludeDefaultHeaders(stream, false);
+ GenExplicitLinkageOpen(stream);
+ GenStructureHandles(stream);
+ GenInterfaceHandles(stream);
+ GenStructures(stream);
+ GenInterfaceCallbacks(stream);
+ GenInterfaces(stream);
+}
+
+void CGroupHeaderGen::OnFiniGen(std::ofstream& stream) {
+ GenExplicitLinkageClose(stream);
+}
+
+std::string CGroupHeaderGen::GetHandlePrefix() {
+ std::string prefix = PREFIX_RPC_PORT_GROUP;
+ if (!HasNamespace())
+ return prefix;
+
+ return prefix + "_" + GetFileNamespace();
+}
+
+void CGroupHeaderGen::GenInterfaceHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenInterfaceHandle(stream, iface);
+ }
+}
+
+void CGroupHeaderGen::GenInterfaceCallbacks(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ for (const auto& d : iface.GetDeclarations()) {
+ GenInterfaceMethodCallbackBase(stream, iface, *d);
+ }
+ }
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_BASE
+void CGroupHeaderGen::GenInterfaceMethodCallbackBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_BASE, {
+ { "<RETURN_TYPE>", GetReturnTypeString(decl.GetType()) },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_PARAMS>", GenMethodParams(iface, decl) }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_HANDLE
+void CGroupHeaderGen::GenInterfaceHandle(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_HANDLE)
+ .Change("<PREFIX>", GetHandlePrefix())
+ .Change("<NAME>", iface.GetID())
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+void CGroupHeaderGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void CGroupHeaderGen::GenInterface(std::ofstream& stream,
+ const Interface& iface) {
+ GenInterfaceBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations())
+ GenInterfaceMethodBase(stream, iface, *d);
+}
+
+// @see #CB_INTERFACE_BASE
+void CGroupHeaderGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_INTERFACE_BASE, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID()},
+ { "<METHOD_CALLBACK_DECLS>", GenMethodCallbackDecls(iface) }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_DECL
+std::string CGroupHeaderGen::GenMethodCallbackDecls(const Interface& iface) {
+ std::string method_callback_decls;
+ for (const auto& d : iface.GetDeclarations()) {
+ std::string method_callback_decl(ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_DECL, {
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", d->GetID() }
+ }));
+
+ method_callback_decl = RemoveLine(method_callback_decl);
+ method_callback_decls += RemoveLine(method_callback_decl, 2);
+ }
+
+ return method_callback_decls;
+}
+
+std::string CGroupHeaderGen::GenMethodParams(const Interface& iface,
+ const Declaration& decl) {
+ std::string params;
+ bool first = true;
+ for (const auto& p : decl.GetParameters()) {
+ if (!first)
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, iface) +
+ p->GetID();
+ first = false;
+ }
+
+ return params;
+}
+
+// @see #CB_INTERFACE_METHOD_BASE
+void CGroupHeaderGen::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl) {
+ ReplaceAll(CB_INTERFACE_METHOD_BASE, {
+ { "<RETURN_TYPE>", GetReturnTypeString(decl.GetType()) },
+ { "<PREFIX>", GetHandlePrefix() },
+ { "<NAME>", iface.GetID() },
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<METHOD_PARAMS>", GenMethodParams(iface, decl) }
+ })
+ .Transform([&](std::string code) {
+ return SmartIndent(code);
+ })
+ .Out(stream);
+}
+
+} // namespace tidl
--- /dev/null
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_C_GROUP_HEADER_GEN_H_
+#define IDLC_GEN_C_GROUP_HEADER_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen/c_header_gen_base.h"
+
+namespace tidl {
+
+class CGroupHeaderGen : public CHeaderGeneratorBase {
+ public:
+ explicit CGroupHeaderGen(std::shared_ptr<Document> doc);
+ virtual ~CGroupHeaderGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+ std::string GetHandlePrefix() override;
+
+ private:
+ void GenInterfaceHandles(std::ofstream& stream);
+ void GenInterfaceHandle(std::ofstream& stream, const Interface& iface);
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+
+ void GenInterfaceCallbacks(std::ofstream& stream);
+ void GenInterfaceMethodCallbackBase(std::ofstream& stream,
+ const Interface& iface, const Declaration& decl);
+ std::string GenMethodCallbackDecls(const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& iface,
+ const Declaration& decl);
+
+ std::string GenMethodParams(const Interface& iface, const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_C_GROUP_HEADER_GEN_H_
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_C_GROUP_HEADER_GEN_CB_H_
+#define IDLC_C_GROUP_HEADER_GEN_CB_H_
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_HANDLE[] =
+R"__c_cb(
+/**
+ * @brief The <PREFIX>_<NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_s *<PREFIX>_<NAME>_h;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+/**
+ * @brief The structure type containing the set of callback functions for handling events.
+ * @details It is one of the input parameters of the <PREFIX>_<NAME>_register() function.
+ *
+ * @see <PREFIX>_<NAME>_create_cb
+ * @see <PREFIX>_<NAME>_terminate_cb
+ */
+typedef struct {
+ <METHOD_CALLBACK_DECLS>
+} <PREFIX>_<NAME>_callback_s;
+
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle.
+ * @remarks The @a h handle should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ *
+ * @param[in] sender_appid ID of app sending events
+ * @param[in] callback The set of callback functions to handle events
+ * @param[in] user_data The user data to be passed to the callback function
+ * @param[out] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RPC_PORT_ERROR_IO_ERROR IO error
+
+ * @see <PREFIX>_<NAME>_destroy()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+int <PREFIX>_<NAME>_create(const char *sender_appid, <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Creates a <PREFIX>_<NAME> handle for sending events.
+ * @remarks The @a h handle should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ *
+ * @param[out] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #RPC_PORT_ERROR_IO_ERROR IO error
+
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_create_for_sender(<PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the method.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The name of the method of the interface.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_BASE[] =
+R"__c_cb(
+/**
+ * @brief Called when the payload is received.
+ *
+ * @param[in] ...
+ * @param[in] user_data The user data passed from the registration function
+ * @see #<PREFIX>_<NAME>_callback_s;
+ */
+typedef <RETURN_TYPE> (*<PREFIX>_<NAME>_<METHOD_NAME>_cb)(<METHOD_PARAMS>, void *user_data);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The name of the method of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_CALLBACK_DECL[] =
+R"__c_cb(
+<PREFIX>_<NAME>_<METHOD_NAME>_cb <METHOD_NAME>; /**< This callback function is invoked when the <METHOD_NAME> request is delivered. */
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The type of the return value.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The of the interface.
+ * <METHOD_NAME> The name of the method.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE[] =
+R"__c_cb(
+/**
+ * @brief Calls the <METHOD_NAME>() method.
+ * @details The return value and args are decided by the interface declaration.
+ * You can get the result using get_last_result().
+ * Before returning the function, the function sets the result using set_last_result().
+ * @remarks The specific error code can be obtained using the get_last_result() function. Error codes are described in Exception section.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] ...
+ * @exception #RPC_PORT_ERROR_NONE Successful
+ * @exception #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @exception #RPC_PORT_ERROR_IO_ERROR I/O error
+ */
+<RETURN_TYPE><PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h, <METHOD_PARAMS>);
+)__c_cb";
+
+#endif // IDLC_C_GROUP_HEADER_GEN_CB_H_
#include "idlc/gen/c_proxy_body_gen.h"
#include "idlc/gen/c_stub_header_gen.h"
#include "idlc/gen/c_stub_body_gen.h"
+#include "idlc/gen/c_group_header_gen.h"
+#include "idlc/gen/c_group_body_gen.h"
#include "idlc/gen/cpp_proxy_header_gen.h"
#include "idlc/gen/cpp_proxy_body_gen.h"
#include "idlc/gen/cpp_stub_header_gen.h"
}
case tidl::Options::LANGUAGE_TYPE_C:
+ {
+ tidl::CGroupHeaderGen group_header(ps.GetDoc());
+ group_header.Run(options->GetOutput() + ".h");
+ tidl::CGroupBodyGen group_body(ps.GetDoc());
+ group_body.Run(options->GetOutput() + ".c");
+ break;
+ }
+
case tidl::Options::LANGUAGE_TYPE_CSHARP:
case tidl::Options::LANGUAGE_TYPE_JAVA:
default:
MessageProxyC.c
MessageStub.cc
FooPubsubGroup.cc
+ FooPubsubGroupC.c
FooPubsubCionGroup.cc
FooPubsubCionGroupC.c
)
OUTPUT="${FILES_FOR_GROUP[index]}Group"
${TIDLC} -g -l C++ -i ${SCRIPT_DIR}/tidl/${INPUT} -o ${TARGET_DIR}/${OUTPUT}
+
+ OUTPUT="${FILES_FOR_GROUP[index]}GroupC"
+ ${TIDLC} -g -l C -i ${SCRIPT_DIR}/tidl/${INPUT} -o ${TARGET_DIR}/${OUTPUT}
done
for index in ${!FILES_CION[*]}; do