From: jusung Date: Mon, 27 Dec 2021 07:30:59 +0000 (+0900) Subject: [cion] Implement C group generator X-Git-Tag: accepted/tizen/unified/20220216.010312~13^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=31767f49dc6bf90e80b1273abb0b9b4caf5efa02;p=platform%2Fcore%2Fappfw%2Ftidl.git [cion] Implement C group generator Change-Id: Ice250308333c7a6769778eb1b3ecb779ca43a329 Signed-off-by: jusung --- diff --git a/idlc/ast/parser.cc b/idlc/ast/parser.cc index f28a11d..d2b6aa6 100644 --- a/idlc/ast/parser.cc +++ b/idlc/ast/parser.cc @@ -33,9 +33,9 @@ void yylex_destroy(void*); namespace tidl { -Parser::Parser(bool beta_enable, bool cion_enable) +Parser::Parser(bool beta_enable, bool cion_enable, bool group_enable) : scanner_(nullptr), error_(false), beta_enable_(beta_enable), - cion_enable_(cion_enable) { + cion_enable_(cion_enable), group_enable_(group_enable) { yylex_init(&scanner_); } @@ -86,4 +86,8 @@ bool Parser::IsCionEnabled() { return cion_enable_; } +bool Parser::IsGroupEnabled() { + return group_enable_; +} + } // namespace tidl diff --git a/idlc/ast/parser.h b/idlc/ast/parser.h index fa8c1b0..69476eb 100644 --- a/idlc/ast/parser.h +++ b/idlc/ast/parser.h @@ -27,7 +27,7 @@ namespace tidl { class Parser { public: - Parser(bool beta_enable = false, bool cion_enable = false); + Parser(bool beta_enable = false, bool cion_enable = false, bool group_enable = false); ~Parser(); void* Scanner() const { return scanner_; } @@ -38,6 +38,7 @@ class Parser { void ReportError(const std::string& err, unsigned line); bool IsBetaEnabled(); bool IsCionEnabled(); + bool IsGroupEnabled(); private: void* scanner_; @@ -46,6 +47,7 @@ class Parser { bool error_; bool beta_enable_; bool cion_enable_; + bool group_enable_; }; } // namespace tidl diff --git a/idlc/ast/tidlc.yy b/idlc/ast/tidlc.yy index bab90b1..25c17fd 100644 --- a/idlc/ast/tidlc.yy +++ b/idlc/ast/tidlc.yy @@ -287,9 +287,15 @@ declarations: declaration { ; declaration: base_type T_ID T_LEFT parameter_list T_RIGHT T_SEMICOLON { - $$ = new tidl::Declaration($2->ToString(), $1, $4, $1->GetComments(), - @1.begin.line, tidl::Declaration::MethodType::SYNC); - delete $2; + if (ps->IsGroupEnabled()) { + ps->ReportError("Group does not support 'sync' method type", @1.begin.line); + $$ = NULL; + delete $2; + } else { + $$ = new tidl::Declaration($2->ToString(), $1, $4, $1->GetComments(), + @1.begin.line, tidl::Declaration::MethodType::SYNC); + delete $2; + } } | T_VOID T_ID T_LEFT parameter_list T_RIGHT T_ASYNC T_SEMICOLON { $$ = new tidl::Declaration($2->ToString(), @@ -299,12 +305,19 @@ declaration: base_type T_ID T_LEFT parameter_list T_RIGHT T_SEMICOLON { delete $2; } | T_VOID T_ID T_LEFT parameter_list T_RIGHT T_DELEGATE T_SEMICOLON { - $$ = new tidl::Declaration($2->ToString(), - new tidl::BaseType("void", $1->GetComments()), $4, - $1->GetComments(), @1.begin.line, - tidl::Declaration::MethodType::DELEGATE); - delete $1; - delete $2; + if (ps->IsGroupEnabled()) { + ps->ReportError("Group does not support 'delegate' method type", @1.begin.line); + $$ = NULL; + delete $1; + delete $2; + } else { + $$ = new tidl::Declaration($2->ToString(), + new tidl::BaseType("void", $1->GetComments()), $4, + $1->GetComments(), @1.begin.line, + tidl::Declaration::MethodType::DELEGATE); + delete $1; + delete $2; + } } | base_type T_ID T_LEFT parameter_list T_RIGHT T_ASYNC T_SEMICOLON { ps->ReportError("syntax error in method declaration.", @2.begin.line); @@ -403,7 +416,11 @@ base_type: raw_type { $$ = $1; } | T_FILE { - if (!ps->IsBetaEnabled()) { + if (ps->IsGroupEnabled()) { + ps->ReportError("Group does not support 'file' type", @1.begin.line); + $$ = NULL; + delete $1; + } else if (!ps->IsBetaEnabled()) { ps->ReportError("syntax error. \"No identifier\".", @1.begin.line); ps->ReportError("try to use beta version (-b option).", @1.begin.line); $$ = NULL; diff --git a/idlc/gen_cion/c_cion_group_body_gen.cc b/idlc/gen_cion/c_cion_group_body_gen.cc new file mode 100644 index 0000000..63620aa --- /dev/null +++ b/idlc/gen_cion/c_cion_group_body_gen.cc @@ -0,0 +1,520 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "idlc/gen_cion/c_cion_group_body_gen.h" +#include "idlc/gen_cion/c_cion_group_body_gen_cb.h" + +namespace tidl { + +CCionGroupBodyGen::CCionGroupBodyGen(std::shared_ptr doc, + std::shared_ptr options) + : CCionBodyGeneratorBase(doc), options_(std::move(options)) { +} + +void CCionGroupBodyGen::OnInitGen(std::ofstream& stream) { + GenVersion(stream); + GenGNUSourceDefinition(stream); + GenIncludeDefaultHeaders(stream); + GenIncludeHeader(stream); + GenLogTag(stream, std::string("CION_GROUP")); + GenLogDefinition(stream); + GenBaseDefinition(stream); + GenInterfaceMethodHandlerType(stream); + GenInterfaceEnums(stream); + GenStructureDefs(stream); + GenInterfaceDefs(stream); + GenStructures(stream); + GenInterfaces(stream); +} + +void CCionGroupBodyGen::OnFiniGen(std::ofstream& stream) { +} + +void CCionGroupBodyGen::GenInterfaceDefs(std::ofstream& stream) { + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() != Block::TYPE_INTERFACE) + continue; + + const Interface &iface = static_cast(*i); + GenInterfaceDef(stream, iface); + } +} + +void CCionGroupBodyGen::GenInterfaceDef(std::ofstream& stream, + const Interface& iface) { + std::string code = ReplaceAll(CB_INTERFACE_BASE_DEF, "", + GetHandlePrefix()); + code = ReplaceAll(code, "", iface.GetID()); + + stream << SmartIndent(code); +} + +void CCionGroupBodyGen::GenInterfaceEnums(std::ofstream& stream) { + for (auto& b : GetDocument().GetBlocks()) { + if (b->GetType() != Block::TYPE_INTERFACE) + continue; + + auto& iface = static_cast(*b); + GenInterfaceEnum(stream, iface); + } +} + +// @see #CB_INTERFACE_METHOD_ENUM +std::string CCionGroupBodyGen::GenMethodEnums(const Interface& iface) { + std::string method_enums, method_enum; + + for (const auto& d : iface.GetDeclarations()) { + if (d->GetMethodType() == Declaration::MethodType::DELEGATE) + continue; + + method_enum = ReplaceAll(CB_INTERFACE_METHOD_ENUM, { + { "", GetHandlePrefix() }, + { "", iface.GetID() }, + { "", d->GetID() } + }); + + method_enums += RemoveLine(method_enum); + } + std::transform(method_enums.begin(), method_enums.end(), method_enums.begin(), + ::toupper); + + return method_enums; +} + +void CCionGroupBodyGen::GenInterfaceEnum(std::ofstream& stream, + const Interface& iface) { + std::string code = ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE, { + { "", GetHandlePrefix() }, + { "", iface.GetID() }, + { "", GenMethodEnums(iface) } + }); + + stream << SmartIndent(code); +} + +// @see #CB_INTERFACE_METHOD_HANDLER_TYPE +void CCionGroupBodyGen::GenInterfaceMethodHandlerType(std::ofstream& stream) { + stream << SmartIndent(CB_INTERFACE_METHOD_HANDLER_TYPE); +} + +void CCionGroupBodyGen::GenInterfaces(std::ofstream& stream) { + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() != Block::TYPE_INTERFACE) + continue; + + const Interface &iface = static_cast(*i); + GenInterface(stream, iface); + } +} + +void CCionGroupBodyGen::GenInterface(std::ofstream& stream, const Interface& iface) { + for (const auto& d : iface.GetDeclarations()) { + if (d->GetMethodType() == Declaration::MethodType::DELEGATE) + continue; + + GenInterfaceMethodHandlerBase(stream, iface, *d); + } + + GenInterfaceMethodTable(stream, iface); + + GenInterfaceBase(stream, iface); + + for (const auto& d : iface.GetDeclarations()) { + if (d->GetMethodType() != Declaration::MethodType::ASYNC) + continue; + + GenInterfaceMethodBase(stream, iface, *d); + } +} + +// @see #CB_INTERFACE_METHOD_TABLE +void CCionGroupBodyGen::GenInterfaceMethodTable(std::ofstream& stream, + const Interface& iface) { + std::string code = ReplaceAll(CB_INTERFACE_METHOD_TABLE, { + { "", iface.GetID() }, + { "", GenMethodHandlers(iface) } + }); + + stream << SmartIndent(code); +} + +// @see #CB_INTERFACE_METHOD_HANDLER +std::string CCionGroupBodyGen::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 }, + { "", GetHandlePrefix() }, + { "", iface.GetID() }, + { "", d->GetID() } + }); + + code += RemoveLine(method_handler); + } + + return code; +} + +// @see #CB_INTERFACE_BASE +void CCionGroupBodyGen::GenInterfaceBase(std::ofstream& stream, + const Interface& iface) { + std::string prefix = GetHandlePrefix(); + std::string code = ReplaceAll(CB_INTERFACE_BASE, "", prefix); + std::string name = iface.GetID(); + code = ReplaceAll(code, "", name); + std::transform(prefix.begin(), prefix.end(), prefix.begin(), ::toupper); + code = ReplaceAll(code, "", prefix); + std::transform(name.begin(), name.end(), name.begin(), ::toupper); + code = ReplaceAll(code, "", name); + std::string security = GenSecurityString(iface); + code = ReplaceAll(code, "", security); + + stream << SmartIndent(code); +} + +// @see #CB_INTERFACE_METHOD_HANDLER_BASE +void CCionGroupBodyGen::GenInterfaceMethodHandlerBase(std::ofstream& stream, + const Interface& iface, const Declaration& decl) { + std::string code = ReplaceAll(CB_INTERFACE_METHOD_HANDLER_BASE, { + { "", GetHandlePrefix() }, + { "", iface.GetID() }, + { "", decl.GetID() }, + { "", GenMethodHandlerArgsDecl(iface, decl) }, + { "", + GenMethodHandlerParcelRead(iface, decl) }, + { "", + GenMethodHandlerCallbackInvoke(decl) }, + { "", GenMethodHandlerArgsFree(iface, decl) } + }); + + stream << SmartIndent(code); +} + +// @see #CB_INTERFACE_METHOD_CALLBACK_INVOKE +std::string CCionGroupBodyGen::GenMethodHandlerCallbackInvoke( + const Declaration& decl) { + std::string code = ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_INVOKE, + "", decl.GetID()); + + if (decl.GetMethodType() == Declaration::MethodType::SYNC) + code = ReplaceAll(code, "", "res_ = "); + else + code = ReplaceAll(code, "", ""); + + std::string args; + for (const auto& p : decl.GetParameters()) { + args += ", "; + auto& param_type = p->GetParameterType(); + if (param_type.GetDirection() != ParameterType::Direction::IN) + args += "&"; + + args += p->GetID(); + } + code = ReplaceAll(code, "", 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 CCionGroupBodyGen::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 (IsDelegateType(iface, type)) { + parcel_read_code = ReplaceAll( + CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ, "", + GetHandlePrefix()); + parcel_read_code = ReplaceAll(parcel_read_code, "", + GetFullNameFromType(type, iface)); + parcel_read_code = ReplaceAll(parcel_read_code, "", p->GetID()); + } else if (type.IsUserDefinedType() || + type.ToString() == "list" || + type.ToString() == "array") { + parcel_read_code = ReplaceAll( + CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ, "", + GetHandlePrefix()); + parcel_read_code = ReplaceAll(parcel_read_code, "", + GetFullNameFromType(type, iface)); + parcel_read_code = ReplaceAll(parcel_read_code, "", p->GetID()); + } else if (type.ToString() == "bundle") { + parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ, + "", p->GetID()); + } else if (type.ToString() == "string") { + parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_READ, + "", p->GetID()); + } else { + parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_READ, + "", GetParcelType(type)); + parcel_read_code = ReplaceAll(parcel_read_code, "", p->GetID()); + } + + code += parcel_read_code; + } + + return RemoveLine(code); +} + +std::string CCionGroupBodyGen::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 CCionGroupBodyGen::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 (IsDelegateType(iface, type) || + type.IsUserDefinedType() || + type.ToString() == "list" || + type.ToString() == "array") { + free_code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_FREE, { + { "", GetHandlePrefix() }, + { "", GetFullNameFromType(type, iface) }, + { "", p->GetID() } + }); + } else if (type.ToString() == "bundle") { + free_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE, + "", p->GetID()); + } else if (type.ToString() == "string") { + free_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE, + "", p->GetID()); + } else { + free_code.clear(); + } + + code += free_code; + } + + return RemoveLine(code); +} + +std::string CCionGroupBodyGen::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; +} + +std::string CCionGroupBodyGen::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 (IsDelegateType(iface, type) || + type.IsUserDefinedType() || + type.ToString() == "list" || + type.ToString() == "array" || + type.ToString() == "bundle" || + type.ToString() == "string") + params_check += " || " + p->GetID() + " == nullptr"; + } + + return params_check; +} + +// @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 CCionGroupBodyGen::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 (IsDelegateType(iface, type) || + type.IsUserDefinedType() || + type.ToString() == "list" || + type.ToString() == "array") { + parcel_write_code = ReplaceAll( + CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE, "", + p->GetID()); + std::string name = GetFullNameFromType(type, iface); + } else if (type.ToString() == "bundle") { + parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE, + "", p->GetID()); + } else if (type.ToString() == "string") { + parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE, + "", p->GetID()); + } else { + parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_WRITE, + "", GetParcelType(type)); + parcel_write_code = ReplaceAll(parcel_write_code, "", + p->GetID()); + } + + code += parcel_write_code; + } + + return RemoveLine(code); +} + +// @see #CB_INTERFACE_METHOD_ASYNC_BASE +std::string CCionGroupBodyGen::GenMethodAsyncBase(const Interface& iface, + const Declaration& decl) { + std::string prefix = GetHandlePrefix(); + std::string code = ReplaceAll(CB_INTERFACE_METHOD_ASYNC_BASE, "", + prefix); + std::string name = iface.GetID(); + code = ReplaceAll(code, "", name); + std::string method_name = decl.GetID(); + code = ReplaceAll(code, "", method_name); + std::string args = GenMethodParams(iface, decl); + code = ReplaceAll(code, "", args); + std::string args_check = GenMethodParamsCheck(iface, decl); + code = ReplaceAll(code, "", args_check); + std::transform(prefix.begin(), prefix.end(), prefix.begin(), ::toupper); + code = ReplaceAll(code, "", prefix); + std::transform(name.begin(), name.end(), name.begin(), ::toupper); + code = ReplaceAll(code, "", name); + std::transform(method_name.begin(), method_name.end(), method_name.begin(), + ::toupper); + code = ReplaceAll(code, "", method_name); + std::string parcel_write = GenMethodParcelWrite(iface, decl); + code = ReplaceAll(code, "", parcel_write); + return code; +} + +std::string CCionGroupBodyGen::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 CCionGroupBodyGen::GenMethodParcelReadBase(const Interface& iface, + const BaseType& type, const std::string& param_name) { + std::string parcel_read_code; + if (IsDelegateType(iface, type) || + type.IsUserDefinedType() || + type.ToString() == "list" || + type.ToString() == "array") { + parcel_read_code = ReplaceAll( + CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ, "", + GetHandlePrefix()); + std::string name = GetFullNameFromType(type, iface); + parcel_read_code = ReplaceAll(parcel_read_code, "", name); + parcel_read_code = ReplaceAll(parcel_read_code, "", param_name); + } else if (type.ToString() == "bundle") { + parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ, + "", param_name); + } else if (type.ToString() == "string") { + parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_READ, + "", param_name); + } else { + parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_READ, + "", GetParcelType(type)); + parcel_read_code = ReplaceAll(parcel_read_code, "", + param_name); + } + + return parcel_read_code; +} + +// @see #CB_INTERFACE_METHOD_VALUE_SET +std::string CCionGroupBodyGen::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, "", + p->GetID()); + } + + // Return Value + auto& base_type = decl.GetType(); + code += GenMethodParcelReadBase(iface, base_type, "ret_"); + return RemoveLine(code); +} + +void CCionGroupBodyGen::GenInterfaceMethodBase(std::ofstream& stream, + const Interface& iface, const Declaration& decl) { + std::string code = GenMethodAsyncBase(iface, decl); + stream << SmartIndent(code); +} + +} // namespace tidl diff --git a/idlc/gen_cion/c_cion_group_body_gen.h b/idlc/gen_cion/c_cion_group_body_gen.h new file mode 100644 index 0000000..326e62f --- /dev/null +++ b/idlc/gen_cion/c_cion_group_body_gen.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IDLC_C_CION_GEN_C_GROUP_BODY_GEN_H_ +#define IDLC_C_CION_GEN_C_GROUP_BODY_GEN_H_ + +#include +#include + +#include "idlc/gen_cion/c_cion_body_gen_base.h" +#include "idlc/options.h" + +namespace tidl { + +class CCionGroupBodyGen : public CCionBodyGeneratorBase { + public: + explicit CCionGroupBodyGen(std::shared_ptr doc, + std::shared_ptr options); + virtual ~CCionGroupBodyGen() = default; + + void OnInitGen(std::ofstream& stream) override; + void OnFiniGen(std::ofstream& stream) 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); + std::string GenMethodParamsCheck(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); + + private: + std::shared_ptr options_; +}; + +} // namespace tidl + +#endif // IDLC_C_CION_GEN_C_GROUP_BODY_GEN_H_ \ No newline at end of file diff --git a/idlc/gen_cion/c_cion_group_body_gen_cb.h b/idlc/gen_cion/c_cion_group_body_gen_cb.h new file mode 100644 index 0000000..06fae16 --- /dev/null +++ b/idlc/gen_cion/c_cion_group_body_gen_cb.h @@ -0,0 +1,590 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IDLC_C_CION_GEN_C_GROUP_BODY_GEN_CB_H_ +#define IDLC_C_CION_GEN_C_GROUP_BODY_GEN_CB_H_ + + +constexpr const char CB_INTERFACE_METHOD_HANDLER_TYPE[] = +R"__c_cb( +typedef int (*cion_group_method_handler)(const cion_peer_info_h peer_info, rpc_port_parcel_h parcel, void *data); +)__c_cb"; + +/** + * The enumeration declarations of methods. + * The prefix of the interface. + * The name of the interface. + */ +constexpr const char CB_INTERFACE_METHOD_ENUM_BASE[] = +R"__c_cb( +typedef enum { + +} __method_e; +)__c_cb"; + + +/** + * The uppercase prefix of the interface. + * The uppercase name of the interface. + * The uppercase method name of the interface. + */ +constexpr const char CB_INTERFACE_METHOD_ENUM[] = +R"__c_cb( +__METHOD_, +)__c_cb"; + + + +/** + * The prefix of the interface. + * The name of the interface. + * The name of the delegate of the interface. + */ +constexpr const char CB_INTERFACE_DELEGATE_DEF[] = +R"__c_cb( +typedef struct ___s { + rpc_port_parcelable_t parcelable; + int id; + int seq_id; + bool once; + ___cb callback; + void *user_data; +} ___t; +)__c_cb"; + +/** + * The enumeration value. + * The prefix of the interface. + * The name of the interface. + * The name of the delegate of the interface. + */ +constexpr const char CB_INTERFACE_DELEGATE_TABLE_MEMBER[] = +R"__c_cb( +[] = _____delegate_handler, +)__c_cb"; + +/** + * The prefix of the interface. + * The name of the interface. + */ +constexpr const char CB_INTERFACE_BASE_DEF[] = +R"__c_cb( +typedef struct __s { + char *topic_name; + cion_group_h group; + cion_security_h security; + __callback_s callback; + GRecMutex mutex; + void *user_data; +} __t; +)__c_cb"; + +/** + * The prefix of the interface. + * The name of the interface. + * The method name of the interface. + * The declarations for arguments of the method. + * The implementation to read the parameter from the parcel. + * The implementation to invoke the callback function of the method. + * The implementation to write the result to the parcel. + * The implementation to release arguments. + */ +constexpr const char CB_INTERFACE_METHOD_HANDLER_BASE[] = +R"__c_cb( +static int ____method__handler(const cion_peer_info_h peer_info, rpc_port_parcel_h parcel, void *user_data) +{ + __t *h = user_data; + int ret_ = CION_ERROR_NONE; + + + if (h == nullptr || h->group == nullptr) { + _E("Invalid parameter"); + ret_ = CION_ERROR_INVALID_PARAMETER; + goto out; + } + + + + out: + + return ret_; +} +)__c_cb"; + + +/** + * The prefix of the interface. + * The name of the interface. + * The uppercase prefix of the interface. + * The uppercase name of the interface. + */ +constexpr const char CB_INTERFACE_BASE[] = +R"__c_cb( +static int ____process_received_event(__t *h, const cion_peer_info_h peer_info, rpc_port_parcel_h parcel) +{ + int ret = CION_ERROR_NONE; + int cmd = -1; + + rpc_port_parcel_read_int32(parcel, &cmd); + if (cmd >= 0 && cmd < ARRAY_SIZE(___method_table)) { + if (___method_table[cmd]) + ret = ___method_table[cmd](peer_info, parcel, h); + } else { + _W("Invalid protocol. cmd(%d)", cmd); + ret = CION_ERROR_INVALID_PARAMETER; + } + + return ret; +} + +static void ____joined_cb(const char *topic_name, + const cion_peer_info_h peer_info, void *user_data) +{ + __h h = user_data; + + _I("topic_name(%s)", topic_name); + h->callback.joined(h, peer_info, h->user_data); +} + +static void ____left_cb(const char *topic_name, + const cion_peer_info_h peer_info, void *user_data) +{ + __h h = user_data; + + _W("topic_name(%s)", topic_name); + h->callback.left(h, peer_info, h->user_data); + +} + +static void ____received(const char *topic_name, + const cion_peer_info_h peer_info, cion_payload_h payload, void *user_data) +{ + __h h = user_data; + rpc_port_parcel_h parcel; + unsigned char *data; + cion_payload_type_e type; + int ret; + unsigned int data_len; + + _W("topic_name(%s)", topic_name); + + ret = cion_payload_get_type(payload, &type); + if (ret != CION_ERROR_NONE || type != CION_PAYLOAD_TYPE_DATA) { + _E("Faled to cion_payload_get_type : [%d][%d]", ret, type); + return; + } + + ret = cion_payload_get_data(payload, &data, &data_len); + if (ret != CION_ERROR_NONE) { + _E("Faled to cion_payload_get_data : %d", ret); + return; + } + + ret = rpc_port_parcel_create_from_raw(&parcel, data, data_len); + free(data); + if (ret != RPC_PORT_ERROR_NONE) { + _E("Failed to create parcel handle from data. error(%d)", ret); + return; + } + + ____process_received_event(h, peer_info, parcel); + rpc_port_parcel_destroy(parcel); + +} + +int __create(const char *topic_name, __callback_s *callback, void *user_data, __h *h) +{ + __t *handle; + int ret; + cion_security_h security; + + if (topic_name == nullptr || callback == nullptr || h == nullptr) { + _E("Invalid parameter"); + return CION_ERROR_INVALID_PARAMETER; + } + + if (callback->joined == nullptr || callback->left == nullptr) { + _E("Invalid parameter"); + return CION_ERROR_INVALID_PARAMETER; + } + + handle = calloc(1, sizeof(__t)); + if (handle == nullptr) { + _E("Out of memory"); + return CION_ERROR_OUT_OF_MEMORY; + } + + g_rec_mutex_init(&handle->mutex); + + handle->topic_name = strdup(topic_name); + if (handle->topic_name == nullptr) { + _E("Failed to duplicate topic name"); + __destroy(handle); + return CION_ERROR_OUT_OF_MEMORY; + } + + ret = cion_security_create(&security); + if (ret != CION_ERROR_NONE) { + _E("Failed to create security handle. error(%d)", ret); + __destroy(handle); + return ret; + } + + + handle->security = security; + + ret = cion_group_create(&handle->group, topic_name, handle->security); + if (ret != CION_ERROR_NONE) { + _E("Failed to create group handle. error(%d)", ret); + __destroy(handle); + return ret; + } + + handle->callback = *callback; + handle->user_data = user_data; + + ret = cion_group_add_joined_cb(handle->group, ____joined_cb, handle); + if (ret != CION_ERROR_NONE) { + _E("Failed to add connection result cb. error(%d)", ret); + __destroy(handle); + return ret; + } + + ret = cion_group_add_left_cb(handle->group, ____left_cb, handle); + if (ret != CION_ERROR_NONE) { + _E("Failed to add disconnected event cb. error(%d)", ret); + __destroy(handle); + return ret; + } + + ret = cion_group_add_payload_received_cb(handle->group, ____received, handle); + if (ret != CION_ERROR_NONE) { + _E("Failed to add received event cb. error(%d)", ret); + __destroy(handle); + return ret; + } + + ret = cion_group_subscribe(handle->group); + if (ret != CION_ERROR_NONE) { + _E("Failed to subscribe event. error(%d)", ret); + __destroy(handle); + return ret; + } + + *h = handle; + + return CION_ERROR_NONE; +} + +int __destroy(__h h) +{ + if (h == nullptr) { + _E("Invalid parameter"); + return CION_ERROR_INVALID_PARAMETER; + } + + g_rec_mutex_lock(&h->mutex); + g_rec_mutex_unlock(&h->mutex); + g_rec_mutex_clear(&h->mutex); + + if (h->group) { + cion_group_unsubscribe(h->group); + cion_group_destroy(h->group); + } + + if (h->security) + cion_security_destroy(h->security); + + if (h->topic_name) + free(h->topic_name); + + free(h); + + return CION_ERROR_NONE; +} +)__c_cb"; + +/** + * The prefix of the interface. + * The name of the interface. + * The method name of the interface. + * The parameters of the method of the interface + * The parameters check of the method. + * The uppercase prefix of the interface. + * The uppercase name of the interface. + * The uppercase method name of the interface. + * The implementation to write arguments to the parcel. + * The implementation to add the delegates to the list. + */ +constexpr const char CB_INTERFACE_METHOD_ASYNC_BASE[] = +R"__c_cb( +void __invoke_(__h h) +{ + rpc_port_parcel_h parcel_ = nullptr; + int res_; + unsigned int data_size_; + unsigned char *data_; + cion_payload_h pl_ = nullptr; + + if (h == nullptr) { + _E("Invalid parameter"); + set_last_result(CION_ERROR_INVALID_PARAMETER); + return; + } + + g_rec_mutex_lock(&h->mutex); + if (h->group == nullptr) { + _E("Not connected"); + g_rec_mutex_unlock(&h->mutex); + set_last_result(CION_ERROR_INVALID_PARAMETER); + return; + } + + res_ = rpc_port_parcel_create(&parcel_); + if (res_ != CION_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_write_int32(parcel_, __METHOD_); + + + + res_ = rpc_port_parcel_get_raw(parcel_, (void **)&data_, &data_size_); + if (res_ != RPC_PORT_ERROR_NONE) { + _E("Failed to get raw. error(%d)", res_); + goto out; + } + + res_ = cion_payload_create(&pl_, CION_PAYLOAD_TYPE_DATA); + if (res_ != CION_ERROR_NONE) { + _E("Failed to cion_payload_create : %d", res_); + goto out; + } + + res_ = cion_payload_set_data(pl_, (const unsigned char*)data_, data_size_); + if (res_ != CION_ERROR_NONE) { + _E("Failed to cion_payload_set_data : %d", res_); + goto out; + } + + res_ = cion_group_publish(h->group, pl_); + if (res_ != CION_ERROR_NONE) { + _E("Failed to cion_group_publish : %d", res_); + goto out; + } + +out: + cion_payload_destroy(pl_); + set_last_result(res_); + g_rec_mutex_unlock(&h->mutex); + +} +)__c_cb"; + +/** + * The argument. + */ +constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE[] = +R"__c_cb( +rpc_port_parcel_write(parcel_, &->parcelable, ); +)__c_cb"; + +/** + * The argument. + */ +constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE[] = +R"__c_cb( +rpc_port_parcel_write_bundle(parcel_, ); +)__c_cb"; + +/** + * The argument. + */ +constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_WRITE[] = +R"__c_cb( +rpc_port_parcel_write_string(parcel_, ); +)__c_cb"; + +/** + * The type of the parcel. + * The argument. + */ +constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_WRITE[] = +R"__c_cb( +rpc_port_parcel_write_(parcel_, ); +)__c_cb"; + +/** + * The prefix of the structure. + * The name of the structure. + * The argument. + */ +constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ[] = +R"__c_cb( + = nullptr; +__create(&); +if ( == nullptr) { + _E("Failed to create handle"); + ret_ = CION_ERROR_OUT_OF_MEMORY; + goto out; +} + +rpc_port_parcel_read(parcel, &->parcelable, ); +if (get_last_result() != CION_ERROR_NONE) { + _E("Failed to read data"); + __destroy(); + = nullptr; + ret_ = get_last_result(); + goto out; +} +)__c_cb"; + + +/** + * The enumeration value of the method. + * The prefix of the interface. + * The name of the interface. + * The method name of the interface. + */ +constexpr const char CB_INTERFACE_METHOD_HANDLER[] = +R"__c_cb( +[] = ____method__handler, +)__c_cb"; + +/** + * The argument. + * The prefix of the structure. + * The name of the structure. + */ +constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_FREE[] = +R"__c_cb( +if () + __destroy(); +)__c_cb"; + +/** + * The argument. + */ +constexpr const char CB_INTERFACE_METHOD_BUNDLE_FREE[] = +R"__c_cb( +if () + bundle_free(); +)__c_cb"; + +/** + * The implemention to set the result of the callback function. + * The name of the method of the interface. + * The arguments of the method. + */ +constexpr const char CB_INTERFACE_METHOD_CALLBACK_INVOKE[] = +R"__c_cb( +if (h->callback.) + h->callback.(peer_info, h->user_data); +)__c_cb"; + + +/** + * The argument. + * The prefix of the interface. + * The name of the interface + */ +constexpr const char CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ[] = +R"__c_cb( +ret_ = __create(&); +if (ret_ != CION_ERROR_NONE) { + _E("Failed to create handle. error(%d)", ret_); + goto out; +} + +____set_peerInfo(, peer_info); +rpc_port_parcel_read(parcel, &->parcelable, ); +ret_ = get_last_result(); +if (ret_ != CION_ERROR_NONE) { + _E("Failed to read data. error(%d)", ret_); + goto out; +} +)__c_cb"; + +/** + * The argument. + */ +constexpr const char CB_INTERFACE_METHOD_STRING_FREE[] = +R"__c_cb( +if () + free(); +)__c_cb"; + +/** + * The name of the interface. + * The declarations of method handlers. + */ +constexpr const char CB_INTERFACE_METHOD_TABLE[] = +R"__c_cb( +static cion_group_method_handler ___method_table[] = { + +}; +)__c_cb"; + +/** + * The argument. + */ +constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ[] = +R"__c_cb( + = nullptr; +rpc_port_parcel_read_bundle(parcel, &); +if ( == nullptr) { + _E("Failed to read data"); + ret_ = CION_ERROR_OUT_OF_MEMORY; + goto out; + +} +)__c_cb"; + +/** + * The argument. + */ +constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_READ[] = +R"__c_cb( + = nullptr; +rpc_port_parcel_read_string(parcel, &); +if ( == nullptr) { + _E("Failed to read data"); + ret_ = CION_ERROR_OUT_OF_MEMORY; + goto out; +} +)__c_cb"; + +/** + * The type of the parcel. + * The argument. + */ +constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_READ[] = +R"__c_cb( +rpc_port_parcel_read_(parcel, &); +)__c_cb"; + +/** + * The name of the parameter. + */ +constexpr const char CB_INTERFACE_METHOD_PARAM_SET[] = +R"__c_cb( +* = new_; +)__c_cb"; + +#endif // IDLC_C_CION_GEN_C_GROUP_BODY_GEN_CB_H_ diff --git a/idlc/gen_cion/c_cion_group_header_gen.cc b/idlc/gen_cion/c_cion_group_header_gen.cc new file mode 100644 index 0000000..065aa0c --- /dev/null +++ b/idlc/gen_cion/c_cion_group_header_gen.cc @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "idlc/gen_cion/c_cion_group_header_gen.h" + +namespace { +#include "idlc/gen_cion/c_cion_group_header_gen_cb.h" +} + +namespace tidl { + +CCionGroupHeaderGen::CCionGroupHeaderGen(std::shared_ptr doc) + : CCionHeaderGeneratorBase(doc) { +} + +void CCionGroupHeaderGen::OnInitGen(std::ofstream& stream) { + GenVersion(stream); + GenPragmaOnce(stream); + GenIncludeDefaultHeaders(stream, false); + GenExplicitLinkageOpen(stream); + GenStructureHandles(stream); + GenInterfaceHandles(stream); + GenStructures(stream); + GenInterfaceCallbacks(stream); + GenInterfaces(stream); +} + +void CCionGroupHeaderGen::OnFiniGen(std::ofstream& stream) { + GenExplicitLinkageClose(stream); +} + +void CCionGroupHeaderGen::GenInterfaceHandles(std::ofstream& stream) { + for (auto& b : GetDocument().GetBlocks()) { + if (b->GetType() != Block::TYPE_INTERFACE) + continue; + + auto& iface = static_cast(*b); + GenInterfaceHandle(stream, iface); + } +} + +void CCionGroupHeaderGen::GenInterfaceCallbacks(std::ofstream& stream) { + for (auto& b : GetDocument().GetBlocks()) { + if (b->GetType() != Block::TYPE_INTERFACE) + continue; + + auto& iface = static_cast(*b); + GenInterfaceCallbackBase(stream, iface); + for (const auto& d : iface.GetDeclarations()) { + if (d->GetMethodType() == Declaration::MethodType::DELEGATE) + continue; + + GenInterfaceMethodCallbackBase(stream, iface, *d); + } + } +} + +void CCionGroupHeaderGen::GenInterfaceCallbackBase(std::ofstream& stream, + const Interface& iface) { + std::string code = ReplaceAll(CB_INTERFACE_CALLBACK_BASE, "", + GetHandlePrefix()); + code = ReplaceAll(code, "", iface.GetID()); + + stream << SmartIndent(code); +} + +// @see #CB_INTERFACE_METHOD_CALLBACK_BASE +void CCionGroupHeaderGen::GenInterfaceMethodCallbackBase(std::ofstream& stream, + const Interface& iface, const Declaration& decl) { + std::string code = ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_BASE, { + { "", GetReturnTypeString(decl.GetType()) }, + { "", GetHandlePrefix() }, + { "", iface.GetID() }, + { "", decl.GetID() }, + { "", GenMethodParams(iface, decl) } + }); + + stream << SmartIndent(code); +} + +// @see #CB_INTERFACE_HANDLE +void CCionGroupHeaderGen::GenInterfaceHandle(std::ofstream& stream, + const Interface& iface) { + std::string code = ReplaceAll(CB_INTERFACE_HANDLE, "", + GetHandlePrefix()); + code = ReplaceAll(code, "", iface.GetID()); + + stream << SmartIndent(code); +} + +void CCionGroupHeaderGen::GenInterfaces(std::ofstream& stream) { + for (auto& i : GetDocument().GetBlocks()) { + if (i->GetType() != Block::TYPE_INTERFACE) + continue; + + const Interface &iface = static_cast(*i); + GenInterface(stream, iface); + } +} + +void CCionGroupHeaderGen::GenInterface(std::ofstream& stream, + const Interface& iface) { + + GenInterfaceBase(stream, iface); + + for (const auto& d : iface.GetDeclarations()) { + if (d->GetMethodType() == Declaration::MethodType::DELEGATE) + continue; + + GenInterfaceMethodBase(stream, iface, *d); + } +} + +// @see #CB_INTERFACE_BASE +void CCionGroupHeaderGen::GenInterfaceBase(std::ofstream& stream, + const Interface& iface) { + std::string code = ReplaceAll(CB_INTERFACE_BASE, { + { "", GetHandlePrefix() }, + { "", iface.GetID()}, + { "", GenMethodCallbackDecls(iface) } + }); + + stream << SmartIndent(code); +} + +// @see #CB_INTERFACE_METHOD_CALLBACK_DECL +std::string CCionGroupHeaderGen::GenMethodCallbackDecls(const Interface& iface) { + std::string method_callback_decls; + for (const auto& d : iface.GetDeclarations()) { + if (d->GetMethodType() == Declaration::MethodType::DELEGATE) + continue; + + std::string method_callback_decl = ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_DECL, { + { "", GetHandlePrefix() }, + { "", iface.GetID() }, + { "", d->GetID() } + }); + + method_callback_decl = RemoveLine(method_callback_decl); + method_callback_decls += RemoveLine(method_callback_decl, 2); + } + + return method_callback_decls; +} + +std::string CCionGroupHeaderGen::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_BASE +void CCionGroupHeaderGen::GenInterfaceMethodBase(std::ofstream& stream, + const Interface& iface, const Declaration& decl) { + std::string code = ReplaceAll(CB_INTERFACE_METHOD_BASE, { + { "", GetReturnTypeString(decl.GetType()) }, + { "", GetHandlePrefix() }, + { "", iface.GetID() }, + { "", decl.GetID() }, + { "", GenMethodParams(iface, decl) } + }); + + stream << SmartIndent(code); +} + +} // namespace tidl diff --git a/idlc/gen_cion/c_cion_group_header_gen.h b/idlc/gen_cion/c_cion_group_header_gen.h new file mode 100644 index 0000000..3661510 --- /dev/null +++ b/idlc/gen_cion/c_cion_group_header_gen.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IDLC_C_CION_GEN_C_GROUP_HEADER_GEN_H_ +#define IDLC_C_CION_GEN_C_GROUP_HEADER_GEN_H_ + +#include +#include + +#include "idlc/gen_cion/c_cion_header_gen_base.h" + +namespace tidl { + +class CCionGroupHeaderGen : public CCionHeaderGeneratorBase { + public: + explicit CCionGroupHeaderGen(std::shared_ptr doc); + virtual ~CCionGroupHeaderGen() = default; + + void OnInitGen(std::ofstream& stream) override; + void OnFiniGen(std::ofstream& stream) 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 GenInterfaceCallbackBase(std::ofstream& stream, const Interface& iface); + 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& ifaceo, + const Declaration& decl); + + std::string GenMethodParams(const Interface& iface, const Declaration& decl); +}; + +} // namespace tidl + +#endif // IDLC_C_CION_GEN_C_GROUP_HEADER_GEN_H_ \ No newline at end of file diff --git a/idlc/gen_cion/c_cion_group_header_gen_cb.h b/idlc/gen_cion/c_cion_group_header_gen_cb.h new file mode 100644 index 0000000..75ee136 --- /dev/null +++ b/idlc/gen_cion/c_cion_group_header_gen_cb.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IDLC_C_CION_GEN_C_GROUP_HEADER_GEN_CB_H_ +#define IDLC_C_CION_GEN_C_GROUP_HEADER_GEN_CB_H_ + +/** + * The prefix of the interface. + * The name of the interface. + */ +constexpr const char CB_INTERFACE_HANDLE[] = +R"__c_cb( +/** + * @brief The _ handle. + */ +typedef struct __s *__h; +)__c_cb"; + +/** + * The prefix of the interface. + * The name of the interface. + */ +constexpr const char CB_INTERFACE_CALLBACK_BASE[] = +R"__c_cb( +/** + * @brief Called when a peer joins a topic. + * + * @param[in] h The _ handle + * @param[in] peer_info The Cion peer information handle \n + * The @a peer_info can be used only in the callback. To use outside, make a copy. + * @param[in] user_data The user data + * @see cion_peer_info_clone() + * @see #__callback_s + */ +typedef void (*__joined_cb)(__h h, + const cion_peer_info_h peer_info, void *user_data); + +/** + * @brief Called when a peer leaves a topic. + * + * @param[in] h The _ handle + * @param[in] peer_info The Cion peer information handle \n + * The @a peer_info can be used only in the callback. To use outside, make a copy. + * @param[in] user_data The user data + * @see cion_peer_info_clone() + * @see #__callback_s + */ +typedef void (*__left_cb)(__h h, + const cion_peer_info_h peer_info, void *user_data); + +)__c_cb"; + + +/** + * The prefix of the interface. + * 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 __register() function. + * + * @see __create_cb + * @see __terminate_cb + */ +typedef struct { + __joined_cb joined;/**< This callback function is invoked when a peer joins a topic. */ + __left_cb left;/**< This callback function is invoked when when a peer leaves a topic. */ + +} __callback_s; + +/** + * @brief Creates a _ handle. + * @remarks The @a h handle should be released using + * the __destroy() if it's no longer needed. + * + * @privilege %http://tizen.org/privilege/d2d.datasharing + * %http://tizen.org/privilege/internet + * + * @param[in] topic_name topic_name The name of topic + * @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 _ handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #CION_ERROR_NONE Successful + * @retval #CION_ERROR_NOT_SUPPORTED Not supported + * @retval #CION_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #CION_ERROR_OUT_OF_MEMORY Out of memory + * @retval #CION_ERROR_PERMISSION_DENIED Permission denied + + * @see __destroy() + * @see #__callback_s + */ +int __create(const char *topic_name, __callback_s *callback, void *user_data, __h *h); + +/** + * @brief Destroys the _ handle. + * + * @param[in] h The _ handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #CION_ERROR_NONE Successful + * @retval #CION_ERROR_INVALID_PARAMETER Invalid parameter + * @see __create() + */ +int __destroy(__h h); + +)__c_cb"; + +/** + * The return type of the method. + * The prefix of the interface. + * The name of the interface. + * The name of the method of the interface. + * 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] peer_info The Cion peer information handle \n + * The @a peer_info can be used only in the callback. To use outside, make a copy. + * @param[in] ... + * @param[in] user_data The user data passed from the registration function + * @see cion_peer_info_clone() + * @see #__callback_s; + */ +typedef (*___cb)(const cion_peer_info_h peer_info, void *user_data); +)__c_cb"; + +/** + * The prefix of the interface. + * The name of the interface. + * The name of the method of the interface. + */ +constexpr const char CB_INTERFACE_METHOD_CALLBACK_DECL[] = +R"__c_cb( +___cb ; /**< This callback function is invoked when the request is delivered. */ +)__c_cb"; + +/** + * The type of the return value. + * The prefix of the interface. + * The of the interface. + * The name of the method. + * The parameters of the method. + */ +constexpr const char CB_INTERFACE_METHOD_BASE[] = +R"__c_cb( +/** + * @brief Calls the () 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 _ handle + * @param[in] ... + * @exception #CION_ERROR_NONE Successful + * @exception #CION_ERROR_INVALID_PARAMETER Invalid parameter + * @exception #CION_ERROR_OUT_OF_MEMORY Out of memory + * @exception #CION_ERROR_IO_ERROR I/O error + */ +__invoke_(__h h); +)__c_cb"; + +#endif // IDLC_C_CION_GEN_C_GROUP_HEADER_GEN_CB_H_ diff --git a/idlc/main.cc b/idlc/main.cc index 7a2c287..b4b68d2 100644 --- a/idlc/main.cc +++ b/idlc/main.cc @@ -35,6 +35,8 @@ #include "idlc/gen_cion/c_cion_proxy_body_gen.h" #include "idlc/gen_cion/c_cion_stub_header_gen.h" #include "idlc/gen_cion/c_cion_stub_body_gen.h" +#include "idlc/gen_cion/c_cion_group_header_gen.h" +#include "idlc/gen_cion/c_cion_group_body_gen.h" #include "idlc/gen_cion/cs_cion_proxy_gen.h" #include "idlc/gen_cion/cs_cion_stub_gen.h" #include "idlc/gen_cion/cpp_cion_proxy_header_gen.h" @@ -237,18 +239,32 @@ void GenerateProxyCodes(std::shared_ptr options, void GenerateGroupCodes(std::shared_ptr options, tidl::Parser& ps) { - switch (options->GetLanguage()) { - case tidl::Options::LANGUAGE_TYPE_C: - break; - case tidl::Options::LANGUAGE_TYPE_CPP: - break; - case tidl::Options::LANGUAGE_TYPE_CSHARP: - break; - case tidl::Options::LANGUAGE_TYPE_JAVA: - break; + if (options->IsCion()) { + switch (options->GetLanguage()) { + case tidl::Options::LANGUAGE_TYPE_C: + { - default: - break; + tidl::CCionGroupHeaderGen group_header(ps.GetDoc()); + group_header.EnableNamespace(options->HasNamespace()); + group_header.SetType(static_cast(options->GetType())); + group_header.Run(options->GetOutput() + ".h"); + + tidl::CCionGroupBodyGen group_body(ps.GetDoc(), options); + group_body.EnableNamespace(options->HasNamespace()); + group_body.SetType(static_cast(options->GetType())); + group_body.Run(options->GetOutput() + ".c"); + break; + } + case tidl::Options::LANGUAGE_TYPE_CPP: + break; + case tidl::Options::LANGUAGE_TYPE_CSHARP: + break; + case tidl::Options::LANGUAGE_TYPE_JAVA: + break; + + default: + break; + } } } @@ -274,7 +290,8 @@ int main(int argc, char** argv) { if (!options) exit(1); - tidl::Parser ps(options->IsBetaEnabled(), options->IsCion()); + tidl::Parser ps(options->IsBetaEnabled(), options->IsCion(), + options->GetType() == tidl::Options::Type::TYPE_GROUP ? true : false); std::string path(options->GetInput()); if (!ps.ParseFromFile(path))