SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wno-unused-function -Wno-sign-compare")
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++11")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++14")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}")
SET(CMAKE_EXE_LINKER_FLAGS "-static-libstdc++ -static-libgcc")
SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
--- /dev/null
+/*
+ * 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_GEN_C_BODY_GEN_ARRAY_BASE_CB_H_
+#define IDLC_C_GEN_C_BODY_GEN_ARRAY_BASE_CB_H_
+
+/**
+ * <PREFIX> The prefix of the array structure.
+ * <NAME> The name of the array structure.
+ * <ELEMENT_TYPE> The type of the element of the array.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ <ELEMENT_TYPE>*value;
+ int size;
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the array structure.
+ * <NAME> The name of the array structure.
+ * <PARCEL_WRITE> The implementation to write the value to the parcel.
+ * <PARCEL_READ> The implemention to read the value from the parcel.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ * <ELEMENT_TYPE> The type of the element of the array.
+ * <ELEMENT_TYPE_SIZE> The size of the type of the element.
+ * <ELEMENTS_FREE> The implementation to release elements.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+ int i;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ rpc_port_parcel_write_array_count(parcel, h->size);
+
+ for (i = 0; i < h->size; ++i)
+ <PARCEL_WRITE>
+}
+
+static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+ <ELEMENT_TYPE>value;
+ int ret;
+ int i;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ ret = rpc_port_parcel_read_array_count(parcel, &h->size);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read array count. error(%d)", ret);
+ set_last_result(ret);
+ return;
+ }
+
+ h->value = calloc(h->size, sizeof(<ELEMENT_TYPE_SIZE>));
+ if (h->value == nullptr) {
+ _E("Out of memory");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+ }
+
+ for (i = 0; i < h->size; ++i) {
+ <PARCEL_READ>
+ }
+
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+int <PREFIX>_<NAME>_create(<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;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_from;
+
+ *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;
+ }
+
+ <ELEMENTS_FREE>
+
+ free(h);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
+{
+ <PREFIX>_<NAME>_h handle;
+ rpc_port_parcel_h parcel;
+ int ret;
+
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_create(&handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ ret = rpc_port_parcel_create(&parcel);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ rpc_port_parcel_write(parcel, &h->parcelable, h);
+ rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+ ret = get_last_result();
+ rpc_port_parcel_destroy(parcel);
+
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ *clone = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_set(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>*value, int size)
+{
+ <PREFIX>_<NAME>_h handle;
+ <PREFIX>_<NAME>_h clone;
+ int ret;
+
+ if (h == nullptr || value == nullptr || size <= 0) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_create(&handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ handle->value = (<ELEMENT_TYPE>*)value;
+ handle->size = size;
+
+ ret = <PREFIX>_<NAME>_clone(handle, &clone);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ handle->value = nullptr;
+ handle->size = 0;
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ handle->value = h->value;
+ handle->size = h->size;
+ <PREFIX>_<NAME>_destroy(handle);
+
+ h->value = clone->value;
+ h->size = clone->size;
+
+ clone->value = nullptr;
+ clone->size = 0;
+ <PREFIX>_<NAME>_destroy(clone);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_get(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>*value, int *size)
+{
+ <PREFIX>_<NAME>_h handle;
+ int ret;
+
+ if (h == nullptr || value == nullptr || size == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_clone(h, &handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ return ret;
+ }
+
+ *value = handle->value;
+ *size = handle->size;
+
+ handle->value = nullptr;
+ handle->size = 0;
+ <PREFIX>_<NAME>_destroy(handle);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel, &h->value[i]->parcelable, h->value[i]);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel, h->value[i]);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel, STRING_GET(h->value[i]));
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel of the value.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel, h->value[i]);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user-defined type.
+ * <NAME> The name of the user-defined type.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+ret = <PREFIX>_<NAME>_create(&value);
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ set_last_result(ret);
+ return;
+}
+
+rpc_port_parcel_read(parcel, &value->parcelable, value);
+if (get_last_result() != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", get_last_result());
+ <PREFIX>_<NAME>_destroy(value);
+ return;
+}
+
+h->value[i] = value;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+value = nullptr;
+rpc_port_parcel_read_bundle(parcel, &value);
+if (value == nullptr) {
+ _E("Failed to read data");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+h->value[i] = value;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_STRING_PARCEL_READ[] =
+R"__c_cb(
+value = nullptr;
+rpc_port_parcel_read_string(parcel, &value);
+if (value == nullptr) {
+ _E("Failed to read data");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+h->value[i] = value;
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel of the value.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &value);
+h->value[i] = value;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_USER_DEFINED_FREE[] =
+R"__c_cb(
+if (h->value) {
+ for (int i = 0; i < h->size; ++i) {
+ if (h->value[i])
+ <PREFIX>_<NAME>_destroy(h->value[i]);
+ }
+
+ free(h->value);
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BUNDLE_FREE[] =
+R"__c_cb(
+if (h->value) {
+ for (int i = 0; i < h->size; ++i) {
+ if (h->value[i])
+ bundle_free(h->value[i]);
+ }
+
+ free(h->value);
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_STRING_FREE[] =
+R"__c_cb(
+if (h->value) {
+ for (int i = 0; i < h->size; ++i) {
+ if (h->value[i])
+ free(h->value[i]);
+ }
+
+ free(h->value);
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_ARRAY_BASE_FREE[] =
+R"__c_cb(
+if (h->value)
+ free(h->value);
+)__c_cb";
+
+#endif // IDLC_C_GEN_C_BODY_GEN_ARRAY_BASE_CB_H_
/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 - 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.
* limitations under the License.
*/
+#include <cstring>
#include <vector>
+#include "idlc/gen/c_body_gen_array_base_cb.h"
#include "idlc/gen/c_body_gen_base.h"
-
-namespace {
#include "idlc/gen/c_body_gen_base_cb.h"
-}
+#include "idlc/gen/c_body_gen_list_base_cb.h"
namespace tidl {
CBodyGeneratorBase::CBodyGeneratorBase(std::shared_ptr<Document> doc)
: CGeneratorBase(doc) {
parcel_type_map_ = {
+ {"none", ""},
{"char", "byte"},
{"int", "int32"},
{"short", "int16"},
{"bundle", "bundle"},
{"file", "string"},
};
-}
-void CBodyGeneratorBase::GenStructures(std::ofstream& stream) {
- for (auto& i : GetDocument().GetBlocks()) {
- if (i->GetType() == Block::TYPE_STRUCTURE) {
- const Structure &st = static_cast<const Structure&>(*i);
- GenStructure(stream, st);
- for (auto& j : st.GetElements().GetElms()) {
- auto& t = j->GetType();
- AddStructureFromType(t);
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ for (auto& e : st.GetElements().GetElms()) {
+ auto& type = e->GetType();
+ AddStructureFromType(type);
}
} else {
- const Interface &inf = static_cast<const Interface&>(*i);
+ auto& inf = static_cast<const Interface&>(*b);
for (auto& d : inf.GetDeclarations().GetDecls()) {
for (auto& p : d->GetParameters().GetParams()) {
- if (IsDelegateType(inf, p->GetParameterType().GetBaseType()))
+ auto& type = p->GetParameterType().GetBaseType();
+ if (IsDelegateType(inf, type))
continue;
- AddStructureFromType(p->GetParameterType().GetBaseType());
+
+ AddStructureFromType(type, inf);
}
}
}
}
-
- for (auto& p : GetStructures()) {
- const Structure& st = *p.second;
- GenStructure(stream, st);
- }
}
-void CBodyGeneratorBase::GenStructure(std::ofstream& stream,
- const Structure& st) {
- GenStructureDeclaration(stream, st);
- GenStructureParcelSerializer(stream, st);
- GenStructureParcelDeserializer(stream, st);
- GenStructureConstructor(stream, st);
- GenStructureDestructor(stream, st);
- GenStructureCloner(stream, st);
- GenStructureSetter(stream, st);
- GenStructureGetter(stream, st);
- GenStructureIterator(stream, st);
- GenStructureRemover(stream, st);
- GenStructureLengthGetter(stream, st);
+void CBodyGeneratorBase::GenIncludeHeader(std::ofstream& stream) {
+ std::string code;
+ code += "#include \"";
+ code += FileName.substr(0, FileName.length() - 2);
+ code += ".h\"";
+ stream << NLine(1);
+ stream << code;
+ stream << NLine(1);
}
-void CBodyGeneratorBase::GenStructureDeclaration(std::ofstream& stream,
- const Structure& st) {
- stream << SmartIndent(GenTemplateString(CB_STRUCT_DECL,
- [&]()->std::string {
- return st.GetComments();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- std::string str;
- for (auto& i : st.GetElements().GetElms()) {
- str += NLine(1) + GetStringFromElementType(i->GetType()) +
- i->GetID() + ";";
- if (i->GetType().ToString() == "array")
- str += NLine(1) + "int " + i->GetID() + "_size;";
- }
- return str;
- }));
+void CBodyGeneratorBase::GenLogTag(std::ofstream& stream,
+ const std::string& log_tag) {
+ std::string code = ReplaceAll(CB_LOG_TAG, "<LOG_TAG>", log_tag);
+ stream << code;
}
-void CBodyGeneratorBase::GenStructureParcelSerializer(std::ofstream& stream,
- const Structure& st) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_STRUCT_SERIALIZER, "##", GetStructIdWithNamespace(st)),
- [&]()->std::string {
- std::string str;
- for (auto& i : st.GetElements().GetElms()) {
- str += NLine(1);
- str += GetParcelWriteString(i->GetID(), i->GetType());
- }
- return str;
- }));
+void CBodyGeneratorBase::GenLogDefinition(std::ofstream& stream) {
+ stream << SmartIndent(CB_LOG_DEF);
}
-void CBodyGeneratorBase::GenStructureParcelDeserializer(std::ofstream& stream,
- const Structure& st) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_STRUCT_DESERIALIZER, "##", GetStructIdWithNamespace(st)),
- [&]()->std::string {
- std::string str;
- for (auto& i : st.GetElements().GetElms()) {
- str += NLine(1);
- str += GetParcelReadString(i->GetID(), i->GetType());
- }
- return str;
- }));
+void CBodyGeneratorBase::GenBaseDefinition(std::ofstream& stream) {
+ stream << SmartIndent(CB_BASE_DEF);
}
-void CBodyGeneratorBase::GenStructureConstructor(std::ofstream& stream,
- const Structure& st) {
- stream << SmartIndent(ReplaceAll(CB_STRUCT_CTOR, "##",
- GetStructIdWithNamespace(st)));
-}
+void CBodyGeneratorBase::GenStructureDefs(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructureDef(stream, st);
+ }
+ }
-void CBodyGeneratorBase::GenStructureDestructor(std::ofstream& stream,
- const Structure& st) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_STRUCT_DTOR, "##",
- GetStructIdWithNamespace(st)),
- [&]()->std::string {
- std::string str;
- for (auto& i : st.GetElements().GetElms()) {
- str += GetFinalizeString(i->GetID(), i->GetType(), "h->");
- }
- return str;
- }));
+ for (auto& i : GetStructures()) {
+ auto& st = i.second;
+ GenStructureDef(stream, *st);
+ }
}
-void CBodyGeneratorBase::GenStructureSetter(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- stream << SmartIndent(GenTemplateString(CB_STRUCT_SETTER,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "list")
- return "add";
- return "set";
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().IsUserDefinedType())
- return GetParcelParamTypeString(i->GetType());
-
- if (i->GetType().ToString() == "list") {
- if (i->GetType().GetMetaType()->IsUserDefinedType() ||
- i->GetType().GetMetaType()->ToString() == "list" ||
- i->GetType().GetMetaType()->ToString() == "array") {
- return GetParcelParamTypeString(*i->GetType().GetMetaType());
- } else {
- return ConvertTypeToString(ParameterType::Direction::IN,
- *i->GetType().GetMetaType());
- }
- }
-
- if (i->GetType().ToString() == "array") {
- return GetStringFromElementType(i->GetType());
- }
-
- return ConvertTypeToString(ParameterType::Direction::IN,
- i->GetType());
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "array") {
- std::string str;
- str += i->GetID();
- str += ", ";
- str += "int " + i->GetID() + "_size";
- return str;
- }
- return i->GetID();
- },
- [&]()->std::string {
- if ((i->GetType().IsUserDefinedType() ||
- i->GetType().ToString() == "string" ||
- i->GetType().ToString() == "bundle" ||
- i->GetType().ToString() == "file") ||
- ((i->GetType().ToString() == "list" ||
- i->GetType().ToString() == "array") &&
- (i->GetType().GetMetaType()->IsUserDefinedType() ||
- i->GetType().GetMetaType()->ToString() == "list" ||
- i->GetType().GetMetaType()->ToString() == "array" ||
- i->GetType().GetMetaType()->ToString() == "string" ||
- i->GetType().GetMetaType()->ToString() == "bundle" ||
- i->GetType().GetMetaType()->ToString() == "file")))
- return "!h || !" + i->GetID();
-
- return "!h";
- },
- [&]()->std::string {
- std::string str;
- str += NLine(1);
- str += GetSetterString(i->GetID(), i->GetType());
- return str;
- }));
- }
+void CBodyGeneratorBase::GenStructureDef(std::ofstream& stream,
+ const Structure& st) {
+ if (st.GetID().compare(0, strlen("array"), "array") == 0)
+ GenStructureArrayDef(stream, st);
+ else if (st.GetID().compare(0, strlen("list"), "list") == 0)
+ GenStructureListDef(stream, st);
+ else
+ GenStructureBaseDef(stream, st);
}
-void CBodyGeneratorBase::GenStructureGetter(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() == "list")
- continue;
+// @see #CB_STRUCTURE_ARRAY_DEF
+void CBodyGeneratorBase::GenStructureArrayDef(std::ofstream& stream,
+ const Structure& st) {
+ std::string code = ReplaceAll(CB_STRUCTURE_ARRAY_DEF, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", st.GetID());
- stream << SmartIndent(GenTemplateString(CB_STRUCT_GETTER,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "array")
- return GetStringFromElementType(i->GetType()) + "*";
-
- return ConvertTypeToString(ParameterType::Direction::OUT,
- i->GetType());
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "array") {
- std::string str;
- str += i->GetID();
- str += ", ";
- str += "int *" + i->GetID() + "_size";
- return str;
- }
- return i->GetID();
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "array") {
- std::string str;
- str += "!";
- str += i->GetID();
- str += " || ";
- str += "!" + i->GetID() + "_size";
- return str;
- }
- return "!" + i->GetID();
- },
- [&]()->std::string {
- std::string str;
- str += NLine(1);
- str += GetGetterString(i->GetID(), i->GetType());
- return str;
- }));
- }
+ auto& elm = st.GetElements().GetElms().front();
+ auto& type = elm->GetType();
+ auto element_type = GetDataTypeString(type, false);
+ code = ReplaceAll(code, "<ELEMENT_TYPE>", element_type);
+
+ stream << SmartIndent(code);
}
-void CBodyGeneratorBase::GenStructureIterator(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() != "list")
- continue;
+// @see #CB_STRUCTURE_LIST_DEF
+void CBodyGeneratorBase::GenStructureListDef(std::ofstream& stream,
+ const Structure& st) {
+ std::string code = ReplaceAll(CB_STRUCTURE_LIST_DEF, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", st.GetID());
- stream << SmartIndent(GenTemplateString(CB_STRUCT_ITERATOR,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().GetMetaType()->IsUserDefinedType() ||
- i->GetType().GetMetaType()->ToString() == "list" ||
- i->GetType().GetMetaType()->ToString() == "array")
- return GetParcelParamTypeString(*i->GetType().GetMetaType());
-
- return ConvertTypeToString(ParameterType::Direction::IN,
- *i->GetType().GetMetaType());
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- std::string str;
- str += NLine(1);
- str += GetIteratorString(i->GetID(), i->GetType());
- return str;
- }));
- }
+ stream << SmartIndent(code);
}
-void CBodyGeneratorBase::GenStructureRemover(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() != "list")
- continue;
+// @see #CB_STRUCTURE_BASE_DEF
+void CBodyGeneratorBase::GenStructureBaseDef(std::ofstream& stream,
+ const Structure& st) {
+ std::string code = ReplaceAll(CB_STRUCTURE_BASE_DEF, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", st.GetID());
- stream << SmartIndent(GenTemplateString(CB_STRUCT_REMOVER,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- if (i->GetType().GetMetaType()->IsUserDefinedType() ||
- i->GetType().GetMetaType()->ToString() == "list" ||
- i->GetType().GetMetaType()->ToString() == "array" ||
- i->GetType().GetMetaType()->ToString() == "string" ||
- i->GetType().GetMetaType()->ToString() == "bundle" ||
- i->GetType().GetMetaType()->ToString() == "file")
- return GetParcelParamTypeString(*i->GetType().GetMetaType());
-
- return ConvertTypeToString(ParameterType::Direction::IN,
- *i->GetType().GetMetaType(), false);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- std::string str;
-
- if (i->GetType().GetMetaType()->IsUserDefinedType() ||
- i->GetType().GetMetaType()->ToString() == "list" ||
- i->GetType().GetMetaType()->ToString() == "array") {
- str = GetHandlePrefix()
- + GetFullNameFromType(*i->GetType().GetMetaType())
- + "_destroy(value);";
- } else {
- str = GetFinalizeString("value", *i->GetType().GetMetaType(), "");
- }
-
- if (str == "")
- return "free(value);\n";
- return str;
- }));
- }
+ auto& elms = st.GetElements();
+ code = ReplaceAll(code, "<ELEMENTS>", GenBaseElements(elms));
+
+ stream << SmartIndent(code);
}
-void CBodyGeneratorBase::GenStructureLengthGetter(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() != "list")
- continue;
+void CBodyGeneratorBase::GenStructures(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructure(stream, st);
+ }
+ }
- stream << SmartIndent(GenTemplateString(CB_STRUCT_LENGTH_GETTER,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- }));
+ for (auto& i : GetStructures()) {
+ auto& st = i.second;
+ GenStructure(stream, *st);
}
}
-void CBodyGeneratorBase::GenStructureCloner(std::ofstream& stream,
- const Structure& st) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_STRUCT_CLONER, "##", GetStructIdWithNamespace(st)),
- [&]()->std::string {
- std::string str;
- for (auto& i : st.GetElements().GetElms()) {
- str += NLine(1);
- str += GetClonerString(i->GetID(), i->GetType(), st);
- }
- return str;
- }));
-}
+void CBodyGeneratorBase::GenStructure(std::ofstream& stream,
+ const Structure& st) {
+ if (st.GetID().compare(0, strlen("array"), "array") == 0)
+ GenStructureArrayBase(stream, st);
+ else if (st.GetID().compare(0, strlen("list"), "list") == 0)
+ GenStructureListBase(stream, st);
+ else
+ GenStructureBase(stream, st);
+}
+
+// @see #CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_WRITE
+// @see #CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_WRITE
+// @see #CB_STRUCTURE_ARRAY_STRING_PARCEL_WRITE
+// @see #CB_STRUCTURE_ARRAY_BASE_PARCEL_WRITE
+std::string CBodyGeneratorBase::GenArrayParcelWrite(
+ const std::unique_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = std::string(CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_WRITE);
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_WRITE);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_ARRAY_STRING_PARCEL_WRITE);
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_BASE_PARCEL_WRITE, "<PARCEL_TYPE>",
+ GetParcelType(type));
+ }
-std::string CBodyGeneratorBase::GetParcelTypeString(const BaseType& type,
- bool meta_type) {
- if (type.IsUserDefinedType())
- return "";
+ return RemoveLine(code);
+}
- if (type.ToString() == "list" ||
+// @see #CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_READ
+// @see #CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_READ
+// @see #CB_STRUCTURE_ARRAY_STRING_PARCEL_READ
+// @see #CB_STRUCTURE_ARRAY_BASE_PARCEL_READ
+std::string CBodyGeneratorBase::GenArrayParcelRead(
+ const std::unique_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
type.ToString() == "array") {
- if (meta_type)
- return "";
- return "array_count";
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+
+ std::string name;
+ auto* meta_type = type.GetMetaType();
+ if (meta_type == nullptr)
+ name = type.ToString();
+ else
+ name = GetFullNameFromType(*meta_type);
+
+ code = ReplaceAll(code, "<NAME>", name);
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_ARRAY_BUNDLE_PARCEL_READ);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_ARRAY_STRING_PARCEL_READ);
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_BASE_PARCEL_READ, "<PARCEL_TYPE>",
+ GetParcelType(type));
}
- return parcel_type_map_[type.ToString()];
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetParcelWriteFunctionString(
- const BaseType& type, bool meta_type) {
- std::string str = "rpc_port_parcel_write";
- std::string parcel_type = GetParcelTypeString(type, meta_type);
- if (parcel_type != "")
- str += "_" + parcel_type;
+// @see #CB_STRUCTURE_ARRAY_USER_DEFINED_FREE
+// @see #CB_STRUCTURE_ARRAY_BUNDLE_FREE
+// @see #CB_STRUCTURE_ARRAY_STRING_FREE
+// @see #CB_STRUCTURE_ARRAY_BASE_FREE
+std::string CBodyGeneratorBase::GenArrayElementsFree(
+ const std::unique_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_ARRAY_USER_DEFINED_FREE, "<PREFIX>",
+ GetHandlePrefix());
- return str;
-}
+ std::string name;
+ auto* meta_type = type.GetMetaType();
+ if (meta_type == nullptr)
+ name = type.ToString();
+ else
+ name = GetFullNameFromType(*meta_type);
-std::string CBodyGeneratorBase::GetParcelWriteString(const std::string& id,
- const BaseType& type) {
- std::string str;
- const char parcel[] = "$$(parcel, $$);";
- const char ternary_operation[] = "## ? ## : \"\"";
-
- str += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelWriteFunctionString(type);
- },
- [&]()->std::string {
- if (type.IsUserDefinedType())
- return "&h->" + id + "->parcelable, h->" + id;
- if (type.ToString() == "list")
- return "g_list_length(h->" + id + ")";
- if (type.ToString() == "array")
- return "h->" + id + "_size";
- if (type.ToString() == "string")
- return ReplaceAll(ternary_operation, "##", "h->" + id);
- return "h->" + id;
- });
-
- if (type.ToString() == "list") {
- str += GenTemplateString(CB_WRITE_LIST_BLOCK,
- [&]()->std::string {
- return "h->" + id;
- },
- [&]()->std::string {
- return GetParcelParamTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- return GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelWriteFunctionString(*type.GetMetaType(), true);
- },
- [&]()->std::string {
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array")
- return "&value->parcelable, value";
- if (type.GetMetaType()->ToString() == "bundle")
- return "value";
- if (type.GetMetaType()->ToString() == "string"
- || type.GetMetaType()->ToString() == "file")
- return ReplaceAll(ternary_operation, "##", "value");
- return "*value";
- });
- });
- } else if (type.ToString() == "array") {
- str += GenTemplateString(CB_WRITE_ARRAY_BLOCK,
- [&]()->std::string {
- return "h->" + id + "_size";
- },
- [&]()->std::string {
- return GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelWriteFunctionString(*type.GetMetaType(), true);
- },
- [&]()->std::string {
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array")
- return "&h->" + id + "[i]->parcelable, h->" + id +"[i]";
- if (type.GetMetaType()->ToString() == "string" ||
- type.GetMetaType()->ToString() == "file")
- return ReplaceAll(ternary_operation, "##", "h->" + id
- + "[i]");
- return "h->" + id + "[i]";
- });
- });
+ code = ReplaceAll(code, "<NAME>", name);
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_ARRAY_BUNDLE_FREE);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_ARRAY_STRING_FREE);
+ } else {
+ code = std::string(CB_STRUCTURE_ARRAY_BASE_FREE);
}
- return str;
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetParcelReadFunctionString(
- const BaseType& type, bool meta_type) {
- std::string str = "rpc_port_parcel_read";
- std::string parcel_type = GetParcelTypeString(type, meta_type);
- if (parcel_type != "")
- str += "_" + parcel_type;
+// @see #CB_STRUCTURE_ARRAY_BASE
+void CBodyGeneratorBase::GenStructureArrayBase(std::ofstream& stream,
+ const Structure& st) {
+ std::string code = ReplaceAll(CB_STRUCTURE_ARRAY_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", st.GetID());
- return str;
+ auto& elm = st.GetElements().GetElms().front();
+ code = ReplaceAll(code, "<PARCEL_WRITE>", GenArrayParcelWrite(elm));
+ code = ReplaceAll(code, "<PARCEL_READ>", GenArrayParcelRead(elm));
+
+ auto& type = elm->GetType();
+ auto param_type = GetParamTypeString(ParameterType::Direction::IN, type);
+ code = ReplaceAll(code, "<PARAM_TYPE_IN>", param_type);
+ param_type = GetParamTypeString(ParameterType::Direction::OUT, type);
+ code = ReplaceAll(code, "<PARAM_TYPE_OUT>", param_type);
+
+ auto element_type = GetDataTypeString(type, false);
+ code = ReplaceAll(code, "<ELEMENT_TYPE>", element_type);
+ auto element_type_size = GetDataTypeString(type, false);
+ element_type_size = RemoveLastSpaces(element_type_size);
+ code = ReplaceAll(code, "<ELEMENT_TYPE_SIZE>", element_type_size);
+ code = ReplaceAll(code, "<ELEMENTS_FREE>", GenArrayElementsFree(elm));
+
+ stream << SmartIndent(code);
}
-std::string CBodyGeneratorBase::GetParcelReadString(const std::string& id,
- const BaseType& type) {
- std::string str;
- const char parcel[] = "$$(parcel, $$);";
-
- if (type.ToString() == "list") {
- str += GenTemplateString(CB_READ_LIST_BLOCK,
- [&]()->std::string {
- return GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(type);
- },
- [&]()->std::string {
- return "&len";
- });
- },
- [&]()->std::string {
- return GetParcelParamTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- std::string s;
-
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array") {
- s += GetConstructorString(*type.GetMetaType(), "value");
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!value";
- },
- [&]()->std::string {
- std::string ss;
- ss += "_E(\"Failed to create handle\");" + NLine(1);
- ss += "return;";
- return ss;
- });
- s += NLine(1);
- s += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(*type.GetMetaType(), true);
- },
- [&]()->std::string {
- return "&value->parcelable, value";
- });
- } else if (type.GetMetaType()->ToString() == "string" ||
- type.GetMetaType()->ToString() == "bundle"||
- type.GetMetaType()->ToString() == "file") {
- s += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(*type.GetMetaType());
- },
- [&]()->std::string {
- return "&value";
- });
- } else {
- s += "value = calloc(1, sizeof(*value));" + NLine(1);
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!value";
- },
- [&]()->std::string {
- std::string ss;
- ss += "_E(\"Out of memory\");" + NLine(1);
- ss += "return;";
- return ss;
- });
- s += NLine(1);
- s += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(*type.GetMetaType());
- },
- [&]()->std::string {
- return "value";
- });
- }
-
- return s;
- },
- [&]()->std::string {
- return "h->" + id;
- },
- [&]()->std::string {
- return "h->" + id;
- });
- } else if (type.ToString() == "array") {
- str += GenTemplateString(ReplaceAll(CB_READ_ARRAY_BLOCK, "##", id),
- [&]()->std::string {
- return GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(type);
- },
- [&]()->std::string {
- return "&h->" + id + "_size";
- });
- },
- [&]()->std::string {
- return GetReturnTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- return GetErrorValue(*type.GetMetaType());
- },
- [&]()->std::string {
- std::string s;
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array") {
- s += GetConstructorString(*type.GetMetaType(), "value");
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!value";
- },
- [&]()->std::string {
- std::string ss;
- ss += "_E(\"Failed to create handle\");" + NLine(1);
- ss += "return;";
- return ss;
- });
- s += NLine(1);
- s += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(*type.GetMetaType(), true);
- },
- [&]()->std::string {
- return "&value->parcelable, value";
- });
- } else {
- s += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(*type.GetMetaType());
- },
- [&]()->std::string {
- return "&value";
- });
- }
- s += NLine(1);
- s += GetSetterString("h->" + id + "[i]", "value");
- return s;
- });
- } else if (type.IsUserDefinedType()) {
- str += GenTemplateString(ReplaceAll(CB_READ_USER_DEFINED_BLOCK, "##", id),
- [&]()->std::string {
- return GetFullNameFromType(type);
- });
+// @see #CB_STRUCTURE_LIST_USER_DEFINED_FREE
+// @see #CB_STRUCTURE_LIST_BUNDLE_FREE
+// @see #CB_STRUCTURE_LIST_STRING_FREE
+// @see #CB_STRUCTURE_LIST_BASE_FREE
+std::string CBodyGeneratorBase::GenListDataFree(
+ const std::unique_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_FREE, "<PREFIX>",
+ GetHandlePrefix());
+
+ std::string name;
+ auto* meta_type = type.GetMetaType();
+ if (meta_type == nullptr)
+ name = type.ToString();
+ else
+ name = GetFullNameFromType(*meta_type);
+
+ code = ReplaceAll(code, "<NAME>", name);
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_FREE);
+ } else if (type.ToString() == "string" || type.ToString() == "flie") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_FREE);
} else {
- str += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(type);
- },
- [&]()->std::string {
- if (type.IsUserDefinedType())
- return "&h->" + id + "->parcelable, h->" + id;
- return "&h->" + id;
- });
+ code = std::string(CB_STRUCTURE_LIST_BASE_FREE);
}
- return str;
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetFinalizeString(const std::string& id,
- const BaseType& type, const std::string& handle) {
- std::string str;
-
- if (!type.IsUserDefinedType() &&
- type.ToString() != "list" &&
- type.ToString() != "array" &&
- type.ToString() != "string" &&
- type.ToString() != "bundle" &&
- type.ToString() != "file")
- return str;
-
- if (type.ToString() == "list") {
- str += GenTemplateString(CB_FINALIZE_LIST_BLOCK,
- [&]()->std::string {
- return handle + id;
- },
- [&]()->std::string {
- return GetParcelParamTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- return GenTemplateString(CB_IF_STATEMENT,
- [&]()->std::string {
- return "value";
- },
- [&]()->std::string {
- return GetDestructorString(*type.GetMetaType(),
- "value", true) + NLine(1);
- });
- },
- [&]()->std::string {
- return handle + id;
- });
- } else if (type.ToString() == "array") {
- if (!type.GetMetaType()->IsUserDefinedType() &&
- type.GetMetaType()->ToString() != "list" &&
- type.GetMetaType()->ToString() != "array" &&
- type.GetMetaType()->ToString() != "string" &&
- type.GetMetaType()->ToString() != "bundle" &&
- type.GetMetaType()->ToString() != "file") {
- return GenTemplateString(CB_IF_STATEMENT,
- [&]()->std::string {
- return handle + id;
- },
- [&]()->std::string {
- return "free(" + handle + id + ");";
- });
- }
- str += GenTemplateString(CB_FINALIZE_ARRAY_BLOCK,
- [&]()->std::string {
- return handle + id + "_size";
- },
- [&]()->std::string {
- return GenTemplateString(CB_IF_STATEMENT,
- [&]()->std::string {
- return handle + id + "[j]";
- },
- [&]()->std::string {
- return GetDestructorString(*type.GetMetaType(),
- handle + id + "[j]", true) + NLine(1);
- });
- },
- [&]()->std::string {
- return handle + id;
- });
+// @see #CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_WRITE
+// @see #CB_STRUCTURE_LIST_BUNDLE_PARCEL_WRITE
+// @see #CB_STRUCTURE_LIST_STRING_PARCEL_WRITE
+// @see #CB_STRUCTURE_LIST_BASE_PARCEL_WRITE
+std::string CBodyGeneratorBase::GenListParcelWrite(
+ const std::unique_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = std::string(CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_WRITE);
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_PARCEL_WRITE);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_PARCEL_WRITE);
} else {
- str += GenTemplateString(CB_IF_STATEMENT,
- [&]()->std::string {
- return handle + id;
- },
- [&]()->std::string {
- return GetDestructorString(type, handle + id) + NLine(1);
- });
+ code = ReplaceAll(CB_STRUCTURE_LIST_BASE_PARCEL_WRITE, "<PARCEL_TYPE>",
+ GetParcelType(type));
}
- return str;
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetSetterString(const std::string& id,
- const BaseType& type) {
- std::string str;
-
+// @see #CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_READ
+// @see #CB_STRUCTURE_LIST_BUNDLE_PARCEL_READ
+// @see #CB_STRUCTURE_LIST_STRING_PARCEL_READ
+// @see #CB_STRUCTURE_LIST_BASE_PARCEL_READ
+std::string CBodyGeneratorBase::GenListParcelRead(
+ const std::unique_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
if (type.IsUserDefinedType() ||
- type.ToString() == "string" ||
- type.ToString() == "bundle" ||
- type.ToString() == "file") {
- str += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "h->" + id;
- },
- [&]()->std::string {
- std::string s;
- s += GetDestructorString(type, "h->" + id) + NLine(1);
- s += GetSetterString("h->" + id, "NULL");
- return s;
- });
- str += NLine(1);
-
- str += NLine(1);
- str += GetSetterString(type, "h->" + id, id);
- str += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!h->" + id;
- },
- [&]()->std::string {
- std::string s;
- s += "_E(\"Failed to duplicate data\");" + NLine(1);
- s += "return -1;";
- return s;
- });
- str += NLine(1);
- } else if (type.ToString() == "list") {
- str += GenTemplateString(CB_SETTER_LIST_BLOCK,
- [&]()->std::string {
- return GetParcelParamTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- std::string s;
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "string" ||
- type.GetMetaType()->ToString() == "bundle" ||
- type.GetMetaType()->ToString() == "file" ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array") {
- s += GetSetterString(*type.GetMetaType(), "value", id);
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!value";
- },
- [&]()->std::string {
- std::string s;
- s += "_E(\"Out of memory\");" + NLine(1);
- s += "return -1;";
- return s;
- });
- s += NLine(1);
- } else {
- s += "value = calloc(1, sizeof(*value));" + NLine(1);
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!value";
- },
- [&]()->std::string {
- std::string s;
- s += "_E(\"Out of memory\");" + NLine(1);
- s += "return -1;";
- return s;
- });
- s += NLine(1);
- s += GetSetterString("*value", id);
- }
- return s;
- },
- [&]()->std::string {
- return "h->" + id;
- },
- [&]()->std::string {
- return "h->" + id;
- });
- } else if (type.ToString() == "array") {
- str += GetFinalizeString(id, type, "h->") + NLine(1);
- str += GetSetterString("h->" + id, "NULL");
- str += NLine(1);
- str += GenTemplateString(ReplaceAll(CB_SETTER_ARRAY_BLOCK, "##", id),
- [&]()->std::string {
- std::string s;
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array")
- s += "int __ret = ";
-
- s += GetSetterString(*type.GetMetaType(), "h->" + id + "[i]",
- id + "[i]");
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array") {
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "__ret != 0";
- },
- [&]()->std::string {
- std::string r;
- r += "_E(\"Failed to clone " + id + "\");" + NLine(1);
- r += GetFinalizeString(id, type, "h->") + NLine(1);
- r += GetSetterString("h->" + id, "NULL") + NLine(1);
- r += "return -1;";
- return r;
- });
- }
-
- s += NLine(1);
- return s;
- });
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+
+ std::string name;
+ auto* meta_type = type.GetMetaType();
+ if (meta_type == nullptr)
+ name = type.ToString();
+ else
+ name = GetFullNameFromType(*meta_type);
+
+ code = ReplaceAll(code, "<NAME>", name);
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_PARCEL_READ);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_PARCEL_READ);
} else {
- str += GetSetterString(type, "h->" + id, id);
+ auto value_type = GetParamTypeString(ParameterType::Direction::IN, type);
+ value_type = RemoveLastSpaces(value_type);
+ code = ReplaceAll(CB_STRUCTURE_LIST_BASE_PARCEL_READ, "<VALUE_TYPE>",
+ value_type);
+ code = ReplaceAll(code, "<PARCEL_TYPE>", GetParcelType(type));
}
- return str;
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetGetterString(const std::string& id,
- const BaseType& type) {
- std::string str;
-
- if (type.ToString() == "array") {
- str += GenTemplateString(ReplaceAll(CB_GETTER_ARRAY_BLOCK, "##", id),
- [&]()->std::string {
- std::string s;
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array")
- s += "int __ret = ";
-
- s += GetSetterString(*type.GetMetaType(),
- "(*" + id + ")[i]", "h->" + id + "[i]");
-
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array") {
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "__ret != 0";
- },
- [&]()->std::string {
- std::string r;
- r += "_E(\"Failed to clone " + id + "\");" + NLine(1);
- r += GetFinalizeString("*" + id, type, "") + NLine(1);
- r += GetSetterString("*" + id, "NULL") + NLine(1);
- r += "return -1;";
- return r;
- });
- }
-
- s += NLine(1);
- return s;
- });
- } else {
- if (type.IsUserDefinedType() ||
- type.ToString() == "string" ||
- type.ToString() == "bundle" ||
- type.ToString() == "file") {
- str += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!h->" + id;
- },
- [&]()->std::string {
- std::string s;
- s += "_E(\"Invalid parameter: h->" + id + " is NULL\");" + NLine(1);
- s += "return -1;";
- return s;
- });
- str += NLine(1);
- str += NLine(1);
- }
+// @see #CB_STRUCTURE_LIST_USER_DEFINED_ADD
+// @see #CB_STRUCTURE_LIST_BUNDLE_ADD
+// @see #CB_STRUCTURE_LIST_STRING_ADD
+// @see #CB_STRUCTURE_LIST_BASE_ADD
+std::string CBodyGeneratorBase::GenListAdd(
+ const std::unique_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_LIST_USER_DEFINED_ADD, "<PREFIX>",
+ GetHandlePrefix());
- if (type.IsUserDefinedType()) {
- str += GetHandlePrefix() + GetFullNameFromType(type) +
- "_clone(h->"+ id + ", " + id +");" + NLine(1);
- } else {
- str += GetSetterString(type, "*" + id, "h->" + id);
- }
+ std::string name;
+ auto* meta_type = type.GetMetaType();
+ if (meta_type == nullptr)
+ name = type.ToString();
+ else
+ name = GetFullNameFromType(*meta_type);
- if (type.IsUserDefinedType() ||
- type.ToString() == "string" ||
- type.ToString() == "bundle" ||
- type.ToString() == "file") {
- str += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "*" + id + " == NULL";
- },
- [&]()->std::string {
- std::string s;
- s += "_E(\"Failed to duplicate " + id + "\");" + NLine(1);
- s += "return -1;";
- return s;
- });
- str += NLine(1);
- }
+ code = ReplaceAll(code, "<NAME>", name);
+ } else if (type.ToString() == "bundle") {
+ code = std::string(CB_STRUCTURE_LIST_BUNDLE_ADD);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = std::string(CB_STRUCTURE_LIST_STRING_ADD);
+ } else {
+ auto value_type = GetParamTypeString(ParameterType::Direction::IN, type);
+ code = ReplaceAll(CB_STRUCTURE_LIST_BASE_ADD, "<VALUE_TYPE>",
+ value_type);
}
- return str;
-}
-std::string CBodyGeneratorBase::GetIteratorString(const std::string& id,
- const BaseType& type) {
- std::string str;
-
- str += GenTemplateString(CB_ITERATOR_BLOCK,
- [&]()->std::string {
- return "h->" + id;
- },
- [&]()->std::string {
- return GetParcelParamTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array" ||
- type.GetMetaType()->ToString() == "string" ||
- type.GetMetaType()->ToString() == "bundle" ||
- type.GetMetaType()->ToString() == "file")
- return "value";
-
- return "*value";
- });
-
- return str;
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetClonerString(const std::string& id,
- const BaseType& type,
- const Structure& st) {
- std::string str;
-
+std::string CBodyGeneratorBase::GenListCallbackParamType(
+ const std::unique_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
if (type.IsUserDefinedType() ||
- type.ToString() == "string" ||
+ type.ToString() == "list" ||
+ type.ToString() == "array"||
type.ToString() == "bundle" ||
- type.ToString() == "file") {
- str += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "h->" + id;
- },
- [&]()->std::string {
- std::string s;
- s += GetSetterString(type, "handle->" + id, "h->" + id);
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!handle->" + id;
- },
- [&]()->std::string {
- std::string ss;
- ss += "_E(\"Failed to duplicate h->" + id + "\");" + NLine(1);
- ss += "rpc_port_" + GetStructIdWithNamespace(st)
- + "_destroy(handle);" + NLine(1);
- ss += "return -1;";
- return ss;
- });
- return s;
- });
- str += NLine(1);
- } else if (type.ToString() == "list") {
- str += GenTemplateString(CB_CLONER_LIST_BLOCK,
- [&]()->std::string {
- return "h->" + id;
- },
- [&]()->std::string {
- return GetParcelParamTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- return GetParcelParamTypeString(*type.GetMetaType());
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- std::string s;
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array" ||
- type.GetMetaType()->ToString() == "string" ||
- type.GetMetaType()->ToString() == "bundle" ||
- type.GetMetaType()->ToString() == "file") {
- s += GetSetterString(*type.GetMetaType(),
- "new_value", "value");
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!new_value";
- },
- [&]()->std::string {
- std::string ss;
- ss += "_E(\"Failed to duplicate value\");" + NLine(1);
- ss += "rpc_port_" + GetStructIdWithNamespace(st)
- + "_destroy(handle);" + NLine(1);
- ss += "return -1;";
- return ss;
- });
- } else {
- s += "new_value = calloc(1, sizeof(*new_value));" + NLine(1);
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "!new_value";
- },
- [&]()->std::string {
- std::string tmp;
- tmp += "_E(\"Out of memory\");" + NLine(1);
- tmp += "rpc_port_" + GetStructIdWithNamespace(st)
- + "_destroy(handle);" + NLine(1);
- tmp += "return -1;";
- return tmp;
- });
- s += NLine(1);
- s += GetSetterString(*type.GetMetaType(),
- "*new_value", "*value");
- }
- s += NLine(1);
- return s;
- },
- [&]()->std::string {
- return "handle->" + id;
- },
- [&]()->std::string {
- return "handle->" + id;
- });
- } else if (type.ToString() == "array") {
- str += GenTemplateString(ReplaceAll(CB_CLONER_ARRAY_BLOCK, "##", id),
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- std::string s;
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array")
- s += "int __ret = ";
-
- s += GetSetterString(*type.GetMetaType(),
- "handle->" + id + "[i]", "h->" + id + "[i]");
-
- if (type.GetMetaType()->IsUserDefinedType() ||
- type.GetMetaType()->ToString() == "list" ||
- type.GetMetaType()->ToString() == "array") {
- s += GenTemplateString(CB_IF_STATEMENT_WITH_BRACES,
- [&]()->std::string {
- return "__ret != 0";
- },
- [&]()->std::string {
- std::string tmp;
- tmp += "_E(\"Failed to clone " + id + "\");" + NLine(1);
- tmp += "rpc_port_" + GetStructIdWithNamespace(st) +
- "_destroy(handle);" + NLine(1);
- tmp += "return -1;";
- return tmp;
- });
- }
-
- s += NLine(1);
- return s;
- });
- } else {
- str += GetSetterString(type, "handle->" + id, "h->" + id);
- }
+ type.ToString() == "string" ||
+ type.ToString() == "file")
+ code = std::string("value");
+ else
+ code = std::string ("*value");
+
+ return code;
+}
+
+// @see #CB_STRUCTURE_LIST_BASE
+void CBodyGeneratorBase::GenStructureListBase(std::ofstream& stream,
+ const Structure& st) {
+ std::string code = ReplaceAll(CB_STRUCTURE_LIST_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", st.GetID());
+
+ auto& elm = st.GetElements().GetElms().front();
+ auto& type = elm->GetType();
+ code = ReplaceAll(code, "<DATA_TYPE>", GetDataTypeString(type, true));
+ code = ReplaceAll(code, "<DATA_FREE>", GenListDataFree(elm));
- return str;
+ auto param_type = GetParamTypeString(ParameterType::Direction::IN, type);
+ code = ReplaceAll(code, "<PARAM_TYPE_IN>", param_type);
+
+ code = ReplaceAll(code, "<PARCEL_WRITE>", GenListParcelWrite(elm));
+ code = ReplaceAll(code, "<PARCEL_READ>", GenListParcelRead(elm));
+
+ code = ReplaceAll(code, "<LIST_ADD>", GenListAdd(elm));
+ code = ReplaceAll(code, "<CALLBACK_PARAM_TYPE>",
+ GenListCallbackParamType(elm));
+
+ stream << SmartIndent(code);
}
-std::string CBodyGeneratorBase::GetDestructorString(const BaseType& type,
- const std::string& value,
- bool container_value) {
- std::string str;
+std::string CBodyGeneratorBase::GenBaseElements(const Elements& elms) {
+ std::string code;
+ for (auto& elm : elms.GetElms()) {
+ auto& type = elm->GetType();
+ auto param_type = GetDataTypeString(type, false);
+ code += param_type + elm->GetID() + ";";
+ code += NLine(1);
+ }
+
+ return code;
+}
+// @see #CB_STRUCTURE_BASE_USER_DEFINED_FREE
+// @see #CB_STRUCTURE_BASE_BUNDLE_FREE
+// @see #CB_STRUCTURE_BASE_STRING_FREE
+std::string CBodyGeneratorBase::GenBaseElementFree(
+ const std::unique_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
if (type.IsUserDefinedType() ||
type.ToString() == "list" ||
type.ToString() == "array") {
- str += GetHandlePrefix() + GetFullNameFromType(type) +
- "_destroy(" + value + ");";
+ code = ReplaceAll(CB_STRUCTURE_BASE_USER_DEFINED_FREE, "<PREFIX>",
+ GetHandlePrefix());
+
+ std::string name = GetFullNameFromType(type);
+ code = ReplaceAll(code, "<NAME>", name);
+ code = ReplaceAll(code, "<ELEMENT_NAME>", elm->GetID());
} else if (type.ToString() == "bundle") {
- str += "bundle_free(" + value + ");";
- } else if (type.ToString() == "string" || type.ToString() == "file" || container_value) {
- str += "free(" + value + ");";
+ code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_FREE, "<ELEMENT_NAME>",
+ elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "flie") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_STRING_FREE, "<ELEMENT_NAME>",
+ elm->GetID());
}
- return str;
+ return code;
+}
+
+std::string CBodyGeneratorBase::GenBaseElementsFree(const Elements& elms) {
+ std::string code;
+ for (auto& elm : elms.GetElms())
+ code += GenBaseElementFree(elm);
+
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetConstructorString(const BaseType& type,
- const std::string& value) {
- std::string str;
- str += GetHandlePrefix() + GetFullNameFromType(type) +
- "_create(&" + value + ");" + NLine(1);
- return str;
+// @see #CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_WRITE
+// @see #CB_STRUCTURE_BASE_BUNDLE_PARCEL_WRITE
+// @see #CB_STRUCTURE_BASE_STRING_PARCEL_WRITE
+// @see #CB_STRUCTURE_BASE_BASE_PARCEL_WRITE
+std::string CBodyGeneratorBase::GenBaseParcelWrite(const Elements& elms) {
+ std::string code;
+ for (auto& elm : elms.GetElms()) {
+ std::string parcel_write_code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_WRITE, "<ELEMENT_NAME>",
+ elm->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_PARCEL_WRITE,
+ "<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_STRUCTURE_BASE_STRING_PARCEL_WRITE,
+ "<ELEMENT_NAME>", elm->GetID());
+ } else {
+ parcel_write_code = ReplaceAll(CB_STRUCTURE_BASE_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ELEMENT_NAME>",
+ elm->GetID());
+ }
+
+ code += parcel_write_code;
+ }
+
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetSetterString(const BaseType& type,
- const std::string& lvalue,
- const std::string& rvalue) {
- std::string str;
+// @see #CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_READ
+// @see #CB_STRUCTURE_BASE_BUNDLE_PARCEL_READ
+// @see #CB_STRUCTURE_BASE_STRING_PARCEL_READ
+// @see #CB_STRUCTURE_BASE_BASE_PARCEL_READ
+std::string CBodyGeneratorBase::GenBaseParcelRead(const Elements& elms) {
+ std::string code;
+ for (auto& elm : elms.GetElms()) {
+ std::string parcel_read_code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_read_code = ReplaceAll(
+ CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>",
+ GetFullNameFromType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ELEMENT_NAME>",
+ elm->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_PARCEL_READ,
+ "<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ parcel_read_code = ReplaceAll(CB_STRUCTURE_BASE_STRING_PARCEL_READ,
+ "<ELEMENT_NAME>", elm->GetID());
+ } else {
+ parcel_read_code = ReplaceAll(CB_STRUCTURE_BASE_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ELEMENT_NAME>",
+ elm->GetID());
+ }
+
+ code += parcel_read_code;
+ }
+
+ return RemoveLine(code);
+}
+// @see #CB_STRUCTURE_BASE_USER_DEFINED_SET
+// @see #CB_STRUCTURE_BASE_BUNDLE_SET
+// @see #CB_STRUCTURE_BASE_STRING_SET
+// @see #CB_STRUCTURE_BASE_BASE_SET
+std::string CBodyGeneratorBase::GenBaseSet(
+ const std::unique_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
if (type.IsUserDefinedType() ||
type.ToString() == "list" ||
type.ToString() == "array") {
- str += GetHandlePrefix() + GetFullNameFromType(type) +
- "_clone(" + rvalue + ", &" + lvalue +");" + NLine(1);
- } else if (type.ToString() == "string" || type.ToString() == "file") {
- str += lvalue + " = strdup(" + rvalue + ");" + NLine(1);
+ code = ReplaceAll(CB_STRUCTURE_BASE_USER_DEFINED_SET, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+
+ auto element_free_code = RemoveLine(GenBaseElementFree(elm));
+ code = ReplaceAll(code, "<ELEMENT_FREE>", element_free_code);
+ code = ReplaceAll(code, "<ELEMENT_NAME>", elm->GetID());
} else if (type.ToString() == "bundle") {
- str += lvalue + " = bundle_dup(" + rvalue + ");" + NLine(1);
+ auto element_free_code = RemoveLine(GenBaseElementFree(elm));
+ code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_SET, "<ELEMENT_FREE>",
+ element_free_code);
+ code = ReplaceAll(code, "<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ auto element_free_code = RemoveLine(GenBaseElementFree(elm));
+ code = ReplaceAll(CB_STRUCTURE_BASE_STRING_SET, "<ELEMENT_FREE>",
+ element_free_code);
+ code = ReplaceAll(code, "<ELEMENT_NAME>", elm->GetID());
} else {
- str += GetSetterString(lvalue, rvalue);
+ code = ReplaceAll(CB_STRUCTURE_BASE_BASE_SET, "<ELEMENT_NAME>",
+ elm->GetID());
}
- return str;
+ return RemoveLine(code);
}
-std::string CBodyGeneratorBase::GetSetterString(const std::string& lvalue,
- const std::string& rvalue) {
- std::string str;
- str += lvalue + " = " + rvalue + ";";
- return str;
+// @see #CB_STRUCTURE_BASE_USER_DEFINED_GET
+// @see #CB_STRUCTURE_BASE_BUNDLE_GET
+// @see #CB_STRUCTURE_BASE_STRING_GET
+// @see #CB_STRUCTURE_BASE_BASE_GET
+std::string CBodyGeneratorBase::GenBaseGet(
+ const std::unique_ptr<Element>& elm) {
+ std::string code;
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_USER_DEFINED_GET, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", GetFullNameFromType(type));
+ code = ReplaceAll(code, "<ELEMENT_NAME>", elm->GetID());
+ } else if (type.ToString() == "bundle") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_BUNDLE_GET, "<ELEMENT_NAME>",
+ elm->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ code = ReplaceAll(CB_STRUCTURE_BASE_STRING_GET, "<ELEMENT_NAME>",
+ elm->GetID());
+ } else {
+ code = ReplaceAll(CB_STRUCTURE_BASE_BASE_GET, "<ELEMENT_NAME>",
+ elm->GetID());
+ }
+
+ return RemoveLine(code);
}
-void CBodyGeneratorBase::GenIncludeHeader(std::ofstream& stream) {
- std::string str;
- str += "#include \"";
- str += FileName.substr(0, FileName.length() - 2);
- str += ".h\"";
- stream << NLine(1);
- stream << str;
- stream << NLine(1);
+// @see #CB_STRUCTURE_BASE_SET_GET
+std::string CBodyGeneratorBase::GenBaseSetGet(const std::string& name,
+ const Elements& elms) {
+ std::string code;
+ for (auto& elm : elms.GetElms()) {
+ std::string set_get_code = ReplaceAll(CB_STRUCTURE_BASE_SET_GET,
+ "<PREFIX>", GetHandlePrefix());
+ set_get_code = ReplaceAll(set_get_code, "<NAME>", name);
+ set_get_code = ReplaceAll(set_get_code, "<ELEMENT_NAME>", elm->GetID());
+
+ auto& type = elm->GetType();
+ auto param_type_in = GetParamTypeString(ParameterType::Direction::IN, type);
+ set_get_code = ReplaceAll(set_get_code, "<PARAM_TYPE_IN>", param_type_in);
+ auto param_type_out = GetParamTypeString(ParameterType::Direction::OUT,
+ type);
+ set_get_code = ReplaceAll(set_get_code, "<PARAM_TYPE_OUT>", param_type_out);
+
+ set_get_code = ReplaceAll(set_get_code, "<BASE_SET>", GenBaseSet(elm));
+ set_get_code = ReplaceAll(set_get_code, "<BASE_GET>", GenBaseGet(elm));
+
+ code += set_get_code;
+ }
+
+ return RemoveLine(code);
}
-void CBodyGeneratorBase::GenLogTag(std::ofstream& stream,
- const std::string& log_tag) {
- GenTemplate(CB_LOG_TAG, stream,
- [&]()->std::string {
- return log_tag;
- });
+// @see #CB_STRUCTURE_BASE
+void CBodyGeneratorBase::GenStructureBase(std::ofstream& stream,
+ const Structure& st) {
+ std::string code = ReplaceAll(CB_STRUCTURE_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", st.GetID());
+
+ auto& elms = st.GetElements();
+ code = ReplaceAll(code, "<ELEMENTS_FREE>", GenBaseElementsFree(elms));
+
+ code = ReplaceAll(code, "<PARCEL_WRITE>", GenBaseParcelWrite(elms));
+ code = ReplaceAll(code, "<PARCEL_READ>", GenBaseParcelRead(elms));
+
+ code += GenBaseSetGet(st.GetID(), elms);
+
+ stream << SmartIndent(code);
}
-void CBodyGeneratorBase::GenInterfaceEnumerations(std::ofstream& stream,
- const Interface& inf) {
- GenInterfaceMethodEnumeration(stream, inf);
- GenInterfaceDelegateEnumeration(stream, inf);
+const std::string& CBodyGeneratorBase::GetParcelType(const BaseType& type) {
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array")
+ return parcel_type_map_["none"];
+
+ return parcel_type_map_[type.ToString()];
}
-bool CBodyGeneratorBase::HasDelegate(const Interface& inf) const {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE) {
- return true;
+bool CBodyGeneratorBase::HasListFile(const Interface& inf) {
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (IsProxy() && d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ for (auto& p : d->GetParameters().GetParams()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ auto name = GetFullNameFromType(type, inf);
+ if (name == "list_file")
+ return true;
}
}
return false;
}
-void CBodyGeneratorBase::GenInterfaceDelegateEnumeration(
- std::ofstream& stream, const Interface& inf) {
- int count = 1;
+// @see #CB_PRIVATE_SHARING_LIST_SET
+void CBodyGeneratorBase::GenPrivateSharingListSet(std::ofstream& stream) {
+ bool has_list_file = false;
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
- if (!HasDelegate(inf))
- return;
+ auto& inf = static_cast<const Interface&>(*i);
+ has_list_file = HasListFile(inf);
+ if (has_list_file)
+ break;
+ }
- stream << SmartIndent(GenTemplateString(CB_DELEGATE_ENUM,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- std::string str;
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
- continue;
-
- str += GenTemplateString(CB_DELEGATE_ENUM_FORMAT,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return std::to_string(count++);
- });
- }
- return str;
- }));
-}
+ if (!has_list_file)
+ return;
-void CBodyGeneratorBase::GenInterfaceMethodEnumeration(
- std::ofstream& stream, const Interface& inf) {
- stream << SmartIndent(GenTemplateString(CB_METHOD_ENUM,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- std::string str;
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
- continue;
- str += GenTemplateString(CB_METHOD_ENUM_FORMAT,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return i->GetID();
- });
- }
- return str;
- }));
-}
+ stream << SmartIndent(std::string(CB_PRIVATE_SHARING_LIST_SET));
+}
+
+// @see #CB_LIST_FILE_SET_PRIVATE_SHARING
+// @see #CB_ARRAY_FILE_SET_PRIVATE_SHARING
+// @see #CB_FILE_SET_PRIVATE_SHARING
+std::string CBodyGeneratorBase::GetPrivateSharingString(const BaseType& type,
+ const Interface& inf, const std::string& port, const std::string& arg) {
+ std::string code;
+ std::string name = GetFullNameFromType(type, inf);
+ if (name == "list_file") {
+ code = ReplaceAll(CB_LIST_FILE_SET_PRIVATE_SHARING, "<PORT>", port);
+ code = ReplaceAll(code, "<ARG>", arg);
+ } else if (name == "array_file") {
+ code = ReplaceAll(CB_ARRAY_FILE_SET_PRIVATE_SHARING, "<PORT>", port);
+ code = ReplaceAll(code, "<ARG>", arg);
+ } else if (name == "file") {
+ code = ReplaceAll(CB_FILE_SET_PRIVATE_SHARING, "<PORT>", port);
+ code = ReplaceAll(code, "<ARG>", arg);
+ }
-void CBodyGeneratorBase::GenLogDefinition(std::ofstream& stream) {
- stream << SmartIndent(CB_LOG_DEF);
+ return code;
}
} // namespace tidl
/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 - 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.
explicit CBodyGeneratorBase(std::shared_ptr<Document> doc);
virtual ~CBodyGeneratorBase() = default;
+ void GenStructureDefs(std::ofstream& stream);
void GenStructures(std::ofstream& stream);
void GenIncludeHeader(std::ofstream& stream);
void GenLogTag(std::ofstream& stream, const std::string& log_tag);
- void GenInterfaceEnumerations(std::ofstream& stream, const Interface& inf);
- std::string GetParcelWriteFunctionString(const BaseType& type,
- bool meta_type = false);
- std::string GetParcelReadFunctionString(const BaseType& type,
- bool meta_type = false);
- std::string GetDestructorString(const BaseType& type,
- const std::string& value,
- bool container_value = false);
- std::string GetConstructorString(const BaseType& type,
- const std::string& value);
- bool HasDelegate(const Interface& inf) const;
void GenLogDefinition(std::ofstream& stream);
+ void GenBaseDefinition(std::ofstream& stream);
+ const std::string& GetParcelType(const BaseType& type);
- private:
- void GenInterfaceMethodEnumeration(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceDelegateEnumeration(std::ofstream& stream,
- const Interface& inf);
+ void GenPrivateSharingListSet(std::ofstream& stream);
+ std::string GetPrivateSharingString(const BaseType& type,
+ const Interface& inf, const std::string& port, const std::string& arg);
private:
+ void GenStructureDef(std::ofstream& stream, const Structure& st);
+ void GenStructureBaseDef(std::ofstream& stream, const Structure& st);
+ void GenStructureArrayDef(std::ofstream& stream, const Structure& st);
+ void GenStructureListDef(std::ofstream& stream, const Structure& st);
+
void GenStructure(std::ofstream& stream, const Structure& st);
- void GenStructureDeclaration(std::ofstream& stream, const Structure& st);
- void GenStructureParcelSerializer(std::ofstream& stream, const Structure& st);
- void GenStructureParcelDeserializer(std::ofstream& stream,
- const Structure& st);
- void GenStructureConstructor(std::ofstream& stream, const Structure& st);
- void GenStructureDestructor(std::ofstream& stream, const Structure& st);
- void GenStructureSetter(std::ofstream& stream, const Structure& st);
- void GenStructureGetter(std::ofstream& stream, const Structure& st);
- void GenStructureIterator(std::ofstream& stream, const Structure& st);
- void GenStructureCloner(std::ofstream& stream, const Structure& st);
- void GenStructureRemover(std::ofstream& stream, const Structure& st);
- void GenStructureLengthGetter(std::ofstream& stream, const Structure& st);
+ void GenStructureBase(std::ofstream& stream, const Structure& st);
+ void GenStructureArrayBase(std::ofstream& stream, const Structure& st);
+ void GenStructureListBase(std::ofstream& stream, const Structure& st);
- private:
- std::string GetParcelTypeString(const BaseType& type, bool meta_type);
- std::string GetParcelWriteString(const std::string& id, const BaseType& type);
- std::string GetParcelReadString(const std::string& id, const BaseType& type);
- std::string GetFinalizeString(const std::string& id, const BaseType& type,
- const std::string& handle);
- std::string GetSetterString(const std::string& id, const BaseType& type);
- std::string GetGetterString(const std::string& id, const BaseType& type);
- std::string GetIteratorString(const std::string& id, const BaseType& type);
- std::string GetClonerString(const std::string& id, const BaseType& type,
- const Structure& st);
- std::string GetSetterString(const BaseType& type, const std::string& lvalue,
- const std::string& rvalue);
- std::string GetSetterString(const std::string& lvalue,
- const std::string& rvalue);
+ std::string GenArrayParcelWrite(const std::unique_ptr<Element>& elm);
+ std::string GenArrayParcelRead(const std::unique_ptr<Element>& elm);
+ std::string GenArrayElementsFree(const std::unique_ptr<Element>& elm);
+
+ std::string GenListDataFree(const std::unique_ptr<Element>& elm);
+ std::string GenListParcelWrite(const std::unique_ptr<Element>& elm);
+ std::string GenListParcelRead(const std::unique_ptr<Element>& elm);
+ std::string GenListAdd(const std::unique_ptr<Element>& elm);
+ std::string GenListCallbackParamType(const std::unique_ptr<Element>& elm);
+
+ std::string GenBaseElements(const Elements& elms);
+ std::string GenBaseElementFree(const std::unique_ptr<Element>& elm);
+ std::string GenBaseElementsFree(const Elements& elms);
+ std::string GenBaseParcelWrite(const Elements& elms);
+ std::string GenBaseParcelRead(const Elements& elms);
+ std::string GenBaseSetGet(const std::string& name, const Elements& elms);
+ std::string GenBaseSet(const std::unique_ptr<Element>& elm);
+ std::string GenBaseGet(const std::unique_ptr<Element>& elm);
+
+ bool HasListFile(const Interface& inf);
private:
std::map<std::string, std::string> parcel_type_map_;
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
#ifndef IDLC_C_GEN_C_BODY_GEN_BASE_CB_H_
#define IDLC_C_GEN_C_BODY_GEN_BASE_CB_H_
-const char CB_STRUCT_DECL[] =
+/**
+ * <LOG_TAG> The log tag.
+ */
+constexpr const char CB_LOG_TAG[] =
R"__c_cb(
-$$struct $$_s {
- rpc_port_parcelable_t parcelable;$$
-};
+#undef LOG_TAG
+#define LOG_TAG "<LOG_TAG>"
)__c_cb";
-const char CB_STRUCT_SERIALIZER[] =
+constexpr const char CB_LOG_DEF[] =
R"__c_cb(
-static void __##_to(rpc_port_parcel_h parcel, void *data)
-{
- rpc_port_##_h h = data;
+#undef _E
+#define _E(fmt, ...) dlog_print(DLOG_ERROR, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
- if (!parcel || !h) {
- _E("Invalid parameter");
- return;
- }
-$$
-}
+#undef _W
+#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _I
+#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#undef _D
+#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
)__c_cb";
-const char CB_STRUCT_DESERIALIZER[] =
+constexpr const char CB_BASE_DEF[] =
R"__c_cb(
-static void __##_from(rpc_port_parcel_h parcel, void *data)
-{
- rpc_port_##_h h = data;
+#ifndef nullptr
+#define nullptr NULL
+#endif
- if (!parcel || !h) {
- _E("Invalid parameter");
- return;
- }
-$$
-}
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
+#ifndef STRING_GET
+#define STRING_GET(x) ((x) ? x : "")
+#endif
)__c_cb";
-const char CB_STRUCT_CTOR[] =
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ELEMENTS> Elements of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ <ELEMENTS>
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ELEMENTS_FREE> The implementation to release elements of the structure.
+ * <PARCEL_WRITE> The implementation to write the data to the parcel.
+ * <PARCEL_READ> The implementation to read the data from the parcel.
+ */
+constexpr const char CB_STRUCTURE_BASE[] =
R"__c_cb(
-int rpc_port_##_create(rpc_port_##_h *h)
+static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
{
- struct ##_s *handle;
+ <PREFIX>_<NAME>_h h = data;
- if (!h) {
- _E("Invalid parameter");
- return -1;
- }
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
- handle = calloc(1, sizeof(struct ##_s));
- if (!handle) {
- _E("Out of memory");
- return -1;
- }
+ <PARCEL_WRITE>
+}
+
+static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
- handle->parcelable.to = __##_to;
- handle->parcelable.from = __##_from;
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
- *h = handle;
+ <PARCEL_READ>
- return 0;
+ set_last_result(RPC_PORT_ERROR_NONE);
}
-)__c_cb";
-const char CB_STRUCT_DTOR[] =
-R"__c_cb(
-int rpc_port_##_destroy(rpc_port_##_h h)
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h)
{
- if (!h) {
- _E("Invalid parameter");
- return -1;
- }
+ <PREFIX>_<NAME>_t *handle;
-$$
- free(h);
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- return 0;
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_from;
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_STRUCT_SETTER[] =
-R"__c_cb(
-int rpc_port_$$_$$_$$(rpc_port_$$_h h, $$$$)
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
{
- if ($$) {
- _E("Invalid parameter");
- return -1;
- }
-$$
- return 0;
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ <ELEMENTS_FREE>
+
+ free(h);
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_STRUCT_GETTER[] =
-R"__c_cb(
-int rpc_port_$$_get_$$(rpc_port_$$_h h, $$$$)
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
{
- if (!h || $$) {
- _E("Invalid parameter");
- return -1;
- }
-$$
- return 0;
+ <PREFIX>_<NAME>_h handle;
+ rpc_port_parcel_h parcel;
+ int ret;
+
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_create(&handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ ret = rpc_port_parcel_create(&parcel);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ rpc_port_parcel_write(parcel, &h->parcelable, h);
+ rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+ ret = get_last_result();
+ rpc_port_parcel_destroy(parcel);
+
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ *clone = handle;
+
+ return RPC_PORT_ERROR_NONE;
}
)__c_cb";
-const char CB_STRUCT_ITERATOR[] =
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <PARAM_TYPE_IN> The type of the input paramter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * <BASE_SET> The implementation to set the data to the structure.
+ * <BASE_GET> The implementation to get the data from the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_SET_GET[] =
R"__c_cb(
-int rpc_port_$$_foreach_$$(rpc_port_$$_h h,
- bool (*callback)($$$$, void *user_data), void *user_data)
+int <PREFIX>_<NAME>_set_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value)
{
- if (!h || !callback) {
- _E("Invalid parameter");
- return -1;
- }
-$$
- return 0;
+ <BASE_SET>
}
-)__c_cb";
-const char CB_STRUCT_REMOVER[] =
-R"__c_cb(
-int rpc_port_$$_remove_$$(rpc_port_$$_h h, unsigned int nth)
+int <PREFIX>_<NAME>_get_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>value)
{
- GList *iter;
+ <BASE_GET>
+}
+)__c_cb";
- if (!h) {
- _E("Invalid parameter");
- return -1;
- }
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel, &h-><ELEMENT_NAME>->parcelable, h-><ELEMENT_NAME>);
+)__c_cb";
- iter = g_list_nth(h->$$, nth);
- if (iter == NULL)
- return -1;
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel, h-><ELEMENT_NAME>);
+)__c_cb";
- $$value = iter->data;
- h->$$ = g_list_remove_link(h->$$, iter);
-$$
- g_list_free(iter);
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel, STRING_GET(h-><ELEMENT_NAME>));
+)__c_cb";
- return 0;
-}
+/**
+ * <PARCEL_TYPE> The type of the parcel of the element.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel, h-><ELEMENT_NAME>);
)__c_cb";
-const char CB_STRUCT_LENGTH_GETTER[] =
+/**
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_PARCEL_READ[] =
R"__c_cb(
-int rpc_port_$$_get_$$_length(rpc_port_$$_h h, unsigned int *length)
-{
- if (!h || !length) {
- _E("Invalid parameter");
- return -1;
- }
+<PREFIX>_<NAME>_create(&h-><ELEMENT_NAME>);
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("Failed to create handle");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+}
- *length = g_list_length(h->$$);
+rpc_port_parcel_read(parcel, &h-><ELEMENT_NAME>->parcelable, h-><ELEMENT_NAME>);
+if (get_last_result() != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data");
+ return;
+}
+)__c_cb";
- return 0;
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_bundle(parcel, &h-><ELEMENT_NAME>);
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("Failed to read data");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
}
)__c_cb";
-const char CB_STRUCT_CLONER[] =
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_PARCEL_READ[] =
R"__c_cb(
-int rpc_port_##_clone(rpc_port_##_h h, rpc_port_##_h *clone)
-{
- rpc_port_##_h handle = NULL;
-
- if (!h || !clone) {
- _E("Invalid parameter");
- return -1;
- }
-
- rpc_port_##_create(&handle);
- if (!handle) {
- _E("Failed to create ## handle");
- return -1;
- }
-$$
- *clone = handle;
-
- return 0;
+rpc_port_parcel_read_string(parcel, &h-><ELEMENT_NAME>);
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("Failed to read data");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
}
)__c_cb";
-const char CB_WRITE_LIST_BLOCK[] =
+/**
+ * <PARCEL_TYPE> The type of the parcel of the element.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BASE_PARCEL_READ[] =
R"__c_cb(
-do {
- GList *iter;
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &h-><ELEMENT_NAME>);
+)__c_cb";
- iter = $$;
- while (iter) {
- $$value = iter->data;
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_FREE[] =
+R"__c_cb(
+if (h-><ELEMENT_NAME>)
+ <PREFIX>_<NAME>_destroy(h-><ELEMENT_NAME>);
+)__c_cb";
- iter = g_list_next(iter);
- if (!value) {
- _W("Warning: value is NULL");
- continue;
- }
- $$
- }
-} while (0);
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_FREE[] =
+R"__c_cb(
+if (h-><ELEMENT_NAME>)
+ bundle_free(h-><ELEMENT_NAME>);
)__c_cb";
-const char CB_WRITE_ARRAY_BLOCK[] =
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_FREE[] =
R"__c_cb(
-do {
- for (int i = 0; i < $$; i++) {
-$$
- }
-} while (0);
+if (h-><ELEMENT_NAME>)
+ free(h-><ELEMENT_NAME>);
)__c_cb";
-const char CB_READ_LIST_BLOCK[] =
-R"__c_cb(do {
- int len = 0;
+/**
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ * <ELEMENT_FREE> The implementation to release the element of the structure.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * @see #CB_STRUCTURE_BASE_USER_DEFINED_FREE
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_SET[] =
+R"__c_cb(
+<PREFIX>_<NAME>_h new_value;
+int ret;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+ret = <PREFIX>_<NAME>_clone(value, &new_value);
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ return ret;
+}
+
+<ELEMENT_FREE>
- $$
- for (int i = 0; i < len; i++) {
- $$value = NULL;
+h-><ELEMENT_NAME> = new_value;
- $$
- $$ = g_list_append($$, value);
- }
-} while (0);
+return RPC_PORT_ERROR_NONE;
)__c_cb";
-const char CB_READ_ARRAY_BLOCK[] =
+/**
+ * <ELEMENT_FREE> The implementation to release the element of the structure.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * @see #CB_STRUCTURE_BASE_BUNDLE_FREE
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_SET[] =
R"__c_cb(
-do {
- $$
+bundle *new_value;
- h->## = calloc(h->##_size, sizeof(*h->##));
- if (!h->##) {
- _E("Out of memory");
- return;
- }
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
- for (int i = 0; i < h->##_size; i++) {
- $$value = $$;
+new_value = bundle_dup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
- $$
- }
-} while (0);
-)__c_cb";
+<ELEMENT_FREE>
-const char CB_READ_USER_DEFINED_BLOCK[] =
-R"__c_cb(do {
- rpc_port_$$_create(&h->##);
- if (!h->##) {
- _E("Failed to create handle");
- return;
- }
+h-><ELEMENT_NAME> = new_value;
- rpc_port_parcel_read(parcel, &h->##->parcelable, h->##);
-} while (0);
+return RPC_PORT_ERROR_NONE;
)__c_cb";
-const char CB_FINALIZE_LIST_BLOCK[] =
+/**
+ * <ELEMENT_FREE> The implementation to release the element of the structure.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ * @see #CB_STRUCTURE_BASE_STRING_FREE
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_SET[] =
R"__c_cb(
-do {
- GList *iter;
-
- iter = $$;
- while (iter) {
- $$value = iter->data;
- $$
- iter = g_list_next(iter);
- }
- g_list_free($$);
-} while (0);
-)__c_cb";
+char *new_value;
-const char CB_FINALIZE_ARRAY_BLOCK[] =
-R"__c_cb(
-do {
- for (int j = 0; j < $$; j++) {
- $$
- }
- free($$);
-} while (0);
-)__c_cb";
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
-const char CB_SETTER_LIST_BLOCK[] =
-R"__c_cb(
-do {
- $$value = NULL;
+new_value = strdup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
- $$
- $$ = g_list_append($$, value);
-} while (0);
-)__c_cb";
+<ELEMENT_FREE>
-const char CB_SETTER_ARRAY_BLOCK[] =
-R"__c_cb(
-do {
- h->## = calloc(##_size, sizeof(*##));
- if (!h->##) {
- _E("Out of memory");
- return -1;
- }
- h->##_size = ##_size;
-
- for (int i = 0; i < h->##_size; i++) {
- $$
- }
-} while (0);
+h-><ELEMENT_NAME> = new_value;
+
+return RPC_PORT_ERROR_NONE;
)__c_cb";
-const char CB_GETTER_ARRAY_BLOCK[] =
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BASE_SET[] =
R"__c_cb(
-do {
- if (h->##_size == 0) {
- _W("## is empty");
- break;
- }
-
- *## = calloc(h->##_size, sizeof(*h->##));
- if (!*##) {
- _E("Out of memory");
- return -1;
- }
- *##_size = h->##_size;
-
- for (int i = 0; i < h->##_size; i++) {
- $$
- }
-} while (0);
+if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+h-><ELEMENT_NAME> = value;
+
+return RPC_PORT_ERROR_NONE;
)__c_cb";
-const char CB_ITERATOR_BLOCK[] =
+/**
+ * <PREFIX> The prefix of the element type.
+ * <NAME> The name of the element type.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_USER_DEFINED_GET[] =
R"__c_cb(
-do {
- GList *iter;
+<PREFIX>_<NAME>_h new_value;
+int ret;
- iter = $$;
- while (iter) {
- $$value = iter->data;
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
- iter = g_list_next(iter);
- if (!value) {
- _W("Warning: value is NULL");
- continue;
- }
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("<ELEMENT_NAME> is nullptr");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
- bool ret = callback($$, user_data);
- if (!ret)
- break;
- }
-} while (0);
-)__c_cb";
+ret = <PREFIX>_<NAME>_clone(h-><ELEMENT_NAME>, &new_value);
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to clone handle. error(%d)", ret);
+ return ret;
+}
-const char CB_CLONER_LIST_BLOCK[] =
-R"__c_cb(
-do {
- GList *iter;
-
- iter = $$;
- while (iter) {
- $$new_value;
- $$value = iter->data;
-
- if (!value) {
- _E("Error: value is NULL");
- rpc_port_$$_destroy(handle);
- return -1;
- }
+*value = new_value;
- $$
- $$ = g_list_append($$, new_value);
- iter = g_list_next(iter);
- }
-} while (0);
+return RPC_PORT_ERROR_NONE;
)__c_cb";
-const char CB_CLONER_ARRAY_BLOCK[] =
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BUNDLE_GET[] =
R"__c_cb(
-do {
- if (h->##_size == 0) {
- _W("## is empty");
- break;
- }
-
- handle->## = calloc(h->##_size, sizeof(*h->##));
- if (!handle->##) {
- _E("Out of memory");
- rpc_port_$$_destroy(handle);
- return -1;
- }
- handle->##_size = h->##_size;
-
- for (int i = 0; i < h->##_size; i++) {
- $$
- }
-} while (0);
-)__c_cb";
+bundle *new_value;
-const char CB_IF_STATEMENT_WITH_BRACES[] =
-R"__c_cb(if ($$) {
- $$
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
}
-)__c_cb";
-const char CB_IF_STATEMENT[] =
-R"__c_cb(if ($$)
- $$
-)__c_cb";
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("<ELEMENT_NAME> is nullptr");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
-const char CB_DELEGATE_ENUM_FORMAT[] = "\n$$_DELEGATE_$$ = $$,";
+new_value = bundle_dup(h-><ELEMENT_NAME>);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
-const char CB_DELEGATE_ENUM[] =
-R"__c_cb(
-enum $$_delegate_e {$$
-};
-)__c_cb";
+*value = new_value;
-const char CB_METHOD_ENUM_FORMAT[] = "\n$$_METHOD_$$,";
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
-const char CB_METHOD_ENUM[] =
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_STRING_GET[] =
R"__c_cb(
-enum $$_method_e {
- $$_METHOD_Result,
- $$_METHOD_Callback,$$
-};
+char *new_value;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+if (h-><ELEMENT_NAME> == nullptr) {
+ _E("<ELEMENT_NAME> is nullptr");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = strdup(h-><ELEMENT_NAME>);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+*value = new_value;
+
+return RPC_PORT_ERROR_NONE;
)__c_cb";
-const char CB_LOG_TAG[] =
+/**
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_BASE_GET[] =
R"__c_cb(
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
-#define LOG_TAG "$$"
+*value = h-><ELEMENT_NAME>;
+
+return RPC_PORT_ERROR_NONE;
)__c_cb";
-const char CB_LOG_DEF[] =
+constexpr const char CB_PRIVATE_SHARING_LIST_SET[] =
R"__c_cb(
-#ifdef _E
-#undef _E
-#endif
+static int __rpc_port_set_private_sharing_list(rpc_port_h port, GList *list)
+{
+ const char **array_file;
+ const char *value;
+ guint size;
+ GList *iter;
+ int idx = 0;
+ int ret;
+
+ size = g_list_length(list);
+ if (size == 0) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
-#ifdef _W
-#undef _W
-#endif
+ array_file = calloc(size, sizeof(const char*));
+ if (array_file == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
-#ifdef _I
-#undef _I
-#endif
+ iter = list;
+ while (iter) {
+ value = iter->data;
+ array_file[idx++] = value;
+ iter = g_list_next(iter);
+ }
-#ifdef _D
-#undef _D
-#endif
+ ret = rpc_port_set_private_sharing_array(port, array_file, idx);
+ free(array_file);
-#define _E(fmt, ...) dlog_print(DLOG_ERROR, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
-#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
-#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
-#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > "fmt, basename(__FILE__), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+ return ret;
+}
+)__c_cb";
+
+/**
+ * <PORT> The rpc port handle.
+ * <ARG> The argument.
+ */
+constexpr const char CB_LIST_FILE_SET_PRIVATE_SHARING[] =
+R"__c_cb(
+__rpc_port_set_private_sharing_list(<PORT>, <ARG>->list);
+)__c_cb";
+
+/**
+ * <PORT> The rpc port handle.
+ * <ARG> The argument.
+ */
+constexpr const char CB_ARRAY_FILE_SET_PRIVATE_SHARING[] =
+R"__c_cb(
+rpc_port_set_private_sharing_array(<PORT>, (const char **)<ARG>->value, <ARG>->size);
+)__c_cb";
+
+/**
+ * <PORT> The rpc port handle.
+ * <ARG> The argument.
+ */
+constexpr const char CB_FILE_SET_PRIVATE_SHARING[] =
+R"__c_cb(
+rpc_port_set_private_sharing(<PORT>, <ARG>);
)__c_cb";
#endif // IDLC_C_GEN_C_BODY_GEN_BASE_CB_H_
--- /dev/null
+/*
+ * 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_GEN_C_BODY_GEN_LIST_BASE_CB_H_
+#define IDLC_C_GEN_C_BODY_GEN_LIST_BASE_CB_H_
+
+/**
+ * <PREFIX> The prefix of the list structure.
+ * <NAME> The name of the list structure.
+ */
+constexpr const char CB_STRUCTURE_LIST_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_s {
+ rpc_port_parcelable_t parcelable;
+ GList *list;
+} <PREFIX>_<NAME>_t;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the list structure.
+ * <NAME> The name of the list structure.
+ * <DATA_TYPE> The type of the data of the list.
+ * <DATA_FREE> The implementation to release the data of the list.
+ * <PARAM_TYPE_IN> The type of the parameter of the add function.
+ * <PARCEL_WRITE> The implementation to write the data to parcel.
+ * <PARCEL_READ> The implementation to read the data from the parcel.
+ * <LIST_ADD> The implementation to add the data to the list.
+ * <CALLBACK_PARAM_TYPE> The type of the parameter of the callback.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+ <DATA_TYPE>value;
+ GList *iter;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ rpc_port_parcel_write_array_count(parcel, g_list_length(h->list));
+
+ iter = h->list;
+ while (iter) {
+ value = iter->data;
+ iter = g_list_next(iter);
+ <PARCEL_WRITE>
+ }
+}
+
+static void __<PREFIX>_<NAME>_from(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+ <DATA_TYPE>value = nullptr;
+ int ret;
+ int len = 0;
+ int i;
+
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ ret = rpc_port_parcel_read_array_count(parcel, &len);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read array count. error(%d)", ret);
+ set_last_result(ret);
+ return;
+ }
+
+ for (i = 0; i < len; ++i) {
+ <PARCEL_READ>
+ }
+
+ set_last_result(RPC_PORT_ERROR_NONE);
+}
+
+int <PREFIX>_<NAME>_create(<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;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_from;
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
+{
+ <DATA_TYPE>value;
+ GList *iter;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (h->list) {
+ iter = h->list;
+ while (iter) {
+ value = iter->data;
+ iter = g_list_next(iter);
+ <DATA_FREE>
+ }
+
+ g_list_free(h->list);
+ }
+
+ free(h);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone)
+{
+ <PREFIX>_<NAME>_h handle;
+ rpc_port_parcel_h parcel;
+ int ret;
+
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_create(&handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ ret = rpc_port_parcel_create(&parcel);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ rpc_port_parcel_write(parcel, &h->parcelable, h);
+ rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+ ret = get_last_result();
+ rpc_port_parcel_destroy(parcel);
+
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ *clone = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_add(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value)
+{
+ <LIST_ADD>
+}
+
+int <PREFIX>_<NAME>_foreach(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_cb callback, void *user_data)
+{
+ <DATA_TYPE>value;
+ GList *iter;
+
+ if (h == nullptr || callback == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ iter = h->list;
+ while (iter) {
+ value = iter->data;
+ iter = g_list_next(iter);
+ if (!callback(<CALLBACK_PARAM_TYPE>, user_data))
+ break;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_remove(<PREFIX>_<NAME>_h h, unsigned int nth)
+{
+ <DATA_TYPE>value;
+ GList *found;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ found = g_list_nth(h->list, nth);
+ if (found == nullptr)
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+
+ value = found->data;
+ h->list = g_list_remove_link(h->list, found);
+ <DATA_FREE>
+ g_list_free(found);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_length(<PREFIX>_<NAME>_h h, unsigned int *length)
+{
+ if (h == nullptr || length == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *length = g_list_length(h->list);
+
+ return RPC_PORT_ERROR_NONE;
+}
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write(parcel, &value->parcelable, value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel, value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel, STRING_GET(value));
+)__c_cb";
+
+/**
+ * <PARCEL_TYPE> The type of the parcel of the value.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel, *value);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user-defined type.
+ * <NAME> The name of the user-defined type.
+ */
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_PARCEL_READ[] =
+R"__c_cb(
+ret = <PREFIX>_<NAME>_create(&value);
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ set_last_result(ret);
+ return;
+}
+
+rpc_port_parcel_read(parcel, &value->parcelable, value);
+if (get_last_result() != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", get_last_result());
+ <PREFIX>_<NAME>_destroy(value);
+ return;
+}
+
+h->list = g_list_append(h->list, value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_bundle(parcel, &value);
+if (value == nullptr) {
+ _E("Failed to read data");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+h->list = g_list_append(h->list, value);
+value = nullptr;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_string(parcel, &value);
+if (value == nullptr) {
+ _E("Failed to read data");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+h->list = g_list_append(h->list, value);
+value = nullptr;
+)__c_cb";
+
+/**
+ * <VALUE_TYPE> The type of the value.
+ * <PARCEL_TYPE> The type of the parcel of the value.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE_PARCEL_READ[] =
+R"__c_cb(
+value = calloc(1, sizeof(sizeof(<VALUE_TYPE>)));
+if (value == nullptr) {
+ _E("Out of memory");
+ set_last_result(RPC_PORT_ERROR_OUT_OF_MEMORY);
+ return;
+}
+
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, value);
+
+h->list = g_list_append(h->list, value);
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user-defined type.
+ * <NAME> The name of the user-defined type.
+ */
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_ADD[] =
+R"__c_cb(
+<PREFIX>_<NAME>_h new_value;
+int ret;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+ret = <PREFIX>_<NAME>_clone(value, &new_value);
+if (ret != RPC_PORT_ERROR_NONE)
+ return ret;
+
+h->list = g_list_append(h->list, new_value);
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_ADD[] =
+R"__c_cb(
+bundle *new_value;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = bundle_dup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+h->list = g_list_append(h->list, new_value);
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_ADD[] =
+R"__c_cb(
+char *new_value;
+
+if (h == nullptr || value == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = strdup(value);
+if (new_value == nullptr) {
+ _E("Failed to duplicate value");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+h->list = g_list_append(h->list, new_value);
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <VALUE_TYPE> The type of the value.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE_ADD[] =
+R"__c_cb(
+<VALUE_TYPE>*new_value;
+
+if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+}
+
+new_value = calloc(1, sizeof(<VALUE_TYPE>));
+if (new_value == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+}
+
+*new_value = value;
+
+h->list = g_list_append(h->list, new_value);
+
+return RPC_PORT_ERROR_NONE;
+)__c_cb";
+
+/**
+ * <PREFIX> The prefix of the user-defined type.
+ * <NAME> The name of the user-defined type.
+ */
+constexpr const char CB_STRUCTURE_LIST_USER_DEFINED_FREE[] =
+R"__c_cb(
+<PREFIX>_<NAME>_destroy(value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BUNDLE_FREE[] =
+R"__c_cb(
+bundle_free(value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_STRING_FREE[] =
+R"__c_cb(
+free(value);
+)__c_cb";
+
+constexpr const char CB_STRUCTURE_LIST_BASE_FREE[] =
+R"__c_cb(
+free(value);
+)__c_cb";
+
+#endif // IDLC_C_GEN_C_BODY_GEN_LIST_BASE_CB_H_
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
namespace {
#include "idlc/gen/c_gen_base_cb.h"
-}
+
+constexpr const char PREFIX_RPC_PORT_PROXY[] = "rpc_port_proxy";
+constexpr const char PREFIX_RPC_PORT_STUB[] = "rpc_port_stub";
+
+} // namespace
namespace tidl {
: Generator(doc) {
structures_.clear();
type_map_ = {
- {"char", "char "}, {"int", "int "}, {"short", "short "},
- {"long", "long long "}, {"bool", "bool "}, {"string", "char *"},
- {"list", "GList *"}, {"float", "float "}, {"double", "double "},
- {"bundle", "bundle *"}, {"void", "void "}, {"file", "char *"}
+ {"char", "char "},
+ {"int", "int "},
+ {"short", "short "},
+ {"long", "long long "},
+ {"bool", "bool "},
+ {"string", "char *"},
+ {"list", "GList *"},
+ {"float", "float "},
+ {"double", "double "},
+ {"bundle", "bundle *"},
+ {"void", "void "},
+ {"file", "char *"}
};
}
std::string CGeneratorBase::Tab(int cnt) {
std::string str;
-
- for (int i = 0; i < cnt; ++i) {
+ for (int i = 0; i < cnt; ++i)
str += "\t";
- }
return str;
}
std::string CGeneratorBase::NLine(int cnt) {
std::string str;
-
- for (int i = 0; i < cnt; ++i) {
+ for (int i = 0; i < cnt; ++i)
str += "\n";
- }
return str;
}
-std::string CGeneratorBase::ConvertTypeToString(
- ParameterType::Direction direction, const BaseType& type, bool bconst) {
- if (type.IsUserDefinedType()) {
- if (direction == ParameterType::Direction::IN)
- return GetHandlePrefix() + type.ToString() + "_h ";
- else
- return GetHandlePrefix() + type.ToString() + "_h *";
- }
-
- if (type.ToString() == "array") {
- if (direction == ParameterType::Direction::IN) {
- return GetReturnTypeString(*type.GetMetaType()) + "*";
- } else {
- return GetReturnTypeString(*type.GetMetaType()) + "**";
- }
- }
+std::string CGeneratorBase::GetFullNameFromType(const BaseType& type) {
+ std::string str = type.ToString();
- if (type.ToString() == "string" || type.ToString() == "file") {
- if (direction == ParameterType::Direction::IN) {
- if (!bconst)
- return "char *";
- return "const char *";
- } else
- return "char **";
+ if (type.GetMetaType() != nullptr) {
+ str += "_";
+ str += GetFullNameFromType(*type.GetMetaType());
}
- if (direction == ParameterType::Direction::IN && bconst)
- return type_map_[type.ToString()];
-
- return type_map_[type.ToString()] + "*";
+ return str;
}
-std::string CGeneratorBase::GetFullNameFromType(const BaseType& type) {
- std::string str = type.ToString();
+std::string CGeneratorBase::GetFullNameFromType(const BaseType& type,
+ const Interface& inf) {
+ std::string str;
+ if (IsDelegateType(inf, type))
+ str += inf.GetID() + "_";
+
+ str += type.ToString();
if (type.GetMetaType() != nullptr) {
str += "_";
- str += GetFullNameFromType(*type.GetMetaType());
+ str += GetFullNameFromType(*type.GetMetaType(), inf);
}
return str;
}
-std::string CGeneratorBase::GetParcelParamTypeString(const BaseType& type,
+std::string CGeneratorBase::GetDataTypeString(const BaseType& type,
bool is_pointer) {
if (type.IsUserDefinedType())
- return GetHandlePrefix() + type.ToString() + "_h ";
+ return GetHandlePrefix() + "_" + type.ToString() + "_h ";
if (type.ToString() == "list" ||
type.ToString() == "array")
- return GetHandlePrefix() + GetFullNameFromType(type) + "_h ";
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type) + "_h ";
if (type.ToString() == "string" || type.ToString() == "file")
return "char *";
std::string CGeneratorBase::GetReturnTypeString(const BaseType& type) {
if (type.IsUserDefinedType())
- return GetHandlePrefix() + type.ToString() + "_h ";
+ return GetHandlePrefix() + "_" + type.ToString() + "_h ";
if (type.ToString() == "list" ||
type.ToString() == "array")
- return GetHandlePrefix() + GetFullNameFromType(type) + "_h ";
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type) + "_h ";
return type_map_[type.ToString()];
}
if (type.GetMetaType() == nullptr)
return;
- BaseType* t = new BaseType(type);
+ BaseType* t = new BaseType(*type.GetMetaType());
assert(t != nullptr);
std::string type_name = GetFullNameFromType(type);
- Element* elm = new Element(type_name + "s", t, "", __LINE__);
+ Element* elm = new Element(type_name, t, "", __LINE__);
assert(elm != nullptr);
Elements* elms = new Elements();
assert(elms != nullptr);
elms->Add(elm);
- Structure* st = new Structure(type_name, elms, "", __LINE__);
+ auto* st = new Structure(type_name, elms, "", __LINE__);
assert(st != nullptr);
- if (StructureExist(*st)) {
+ AddStructureFromType(*type.GetMetaType());
+
+ if (StructureExist(st)) {
delete st;
- } else {
- structures_[type_name] = std::unique_ptr<Structure>(st);
+ return;
}
- AddStructureFromType(*type.GetMetaType());
+ structures_[type_name] = std::unique_ptr<Structure>(st);
+}
+
+void CGeneratorBase::AddStructureFromType(const BaseType& type,
+ const Interface& inf) {
+ if (type.GetMetaType() == nullptr)
+ return;
+
+ BaseType* t = nullptr;
+ if (IsDelegateType(inf, *type.GetMetaType()))
+ t = new BaseType(GetFullNameFromType(*type.GetMetaType(), inf), "", true);
+ else
+ t = new BaseType(*type.GetMetaType());
+
+ assert(t != nullptr);
+
+ std::string type_name = GetFullNameFromType(type, inf);
+ Element* elm = new Element(type_name, t, "", __LINE__);
+ assert(elm != nullptr);
+
+ Elements* elms = new Elements();
+ assert(elms != nullptr);
+ elms->Add(elm);
+
+ auto* st = new Structure(type_name, elms, "", __LINE__);
+ assert(st != nullptr);
+
+ AddStructureFromType(*type.GetMetaType(), inf);
+
+ if (StructureExist(st)) {
+ delete st;
+ return;
+ }
+
+ structures_[type_name] = std::unique_ptr<Structure>(st);
+}
+
+std::string CGeneratorBase::RemoveLine(std::string lines,
+ unsigned int line_num) {
+ std::stringstream ss(lines);
+ std::string result;
+ std::string line;
+ unsigned int line_count = 0;
+
+ while (std::getline(ss, line, '\n')) {
+ line_count++;
+ if (line_num == line_count)
+ continue;
+
+ result += Trim(line);
+ result += NLine(1);
+ }
+
+ return result;
}
std::string CGeneratorBase::SmartIndent(std::string lines) {
int line_count = 0;
while (std::getline(ss, next_line, '\n')) {
+ next_line = RemoveSpaces(next_line);
line_count++;
if (line_count == 1) {
line = Trim(next_line);
tab_size--;
}
- if (line.length() > 0) {
+ back = line.back();
+ if (back != ":" && line.length() > 0)
tab += Tab(tab_size);
- }
if (continuous && tab_size == 0 &&
found == std::string::npos) {
}
continuous = false;
- back = line.back();
- if (back == ",")
+ if (back == "," || back == "\\")
continuous = true;
if (line.empty() ||
result += NLine(1);
}
} else {
- result += tab + line;
+ // for annotation && ifdef
+ if (line.compare(0, 2, " *") == 0 || line.compare(0, 1, "#") == 0)
+ result += line;
+ else
+ result += tab + line;
+
result += NLine(1);
}
tab_size++;
if_statement = true;
}
+
+ found = line.find("else");
+ if (found != std::string::npos && line != "#else") {
+ tab_size++;
+ if_statement = true;
+ }
+
+ found = line.find("for (");
+ if (found != std::string::npos) {
+ tab_size++;
+ if_statement = true;
+ }
+
+ back = line.back();
+ found = line.find("while (");
+ if (found != std::string::npos && back != ";") {
+ tab_size++;
+ if_statement = true;
+ }
}
line = Trim(next_line);
return result;
}
+std::string CGeneratorBase::RemoveLastSpaces(const std::string& str) {
+ std::size_t found = str.find_last_not_of(' ');
+ if (found == std::string::npos)
+ return str;
+
+ return str.substr(0, found + 1);
+}
+
+std::string CGeneratorBase::RemoveSpaces(const std::string& str) {
+ // for annotation
+ if (str.compare(0, 3, "/**") == 0 ||
+ str.compare(0, 2, " *") == 0 ||
+ str.compare(0, 3, " */") == 0)
+ return str;
+
+ std::size_t found = str.find_first_not_of(' ');
+ if (found == std::string::npos)
+ return "";
+
+ return str.substr(found, str.size() - found);
+}
+
std::string CGeneratorBase::Trim(const std::string& str) {
+ // for annotation
+ if (str.compare(0, 3, "/**") == 0 ||
+ str.compare(0, 2, " *") == 0 ||
+ str.compare(0, 3, " */") == 0)
+ return str;
+
std::size_t first = str.find_first_not_of(" \t\r\n");
if (first == std::string::npos)
return str;
}
void CGeneratorBase::GenVersion(std::ofstream& stream) {
- GenTemplate(CB_VERSION, stream,
- [&]()->std::string {
- return FULLVER;
- });
+ stream << ReplaceAll(CB_VERSION, "<VERSION>", FULLVER);
}
void CGeneratorBase::GenIncludeDefaultHeaders(std::ofstream& stream,
}
void CGeneratorBase::GenGNUSourceDefinition(std::ofstream& stream) {
- stream << NLine(1);
- stream << CB_GNU_SOURCE;
+ stream << SmartIndent(CB_GNU_SOURCE);
}
-bool CGeneratorBase::StructureExist(const Structure& st) {
+bool CGeneratorBase::StructureExist(const Structure* st) {
for (auto& i : GetDocument().GetBlocks()) {
if (i->GetType() != Block::TYPE_STRUCTURE)
continue;
const Structure &s = static_cast<const Structure&>(*i);
- if (s.GetID() == st.GetID())
+ if (s.GetID() == st->GetID())
return true;
}
+
return false;
}
type.ToString() == "list" ||
type.ToString() == "array") {
if (direction == ParameterType::Direction::IN)
- return GetHandlePrefix() + GetFullNameFromType(type) + "_h ";
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type) + "_h ";
else
- return GetHandlePrefix() + GetFullNameFromType(type) + "_h *";
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type) + "_h *";
}
- if (type.ToString() == "string") {
+ if (type.ToString() == "string" || type.ToString() == "file") {
if (direction == ParameterType::Direction::IN)
return "const char *";
else
return type_map_[type.ToString()] + "*";
}
+std::string CGeneratorBase::GetParamTypeString(
+ ParameterType::Direction direction, const BaseType& type,
+ const Interface& inf) {
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ if (direction == ParameterType::Direction::IN)
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type, inf) + "_h ";
+ else
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type, inf) + "_h *";
+ }
+
+ if (type.ToString() == "string" || type.ToString() == "file") {
+ if (direction == ParameterType::Direction::IN)
+ return "const char *";
+ else
+ return "char **";
+ }
+
+ if (direction == ParameterType::Direction::IN)
+ return type_map_[type.ToString()];
+
+ return type_map_[type.ToString()] + "*";
+}
+
+std::string CGeneratorBase::GetArgTypeString(const BaseType& type,
+ const Interface& inf) {
+ if (type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array")
+ return GetHandlePrefix() + "_" + GetFullNameFromType(type, inf) + "_h ";
+
+ return type_map_[type.ToString()];
+}
+
std::string CGeneratorBase::GetErrorValue(const BaseType& type) {
if (type.IsUserDefinedType() ||
type.ToString() == "list" ||
type.ToString() == "bundle" ||
type.ToString() == "string"||
type.ToString() == "file")
- return "NULL";
+ return "nullptr";
if (type.ToString() == "bool")
return "false";
if (type.ToString() == "char")
return "-1";
}
-std::string CGeneratorBase::GetStringFromElementType(const BaseType& type) {
- if (type.IsUserDefinedType())
- return GetHandlePrefix() + type.ToString() + "_h ";
- if (type.ToString() == "array")
- return GetReturnTypeString(*type.GetMetaType()) + "*";
-
- return type_map_[type.ToString()];
-}
-
-std::string CGeneratorBase::GetStructIdWithNamespace(const Structure& st) {
+std::string CGeneratorBase::GetHandlePrefix() {
+ std::string prefix =
+ IsProxy() ? PREFIX_RPC_PORT_PROXY : PREFIX_RPC_PORT_STUB;
if (!HasNamespace())
- return st.GetID();
- return GetFileNamespace() + "_" + st.GetID();
-}
+ return prefix;
-std::string CGeneratorBase::GetInterfaceIdWithNamespace(const Interface& inf) {
- if (!HasNamespace())
- return inf.GetID();
- return GetFileNamespace() + "_" + inf.GetID();
+ return prefix + "_" + GetFileNamespace() + "_";
}
-std::string CGeneratorBase::GetHandlePrefix() {
- if (!HasNamespace())
- return "rpc_port_";
- return "rpc_port_" + GetFileNamespace() + "_";
+const std::map<std::string, std::unique_ptr<Structure>>&
+CGeneratorBase::GetStructures() {
+ return structures_;
}
} // namespace tidl
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
#ifndef IDLC_C_GEN_C_GEN_BASE_H_
#define IDLC_C_GEN_C_GEN_BASE_H_
+#include <map>
#include <memory>
#include <string>
-#include <map>
#include "idlc/ast/type.h"
#include "idlc/ast/structure.h"
explicit CGeneratorBase(std::shared_ptr<Document> doc);
virtual ~CGeneratorBase() = default;
- std::string Trim(const std::string& str);
+ std::string RemoveLine(std::string lines, unsigned int line_num = 1);
std::string SmartIndent(std::string lines);
- std::string Tab(int cnt);
std::string NLine(int cnt);
- std::string ConvertTypeToString(ParameterType::Direction direction,
- const BaseType& type, bool bconst = true);
+
std::string GetFullNameFromType(const BaseType& type);
- std::string GetParcelParamTypeString(const BaseType& type,
- bool is_pointer = true);
+ std::string GetFullNameFromType(const BaseType& type, const Interface& inf);
+
+ std::string GetDataTypeString(const BaseType& type, bool is_pointer = true);
std::string GetReturnTypeString(const BaseType& type);
std::string GetParamTypeString(ParameterType::Direction direction,
- const BaseType& type);
- std::string GetStringFromElementType(const BaseType& type);
+ const BaseType& type);
+ std::string GetParamTypeString(ParameterType::Direction direction,
+ const BaseType& type, const Interface& inf);
+ std::string GetArgTypeString(const BaseType& type, const Interface& inf);
std::string GetErrorValue(const BaseType& type);
+
void AddStructureFromType(const BaseType& type);
- const std::map<std::string, std::unique_ptr<Structure>>& GetStructures(void) {
- return structures_;
- }
+ void AddStructureFromType(const BaseType& type, const Interface& inf);
+
+ const std::map<std::string, std::unique_ptr<Structure>>& GetStructures();
void GenVersion(std::ofstream& stream);
void GenIncludeDefaultHeaders(std::ofstream& stream, bool body = true);
void GenGNUSourceDefinition(std::ofstream& stream);
- std::string GetStructIdWithNamespace(const Structure& st);
- std::string GetInterfaceIdWithNamespace(const Interface& inf);
std::string GetHandlePrefix();
+ std::string RemoveLastSpaces(const std::string& str);
private:
- bool StructureExist(const Structure& st);
+ std::string Tab(int cnt);
+ std::string Trim(const std::string& str);
+ std::string RemoveSpaces(const std::string& str);
+ bool StructureExist(const Structure* st);
private:
std::map<std::string, std::unique_ptr<Structure>> structures_;
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
#ifndef IDLC_C_GEN_C_GEN_BASE_CB_H_
#define IDLC_C_GEN_C_GEN_BASE_CB_H_
-const char CB_VERSION[] =
+/**
+ * <VERSION> Version of TIDL Compiler.
+ */
+constexpr const char CB_VERSION[] =
R"__c_cb(/*
- * Generated by tidlc $$.
+ * Generated by tidlc <VERSION>.
*/
)__c_cb";
-const char CB_GNU_SOURCE[] =
+constexpr const char CB_GNU_SOURCE[] =
R"__c_cb(
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
)__c_cb";
-const char CB_HEADER[] =
+constexpr const char CB_HEADER[] =
R"__c_cb(
#include <stdbool.h>
#include <bundle.h>
+#include <rpc-port.h>
)__c_cb";
-const char CB_BODY_HEADER[] =
+constexpr const char CB_BODY_HEADER[] =
R"__c_cb(
#include <pthread.h>
#include <stdio.h>
/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 - 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.
* limitations under the License.
*/
+#include <string.h>
+
#include <vector>
#include "idlc/gen/c_header_gen_base.h"
namespace tidl {
CHeaderGeneratorBase::CHeaderGeneratorBase(std::shared_ptr<Document> doc)
- : CGeneratorBase(doc) {}
+ : CGeneratorBase(doc) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ for (auto& e : st.GetElements().GetElms()) {
+ auto& type = e->GetType();
+ AddStructureFromType(type);
+ }
+ } else {
+ auto& inf = static_cast<const Interface&>(*b);
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ for (auto& p : d->GetParameters().GetParams()) {
+ auto& type = p->GetParameterType().GetBaseType();
+ if (IsDelegateType(inf, type))
+ continue;
+
+ AddStructureFromType(type, inf);
+ }
+ }
+ }
+ }
+}
void CHeaderGeneratorBase::GenPragmaOnce(std::ofstream& stream) {
const char format[] = "#pragma once\n";
stream << CB_EXPLICIT_LINKAGE_CLOSE;
}
-void CHeaderGeneratorBase::GenStructures(std::ofstream& stream) {
- for (auto& i : GetDocument().GetBlocks()) {
- if (i->GetType() == Block::TYPE_STRUCTURE) {
- const Structure &st = static_cast<const Structure&>(*i);
- GenStructure(stream, st);
- for (auto& j : st.GetElements().GetElms()) {
- auto& t = j->GetType();
- AddStructureFromType(t);
- }
- } else {
- const Interface &inf = static_cast<const Interface&>(*i);
- for (auto& d : inf.GetDeclarations().GetDecls()) {
- for (auto& p : d->GetParameters().GetParams()) {
- if (IsDelegateType(inf, p->GetParameterType().GetBaseType()))
- continue;
- AddStructureFromType(p->GetParameterType().GetBaseType());
- }
- }
+void CHeaderGeneratorBase::GenStructureHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructureHandle(stream, st);
}
}
- for (auto& p : GetStructures()) {
- const Structure& st = *p.second;
- GenStructure(stream, st);
+ for (auto& i : GetStructures()) {
+ auto& st = i.second;
+ GenStructureHandle(stream, *st);
}
}
-void CHeaderGeneratorBase::GenStructure(std::ofstream& stream,
- const Structure& st) {
- GenStructureDeclaration(stream, st);
- GenStructureConstructor(stream, st);
- GenStructureDestructor(stream, st);
- GenStructureCloner(stream, st);
- GenStructureSetter(stream, st);
- GenStructureGetter(stream, st);
- GenStructureIterator(stream, st);
- GenStructureRemover(stream, st);
- GenStructureLengthGetter(stream, st);
-}
-
-void CHeaderGeneratorBase::GenStructureDeclaration(std::ofstream& stream,
- const Structure& st) {
- GenTemplate(CB_STRUCT_DECL, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- });
-}
-
-void CHeaderGeneratorBase::GenStructureConstructor(std::ofstream& stream,
- const Structure& st) {
- GenTemplate(CB_STRUCT_CTOR, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- });
-}
-
-void CHeaderGeneratorBase::GenStructureDestructor(std::ofstream& stream,
- const Structure& st) {
- GenTemplate(CB_STRUCT_DTOR, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- });
-}
-
-void CHeaderGeneratorBase::GenStructureSetter(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- GenTemplate(CB_STRUCT_SETTER, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "list")
- return "add";
- return "set";
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().IsUserDefinedType())
- return GetParcelParamTypeString(i->GetType());
-
- if (i->GetType().ToString() == "list") {
- if (i->GetType().GetMetaType()->IsUserDefinedType() ||
- i->GetType().GetMetaType()->ToString() == "list" ||
- i->GetType().GetMetaType()->ToString() == "array") {
- return GetParcelParamTypeString(*i->GetType().GetMetaType());
- } else {
- return ConvertTypeToString(ParameterType::Direction::IN,
- *i->GetType().GetMetaType());
- }
- }
-
- if (i->GetType().ToString() == "array") {
- return GetStringFromElementType(i->GetType());
- }
-
- return ConvertTypeToString(ParameterType::Direction::IN,
- i->GetType());
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "array") {
- std::string str;
- str += i->GetID();
- str += ", ";
- str += "int " + i->GetID() + "_size";
- return str;
- }
- return i->GetID();
- });
+void CHeaderGeneratorBase::GenStructures(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ GenStructure(stream, st);
+ }
}
-}
-void CHeaderGeneratorBase::GenStructureGetter(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() == "list")
- continue;
-
- GenTemplate(CB_STRUCT_GETTER, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "array")
- return GetStringFromElementType(i->GetType()) + "*";
-
- return ConvertTypeToString(ParameterType::Direction::OUT,
- i->GetType());
- },
- [&]()->std::string {
- if (i->GetType().ToString() == "array") {
- std::string str;
- str += i->GetID();
- str += ", ";
- str += "int *" + i->GetID() + "_size";
- return str;
- }
- return i->GetID();
- });
+ for (auto& i : GetStructures()) {
+ auto& st = i.second;
+ GenStructure(stream, *st);
}
}
-void CHeaderGeneratorBase::GenStructureIterator(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() != "list")
- continue;
+// @see #CB_STRUCTURE_HANDLE
+void CHeaderGeneratorBase::GenStructureHandle(std::ofstream& stream,
+ const Structure& st) {
+ std::string str = ReplaceAll(CB_STRUCTURE_HANDLE, "<PREFIX>",
+ GetHandlePrefix());
+ str = ReplaceAll(str, "<NAME>", st.GetID());
+ stream << SmartIndent(str);
+}
- GenTemplate(CB_STRUCT_ITERATOR, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- if (i->GetType().GetMetaType()->IsUserDefinedType() ||
- i->GetType().GetMetaType()->ToString() == "list" ||
- i->GetType().GetMetaType()->ToString() == "array")
- return GetParcelParamTypeString(*i->GetType().GetMetaType());
+// @see #CB_STRUCTURE_ARRAY_BASE
+void CHeaderGeneratorBase::GenStructureArrayBase(std::ofstream& stream,
+ const Structure& st) {
+ std::string str = ReplaceAll(CB_STRUCTURE_ARRAY_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ str = ReplaceAll(str, "<NAME>", st.GetID());
- return ConvertTypeToString(ParameterType::Direction::IN,
- *i->GetType().GetMetaType());
- },
- [&]()->std::string {
- return i->GetID();
- });
- }
-}
+ auto& elm = st.GetElements().GetElms().front();
+ auto& type = elm->GetType();
+ auto param_type = GetParamTypeString(ParameterType::Direction::IN, type);
+ str = ReplaceAll(str, "<PARAM_TYPE_IN>", param_type);
-void CHeaderGeneratorBase::GenStructureRemover(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() != "list")
- continue;
+ param_type = GetParamTypeString(ParameterType::Direction::OUT, type);
+ str = ReplaceAll(str, "<PARAM_TYPE_OUT>", param_type);
- GenTemplate(CB_STRUCT_REMOVER, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- });
- }
+ stream << SmartIndent(str);
}
-void CHeaderGeneratorBase::GenStructureLengthGetter(std::ofstream& stream,
- const Structure& st) {
- for (auto& i : st.GetElements().GetElms()) {
- if (i->GetType().ToString() != "list")
- continue;
+// @see #CB_STRUCTURE_LIST_BASE
+void CHeaderGeneratorBase::GenStructureListBase(std::ofstream& stream,
+ const Structure& st) {
+ std::string str = ReplaceAll(CB_STRUCTURE_LIST_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ str = ReplaceAll(str, "<NAME>", st.GetID());
+
+ auto& elm = st.GetElements().GetElms().front();
+ auto& type = elm->GetType();
+ auto param_type = GetParamTypeString(ParameterType::Direction::IN, type);
+ str = ReplaceAll(str, "<PARAM_TYPE_IN>", param_type);
+ stream << SmartIndent(str);
+}
- GenTemplate(CB_STRUCT_LENGTH_GETTER, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- });
+// @see #CB_STRUCTURE_BASE
+void CHeaderGeneratorBase::GenStructureBase(std::ofstream& stream,
+ const Structure& st) {
+ std::string str = ReplaceAll(CB_STRUCTURE_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ str = ReplaceAll(str, "<NAME>", st.GetID());
+ stream << SmartIndent(str);
+
+ for (auto& e : st.GetElements().GetElms()) {
+ str = ReplaceAll(CB_STRUCTURE_BASE_SET_GET, "<PREFIX>", GetHandlePrefix());
+ str = ReplaceAll(str, "<NAME>", st.GetID());
+
+ auto& type = e->GetType();
+ auto param_type = GetParamTypeString(ParameterType::Direction::IN, type);
+ str = ReplaceAll(str, "<PARAM_TYPE_IN>", param_type);
+
+ param_type = GetParamTypeString(ParameterType::Direction::OUT, type);
+ str = ReplaceAll(str, "<PARAM_TYPE_OUT>", param_type);
+ str = ReplaceAll(str, "<ELEMENT_NAME>", e->GetID());
+ stream << SmartIndent(str);
}
}
-void CHeaderGeneratorBase::GenStructureCloner(std::ofstream& stream,
- const Structure& st) {
- GenTemplate(CB_STRUCT_CLONER, stream,
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- },
- [&]()->std::string {
- return GetStructIdWithNamespace(st);
- });
+void CHeaderGeneratorBase::GenStructure(std::ofstream& stream,
+ const Structure& st) {
+ if (st.GetID().compare(0, strlen("array"), "array") == 0)
+ GenStructureArrayBase(stream, st);
+ else if (st.GetID().compare(0, strlen("list"), "list") == 0)
+ GenStructureListBase(stream, st);
+ else
+ GenStructureBase(stream, st);
}
} // namespace tidl
/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 - 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.
void GenPragmaOnce(std::ofstream& stream);
void GenExplicitLinkageOpen(std::ofstream& stream);
void GenExplicitLinkageClose(std::ofstream& stream);
+ void GenStructureHandles(std::ofstream& stream);
void GenStructures(std::ofstream& stream);
private:
+ void GenStructureHandle(std::ofstream& stream, const Structure& st);
+ void GenStructureArrayBase(std::ofstream& stream, const Structure& st);
+ void GenStructureListBase(std::ofstream& stream, const Structure& st);
+ void GenStructureBase(std::ofstream& stream, const Structure& st);
void GenStructure(std::ofstream& stream, const Structure& st);
- void GenStructureDeclaration(std::ofstream& stream, const Structure& st);
- void GenStructureParcelTo(std::ofstream& stream, const Structure& st);
- void GenStructureParcelFrom(std::ofstream& stream, const Structure& st);
- void GenStructureConstructor(std::ofstream& stream, const Structure& st);
- void GenStructureDestructor(std::ofstream& stream, const Structure& st);
- void GenStructureSetter(std::ofstream& stream, const Structure& st);
- void GenStructureGetter(std::ofstream& stream, const Structure& st);
- void GenStructureIterator(std::ofstream& stream, const Structure& st);
- void GenStructureRemover(std::ofstream& stream, const Structure& st);
- void GenStructureLengthGetter(std::ofstream& stream, const Structure& st);
- void GenStructureCloner(std::ofstream& stream, const Structure& st);
};
} // namespace tidl
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
#ifndef IDLC_C_GEN_C_HEADER_GEN_BASE_CB_H_
#define IDLC_C_GEN_C_HEADER_GEN_BASE_CB_H_
-const char CB_EXPLICIT_LINKAGE_OPEN[] =
+constexpr const char CB_EXPLICIT_LINKAGE_OPEN[] =
R"__c_cb(
#ifdef __cplusplus
extern "C" {
#endif
)__c_cb";
-const char CB_EXPLICIT_LINKAGE_CLOSE[] =
+constexpr const char CB_EXPLICIT_LINKAGE_CLOSE[] =
R"__c_cb(
#ifdef __cplusplus
}
#endif
)__c_cb";
-const char CB_STRUCT_DECL[] =
-R"__c_cb(
-typedef struct $$_s *rpc_port_$$_h;
-)__c_cb";
-const char CB_STRUCT_CTOR[] =
+/**
+ * <PREFIX> The prefix of the handle.
+ * <NAME> The name of the handle.
+ */
+constexpr const char CB_STRUCTURE_HANDLE[] =
R"__c_cb(
-int rpc_port_$$_create(rpc_port_$$_h *h);
+/**
+ * @brief The <PREFIX>_<NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_s *<PREFIX>_<NAME>_h;
)__c_cb";
-const char CB_STRUCT_DTOR[] =
+/**
+ * <PREFIX> The prefix of the array structure.
+ * <NAME> The name of the array structure.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ */
+constexpr const char CB_STRUCTURE_ARRAY_BASE[] =
R"__c_cb(
-int rpc_port_$$_destroy(rpc_port_$$_h h);
-)__c_cb";
+/**
+ * @briefs Creates a <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a h should be released using the <PREFIX>_<NAME>_destroy()
+ * if it's no longer needed.
+ * @param[out] h The <PREFIX>_<NAME> handle that is newly created
+ * @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
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h);
-const char CB_STRUCT_SETTER[] =
-R"__c_cb(
-int rpc_port_$$_$$_$$(rpc_port_$$_h h, $$$$);
-)__c_cb";
+/**
+ * @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);
-const char CB_STRUCT_GETTER[] =
-R"__c_cb(
-int rpc_port_$$_get_$$(rpc_port_$$_h h, $$$$);
-)__c_cb";
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME> should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME> handle will be returned
+ * @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
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone);
-const char CB_STRUCT_ITERATOR[] =
-R"__c_cb(
-int rpc_port_$$_foreach_$$(rpc_port_$$_h h,
- bool (*callback)($$$$, void *user_data), void *user_data);
+/**
+ * @brief Sets the value to the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The value is internally copied and stored.
+ * You should release it if it's allocaed when it's no longer needed,
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] value The array value
+ * @param[in] size The size of the array
+ * @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
+ * @see <PREFIX>_<NAME>_get()
+ */
+int <PREFIX>_<NAME>_set(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>*value, int size);
+
+/**
+ * @brief Gets the value from the <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created value should be released if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] value The array value
+ * @param[out] size The size of the array
+ * @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
+ * @see <PREFIX>_<NAME>_set()
+ */
+int <PREFIX>_<NAME>_get(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>*value, int *size);
)__c_cb";
-const char CB_STRUCT_REMOVER[] =
+/**
+ * <PREFIX> The prefix of the list structure.
+ * <NAME> The name of the list structure.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ */
+constexpr const char CB_STRUCTURE_LIST_BASE[] =
R"__c_cb(
-int rpc_port_$$_remove_$$(rpc_port_$$_h h, unsigned int nth);
+/**
+ * @brief Called to retrieve the value contained in the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The @a value MUST NOT be released by the application.
+ * @param[in] value The value of the list
+ * @param[in] user_data The user data passed from the foreach function
+ * @return @c true to continue with the next iteration of the loop,
+ * otherwise @c false to break out of the loop
+ * @see <PREFIX>_<NAME>_foreach()
+ */
+typedef bool (*<PREFIX>_<NAME>_cb)(<PARAM_TYPE_IN>value, void *user_data);
+
+/**
+ * @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[out] h The <PREFIX>_<NAME> handle that is newly created
+ * @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
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_create(<PREFIX>_<NAME>_h *h);
+
+/**
+ * @brief Destroys the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] 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);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME> should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME> handle will be returned
+ * @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
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone);
+
+/**
+ * @brief Adds the value to the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The value is internally copied and stored.
+ * You should release it if it's allocaed when it's no longer needed,
+ * @param[in] h The <PREFIX>_<NAME> handle.
+ * @param[in] value The value
+ * @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
+ * @see <PREFIX>_<NAME>_remove()
+ */
+int <PREFIX>_<NAME>_add(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value);
+
+/**
+ * @brief Retrieves all values contained in the <PREFIX>_<NAME> handle.
+ * @details This function called <PREFIX>_<NAME>_cb once for each value contained in the <PREFIX>_<NAME> handle.
+ * If the <PREFIX>_<NAME>_cb callback function returns @c false, the iteration will be finished.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] callback The iteration callback function
+ * @param[in] user_data The user data to be passed to the callback function
+ * @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>_cb()
+ */
+int <PREFIX>_<NAME>_foreach(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_cb callback, void *user_data);
+
+/**
+ * @brief Removes the element at the given position in the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] nth The position of the element
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_remove(<PREFIX>_<NAME>_h h, unsigned int nth);
+
+/**
+ * @brief Gets the number of elements in the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] length The number of elements
+ * @return @c on 0 success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_length(<PREFIX>_<NAME>_h h, unsigned int *length);
)__c_cb";
-const char CB_STRUCT_LENGTH_GETTER[] =
+/**
+ * <PREFIX> The prefix of the structure. e.g. rpc_port_proxy_ or rpc_port_stub_
+ * <NAME> The name of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE[] =
R"__c_cb(
-int rpc_port_$$_get_$$_length(rpc_port_$$_h h, unsigned int *length);
+/**
+ * @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[out] h The <PREFIX>_<NAME> handle that is newly created
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMTER Invaid parameter
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_create(<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
+ * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory
+ * @see <PREFIX>_<NAME>_create()
+ */
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME> should be released using
+ * the <PREFIX>_<NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME> handle will be returned
+ * @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
+ * @see <PREFIX>_<NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_clone(<PREFIX>_<NAME>_h h, <PREFIX>_<NAME>_h *clone);
)__c_cb";
-const char CB_STRUCT_CLONER[] =
+/**
+ * <PREFIX> The prefix of the structure. e.g. rpc_port_proxy_ or rpc_port_stub_
+ * <NAME> The name of the structure.
+ * <PARAM_TYPE_IN> The type of the input parameter.
+ * <PARAM_TYPE_OUT> The type of the output parameter.
+ * <ELEMENT_NAME> The name of the element of the structure.
+ */
+constexpr const char CB_STRUCTURE_BASE_SET_GET[] =
R"__c_cb(
-int rpc_port_$$_clone(rpc_port_$$_h h, rpc_port_$$_h *clone);
+/**
+ * @brief Sets the <ELEMENT_NAME> to the <PREFIX>_<NAME> handle.
+ *
+ * @remarks The <ELEMENT_NAME> is internally copied and stored.
+ * You should release it if it's allocated when it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] value The <ELEMENT_NAME>
+ * @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
+ * @see <PREFIX>_<NAME>_get_<ELEMENT_NAME>()
+ */
+int <PREFIX>_<NAME>_set_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_IN>value);
+
+/**
+ * @brief Gets the <ELEMENT_NAME> from the <PREFIX>_<NAME> handle.
+ *
+ * @remarks A new created value should be released if it's allocated when it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[out] value The <ELEMENT_NAME>
+ * @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
+ * @see <PREFIX>_<NAME>_set_<ELEMENT_NAME>
+ */
+int <PREFIX>_<NAME>_get_<ELEMENT_NAME>(<PREFIX>_<NAME>_h h, <PARAM_TYPE_OUT>value);
)__c_cb";
#endif // IDLC_C_GEN_C_HEADER_GEN_BASE_CB_H_
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
* limitations under the License.
*/
-#include "idlc/gen/c_proxy_body_gen.h"
+#include <algorithm>
-namespace {
+#include "idlc/gen/c_proxy_body_gen.h"
#include "idlc/gen/c_proxy_body_gen_cb.h"
-}
namespace tidl {
-CProxyBodyGen::CProxyBodyGen(std::shared_ptr<Document> doc)
- : CBodyGeneratorBase(doc) {}
+CProxyBodyGen::CProxyBodyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options)
+ : CBodyGeneratorBase(doc), options_(std::move(options)) {
+}
void CProxyBodyGen::OnInitGen(std::ofstream& stream) {
GenVersion(stream);
GenIncludeHeader(stream);
GenLogTag(stream, std::string("RPC_PORT_PROXY"));
GenLogDefinition(stream);
- GenTypedefProxyDelegate(stream);
+ GenBaseDefinition(stream);
+ GenInterfaceDelegateCallback(stream);
+ GenStructureDefs(stream);
+ GenInterfaceDefs(stream);
+ GenPrivateSharingListSet(stream);
GenStructures(stream);
GenInterfaces(stream);
}
void CProxyBodyGen::OnFiniGen(std::ofstream& stream) {
}
-void CProxyBodyGen::GenTypedefProxyDelegate(std::ofstream& stream) {
- const char format[] =
- "typedef void (*proxy_delegate)(GList **list, rpc_port_parcel_h parcel," \
- " int seq_id, int id);\n";
- stream << NLine(1);
- stream << std::string(format);
+// @see #CB_INTERFACE_DELEGATE_CALLBACK
+void CProxyBodyGen::GenInterfaceDelegateCallback(std::ofstream& stream) {
+ stream << SmartIndent(CB_INTERFACE_DELEGATE_CALLBACK);
}
-void CProxyBodyGen::GenInterfaces(std::ofstream& stream) {
+void CProxyBodyGen::GenInterfaceDefs(std::ofstream& stream) {
for (auto& i : GetDocument().GetBlocks()) {
if (i->GetType() != Block::TYPE_INTERFACE)
continue;
const Interface &inf = static_cast<const Interface&>(*i);
- GenInterface(stream, inf);
+ GenInterfaceDef(stream, inf);
}
}
-void CProxyBodyGen::GenInterface(std::ofstream& stream, const Interface& inf) {
- GenInterfaceFileSharing(stream, inf);
- GenInterfaceEnumerations(stream, inf);
- GenInterfaceDeclaration(stream, inf);
- GenInterfaceDelegators(stream, inf);
- GenInterfaceDelegatorTable(stream, inf);
- GenInterfaceDelegatorHandler(stream, inf);
- GenInterfaceConsumeCommand(stream, inf);
- GenInterfaceOnConnectedEventCB(stream, inf);
- GenInterfaceOnDisconnectedEventCB(stream, inf);
- GenInterfaceOnRejectedEventCB(stream, inf);
- GenInterfaceOnReceivedEventCB(stream, inf);
- GenInterfaceMethods(stream, inf);
- GenInterfaceHandleCtor(stream, inf);
- GenInterfaceHandleDtor(stream, inf);
- GenInterfaceCtor(stream, inf);
- GenInterfaceConnect(stream, inf);
- GenInterfaceDtor(stream, inf);
- GenInterfaceConnectSync(stream, inf);
-}
+void CProxyBodyGen::GenInterfaceDef(std::ofstream& stream,
+ const Interface& inf) {
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
-void CProxyBodyGen::GenInterfaceFileSharing(std::ofstream& stream,
- const Interface& inf) {
-
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- for (auto& p : i->GetParameters().GetParams()) {
- if ((p->GetParameterType().GetBaseType().ToString() == "list" ||
- p->GetParameterType().GetBaseType().ToString() == "array") &&
- p->GetParameterType().GetBaseType().GetMetaType()->ToString() == "file") {
- if (p->GetParameterType().GetBaseType().ToString() == "array") {
- stream << SmartIndent(std::string(CB_FILE_ARRAY_SHARING));
- } else {
- stream << SmartIndent(std::string(CB_FILE_LIST_SHARING));
- }
- }
- }
+ GenInterfaceDelegateDef(stream, inf, *d);
}
+
+ GenInterfaceBaseDef(stream, inf);
}
+// @see #CB_INTERFACE_DELEGATE_DEF
+void CProxyBodyGen::GenInterfaceDelegateDef(std::ofstream& stream,
+ const Interface& inf, const Declaration& decl) {
+ std::string code = ReplaceAll(CB_INTERFACE_DELEGATE_DEF, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<DELEGATE_NAME>", decl.GetID());
-void CProxyBodyGen::GenInterfaceDeclaration(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_STRUCT, "##",
- GetInterfaceIdWithNamespace(inf)));
+ stream << SmartIndent(code);
}
-void CProxyBodyGen::GenInterfaceDelegators(std::ofstream& stream,
- const Interface& inf) {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
- continue;
- GenInterfaceDelegator(stream, GetInterfaceIdWithNamespace(inf), *i);
- }
-}
+// @see #CB_INTERFACE_BASE_DEF
+void CProxyBodyGen::GenInterfaceBaseDef(std::ofstream& stream,
+ const Interface& inf) {
+ std::string code = ReplaceAll(CB_INTERFACE_BASE_DEF, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
-void CProxyBodyGen::GenInterfaceDelegator(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- GenInterfaceDelegatorDeclaration(stream, id, decl);
- GenInterfaceDelegatorSerializer(stream, id, decl);
- GenInterfaceDelegatorDeserializer(stream, id, decl);
- GenInterfaceDelegatorConstructor(stream, id, decl);
- GenInterfaceDelegatorDestructor(stream, id, decl);
- GenInterfaceDelegatorDisposer(stream, id, decl);
- GenInterfaceDelegatorInvoker(stream, id, decl);
+ stream << SmartIndent(code);
}
-void CProxyBodyGen::GenInterfaceDelegatorDeclaration(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << SmartIndent(ReplaceAll(
- CB_DELEGATE_STRUCT, "##", id + "_" + decl.GetID()));
-}
+void CProxyBodyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
-void CProxyBodyGen::GenInterfaceDelegatorSerializer(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << SmartIndent(
- ReplaceAll(CB_DELEGATE_SERIALIZER, "##", id + "_" + decl.GetID()));
+ const Interface &inf = static_cast<const Interface&>(*i);
+ GenInterface(stream, inf);
+ }
}
-void CProxyBodyGen::GenInterfaceDelegatorDeserializer(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << SmartIndent(
- ReplaceAll(CB_DELEGATE_DESERIALIZER, "##", id + "_" + decl.GetID()));
-}
+void CProxyBodyGen::GenInterface(std::ofstream& stream, const Interface& inf) {
+ GenInterfaceDelegateEnumBase(stream, inf);
-void CProxyBodyGen::GenInterfaceDelegatorConstructor(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_DELEGATE_CTOR, "##", id + "_" + decl.GetID()),
- [&]()->std::string {
- return id;
- },
- [&]()->std::string {
- return decl.GetID();
- }));
-}
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
-void CProxyBodyGen::GenInterfaceDelegatorDisposer(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_DELEGATE_DISPOSER, "##", id + "_" + decl.GetID()),
- [&]()->std::string {
- return id;
- }));
-}
+ GenInterfaceDelegateBase(stream, inf, *d);
+ }
-void CProxyBodyGen::GenInterfaceDelegatorInvoker(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- const char parcel[] = "$$(parcel, $$);\n";
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_DELEGATE_INVOKER, "##", id + "_" + decl.GetID()),
- [&]()->std::string {
- return id;
- },
- [&]()->std::string {
- return decl.GetID();
- },
- [&]()->std::string {
- std::string str;
- int cnt = 0;
- for (auto& i : decl.GetParameters().GetParams()) {
- str += GetParcelParamTypeString(
- i->GetParameterType().GetBaseType(), false) + i->GetID();
- str += " = " + GetErrorValue(i->GetParameterType().GetBaseType());
- str += ";" + NLine(1);
- cnt++;
- }
- if (cnt > 0)
- str += NLine(1);
- for (auto& i : decl.GetParameters().GetParams()) {
- if (i->GetParameterType().GetBaseType().IsUserDefinedType() ||
- i->GetParameterType().GetBaseType().ToString() == "list" ||
- i->GetParameterType().GetBaseType().ToString() == "array") {
- str += GetConstructorString(i->GetParameterType().GetBaseType(),
- i->GetID());
- }
- str += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelReadFunctionString(
- i->GetParameterType().GetBaseType(), true);
- },
- [&]()->std::string {
- if (i->GetParameterType().GetBaseType().IsUserDefinedType() ||
- i->GetParameterType().GetBaseType()
- .ToString() == "list" ||
- i->GetParameterType().GetBaseType().ToString() == "array")
- return "&" + i->GetID() + "->parcelable, " + i->GetID();
- return "&" + i->GetID();
- });
- }
- return str;
- },
- [&]()->std::string {
- std::string str;
- str += "handle->callback(handle->user_data";
- for (auto& i : decl.GetParameters().GetParams()) {
- str += ", ";
- str += i->GetID();
- }
- str += ");" + NLine(1);
- return str;
- },
- [&]()->std::string {
- std::string str;
- for (auto& i : decl.GetParameters().GetParams()) {
- str += GetDestructorString(i->GetParameterType().GetBaseType(),
- i->GetID());
- str += NLine(1);
- }
- return str;
- }));
-}
+ GenInterfaceDelegateTable(stream, inf);
+ GenInterfaceMethodEnumBase(stream, inf);
+ GenInterfaceBase(stream, inf);
-void CProxyBodyGen::GenInterfaceDelegatorDestructor(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << SmartIndent(ReplaceAll(
- CB_DELEGATE_DTOR, "##", id + "_" + decl.GetID()));
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceMethodBase(stream, inf, *d);
+ }
}
-void CProxyBodyGen::GenInterfaceDelegatorTable(std::ofstream& stream,
- const Interface& inf) {
- const char block[] =
- "static proxy_delegate __$$_delegate_table[] = {\n" \
- "$$" \
- "};\n";
- const char delegate_format[] = "[$$] = $$,\n";
- std::string str;
- int cnt = 0;
-
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+// @see #CB_INTERFACE_BASE
+void CProxyBodyGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& inf) {
+ std::string prefix = GetHandlePrefix();
+ std::string code = ReplaceAll(CB_INTERFACE_BASE, "<PREFIX>", prefix);
+ std::string name = inf.GetID();
+ code = ReplaceAll(code, "<NAME>", name);
+ std::transform(prefix.begin(), prefix.end(), prefix.begin(), ::toupper);
+ code = ReplaceAll(code, "<UPPERCASE_PREFIX>", prefix);
+ std::transform(name.begin(), name.end(), name.begin(), ::toupper);
+ code = ReplaceAll(code, "<UPPERCASE_NAME>", name);
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_DELEGATE_ENUM_BASE
+void CProxyBodyGen::GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& inf) {
+ unsigned int num = 1;
+ std::string enums;
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
continue;
- str += GenTemplateString(delegate_format,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf) + "_DELEGATE_" + i->GetID();
- },
- [&]()->std::string {
- return "__" + GetInterfaceIdWithNamespace(inf) + "_delegate_"
- + i->GetID();
- });
- cnt++;
+
+ enums += GetHandlePrefix() + "_" + inf.GetID() + "_DELEGATE_" + d->GetID();
+ enums += " = " + std::to_string(num++) + ",";
+ enums += NLine(1);
}
- if (cnt == 0)
+ if (enums.empty())
return;
- stream << NLine(1);
- stream << SmartIndent(GenTemplateString(block,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return str;
- }));
-}
+ std::transform(enums.begin(), enums.end(), enums.begin(), ::toupper);
+ std::string code = ReplaceAll(CB_INTERFACE_DELEGATE_ENUM_BASE, "<ENUMS>",
+ enums);
+ code = ReplaceAll(code, "<PREFIX>", GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
-void CProxyBodyGen::GenInterfaceDelegatorHandler(std::ofstream& stream,
- const Interface& inf) {
- std::string str;
- int cnt = 0;
+ stream << SmartIndent(code);
+}
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
- continue;
- cnt++;
+std::string CProxyBodyGen::GenDelegateArgsDecl(const Interface& inf,
+ const Declaration& decl) {
+ std::string code;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ code += GetArgTypeString(type, inf) + p->GetID() + " = " +
+ GetErrorValue(param_type.GetBaseType()) + ";" + NLine(1);
}
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_PROCESS_RECEIVED_EVENT, "##",
- GetInterfaceIdWithNamespace(inf)),
- [&]()->std::string {
- if (cnt == 0)
- return str;
- return ReplaceAll(CB_PROCESS_RECEIVED_EVENT_IMPL, "##",
- GetInterfaceIdWithNamespace(inf));
- }));
+ return code;
}
-void CProxyBodyGen::GenInterfaceConsumeCommand(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_CONSUME_COMMAND, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+// @see #CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_READ
+// @see #CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_READ
+// @see #CB_INTERFACE_DELEGATE_STRING_PARCEL_READ
+// @see #CB_INTERFACE_DELEGATE_BASE_PARCEL_READ
+std::string CProxyBodyGen::GenDelegateParcelRead(const Interface& inf,
+ const Declaration& decl) {
+ std::string code;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ std::string param_read_code;
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(inf, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ param_read_code = ReplaceAll(
+ CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+
+ std::string name = GetFullNameFromType(type, inf);
+ param_read_code = ReplaceAll(param_read_code, "<NAME>", name);
+ param_read_code = ReplaceAll(param_read_code, "<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ param_read_code = ReplaceAll(CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ param_read_code = ReplaceAll(CB_INTERFACE_DELEGATE_STRING_PARCEL_READ,
+ "<ARG>", p->GetID());
+ } else {
+ param_read_code = ReplaceAll(CB_INTERFACE_DELEGATE_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ param_read_code = ReplaceAll(param_read_code, "<ARG>", p->GetID());
+ }
-void CProxyBodyGen::GenInterfaceOnConnectedEventCB(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_ON_CONNECTED, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+ code += param_read_code;
+ }
-void CProxyBodyGen::GenInterfaceOnDisconnectedEventCB(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_ON_DISCONNECTED, "##",
- GetInterfaceIdWithNamespace(inf)));
+ return RemoveLine(code);
}
-void CProxyBodyGen::GenInterfaceOnRejectedEventCB(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_ON_REJECTED, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+// @see CB_INTERFACE_DELEGATE_USER_DEFINED_ARG_FREE
+// @see CB_INTERFACE_DELEGATE_BUNDLE_ARG_FREE
+// @see CB_INTERFACE_DELEGATE_STRING_ARG_FREE
+std::string CProxyBodyGen::GenDelegateArgsFree(const Interface& inf,
+ const Declaration& decl) {
+ std::string code;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ std::string param_free_code;
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(inf, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ param_free_code = ReplaceAll(
+ CB_INTERFACE_DELEGATE_USER_DEFINED_ARG_FREE, "<PREFIX>",
+ GetHandlePrefix());
+
+ std::string name = GetFullNameFromType(type, inf);
+ param_free_code = ReplaceAll(param_free_code, "<NAME>", name);
+ param_free_code = ReplaceAll(param_free_code, "<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ param_free_code = ReplaceAll(CB_INTERFACE_DELEGATE_BUNDLE_ARG_FREE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ param_free_code = ReplaceAll(CB_INTERFACE_DELEGATE_STRING_ARG_FREE,
+ "<ARG>", p->GetID());
+ }
-void CProxyBodyGen::GenInterfaceOnReceivedEventCB(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_ON_RECEIVED, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+ code += param_free_code;
+ }
-void CProxyBodyGen::GenInterfaceMethods(std::ofstream& stream,
- const Interface& inf) {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ return RemoveLine(code);
+}
+
+std::string CProxyBodyGen::GenDelegateCallbackArgs(const Declaration& decl) {
+ std::string code;
+ for (auto& p : decl.GetParameters().GetParams())
+ code += ", " + p->GetID();
+
+ return code;
+}
+
+// @see CB_INTERFACE_DELEGATE_BASE
+void CProxyBodyGen::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& inf, const Declaration& decl) {
+ std::string code = ReplaceAll(CB_INTERFACE_DELEGATE_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<DELEGATE_NAME>", decl.GetID());
+
+ std::string enum_value = GetHandlePrefix() + "_" + inf.GetID() +
+ "_DELEGATE_" + decl.GetID();
+ std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
+ ::toupper);
+ code = ReplaceAll(code, "<DELEGATE_ENUM_VALUE>", enum_value);
+ code = ReplaceAll(code, "<DELEGATE_ARGS_DECL>",
+ GenDelegateArgsDecl(inf, decl));
+ code = ReplaceAll(code, "<DELEGATE_PARCEL_READ>",
+ GenDelegateParcelRead(inf, decl));
+ code = ReplaceAll(code, "<DELEGATE_ARGS_FREE>",
+ GenDelegateArgsFree(inf, decl));
+ code = ReplaceAll(code, "<DELEGATE_CALLBACK_ARGS>",
+ GenDelegateCallbackArgs(decl));
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_DELEGATE_TABLE
+// @see #CB_INTERFACE_DELEGATE_TABLE_MEMBER
+void CProxyBodyGen::GenInterfaceDelegateTable(std::ofstream& stream,
+ const Interface& inf) {
+ std::string delegate_handlers;
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
continue;
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_INTERFACE_METHODS, "##",
- GetInterfaceIdWithNamespace(inf)),
- [&]()->std::string {
- return GetReturnTypeString(i->GetType());
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- std::string str;
- for (auto& p : i->GetParameters().GetParams()) {
- str += ", ";
- if (IsDelegateType(inf, p->GetParameterType().GetBaseType())) {
- str += "rpc_port_" + GetInterfaceIdWithNamespace(inf) + "_" +
- p->GetParameterType().GetBaseType().ToString() +
- "_h " + p->GetID();
- } else {
- str += GetParamTypeString(p->GetParameterType().GetDirection(),
- p->GetParameterType().GetBaseType()) + p->GetID();
- }
- }
- return str;
- },
- [&]()->std::string {
- if (GetReturnTypeString(i->GetType()) != "void ")
- return GetReturnTypeString(i->GetType()) + "ret = " +
- GetErrorValue(i->GetType()) + ";";
- return "";
- },
- [&]()->std::string {
- std::string str;
- for (auto& p : i->GetParameters().GetParams()) {
- if (p->GetParameterType().GetDirection() ==
- ParameterType::Direction::OUT ||
- p->GetParameterType().GetBaseType().IsUserDefinedType() ||
- p->GetParameterType().GetBaseType().ToString() == "list" ||
- p->GetParameterType().GetBaseType().ToString() == "array" ||
- p->GetParameterType().GetBaseType().ToString() == "bundle")
- str += " || !" + p->GetID();
- }
- return str;
- },
- [&]()->std::string {
- if (GetReturnTypeString(i->GetType()) != "void ")
- return " ret";
- return "";
- },
- [&]()->std::string {
- if (GetReturnTypeString(i->GetType()) != "void ")
- return " ret";
- return "";
- },
- [&]()->std::string {
- for (auto& p : i->GetParameters().GetParams()) {
- if (p->GetParameterType().GetDirection() ==
- ParameterType::Direction::IN &&
- p->GetParameterType().GetBaseType().ToString() == "file") {
- return ReplaceAll(CB_PRIVATE_SHARING_BLOCK, "##",
- p->GetID());
- }
-
- if ((p->GetParameterType().GetBaseType().ToString() == "list" ||
- p->GetParameterType().GetBaseType().ToString() == "array") &&
- p->GetParameterType().GetBaseType().GetMetaType()->ToString() == "file") {
- if (p->GetParameterType().GetBaseType().ToString() == "array") {
-
- return ReplaceAll(CB_ARRAY_PRIVATE_SHARING_BLOCK, "##",
- p->GetID());
- } else {
- return ReplaceAll(CB_LIST_PRIVATE_SHARING_BLOCK, "##",
- p->GetID());
- }
- }
- }
- return "";
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetMethodWriteString(inf, *i);
- },
- [&]()->std::string {
- return GetMethodReadString(inf, *i);
- }));
+ std::string enum_value = GetHandlePrefix() + "_" + inf.GetID() +
+ "_DELEGATE_" + d->GetID();
+ std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
+ ::toupper);
+ std::string member = ReplaceAll(CB_INTERFACE_DELEGATE_TABLE_MEMBER,
+ "<ENUM_VALUE>", enum_value);
+ member = ReplaceAll(member, "<PREFIX>", GetHandlePrefix());
+ member = ReplaceAll(member, "<NAME>", inf.GetID());
+ member = ReplaceAll(member, "<DELEGATE_NAME>", d->GetID());
+ member = RemoveLine(member);
+
+ delegate_handlers += member;
}
-}
-void CProxyBodyGen::GenInterfaceHandleCtor(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_HANDLE_CTOR, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+ if (delegate_handlers.empty())
+ return;
-void CProxyBodyGen::GenInterfaceHandleDtor(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_HANDLE_DTOR, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
+ std::string code = ReplaceAll(CB_INTERFACE_DELEGATE_TABLE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<DELEGATE_HANDLERS>", delegate_handlers);
-void CProxyBodyGen::GenInterfaceCtor(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_CTOR, "##",
- GetInterfaceIdWithNamespace(inf)));
+ stream << SmartIndent(code);
}
-void CProxyBodyGen::GenInterfaceConnect(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_CONNECT, "##",
- GetInterfaceIdWithNamespace(inf)));
+// @see #CB_INTERFACE_METHOD_ENUM_BASE
+void CProxyBodyGen::GenInterfaceMethodEnumBase(std::ofstream& stream,
+ const Interface& inf) {
+ std::string enums;
+ enums += GetHandlePrefix() + "_" + inf.GetID() + "_METHOD_RESULT_,";
+ enums += NLine(1);
+ enums += GetHandlePrefix() + "_" + inf.GetID() + "_METHOD_CALLBACK_,";
+ enums += NLine(1);
+
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string enum_value = GetHandlePrefix() + "_" + inf.GetID() +
+ "_METHOD_" + d->GetID() + ",";
+ enums += enum_value;
+ enums += NLine(1);
+ }
+
+ std::transform(enums.begin(), enums.end(), enums.begin(), ::toupper);
+ std::string code = ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE, "<ENUMS>",
+ enums);
+ code = ReplaceAll(code, "<PREFIX>", GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+
+ stream << SmartIndent(code);
}
-void CProxyBodyGen::GenInterfaceDtor(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_DTOR, "##",
- GetInterfaceIdWithNamespace(inf)));
+std::string CProxyBodyGen::GenMethodParams(const Interface& inf,
+ const Declaration& decl) {
+ std::string params;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, inf) +
+ p->GetID();
+ }
+
+ return params;
}
-void CProxyBodyGen::GenInterfaceConnectSync(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_CONNECT_SYNC, "##",
- GetInterfaceIdWithNamespace(inf)));
+std::string CProxyBodyGen::GenMethodParamsCheck(const Interface& inf,
+ const Declaration& decl) {
+ std::string params_check;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(inf, type) ||
+ 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;
}
-std::string CProxyBodyGen::GetMethodWriteString(const Interface& inf,
- const Declaration& decl) {
- const char setter[] = "$$($$, $$);\n";
- const char ternary_operation[] = "## ? ## : \"\"";
- std::string str;
+// @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
+// @see #CB_INTERFACE_METHOD_LIST_FILE_SET_PRIVATE_SHARING
+// @see #CB_INTERFACE_METHOD_ARRAY_FILE_SET_PRIVATE_SHARING
+// @see #CB_INTERFACE_METHOD_FILE_SET_PRIVATE_SHARING
+std::string CProxyBodyGen::GenMethodParcelWrite(const Interface& inf,
+ const Declaration& decl) {
+ std::string code;
for (auto& p : decl.GetParameters().GetParams()) {
- if (p->GetParameterType().GetDirection() == ParameterType::Direction::OUT)
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
continue;
- if (IsDelegateType(inf, p->GetParameterType().GetBaseType())) {
- str += GenTemplateString(ReplaceAll(CB_DELEGATE_BLOCK, "##",
- GetInterfaceIdWithNamespace(inf) + "_" + p->GetParameterType()
- .GetBaseType().ToString()),
- [&]()->std::string {
- return p->GetID();
- });
+
+ std::string parcel_write_code;
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(inf, type) ||
+ 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, inf);
+ parcel_write_code += GetPrivateSharingString(type, inf, "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, inf, "h->port",
+ p->GetID());
} else {
- str += GenTemplateString(setter,
- [&]()->std::string {
- return GetParcelWriteFunctionString(
- p->GetParameterType().GetBaseType(), true);
- },
- [&]()->std::string {
- return "parcel";
- },
- [&]()->std::string {
- if (p->GetParameterType().GetBaseType().IsUserDefinedType() ||
- p->GetParameterType().GetBaseType().ToString() == "list" ||
- p->GetParameterType().GetBaseType().ToString() == "array") {
- if (p->GetParameterType().GetDirection()
- == ParameterType::Direction::REF)
- return "&(*" + p->GetID() + ")->parcelable, " + "*"
- + p->GetID();
- else
- return "&" + p->GetID() + "->parcelable, " + p->GetID();
- } else if (p->GetParameterType().GetDirection()
- == ParameterType::Direction::REF) {
- if (p->GetParameterType().GetBaseType().ToString() == "string"
- || p->GetParameterType().GetBaseType().ToString() == "file")
- return ReplaceAll(ternary_operation, "##", "*" + p->GetID());
- return "*" + p->GetID();
- } else if (p->GetParameterType().GetBaseType().ToString() == "string"
- || p->GetParameterType().GetBaseType().ToString() == "file") {
- return ReplaceAll(ternary_operation, "##", p->GetID());
- }
- return p->GetID();
- });
+ 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 str;
+
+ return RemoveLine(code);
}
-std::string CProxyBodyGen::GetMethodReadString(const Interface& inf,
- const Declaration& decl) {
- const char setter[] = "$$($$, $$);\n";
- std::string str;
- if (decl.GetMethodType() != Declaration::MethodType::SYNC) {
- str += "set_last_result(r);" + NLine(1);
- return str;
+// @see #CB_INTERFACE_METHOD_DELEGATE_APPEND
+std::string CProxyBodyGen::GenMethodDelegateAppend(const Interface& inf,
+ const Declaration& decl) {
+ std::string code;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(inf, type)) {
+ std::string delegate_append_code = ReplaceAll(
+ CB_INTERFACE_METHOD_DELEGATE_APPEND, "<ARG>", p->GetID());
+ code += delegate_append_code;
+ }
}
- str += GenTemplateString(CB_RECEIVE_BLOCK,
- [&]()->std::string {
- std::string s;
- for (auto& p : decl.GetParameters().GetParams()) {
- if (p->GetParameterType().GetDirection() !=
- ParameterType::Direction::OUT)
- continue;
- s += GetReturnTypeString(p->GetParameterType().GetBaseType()) +
- "out_" + p->GetID() + ";" + NLine(1);
- }
- return s;
- },
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- std::string s;
- for (auto& p : decl.GetParameters().GetParams()) {
- if (p->GetParameterType().GetDirection() !=
- ParameterType::Direction::OUT)
- continue;
- if (p->GetParameterType().GetBaseType().IsUserDefinedType() ||
- p->GetParameterType().GetBaseType().ToString() == "list" ||
- p->GetParameterType().GetBaseType().ToString() == "array") {
- s += GetConstructorString(p->GetParameterType().GetBaseType(),
- "out_" + p->GetID());
- }
- s += GenTemplateString(setter,
- [&]()->std::string {
- return GetParcelReadFunctionString(
- p->GetParameterType().GetBaseType(), true);
- },
- [&]()->std::string {
- return "parcel_received";
- },
- [&]()->std::string {
- auto& t = p->GetParameterType().GetBaseType();
- if (t.IsUserDefinedType() || t.ToString() == "list" ||
- t.ToString() == "array") {
- return "&out_" + p->GetID() + "->parcelable, out_"
- + p->GetID();
- }
-
- return "&out_" + p->GetID();
- });
- s += "*" + p->GetID() + " = out_" + p->GetID() + ";" + NLine(1);
- }
- if (GetReturnTypeString(decl.GetType()) != "void ") {
- if (decl.GetType().IsUserDefinedType() ||
- decl.GetType().ToString() == "list" ||
- decl.GetType().ToString() == "array") {
- s += GetConstructorString(decl.GetType(), "ret");
- }
- s += GenTemplateString(setter,
- [&]()->std::string {
- return GetParcelReadFunctionString(decl.GetType(), false);
- },
- [&]()->std::string {
- return "parcel_received";
- },
- [&]()->std::string {
- if (decl.GetType().IsUserDefinedType() ||
- decl.GetType().ToString() == "list" ||
- decl.GetType().ToString() == "array")
- return "&ret->parcelable, ret";
- return "&ret";
- });
- }
- return s;
- });
- if (GetReturnTypeString(decl.GetType()) != "void ") {
- str += "set_last_result(r);" + NLine(1);
- str += NLine(1);
- str += "return ret;";
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_ASYNC_BASE
+std::string CProxyBodyGen::GenMethodAsyncBase(const Interface& inf,
+ const Declaration& decl) {
+ std::string prefix = GetHandlePrefix();
+ std::string code = ReplaceAll(CB_INTERFACE_METHOD_ASYNC_BASE, "<PREFIX>",
+ prefix);
+ std::string name = inf.GetID();
+ code = ReplaceAll(code, "<NAME>", name);
+ std::string method_name = decl.GetID();
+ code = ReplaceAll(code, "<METHOD_NAME>", method_name);
+ std::string args = GenMethodParams(inf, decl);
+ code = ReplaceAll(code, "<METHOD_PARAMS>", args);
+ std::string args_check = GenMethodParamsCheck(inf, decl);
+ code = ReplaceAll(code, "<METHOD_PARAMS_CHECK>", args_check);
+ std::transform(prefix.begin(), prefix.end(), prefix.begin(), ::toupper);
+ code = ReplaceAll(code, "<UPPERCASE_PREFIX>", prefix);
+ std::transform(name.begin(), name.end(), name.begin(), ::toupper);
+ code = ReplaceAll(code, "<UPPERCASE_NAME>", name);
+ std::transform(method_name.begin(), method_name.end(), method_name.begin(),
+ ::toupper);
+ code = ReplaceAll(code, "<UPPERCASE_METHOD_NAME>", method_name);
+ std::string parcel_write = GenMethodParcelWrite(inf, decl);
+ code = ReplaceAll(code, "<METHOD_PARCEL_WRITE>", parcel_write);
+ std::string delegate_append = GenMethodDelegateAppend(inf, decl);
+ code = ReplaceAll(code, "<METHOD_DELEGATE_APPEND>", delegate_append);
+ return code;
+}
+
+std::string CProxyBodyGen::GenMethodArgs(const Interface& inf,
+ const Declaration& decl) {
+ std::string args_code;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ 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 str;
+
+ 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 CProxyBodyGen::GenMethodParcelReadBase(const Interface& inf,
+ const BaseType& type, const std::string& param_name) {
+ std::string parcel_read_code;
+ if (IsDelegateType(inf, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_read_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ std::string name = GetFullNameFromType(type, inf);
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>", name);
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", param_name);
+ } else if (type.ToString() == "bundle") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ,
+ "<ARG>", param_name);
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ 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 CProxyBodyGen::GenMethodParcelRead(const Interface& inf,
+ const Declaration& decl) {
+ std::string code;
+ std::string parcel_read_code;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ code += GenMethodParcelReadBase(inf, type, "new_" + p->GetID());
+ code += ReplaceAll(CB_INTERFACE_METHOD_PARAM_SET, "<PARAM>",
+ p->GetID());
+ }
+
+ // Return Value
+ auto& base_type = decl.GetType();
+ code += GenMethodParcelReadBase(inf, base_type, "ret_");
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_BASE
+std::string CProxyBodyGen::GenMethodBase(const Interface& inf,
+ const Declaration& decl) {
+ std::string code = ReplaceAll(CB_INTERFACE_METHOD_BASE, "<RETURN_TYPE>",
+ GetReturnTypeString(decl.GetType()));
+ std::string prefix = GetHandlePrefix();
+ code = ReplaceAll(code, "<PREFIX>", prefix);
+ std::string name = inf.GetID();
+ code = ReplaceAll(code, "<NAME>", name);
+ std::string method_name = decl.GetID();
+ code = ReplaceAll(code, "<METHOD_NAME>", method_name);
+ std::string args = GenMethodParams(inf, decl);
+ code = ReplaceAll(code, "<METHOD_PARAMS>", args);
+ std::string values = GenMethodArgs(inf, decl);
+ code = ReplaceAll(code, "<METHOD_ARGS>", values);
+ std::string error_value = GetErrorValue(decl.GetType());
+ code = ReplaceAll(code, "<ERROR_VALUE>", error_value);
+ std::string args_check = GenMethodParamsCheck(inf, decl);
+ code = ReplaceAll(code, "<METHOD_PARAMS_CHECK>", args_check);
+ std::transform(prefix.begin(), prefix.end(), prefix.begin(), ::toupper);
+ code = ReplaceAll(code, "<UPPERCASE_PREFIX>", prefix);
+ std::transform(name.begin(), name.end(), name.begin(), ::toupper);
+ code = ReplaceAll(code, "<UPPERCASE_NAME>", name);
+ std::transform(method_name.begin(), method_name.end(), method_name.begin(),
+ ::toupper);
+ code = ReplaceAll(code, "<UPPERCASE_METHOD_NAME>", method_name);
+ std::string parcel_write = GenMethodParcelWrite(inf, decl);
+ code = ReplaceAll(code, "<METHOD_PARCEL_WRITE>", parcel_write);
+ std::string parcel_read = GenMethodParcelRead(inf, decl);
+ code = ReplaceAll(code, "<METHOD_PARCEL_READ>", parcel_read);
+ std::string delegate_append = GenMethodDelegateAppend(inf, decl);
+ code = ReplaceAll(code, "<METHOD_DELEGATE_APPEND>", delegate_append);
+ return code;
+}
+
+void CProxyBodyGen::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& inf, const Declaration& decl) {
+ std::string code;
+ auto method_type = decl.GetMethodType();
+ if (method_type == Declaration::MethodType::ASYNC)
+ code = GenMethodAsyncBase(inf, decl);
+ else
+ code = GenMethodBase(inf, decl);
+
+ stream << SmartIndent(code);
}
} // namespace tidl
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
#include <string>
#include "idlc/gen/c_body_gen_base.h"
+#include "idlc/options.h"
namespace tidl {
class CProxyBodyGen : public CBodyGeneratorBase {
public:
- explicit CProxyBodyGen(std::shared_ptr<Document> doc);
+ explicit CProxyBodyGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<Options> options);
virtual ~CProxyBodyGen() = default;
void OnInitGen(std::ofstream& stream) override;
void OnFiniGen(std::ofstream& stream) override;
private:
- void GenTypedefProxyDelegate(std::ofstream& stream);
- void GenInterfaces(std::ofstream& stream);
+ void GenInterfaceDefs(std::ofstream& stream);
+ void GenInterfaceDef(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDelegateDef(std::ofstream& stream, const Interface& inf,
+ const Declaration& decl);
+ void GenInterfaceBaseDef(std::ofstream& stream, const Interface& inf);
- private:
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterfaceDelegateCallback(std::ofstream& stream);
void GenInterface(std::ofstream& stream, const Interface& inf);
- void GenInterfaceFileSharing(std::ofstream& stream, const Interface& st);
- void GenInterfaceDeclaration(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDelegators(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDelegatorTable(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDelegatorHandler(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceConsumeCommand(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceOnConnectedEventCB(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceOnDisconnectedEventCB(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceOnRejectedEventCB(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceOnReceivedEventCB(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceMethods(std::ofstream& stream, const Interface& inf);
- void GenInterfaceHandleCtor(std::ofstream& stream, const Interface& inf);
- void GenInterfaceHandleDtor(std::ofstream& stream, const Interface& inf);
- void GenInterfaceCtor(std::ofstream& stream, const Interface& inf);
- void GenInterfaceConnect(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDtor(std::ofstream& stream, const Interface& inf);
- void GenInterfaceConnectSync(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& inf);
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& inf,
+ const Declaration& decl);
+ void GenInterfaceDelegateTable(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceMethodEnumBase(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& inf,
+ const Declaration& decl);
- private:
- void GenInterfaceDelegator(std::ofstream& stream, const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDeclaration(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorSerializer(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDeserializer(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorConstructor(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDisposer(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorInvoker(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDestructor(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
+ bool HasListFile(const Interface& inf);
- private:
- std::string GetMethodWriteString(const Interface& inf,
- const Declaration& decl);
- std::string GetMethodReadString(const Interface& inf,
- const Declaration& decl);
+ std::string GenDelegateArgsDecl(const Interface& inf,
+ const Declaration& decl);
+ std::string GenDelegateParcelRead(const Interface& inf,
+ const Declaration& decl);
+ std::string GenDelegateArgsFree(const Interface& inf,
+ const Declaration& decl);
+ std::string GenDelegateCallbackArgs(const Declaration& decl);
+
+ std::string GenMethodAsyncBase(const Interface& inf, const Declaration& decl);
+ std::string GenMethodBase(const Interface& inf, const Declaration& decl);
+ std::string GenMethodParams(const Interface& inf, const Declaration& decl);
+ std::string GenMethodParamsCheck(const Interface& inf,
+ const Declaration& decl);
+ std::string GenMethodParcelWrite(const Interface& inf,
+ const Declaration& decl);
+ std::string GenMethodDelegateAppend(const Interface& inf,
+ const Declaration& decl);
+ std::string GenMethodArgs(const Interface& inf, const Declaration& decl);
+ std::string GenMethodParcelReadBase(const Interface& inf,
+ const BaseType& type, const std::string& param_name);
+ std::string GenMethodParcelRead(const Interface& inf,
+ const Declaration& decl);
+
+ private:
+ std::shared_ptr<Options> options_;
};
} // namespace tidl
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
#ifndef IDLC_C_GEN_C_PROXY_BODY_GEN_CB_H_
#define IDLC_C_GEN_C_PROXY_BODY_GEN_CB_H_
-const char CB_INTERFACE_STRUCT[] =
+constexpr const char CB_INTERFACE_DELEGATE_CALLBACK[] =
R"__c_cb(
-struct ##_s {
- char *stub_appid;
- rpc_port_proxy_h proxy;
- rpc_port_h port;
- rpc_port_h callback_port;
- rpc_port_proxy_##_callback_s callback;
- void *user_data;
- GList *delegates;
- GRecMutex mutex;
-};
+typedef void (*rpc_port_proxy_delegate_cb)(GList **delegates, rpc_port_parcel_h parcel, int id, int seq_id);
)__c_cb";
-const char CB_FILE_LIST_SHARING[] =
+/**
+ * <ENUMS> The enumeration of the interface delegate.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_ENUM_BASE[] =
R"__c_cb(
-int __file_list_set_private_sharing(rpc_port_h port, GList *list_files) {
- const char **arr = calloc(g_list_length(list_files), sizeof(char*));
- GList *iter;
- int idx = 0;
- int r = 0;
- iter = list_files;
- while (iter) {
- char *value = iter->data;
- if (!value) {
- _W("Warning: value is NULL");
- continue;
- }
- arr[idx++] = value;
- iter = g_list_next(iter);
- }
- if (idx > 0)
- r = rpc_port_set_private_sharing_array(port, arr, idx);
- return r;
-}
+typedef enum {
+ <ENUMS>
+} <PREFIX>_<NAME>_delegate_e;
)__c_cb";
-const char CB_FILE_ARRAY_SHARING[] =
+/**
+ * <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(
-int __file_array_set_private_sharing(rpc_port_h port,
- const char **files, int files_size) {
- return rpc_port_set_private_sharing_array(port, files, files_size);
-}
+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";
-const char CB_DELEGATE_STRUCT[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ * <DELEGATE_ENUM_VALUE> The enumeration value of the delegate.
+ * <DELEGATE_ARGS_DECL> The implementation to declares the arguments.
+ * <DELEGATE_PARCEL_READ> The implementation to read the arguments from the parcel.
+ * <DELEGATE_ARGS_FREE> The implementation to release the allocated arguments.
+ * <DELEGATE_CALLBACK_ARGS> The arguments of the delegate callback.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
R"__c_cb(
-struct ##_s {
- rpc_port_parcelable_t parcelable;
- int id;
- int seq_id;
- ## callback;
- bool once;
- void *user_data;
-};
-)__c_cb";
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_to(rpc_port_parcel_h parcel, void *data)
+{
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = data;
-const char CB_DELEGATE_SERIALIZER[] =
-R"__c_cb(
-static void __##_to(rpc_port_parcel_h parcel, void *data)
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
+
+ rpc_port_parcel_write_int32(parcel, h->id);
+
+ rpc_port_parcel_write_int32(parcel, h->seq_id);
+
+ rpc_port_parcel_write_bool(parcel, h->once);
+
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+}
+
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_from(rpc_port_parcel_h parcel, void *data)
{
- struct ##_s *handle = data;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = data;
- if (!handle) {
- _E("Invalid parameter");
- return;
- }
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
- rpc_port_parcel_write_int32(parcel, handle->id);
- rpc_port_parcel_write_int32(parcel, handle->seq_id);
- rpc_port_parcel_write_bool(parcel, handle->once);
- _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+ rpc_port_parcel_read_int32(parcel, &h->id);
+
+ rpc_port_parcel_read_int32(parcel, &h->seq_id);
+
+ rpc_port_parcel_read_bool(parcel, &h->once);
+
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+ set_last_result(RPC_PORT_ERROR_NONE);
}
-)__c_cb";
-const char CB_DELEGATE_DESERIALIZER[] =
-R"__c_cb(
-static void __##_from(rpc_port_parcel_h parcel, void *data)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h)
{
- struct ##_s *handle = data;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_t *handle;
+ static int seq_num;
- if (!handle) {
- _E("Invalid parameter");
- return;
- }
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_<DELEGATE_NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_<DELEGATE_NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_<DELEGATE_NAME>_from;
+ handle->id = <DELEGATE_ENUM_VALUE>;
+ handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+ _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
- rpc_port_parcel_read_int32(parcel, &handle->id);
- rpc_port_parcel_read_int32(parcel, &handle->seq_id);
- rpc_port_parcel_read_bool(parcel, &handle->once);
- _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_DELEGATE_CTOR[] =
-R"__c_cb(
-rpc_port_##_h rpc_port_##_create(## callback, bool once, void *user_data)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h)
{
- struct ##_s *handle;
- static int seq_num;
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- handle = calloc(1, sizeof(struct ##_s));
- if (!handle) {
- _E("Out of memory");
- return NULL;
- }
+ _W("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
- handle->parcelable.to = __##_to;
- handle->parcelable.from= __##_from;
- handle->id = $$_DELEGATE_$$;
- handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
- handle->callback = callback;
- handle->once = once;
- handle->user_data = user_data;
- _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+ free(h);
- return handle;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_DELEGATE_DISPOSER[] =
-R"__c_cb(
-int rpc_port_proxy_##_dispose(rpc_port_proxy_$$_h proxy, rpc_port_##_h delegate)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone)
{
- struct ##_s *handle;
- GList *iter;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h handle;
+ rpc_port_parcel_h parcel;
+ int ret;
+
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = <PREFIX>_<NAME>_<DELEGATE_NAME>_create(&handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
+
+ ret = rpc_port_parcel_create(&parcel);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret);
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(handle);
+ return ret;
+ }
+
+ rpc_port_parcel_write(parcel, &h->parcelable, h);
+ rpc_port_parcel_read(parcel, &handle->parcelable, handle);
+ ret = get_last_result();
+ rpc_port_parcel_destroy(parcel);
+
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data. error(%d)", ret);
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(handle);
+ return ret;
+ }
+
+ *clone = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
- if (!proxy || !delegate) {
- _E("Invalid handle %p %p", proxy, delegate);
- return -1;
- }
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_callback(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback, void *user_data)
+{
+ if (h == nullptr || callback == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- iter = proxy->delegates;
- while (iter) {
- handle = (struct ##_s *)iter->data;
- if (handle == delegate) {
- _W("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
- proxy->delegates = g_list_remove_link(proxy->delegates, iter);
- free(handle);
- g_list_free(iter);
- return 0;
- }
- iter = g_list_next(iter);
- }
+ h->callback = callback;
+ h->user_data = user_data;
- return -1;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_DELEGATE_DTOR[] =
-R"__c_cb(
-int rpc_port_##_destroy(rpc_port_##_h delegate)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool once)
{
- if (!delegate) {
- _E("Invalid parameter");
- return -1;
- }
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- free(delegate);
+ h->once = once;
- return 0;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_DELEGATE_INVOKER[] =
-R"__c_cb(
-static void __$$_delegate_$$(GList **list, rpc_port_parcel_h parcel, int seq_id, int id)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id)
{
-$$
- do {
- struct ##_s *handle;
- GList *iter;
-
- iter = *list;
- while (iter) {
- handle = (struct ##_s *)iter->data;
- if (handle->seq_id == seq_id && handle->id == id) {
- bool once = handle->once;
-
- _W("Invoke id(%d), seq_id(%d)", id, seq_id);
- $$
- if (once) {
- _W("Dispose");
- *list = g_list_remove_link(*list, iter);
- free(handle);
- g_list_free(iter);
- }
- break;
- }
- iter = g_list_next(iter);
- }
- } while (0);
-$$
+ if (h == nullptr || id == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *id = h->id;
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_PROCESS_RECEIVED_EVENT[] =
-R"__c_cb(
-static void __##_process_received_event(GList **list, rpc_port_parcel_h parcel)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id)
{
-$$
+ if (h == nullptr || seq_id == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ *seq_id = h->seq_id;
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_PROCESS_RECEIVED_EVENT_IMPL[] =
-R"__c_cb(int id;
-int seq_id;
-bool once;
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once)
+{
+ if (h == nullptr || once == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
-rpc_port_parcel_read_int32(parcel, &id);
-rpc_port_parcel_read_int32(parcel, &seq_id);
-rpc_port_parcel_read_bool(parcel, &once);
-_W("id(%d), seq_id(%d)", id, seq_id);
+ *once = h->once;
-if (id > 0 && id < (sizeof(__##_delegate_table) / sizeof(__##_delegate_table[0]))) {
- if (__##_delegate_table[id])
- __##_delegate_table[id](list, parcel, seq_id, id);
-} else {
- _W("Unknown id(%d)", id);
-})__c_cb";
+ return RPC_PORT_ERROR_NONE;
+}
-const char CB_CONSUME_COMMAND[] =
-R"__c_cb(
-static rpc_port_parcel_h __##_consume_command(rpc_port_proxy_##_h h)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag)
{
- rpc_port_parcel_h parcel = NULL;
- int cmd = -1;
+ char *new_tag;
+ char buf[128];
- do {
- rpc_port_parcel_create_from_port(&parcel, h->port);
- if (!parcel)
- break;
+ if (h == nullptr || tag == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- rpc_port_parcel_read_int32(parcel, &cmd);
- if (cmd == ##_METHOD_Result)
- return parcel;
+ snprintf(buf, sizeof(buf), "%d::%d", h->id, h->seq_id);
+ new_tag = strdup(buf);
+ if (new_tag == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
- rpc_port_parcel_destroy(parcel);
- parcel = NULL;
- } while (true);
+ *tag = new_tag;
- return NULL;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_ON_CONNECTED[] =
-R"__c_cb(
-static void __##_on_connected(const char *endpoint, const char *port_name, rpc_port_h port, void *data)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose(<PREFIX>_<NAME>_h proxy, <PREFIX>_<NAME>_<DELEGATE_NAME>_h h)
+{
+ GList *found;
+
+ if (proxy == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ found = g_list_find(proxy->delegates, h);
+ if (found == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ proxy->delegates = g_list_remove_link(proxy->delegates, found);
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(h);
+ g_list_free(found);
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_delegate_handler(GList **delegates, rpc_port_parcel_h parcel, int id, int seq_id)
{
- rpc_port_proxy_##_h handle = data;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h handle;
+ GList *iter;
+ bool once;
+ <DELEGATE_ARGS_DECL>
+
+ <DELEGATE_PARCEL_READ>
+
+ iter = *delegates;
+ while (iter) {
+ handle = iter->data;
+ iter = g_list_next(iter);
+ if (handle->id == id && handle->seq_id == seq_id) {
+ once = handle->once;
+ _W("Invoke id(%d), seq_id(%d)", id, seq_id);
+ if (handle->callback)
+ handle->callback(handle->user_data<DELEGATE_CALLBACK_ARGS>);
+ else
+ _W("The callback function is nullptr");
+
+ if (once) {
+ *delegates = g_list_remove(*delegates, handle);
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(handle);
+ }
+
+ break;
+ }
+ }
- handle->port = port;
- rpc_port_proxy_get_port(handle->proxy, RPC_PORT_PORT_CALLBACK, &handle->callback_port);
- if (handle->callback.connected)
- handle->callback.connected(handle, handle->user_data);
- _I("[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
+out:
+ <DELEGATE_ARGS_FREE>
}
)__c_cb";
-const char CB_ON_DISCONNECTED[] =
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_READ[] =
R"__c_cb(
-static void __##_on_disconnected(const char *endpoint, const char *port_name, void *data)
-{
- rpc_port_proxy_##_h handle = data;
+<PREFIX>_<NAME>_create(&<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to create handle");
+ goto out;
+}
- handle->port = NULL;
- if (handle->callback.disconnected)
- handle->callback.disconnected(handle, handle->user_data);
- _I("[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
+rpc_port_parcel_read(parcel, &<ARG>->parcelable, <ARG>);
+if (get_last_result() != RPC_PORT_ERROR_NONE) {
+ _E("Failed to read data");
+ goto out;
}
)__c_cb";
-const char CB_ON_REJECTED[] =
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_READ[] =
R"__c_cb(
-static void __##_on_rejected(const char *endpoint, const char *port_name, void *data)
-{
- rpc_port_proxy_##_h handle = data;
+rpc_port_parcel_read_bundle(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ goto out;
+}
+)__c_cb";
- handle->port = NULL;
- if (handle->callback.rejected)
- handle->callback.rejected(handle, handle->user_data);
- _I("[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_STRING_PARCEL_READ[] =
+R"__c_cb(
+rpc_port_parcel_read_string(parcel, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ goto out;
}
)__c_cb";
-const char CB_ON_RECEIVED[] =
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE_PARCEL_READ[] =
R"__c_cb(
-static void __##_on_received(const char *endpoint, const char *port_name, void *data)
-{
- rpc_port_proxy_##_h handle = data;
- rpc_port_parcel_h parcel_received = NULL;
- int cmd = -1;
-
- rpc_port_parcel_create_from_port(&parcel_received, handle->callback_port);
- if (!parcel_received) {
- _E("Failed to create parcel from port(%s)", port_name);
- return;
- }
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &<ARG>);
+)__c_cb";
- rpc_port_parcel_read_int32(parcel_received, &cmd);
- if (cmd != ##_METHOD_Callback) {
- _E("Invalid protocol");
- rpc_port_parcel_destroy(parcel_received);
- return;
- }
+/**
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_USER_DEFINED_ARG_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ <PREFIX>_<NAME>_destroy(<ARG>);
+)__c_cb";
- __##_process_received_event(&handle->delegates, parcel_received);
- rpc_port_parcel_destroy(parcel_received);
- _I("[__RPC_PORT__] endpoint(%s), port_name(%s)", endpoint, port_name);
-}
+/**
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BUNDLE_ARG_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ bundle_free(<ARG>);
)__c_cb";
-const char CB_INTERFACE_METHODS[] =
+/**
+ * <ARG> The name of the value;
+ */
+constexpr const char CB_INTERFACE_DELEGATE_STRING_ARG_FREE[] =
R"__c_cb(
-$$rpc_port_proxy_##_invoke_$$(rpc_port_proxy_##_h h$$)
-{
- rpc_port_parcel_h parcel;
- int r;
-$$
+if (<ARG>)
+ free(<ARG>);
+)__c_cb";
- if (!h$$) {
- _E("Invalid parameter");
- return$$;
- }
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_HANDLERS> The array of the delegate callbacks.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_TABLE[] =
+R"__c_cb(
+static <PREFIX>_delegate_cb __<PREFIX>_<NAME>_delegate_table[] = {
+ <DELEGATE_HANDLERS>
+};
+)__c_cb";
- if (!h->port) {
- _E("Not connected");
- return$$;
- }
-$$
- rpc_port_parcel_create(&parcel);
- rpc_port_parcel_write_int32(parcel, ##_METHOD_$$);
-$$
- r = rpc_port_parcel_send(parcel, h->port);
- if (r != RPC_PORT_ERROR_NONE) {
- _E("Failed to send parcel. result(%d)", r);
- r = RPC_PORT_ERROR_IO_ERROR;
- }
+/**
+ * <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";
- rpc_port_parcel_destroy(parcel);
-$$
-}
+/**
+ * <ENUMS> The enumerations of the interface method.
+ * <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 {
+ <ENUMS>
+} <PREFIX>_<NAME>_method_e;
)__c_cb";
-const char CB_INTERFACE_HANDLE_CTOR[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE_DEF[] =
R"__c_cb(
-static struct ##_s *__create_##(const char *stub_appid, rpc_port_proxy_##_callback_s *callback, void *user_data)
-{
- struct ##_s *handle;
+typedef struct <PREFIX>_<NAME>_s {
+ char *stub_appid;
+ rpc_port_proxy_h proxy;
+ rpc_port_h port;
+ rpc_port_h callback_port;
+ <PREFIX>_<NAME>_callback_s callback;
+ void *user_data;
+ GList *delegates;
+ GRecMutex mutex;
+} <PREFIX>_<NAME>_t;
+)__c_cb";
- handle = calloc(1, sizeof(struct ##_s));
- if (!handle) {
- _E("Out of memory");
- return NULL;
- }
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_process_received_event(GList **delegates, rpc_port_parcel_h parcel)
+{
+ int id = 0;
+ int seq_id = 0;
+ bool once = false;
+
+ rpc_port_parcel_read_int32(parcel, &id);
+ rpc_port_parcel_read_int32(parcel, &seq_id);
+ rpc_port_parcel_read_bool(parcel, &once);
+ _W("id(%d), seq_id(%d)", id, seq_id);
+
+ if (id > 0 && id < ARRAY_SIZE(__<PREFIX>_<NAME>_delegate_table)) {
+ if (__<PREFIX>_<NAME>_delegate_table[id])
+ __<PREFIX>_<NAME>_delegate_table[id](delegates, parcel, id, seq_id);
+ } else {
+ _W("Unknown ID(%d)", id);
+ }
+}
- handle->stub_appid = strdup(stub_appid);
- if (!handle->stub_appid) {
- _E("Out of memory");
- free(handle);
- return NULL;
+static void __<PREFIX>_<NAME>_consume_command(rpc_port_h port, rpc_port_parcel_h *p)
+{
+ rpc_port_parcel_h parcel;
+ int cmd = -1;
+ int ret;
+
+ do {
+ ret = rpc_port_parcel_create_from_port(&parcel, port);
+ if (ret != RPC_PORT_ERROR_NONE)
+ break;
+
+ rpc_port_parcel_read_int32(parcel, &cmd);
+ if (cmd == <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_RESULT_) {
+ *p = parcel;
+ return;
}
- rpc_port_proxy_create(&handle->proxy);
- if (!handle->proxy) {
- _E("Failed to create proxy");
- free(handle->stub_appid);
- free(handle);
- return NULL;
- }
+ rpc_port_parcel_destroy(parcel);
+ } while (true);
- g_rec_mutex_init(&handle->mutex);
+ *p = nullptr;
+}
- handle->callback = *callback;
- handle->user_data = user_data;
+static void __<PREFIX>_<NAME>_connected(const char *endpoint, const char *port_name, rpc_port_h port, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
- return handle;
+ _I("endpoint(%s), port_name(%s)", endpoint, port_name);
+ h->port = port;
+ rpc_port_proxy_get_port(h->proxy, RPC_PORT_PORT_CALLBACK, &h->callback_port);
+ h->callback.connected(h, h->user_data);
}
-)__c_cb";
-const char CB_INTERFACE_HANDLE_DTOR[] =
-R"__c_cb(
-static void __destroy_##(struct ##_s *h)
+static void __<PREFIX>_<NAME>_disconnected(const char *endpoint, const char *port_name, void *data)
{
- if (!h)
- return;
+ <PREFIX>_<NAME>_h h = data;
- g_rec_mutex_clear(&h->mutex);
+ _W("endpoint(%s), port_name(%s)", endpoint, port_name);
+ h->port = nullptr;
+ h->callback.disconnected(h, h->user_data);
- if (h->delegates)
- g_list_free_full(h->delegates, free);
+}
- if (h->proxy)
- rpc_port_proxy_destroy(h->proxy);
+static void __<PREFIX>_<NAME>_rejected(const char *endpoint, const char *port_name, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
- if (h->stub_appid)
- free(h->stub_appid);
+ _W("endpoint(%s), port_name(%s)", endpoint, port_name);
+ h->port = nullptr;
+ h->callback.rejected(h, h->user_data);
+}
- free(h);
+static void __<PREFIX>_<NAME>_received(const char *endpoint, const char *port_name, void *data)
+{
+ <PREFIX>_<NAME>_h h = data;
+ rpc_port_parcel_h parcel;
+ int cmd = -1;
+ int ret;
+
+ _W("endpoint(%s), port_name(%s)", endpoint, port_name);
+ ret = rpc_port_parcel_create_from_port(&parcel, h->callback_port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle from port. error(%d)", ret);
+ return;
+ }
+
+ rpc_port_parcel_read_int32(parcel, &cmd);
+ if (cmd != <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_CALLBACK_) {
+ _E("Invalid protocol");
+ rpc_port_parcel_destroy(parcel);
+ return;
+ }
+
+ __<PREFIX>_<NAME>_process_received_event(&h->delegates, parcel);
+ rpc_port_parcel_destroy(parcel);
}
-)__c_cb";
-const char CB_INTERFACE_CTOR[] =
-R"__c_cb(
-int rpc_port_proxy_##_create(const char *stub_appid, rpc_port_proxy_##_callback_s *callback, void *user_data, rpc_port_proxy_##_h *h)
+int <PREFIX>_<NAME>_create(const char *stub_appid, <PREFIX>_<NAME>_callback_s *callback, void *user_data, <PREFIX>_<NAME>_h *h)
+{
+ <PREFIX>_<NAME>_t *handle;
+ int ret;
+
+ if (stub_appid == nullptr || callback == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (callback->connected == nullptr || callback->disconnected == nullptr || callback->rejected == 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->stub_appid = strdup(stub_appid);
+ if (handle->stub_appid == nullptr) {
+ _E("Failed to duplicate stub appid");
+ <PREFIX>_<NAME>_destroy(handle);
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ ret = rpc_port_proxy_create(&handle->proxy);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create proxy handle. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ handle->callback = *callback;
+ handle->user_data = user_data;
+
+ ret = rpc_port_proxy_add_connected_event_cb(handle->proxy, __<PREFIX>_<NAME>_connected, handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add connected event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = rpc_port_proxy_add_disconnected_event_cb(handle->proxy, __<PREFIX>_<NAME>_disconnected, handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add disconnected event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = rpc_port_proxy_add_rejected_event_cb(handle->proxy, __<PREFIX>_<NAME>_rejected, handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add rejected event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ ret = rpc_port_proxy_add_received_event_cb(handle->proxy, __<PREFIX>_<NAME>_received, handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add received event cb. error(%d)", ret);
+ <PREFIX>_<NAME>_destroy(handle);
+ return ret;
+ }
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_destroy(<PREFIX>_<NAME>_h h)
{
- struct ##_s *handle;
- int r;
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- if (!stub_appid || !callback || !h) {
- _E("Invalid parameter");
- return -1;
- }
+ g_rec_mutex_lock(&h->mutex);
+ g_rec_mutex_unlock(&h->mutex);
+ g_rec_mutex_clear(&h->mutex);
- handle = __create_##(stub_appid, callback, user_data);
- if (!handle)
- return -1;
+ if (h->delegates)
+ g_list_free_full(h->delegates, free);
- r = rpc_port_proxy_add_connected_event_cb(handle->proxy, __##_on_connected, handle);
- if (r != 0) {
- _E("Failed to add connected event cb. err = %d", r);
- __destroy_##(handle);
- return r;
- }
+ if (h->proxy)
+ rpc_port_proxy_destroy(h->proxy);
- r = rpc_port_proxy_add_disconnected_event_cb(handle->proxy, __##_on_disconnected, handle);
- if (r != 0) {
- _E("Failed to add disconnected event cb. err = %d", r);
- __destroy_##(handle);
- return r;
- }
+ if (h->stub_appid)
+ free(h->stub_appid);
- r = rpc_port_proxy_add_rejected_event_cb(handle->proxy, __##_on_rejected, handle);
- if (r != 0) {
- _E("Failed to add rejected event cb. err = %d", r);
- __destroy_##(handle);
- return r;
- }
+ free(h);
- r = rpc_port_proxy_add_received_event_cb(handle->proxy, __##_on_received, handle);
- if (r != 0) {
- _E("Failed to add received event cb. err = %d", r);
- __destroy_##(handle);
- return r;
- }
+ return RPC_PORT_ERROR_NONE;
+}
+
+int <PREFIX>_<NAME>_connect(<PREFIX>_<NAME>_h h)
+{
+ int ret;
+
+ if (h == nullptr || h->proxy == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- *h = handle;
+ ret = rpc_port_proxy_connect(h->proxy, h->stub_appid, "<NAME>");
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to connect to stub. error(%d)", ret);
+ return ret;
+ }
- return 0;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_INTERFACE_CONNECT[] =
-R"__c_cb(
-int rpc_port_proxy_##_connect(rpc_port_proxy_##_h h)
+int <PREFIX>_<NAME>_connect_sync(<PREFIX>_<NAME>_h h)
{
- int r;
+ int ret;
- if (!h || !h->proxy) {
- _E("Invalid parameter");
- return -1;
- }
+ if (h == nullptr || h->proxy == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- r = rpc_port_proxy_connect(h->proxy, h->stub_appid, "##");
- if (r != 0) {
- _E("Failed to connect ##(%s)", h->stub_appid);
- return r;
- }
+ ret = rpc_port_proxy_connect_sync(h->proxy, h->stub_appid, "<NAME>");
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to connect to stub. error(%d)", ret);
+ return ret;
+ }
- return 0;
+ return RPC_PORT_ERROR_NONE;
}
)__c_cb";
-const char CB_INTERFACE_DTOR[] =
+/**
+ * <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.
+ * <METHOD_DELEGATES_APPEND> The implementation to add the delegates to the list.
+ */
+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_;
+ int res_;
+
+ if (h == nullptr<METHOD_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ if (h->port == nullptr) {
+ _E("Not connected");
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
+
+ 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_write_int32(parcel_, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
+
+ <METHOD_PARCEL_WRITE>
+ <METHOD_DELEGATE_APPEND>
+
+ res_ = rpc_port_parcel_send(parcel_, h->port);
+ rpc_port_parcel_destroy(parcel_);
+ if (res_ != RPC_PORT_ERROR_NONE)
+ _E("Failed to send parcel. error(%d)", res_);
+
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(res_);
+}
+)__c_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the method of the interface.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_NAME> The method name of the interface.
+ * <METHOD_ARGS> The value declarations for reading the data from the parcel.
+ * <ERROR_VALUE> The error value of the method.
+ * <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.
+ * <METHOD_PARCEL_READ> The implementation to read results from the parcel.
+ * <METHOD_DELEGATE_APPEND> The implementation to add the delegates to the list.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE[] =
R"__c_cb(
-int rpc_port_proxy_##_destroy(rpc_port_proxy_##_h h)
+<RETURN_TYPE><PREFIX>_<NAME>_invoke_<METHOD_NAME>(<PREFIX>_<NAME>_h h<METHOD_PARAMS>)
{
- if (!h) {
- _E("Invalid parameter");
- return -1;
+ rpc_port_parcel_h parcel_;
+ int res_;
+ <RETURN_TYPE>ret_ = <ERROR_VALUE>;
+ <METHOD_ARGS>
+
+ if (h == nullptr<METHOD_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return ret_;
+ }
+
+ g_rec_mutex_lock(&h->mutex);
+ if (h->port == nullptr) {
+ _E("Not connected");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ g_rec_mutex_unlock(&h->mutex);
+ return ret_;
+ }
+
+ res_ = rpc_port_parcel_create(&parcel_);
+ if (res_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", res_);
+ set_last_result(res_);
+ g_rec_mutex_unlock(&h->mutex);
+ return ret_;
+ }
+
+ rpc_port_parcel_write_int32(parcel_, <UPPERCASE_PREFIX>_<UPPERCASE_NAME>_METHOD_<UPPERCASE_METHOD_NAME>);
+
+ <METHOD_PARCEL_WRITE>
+ <METHOD_DELEGATE_APPEND>
+
+ res_ = rpc_port_parcel_send(parcel_, h->port);
+ rpc_port_parcel_destroy(parcel_);
+ if (res_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to send parcel. error(%d)", res_);
+ set_last_result(res_);
+ g_rec_mutex_unlock(&h->mutex);
+ return ret_;
+ }
+
+ do {
+ parcel_ = nullptr;
+ __<PREFIX>_<NAME>_consume_command(h->port, &parcel_);
+ if (parcel_ == nullptr) {
+ _E("Invalid protocol");
+ res_ = RPC_PORT_ERROR_IO_ERROR;
+ break;
}
- __destroy_##(h);
- return 0;
+ <METHOD_PARCEL_READ>
+ rpc_port_parcel_destroy(parcel_);
+ } while (0);
+ g_rec_mutex_unlock(&h->mutex);
+ set_last_result(res_);
+
+ return ret_;
}
)__c_cb";
-const char CB_DELEGATE_BLOCK[] =
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE[] =
R"__c_cb(
-do {
- struct ##_s *handle = $$;
-
- rpc_port_parcel_write(parcel, &handle->parcelable, handle);
- h->delegates = g_list_append(h->delegates, handle);
-} while (0);
+rpc_port_parcel_write(parcel_, &<ARG>->parcelable, <ARG>);
)__c_cb";
-const char CB_RECEIVE_BLOCK[] =
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE[] =
R"__c_cb(
-g_rec_mutex_lock(&h->mutex);
-do {
- rpc_port_parcel_h parcel_received;
-$$
- parcel_received = __$$_consume_command(h);
- if (!parcel_received) {
- _E("Invalid protocol");
- r = RPC_PORT_ERROR_IO_ERROR;
- break;
- }
+rpc_port_parcel_write_bundle(parcel_, <ARG>);
+)__c_cb";
-$$
- rpc_port_parcel_destroy(parcel_received);
-} while (0);
-g_rec_mutex_unlock(&h->mutex);
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel_, <ARG>);
)__c_cb";
-const char CB_LIST_PRIVATE_SHARING_BLOCK[] =
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_WRITE[] =
R"__c_cb(
- r = __file_list_set_private_sharing(h->port, ##->list_files);
- if (r != RPC_PORT_ERROR_NONE) {
- _E("Fail to set private sharing");
- return ret;
- }
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel_, <ARG>);
)__c_cb";
-const char CB_ARRAY_PRIVATE_SHARING_BLOCK[] =
+/**
+ * <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(
- r = __file_array_set_private_sharing(h->port,
- (const char **)##->array_files, ##->array_files_size);
- if (r != RPC_PORT_ERROR_NONE) {
- _E("Fail to set private sharing");
- return ret;
- }
+<ARG> = nullptr;
+<PREFIX>_<NAME>_create(&<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to create handle");
+ res_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ break;
+}
+
+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>);
+ res_ = get_last_result();
+ break;
+}
)__c_cb";
-const char CB_PRIVATE_SHARING_BLOCK[] =
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ[] =
R"__c_cb(
- r = rpc_port_set_private_sharing(h->port, ##);
- if (r != RPC_PORT_ERROR_NONE) {
- _E("Fail to set private sharing");
- return ret;
- }
+<ARG> = nullptr;
+rpc_port_parcel_read_bundle(parcel_, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ res_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ break;
+}
)__c_cb";
-const char CB_INTERFACE_CONNECT_SYNC[] =
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_READ[] =
R"__c_cb(
-int rpc_port_proxy_##_connect_sync(rpc_port_proxy_##_h h)
-{
- int r;
+<ARG> = nullptr;
+rpc_port_parcel_read_string(parcel_, &<ARG>);
+if (<ARG> == nullptr) {
+ _E("Failed to read data");
+ res_ = RPC_PORT_ERROR_OUT_OF_MEMORY;
+ break;
+}
+)__c_cb";
- if (!h || !h->proxy) {
- _E("Invalid parameter");
- return -1;
- }
+/**
+ * <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";
- r = rpc_port_proxy_connect_sync(h->proxy, h->stub_appid, "##");
- if (r != 0) {
- _E("Failed to connect sync ##(%s)", h->stub_appid);
- return r;
- }
+/**
+ * <PARAM> The name of the parameter.
+ */
+constexpr const char CB_INTERFACE_METHOD_PARAM_SET[] =
+R"__c_cb(
+*<PARAM> = new_<PARAM>;
+)__c_cb";
- return 0;
-}
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_DELEGATE_APPEND[] =
+R"__c_cb(
+h->delegates = g_list_append(h->delegates, <ARG>);
)__c_cb";
#endif // IDLC_C_GEN_C_PROXY_BODY_GEN_CB_H_
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
namespace tidl {
CProxyHeaderGen::CProxyHeaderGen(std::shared_ptr<Document> doc)
- : CHeaderGeneratorBase(doc) {}
+ : CHeaderGeneratorBase(doc) {
+}
void CProxyHeaderGen::OnInitGen(std::ofstream& stream) {
GenVersion(stream);
GenPragmaOnce(stream);
GenIncludeDefaultHeaders(stream, false);
GenExplicitLinkageOpen(stream);
+ GenStructureHandles(stream);
+ GenInterfaceHandles(stream);
GenStructures(stream);
GenInterfaces(stream);
}
GenExplicitLinkageClose(stream);
}
+void CProxyHeaderGen::GenInterfaceHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& inf = static_cast<const Interface&>(*b);
+ GenInterfaceHandle(stream, inf);
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateHandle(stream, inf, *d);
+ }
+ }
+}
+
+// @see #CB_INTERFACE_HANDLE
+void CProxyHeaderGen::GenInterfaceHandle(std::ofstream& stream,
+ const Interface& inf) {
+ std::string code = ReplaceAll(CB_INTERFACE_HANDLE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_DELEGATE_HANDLE
+void CProxyHeaderGen::GenInterfaceDelegateHandle(std::ofstream& stream,
+ const Interface& inf, const Declaration& decl) {
+ std::string code = ReplaceAll(CB_INTERFACE_DELEGATE_HANDLE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<DELEGATE_NAME>", decl.GetID());
+
+ stream << SmartIndent(code);
+}
+
void CProxyHeaderGen::GenInterfaces(std::ofstream& stream) {
for (auto& i : GetDocument().GetBlocks()) {
if (i->GetType() != Block::TYPE_INTERFACE)
}
void CProxyHeaderGen::GenInterface(std::ofstream& stream,
- const Interface& inf) {
- GenInterfaceDeclaration(stream, inf);
- GenInterfaceDelegators(stream, inf);
- GenInterfaceCtor(stream, inf);
- GenInterfaceConnect(stream, inf);
- GenInterfaceDtor(stream, inf);
- GenInterfaceMethods(stream, inf);
- GenInterfaceConnectSync(stream, inf);
-}
+ const Interface& inf) {
+ for (auto& d: inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateBase(stream, inf, *d);
+ }
+
+ GenInterfaceBase(stream, inf);
-void CProxyHeaderGen::GenInterfaceDelegators(std::ofstream& stream,
- const Interface& inf) {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
- GenInterfaceDelegator(stream, GetInterfaceIdWithNamespace(inf), *i);
+
+ GenInterfaceMethodBase(stream, inf, *d);
}
}
-void CProxyHeaderGen::GenInterfaceDelegator(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- const char handle[] = "typedef struct $$_s *rpc_port_$$_h;";
-
- stream << NLine(1);
- stream << GenTemplateString(handle,
- [&]()->std::string {
- return id + "_" + decl.GetID();
- },
- [&]()->std::string {
- return id + "_" + decl.GetID();
- });
-
- stream << NLine(1);
- stream << GenTemplateString(CB_INTERFACE_DELEGATOR,
- [&]()->std::string {
- return GetReturnTypeString(decl.GetType());
- },
- [&]()->std::string {
- return id + "_" + decl.GetID();
- },
- [&]()->std::string {
- std::string str;
- str += "void *user_data";
- for (auto& p : decl.GetParameters().GetParams()) {
- str += ", ";
- str += GetParamTypeString(p->GetParameterType().GetDirection(),
- p->GetParameterType().GetBaseType()) + p->GetID();
- }
- return str;
- });
-
- stream << ReplaceAll(CB_DELEGATE_CTOR, "##", id + "_" + decl.GetID());
- stream << ReplaceAll(CB_DELEGATE_DTOR, "##", id + "_" + decl.GetID());
- stream << GenTemplateString(
- ReplaceAll(CB_DELEGATE_DISPOSER, "##", id + "_" + decl.GetID()),
- [&]()->std::string {
- return id;
- });
-}
+// @see #CB_INTERFACE_BASE
+void CProxyHeaderGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& inf) {
+ std::string code = ReplaceAll(CB_INTERFACE_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
-void CProxyHeaderGen::GenInterfaceDeclaration(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_DECL, "##",
- GetInterfaceIdWithNamespace(inf)));
+ stream << SmartIndent(code);
}
-void CProxyHeaderGen::GenInterfaceMethods(std::ofstream& stream,
- const Interface& inf) {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
- continue;
- stream << GenTemplateString(
- ReplaceAll(CB_INTERFACE_METHODS, "##",
- GetInterfaceIdWithNamespace(inf)),
- [&]()->std::string {
- return GetReturnTypeString(i->GetType());
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- std::string str;
- for (auto& p : i->GetParameters().GetParams()) {
- str += ", ";
- if (IsDelegateType(inf, p->GetParameterType().GetBaseType())) {
- str += "rpc_port_" + GetInterfaceIdWithNamespace(inf) + "_" +
- p->GetParameterType().GetBaseType().ToString() +
- "_h " + p->GetID();
- } else {
- str += GetParamTypeString(p->GetParameterType().GetDirection(),
- p->GetParameterType().GetBaseType()) + p->GetID();
- }
- }
- return str;
- });
+std::string CProxyHeaderGen::GenDelegateParams(const Interface& inf,
+ const Declaration& decl) {
+ std::string params;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, inf) +
+ p->GetID();
}
-}
-void CProxyHeaderGen::GenInterfaceCtor(std::ofstream& stream,
- const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CTOR, "##",
- GetInterfaceIdWithNamespace(inf));
+ return params;
}
-void CProxyHeaderGen::GenInterfaceConnect(std::ofstream& stream,
- const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CONNECT, "##",
- GetInterfaceIdWithNamespace(inf));
+// @see #CB_INTERFACE_DELEGATE_BASE
+void CProxyHeaderGen::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& inf, const Declaration& decl) {
+ std::string code = ReplaceAll(CB_INTERFACE_DELEGATE_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<DELEGATE_NAME>", decl.GetID());
+ code = ReplaceAll(code, "<DELEGATE_PARAMS>", GenDelegateParams(inf, decl));
+
+ stream << SmartIndent(code);
}
-void CProxyHeaderGen::GenInterfaceDtor(std::ofstream& stream,
- const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_DTOR, "##",
- GetInterfaceIdWithNamespace(inf));
+std::string CProxyHeaderGen::GenMethodParams(const Interface& inf,
+ const Declaration& decl) {
+ std::string params;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, inf) +
+ p->GetID();
+ }
+
+ return params;
}
-void CProxyHeaderGen::GenInterfaceConnectSync(std::ofstream& stream,
- const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CONNECT_SYNC, "##",
- GetInterfaceIdWithNamespace(inf));
+// @see #CB_INTERFACE_METHOD_BASE
+void CProxyHeaderGen::GenInterfaceMethodBase(std::ofstream& stream,
+ const Interface& inf, const Declaration& decl) {
+ std::string code = ReplaceAll(CB_INTERFACE_METHOD_BASE, "<RETURN_TYPE>",
+ GetReturnTypeString(decl.GetType()));
+ code = ReplaceAll(code, "<PREFIX>", GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<METHOD_NAME>", decl.GetID());
+ code = ReplaceAll(code, "<METHOD_PARAMS>", GenMethodParams(inf, decl));
+
+ stream << SmartIndent(code);
}
} // namespace tidl
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
void OnFiniGen(std::ofstream& stream) override;
private:
- void GenInterfaces(std::ofstream& stream);
+ void GenInterfaceHandles(std::ofstream& stream);
+ void GenInterfaceHandle(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDelegateHandle(std::ofstream& stream, const Interface& inf,
+ const Declaration& decl);
- private:
+ void GenInterfaces(std::ofstream& stream);
void GenInterface(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDeclaration(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDelegators(std::ofstream& stream, const Interface& inf);
- void GenInterfaceMethods(std::ofstream& stream, const Interface& inf);
- void GenInterfaceCtor(std::ofstream& stream, const Interface& inf);
- void GenInterfaceConnect(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDtor(std::ofstream& stream, const Interface& inf);
- void GenInterfaceConnectSync(std::ofstream& stream, const Interface& inf);
- private:
- void GenInterfaceDelegator(std::ofstream& stream, const std::string& id,
- const Declaration& decl);
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& inf,
+ const Declaration& decl);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceMethodBase(std::ofstream& stream, const Interface& info,
+ const Declaration& decl);
+
+ std::string GenDelegateParams(const Interface& inf, const Declaration& decl);
+ std::string GenMethodParams(const Interface& inf, const Declaration& decl);
};
} // namespace tidl
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
#ifndef IDLC_C_GEN_C_PROXY_HEADER_GEN_CB_H_
#define IDLC_C_GEN_C_PROXY_HEADER_GEN_CB_H_
-const char CB_INTERFACE_DECL[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_HANDLE[] =
R"__c_cb(
-typedef struct ##_s *rpc_port_proxy_##_h;
-
-typedef struct {
- void (*connected)(rpc_port_proxy_##_h h, void *user_data);
- void (*disconnected)(rpc_port_proxy_##_h h, void *user_data);
- void (*rejected)(rpc_port_proxy_##_h h, void *user_data);
-} rpc_port_proxy_##_callback_s;
+/**
+ * @brief The <PREFIX>_<NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_s *<PREFIX>_<NAME>_h;
)__c_cb";
-const char CB_INTERFACE_CTOR[] =
+constexpr const char CB_INTERFACE_DELEGATE_HANDLE[] =
R"__c_cb(
-int rpc_port_proxy_##_create(const char *stub_appid,
- rpc_port_proxy_##_callback_s *callback, void *user_data,
- rpc_port_proxy_##_h *h);
+/**
+ * @brief The <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s *<PREFIX>_<NAME>_<DELEGATE_NAME>_h;
)__c_cb";
-const char CB_INTERFACE_CONNECT[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate.
+ * <DELEGATE_PARAMS> The parameters of the callback function.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
R"__c_cb(
-int rpc_port_proxy_##_connect(rpc_port_proxy_##_h h);
-)__c_cb";
+/**
+ * @brief Called when the event is received.
+ *
+ * @param[in] user_data The user data passed from the callback registration function
+ * @param[in] ...
+ *
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_create()
+ */
+typedef void (*<PREFIX>_<NAME>_<DELEGATE_NAME>_cb)(void *user_data<DELEGATE_PARAMS>);
-const char CB_INTERFACE_DTOR[] =
-R"__c_cb(
-int rpc_port_proxy_##_destroy(rpc_port_proxy_##_h h);
-)__c_cb";
+/**
+ * @brief Creates a <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[out] h The <PREFIX>_<NAME>_<DELEGATE_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 memorya
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose()
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_set_callback()
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_set_once()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h);
-const char CB_INTERFACE_METHODS[] =
-R"__c_cb(
-$$rpc_port_proxy_##_invoke_$$(rpc_port_proxy_##_h h$$);
-)__c_cb";
+/**
+ * @brief Destroys the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_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>_<DELEGATE_NAME>_create()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h);
-const char CB_INTERFACE_DELEGATOR[] =
-R"__c_cb(
-typedef $$(*$$)($$);
-)__c_cb";
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME>_<DELEGATE_NAME> should be released using
+ * the <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME>_<DELEGATE_NAME> handle will be returned
+ * @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
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone);
-const char CB_DELEGATE_CTOR[] =
-R"__c_cb(
-rpc_port_##_h rpc_port_##_create(## callback, bool once, void *user_data);
-)__c_cb";
+/**
+ * @brief Sets the callback function to the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[in] callback The callback function
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_callback(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_cb callback, void *user_data);
-const char CB_DELEGATE_DISPOSER[] =
-R"__c_cb(
-int rpc_port_proxy_##_dispose(rpc_port_proxy_$$_h proxy, rpc_port_##_h delegate);
+/**
+ * @brief Set the once flag to the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ * @details If the once flag is 'true', the delegate handle will be deleted after invocation.
+ * If the @a h handle is not used using the method, the handle should be released using
+ * the <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy() when it's no longer needed.
+ * If you don't want the delegate callback function to be called after it's used using the method,
+ * you should release the handle using the <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose().
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[in] once The flag if it's true, the delegate will be deleted after invocation
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool once);
+
+/**
+ * @brief Gets the ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] id The ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id);
+
+/**
+ * @brief Gets the sequence ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] seq_id The Sequence ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id);
+
+/**
+ * @brief Checks whether the delegate is for one-time or not.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] once The flag, it's true, the handle is for one-time
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once);
+
+/**
+ * @brief Gets the tag from the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks The @a tag should be released using free().
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] tag The tag
+ * @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
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag);
+
+/**
+ * @brief Disposes the <PREFIX>_<NAME>_<DELEGATE_NAME> handle from the <PREFIX>_<NAME> handle.
+ *
+ * @param[in] proxy The <PREFIX>_<NAME> handle
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_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>_<DELEGATE_NAME>_create()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_dispose(<PREFIX>_<NAME>_h proxy, <PREFIX>_<NAME>_<DELEGATE_NAME>_h h);
)__c_cb";
-const char CB_DELEGATE_DTOR[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
R"__c_cb(
-int rpc_port_##_destroy(rpc_port_##_h delegate);
+/**
+ * @brief Called when the proxy is connected.
+ * @details The callback function is called when the proxy is connected to the stub.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] user_data The user data passed from the registeration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_connected_cb)(<PREFIX>_<NAME>_h h, void *user_data);
+
+/**
+ * @brief Called when the proxy is disconnected.
+ * @details The callback function is called when the proxy is disconnected from the stub.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] user_data The user data passed from the registeration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_disconnected_cb)(<PREFIX>_<NAME>_h h, void *user_data);
+
+/**
+ * @brief Called when the proxy is rejected.
+ * @details The callback function is called when the proxy is rejected to connect to the stub.
+ *
+ * @param[in] h The <PREFIX>_<NAME> handle
+ * @param[in] user_data The user data passed from the registeration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_rejected_cb)(<PREFIX>_<NAME>_h h, void *user_data);
+
+/**
+ * @brief The structure type containing the set of callback functions for handling proxy events.
+ * @details It is one of the input parameters of the <PREFIX>_<NAME>_create() function.
+ *
+ * @see <PREFIX>_<NAME>_connected_cb
+ * @see <PREFIX>_<NAME>_disconnected_cb
+ * @see <PREFIX>_<NAME>_rejected_cb
+ */
+typedef struct {
+ <PREFIX>_<NAME>_connected_cb connected; /**< This callback function is called when the proxy is connected to the stub. */
+ <PREFIX>_<NAME>_disconnected_cb disconnected; /**< This callback function is called when the proxy is disconnected from the stub. */
+ <PREFIX>_<NAME>_rejected_cb rejected; /**< This callback function is called when the proxy is rejected to connect to the stub. */
+} <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] stub_appid The application ID of the stub
+ * @param[in] callback The set of callback functions to handle proxy 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
+ * @see <PREFIX>_<NAME>_destroy()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+int <PREFIX>_<NAME>_create(const char *stub_appid, <PREFIX>_<NAME>_callback_s *callback, void *user_data, <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);
+
+/**
+ * @brief Connects to the stub.
+ *
+ * @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
+ * @retval #RPC_PORT_ERROR_IO_ERROR I/O error
+ * @retval #RPC_PORT_ERROR_PERMISSION_DENIED Permission denied
+ */
+int <PREFIX>_<NAME>_connect(<PREFIX>_<NAME>_h h);
+
+/**
+ * @brief Connects to the stub synchronously.
+ *
+ * @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
+ * @retval #RPC_PORT_ERROR_IO_ERROR I/O error
+ * @retval #RPC_PORT_ERROR_PERMISSION_DENIED Permission denied
+ */
+int <PREFIX>_<NAME>_connect_sync(<PREFIX>_<NAME>_h h);
)__c_cb";
-const char CB_INTERFACE_CONNECT_SYNC[] =
+/**
+ * <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(
-int rpc_port_proxy_##_connect_sync(rpc_port_proxy_##_h h);
+/**
+ * @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_GEN_C_PROXY_HEADER_GEN_CB_H_
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
* limitations under the License.
*/
-#include "idlc/gen/c_stub_body_gen.h"
+#include <algorithm>
-namespace {
+#include "idlc/gen/c_stub_body_gen.h"
#include "idlc/gen/c_stub_body_gen_cb.h"
-}
namespace tidl {
CStubBodyGen::CStubBodyGen(std::shared_ptr<Document> doc,
std::shared_ptr<Options> options)
- : CBodyGeneratorBase(doc), options_(options) {}
+ : CBodyGeneratorBase(doc), options_(options) {
+}
void CStubBodyGen::OnInitGen(std::ofstream& stream) {
GenVersion(stream);
GenIncludeHeader(stream);
GenLogTag(stream, std::string("RPC_PORT_STUB"));
GenLogDefinition(stream);
- GenTypedefStubMethod(stream);
+ GenBaseDefinition(stream);
+ GenThreadEnableDefinition(stream);
+ GenInterfaceMethodHandlerType(stream);
+ GenInterfaceEnums(stream);
+ GenStructureDefs(stream);
+ GenInterfaceDefs(stream);
+ GenPrivateSharingListSet(stream);
GenStructures(stream);
GenInterfaces(stream);
}
-void CStubBodyGen::OnFiniGen(std::ofstream& stream) {}
+void CStubBodyGen::OnFiniGen(std::ofstream& stream) {
+}
-void CStubBodyGen::GenInterfaces(std::ofstream& stream) {
- for (auto& i : GetDocument().GetBlocks()) {
- if (i->GetType() != Block::TYPE_INTERFACE)
+// @see #CB_THREAD_ENABLE_DEF
+void CStubBodyGen::GenThreadEnableDefinition(std::ofstream& stream) {
+ if (!options_->IsThreadEnabled())
+ return;
+
+ stream << std::string(CB_THREAD_ENABLE_DEF);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_TYPE
+void CStubBodyGen::GenInterfaceMethodHandlerType(std::ofstream& stream) {
+ std::string code = ReplaceAll(CB_INTERFACE_METHOD_HANDLER_TYPE, "<PREFIX>",
+ GetHandlePrefix());
+
+ stream << SmartIndent(code);
+}
+
+void CStubBodyGen::GenInterfaceEnums(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
continue;
- const Interface &inf = static_cast<const Interface&>(*i);
- GenInterface(stream, inf);
+ auto& inf = static_cast<const Interface&>(*b);
+ GenInterfaceEnum(stream, inf);
}
}
-void CStubBodyGen::GenInterface(std::ofstream& stream, const Interface& inf) {
- GenInterfaceEnumerations(stream, inf);
- GenInterfaceGlobalVariables(stream, inf);
- GenInterfaceContext(stream, inf);
- GenInterfaceDelegators(stream, inf);
- GenInterfaceMethods(stream, inf);
- GenInterfaceMethodTable(stream, inf);
- GenInterfaceOnConnectedEventCB(stream, inf);
- GenInterfaceOnDisconnectedEventCB(stream, inf);
- GenInterfaceOnReceivedEventCB(stream, inf);
- GenInterfaceAddPrivileges(stream, inf);
- GenInterfaceRegister(stream, inf);
- GenInterfaceUnregister(stream, inf);
- GenInterfaceClientNumberGetter(stream, inf);
-}
-
-void CStubBodyGen::GenInterfaceMethods(std::ofstream& stream,
- const Interface& inf) {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+void CStubBodyGen::GenInterfaceEnum(std::ofstream& stream,
+ const Interface& inf) {
+ GenInterfaceMethodEnumBase(stream, inf);
+ GenInterfaceDelegateEnumBase(stream, inf);
+}
+
+// @see #CB_INTERFACE_METHOD_ENUM
+std::string CStubBodyGen::GenMethodEnums(const Interface& inf) {
+ std::string method_enum = ReplaceAll(CB_INTERFACE_METHOD_ENUM,
+ "<UPPERCASE_PREFIX>", GetHandlePrefix());
+ method_enum = ReplaceAll(method_enum, "<UPPERCASE_NAME>", inf.GetID());
+ method_enum = ReplaceAll(method_enum, "<UPPERCASE_METHOD_NAME>", "RESULT_");
+ std::string method_enums = RemoveLine(method_enum);
+
+ method_enum = ReplaceAll(CB_INTERFACE_METHOD_ENUM, "<UPPERCASE_PREFIX>",
+ GetHandlePrefix());
+ method_enum = ReplaceAll(method_enum, "<UPPERCASE_NAME>", inf.GetID());
+ method_enum = ReplaceAll(method_enum, "<UPPERCASE_METHOD_NAME>", "CALLBACK_");
+ method_enums += RemoveLine(method_enum);
+
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
- stream << SmartIndent(GenTemplateString(CB_INTERFACE_METHOD,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return GetMethodString(inf, *i);
- }));
+ method_enum = ReplaceAll(CB_INTERFACE_METHOD_ENUM, "<UPPERCASE_PREFIX>",
+ GetHandlePrefix());
+ method_enum = ReplaceAll(method_enum, "<UPPERCASE_NAME>", inf.GetID());
+ method_enum = ReplaceAll(method_enum, "<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 CStubBodyGen::GenInterfaceMethodTable(std::ofstream& stream,
- const Interface& inf) {
- std::string str;
- int cnt = 0;
+// @see #CB_INTERFACE_METHOD_ENUM_BASE
+void CStubBodyGen::GenInterfaceMethodEnumBase(std::ofstream& stream,
+ const Interface& inf) {
+ std::string code = ReplaceAll(CB_INTERFACE_METHOD_ENUM_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<METHOD_ENUMS>", GenMethodEnums(inf));
+
+ stream << SmartIndent(code);
+}
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+// @see #CB_INTERFACE_DELEGATE_ENUM
+std::string CStubBodyGen::GenDelegateEnums(const Interface& inf) {
+ unsigned int num = 1;
+ std::string method_enums;
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
continue;
- str += GenTemplateString(CB_INTERFACE_METHOD_FORMAT,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf) + "_METHOD_" + i->GetID();
- },
- [&]()->std::string {
- return "__" + GetInterfaceIdWithNamespace(inf) + "_method_"
- + i->GetID();
- });
- cnt++;
+
+ std::string method_enum = ReplaceAll(CB_INTERFACE_DELEGATE_ENUM,
+ "<UPPERCASE_PREFIX>", GetHandlePrefix());
+ method_enum = ReplaceAll(method_enum, "<UPPERCASE_NAME>", inf.GetID());
+ method_enum = ReplaceAll(method_enum, "<UPPERCASE_DELEGATE_NAME>",
+ d->GetID());
+ method_enum = ReplaceAll(method_enum, "<NUMBER>", std::to_string(num++));
+
+ method_enums += RemoveLine(method_enum);
}
+ std::transform(method_enums.begin(), method_enums.end(), method_enums.begin(),
+ ::toupper);
- if (cnt == 0)
- return;
+ return method_enums;
+}
+
+// @see #CB_INTERFACE_DELEGATE_ENUM_BASE
+void CStubBodyGen::GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& inf) {
+ std::string code = ReplaceAll(CB_INTERFACE_DELEGATE_ENUM_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<DELEGATE_ENUMS>", GenDelegateEnums(inf));
+
+ stream << SmartIndent(code);
+}
+
+void CStubBodyGen::GenInterfaceDefs(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
- stream << NLine(1);
- stream << SmartIndent(GenTemplateString(CB_INTERFACE_METHOD_TABLE,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- return str;
- }));
-}
-
-void CStubBodyGen::GenInterfaceOnConnectedEventCB(std::ofstream& stream,
- const Interface& inf) {
- if (options_->IsThreadEnabled()) {
- stream << SmartIndent(
- ReplaceAll(CB_INTERFACE_THREAD_METHODS, "##",
- GetInterfaceIdWithNamespace(inf)));
+ auto& inf = static_cast<const Interface&>(*b);
+ GenInterfaceDef(stream, inf);
}
+}
- stream << SmartIndent(
- ReplaceAll(CB_INTERFACE_ON_CONNECTED, "##",
- GetInterfaceIdWithNamespace(inf)));
+void CStubBodyGen::GenInterfaceDef(std::ofstream& stream,
+ const Interface& inf) {
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateDef(stream, inf, *d);
+ }
+
+ GenInterfaceContextDef(stream, inf);
+ GenInterfaceBaseDef(stream, inf);
}
-void CStubBodyGen::GenInterfaceOnDisconnectedEventCB(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(
- ReplaceAll(CB_INTERFACE_ON_DISCONNECTED, "##",
- GetInterfaceIdWithNamespace(inf)));
+// @see #CB_INTERFACE_DELEGATE_DEF
+void CStubBodyGen::GenInterfaceDelegateDef(std::ofstream& stream,
+ const Interface& inf, const Declaration& decl) {
+ std::string code = ReplaceAll(CB_INTERFACE_DELEGATE_DEF, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<DELEGATE_NAME>", decl.GetID());
+
+ stream << SmartIndent(code);
}
-void CStubBodyGen::GenInterfaceOnReceivedEventCB(std::ofstream& stream,
- const Interface& inf) {
- if (options_->IsThreadEnabled()) {
- stream << SmartIndent(
- ReplaceAll(CB_INTERFACE_THREAD_ON_RECEIVED, "##",
- GetInterfaceIdWithNamespace(inf)));
- } else {
- stream << SmartIndent(
- ReplaceAll(CB_INTERFACE_ON_RECEIVED, "##",
- GetInterfaceIdWithNamespace(inf)));
+// @see #CB_INTERFACE_CONTEXT_DEF
+void CStubBodyGen::GenInterfaceContextDef(std::ofstream& stream,
+ const Interface& inf) {
+ std::string code = ReplaceAll(CB_INTERFACE_CONTEXT_DEF, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_BASE_DEF
+void CStubBodyGen::GenInterfaceBaseDef(std::ofstream& stream,
+ const Interface& inf) {
+ std::string code = ReplaceAll(CB_INTERFACE_BASE_DEF, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+
+ stream << SmartIndent(code);
+}
+
+void CStubBodyGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ const Interface &inf = static_cast<const Interface&>(*i);
+ GenInterface(stream, inf);
}
}
-void CStubBodyGen::GenInterfaceRegister(std::ofstream& stream,
- const Interface& inf) {
- std::string r_str = ReplaceAll(CB_INTERFACE_REGISTER, "##",
- GetInterfaceIdWithNamespace(inf));
-
- stream << SmartIndent(GenTemplateString(r_str,
- [&]()->std::string {
- if (options_->IsThreadEnabled())
- return CB_INTERFACE_THREAD_CREATE;
- return "";
- }));
-}
-
-void CStubBodyGen::GenInterfaceUnregister(std::ofstream& stream,
- const Interface& inf) {
- std::string r_str = ReplaceAll(CB_INTERFACE_UNREGISTER, "##",
- GetInterfaceIdWithNamespace(inf));
-
- stream << SmartIndent(GenTemplateString(r_str,
- [&]()->std::string {
- if (options_->IsThreadEnabled())
- return "job_h job;";
- return "";
- },
- [&]()->std::string {
- if (options_->IsThreadEnabled())
- return CB_INTERFACE_THREAD_DESTROY;
- return "";
- }));
-}
-
-void CStubBodyGen::GenInterfaceGlobalVariables(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_GLOBALS, "##",
- GetInterfaceIdWithNamespace(inf)));
-}
-
-std::string CStubBodyGen::GetMethodString(const Interface& inf,
- const Declaration& decl) {
- std::string str;
- const char port_setter[] = "rpc_port_$$_set_port($$, callback_port);\n";
- const char setter[] = "$$($$, $$);\n";
- const char do_while_block[] =
- "do {\n" \
- " rpc_port_parcel_h result;\n" \
- "\n" \
- " rpc_port_parcel_create(&result);\n" \
- " rpc_port_parcel_write_int32(result, $$_METHOD_Result);\n" \
- "$$" \
- " r = rpc_port_parcel_send(result, port);\n" \
- " rpc_port_parcel_destroy(result);\n" \
- "} while (0);\n";
- const char ternary_operation[] = "## ? ## : \"\"";
- int cnt = 0;
- for (auto& i : decl.GetParameters().GetParams()) {
- if (IsDelegateType(inf, i->GetParameterType().GetBaseType())) {
- str += "rpc_port_" + GetInterfaceIdWithNamespace(inf) + "_" +
- i->GetParameterType().GetBaseType().ToString() + "_h " +
- i->GetID() + " = NULL;" + NLine(1);
- } else if (i->GetParameterType().GetBaseType().IsUserDefinedType() ||
- i->GetParameterType().GetBaseType().ToString() == "list" ||
- i->GetParameterType().GetBaseType().ToString() == "array") {
- str += GetReturnTypeString(i->GetParameterType().GetBaseType()) +
- i->GetID() + " = NULL;" + NLine(1);
- } else {
- str += GetReturnTypeString(i->GetParameterType().GetBaseType()) +
- i->GetID() + ";" + NLine(1);
- }
- if (i->GetParameterType().GetDirection() == ParameterType::Direction::IN)
- cnt++;
+void CStubBodyGen::GenInterface(std::ofstream& stream, const Interface& inf) {
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateBase(stream, inf, *d);
}
- str += NLine(1);
- for (auto& i : decl.GetParameters().GetParams()) {
- if (i->GetParameterType().GetDirection() != ParameterType::Direction::IN)
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
- if (i->GetParameterType().GetBaseType().IsUserDefinedType() ||
- i->GetParameterType().GetBaseType().ToString() == "list" ||
- i->GetParameterType().GetBaseType().ToString() == "array") {
- if (IsDelegateType(inf, i->GetParameterType().GetBaseType())) {
- str += "rpc_port_" + GetInterfaceIdWithNamespace(inf) + "_" +
- i->GetParameterType().GetBaseType().ToString() +
- "_create(&" + i->GetID() + ");" + NLine(1);
- str += "\nif (!" + i->GetID() + ") {\n";
- str += " _E(\"Failed to create handle\");\n";
- str += " return -1;\n";
- str += "}\n\n";
- str += GenTemplateString(port_setter,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf) + "_" +
- i->GetParameterType().GetBaseType().ToString();
- },
- [&]()->std::string {
- return i->GetID();
- });
- } else {
- str += GetConstructorString(i->GetParameterType().GetBaseType(),
- i->GetID());
- }
- }
+ GenInterfaceMethodHandlerBase(stream, inf, *d);
+ }
+
+ GenInterfaceMethodTable(stream, inf);
+ GenInterfaceContextBase(stream, inf);
+ GenInterfaceBase(stream, inf);
+}
+
+// @see #CB_INTERFACE_CONTEXT_BASE
+void CStubBodyGen::GenInterfaceContextBase(std::ofstream& stream,
+ const Interface& inf) {
+ std::string code = ReplaceAll(CB_INTERFACE_CONTEXT_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
- str += GenTemplateString(setter,
- [&]()->std::string {
- return GetParcelReadFunctionString(
- i->GetParameterType().GetBaseType(), true);
- },
- [&]()->std::string {
- return "parcel";
- },
- [&]()->std::string {
- if (i->GetParameterType().GetBaseType().IsUserDefinedType() ||
- i->GetParameterType().GetBaseType().ToString() == "list" ||
- i->GetParameterType().GetBaseType().ToString() == "array")
- return "&" + i->GetID() + "->parcelable, " + i->GetID();
- return "&" + i->GetID();
- });
+ stream << SmartIndent(code);
+}
+
+std::string CStubBodyGen::GenDelegateParams(const Interface& inf,
+ const Declaration& decl) {
+ std::string params;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, inf) +
+ p->GetID();
}
- if (cnt > 0)
- str += NLine(1);
+ return params;
+}
+
+std::string CStubBodyGen::GenDelegateParamsCheck(const Interface& inf,
+ const Declaration& decl) {
+ std::string params_check;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(inf, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array" ||
+ type.ToString() == "bundle" ||
+ type.ToString() == "string" ||
+ type.ToString() == "file")
+ params_check += " || " + p->GetID() + " == nullptr";
+ }
- if (decl.GetMethodType() == Declaration::MethodType::SYNC &&
- decl.GetType().ToString() != "void") {
- str += GetReturnTypeString(decl.GetType()) + "ret = ";
+ return params_check;
+}
+
+// @see #CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_WRITE
+// @see #CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_WRITE
+// @see #CB_INTERFACE_DELEGATE_STRING_PARCEL_WRITE
+// @see #CB_INTERFACE_DELEGATE_BASE_PARCEL_WRITE
+std::string CStubBodyGen::GenDelegateParcelWrite(const Interface& inf,
+ const Declaration& decl) {
+ std::string code;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ std::string parcel_write_code;
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(inf, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_INTERFACE_DELEGATE_USER_DEFINED_PARCEL_WRITE, "<ARG>",
+ p->GetID());
+ parcel_write_code += GetPrivateSharingString(type, inf, "h->port",
+ p->GetID());
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_DELEGATE_BUNDLE_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_DELEGATE_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_DELEGATE_STRING_PARCEL_WRITE,
+ "<ARG>", p->GetID());
+ parcel_write_code += GetPrivateSharingString(type, inf, "h->port",
+ p->GetID());
+ } else {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_DELEGATE_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ARG>", p->GetID());
+ }
+
+ code += parcel_write_code;
}
- str += "context->callback." + decl.GetID() + "(context";
- for (auto& i : decl.GetParameters().GetParams()) {
- str += ", ";
- if (i->GetParameterType().GetDirection() != ParameterType::Direction::IN)
- str += "&" + i->GetID();
- else
- str += i->GetID();
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_DELEGATE_BASE
+void CStubBodyGen::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& inf, const Declaration& decl) {
+ std::string code = ReplaceAll(CB_INTERFACE_DELEGATE_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<DELEGATE_NAME>", decl.GetID());
+ code = ReplaceAll(code, "<DELEGATE_PARAMS>", GenDelegateParams(inf, decl));
+ code = ReplaceAll(code, "<DELEGATE_PARAMS_CHECK>",
+ GenDelegateParamsCheck(inf, decl));
+
+ std::string enum_value = GetHandlePrefix() + "_" + inf.GetID() +
+ "_DELEGATE_" + decl.GetID();
+ std::transform(enum_value.begin(), enum_value.end(), enum_value.begin(),
+ ::toupper);
+ code = ReplaceAll(code, "<DELEGATE_ENUM_VALUE>", enum_value);
+ code = ReplaceAll(code, "<DELEGATE_PARCEL_WRITE>",
+ GenDelegateParcelWrite(inf, decl));
+
+ stream << SmartIndent(code);
+}
+
+std::string CStubBodyGen::GenMethodHandlerArgsDecl(const Interface& inf,
+ const Declaration& decl) {
+ std::string args_decl;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ args_decl += GetArgTypeString(type, inf) + p->GetID() + " = " +
+ GetErrorValue(type) + ";" + NLine(1);
}
- str += ", context->user_data);" + NLine(1);
+
if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
- str += GenTemplateString(do_while_block,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- std::string s;
- for (auto& i : decl.GetParameters().GetParams()) {
- if (i->GetParameterType().GetDirection() ==
- ParameterType::Direction::IN)
- continue;
- s += GenTemplateString(setter,
- [&]()->std::string {
- return GetParcelWriteFunctionString(
- i->GetParameterType().GetBaseType(), true);
- },
- [&]()->std::string {
- return "result";
- },
- [&]()->std::string {
- auto& t = i->GetParameterType().GetBaseType();
- if (t.IsUserDefinedType() || t.ToString() == "list" ||
- t.ToString() == "array")
- return "&" + i->GetID() + "->parcelable, " + i->GetID();
- else if (t.ToString() == "string" || t.ToString() == "file")
- return ReplaceAll(ternary_operation, "##", i->GetID());
- return i->GetID();
- });
- }
- if (decl.GetType().ToString() != "void") {
- s += GenTemplateString(setter,
- [&]()->std::string {
- return GetParcelWriteFunctionString(decl.GetType(), true);
- },
- [&]()->std::string {
- return "result";
- },
- [&]()->std::string {
- if (decl.GetType().IsUserDefinedType() ||
- decl.GetType().ToString() == "list" ||
- decl.GetType().ToString() == "array")
- return "&ret->parcelable, ret";
- else if (decl.GetType().ToString() == "string" ||
- decl.GetType().ToString() == "file")
- return ReplaceAll(ternary_operation, "##", "ret");
- return "ret";
- });
- }
- return s;
- });
- }
+ args_decl += "rpc_port_parcel_h parcel_;" + NLine(1);
+ args_decl += GetArgTypeString(decl.GetType(), inf) + "res_ = " +
+ GetErrorValue(decl.GetType()) + ";" + NLine(1);
+ }
- for (auto& i : decl.GetParameters().GetParams()) {
- str += NLine(1);
- if (IsDelegateType(inf, i->GetParameterType().GetBaseType())) {
- str += "rpc_port_" + GetInterfaceIdWithNamespace(inf) + "_" +
- i->GetParameterType().GetBaseType().ToString() +
- "_destroy(" + i->GetID() + ");";
+ return args_decl;
+}
+
+// @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 CStubBodyGen::GenMethodHandlerParcelRead(const Interface& inf,
+ const Declaration& decl) {
+ std::string code;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ std::string parcel_read_code;
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(inf, type)) {
+ parcel_read_code = ReplaceAll(
+ CB_INTERFACE_METHOD_DELEGATE_PARCEL_READ, "<PREFIX>",
+ GetHandlePrefix());
+ parcel_read_code = ReplaceAll(parcel_read_code, "<NAME>",
+ GetFullNameFromType(type, inf));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
+ } else 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, inf));
+ 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" || type.ToString() == "file") {
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_READ,
+ "<ARG>", p->GetID());
} else {
- str += GetDestructorString(i->GetParameterType().GetBaseType(),
- i->GetID());
+ parcel_read_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_READ,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_read_code = ReplaceAll(parcel_read_code, "<ARG>", p->GetID());
}
- }
- str += GetDestructorString(decl.GetType(), "ret");
+ code += parcel_read_code;
+ }
- return str;
+ return RemoveLine(code);
}
-std::string CStubBodyGen::GetAddPrivilegeString(const std::string& id,
- const Attribute& attr) {
- std::string str;
+// @see #CB_INTERFACE_METHOD_CALLBACK_INVOKE
+std::string CStubBodyGen::GenMethodHandlerCallbackInvoke(
+ const Declaration& decl) {
+ std::string code = ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_INVOKE,
+ "<METHOD_NAME>", decl.GetID());
- str += GenTemplateString(CB_INTERFACE_PRIVILEGE_BLOCK,
- [&]()->std::string {
- return "rpc_port_stub_add_privilege(__" + id +
- "_stub, \"" + attr.GetValue() + "\")";
- },
- [&]()->std::string {
- return attr.GetValue();
- });
- return str;
-}
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC)
+ code = ReplaceAll(code, "<RES_SET>", "res_ = ");
+ else
+ code = ReplaceAll(code, "<RES_SET>", "");
-std::string CStubBodyGen::GetTrustedModeString(const std::string& id,
- const Attribute& attr) {
- std::string str;
+ std::string args;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ args += ", ";
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ args += "&";
- str += GenTemplateString(CB_INTERFACE_TRUSTED_MODE_BLOCK,
- [&]()->std::string {
- return "rpc_port_stub_set_trusted(__" + id +
- "_stub, " + attr.GetValue() + ")";
- },
- [&]()->std::string {
- return attr.GetValue();
- });
- return str;
-}
+ args += p->GetID();
+ }
+ code = ReplaceAll(code, "<METHOD_ARGS>", args);
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_PARCEL_WRITE_PRE
+// @see #CB_INTERFACE_METHOD_PARCEL_WRITE_POST
+// @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 CStubBodyGen::GenMethodHandlerParcelWrite(const Interface& inf,
+ const Declaration& decl) {
+ std::string code;
+ if (decl.GetMethodType() != Declaration::MethodType::SYNC)
+ return code;
+
+ std::string name = inf.GetID();
+ std::transform(name.begin(), name.end(), name.begin(), ::toupper);
+ code = ReplaceAll(CB_INTERFACE_METHOD_PARCEL_WRITE_PRE, "<UPPERCASE_NAME>",
+ name);
+
+ std::string parcel_write_code;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() == ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(inf, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE, "<ARG>",
+ p->GetID());
+ parcel_write_code += GetPrivateSharingString(type, inf, "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, inf, "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;
+ }
-void CStubBodyGen::GenInterfaceDelegators(std::ofstream& stream,
- const Interface& inf) {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ auto& type = decl.GetType();
+ if (IsDelegateType(inf, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ parcel_write_code = ReplaceAll(
+ CB_INTERFACE_METHOD_USER_DEFINED_PARCEL_WRITE, "<ARG>", "res_");
+ parcel_write_code += GetPrivateSharingString(type, inf, "port", "res_");
+ } else if (type.ToString() == "bundle") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE,
+ "<ARG>", "res_");
+ } else if (type.ToString() == "string") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", "res_");
+ } else if (type.ToString() == "file") {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_PARCEL_WRITE,
+ "<ARG>", "res_");
+ parcel_write_code += GetPrivateSharingString(type, inf, "port", "res_");
+ } else {
+ parcel_write_code = ReplaceAll(CB_INTERFACE_METHOD_BASE_PARCEL_WRITE,
+ "<PARCEL_TYPE>", GetParcelType(type));
+ parcel_write_code = ReplaceAll(parcel_write_code, "<ARG>", "res_");
+ }
+
+ code += parcel_write_code;
+ code += std::string(CB_INTERFACE_METHOD_PARCEL_WRITE_POST);
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_USER_DEFINED_FREE
+// @see #CB_INTERFACE_METHOD_BUNDLE_FREE
+// @see #CB_INTERFACE_METHOD_STRING_FREE
+std::string CStubBodyGen::GenMethodHandlerArgsFree(const Interface& inf,
+ const Declaration& decl) {
+ std::string free_code;
+ std::string code;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (IsDelegateType(inf, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_FREE,
+ "<PREFIX>", GetHandlePrefix());
+ free_code = ReplaceAll(free_code, "<NAME>",
+ GetFullNameFromType(type, inf));
+ free_code = ReplaceAll(free_code, "<ARG>", p->GetID());
+ } else if (type.ToString() == "bundle") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE,
+ "<ARG>", p->GetID());
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE,
+ "<ARG>", p->GetID());
+ } else {
+ free_code.clear();
+ }
+
+ code += free_code;
+ }
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC) {
+ auto& type = decl.GetType();
+ if (IsDelegateType(inf, type) ||
+ type.IsUserDefinedType() ||
+ type.ToString() == "list" ||
+ type.ToString() == "array") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_USER_DEFINED_FREE,
+ "<PREFIX>", GetHandlePrefix());
+ free_code = ReplaceAll(free_code, "<NAME>",
+ GetFullNameFromType(type, inf));
+ free_code = ReplaceAll(free_code, "<ARG>", "res_");
+ } else if (type.ToString() == "bundle") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_BUNDLE_FREE,
+ "<ARG>", "res_");
+ } else if (type.ToString() == "string" || type.ToString() == "file") {
+ free_code = ReplaceAll(CB_INTERFACE_METHOD_STRING_FREE,
+ "<ARG>", "res_");
+ } else {
+ free_code.clear();
+ }
+
+ code += free_code;
+ }
+
+ return RemoveLine(code);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER_BASE
+void CStubBodyGen::GenInterfaceMethodHandlerBase(std::ofstream& stream,
+ const Interface& inf, const Declaration& decl) {
+ std::string code = ReplaceAll(CB_INTERFACE_METHOD_HANDLER_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<METHOD_NAME>", decl.GetID());
+ code = ReplaceAll(code, "<METHOD_HANDLER_ARGS_DECL>",
+ GenMethodHandlerArgsDecl(inf, decl));
+ code = ReplaceAll(code, "<METHOD_HANDLER_PARCEL_READ>",
+ GenMethodHandlerParcelRead(inf, decl));
+ code = ReplaceAll(code, "<METHOD_HANDLER_CALLBACK_INVOKE>",
+ GenMethodHandlerCallbackInvoke(decl));
+ code = ReplaceAll(code, "<METHOD_HANDLER_PARCEL_WRITE>",
+ GenMethodHandlerParcelWrite(inf, decl));
+ code = ReplaceAll(code, "<METHOD_HANDLER_ARGS_FREE>",
+ GenMethodHandlerArgsFree(inf, decl));
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_METHOD_HANDLER
+std::string CStubBodyGen::GenMethodHandlers(const Interface& inf) {
+ std::string code;
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
continue;
- GenInterfaceDelegator(stream, GetInterfaceIdWithNamespace(inf), *i);
+
+ std::string enum_value = GetHandlePrefix() + "_" + inf.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);
+ method_handler = ReplaceAll(method_handler, "<PREFIX>", GetHandlePrefix());
+ method_handler = ReplaceAll(method_handler, "<NAME>", inf.GetID());
+ method_handler = ReplaceAll(method_handler, "<METHOD_NAME>", d->GetID());
+
+ code += RemoveLine(method_handler);
}
+
+ return code;
}
-void CStubBodyGen::GenInterfaceDelegator(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- GenInterfaceDelegatorDeclaration(stream, id, decl);
- GenInterfaceDelegatorSerializer(stream, id, decl);
- GenInterfaceDelegatorDeserializer(stream, id, decl);
- GenInterfaceDelegatorConstructor(stream, id, decl);
- GenInterfaceDelegatorDestructor(stream, id, decl);
- GenInterfaceDelegatorCloner(stream, id, decl);
- GenInterfaceDelegatorInvoker(stream, id, decl);
- GenInterfaceDelegatorPortSetter(stream, id, decl);
-}
-
-void CStubBodyGen::GenInterfaceDelegatorDeclaration(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- stream << SmartIndent(GenTemplateString(CB_INTERFACE_DELEGATOR_DECL,
- [&]()->std::string {
- return id + "_" + decl.GetID();
- }));
-}
-
-void CStubBodyGen::GenInterfaceDelegatorConstructor(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_INTERFACE_DELEGATOR_CTOR, "##", id + "_" + decl.GetID()),
- [&]()->std::string {
- return id;
- },
- [&]()->std::string {
- return decl.GetID();
- }));
-}
-
-void CStubBodyGen::GenInterfaceDelegatorDestructor(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- stream << SmartIndent(
- ReplaceAll(CB_INTERFACE_DELEGATOR_DTOR, "##", id + "_" + decl.GetID()));
-}
-
-void CStubBodyGen::GenInterfaceDelegatorSerializer(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_DELEGATOR_SERIALIZER, "##", id + "_" + decl.GetID()));
-}
-
-void CStubBodyGen::GenInterfaceDelegatorDeserializer(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_DELEGATOR_DESERIALIZER, "##", id + "_" + decl.GetID()));
-}
-
-void CStubBodyGen::GenInterfaceDelegatorCloner(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_DELEGATOR_CLONER, "##", id + "_" + decl.GetID()));
-}
-
-void CStubBodyGen::GenInterfaceDelegatorInvoker(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- const char parcel[] = "$$(parcel, $$);\n";
- const char ternary_operation[] = "## ? ## : \"\"";
- stream << SmartIndent(GenTemplateString(CB_INTERFACE_DELEGATOR_INVOKER,
- [&]()->std::string {
- return id + "_" + decl.GetID();
- },
- [&]()->std::string {
- std::string str;
- str += "rpc_port_" + id + "_" + decl.GetID() + "_h h";
- for (auto& i : decl.GetParameters().GetParams()) {
- str += ", ";
- str += GetParamTypeString(i->GetParameterType().GetDirection(),
- i->GetParameterType().GetBaseType()) + i->GetID();
- }
- return str;
- },
- [&]()->std::string {
- return id;
- },
- [&]()->std::string {
- std::string str;
- for (auto& i : decl.GetParameters().GetParams()) {
- str += GenTemplateString(parcel,
- [&]()->std::string {
- return GetParcelWriteFunctionString(
- i->GetParameterType().GetBaseType(), true);
- },
- [&]()->std::string {
- auto& t = i->GetParameterType().GetBaseType();
- if (t.IsUserDefinedType() || t.ToString() == "list" ||
- t.ToString() == "array")
- return "&" + i->GetID() + "->parcelable, " + i->GetID();
- else if (t.ToString() == "string" || t.ToString() == "file")
- return ReplaceAll(ternary_operation, "##", i->GetID());
- return i->GetID();
- });
- }
- return str;
- }));
-}
-
-void CStubBodyGen::GenInterfaceDelegatorPortSetter(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_DELEGATOR_PORT_SETTER, "##", id + "_" + decl.GetID()));
-}
-
-void CStubBodyGen::GenInterfaceContext(std::ofstream& stream,
- const Interface& inf) {
- GenInterfaceContextDeclaration(stream, inf);
- GenInterfaceContextConstructor(stream, inf);
- GenInterfaceContextDestructor(stream, inf);
- GenInterfaceContextFinder(stream, inf);
- GenInterfaceContextTagSetter(stream, inf);
- GenInterfaceContextTagGetter(stream, inf);
- GenInterfaceContextSenderGetter(stream, inf);
-}
-
-void CStubBodyGen::GenInterfaceContextDeclaration(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_INTERFACE_CONTEXT_DECL, "##",
- GetInterfaceIdWithNamespace(inf)),
- [&]()->std::string {
- if (options_->IsThreadEnabled())
- return std::string(CB_INTERFACE_CONTEXT_DECL_THREAD_ELEM);
- return "";
- }));
-
- if (options_->IsThreadEnabled()) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_THREAD_FEATURE, "##", GetInterfaceIdWithNamespace(inf)));
+// @see #CB_INTERFACE_METHOD_TABLE
+void CStubBodyGen::GenInterfaceMethodTable(std::ofstream& stream,
+ const Interface& inf) {
+ std::string code = ReplaceAll(CB_INTERFACE_METHOD_TABLE, "<NAME>",
+ inf.GetID());
+ code = ReplaceAll(code, "<METHOD_HANDLERS>", GenMethodHandlers(inf));
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_PRIVILEGE_ADD
+// @see #CB_INTERFACE_TRUSTED_SET
+std::string CStubBodyGen::GenAccessControlSet(const Interface& inf) {
+ std::string code;
+ for (auto& attr : inf.GetAttributes().GetAttrs()) {
+ if (attr->GetKey() == "privilege") {
+ std::string privilege_add = ReplaceAll(CB_INTERFACE_PRIVILEGE_ADD,
+ "<NAME>", inf.GetID());
+ privilege_add = ReplaceAll(privilege_add, "<PRIVILEGE>",
+ attr->GetValue());
+
+ code += privilege_add;
+ } else if (attr->GetKey() == "trusted" && attr->GetValue() == "true") {
+ std::string trusted_set = ReplaceAll(CB_INTERFACE_TRUSTED_SET,
+ "<NAME>", inf.GetID());
+
+ code += trusted_set;
+ }
}
+
+ return RemoveLine(code);
}
-void CStubBodyGen::GenInterfaceContextConstructor(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_INTERFACE_CONTEXT_CTOR, "##",
- GetInterfaceIdWithNamespace(inf)),
- [&]()->std::string {
- if (options_->IsThreadEnabled())
- return std::string(CB_INTERFACE_CONTEXT_CTOR_THREAD_IMPL);
- return "";
- }));
-}
-
-void CStubBodyGen::GenInterfaceContextDestructor(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(GenTemplateString(
- ReplaceAll(CB_INTERFACE_CONTEXT_DTOR, "##",
- GetInterfaceIdWithNamespace(inf)),
- [&]()->std::string {
- if (options_->IsThreadEnabled())
- return std::string(CB_INTERFACE_CONTEXT_DTOR_THREAD_VARS);
- return "";
- },
- [&]()->std::string {
- if (options_->IsThreadEnabled())
- return std::string(CB_INTERFACE_CONTEXT_DTOR_THREAD_IMPL);
- return "";
- }));
-}
-
-void CStubBodyGen::GenInterfaceContextFinder(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_CONTEXT_FINDER, "##", GetInterfaceIdWithNamespace(inf)));
-}
-
-void CStubBodyGen::GenInterfaceContextTagSetter(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_CONTEXT_TAG_SETTER, "##", GetInterfaceIdWithNamespace(inf)));
-}
-
-void CStubBodyGen::GenInterfaceContextTagGetter(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_CONTEXT_TAG_GETTER, "##", GetInterfaceIdWithNamespace(inf)));
-}
-
-void CStubBodyGen::GenInterfaceContextSenderGetter(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(
- CB_INTERFACE_CONTEXT_GET_SENDER, "##", GetInterfaceIdWithNamespace(inf)));
-}
-
-void CStubBodyGen::GenTypedefStubMethod(std::ofstream& stream) {
- stream << CB_STUB_METHOD_TYPE;
-}
-
-void CStubBodyGen::GenInterfaceAddPrivileges(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(GenTemplateString(CB_INTERFACE_ADD_PRIVILEGE,
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- std::string str;
- for (auto& a : inf.GetAttributes().GetAttrs()) {
- if (a->GetKey() == "privilege") {
- str += GetAddPrivilegeString(
- GetInterfaceIdWithNamespace(inf), *a);
- str += NLine(1);
- } else if (a->GetKey() == "trusted" && a->GetValue() == "true") {
- str += GetTrustedModeString(GetInterfaceIdWithNamespace(inf), *a);
- str += NLine(1);
- }
- }
-
- if (!str.empty())
- str = SmartIndent("int r;\n\n") + str;
- return str;
- }));
-}
-
-void CStubBodyGen::GenInterfaceClientNumberGetter(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(ReplaceAll(CB_INTERFACE_CLIENT_NUMBER_GETTER, "##",
- GetInterfaceIdWithNamespace(inf)));
+// @see #CB_INTERFACE_BASE
+void CStubBodyGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& inf) {
+ std::string code = ReplaceAll(CB_INTERFACE_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<ACCESS_CONTROL_SET>", GenAccessControlSet(inf));
+
+ stream << SmartIndent(code);
}
} // namespace tidl
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
void OnFiniGen(std::ofstream& stream) override;
private:
+ void GenThreadEnableDefinition(std::ofstream& stream);
+ void GenInterfaceMethodHandlerType(std::ofstream& stream);
+ void GenInterfaceEnums(std::ofstream& stream);
+ void GenInterfaceEnum(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceMethodEnumBase(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDelegateEnumBase(std::ofstream& stream,
+ const Interface& inf);
+
+ void GenInterfaceDefs(std::ofstream& stream);
+ void GenInterfaceDef(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceContextDef(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDelegateDef(std::ofstream& stream, const Interface& inf,
+ const Declaration& decl);
+ void GenInterfaceBaseDef(std::ofstream& stream, const Interface& inf);
+
void GenInterfaces(std::ofstream& stream);
void GenInterface(std::ofstream& stream, const Interface& inf);
- void GenTypedefStubMethod(std::ofstream& stream);
- void GenInterfaceMethods(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceContextBase(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& inf,
+ const Declaration& decl);
+ void GenInterfaceMethodHandlerBase(std::ofstream& stream,
+ const Interface& inf, const Declaration& decl);
void GenInterfaceMethodTable(std::ofstream& stream, const Interface& inf);
- void GenInterfaceOnConnectedEventCB(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceOnDisconnectedEventCB(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceOnReceivedEventCB(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceRegister(std::ofstream& stream, const Interface& inf);
- void GenInterfaceUnregister(std::ofstream& stream, const Interface& inf);
- void GenInterfaceGlobalVariables(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDelegators(std::ofstream& stream, const Interface& inf);
- void GenInterfaceContext(std::ofstream& stream, const Interface& inf);
- void GenInterfaceAddPrivileges(std::ofstream& stream, const Interface& inf);
- void GenInterfaceClientNumberGetter(std::ofstream& stream,
- const Interface& inf);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& inf);
- private:
- void GenInterfaceContextDeclaration(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextConstructor(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextDestructor(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextFinder(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextTagSetter(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextTagGetter(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextSenderGetter(std::ofstream& stream,
- const Interface& inf);
+ std::string GenMethodEnums(const Interface& inf);
+ std::string GenDelegateEnums(const Interface& inf);
- private:
- void GenInterfaceDelegator(std::ofstream& stream, const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDeclaration(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorConstructor(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDestructor(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorSerializer(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDeserializer(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorCloner(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorInvoker(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorPortSetter(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
+ std::string GenDelegateParams(const Interface& inf, const Declaration& decl);
+ std::string GenDelegateParamsCheck(const Interface& inf,
+ const Declaration& decl);
+ std::string GenDelegateParcelWrite(const Interface& inf,
+ const Declaration& decl);
- private:
- std::string GetMethodString(const Interface& id, const Declaration& decl);
- std::string GetAddEventCBString(const std::string& id);
- std::string GetAddPrivilegeString(const std::string& id,
- const Attribute& attr);
- std::string GetTrustedModeString(const std::string& id,
- const Attribute& attr);
+ std::string GenMethodHandlerArgsDecl(const Interface& inf,
+ const Declaration& decl);
+ std::string GenMethodHandlerParcelRead(const Interface& inf,
+ const Declaration& decl);
+ std::string GenMethodHandlerCallbackInvoke(const Declaration& decl);
+ std::string GenMethodHandlerParcelWrite(const Interface& inf,
+ const Declaration& decl);
+ std::string GenMethodHandlerArgsFree(const Interface& inf,
+ const Declaration& decl);
+ std::string GenMethodHandlers(const Interface& inf);
+ std::string GenAccessControlSet(const Interface& inf);
private:
std::shared_ptr<Options> options_;
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
#ifndef IDLC_C_GEN_C_STUB_BODY_GEN_CB_H_
#define IDLC_C_GEN_C_STUB_BODY_GEN_CB_H_
-const char CB_INTERFACE_METHOD[] =
+constexpr const char CB_THREAD_ENABLE_DEF[] =
R"__c_cb(
-static int __$$_method_$$(rpc_port_h port, rpc_port_parcel_h parcel, void *data)
-{
- rpc_port_stub_$$_context_h context = data;
- rpc_port_h callback_port;
- int r;
+#define TIDL_THREAD_ENABLE 1
+)__c_cb";
- r = rpc_port_stub_get_port(__$$_stub, RPC_PORT_PORT_CALLBACK, context->instance, &callback_port);
- if (r != 0) {
- _E("Failed to get callback port");
- return -1;
- }
+/**
+ * <PREFIX> The prefix of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_HANDLER_TYPE[] =
+R"__c_cb(
+typedef int (*<PREFIX>_method_handler)(rpc_port_h port, rpc_port_parcel_h parcel, void *data);
+)__c_cb";
-$$
- return r;
-}
+/**
+ * <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";
-const char CB_INTERFACE_METHOD_TABLE[] =
-R"__c_cb(static stub_method __$$_method_table[] = {$$
-};
+/**
+ * <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";
-const char CB_INTERFACE_METHOD_FORMAT[] =
+/**
+ * <DELEGATE_ENUMS> The enumeration declarations of deleagtes.
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_ENUM_BASE[] =
R"__c_cb(
-[$$] = $$,)__c_cb";
+typedef enum {
+ <DELEGATE_ENUMS>
+} <PREFIX>_<NAME>_delegate_e;
+)__c_cb";
-const char CB_INTERFACE_THREAD_METHODS[] =
+/**
+ * <UPPERCASE_PREFIX> The uppercase prefix of the interface.
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ * <UPPERCASE_DELEGATE_NAME> The uppercase delegate name of the interface.
+ * <NUMBER> The number of the delegate.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_ENUM[] =
R"__c_cb(
-static int __run_pending_job(void)
-{
- int cmd = -1;
- job_h job;
- int r = 0;
+<UPPERCASE_PREFIX>_<UPPERCASE_NAME>_DELEGATE_<UPPERCASE_DELEGATE_NAME> = <NUMBER>,
+)__c_cb";
- if (g_queue_is_empty(__job_queue)) {
- _E("Empty queue");
- return -1;
- }
+/**
+ * <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 {
+ rpc_port_stub_h stub;
+ <PREFIX>_<NAME>_callback_s callback;
+ void *user_data;
+ GList* contexts;
+ GList* callback_ports;
+ GRecMutex mutex;
+} <PREFIX>_<NAME>_t;
+
+static <PREFIX>_<NAME>_t __<NAME>;
+)__c_cb";
- job = g_queue_pop_head(__job_queue);
- rpc_port_parcel_read_int32(job->parcel, &cmd);
- if (cmd > 1 && cmd < (sizeof(__##_method_table) / sizeof(__##_method_table[0]))) {
- if (__##_method_table[cmd])
- r = __##_method_table[cmd](job->port, job->parcel, job->context);
- } else {
- _E("Unknown Command(%d)", cmd);
- r = -1;
- }
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CONTEXT_DEF[] =
+R"__c_cb(
+typedef struct <PREFIX>_<NAME>_context_s {
+ char *sender;
+ char *instance;
+ rpc_port_h port;
+ rpc_port_h callback_port;
+ void *tag;
+ <PREFIX>_<NAME>_callback_s callback;
+ void *user_data;
+#ifdef TIDL_THREAD_ENABLE
+ GThread *thread;
+ GQueue *queue;
+ GMutex mutex;
+ GCond cond;
+ bool done;
+#endif /* TIDL_THREAD_ENABLE */
+} <PREFIX>_<NAME>_context_t;
+
+static bool __<PREFIX>_<NAME>_exist_callback_port(rpc_port_h callback_port);
+)__c_cb";
- __destroy_job(job);
- return r;
-}
+/**
+ * <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;
+ rpc_port_h port;
+ int id;
+ int seq_id;
+ bool once;
+ bool valid;
+} <PREFIX>_<NAME>_<DELEGATE_NAME>_t;
)__c_cb";
-const char CB_INTERFACE_ON_CONNECTED[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CONTEXT_BASE[] =
R"__c_cb(
-static void __##_on_connected(const char *sender, const char *instance, void *data)
+static int __<PREFIX>_<NAME>_context_handle_request(<PREFIX>_<NAME>_context_h h, rpc_port_parcel_h parcel)
{
- rpc_port_stub_##_context_h context;
+ int ret = RPC_PORT_ERROR_NONE;
+ int cmd = -1;
+
+ rpc_port_parcel_read_int32(parcel, &cmd);
+ if (cmd > 1 && cmd < ARRAY_SIZE(__<NAME>_method_table)) {
+ if (__<NAME>_method_table[cmd])
+ ret = __<NAME>_method_table[cmd](h->port, parcel, h);
+ } else {
+ _W("Invalid protocol. cmd(%d)", cmd);
+ ret = RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ return ret;
+}
- _I("[__RPC_PORT__] sender(%s), instance(%s)", sender, instance);
- context = __create_##_context(sender, instance);
- if (!context)
- return;
+#ifdef TIDL_THREAD_ENABLE
+static int __<PREFIX>_<NAME>_context_push(<PREFIX>_<NAME>_context_h h, rpc_port_parcel_h parcel)
+{
+ g_mutex_lock(&h->mutex);
+ g_queue_push_tail(h->queue, parcel);
+ g_cond_signal(&h->cond);
+ g_mutex_unlock(&h->mutex);
- if (context->callback.create)
- context->callback.create(context, context->user_data);
- __##_contexts = g_list_append(__##_contexts, context);
+ return 0;
}
-)__c_cb";
-const char CB_INTERFACE_ON_DISCONNECTED[] =
-R"__c_cb(
-static void __##_on_disconnected(const char *sender, const char *instance, void *data)
+static rpc_port_parcel_h __<PREFIX>_<NAME>_context_wait_and_pop(<PREFIX>_<NAME>_context_h h)
{
- rpc_port_stub_##_context_h context;
+ rpc_port_parcel_h parcel;
- _I("[__RPC_PORT__] sender(%s), instance(%s)", sender, instance);
- context = __find_##_context(instance);
- if (!context)
- return;
+ g_mutex_lock(&h->mutex);
+ while (g_queue_is_empty(h->queue) && !h->done)
+ g_cond_wait(&h->cond, &h->mutex);
- if (context->callback.terminate)
- context->callback.terminate(context, context->user_data);
- __##_contexts = g_list_remove(__##_contexts, context);
- __destroy_##_context(context);
+ parcel = g_queue_pop_head(h->queue);
+ g_mutex_unlock(&h->mutex);
+
+ return parcel;
}
-)__c_cb";
-const char CB_INTERFACE_ON_RECEIVED[] =
-R"__c_cb(
-static int __##_on_received(const char *sender, const char *instance, rpc_port_h port, void *data)
+static gpointer __<PREFIX>_<NAME>_context_thread_cb(gpointer user_data)
{
- rpc_port_stub_##_context_h context;
- rpc_port_parcel_h parcel;
- int cmd = -1;
- int r;
-
- _I("[__RPC_PORT__] sender(%s), instance(%s)", sender, instance);
- context = __find_##_context(instance);
- if (!context) {
- _E("Failed to find ## context(%s)", instance);
- return -1;
+ <PREFIX>_<NAME>_context_h h = user_data;
+ rpc_port_parcel_h parcel;
+
+ _W("START");
+ while (!h->done) {
+ parcel = __<PREFIX>_<NAME>_context_wait_and_pop(h);
+ if (parcel) {
+ __<PREFIX>_<NAME>_context_handle_request(h, parcel);
+ rpc_port_parcel_destroy(parcel);
}
+ }
+ _W("END");
- context->port = port;
- r = rpc_port_parcel_create_from_port(&parcel, port);
- if (r != 0) {
- _E("Failed to create parcel from port");
- return r;
- }
+ return nullptr;
+}
+#endif /* TIDL_THREAD_ENABLE */
- rpc_port_parcel_read_int32(parcel, &cmd);
- if (cmd > 1 && cmd < (sizeof(__##_method_table) / sizeof(__##_method_table[0]))) {
- if (__##_method_table[cmd])
- r = __##_method_table[cmd](port, parcel, context);
- } else {
- _E("Unknown Command(%d)", cmd);
- r = -1;
+static void __<PREFIX>_<NAME>_context_destroy(gpointer data)
+{
+ <PREFIX>_<NAME>_context_h h = data;
+#ifdef TIDL_THREAD_ENABLE
+ rpc_port_parcel_h parcel;
+#endif /* TIDL_THREAD_ENABLE */
+
+ if (h == nullptr)
+ return;
+
+#ifdef TIDL_THREAD_ENABLE
+ g_mutex_lock(&h->mutex);
+ h->done = true;
+ g_cond_signal(&h->cond);
+ g_mutex_unlock(&h->mutex);
+
+ if (h->thread) {
+ g_thread_join(h->thread);
+ g_thread_unref(h->thread);
+ }
+
+ g_mutex_clear(&h->mutex);
+ g_cond_clear(&h->cond);
+
+ if (h->queue) {
+ while (!g_queue_is_empty(h->queue)) {
+ parcel = g_queue_pop_head(h->queue);
+ rpc_port_parcel_destroy(parcel);
}
- rpc_port_parcel_destroy(parcel);
+ g_queue_free(h->queue);
+ }
+#endif /* TIDL_THREAD_ENABLE */
+
+ if (h->instance)
+ free(h->instance);
- return r;
+ if (h->sender)
+ free(h->sender);
+
+ free(h);
}
-)__c_cb";
-const char CB_INTERFACE_THREAD_ON_RECEIVED[] =
-R"__c_cb(
-static int __##_on_received(const char *sender, const char *instance, rpc_port_h port, void *data)
+static <PREFIX>_<NAME>_context_h __<PREFIX>_<NAME>_context_create(const char *sender, const char *instance, rpc_port_h callback_port)
{
- rpc_port_stub_##_context_h context;
- int r;
+ <PREFIX>_<NAME>_context_t *handle;
+
+ if (sender == nullptr || instance == nullptr || callback_port == nullptr) {
+ _E("Invalid parameter");
+ return nullptr;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_context_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return nullptr;
+ }
+
+ handle->sender = strdup(sender);
+ if (handle->sender == nullptr) {
+ _E("Failed to duplicate sender");
+ __<PREFIX>_<NAME>_context_destroy(handle);
+ return nullptr;
+ }
+
+ handle->instance = strdup(instance);
+ if (handle->instance == nullptr) {
+ _E("Failed to duplicate instance");
+ __<PREFIX>_<NAME>_context_destroy(handle);
+ return nullptr;
+ }
+
+#ifdef TIDL_THREAD_ENABLE
+ g_mutex_init(&handle->mutex);
+ g_cond_init(&handle->cond);
+
+ handle->queue = g_queue_new();
+ if (handle->queue == nullptr) {
+ _E("Failed to create queue");
+ __<PREFIX>_<NAME>_context_destroy(handle);
+ return nullptr;
+ }
+
+ handle->thread = g_thread_new(instance, __<PREFIX>_<NAME>_context_thread_cb, handle);
+ if (handle->thread == nullptr) {
+ _E("Failed to create thread");
+ __<PREFIX>_<NAME>_context_destroy(handle);
+ return nullptr;
+ }
+#endif /* TIDL_THREAD_ENABLE */
+
+ handle->callback_port = callback_port;
+ handle->callback = __<NAME>.callback;
+ handle->user_data = __<NAME>.user_data;
+
+ return handle;
+}
- _I("[__RPC_PORT__] sender(%s), instance(%s)", sender, instance);
- context = __find_##_context(instance);
- if (!context) {
- _E("Failed to find ## context(%s)", instance);
- return -1;
- }
- r = __add_thread_queue(port, context);
+int <PREFIX>_<NAME>_context_set_tag(<PREFIX>_<NAME>_context_h context, void *tag)
+{
+ if (context == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- return r;
+ context->tag = tag;
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_INTERFACE_THREAD_CREATE[] =
-R"__c_cb(
-__job_queue = g_queue_new();
-)__c_cb";
+int <PREFIX>_<NAME>_context_get_tag(<PREFIX>_<NAME>_context_h context, void **tag)
+{
+ if (context == nullptr || tag == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
-const char CB_INTERFACE_THREAD_DESTROY[] =
-R"__c_cb(
-while (!g_queue_is_empty(__job_queue)) {
- job = g_queue_pop_head(__job_queue);
- __destroy_job(job);
+ *tag = context->tag;
+
+ return RPC_PORT_ERROR_NONE;
}
-g_queue_free(__job_queue);
-__job_queue = NULL;
-)__c_cb";
-const char CB_INTERFACE_REGISTER[] =
-R"__c_cb(
-int rpc_port_stub_##_register(rpc_port_stub_##_callback_s *callback, void *user_data)
+int <PREFIX>_<NAME>_context_get_sender(<PREFIX>_<NAME>_context_h context, char **sender)
{
- int r;
+ char *value;
- if (__##_stub) {
- _W("Already exists");
- return -1;
- }
+ if (context == nullptr || sender == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- if (!callback) {
- _E("Invalid parameter");
- return -1;
- }
+ value = strdup(context->sender);
+ if (value == nullptr) {
+ _E("Failed to duplicate sender");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
- __##_callback = *callback;
- __##_user_data = user_data;
- r = rpc_port_stub_create(&__##_stub, "##");
- if (r != 0) {
- _E("Failed to create stub handle");
- return r;
- }
-$$
-
- r = rpc_port_stub_add_received_event_cb(__##_stub, __##_on_received, NULL);
- if (r != 0) {
- _E("Failed to add received event callback");
- rpc_port_stub_destroy(__##_stub);
- __##_stub = NULL;
- return r;
- }
+ *sender = value;
- r = rpc_port_stub_add_connected_event_cb(__##_stub, __##_on_connected, NULL);
- if (r != 0) {
- _E("Failed to add connected event callback");
- rpc_port_stub_destroy(__##_stub);
- __##_stub = NULL;
- return r;
- }
+ return RPC_PORT_ERROR_NONE;
+}
- r = rpc_port_stub_add_disconnected_event_cb(__##_stub, __##_on_disconnected, NULL);
- if (r != 0) {
- _E("Failed to add disconnected event callback");
- rpc_port_stub_destroy(__##_stub);
- __##_stub = NULL;
- return r;
- }
+int <PREFIX>_<NAME>_context_get_instance(<PREFIX>_<NAME>_context_h context, char **instance)
+{
+ char *value;
- r = __##_add_privileges();
- if (r != 0) {
- _E("Failed to add privileges");
- rpc_port_stub_destroy(__##_stub);
- __##_stub = NULL;
- return r;
- }
+ if (context == nullptr || instance == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- r = rpc_port_stub_listen(__##_stub);
- if (r != 0) {
- _E("Failed to listen stub");
- rpc_port_stub_destroy(__##_stub);
- __##_stub = NULL;
- return r;
- }
+ value = strdup(context->instance);
+ if (value == nullptr) {
+ _E("Failed to duplicate instance");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
- return 0;
+ *instance = value;
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_INTERFACE_UNREGISTER[] =
-R"__c_cb(
-int rpc_port_stub_##_unregister(void)
+static <PREFIX>_<NAME>_context_h __<PREFIX>_<NAME>_find_context(const char *instance)
{
- int r;
-$$
-
- if (!__##_stub)
- return -1;
-
- if (__##_contexts) {
- g_list_free_full(__##_contexts, __destroy_##_context);
- __##_contexts = NULL;
+ <PREFIX>_<NAME>_context_h context;
+ GList *iter;
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ iter = __<NAME>.contexts;
+ while (iter) {
+ context = iter->data;
+ if (!strcmp(context->instance, instance)) {
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+ return context;
}
- r = rpc_port_stub_destroy(__##_stub);
- __##_stub = NULL;
-$$
+ iter = g_list_next(iter);
+ }
+ g_rec_mutex_unlock(&__<NAME>.mutex);
- return r;
+ return nullptr;
}
-)__c_cb";
-const char CB_INTERFACE_CLIENT_NUMBER_GETTER[] =
-R"__c_cb(
-int rpc_port_stub_##_get_client_number(unsigned int *n)
+static void __<PREFIX>_<NAME>_add_context(<PREFIX>_<NAME>_context_h context)
{
- if (!n) {
- _E("Invalid parameter");
- return -1;
- }
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ __<NAME>.contexts = g_list_append(__<NAME>.contexts, context);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+}
+
+static void __<PREFIX>_<NAME>_remove_context(<PREFIX>_<NAME>_context_h context)
+{
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ __<NAME>.contexts = g_list_remove(__<NAME>.contexts, context);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+}
- if (!__##_stub) {
- _E("## Stub is not ready");
- return -1;
+static bool __<PREFIX>_<NAME>_exist_callback_port(rpc_port_h callback_port)
+{
+ rpc_port_h port;
+ GList *iter;
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ iter = __<NAME>.callback_ports;
+ while (iter) {
+ port = iter->data;
+ if (port == callback_port) {
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+ return true;
}
- *n = g_list_length(__##_contexts);
+ iter = g_list_next(iter);
+ }
+ g_rec_mutex_unlock(&__<NAME>.mutex);
- return 0;
+ return false;
}
-)__c_cb";
-const char CB_GLOBALS[] =
-R"__c_cb(
-static rpc_port_stub_h __##_stub;
-static rpc_port_stub_##_callback_s __##_callback;
-static void *__##_user_data;
-static GList *__##_contexts;
-)__c_cb";
+static void __<PREFIX>_<NAME>_add_callback_port(rpc_port_h callback_port)
+{
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ __<NAME>.callback_ports = g_list_append(__<NAME>.callback_ports, callback_port);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+}
-const char CB_INTERFACE_DELEGATOR_DECL[] =
-R"__c_cb(
-struct $$_s {
- rpc_port_parcelable_t parcelable;
- rpc_port_h port;
- int id;
- int seq_id;
- bool once;
- bool valid;
-};
+static void __<PREFIX>_<NAME>_remove_callback_port(rpc_port_h callback_port)
+{
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ __<NAME>.callback_ports = g_list_remove(__<NAME>.callback_ports, callback_port);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+}
)__c_cb";
-const char CB_INTERFACE_DELEGATOR_CTOR[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate of the interface.
+ * <DELEGATE_PARAMS> The parameters of the delegate.
+ * <DELEGATE_PARAMS_CHECK> The implementation to check whether arguments are nullptr or not
+ * <DELEGATE_ENUM_VALUE> The enumeration value of the method.
+ * <DELEGATE_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
R"__c_cb(
-static int rpc_port_##_create(rpc_port_##_h *h)
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_to(rpc_port_parcel_h parcel, void *user_data)
{
- struct ##_s *handle;
- static int seq_num;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = user_data;
- if (!h) {
- _E("Invalid parameter");
- return -1;
- }
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ return;
+ }
- handle = calloc(1, sizeof(struct ##_s));
- if (!handle) {
- _E("Out of memory");
- return -1;
- }
+ rpc_port_parcel_write_int32(parcel, h->id);
- handle->parcelable.to = __##_to;
- handle->parcelable.from = __##_from;
- handle->id = $$_DELEGATE_$$;
- handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
- handle->once = false;
- handle->valid = true;
+ rpc_port_parcel_write_int32(parcel, h->seq_id);
- *h = handle;
+ rpc_port_parcel_write_bool(parcel, h->once);
- return 0;
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
}
-)__c_cb";
-const char CB_INTERFACE_DELEGATOR_DTOR[] =
-R"__c_cb(
-int rpc_port_##_destroy(rpc_port_##_h h)
+static void __<PREFIX>_<NAME>_<DELEGATE_NAME>_from(rpc_port_parcel_h parcel, void *user_data)
{
- if (!h) {
- _E("Invalid parameter");
- return -1;
- }
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h h = user_data;
- free(h);
+ if (parcel == nullptr || h == nullptr) {
+ _E("Invalid parameter");
+ set_last_result(RPC_PORT_ERROR_INVALID_PARAMETER);
+ return;
+ }
- return 0;
-}
-)__c_cb";
+ rpc_port_parcel_read_int32(parcel, &h->id);
-const char CB_INTERFACE_DELEGATOR_SERIALIZER[] =
-R"__c_cb(
-static void __##_to(rpc_port_parcel_h parcel, void *data)
-{
- rpc_port_##_h handle = data;
+ rpc_port_parcel_read_int32(parcel, &h->seq_id);
- if (!handle) {
- _E("Invalid parameter");
- return;
- }
+ rpc_port_parcel_read_bool(parcel, &h->once);
- rpc_port_parcel_write_int32(parcel, handle->id);
- rpc_port_parcel_write_int32(parcel, handle->seq_id);
- rpc_port_parcel_write_bool(parcel, handle->once);
- _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+ _I("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
+ set_last_result(RPC_PORT_ERROR_NONE);
}
-)__c_cb";
-const char CB_INTERFACE_DELEGATOR_DESERIALIZER[] =
-R"__c_cb(
-static void __##_from(rpc_port_parcel_h parcel, void *data)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h)
{
- rpc_port_##_h handle = data;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_t *handle;
+ static int seq_num;
+
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ handle = calloc(1, sizeof(<PREFIX>_<NAME>_<DELEGATE_NAME>_t));
+ if (handle == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle->parcelable.to = __<PREFIX>_<NAME>_<DELEGATE_NAME>_to;
+ handle->parcelable.from = __<PREFIX>_<NAME>_<DELEGATE_NAME>_from;
+ handle->id = <DELEGATE_ENUM_VALUE>;
+ handle->seq_id = g_atomic_int_add(&seq_num, 1) + 1;
+ handle->once = false;
+ handle->valid = true;
+ _I("id(%d), seq_id(%d)", handle->id, handle->seq_id);
+
+ *h = handle;
+
+ return RPC_PORT_ERROR_NONE;
+}
- if (!handle) {
- _E("Invalid parameter");
- return;
- }
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h)
+{
+ if (h == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ _W("id(%d), seq_id(%d), once(%s)", h->id, h->seq_id, h->once ? "true" : "false");
- rpc_port_parcel_read_int32(parcel, &handle->id);
- rpc_port_parcel_read_int32(parcel, &handle->seq_id);
- rpc_port_parcel_read_bool(parcel, &handle->once);
- _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+ free(h);
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_INTERFACE_DELEGATOR_CLONER[] =
-R"__c_cb(
-int rpc_port_##_clone(rpc_port_##_h h, rpc_port_##_h *clone)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone)
{
- rpc_port_##_h handle;
+ <PREFIX>_<NAME>_<DELEGATE_NAME>_h handle;
+ int ret;
- if (!h || !clone) {
- _E("Invalid parameter");
- return -1;
- }
+ if (h == nullptr || clone == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- handle = calloc(1, sizeof(struct ##_s));
- if (!handle) {
- _E("Out of memory");
- return -1;
- }
+ ret = <PREFIX>_<NAME>_<DELEGATE_NAME>_create(&handle);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret);
+ return ret;
+ }
- handle->parcelable = h->parcelable;
- handle->port = h->port;
- handle->id = h->id;
- handle->seq_id = h->seq_id;
- handle->once = h->once;
- handle->valid = h->valid;
- _I("id(%d), seq_id(%d), once(%s)", handle->id, handle->seq_id, handle->once ? "true" : "false");
+ handle->port = h->port;
+ handle->seq_id = h->seq_id;
+ handle->once = h->once;
+ handle->valid = h->valid;
- *clone = handle;
+ *clone = handle;
- return 0;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_INTERFACE_DELEGATOR_INVOKER[] =
-R"__c_cb(
-int rpc_port_$$_invoke($$)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id)
{
- rpc_port_parcel_h parcel = NULL;
- int r;
+ if (h == nullptr || id == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- if (!h || !h->port) {
- _E("Invalid parameter");
- return -1;
- }
+ *id = h->id;
- if (h->once && !h->valid) {
- _E("Invalid callback");
- return -1;
- }
+ return RPC_PORT_ERROR_NONE;
+}
- rpc_port_parcel_create(&parcel);
- if (!parcel) {
- _E("Failed to create parcel");
- return -1;
- }
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id)
+{
+ if (h == nullptr || seq_id == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- rpc_port_parcel_write_int32(parcel, $$_METHOD_Callback);
- rpc_port_parcel_write(parcel, &h->parcelable, h);
-$$
- r = rpc_port_parcel_send(parcel, h->port);
- rpc_port_parcel_destroy(parcel);
- h->valid = false;
+ *seq_id = h->seq_id;
- return r;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_INTERFACE_DELEGATOR_PORT_SETTER[] =
-R"__c_cb(
-int rpc_port_##_set_port(rpc_port_##_h h, rpc_port_h port)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once)
{
- if (!h || !port) {
- _E("Invalid parameter");
- return -1;
- }
+ if (h == nullptr || once == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- h->port = port;
+ *once = h->once;
- return 0;
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_INTERFACE_CONTEXT_DECL[] =
-R"__c_cb(
-struct ##_context_s {
- char *sender;
- char *instance;
- rpc_port_h port;
- void *tag;
- rpc_port_stub_##_callback_s callback;
- void *user_data;
-$$
-};
-)__c_cb";
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag)
+{
+ char *value;
+ char buf[128];
-const char CB_INTERFACE_CONTEXT_DECL_THREAD_ELEM[] =
-R"__c_cb(pthread_mutex_t mutex;
-pthread_cond_t cond;
-pthread_t thread;
-bool run_wait_queue;
-)__c_cb";
+ if (h == nullptr || tag == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
-const char CB_INTERFACE_THREAD_FEATURE[] =
-R"__c_cb(
-typedef struct {
- rpc_port_parcel_h parcel;
- rpc_port_h port;
- void *context;
-} job_s;
-typedef job_s *job_h;
+ snprintf(buf, sizeof(buf), "%d::%d", h->id, h->seq_id);
+ value = strdup(buf);
+ if (value == nullptr) {
+ _E("Out of memory");
+ return RPC_PORT_ERROR_OUT_OF_MEMORY;
+ }
-static GQueue *__job_queue;
+ *tag = value;
-static int __run_pending_job(void);
+ return RPC_PORT_ERROR_NONE;
+}
-static void *__wait_queue(void *data)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_set_port(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, rpc_port_h port)
{
- rpc_port_stub_##_context_h context = (rpc_port_stub_##_context_h)data;
+ if (h == nullptr || port == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- while(context->run_wait_queue) {
- pthread_mutex_lock(&context->mutex);
- pthread_cond_wait(&context->cond, &context->mutex);
- __run_pending_job();
- pthread_mutex_unlock(&context->mutex);
- }
+ h->port = port;
- return NULL;
+ return RPC_PORT_ERROR_NONE;
}
-static job_h __create_job(rpc_port_parcel_h parcel, rpc_port_h port, void *context)
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_invoke(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h<DELEGATE_PARAMS>)
{
- job_h job;
+ rpc_port_parcel_h parcel_;
+ int ret_;
- job = (job_s *)calloc(1, sizeof(job_s));
- if (!job) {
- _E("Out of memory");
- return NULL;
- }
+ if (h == nullptr || h->port == nullptr<DELEGATE_PARAMS_CHECK>) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- job->parcel = parcel;
- job->port = port;
- job->context = context;
+ if (!__<PREFIX>_<NAME>_exist_callback_port(h->port)) {
+ _E("Not connected");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
- return job;
-}
+ if (h->once && !h->valid) {
+ _E("The delegate handle is already used");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
-static void __destroy_job(job_h job)
-{
- rpc_port_parcel_destroy(job->parcel);
- free(job);
+ ret_ = rpc_port_parcel_create(&parcel_);
+ if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret_);
+ return ret_;
+ }
+
+ rpc_port_parcel_write_int32(parcel_, <DELEGATE_ENUM_VALUE>);
+
+ rpc_port_parcel_write(parcel_, &h->parcelable, h);
+
+ <DELEGATE_PARCEL_WRITE>
+ ret_ = rpc_port_parcel_send(parcel_, h->port);
+ rpc_port_parcel_destroy(parcel_);
+ h->valid = false;
+
+ return ret_;
}
+)__c_cb";
-static int __add_thread_queue(rpc_port_h port, rpc_port_stub_##_context_h context)
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_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_DELEGATE_BUNDLE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_bundle(parcel_, <ARG>);
+)__c_cb";
+
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_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_DELEGATE_BASE_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_<PARCEL_TYPE>(parcel_, <ARG>);
+)__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_h port, rpc_port_parcel_h parcel, void *user_data)
{
- rpc_port_parcel_h parcel;
- job_h job;
- int r;
+ <PREFIX>_<NAME>_context_h context_ = user_data;
+ rpc_port_h callback_port_;
+ int ret_;
+ <METHOD_HANDLER_ARGS_DECL>
- r = rpc_port_parcel_create_from_port(&parcel, port);
- if (r != 0) {
- _E("Failed to create parcel from port");
- return r;
- }
+ ret_ = rpc_port_stub_get_port(__<NAME>.stub, RPC_PORT_PORT_CALLBACK, context_->instance, &callback_port_);
+ if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get callback port. error(%d)", ret_);
+ goto out;
+ }
- job = __create_job(parcel, port, context);
- g_queue_push_tail(__job_queue, job);
- if (g_queue_is_empty(__job_queue)) {
- _E("Empty queue ##");
- return -1;
- }
+ <METHOD_HANDLER_PARCEL_READ>
+ <METHOD_HANDLER_CALLBACK_INVOKE>
+ <METHOD_HANDLER_PARCEL_WRITE>
- pthread_mutex_lock(&context->mutex);
- pthread_cond_signal(&context->cond);
- pthread_mutex_unlock(&context->mutex);
+out:
+ <METHOD_HANDLER_ARGS_FREE>
- return 0;
+ return ret_;
}
)__c_cb";
-const char CB_INTERFACE_CONTEXT_CTOR[] =
+/**
+ * <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(
-static struct ##_context_s *__create_##_context(const char *sender, const char *instance)
-{
- struct ##_context_s *handle;
+ret_ = <PREFIX>_<NAME>_create(&<ARG>);
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create handle. error(%d)", ret_);
+ goto out;
+}
- handle = calloc(1, sizeof(struct ##_context_s));
- if (!handle) {
- _E("Out of memory");
- return NULL;
- }
+<PREFIX>_<NAME>_set_port(<ARG>, callback_port_);
+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";
- handle->sender = strdup(sender);
- if (!handle->sender) {
- _E("Out of memory");
- free(handle);
- return NULL;
- }
+/**
+ * <ARG> The name of the value.
+ * <PREFIX> The prefix of the structure.
+ * <NAME> The name of the structure.
+ */
+constexpr const char CB_INTERFACE_METHOD_USER_DEFINED_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;
+}
- handle->instance = strdup(instance);
- if (!handle->instance) {
- _E("Out of memory");
- free(handle->sender);
- free(handle);
- return NULL;
- }
+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";
- handle->callback = __##_callback;
- handle->user_data = __##_user_data;
-$$
- return handle;
+/**
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_READ[] =
+R"__c_cb(
+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";
-const char CB_INTERFACE_CONTEXT_CTOR_THREAD_IMPL[] =
+/**
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_READ[] =
R"__c_cb(
-pthread_mutex_init(&handle->mutex, NULL);
-pthread_cond_init(&handle->cond, NULL);
-handle->run_wait_queue = true;
-if (pthread_create(&handle->thread, NULL, &__wait_queue, (void *)handle) < 0) {
- _E("Fail to create thread");
- free(handle->instance);
- free(handle->sender);
- free(handle);
- return NULL;
+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";
-const char CB_INTERFACE_CONTEXT_DTOR[] =
+/**
+ * <PARCEL_TYPE> The type of the parcel.
+ * <ARG> The name of the value.
+ */
+constexpr const char CB_INTERFACE_METHOD_BASE_PARCEL_READ[] =
R"__c_cb(
-static void __destroy_##_context(gpointer data)
-{
- struct ##_context_s *handle = data;
-$$
- if (!handle) {
- _E("Critical error!");
- return;
- }
+rpc_port_parcel_read_<PARCEL_TYPE>(parcel, &<ARG>);
+)__c_cb";
- free(handle->instance);
- free(handle->sender);
-$$
- free(handle);
+/**
+ * <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 (context_->callback.<METHOD_NAME>)
+ <RES_SET>context_->callback.<METHOD_NAME>(context_<METHOD_ARGS>, context_->user_data);
+)__c_cb";
+
+/**
+ * <UPPERCASE_NAME> The uppercase name of the interface.
+ */
+constexpr const char CB_INTERFACE_METHOD_PARCEL_WRITE_PRE[] =
+R"__c_cb(
+ret_ = rpc_port_parcel_create(&parcel_);
+if (ret_ != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle. error(%d)", ret_);
+ goto out;
}
+
+rpc_port_parcel_write_int32(parcel_, RPC_PORT_STUB_<UPPERCASE_NAME>_METHOD_RESULT_);
+)__c_cb";
+
+constexpr const char CB_INTERFACE_METHOD_PARCEL_WRITE_POST[] =
+R"__c_cb(
+ret_ = rpc_port_parcel_send(parcel_, port);
+rpc_port_parcel_destroy(parcel_);
)__c_cb";
-const char CB_INTERFACE_CONTEXT_DTOR_THREAD_VARS[] =
-R"__c_cb(void *retval = NULL;
-int ret;
+/**
+ * <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";
-const char CB_INTERFACE_CONTEXT_DTOR_THREAD_IMPL[] =
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_PARCEL_WRITE[] =
R"__c_cb(
-handle->run_wait_queue = false;
-pthread_mutex_lock(&handle->mutex);
-pthread_cond_signal(&handle->cond);
-pthread_mutex_unlock(&handle->mutex);
+rpc_port_parcel_write_bundle(parcel_, <ARG>);
+)__c_cb";
-ret = pthread_join(handle->thread, &retval);
-if (ret != 0)
- _E("joining thread error [%d].", ret);
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_PARCEL_WRITE[] =
+R"__c_cb(
+rpc_port_parcel_write_string(parcel_, <ARG>);
+)__c_cb";
-pthread_cond_destroy(&handle->cond);
-pthread_mutex_destroy(&handle->mutex);
+/**
+ * <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";
-const char CB_INTERFACE_CONTEXT_FINDER[] =
+/**
+ * <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(
-static struct ##_context_s *__find_##_context(const char *instance)
-{
- struct ##_context_s *handle;
- GList *iter;
+if (<ARG>)
+ <PREFIX>_<NAME>_destroy(<ARG>);
+)__c_cb";
- iter = __##_contexts;
- while (iter) {
- handle = (struct ##_context_s *)iter->data;
- if (!strcmp(handle->instance, instance))
- return handle;
- iter = g_list_next(iter);
- }
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_BUNDLE_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ bundle_free(<ARG>);
+)__c_cb";
- return NULL;
-}
+/**
+ * <ARG> The argument.
+ */
+constexpr const char CB_INTERFACE_METHOD_STRING_FREE[] =
+R"__c_cb(
+if (<ARG>)
+ free(<ARG>);
)__c_cb";
-const char CB_INTERFACE_CONTEXT_TAG_SETTER[] =
+/**
+ * <NAME> The name of the interface.
+ * <METHOD_HANDLERS> The declarations of method handlers.
+ */
+constexpr const char CB_INTERFACE_METHOD_TABLE[] =
R"__c_cb(
-int rpc_port_stub_##_context_set_tag(rpc_port_stub_##_context_h ctx, void *tag)
+static rpc_port_stub_method_handler __<NAME>_method_table[] = {
+ <METHOD_HANDLERS>
+};
+)__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";
+
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <ACCESS_CONTROL_SET> The implmentation to set the access control the stub handle.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__c_cb(
+static void __<PREFIX>_<NAME>_connected_event_cb(const char *sender, const char *instance, void *user_data)
{
- if (!ctx) {
- _E("Invalid parameter");
- return -1;
- }
+ <PREFIX>_<NAME>_context_h context;
+ rpc_port_h callback_port = nullptr;
+ int ret;
+
+ _W("sender(%s), instance(%s)", sender, instance);
+ ret = rpc_port_stub_get_port(__<NAME>.stub, RPC_PORT_PORT_CALLBACK, instance, &callback_port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get callback port. error(%d)", ret);
+ return;
+ }
+
+ context = __<PREFIX>_<NAME>_context_create(sender, instance, callback_port);
+ if (context == nullptr)
+ return;
+
+ __<PREFIX>_<NAME>_add_context(context);
+ __<PREFIX>_<NAME>_add_callback_port(context->callback_port);
+ context->callback.create(context, context->user_data);
+}
+
+static void __<PREFIX>_<NAME>_disconnected_event_cb(const char *sender, const char *instance, void *user_data)
+{
+ <PREFIX>_<NAME>_context_h context;
+
- ctx->tag = tag;
+ _W("sender(%s), instance(%s)", sender, instance);
+ context = __<PREFIX>_<NAME>_find_context(instance);
+ if (context == nullptr)
+ return;
- return 0;
+ __<PREFIX>_<NAME>_remove_callback_port(context->callback_port);
+ context->callback.terminate(context, context->user_data);
+ __<PREFIX>_<NAME>_remove_context(context);
+ __<PREFIX>_<NAME>_context_destroy(context);
}
-)__c_cb";
-const char CB_INTERFACE_CONTEXT_TAG_GETTER[] =
-R"__c_cb(
-int rpc_port_stub_##_context_get_tag(rpc_port_stub_##_context_h ctx, void **tag)
+static int __<PREFIX>_<NAME>_received_event_cb(const char *sender, const char *instance, rpc_port_h port, void *user_data)
{
- if (!ctx || !tag) {
- _E("Invalid parameter");
- return -1;
- }
+ <PREFIX>_<NAME>_context_h context;
+ rpc_port_parcel_h parcel;
+ int ret;
+
+ _W("sender(%s), instance(%s)", sender, instance);
+ context = __<PREFIX>_<NAME>_find_context(instance);
+ if (context == nullptr) {
+ _E("Failed to find context. instance(%s)", instance);
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ context->port = port;
+ ret = rpc_port_parcel_create_from_port(&parcel, port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create parcel handle from port. error(%d)", ret);
+ return ret;
+ }
+
+#ifdef TIDL_THREAD_ENABLE
+ ret = __<PREFIX>_<NAME>_context_push(context, parcel);
+#else
+ ret = __<PREFIX>_<NAME>_context_handle_request(context, parcel);
+ rpc_port_parcel_destroy(parcel);
+#endif /* TIDL_THREAD_ENABLE */
+
+ return ret;
+}
- *tag = ctx->tag;
+static int __<PREFIX>_<NAME>_set_access_control(void)
+{
+ int ret = RPC_PORT_ERROR_NONE;
+
+ <ACCESS_CONTROL_SET>
- return 0;
+ return ret;
}
-)__c_cb";
-const char CB_INTERFACE_CONTEXT_GET_SENDER[] =
-R"__c_cb(
-int rpc_port_stub_##_context_get_sender(rpc_port_stub_##_context_h ctx, char **sender)
+int <PREFIX>_<NAME>_register(rpc_port_stub_<NAME>_callback_s *callback, void *user_data)
{
- if (!ctx || !sender) {
- _E("Invalid parameter");
- return -1;
- }
+ int ret;
+
+ if (callback == nullptr || callback->create == nullptr || callback->terminate == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (__<NAME>.stub) {
+ _E("Already exists");
+ return RPC_PORT_ERROR_NONE;
+ }
+
+ g_rec_mutex_init(&__<NAME>.mutex);
+ __<NAME>.callback = *callback;
+ __<NAME>.user_data = user_data;
+
+ ret = rpc_port_stub_create(&__<NAME>.stub, "<NAME>");
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create stub handle. error(%d)", ret);
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = rpc_port_stub_add_received_event_cb(__<NAME>.stub, __<PREFIX>_<NAME>_received_event_cb, &__<NAME>);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add received event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = rpc_port_stub_add_connected_event_cb(__<NAME>.stub, __<PREFIX>_<NAME>_connected_event_cb, &__<NAME>);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add connected event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = rpc_port_stub_add_disconnected_event_cb(__<NAME>.stub, __<PREFIX>_<NAME>_disconnected_event_cb, &__<NAME>);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add disconnected event callback");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = __<PREFIX>_<NAME>_set_access_control();
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add privileges");
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ ret = rpc_port_stub_listen(__<NAME>.stub);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to listen events. error(%d)", ret);
+ <PREFIX>_<NAME>_unregister();
+ return ret;
+ }
+
+ return RPC_PORT_ERROR_NONE;
+}
- *sender = strdup(ctx->sender);
- if (*sender == NULL) {
- _E("Out of memory");
- return -1;
- }
+int <PREFIX>_<NAME>_unregister(void)
+{
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+ g_rec_mutex_clear(&__<NAME>.mutex);
- return 0;
+ if (__<NAME>.contexts) {
+ g_list_free_full(__<NAME>.contexts, __<PREFIX>_<NAME>_context_destroy);
+ __<NAME>.contexts = nullptr;
+ }
+
+ if (__<NAME>.stub) {
+ rpc_port_stub_destroy(__<NAME>.stub);
+ __<NAME>.stub = nullptr;
+ }
+
+ return RPC_PORT_ERROR_NONE;
}
-)__c_cb";
-const char CB_STUB_METHOD_TYPE[] =
-R"__c_cb(
-typedef int (*stub_method)(rpc_port_h, rpc_port_parcel_h, void *data);
-)__c_cb";
+int <PREFIX>_<NAME>_foreach_context(<PREFIX>_<NAME>_context_cb callback, void *user_data)
+{
+ <PREFIX>_<NAME>_context_h context;
+ GList *iter;
+
+ if (callback == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ iter = __<NAME>.contexts;
+ while (iter) {
+ context = iter->data;
+ if (!callback(context, user_data))
+ break;
+
+ iter = g_list_next(iter);
+ }
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+
+ return RPC_PORT_ERROR_NONE;
+}
-const char CB_INTERFACE_ADD_PRIVILEGE[] =
-R"__c_cb(
-static int __$$_add_privileges(void)
+int <PREFIX>_<NAME>_get_client_number(unsigned int *client_number)
{
-$$
- return 0;
+ if (client_number == nullptr) {
+ _E("Invalid parameter");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ if (__<NAME>.stub == nullptr) {
+ _E("Invalid context");
+ return RPC_PORT_ERROR_INVALID_PARAMETER;
+ }
+
+ g_rec_mutex_lock(&__<NAME>.mutex);
+ *client_number = g_list_length(__<NAME>.contexts);
+ g_rec_mutex_unlock(&__<NAME>.mutex);
+
+ return RPC_PORT_ERROR_NONE;
}
)__c_cb";
-const char CB_INTERFACE_PRIVILEGE_BLOCK[] =
-R"__c_cb(r = $$;
-if (r != 0) {
- _E("Failed to add privilege($$)");
- return r;
+/**
+ * <NAME> The name of the interface.
+ * <PRIVILEGE> The privilege name.
+ */
+constexpr const char CB_INTERFACE_PRIVILEGE_ADD[] =
+R"__c_cb(
+ret = rpc_port_stub_add_privilege(__<NAME>.stub, "<PRIVILEGE>");
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to add privilege. error(%d)", ret);
+ return ret;
}
)__c_cb";
-const char CB_INTERFACE_TRUSTED_MODE_BLOCK[] =
-R"__c_cb(r = $$;
-if (r != 0) {
- _E("Failed to set trusted mode($$)");
- return r;
+/**
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_TRUSTED_SET[] =
+R"__c_cb(
+ret = rpc_port_stub_set_trusted(__<NAME>.stub, true);
+if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to set trusted mode. error(%d)", ret);
+ return ret;
}
)__c_cb";
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
GenPragmaOnce(stream);
GenIncludeDefaultHeaders(stream, false);
GenExplicitLinkageOpen(stream);
+ GenStructureHandles(stream);
+ GenInterfaceHandles(stream);
GenStructures(stream);
+ GenInterfaceCallbacks(stream);
GenInterfaces(stream);
}
GenExplicitLinkageClose(stream);
}
+void CStubHeaderGen::GenInterfaceHandles(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& inf = static_cast<const Interface&>(*b);
+ GenInterfaceContextHandle(stream, inf);
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceDelegateHandle(stream, inf, *d);
+ }
+ }
+}
+
+// @see #CB_INTERFACE_CONTEXT_HANDLE
+void CStubHeaderGen::GenInterfaceContextHandle(std::ofstream& stream,
+ const Interface& inf) {
+ std::string code = ReplaceAll(CB_INTERFACE_CONTEXT_HANDLE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+
+ stream << SmartIndent(code);
+}
+
+// @see #CB_INTERFACE_DELEGATE_HANDLE
+void CStubHeaderGen::GenInterfaceDelegateHandle(std::ofstream& stream,
+ const Interface& inf, const Declaration& decl) {
+ std::string code = ReplaceAll(CB_INTERFACE_DELEGATE_HANDLE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<DELEGATE_NAME>", decl.GetID());
+
+ stream << SmartIndent(code);
+}
+
+void CStubHeaderGen::GenInterfaceCallbacks(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& inf = static_cast<const Interface&>(*b);
+ GenInterfaceCallbackBase(stream, inf);
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ GenInterfaceMethodCallbackBase(stream, inf, *d);
+ }
+ }
+}
+
+// @see #CB_INTERFACE_CALLBACK_BASE
+void CStubHeaderGen::GenInterfaceCallbackBase(std::ofstream& stream,
+ const Interface& inf) {
+ std::string code = ReplaceAll(CB_INTERFACE_CALLBACK_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+
+ stream << SmartIndent(code);
+}
+
+std::string CStubHeaderGen::GenMethodParams(const Interface& inf,
+ const Declaration& decl) {
+ std::string params;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, inf) +
+ p->GetID();
+ }
+
+ return params;
+}
+
+// @see #CB_INTERFACE_METHOD_CALLBACK_BASE
+void CStubHeaderGen::GenInterfaceMethodCallbackBase(std::ofstream& stream,
+ const Interface& inf, const Declaration& decl) {
+ std::string code = ReplaceAll(CB_INTERFACE_METHOD_CALLBACK_BASE,
+ "<RETURN_TYPE>", GetReturnTypeString(decl.GetType()));
+ code = ReplaceAll(code, "<PREFIX>", GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<METHOD_NAME>", decl.GetID());
+ code = ReplaceAll(code, "<METHOD_PARAMS>", GenMethodParams(inf, decl));
+
+ stream << SmartIndent(code);
+}
+
void CStubHeaderGen::GenInterfaces(std::ofstream& stream) {
for (auto& i : GetDocument().GetBlocks()) {
if (i->GetType() != Block::TYPE_INTERFACE)
}
void CStubHeaderGen::GenInterface(std::ofstream& stream,
- const Interface& inf) {
- GenInterfaceContext(stream, inf);
- GenInterfaceDelegators(stream, inf);
- GenInterfaceDeclaration(stream, inf);
- GenInterfaceRegister(stream, inf);
- GenInterfaceUnregister(stream, inf);
- GenInterfaceClientNumberGetter(stream, inf);
-}
-
-void CStubHeaderGen::GenInterfaceDeclaration(std::ofstream& stream,
- const Interface& inf) {
- stream << SmartIndent(GenTemplateString(ReplaceAll(
- CB_INTERFACE_DECL, "##", GetInterfaceIdWithNamespace(inf)),
- [&]()->std::string {
- std::string str;
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
- continue;
- str += NLine(1);
- str += GenTemplateString(CB_INTERFACE_CALLBACK,
- [&]()->std::string {
- return GetReturnTypeString(i->GetType());
- },
- [&]()->std::string {
- return i->GetID();
- },
- [&]()->std::string {
- return GetInterfaceIdWithNamespace(inf);
- },
- [&]()->std::string {
- std::string s;
- for (auto& p : i->GetParameters().GetParams()) {
- if (IsDelegateType(inf, p->GetParameterType()
- .GetBaseType())) {
- s += "rpc_port_" + GetInterfaceIdWithNamespace(inf)
- + "_" + p->GetParameterType().GetBaseType().ToString()
- + "_h " + p->GetID();
- } else {
- s += GetParamTypeString(p->GetParameterType()
- .GetDirection(), p->GetParameterType().GetBaseType())
- + p->GetID();
- }
- s += ", ";
- }
- return s;
- });
- }
- return str;
- }));
-}
-
-void CStubHeaderGen::GenInterfaceContext(std::ofstream& stream,
- const Interface& inf) {
- GenInterfaceContextDeclaration(stream, inf);
- GenInterfaceContextTagSetter(stream, inf);
- GenInterfaceContextTagGetter(stream, inf);
- GenInterfaceContextSenderGetter(stream, inf);
-}
-
-void CStubHeaderGen::GenInterfaceContextDeclaration(
- std::ofstream& stream, const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CONTEXT_DECL, "##",
- GetInterfaceIdWithNamespace(inf));
-}
-
-void CStubHeaderGen::GenInterfaceContextTagSetter(
- std::ofstream& stream, const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CONTEXT_SET_TAG, "##",
- GetInterfaceIdWithNamespace(inf));
-}
-
-void CStubHeaderGen::GenInterfaceContextTagGetter(
- std::ofstream& stream, const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CONTEXT_GET_TAG, "##",
- GetInterfaceIdWithNamespace(inf));
-}
-
-void CStubHeaderGen::GenInterfaceContextSenderGetter(
- std::ofstream& stream, const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CONTEXT_GET_SENDER, "##",
- GetInterfaceIdWithNamespace(inf));
-}
-
-void CStubHeaderGen::GenInterfaceDelegators(std::ofstream& stream,
- const Interface& inf) {
- for (auto& i : inf.GetDeclarations().GetDecls()) {
- if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ const Interface& inf) {
+ GenInterfaceContextBase(stream, inf);
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() != Declaration::MethodType::DELEGATE)
continue;
- GenInterfaceDelegator(stream, GetInterfaceIdWithNamespace(inf), *i);
+
+ GenInterfaceDelegateBase(stream, inf, *d);
}
-}
-void CStubHeaderGen::GenInterfaceDelegator(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl) {
- GenInterfaceDelegatorDeclaration(stream, id, decl);
- GenInterfaceDelegatorDestructor(stream, id, decl);
- GenInterfaceDelegatorCloner(stream, id, decl);
- GenInterfaceDelegatorInvoker(stream, id, decl);
+ GenInterfaceBase(stream, inf);
}
-void CStubHeaderGen::GenInterfaceDelegatorDeclaration(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << ReplaceAll(
- CB_INTERFACE_DELEGATOR_DECL, "##", id + "_" + decl.GetID());
-}
+// @see #CB_INTERFACE_CONTEXT_BASE
+void CStubHeaderGen::GenInterfaceContextBase(std::ofstream& stream,
+ const Interface& inf) {
+ std::string code = ReplaceAll(CB_INTERFACE_CONTEXT_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
-void CStubHeaderGen::GenInterfaceDelegatorDestructor(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << ReplaceAll(
- CB_INTERFACE_DELEGATOR_DTOR, "##", id + "_" + decl.GetID());
+ stream << SmartIndent(code);
}
-void CStubHeaderGen::GenInterfaceDelegatorCloner(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << ReplaceAll(
- CB_INTERFACE_DELEGATOR_CLONER, "##", id + "_" + decl.GetID());
-}
+std::string CStubHeaderGen::GenDelegateParams(const Interface& inf,
+ const Declaration& decl) {
+ std::string params;
+ for (auto& p : decl.GetParameters().GetParams()) {
+ params += ", ";
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += GetParamTypeString(param_type.GetDirection(), type, inf) +
+ p->GetID();
+ }
-void CStubHeaderGen::GenInterfaceDelegatorInvoker(
- std::ofstream& stream, const std::string& id, const Declaration& decl) {
- stream << GenTemplateString(ReplaceAll(
- CB_INTERFACE_DELEGATOR_INVOKER, "##", id + "_" + decl.GetID()),
- [&]()->std::string {
- std::string str;
- for (auto& i : decl.GetParameters().GetParams()) {
- str += ", ";
- str += GetParamTypeString(i->GetParameterType().GetDirection(),
- i->GetParameterType().GetBaseType()) + i->GetID();
- }
- return str;
- });
+ return params;
}
-void CStubHeaderGen::GenInterfaceRegister(std::ofstream& stream,
- const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_REGISTER, "##",
- GetInterfaceIdWithNamespace(inf));
+// @see #CB_INTERFACE_DELEGATE_BASE
+void CStubHeaderGen::GenInterfaceDelegateBase(std::ofstream& stream,
+ const Interface& inf, const Declaration& decl) {
+ std::string code = ReplaceAll(CB_INTERFACE_DELEGATE_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<DELEGATE_NAME>", decl.GetID());
+ code = ReplaceAll(code, "<DELEGATE_PARAMS>", GenDelegateParams(inf, decl));
+
+ stream << SmartIndent(code);
}
-void CStubHeaderGen::GenInterfaceUnregister(std::ofstream& stream,
- const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_UNREGISTER, "##",
- GetInterfaceIdWithNamespace(inf));
+// @see #CB_INTERFACE_METHOD_CALLBACK_DECL
+std::string CStubHeaderGen::GenMethodCallbackDecls(const Interface& inf) {
+ std::string method_callback_decls;
+ for (auto& d : inf.GetDeclarations().GetDecls()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string method_callback_decl = ReplaceAll(
+ CB_INTERFACE_METHOD_CALLBACK_DECL, "<PREFIX>", GetHandlePrefix());
+ method_callback_decl = ReplaceAll(method_callback_decl, "<NAME>",
+ inf.GetID());
+ method_callback_decl = ReplaceAll(method_callback_decl, "<METHOD_NAME>",
+ d->GetID());
+
+ method_callback_decl = RemoveLine(method_callback_decl);
+ method_callback_decls += RemoveLine(method_callback_decl, 2);
+ }
+
+ return method_callback_decls;
}
-void CStubHeaderGen::GenInterfaceClientNumberGetter(std::ofstream& stream,
- const Interface& inf) {
- stream << ReplaceAll(CB_INTERFACE_CLIENT_NUMBER_GETTER, "##",
- GetInterfaceIdWithNamespace(inf));
+// @see #CB_INTERFACE_BASE
+void CStubHeaderGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& inf) {
+ std::string code = ReplaceAll(CB_INTERFACE_BASE, "<PREFIX>",
+ GetHandlePrefix());
+ code = ReplaceAll(code, "<NAME>", inf.GetID());
+ code = ReplaceAll(code, "<METHOD_CALLBACK_DECLS>",
+ GenMethodCallbackDecls(inf));
+
+ stream << SmartIndent(code);
}
} // namespace tidl
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
void OnFiniGen(std::ofstream& stream) override;
private:
+ void GenInterfaceHandles(std::ofstream& stream);
+ void GenInterfaceContextHandle(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDelegateHandle(std::ofstream& stream, const Interface& inf,
+ const Declaration& decl);
+
+ void GenInterfaceCallbacks(std::ofstream& stream);
+ void GenInterfaceCallbackBase(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceMethodCallbackBase(std::ofstream& stream,
+ const Interface& inf, const Declaration& decl);
+
void GenInterfaces(std::ofstream& stream);
void GenInterface(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDeclaration(std::ofstream& stream, const Interface& inf);
- void GenInterfaceContext(std::ofstream& stream, const Interface& inf);
- void GenInterfaceDelegators(std::ofstream& stream, const Interface& inf);
- void GenInterfaceRegister(std::ofstream& stream, const Interface& inf);
- void GenInterfaceUnregister(std::ofstream& stream, const Interface& inf);
- void GenInterfaceClientNumberGetter(std::ofstream& stream,
- const Interface& inf);
- private:
- void GenInterfaceContextDeclaration(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextTagSetter(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextTagGetter(std::ofstream& stream,
- const Interface& inf);
- void GenInterfaceContextSenderGetter(std::ofstream& stream,
- const Interface& inf);
+ void GenInterfaceContextBase(std::ofstream& stream, const Interface& inf);
+ void GenInterfaceDelegateBase(std::ofstream& stream, const Interface& inf,
+ const Declaration& decl);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& inf);
- private:
- void GenInterfaceDelegator(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDeclaration(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorDestructor(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorCloner(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
- void GenInterfaceDelegatorInvoker(std::ofstream& stream,
- const std::string& id,
- const Declaration& decl);
+ std::string GenDelegateParams(const Interface& inf, const Declaration& decl);
+ std::string GenMethodParams(const Interface& inf, const Declaration& decl);
+ std::string GenMethodCallbackDecls(const Interface& inf);
};
} // namespace tidl
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 - 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.
#ifndef IDLC_C_GEN_C_STUB_HEADER_GEN_CB_H_
#define IDLC_C_GEN_C_STUB_HEADER_GEN_CB_H_
-const char CB_INTERFACE_DECL[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CONTEXT_HANDLE[] =
R"__c_cb(
-typedef struct {
- void (*create)(rpc_port_stub_##_context_h context, void *user_data);
- void (*terminate)(rpc_port_stub_##_context_h context, void *user_data);
-$$
-} rpc_port_stub_##_callback_s;
+/**
+ * @brief The <PREFIX>_<NAME>_context handle.
+ */
+typedef struct <PREFIX>_<NAME>_context_s *<PREFIX>_<NAME>_context_h;
)__c_cb";
-const char CB_INTERFACE_CALLBACK[] =
-R"__c_cb($$(*$$)(rpc_port_stub_$$_context_h context, $$void *user_data);)__c_cb";
-
-const char CB_INTERFACE_CONTEXT_DECL[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CONTEXT_BASE[] =
R"__c_cb(
-typedef struct ##_context_s* rpc_port_stub_##_context_h;
-)__c_cb";
+/**
+ * @brief Sets the tag to the context handle.
+ *
+ * @param[in] context The context handle
+ * @param[in] tag The tag
+ * @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>_context_get_tag()
+ */
+int <PREFIX>_<NAME>_context_set_tag(<PREFIX>_<NAME>_context_h context, void *tag);
-const char CB_INTERFACE_CONTEXT_SET_TAG[] =
-R"__c_cb(
-int rpc_port_stub_##_context_set_tag(rpc_port_stub_##_context_h ctx, void *tag);
-)__c_cb";
+/**
+ * @brief Gets the tag from the context handle.
+ *
+ * @param[in] context The context handle
+ * @param[out] tag The tag
+ * @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>_context_set_tag()
+ */
+int <PREFIX>_<NAME>_context_get_tag(<PREFIX>_<NAME>_context_h context, void **tag);
-const char CB_INTERFACE_CONTEXT_GET_TAG[] =
-R"__c_cb(
-int rpc_port_stub_##_context_get_tag(rpc_port_stub_##_context_h ctx, void **tag);
-)__c_cb";
+/**
+ * @brief Gets the sender ID from the context handle.
+ * @details The @a sender should be released using free().
+ *
+ * @param[in] context The context handle
+ * @param[out] sender The sender ID of the context 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
+ */
+int <PREFIX>_<NAME>_context_get_sender(<PREFIX>_<NAME>_context_h context, char **sender);
-const char CB_INTERFACE_CONTEXT_GET_SENDER[] =
-R"__c_cb(
-int rpc_port_stub_##_context_get_sender(rpc_port_stub_##_context_h ctx, char **sender);
+/**
+ * @brief Gets the instance ID from the context handle.
+ * @details The @a instance should be released using free().
+ *
+ * @param[in] context The context handle
+ * @param[out] instance The instance ID of the context 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
+ */
+int <PREFIX>_<NAME>_context_get_instance(<PREFIX>_<NAME>_context_h context, char **instance);
)__c_cb";
-const char CB_INTERFACE_DELEGATOR_DECL[] =
+/**
+ * <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_HANDLE[] =
R"__c_cb(
-typedef struct ##_s *rpc_port_##_h;
+/**
+ * @brief The <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ */
+typedef struct <PREFIX>_<NAME>_<DELEGATE_NAME>_s *<PREFIX>_<NAME>_<DELEGATE_NAME>_h;
)__c_cb";
-const char CB_INTERFACE_DELEGATOR_DTOR[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <DELEGATE_NAME> The name of the delegate.
+ * <DELEGATE_PARAMS> The parameters of the callback function.
+ */
+constexpr const char CB_INTERFACE_DELEGATE_BASE[] =
R"__c_cb(
-int rpc_port_##_destroy(rpc_port_##_h h);
-)__c_cb";
+/**
+ * @brief Creates a <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[out] h The <PREFIX>_<NAME>_<DELEGATE_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
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_create(<PREFIX>_<NAME>_<DELEGATE_NAME>_h *h);
-const char CB_INTERFACE_DELEGATOR_CLONER[] =
-R"__c_cb(
-int rpc_port_##_clone(rpc_port_##_h h, rpc_port_##_h *clone);
+/**
+ * @brief Destroys the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_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>_<DELEGATE_NAME>_clone()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h);
+
+/**
+ * @brief Creates and returns a copy of the given <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks A new created <PREFIX>_<NAME>_<DELEGATE_NAME> should be released using
+ * the <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy() if it's no longer needed.
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] clone If successful, a new created <PREFIX>_<NAME>_<DELEGATE_NAME> handle will be returned
+ * @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
+ * @see <PREFIX>_<NAME>_<DELEGATE_NAME>_destroy()
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_clone(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, <PREFIX>_<NAME>_<DELEGATE_NAME>_h *clone);
+
+/**
+ * @brief Gets the ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] id The ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *id);
+
+/**
+ * @brief Gets the sequence ID of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] seq_id The Sequence ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_seq_id(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, int *seq_id);
+
+/**
+ * @brief Checks whether the delegate is for one-time or not.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] once The flag, it's true, the handle is for one-time
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_is_once(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, bool *once);
+
+/**
+ * @brief Gets the tag from the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @remarks The @a tag should be released using free().
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[out] tag The tag
+ * @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
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_get_tag(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h, char **tag);
+
+/**
+ * @brief Invokes the callback function of the <PREFIX>_<NAME>_<DELEGATE_NAME> handle.
+ *
+ * @param[in] h The <PREFIX>_<NAME>_<DELEGATE_NAME> handle
+ * @param[in] ...
+ * @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 I/O error
+ */
+int <PREFIX>_<NAME>_<DELEGATE_NAME>_invoke(<PREFIX>_<NAME>_<DELEGATE_NAME>_h h<DELEGATE_PARAMS>);
)__c_cb";
-const char CB_INTERFACE_DELEGATOR_INVOKER[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ */
+constexpr const char CB_INTERFACE_CALLBACK_BASE[] =
R"__c_cb(
-int rpc_port_##_invoke(rpc_port_##_h h$$);
+/**
+ * @brief Called when the proxy is connected.
+ * @details The callback function is called when the proxy is connected to the stub.
+ *
+ * @param[in] context The context handle
+ * @param[in] user_data The user data passed from the registration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_create_cb)(<PREFIX>_<NAME>_context_h context, void *user_data);
+
+/**
+ * @brief Called when the proxy is disconnected.
+ * @details The callback function is called when the proxy is disconnected from the stub.
+ *
+ * @param[in] context The context handle
+ * @param[in] user_data The user data passed from the registration function
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+typedef void (*<PREFIX>_<NAME>_terminate_cb)(<PREFIX>_<NAME>_context_h context, void *user_data);
+
+/**
+ * @brief Called to get the proxy context once for each connected proxy.
+ *
+ * @param[in] context The context handle
+ * @param[in] user_data The user data passed from the registration function
+ * @return @c true to continue with the next iteration of the loop,
+ * otherwise @c false to break out of the loop
+ * @pre <PREFIX>_<NAME>_foreach_context() will invoke this callback.
+ * @see <PREFIX>_<NAME>_foreach_context()
+ */
+typedef bool (*<PREFIX>_<NAME>_context_cb)(<PREFIX>_<NAME>_context_h context, void *user_data);
)__c_cb";
-const char CB_INTERFACE_REGISTER[] =
+/**
+ * <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(
-int rpc_port_stub_##_register(rpc_port_stub_##_callback_s *callback, void *user_data);
+/**
+ * @brief Called when the request of the proxy is delivered.
+ *
+ * @param[in] context The context handle
+ * @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)(<PREFIX>_<NAME>_context_h context<METHOD_PARAMS>, void *user_data);
)__c_cb";
-const char CB_INTERFACE_UNREGISTER[] =
+/**
+ * <PREFIX> The prefix of the interface.
+ * <NAME> The name of the interface.
+ * <METHOD_CALLBACK_DECLS> The declarations of the method callback functions.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
R"__c_cb(
-int rpc_port_stub_##_unregister(void);
+/**
+ * @brief The structure type containing the set of callback functions for handling stub 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 {
+ <PREFIX>_<NAME>_create_cb create; /**< This callback function is invoked when the proxy is connected. */
+ <PREFIX>_<NAME>_terminate_cb terminate; /**< This callback function is invoked when the proxy is disconnected. */
+ <METHOD_CALLBACK_DECLS>
+} <PREFIX>_<NAME>_callback_s;
+
+/**
+ * @brief Registers the set of the callback functions and the port.
+ * @details This function registers the set of the callback functions to handle stub events.
+ * And, the rpc_port_stub_listen() is called internally to handle events.
+ *
+ * @param[in] callback The set of callback functions to handle stub events
+ * @param[in] user_data The user data to be passed to the callback function
+ * @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 I/O error
+ * @retval #RPC_PORT_ERROR_PERMISSION_DENIED Permission denied
+ * @see <PREFIX>_<NAME>_unregister()
+ * @see #<PREFIX>_<NAME>_callback_s
+ */
+int <PREFIX>_<NAME>_register(<PREFIX>_<NAME>_callback_s *callback, void *user_data);
+
+/**
+ * @brief Unregisters the registered port.
+ */
+int <PREFIX>_<NAME>_unregister(void);
+
+/**
+ * @brief Retrieves the connected context handles.
+ *
+ * @param[in] callback The callback function
+ * @param[in] user_data The user data to be passed to the callback function
+ * @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>_context_cb()
+ */
+int <PREFIX>_<NAME>_foreach_context(<PREFIX>_<NAME>_context_cb callback, void *user_data);
+
+/**
+ * @brief Gets the number of connected clients.
+ *
+ * @param[out] client_number The client number
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #RPC_PORT_ERROR_NONE Successful
+ * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int <PREFIX>_<NAME>_get_client_number(unsigned int *client_number);
)__c_cb";
-const char CB_INTERFACE_CLIENT_NUMBER_GETTER[] =
+/**
+ * <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(
-int rpc_port_stub_##_get_client_number(unsigned int *n);
+<PREFIX>_<NAME>_<METHOD_NAME>_cb <METHOD_NAME>; /**< This callback function is invoked when the <METHOD_NAME> request is delivered. */
)__c_cb";
#endif // IDLC_C_GEN_C_STUB_HEADER_GEN_CB_H_
return hasNamespace_;
}
+ void EnableProxy(bool enable) {
+ isProxy_ = enable;
+ }
+
+ bool IsProxy() const {
+ return isProxy_;
+ }
+
template<typename T, typename ...ARGS>
void GenTemplate(std::string templ, std::ofstream& stream,
T cb, ARGS... args) {
std::shared_ptr<Document> doc_;
std::ofstream out_file_;
bool hasNamespace_ = true;
+ bool isProxy_ = true;
};
} // namespace tidl
{
tidl::CStubHeaderGen stub_header(ps.GetDoc());
stub_header.EnableNamespace(options->HasNamespace());
+ stub_header.EnableProxy(false);
stub_header.Run(options->GetOutput() + ".h");
tidl::CStubBodyGen stub_body(ps.GetDoc(), options);
stub_body.EnableNamespace(options->HasNamespace());
+ stub_body.EnableProxy(false);
stub_body.Run(options->GetOutput() + ".c");
break;
}
{
tidl::CProxyHeaderGen proxy_header(ps.GetDoc());
proxy_header.EnableNamespace(options->HasNamespace());
+ proxy_header.EnableProxy(true);
proxy_header.Run(options->GetOutput() + ".h");
- tidl::CProxyBodyGen proxy_body(ps.GetDoc());
+ tidl::CProxyBodyGen proxy_body(ps.GetDoc(), options);
proxy_body.EnableNamespace(options->HasNamespace());
+ proxy_body.EnableProxy(true);
proxy_body.Run(options->GetOutput() + ".c");
break;
}