diff --git a/tools/hdi-gen/ast/ast.cpp b/tools/hdi-gen/ast/ast.cpp index 251e659d..36e934e9 100755 --- a/tools/hdi-gen/ast/ast.cpp +++ b/tools/hdi-gen/ast/ast.cpp @@ -7,6 +7,7 @@ */ #include "ast/ast.h" +#include #include "util/string_builder.h" namespace OHOS { @@ -232,5 +233,11 @@ bool AST::AddImport(const AutoPtr& importAst) return true; } + +void AST::SetVersion(size_t& majorVer, size_t& minorVer) +{ + majorVersion_ = majorVer; + minorVersion_ = minorVer; +} } // namespace HDI } // namespace OHOS \ No newline at end of file diff --git a/tools/hdi-gen/ast/ast.h b/tools/hdi-gen/ast/ast.h index d3a42fe0..d8cae684 100755 --- a/tools/hdi-gen/ast/ast.h +++ b/tools/hdi-gen/ast/ast.h @@ -153,11 +153,30 @@ public: return imports_; } + void SetVersion(size_t& majorVer, size_t& minorVer); + + inline size_t GetMajorVer() + { + return majorVersion_; + } + + inline size_t GetMinorVer() + { + return minorVersion_; + } + + String GetVersion() + { + return String::Format("%u.%u", majorVersion_, minorVersion_); + } + private: ASTFileType astFileType_ = ASTFileType::AST_IFACE; String name_; String license_; String packageName_; + size_t majorVersion_; + size_t minorVersion_; std::vector> namespaces_; std::vector> typeDefinitions_; AutoPtr sequenceableDef_ = nullptr; diff --git a/tools/hdi-gen/ast/ast_interface_type.cpp b/tools/hdi-gen/ast/ast_interface_type.cpp index 85b023ed..79adb8a1 100755 --- a/tools/hdi-gen/ast/ast_interface_type.cpp +++ b/tools/hdi-gen/ast/ast_interface_type.cpp @@ -132,8 +132,8 @@ String ASTInterfaceType::EmitJavaType(TypeMode mode, bool isInnerType) const void ASTInterfaceType::EmitCWriteVar(const String& parcelName, const String& name, const String& gotoLabel, StringBuilder& sb, const String& prefix) const { - sb.Append(prefix).AppendFormat("if (HdfSBufWriteRemoteService(%s, %s->remote) != 0) {\n", - parcelName.string(), name.string()); + sb.Append(prefix).AppendFormat("if (HdfSBufWriteRemoteService(%s, %s->AsObject(%s)) != 0) {\n", + parcelName.string(), name.string(), name.string()); sb.Append(prefix + g_tab).AppendFormat( "HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.string()); sb.Append(prefix + g_tab).Append("ec = HDF_ERR_INVALID_PARAM;\n"); diff --git a/tools/hdi-gen/ast/ast_interface_type.h b/tools/hdi-gen/ast/ast_interface_type.h index 7d3f1154..70870730 100755 --- a/tools/hdi-gen/ast/ast_interface_type.h +++ b/tools/hdi-gen/ast/ast_interface_type.h @@ -79,6 +79,16 @@ public: return methods_.size(); } + void AddVersionMethod(const AutoPtr& method) + { + getVerMethod_ = method; + } + + AutoPtr GetVersionMethod() + { + return getVerMethod_; + } + bool IsInterfaceType() override; String ToString() override; @@ -122,6 +132,7 @@ private: bool isFull_ = false; bool isLite_ = false; std::vector> methods_; + AutoPtr getVerMethod_; }; } // namespace HDI } // namespace OHOS diff --git a/tools/hdi-gen/ast/ast_parameter.h b/tools/hdi-gen/ast/ast_parameter.h index 97e4cd22..85603674 100755 --- a/tools/hdi-gen/ast/ast_parameter.h +++ b/tools/hdi-gen/ast/ast_parameter.h @@ -24,6 +24,10 @@ enum class ParamAttr { class ASTParameter : public ASTNode { public: + ASTParameter() : ASTNode() {} + ASTParameter(const String& name, ParamAttr attribute, const AutoPtr& type) + : ASTNode(), name_(name), attribute_(attribute), type_(type) {} + inline void SetName(const String& name) { name_ = name; diff --git a/tools/hdi-gen/ast/ast_smq_type.cpp b/tools/hdi-gen/ast/ast_smq_type.cpp new file mode 100644 index 00000000..c2087e50 --- /dev/null +++ b/tools/hdi-gen/ast/ast_smq_type.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#include "ast/ast_smq_type.h" + +namespace OHOS { +namespace HDI { +bool ASTSharedMemQueueType::IsSharedMemQueueType() +{ + return true; +} + +String ASTSharedMemQueueType::ToString() +{ + return String::Format("SharedMemQueue<%s>", innerType_->ToString().string()); +} + +TypeKind ASTSharedMemQueueType::GetTypeKind() +{ + return TypeKind::TYPE_SMQ; +} + +String ASTSharedMemQueueType::EmitCppType(TypeMode mode) const +{ + switch(mode) { + case TypeMode::NO_MODE: + return String::Format("SharedMemQueue<%s>", innerType_->EmitCppType().string()); + case TypeMode::PARAM_IN: + return String::Format("const std::shared_ptr>&", innerType_->EmitCppType().string()); + case TypeMode::PARAM_OUT: + return String::Format("std::shared_ptr>&", innerType_->EmitCppType().string()); + case TypeMode::LOCAL_VAR: + return String::Format("std::shared_ptr>", innerType_->EmitCppType().string()); + default: + return "unknow type"; + } +} + +void ASTSharedMemQueueType::EmitCppWriteVar(const String& parcelName, const String& name, StringBuilder& sb, + const String& prefix, unsigned int innerLevel) const +{ + sb.Append(prefix).AppendFormat("if (!%s->IsGood() || %s->GetMeta() == nullptr || ", name.string(), name.string()); + sb.AppendFormat("!%s->GetMeta()->Marshalling(%s)) {\n", name.string(), parcelName.string()); + sb.Append(prefix + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: write %s failed!\", __func__);\n", name.string()); + sb.Append(prefix + g_tab).Append("return HDF_ERR_INVALID_PARAM;\n"); + sb.Append(prefix).Append("}\n"); +} + +void ASTSharedMemQueueType::EmitCppReadVar(const String& parcelName, const String& name, StringBuilder& sb, + const String& prefix, bool initVariable, unsigned int innerLevel) const +{ + String metaVarName = String::Format("%sMeta_", name.string()); + sb.Append(prefix).AppendFormat("SharedMemQueueMeta<%s> *%s = ", + innerType_->EmitCppType().string(), metaVarName.string()); + sb.AppendFormat("SharedMemQueueMeta<%s>::UnMarshalling(%s);\n", + innerType_->EmitCppType().string(), parcelName.string()); + sb.Append(prefix).AppendFormat("if (%s == nullptr) {\n", metaVarName.string()); + sb.Append(prefix + g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: SharedMemQueueMeta is nullptr\", __func__);\n"); + sb.Append(prefix + g_tab).Append("return HDF_ERR_INVALID_PARAM;\n"); + sb.Append(prefix).Append("}\n\n"); + + sb.Append(prefix).AppendFormat("std::shared_ptr> %s = ", + innerType_->EmitCppType().string(), name.string()); + sb.AppendFormat("std::make_shared>(*%s);\n", + innerType_->EmitCppType().string(), metaVarName.string()); +} + +} // namespace HDI +} // namespace OHOS \ No newline at end of file diff --git a/tools/hdi-gen/ast/ast_smq_type.h b/tools/hdi-gen/ast/ast_smq_type.h new file mode 100644 index 00000000..d4a79f99 --- /dev/null +++ b/tools/hdi-gen/ast/ast_smq_type.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#ifndef OHOS_HDI_AST_SMQ_H +#define OHOS_HDI_AST_SMQ_H + +#include "ast/ast_type.h" + +namespace OHOS { +namespace HDI { +class ASTSharedMemQueueType : public ASTType { +public: + inline void SetInnerType(const AutoPtr& innerType) + { + innerType_ = innerType; + } + + bool IsSharedMemQueueType() override; + + String ToString() override; + + TypeKind GetTypeKind() override; + + String EmitCppType(TypeMode mode = TypeMode::NO_MODE) const override; + + void EmitCppWriteVar(const String& parcelName, const String& name, StringBuilder& sb, + const String& prefix, unsigned int innerLevel = 0) const override; + + void EmitCppReadVar(const String& parcelName, const String& name, StringBuilder& sb, + const String& prefix, bool initVariable, unsigned int innerLevel = 0) const override; + +private: + AutoPtr innerType_; +}; +} // namespace HDI +} // namespace OHOS + +#endif // OHOS_HDI_AST_SMQ_H \ No newline at end of file diff --git a/tools/hdi-gen/ast/ast_type.cpp b/tools/hdi-gen/ast/ast_type.cpp index 61b859e8..b1a9b1da 100755 --- a/tools/hdi-gen/ast/ast_type.cpp +++ b/tools/hdi-gen/ast/ast_type.cpp @@ -142,6 +142,11 @@ bool ASTType::IsFdType() return false; } +bool ASTType::IsSharedMemQueueType() +{ + return false; +} + String ASTType::ToShortString() { return name_; diff --git a/tools/hdi-gen/ast/ast_type.h b/tools/hdi-gen/ast/ast_type.h index 7e8cdd4a..09d4955d 100755 --- a/tools/hdi-gen/ast/ast_type.h +++ b/tools/hdi-gen/ast/ast_type.h @@ -42,6 +42,7 @@ enum class TypeKind { TYPE_ENUM, TYPE_STRUCT, TYPE_UNION, + TYPE_SMQ, }; enum class TypeMode { @@ -111,6 +112,8 @@ public: virtual bool IsFdType(); + virtual bool IsSharedMemQueueType(); + virtual String ToShortString(); String ToString() override; diff --git a/tools/hdi-gen/build_hdi_files.py b/tools/hdi-gen/build_hdi_files.py index 67aab067..80055564 100755 --- a/tools/hdi-gen/build_hdi_files.py +++ b/tools/hdi-gen/build_hdi_files.py @@ -32,22 +32,21 @@ # POSSIBILITY OF SUCH DAMAGE. import os +import re import sys - class IdlType: INTERFACE = 1 CALLBACK = 2 TYPES = 3 - def translate_file_name(file_name): name = file_name[1:] if file_name.startswith("I") else file_name translate_name = "" - for index,_ in enumerate(name): - c = name[index] + for i in range(len(name)): + c = name[i] if c >= 'A' and c <= 'Z': - if index > 1: + if i > 1: translate_name += "_" translate_name += c.lower() else: @@ -159,8 +158,7 @@ def cpp_interface_file_translate(idl_file, out_dir, part, outputs): iface_header_file = os.path.join(out_dir, "i" + file_name + ".h") client_proxy_header_file = os.path.join(out_dir, file_name + "_proxy.h") client_proxy_source_file = os.path.join(out_dir, file_name + "_proxy.cpp") - server_driver_source_file = os.path.join(out_dir, - file_name + "_driver.cpp") + server_driver_source_file = os.path.join(out_dir, file_name + "_driver.cpp") server_stub_header_file = os.path.join(out_dir, file_name + "_stub.h") server_stub_source_file = os.path.join(out_dir, file_name + "_stub.cpp") server_impl_header_file = os.path.join(out_dir, file_name + "_service.h") @@ -283,7 +281,7 @@ def get_compile_source_file(idl_files, language, out_dir, part): return outputs -def main(argv): +def get_files(argv): outputs = [] if len(argv) < 4: return outputs @@ -296,14 +294,44 @@ def main(argv): if option == "-o": outputs = idl_translate(files, language, out_dir) elif option == "-c": - outputs = get_compile_source_file(argv[4:], - language, out_dir, "client_lib_source") + outputs = get_compile_source_file(argv[4:], language, out_dir, "client_lib_source") elif option == "-s": - outputs = get_compile_source_file(argv[4:], - language, out_dir, "server_lib_source") + outputs = get_compile_source_file(argv[4:], language, out_dir, "server_lib_source") sys.stdout.write('\n'.join(outputs)) +def get_file_version(file_path): + major_version = 0 + minor_version = 0 + file = open(file_path, "r") + file_str = file.read() + result = re.findall(r'package\s\w+(?:\.\w+)*\.[V|v](\d+)_(\d+);', file_str) + + if len(result) > 0: + major_version = result[0][0] + minor_version = result[0][1] + file.close() + version = str(major_version) + "." + str(minor_version) + return version + + +def get_version(argv): + version = "0.0" + idl_files = argv[2:] + for idl_file in idl_files: + idl_file_type = get_idl_file_type(idl_file) + if idl_file_type == IdlType.INTERFACE: + version = get_file_version(idl_file) + break + sys.stdout.write(version) + + if __name__ == "__main__": - main(sys.argv) \ No newline at end of file + if len(sys.argv) < 1: + sys.stdout.write('\n') + option = sys.argv[1] + if option == "-v": + get_version(sys.argv) + else: + get_files(sys.argv) \ No newline at end of file diff --git a/tools/hdi-gen/codegen/c_client_proxy_code_emitter.cpp b/tools/hdi-gen/codegen/c_client_proxy_code_emitter.cpp index d325f6a5..ae87d1df 100755 --- a/tools/hdi-gen/codegen/c_client_proxy_code_emitter.cpp +++ b/tools/hdi-gen/codegen/c_client_proxy_code_emitter.cpp @@ -16,8 +16,7 @@ bool CClientProxyCodeEmitter::ResolveDirectory(const String& targetDirectory) { if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { - directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); + directory_ = GetFilePath(targetDirectory); } else { return false; } @@ -37,7 +36,7 @@ void CClientProxyCodeEmitter::EmitCode() void CClientProxyCodeEmitter::EmitProxySourceFile() { - String filePath = String::Format("%s%s.c", directory_.string(), FileName(proxyName_).string()); + String filePath = String::Format("%s/%s.c", directory_.string(), FileName(proxyName_).string()); File file(filePath, File::WRITE); StringBuilder sb; @@ -46,7 +45,12 @@ void CClientProxyCodeEmitter::EmitProxySourceFile() sb.Append("\n"); EmitProxyDefinition(sb); sb.Append("\n"); - EmitProxyCallMethodImpl(sb); + if (!isKernelCode_) { + EmitProxyCallMethodImpl(sb); + } else { + EmitProxyKernelCallMethodImpl(sb); + } + sb.Append("\n"); EmitProxyMethodImpls(sb); sb.Append("\n"); @@ -100,9 +104,7 @@ void CClientProxyCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFile headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_io_service_if")); } else { headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "servmgr_hdi")); - if (!isCallbackInterface()) { - headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_dlist")); - } + headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_dlist")); } const AST::TypeStringMap& types = ast_->GetTypes(); @@ -118,7 +120,7 @@ void CClientProxyCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFile void CClientProxyCodeEmitter::EmitProxyDefinition(StringBuilder& sb) { sb.AppendFormat("struct %sProxy {\n", infName_.string()); - sb.Append(g_tab).AppendFormat("struct %s instance;\n", interfaceName_.string()); + sb.Append(g_tab).AppendFormat("struct %s impl;\n", interfaceName_.string()); if (isKernelCode_) { sb.Append(g_tab).Append("struct HdfIoService *serv;\n"); } else { @@ -132,33 +134,51 @@ void CClientProxyCodeEmitter::EmitProxyCallMethodImpl(StringBuilder& sb) { sb.AppendFormat("static int32_t %sProxyCall(struct %s *self, int32_t id, struct HdfSBuf *data,\n", infName_.string(), interfaceName_.string()); - sb.Append(g_tab).Append("struct HdfSBuf *reply)\n"); + sb.Append(g_tab).Append("struct HdfSBuf *reply, bool isOneWay)\n"); sb.Append("{\n"); - String proxyName = "self"; - if (!isCallbackInterface()) { - sb.Append(g_tab).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(self, struct %sProxy, instance);\n", - infName_.string(), infName_.string()); - proxyName = "proxy"; - } - - String remoteName = isKernelCode_ ? "serv" : "remote"; - sb.Append(g_tab).AppendFormat("if (%s->%s == NULL\n", proxyName.string(), remoteName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("|| %s->%s->dispatcher == NULL\n", - proxyName.string(), remoteName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("|| %s->%s->dispatcher->Dispatch == NULL) {\n", - proxyName.string(), remoteName.string()); - sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: obj is null\", __func__);\n"); + String remoteName = "remote"; + sb.Append(g_tab).AppendFormat("struct HdfRemoteService *%s = self->AsObject(self);\n", remoteName.string()); + sb.Append(g_tab).AppendFormat("if (%s == NULL\n", remoteName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("|| %s->dispatcher == NULL\n", remoteName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("|| %s->dispatcher->Dispatch == NULL\n", remoteName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("|| %s->dispatcher->DispatchAsync == NULL) {\n", + remoteName.string()); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: Invalid HdfRemoteService obj\", __func__);\n"); sb.Append(g_tab).Append(g_tab).Append("return HDF_ERR_INVALID_OBJECT;\n"); sb.Append(g_tab).Append("}\n"); - if (isKernelCode_) { - sb.Append(g_tab).AppendFormat("return %s->serv->dispatcher->Dispatch", proxyName.string()); - sb.AppendFormat("((struct HdfObject *)&(%s->serv->object), id, data, reply);\n", proxyName.string()); - } else { - sb.Append(g_tab).AppendFormat("return %s->remote->dispatcher->Dispatch(%s->remote, id, data, reply);\n", - proxyName.string(), proxyName.string()); - } + sb.Append(g_tab).AppendFormat("if (isOneWay) {\n"); + sb.Append(g_tab).Append(g_tab).AppendFormat("return %s->dispatcher->DispatchAsync(%s, id, data, reply);\n", + remoteName.string(), remoteName.string()); + sb.Append(g_tab).AppendFormat("} else {\n"); + sb.Append(g_tab).Append(g_tab).AppendFormat("return %s->dispatcher->Dispatch(%s, id, data, reply);\n", + remoteName.string(), remoteName.string()); + sb.Append(g_tab).AppendFormat("}\n"); + sb.Append("}\n"); +} + +void CClientProxyCodeEmitter::EmitProxyKernelCallMethodImpl(StringBuilder& sb) +{ + sb.AppendFormat("static int32_t %sProxyCall(struct %s *self, int32_t id, struct HdfSBuf *data,\n", + infName_.string(), interfaceName_.string()); + sb.Append(g_tab).Append("struct HdfSBuf *reply)\n"); + sb.Append("{\n"); + + String remoteName = "serv"; + sb.Append(g_tab).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(self, struct %sProxy, impl);\n", + infName_.string(), infName_.string(), remoteName.string()); + sb.Append(g_tab).AppendFormat("struct HdfIoService *%s = proxy->%s;\n", remoteName.string(), remoteName.string()); + + sb.Append(g_tab).AppendFormat("if (%s == NULL\n", remoteName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("|| %s->dispatcher == NULL\n", remoteName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("|| %s->dispatcher->Dispatch == NULL) {\n", remoteName.string()); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: Invalid HdfRemoteService obj\", __func__);\n"); + sb.Append(g_tab).Append(g_tab).Append("return HDF_ERR_INVALID_OBJECT;\n"); + sb.Append(g_tab).Append("}\n\n"); + + sb.Append(g_tab).AppendFormat("return %s->dispatcher->Dispatch(", remoteName.string()); + sb.AppendFormat("(struct HdfObject *)&(%s->object), id, data, reply);\n", remoteName.string()); sb.Append("}\n"); } @@ -167,9 +187,14 @@ void CClientProxyCodeEmitter::EmitProxyMethodImpls(StringBuilder& sb) for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { AutoPtr method = interface_->GetMethod(i); EmitProxyMethodImpl(method, sb); - if (i + 1 != interface_->GetMethodNumber()) { - sb.Append("\n"); - } + sb.Append("\n"); + } + + EmitProxyMethodImpl(interface_->GetVersionMethod(), sb); + + if (!isKernelCode_) { + sb.Append("\n"); + EmitProxyAsObjectMethodImpl(sb); } } @@ -231,8 +256,14 @@ void CClientProxyCodeEmitter::EmitProxyMethodBody(const AutoPtr& meth } } - sb.Append(prefix + g_tab).AppendFormat("ec = %sCall(self, CMD_%s, %s, %s);\n", - proxyName_.string(), ConstantName(method->GetName()).string(), dataName.string(), replyName.string()); + if (!isKernelCode_) { + sb.Append(prefix + g_tab).AppendFormat("ec = %sCall(self, %s, %s, %s, %s);\n", proxyName_.string(), + EmitMethodCmdID(method).string(), dataName.string(), replyName.string(), + method->IsOneWay() ? "true" : "false"); + } else { + sb.Append(prefix + g_tab).AppendFormat("ec = %sCall(self, %s, %s, %s);\n", proxyName_.string(), + EmitMethodCmdID(method).string(), dataName.string(), replyName.string()); + } sb.Append(prefix + g_tab).Append("if (ec != HDF_SUCCESS) {\n"); sb.Append(prefix + g_tab + g_tab).Append( "HDF_LOGE(\"%{public}s: call failed! error code is %{public}d\", __func__, ec);\n"); @@ -240,11 +271,13 @@ void CClientProxyCodeEmitter::EmitProxyMethodBody(const AutoPtr& meth sb.Append(prefix + g_tab).Append("}\n"); sb.Append("\n"); - for (size_t i = 0; i < method->GetParameterNumber(); i++) { - AutoPtr param = method->GetParameter(i); - if (param->GetAttribute() == ParamAttr::PARAM_OUT) { - EmitReadProxyMethodParameter(param, replyName, gotoName, sb, prefix + g_tab); - sb.Append("\n"); + if (!method->IsOneWay()) { + for (size_t i = 0; i < method->GetParameterNumber(); i++) { + AutoPtr param = method->GetParameter(i); + if (param->GetAttribute() == ParamAttr::PARAM_OUT) { + EmitReadProxyMethodParameter(param, replyName, gotoName, sb, prefix + g_tab); + sb.Append("\n"); + } } } @@ -357,9 +390,23 @@ String CClientProxyCodeEmitter::GetGotLabel(const AutoPtr& method) return labelName; } +void CClientProxyCodeEmitter::EmitProxyAsObjectMethodImpl(StringBuilder& sb) +{ + sb.AppendFormat("static struct HdfRemoteService *%sProxyAsObject(struct %s *self)\n", + infName_.string(), interfaceName_.string()); + sb.Append("{\n"); + sb.Append(g_tab).Append("if (self == NULL) {\n"); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n"); + sb.Append(g_tab).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(self, struct %sProxy, impl);\n", + infName_.string(), infName_.string()); + sb.Append(g_tab).Append("return proxy->remote;\n"); + sb.Append("}\n"); +} + void CClientProxyCodeEmitter::EmitProxyConstruction(StringBuilder& sb) { - String objName = "instance"; + String objName = "impl"; sb.AppendFormat("static void %sProxyConstruct(struct %s *%s)\n", infName_.string(), interfaceName_.string(), objName.string()); sb.Append("{\n"); @@ -370,6 +417,14 @@ void CClientProxyCodeEmitter::EmitProxyConstruction(StringBuilder& sb) objName.string(), method->GetName().string(), infName_.string(), method->GetName().string()); } + AutoPtr getVerMethod = interface_->GetVersionMethod(); + sb.Append(g_tab).AppendFormat("%s->%s = %sProxy%s;\n", objName.string(), getVerMethod->GetName().string(), + infName_.string(), getVerMethod->GetName().string()); + + if (!isKernelCode_) { + sb.Append(g_tab).AppendFormat("%s->AsObject = %sProxyAsObject;\n", objName.string(), infName_.string()); + } + sb.Append("}\n"); } @@ -383,6 +438,9 @@ void CClientProxyCodeEmitter::EmitProxyGetMethodImpl(StringBuilder& sb) void CClientProxyCodeEmitter::EmitProxyGetInstanceMethodImpl(StringBuilder& sb) { + String objName = "client"; + String SerMajorName = "serMajorVer"; + String SerMinorName = "serMinorVer"; sb.AppendFormat("struct %s *%sGetInstance(const char *instanceName)\n", interfaceName_.string(), infName_.string()); sb.Append("{\n"); @@ -390,32 +448,45 @@ void CClientProxyCodeEmitter::EmitProxyGetInstanceMethodImpl(StringBuilder& sb) sb.Append(g_tab).Append("if (serviceMgr == NULL) {\n"); sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: HDIServiceManager not found!\", __func__);\n"); sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); - sb.Append(g_tab).Append("}\n"); - sb.Append("\n"); - + sb.Append(g_tab).Append("}\n\n"); sb.Append(g_tab).Append("struct HdfRemoteService *remote = "); sb.Append("serviceMgr->GetService(serviceMgr, instanceName);\n"); sb.Append(g_tab).Append("HDIServiceManagerRelease(serviceMgr);\n"); sb.Append(g_tab).Append("if (remote == NULL) {\n"); - sb.Append(g_tab).Append(g_tab).AppendFormat( - "HDF_LOGE(\"%%{public}s: %sService not found!\", __func__);\n", infName_.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: %sService not found!\", __func__);\n", + infName_.string()); sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); - sb.Append(g_tab).Append("}\n"); - sb.Append("\n"); - + sb.Append(g_tab).Append("}\n\n"); sb.Append(g_tab).AppendFormat("struct %sProxy *proxy = ", infName_.string()); - sb.AppendFormat("(struct %sProxy *)OsalMemAlloc(sizeof(struct %sProxy));\n", infName_.string(), infName_.string()); + sb.AppendFormat("(struct %sProxy *)OsalMemAlloc(sizeof(struct %sProxy));\n", infName_.string(), + infName_.string()); sb.Append(g_tab).Append("if (proxy == NULL) {\n"); sb.Append(g_tab).Append(g_tab).AppendFormat( "HDF_LOGE(\"%%{public}s: malloc %s proxy failed!\", __func__);\n", interfaceName_.string()); sb.Append(g_tab).Append(g_tab).Append("HdfRemoteServiceRecycle(remote);\n"); sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); - sb.Append(g_tab).Append("}\n"); - sb.Append("\n"); - + sb.Append(g_tab).Append("}\n\n"); sb.Append(g_tab).Append("proxy->remote = remote;\n"); - sb.Append(g_tab).AppendFormat("%sProxyConstruct(&proxy->instance);\n", infName_.string()); - sb.Append(g_tab).Append("return &proxy->instance;\n"); + sb.Append(g_tab).AppendFormat("struct %s *%s = &proxy->impl;\n", interfaceName_.string(), objName.string()); + sb.Append(g_tab).AppendFormat("%sProxyConstruct(%s);\n", infName_.string(), objName.string()); + sb.Append(g_tab).AppendFormat("uint32_t %s = 0;\n", SerMajorName.string()); + sb.Append(g_tab).AppendFormat("uint32_t %s = 0;\n", SerMinorName.string()); + sb.Append(g_tab).AppendFormat("int32_t ec = %s->GetVersion(%s, &%s, &%s);\n", objName.string(), objName.string(), + SerMajorName.string(), SerMinorName.string()); + sb.Append(g_tab).Append("if (ec != HDF_SUCCESS) {\n"); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: get version failed!\", __func__);\n"); + sb.Append(g_tab).Append(g_tab).AppendFormat("%sRelease(%s);\n", infName_.string(), objName.string()); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).AppendFormat("if (%s != %s) {\n", SerMajorName.string(), majorVerName_.string()); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s:check version failed! "); + sb.Append("version of service:%u.%u, version of client:%u.%u\", __func__,\n"); + sb.Append(g_tab).Append(g_tab).Append(g_tab).AppendFormat("%s, %s, %s, %s);\n", SerMajorName.string(), + SerMinorName.string(), majorVerName_.string(), minorVerName_.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("%sRelease(%s);\n", infName_.string(), objName.string()); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).AppendFormat("return %s;\n", objName.string()); sb.Append("}\n"); } @@ -443,25 +514,54 @@ void CClientProxyCodeEmitter::EmitKernelProxyGetInstanceMethodImpl(StringBuilder sb.Append("\n"); sb.Append(g_tab).Append("proxy->serv = serv;\n"); - sb.Append(g_tab).AppendFormat("%sProxyConstruct(&proxy->instance);\n", infName_.string()); - sb.Append(g_tab).Append("return &proxy->instance;\n"); + sb.Append(g_tab).AppendFormat("%sProxyConstruct(&proxy->impl);\n", infName_.string()); + sb.Append(g_tab).Append("return &proxy->impl;\n"); sb.Append("}\n"); } void CClientProxyCodeEmitter::EmitCbProxyGetMethodImpl(StringBuilder& sb) { + String objName = "client"; + String SerMajorName = "serMajorVer"; + String SerMinorName = "serMinorVer"; sb.AppendFormat("struct %s *%sGet(struct HdfRemoteService *remote)\n", interfaceName_.string(), infName_.string()); sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("struct %s *instance = (struct %s*)OsalMemAlloc(sizeof(struct %s));\n", - interfaceName_.string(), interfaceName_.string(), interfaceName_.string()); - sb.Append(g_tab).Append("if (instance == NULL) {\n"); - sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: OsalMemAlloc failed!\", __func__);\n"); + sb.Append(g_tab).Append("if (remote == NULL) {\n"); + sb.Append(g_tab).Append(g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: %sService not found!\", __func__);\n", + infName_.string()); sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); sb.Append(g_tab).Append("}\n\n"); - sb.Append(g_tab).Append("instance->remote = remote;\n"); - sb.Append(g_tab).AppendFormat("%sProxyConstruct(instance);\n", infName_.string()); - sb.Append(g_tab).Append("return instance;\n"); + sb.Append(g_tab).AppendFormat("struct %sProxy *proxy = ", infName_.string()); + sb.AppendFormat("(struct %sProxy *)OsalMemAlloc(sizeof(struct %sProxy));\n", infName_.string(), + infName_.string()); + sb.Append(g_tab).Append("if (proxy == NULL) {\n"); + sb.Append(g_tab).Append(g_tab).AppendFormat( + "HDF_LOGE(\"%%{public}s: malloc %s proxy failed!\", __func__);\n", interfaceName_.string()); + sb.Append(g_tab).Append(g_tab).Append("HdfRemoteServiceRecycle(remote);\n"); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).Append("proxy->remote = remote;\n"); + sb.Append(g_tab).AppendFormat("struct %s *%s = &proxy->impl;\n", interfaceName_.string(), objName.string()); + sb.Append(g_tab).AppendFormat("%sProxyConstruct(%s);\n", infName_.string(), objName.string()); + sb.Append(g_tab).AppendFormat("uint32_t %s = 0;\n", SerMajorName.string()); + sb.Append(g_tab).AppendFormat("uint32_t %s = 0;\n", SerMinorName.string()); + sb.Append(g_tab).AppendFormat("int32_t ec = %s->GetVersion(%s, &%s, &%s);\n", objName.string(), objName.string(), + SerMajorName.string(), SerMinorName.string()); + sb.Append(g_tab).Append("if (ec != HDF_SUCCESS) {\n"); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: get version failed!\", __func__);\n"); + sb.Append(g_tab).Append(g_tab).AppendFormat("%sRelease(%s);\n", infName_.string(), objName.string()); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).AppendFormat("if (%s != %s) {\n", SerMajorName.string(), majorVerName_.string()); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s:check version failed! "); + sb.Append("version of service:%u.%u, version of client:%u.%u\", __func__,\n"); + sb.Append(g_tab).Append(g_tab).Append(g_tab).AppendFormat("%s, %s, %s, %s);\n", SerMajorName.string(), + SerMinorName.string(), majorVerName_.string(), minorVerName_.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("%sRelease(%s);\n", infName_.string(), objName.string()); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).AppendFormat("return %s;\n", objName.string()); sb.Append("}\n"); } @@ -472,15 +572,10 @@ void CClientProxyCodeEmitter::EmitProxyReleaseMethodImpl(StringBuilder& sb) sb.Append(g_tab).Append("if (instance == NULL) {\n"); sb.Append(g_tab).Append(g_tab).Append("return;\n"); sb.Append(g_tab).Append("}\n"); - - if (!isCallbackInterface()) { - sb.Append(g_tab).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, instance);\n", - infName_.string(), infName_.string()); - sb.Append(g_tab).Append("HdfRemoteServiceRecycle(proxy->remote);\n"); - sb.Append(g_tab).Append("OsalMemFree(proxy);\n"); - } else { - sb.Append(g_tab).Append("OsalMemFree(instance);\n"); - } + sb.Append(g_tab).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, impl);\n", + infName_.string(), infName_.string()); + sb.Append(g_tab).Append("HdfRemoteServiceRecycle(proxy->remote);\n"); + sb.Append(g_tab).Append("OsalMemFree(proxy);\n"); sb.Append("}\n"); } @@ -491,7 +586,7 @@ void CClientProxyCodeEmitter::EmitKernelProxyReleaseMethodImpl(StringBuilder& sb sb.Append(g_tab).Append("if (instance == NULL) {\n"); sb.Append(g_tab).Append(g_tab).Append("return;\n"); sb.Append(g_tab).Append("}\n"); - sb.Append(g_tab).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, instance);\n", + sb.Append(g_tab).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, impl);\n", infName_.string(), infName_.string()); sb.Append(g_tab).Append("HdfIoServiceRecycle(proxy->serv);\n"); sb.Append(g_tab).Append("OsalMemFree(proxy);\n"); diff --git a/tools/hdi-gen/codegen/c_client_proxy_code_emitter.h b/tools/hdi-gen/codegen/c_client_proxy_code_emitter.h index 0c0c6448..c2bfe910 100755 --- a/tools/hdi-gen/codegen/c_client_proxy_code_emitter.h +++ b/tools/hdi-gen/codegen/c_client_proxy_code_emitter.h @@ -33,6 +33,8 @@ private: void EmitProxyCallMethodImpl(StringBuilder& sb); + void EmitProxyKernelCallMethodImpl(StringBuilder& sb); + void EmitProxyMethodImpls(StringBuilder& sb); void EmitProxyMethodImpl(const AutoPtr& method, StringBuilder& sb); @@ -49,6 +51,8 @@ private: String GetGotLabel(const AutoPtr& method); + void EmitProxyAsObjectMethodImpl(StringBuilder& sb); + void EmitProxyConstruction(StringBuilder&); void EmitProxyGetMethodImpl(StringBuilder& sb); diff --git a/tools/hdi-gen/codegen/c_code_emitter.cpp b/tools/hdi-gen/codegen/c_code_emitter.cpp index 6bed3067..ef704989 100755 --- a/tools/hdi-gen/codegen/c_code_emitter.cpp +++ b/tools/hdi-gen/codegen/c_code_emitter.cpp @@ -10,6 +10,7 @@ #include #include #include +#include "util/options.h" namespace OHOS { namespace HDI { @@ -19,13 +20,13 @@ String CCodeEmitter::FileName(const String& name) return name; } + String subName = Options::GetInstance().GetSubPackage(name); StringBuilder sb; - - for (int i = 0; i < name.GetLength(); i++) { - char c = name[i]; + for (int i = 0; i < subName.GetLength(); i++) { + char c = subName[i]; if (isupper(c) != 0) { // 2->Index of the last char array. - if (i > 1 && name[i - 1] != '.' && name[i - 2] != '.') { + if (i > 1 && subName[i - 1] != '.' && subName[i - 2] != '.') { sb.Append('_'); } sb.Append(tolower(c)); @@ -37,13 +38,21 @@ String CCodeEmitter::FileName(const String& name) return sb.ToString().Replace('.', '/'); } +String CCodeEmitter::EmitMethodCmdID(const AutoPtr& method) +{ + return String::Format("CMD_%s_%s", infName_.ToUnderLineUpper().string(), + method->GetName().ToUnderLineUpper().string()); +} + void CCodeEmitter::EmitInterfaceMethodCommands(StringBuilder& sb) { sb.Append("enum {\n"); for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { AutoPtr method = interface_->GetMethod(i); - sb.Append(g_tab).AppendFormat("CMD_%s,\n", ConstantName(method->GetName()).string()); + sb.Append(g_tab).Append(EmitMethodCmdID(method)).Append(",\n"); } + + sb.Append(g_tab).Append(EmitMethodCmdID(interface_->GetVersionMethod())).Append(",\n"); sb.Append("};\n"); } diff --git a/tools/hdi-gen/codegen/c_code_emitter.h b/tools/hdi-gen/codegen/c_code_emitter.h index 0ed14fa0..9e0abf87 100755 --- a/tools/hdi-gen/codegen/c_code_emitter.h +++ b/tools/hdi-gen/codegen/c_code_emitter.h @@ -23,6 +23,8 @@ public: static String FileName(const String& name); protected: + String EmitMethodCmdID(const AutoPtr& method); + void EmitInterfaceMethodCommands(StringBuilder& sb); void GetImportInclusions(HeaderFile::HeaderFileSet& headerFiles); diff --git a/tools/hdi-gen/codegen/c_custom_types_code_emitter.cpp b/tools/hdi-gen/codegen/c_custom_types_code_emitter.cpp index 51942e8a..75c77d9e 100755 --- a/tools/hdi-gen/codegen/c_custom_types_code_emitter.cpp +++ b/tools/hdi-gen/codegen/c_custom_types_code_emitter.cpp @@ -19,8 +19,7 @@ bool CCustomTypesCodeEmitter::ResolveDirectory(const String& targetDirectory) return false; } - directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); + directory_ = GetFilePath(targetDirectory); if (!File::CreateParentDir(directory_)) { Logger::E("CCustomTypesCodeEmitter", "Create '%s' failed!", directory_.string()); return false; @@ -161,7 +160,7 @@ void CCustomTypesCodeEmitter::EmitCustomTypeFreeDecl(StringBuilder& sb, void CCustomTypesCodeEmitter::EmitCustomTypesSourceFile() { - String filePath = String::Format("%s%s.c", directory_.string(), FileName(infName_).string()); + String filePath = String::Format("%s/%s.c", directory_.string(), FileName(infName_).string()); File file(filePath, File::WRITE); StringBuilder sb; diff --git a/tools/hdi-gen/codegen/c_interface_code_emitter.cpp b/tools/hdi-gen/codegen/c_interface_code_emitter.cpp index 1e536f12..d2c204e6 100755 --- a/tools/hdi-gen/codegen/c_interface_code_emitter.cpp +++ b/tools/hdi-gen/codegen/c_interface_code_emitter.cpp @@ -16,8 +16,7 @@ bool CInterfaceCodeEmitter::ResolveDirectory(const String& targetDirectory) { if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { - directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); + directory_ = GetFilePath(targetDirectory); } else { return false; } @@ -37,7 +36,7 @@ void CInterfaceCodeEmitter::EmitCode() void CInterfaceCodeEmitter::EmitInterfaceHeaderFile() { - String filePath = String::Format("%s%s.h", directory_.string(), FileName(interfaceName_).string()); + String filePath = String::Format("%s/%s.h", directory_.string(), FileName(interfaceName_).string()); File file(filePath, File::WRITE); StringBuilder sb; @@ -48,6 +47,10 @@ void CInterfaceCodeEmitter::EmitInterfaceHeaderFile() sb.Append("\n"); EmitHeadExternC(sb); sb.Append("\n"); + EmitPreDeclaration(sb); + sb.Append("\n"); + EmitInterfaceVersionMacro(sb); + sb.Append("\n"); EmitInterfaceMethodCommands(sb); sb.Append("\n"); EmitInterfaceDefinition(sb); @@ -83,13 +86,20 @@ void CInterfaceCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSe headerFiles.emplace(HeaderFile(HeaderFileType::C_STD_HEADER_FILE, "stdint")); } +void CInterfaceCodeEmitter::EmitPreDeclaration(StringBuilder& sb) +{ + sb.Append("struct HdfRemoteService;\n"); +} + +void CInterfaceCodeEmitter::EmitInterfaceVersionMacro(StringBuilder& sb) +{ + sb.AppendFormat("#define %s %u\n", majorVerName_.string(), ast_->GetMajorVer()); + sb.AppendFormat("#define %s %u\n", minorVerName_.string(), ast_->GetMinorVer()); +} + void CInterfaceCodeEmitter::EmitInterfaceDefinition(StringBuilder& sb) { sb.AppendFormat("struct %s {\n", interfaceName_.string()); - if (isCallbackInterface()) { - sb.Append(g_tab).Append("struct HdfRemoteService *remote;\n"); - sb.Append("\n"); - } EmitInterfaceMethods(sb, g_tab); sb.Append("};\n"); } @@ -99,9 +109,14 @@ void CInterfaceCodeEmitter::EmitInterfaceMethods(StringBuilder& sb, const String for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { AutoPtr method = interface_->GetMethod(i); EmitInterfaceMethod(method, sb, prefix); - if (i + 1 < interface_->GetMethodNumber()) { - sb.Append("\n"); - } + sb.Append("\n"); + } + + EmitInterfaceMethod(interface_->GetVersionMethod(), sb, prefix); + + if (!isKernelCode_) { + sb.Append("\n"); + EmitAsObjectMethod(sb, g_tab); } } @@ -129,6 +144,12 @@ void CInterfaceCodeEmitter::EmitInterfaceMethod(const AutoPtr& method } } +void CInterfaceCodeEmitter::EmitAsObjectMethod(StringBuilder& sb, const String& prefix) +{ + sb.Append(prefix).AppendFormat("struct HdfRemoteService* (*AsObject)(struct %s *self);\n", + interfaceName_.string()); +} + void CInterfaceCodeEmitter::EmitInterfaceGetMethodDecl(StringBuilder& sb) { String methodParamStr = isCallbackInterface() ? "struct HdfRemoteService *remote" : "void"; @@ -144,5 +165,6 @@ void CInterfaceCodeEmitter::EmitInterfaceReleaseMethodDecl(StringBuilder& sb) { sb.AppendFormat("void %sRelease(struct %s *instance);\n", infName_.string(), interfaceName_.string()); } + } // namespace HDI } // namespace OHOS \ No newline at end of file diff --git a/tools/hdi-gen/codegen/c_interface_code_emitter.h b/tools/hdi-gen/codegen/c_interface_code_emitter.h index 933dfb0b..33ae81b8 100755 --- a/tools/hdi-gen/codegen/c_interface_code_emitter.h +++ b/tools/hdi-gen/codegen/c_interface_code_emitter.h @@ -29,12 +29,18 @@ private: void GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet& headerFiles); + void EmitPreDeclaration(StringBuilder& sb); + + void EmitInterfaceVersionMacro(StringBuilder& sb); + void EmitInterfaceDefinition(StringBuilder& sb); void EmitInterfaceMethods(StringBuilder& sb, const String& prefix); void EmitInterfaceMethod(const AutoPtr& method, StringBuilder& sb, const String& prefix); + void EmitAsObjectMethod(StringBuilder& sb, const String& prefix); + void EmitInterfaceGetMethodDecl(StringBuilder& sb); void EmitInterfaceReleaseMethodDecl(StringBuilder& sb); diff --git a/tools/hdi-gen/codegen/c_service_driver_code_emitter.cpp b/tools/hdi-gen/codegen/c_service_driver_code_emitter.cpp index 1f3efb4a..6e818a95 100755 --- a/tools/hdi-gen/codegen/c_service_driver_code_emitter.cpp +++ b/tools/hdi-gen/codegen/c_service_driver_code_emitter.cpp @@ -19,8 +19,7 @@ bool CServiceDriverCodeEmitter::ResolveDirectory(const String& targetDirectory) return false; } - directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); + directory_ = GetFilePath(targetDirectory); if (!File::CreateParentDir(directory_)) { Logger::E("CServiceDriverCodeEmitter", "Create '%s' failed!", directory_.string()); return false; @@ -39,7 +38,7 @@ void CServiceDriverCodeEmitter::EmitCode() void CServiceDriverCodeEmitter::EmitDriverSourceFile() { - String filePath = String::Format("%s%s.c", directory_.string(), FileName(infName_ + "Driver").string()); + String filePath = String::Format("%s/%s.c", directory_.string(), FileName(infName_ + "Driver").string()); File file(filePath, File::WRITE); StringBuilder sb; @@ -69,6 +68,7 @@ void CServiceDriverCodeEmitter::EmitDriverIncluions(StringBuilder& sb) HeaderFile::HeaderFileSet headerFiles; headerFiles.emplace(HeaderFile(HeaderFileType::OWN_MODULE_HEADER_FILE, FileName(stubName_))); + headerFiles.emplace(HeaderFile(HeaderFileType::OWN_MODULE_HEADER_FILE, FileName(implName_))); GetDriverSourceOtherLibInclusions(headerFiles); for (const auto& file : headerFiles) { @@ -88,7 +88,7 @@ void CServiceDriverCodeEmitter::EmitDriverServiceDecl(StringBuilder& sb) { sb.AppendFormat("struct Hdf%sHost {\n", infName_.string()); sb.Append(g_tab).AppendFormat("struct IDeviceIoService ioservice;\n"); - sb.Append(g_tab).Append("void *instance;\n"); + sb.Append(g_tab).AppendFormat("struct %s *service;\n", interfaceName_.string()); sb.Append("};\n"); } @@ -103,7 +103,7 @@ void CServiceDriverCodeEmitter::EmitDriverDispatch(StringBuilder& sb) infName_.string(), hostName.string()); sb.Append(g_tab).Append(g_tab).AppendFormat("client->device->service, struct Hdf%sHost, ioservice);\n", infName_.string()); - sb.Append(g_tab).AppendFormat("return %sServiceOnRemoteRequest(%s->instance, cmdId, data, reply);\n", + sb.Append(g_tab).AppendFormat("return %sServiceOnRemoteRequest(%s->service, cmdId, data, reply);\n", infName_.string(), hostName.string()); sb.Append("}\n"); } @@ -137,12 +137,13 @@ void CServiceDriverCodeEmitter::EmitDriverBind(StringBuilder& sb) hostName.string(), infName_.string()); sb.Append(g_tab).AppendFormat("%s->ioservice.Open = NULL;\n", hostName.string()); sb.Append(g_tab).AppendFormat("%s->ioservice.Release = NULL;\n", hostName.string()); - sb.Append(g_tab).AppendFormat("%s->instance = %sStubGetInstance();\n", hostName.string(), infName_.string()); - sb.Append(g_tab).AppendFormat("if (%s->instance == NULL) {\n", hostName.string()); + sb.Append(g_tab).AppendFormat("%s->service = %sStubGetInstance();\n", hostName.string(), infName_.string()); + sb.Append(g_tab).AppendFormat("if (%s->service == NULL) {\n", hostName.string()); sb.Append(g_tab).Append(g_tab).AppendFormat("OsalMemFree(%s);\n", hostName.string()); sb.Append(g_tab).Append(g_tab).Append("return HDF_FAILURE;\n"); sb.Append(g_tab).Append("}\n"); sb.Append("\n"); + sb.Append(g_tab).AppendFormat("%sServiceConstruct(%s->service);\n", infName_.string(), hostName.string()); sb.Append(g_tab).AppendFormat("deviceObject->service = &%s->ioservice;\n", hostName.string()); sb.Append(g_tab).Append("return HDF_SUCCESS;\n"); sb.Append("}\n"); @@ -157,7 +158,7 @@ void CServiceDriverCodeEmitter::EmitDriverRelease(StringBuilder& sb) sb.Append(g_tab).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", infName_.string(), hostName.string()); sb.AppendFormat("deviceObject->service, struct Hdf%sHost, ioservice);\n", infName_.string()); - sb.Append(g_tab).AppendFormat("%sStubRelease(%s->instance);\n", infName_.string(), hostName.string()); + sb.Append(g_tab).AppendFormat("%sStubRelease(%s->service);\n", infName_.string(), hostName.string()); sb.Append(g_tab).AppendFormat("OsalMemFree(%s);\n", hostName.string()); sb.Append("}\n"); } diff --git a/tools/hdi-gen/codegen/c_service_impl_code_emitter.cpp b/tools/hdi-gen/codegen/c_service_impl_code_emitter.cpp index e73d3bd9..a6926119 100755 --- a/tools/hdi-gen/codegen/c_service_impl_code_emitter.cpp +++ b/tools/hdi-gen/codegen/c_service_impl_code_emitter.cpp @@ -16,8 +16,7 @@ bool CServiceImplCodeEmitter::ResolveDirectory(const String& targetDirectory) { if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { - directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); + directory_ = GetFilePath(targetDirectory); } else { return false; } @@ -38,7 +37,7 @@ void CServiceImplCodeEmitter::EmitCode() void CServiceImplCodeEmitter::EmitServiceImplHeaderFile() { - String filePath = String::Format("%s%s.h", directory_.string(), FileName(infName_ + "Service").string()); + String filePath = String::Format("%s/%s.h", directory_.string(), FileName(infName_ + "Service").string()); File file(filePath, File::WRITE); StringBuilder sb; @@ -79,7 +78,7 @@ void CServiceImplCodeEmitter::EmitServiceImplConstructDecl(StringBuilder& sb) void CServiceImplCodeEmitter::EmitServiceImplSourceFile() { - String filePath = String::Format("%s%s.c", directory_.string(), FileName(infName_ + "Service").string()); + String filePath = String::Format("%s/%s.c", directory_.string(), FileName(infName_ + "Service").string()); File file(filePath, File::WRITE); StringBuilder sb; diff --git a/tools/hdi-gen/codegen/c_service_stub_code_emitter.cpp b/tools/hdi-gen/codegen/c_service_stub_code_emitter.cpp index 4ccf0d70..bdf2df7d 100755 --- a/tools/hdi-gen/codegen/c_service_stub_code_emitter.cpp +++ b/tools/hdi-gen/codegen/c_service_stub_code_emitter.cpp @@ -17,8 +17,7 @@ bool CServiceStubCodeEmitter::ResolveDirectory(const String& targetDirectory) { if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { - directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); + directory_ = GetFilePath(targetDirectory); } else { return false; } @@ -39,7 +38,7 @@ void CServiceStubCodeEmitter::EmitCode() void CServiceStubCodeEmitter::EmitServiceStubHeaderFile() { - String filePath = String::Format("%s%s.h", directory_.string(), FileName(stubName_).string()); + String filePath = String::Format("%s/%s.h", directory_.string(), FileName(stubName_).string()); File file(filePath, File::WRITE); StringBuilder sb; @@ -76,8 +75,9 @@ void CServiceStubCodeEmitter::EmitStubHeaderInclusions(StringBuilder& sb) void CServiceStubCodeEmitter::EmitCbServiceStubMethodsDcl(StringBuilder& sb) { if (!isCallbackInterface()) { - sb.AppendFormat("int32_t %sServiceOnRemoteRequest(void *service, int cmdId, ", infName_.string()); - sb.Append("struct HdfSBuf *data, struct HdfSBuf *reply);\n"); + sb.AppendFormat("int32_t %sServiceOnRemoteRequest(struct %s *serviceImpl, ", infName_.string(), + interfaceName_.string()); + sb.Append("int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply);\n"); sb.Append("\n"); } sb.AppendFormat("struct %s* %sStubGetInstance(void);\n", interfaceName_.string(), infName_.string()); @@ -87,7 +87,7 @@ void CServiceStubCodeEmitter::EmitCbServiceStubMethodsDcl(StringBuilder& sb) void CServiceStubCodeEmitter::EmitServiceStubSourceFile() { - String filePath = String::Format("%s%s.c", directory_.string(), FileName(stubName_).string()); + String filePath = String::Format("%s/%s.c", directory_.string(), FileName(stubName_).string()); File file(filePath, File::WRITE); StringBuilder sb; @@ -96,23 +96,23 @@ void CServiceStubCodeEmitter::EmitServiceStubSourceFile() sb.Append("\n"); if (!isKernelCode_) { - EmitDriverLibPath(sb); - sb.Append("\n"); - EmitServConstructTypedef(sb); - sb.Append("\n"); - EmitCbStubDefinitions(sb); + EmitStubDefinitions(sb); sb.Append("\n"); } EmitServiceStubMethodImpls(sb, ""); sb.Append("\n"); - EmitServiceStubOnRequestMethodImpl(sb, ""); - sb.Append("\n"); if (isKernelCode_) { + EmitServiceStubOnRequestMethodImpl(sb, ""); + sb.Append("\n"); EmitKernelStubGetMethodImpl(sb); } else { - EmitStubLinkService(sb); + EmitStubOnRequestMethodImpl(sb, ""); sb.Append("\n"); + if (!isCallbackInterface()) { + EmitServiceStubOnRequestMethodImpl(sb, ""); + sb.Append("\n"); + } EmitStubGetMethodImpl(sb); } @@ -132,23 +132,17 @@ void CServiceStubCodeEmitter::EmitServiceStubSourceFile() void CServiceStubCodeEmitter::EmitStubSourceInclusions(StringBuilder& sb) { HeaderFile::HeaderFileSet headerFiles; - if (!isCallbackInterface()) { - headerFiles.emplace(HeaderFile(HeaderFileType::OWN_HEADER_FILE, FileName(stubName_))); - if (isKernelCode_) { - headerFiles.emplace(HeaderFile(HeaderFileType::OWN_MODULE_HEADER_FILE, FileName(implName_))); - } else { - for (const auto& importPair : ast_->GetImports()) { - AutoPtr importAst = importPair.second; - if (importAst->GetASTFileType() == ASTFileType::AST_ICALLBACK) { - String fileName = FileName(importAst->GetInterfaceDef()->GetFullName()); - headerFiles.emplace(HeaderFile(HeaderFileType::OWN_MODULE_HEADER_FILE, fileName)); - } + + headerFiles.emplace(HeaderFile(HeaderFileType::OWN_HEADER_FILE, FileName(stubName_))); + + if (!isKernelCode_ && !isCallbackInterface()) { + for (const auto& importPair : ast_->GetImports()) { + AutoPtr importAst = importPair.second; + if (importAst->GetASTFileType() == ASTFileType::AST_ICALLBACK) { + String fileName = FileName(importAst->GetInterfaceDef()->GetFullName()); + headerFiles.emplace(HeaderFile(HeaderFileType::OWN_MODULE_HEADER_FILE, fileName)); } } - } else { - headerFiles.emplace(HeaderFile(HeaderFileType::OWN_HEADER_FILE, FileName(stubName_))); - headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_remote_service")); - headerFiles.emplace(HeaderFile(HeaderFileType::OWN_MODULE_HEADER_FILE, FileName(implName_))); } GetSourceOtherLibInclusions(headerFiles); @@ -161,8 +155,8 @@ void CServiceStubCodeEmitter::EmitStubSourceInclusions(StringBuilder& sb) void CServiceStubCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet& headerFiles) { if (!isKernelCode_) { - headerFiles.emplace(HeaderFile(HeaderFileType::SYSTEM_HEADER_FILE, "dlfcn")); headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec")); + headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_remote_service")); } else { const AST::TypeStringMap& types = ast_->GetTypes(); for (const auto& pair : types) { @@ -181,28 +175,12 @@ void CServiceStubCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFile headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem")); } -void CServiceStubCodeEmitter::EmitDriverLibPath(StringBuilder& sb) -{ - sb.Append("#ifdef __ARM64__\n"); - sb.Append("#define DRIVER_PATH \"system/lib64\"\n"); - sb.Append("#else\n"); - sb.Append("#define DRIVER_PATH \"system/lib\"\n"); - sb.Append("#endif\n"); -} - -void CServiceStubCodeEmitter::EmitServConstructTypedef(StringBuilder& sb) -{ - sb.AppendFormat("typedef void (*SERVICE_CONSTRUCT_FUNC)(struct %s *);\n", interfaceName_.string()); -} - -void CServiceStubCodeEmitter::EmitCbStubDefinitions(StringBuilder& sb) +void CServiceStubCodeEmitter::EmitStubDefinitions(StringBuilder& sb) { sb.AppendFormat("struct %sStub {\n", infName_.string()); - sb.Append(g_tab).AppendFormat("struct %s service;\n", interfaceName_.string()); - if (isCallbackInterface()) { - sb.Append(g_tab).Append("struct HdfRemoteDispatcher dispatcher;\n"); - } - sb.Append(g_tab).Append("void *dlHandler;\n"); + sb.Append(g_tab).AppendFormat("struct %s impl;\n", interfaceName_.string()); + sb.Append(g_tab).Append("struct HdfRemoteService *remote;\n"); + sb.Append(g_tab).Append("struct HdfRemoteDispatcher dispatcher;\n"); sb.Append("};\n"); } @@ -211,10 +189,12 @@ void CServiceStubCodeEmitter::EmitServiceStubMethodImpls(StringBuilder& sb, cons for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { AutoPtr method = interface_->GetMethod(i); EmitServiceStubMethodImpl(method, sb, prefix); - if (i + 1 < interface_->GetMethodNumber()) { - sb.Append("\n"); - } + sb.Append("\n"); } + + EmitStubGetVerMethodImpl(interface_->GetVersionMethod(), sb, prefix); + sb.Append("\n"); + EmitStubAsObjectMethodImpl(sb, prefix); } void CServiceStubCodeEmitter::EmitServiceStubMethodImpl(const AutoPtr& method, StringBuilder& sb, @@ -387,32 +367,70 @@ void CServiceStubCodeEmitter::EmitCallParameter(StringBuilder& sb, const AutoPtr } } -void CServiceStubCodeEmitter::EmitServiceStubOnRequestMethodImpl(StringBuilder& sb, const String& prefix) +void CServiceStubCodeEmitter::EmitStubGetVerMethodImpl(const AutoPtr& method, StringBuilder& sb, + const String& prefix) { - String codeName; - if (!isCallbackInterface()) { - codeName = "cmdId"; - sb.Append(prefix).AppendFormat("int32_t %sServiceOnRemoteRequest(void *service, int %s, ", - infName_.string(), codeName.string()); - sb.Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n"); - } else { - codeName = "code"; - sb.Append(prefix).AppendFormat("int32_t %sServiceOnRemoteRequest(struct HdfRemoteService *service, int %s,\n", - infName_.string(), codeName.string()); - sb.Append(prefix + g_tab).Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n"); - } + String dataName = "data_"; + String replyName = "reply_"; + sb.Append(prefix).AppendFormat( + "static int32_t SerStub%s(struct %s *serviceImpl, struct HdfSBuf *%s, struct HdfSBuf *%s)\n", + method->GetName().string(), interfaceName_.string(), dataName.string(), replyName.string()); sb.Append(prefix).Append("{\n"); - sb.Append(prefix + g_tab).AppendFormat("struct %s *serviceImpl = (struct %s*)service;\n", - interfaceName_.string(), interfaceName_.string()); + sb.Append(prefix + g_tab).Append("int32_t ec = HDF_FAILURE;\n"); + + String gotoName = "errors"; + AutoPtr type = new ASTUintType(); + type->EmitCWriteVar(replyName, majorVerName_, gotoName, sb, prefix + g_tab); + sb.Append("\n"); + type->EmitCWriteVar(replyName, minorVerName_, gotoName, sb, prefix + g_tab); + sb.Append("\n"); + + sb.Append(gotoName).Append(":\n"); + sb.Append(prefix + g_tab).Append("return ec;\n"); + sb.Append(prefix).Append("}\n"); +} + +void CServiceStubCodeEmitter::EmitStubAsObjectMethodImpl(StringBuilder& sb, const String& prefix) +{ + String objName = "self"; + sb.Append(prefix).AppendFormat("static struct HdfRemoteService *%sStubAsObject(struct %s *%s)\n", + infName_.string(), interfaceName_.string(), objName.string()); + sb.Append(prefix).Append("{\n"); + + sb.Append(prefix + g_tab).AppendFormat("if (%s == NULL) {\n", objName.string()); + sb.Append(prefix + g_tab + g_tab).Append("return NULL;\n"); + sb.Append(prefix + g_tab).Append("}\n"); + + sb.Append(prefix + g_tab).AppendFormat("struct %sStub *stub = CONTAINER_OF(%s, struct %sStub, impl);\n", + infName_.string(), objName.string(), infName_.string()); + sb.Append(prefix + g_tab).Append("return stub->remote;\n"); + sb.Append(prefix).Append("}\n"); +} + +void CServiceStubCodeEmitter::EmitStubOnRequestMethodImpl(StringBuilder& sb, const String& prefix) +{ + String implName = "remote"; + String codeName = "code"; + sb.Append(prefix).AppendFormat("static int32_t OnRemoteRequest(struct HdfRemoteService *%s, int %s, ", + implName.string(), codeName.string()); + sb.Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n"); + sb.Append(prefix).Append("{\n"); + sb.Append(prefix + g_tab).AppendFormat("struct %s *serviceImpl = (struct %s*)%s;\n", + interfaceName_.string(), interfaceName_.string(), implName.string()); sb.Append(prefix + g_tab).AppendFormat("switch (%s) {\n", codeName.string()); for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { AutoPtr method = interface_->GetMethod(i); - sb.Append(prefix + g_tab + g_tab).AppendFormat("case CMD_%s:\n", ConstantName(method->GetName()).string()); + sb.Append(prefix + g_tab + g_tab).AppendFormat("case %s:\n", EmitMethodCmdID(method).string()); sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat("return SerStub%s(serviceImpl, data, reply);\n", method->GetName().string()); } + AutoPtr getVerMethod = interface_->GetVersionMethod(); + sb.Append(prefix + g_tab + g_tab).AppendFormat("case %s:\n", EmitMethodCmdID(getVerMethod).string()); + sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat("return SerStub%s(serviceImpl, data, reply);\n", + getVerMethod->GetName().string()); + sb.Append(prefix + g_tab + g_tab).Append("default: {\n"); sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat( "HDF_LOGE(\"%%{public}s: not support cmd %%{public}d\", __func__, %s);\n", codeName.string()); @@ -422,44 +440,44 @@ void CServiceStubCodeEmitter::EmitServiceStubOnRequestMethodImpl(StringBuilder& sb.Append("}\n"); } -void CServiceStubCodeEmitter::EmitStubLinkService(StringBuilder& sb) +void CServiceStubCodeEmitter::EmitServiceStubOnRequestMethodImpl(StringBuilder& sb, const String& prefix) { - sb.Append("static void *LoadServiceHandler(const char* libFileName)\n"); - sb.Append("{\n"); - sb.Append(g_tab).Append("char path[PATH_MAX + 1] = {0};\n"); - sb.Append(g_tab).Append("char libPath[PATH_MAX + 1] = {0};\n"); - sb.Append(g_tab).Append("void *handler = NULL;\n"); - sb.Append("\n"); - sb.Append(g_tab).AppendFormat("if (snprintf_s(path, sizeof(path), sizeof(path) - 1, \"%%s/%%s\", "); - sb.Append("DRIVER_PATH, libFileName) < 0) {\n"); - sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: snprintf_s failed\", __func__);\n"); - sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); - sb.Append(g_tab).Append("}\n"); - sb.Append("\n"); - sb.Append(g_tab).Append("if (realpath(path, libPath) == NULL) {\n"); - sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s file name invalid\", __func__);\n"); - sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); - sb.Append(g_tab).Append("}\n"); - sb.Append("\n"); - sb.Append(g_tab).Append("handler = dlopen(libPath, RTLD_LAZY);\n"); - sb.Append(g_tab).Append("if (handler == NULL) {\n"); - sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: dlopen failed %{public}s\", "); - sb.AppendFormat("__func__, dlerror());\n"); - sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); - sb.Append(g_tab).Append("}\n"); - sb.Append("\n"); - sb.Append(g_tab).Append("return handler;\n"); + String implName = "serviceImpl"; + String codeName = "cmdId"; + sb.Append(prefix).AppendFormat("int32_t %sServiceOnRemoteRequest(struct %s *%s, int %s, ", + infName_.string(), interfaceName_.string(), implName.string(), codeName.string()); + sb.Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n"); + sb.Append(prefix).Append("{\n"); + sb.Append(prefix + g_tab).AppendFormat("switch (%s) {\n", codeName.string()); + + for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { + AutoPtr method = interface_->GetMethod(i); + sb.Append(prefix + g_tab + g_tab).AppendFormat("case %s:\n", EmitMethodCmdID(method).string()); + sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat("return SerStub%s(%s, data, reply);\n", + method->GetName().string(), implName.string()); + } + + AutoPtr getVerMethod = interface_->GetVersionMethod(); + sb.Append(prefix + g_tab + g_tab).AppendFormat("case %s:\n", EmitMethodCmdID(getVerMethod).string()); + sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat("return SerStub%s(serviceImpl, data, reply);\n", + getVerMethod->GetName().string()); + + sb.Append(prefix + g_tab + g_tab).Append("default: {\n"); + sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat( + "HDF_LOGE(\"%%{public}s: not support cmd %%{public}d\", __func__, %s);\n", codeName.string()); + sb.Append(prefix + g_tab + g_tab + g_tab).Append("return HDF_ERR_INVALID_PARAM;\n"); + sb.Append(prefix + g_tab + g_tab).Append("}\n"); + sb.Append(prefix + g_tab).Append("}\n"); sb.Append("}\n"); } void CServiceStubCodeEmitter::EmitStubGetMethodImpl(StringBuilder& sb) { - String libName = String::Format("lib%s.z.so", FileName(implName_).string()); String stubTypeName = String::Format("%sStub", infName_.string()); String objName = "stub"; + sb.AppendFormat("struct %s *%sStubGetInstance(void)\n", interfaceName_.string(), infName_.string()); sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("SERVICE_CONSTRUCT_FUNC serviceConstructFunc = NULL;\n", libName.string()); sb.Append(g_tab).AppendFormat("struct %s *%s = (struct %s *)OsalMemAlloc(sizeof(struct %s));\n", stubTypeName.string(), objName.string(), stubTypeName.string(), stubTypeName.string()); sb.Append(g_tab).AppendFormat("if (%s == NULL) {\n", objName.string()); @@ -467,38 +485,19 @@ void CServiceStubCodeEmitter::EmitStubGetMethodImpl(StringBuilder& sb) stubTypeName.string()); sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); sb.Append(g_tab).Append("}\n\n"); - if (isCallbackInterface()) { - sb.Append(g_tab).AppendFormat("%s->dispatcher.Dispatch = %sServiceOnRemoteRequest;\n", - objName.string(), infName_.string()); - sb.Append(g_tab).AppendFormat( - "%s->service.remote = HdfRemoteServiceObtain((struct HdfObject*)%s, &(%s->dispatcher));\n", - objName.string(), objName.string(), objName.string()); - sb.Append(g_tab).AppendFormat("if (%s->service.remote == NULL) {\n", objName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat( - "HDF_LOGE(\"%%{public}s: %s->service.remote is null\", __func__);\n", objName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("OsalMemFree(%s);\n", objName.string()); - sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); - sb.Append(g_tab).Append("}\n\n"); - } - sb.Append(g_tab).AppendFormat("%s->dlHandler = LoadServiceHandler(\"lib%s.z.so\");\n", - objName.string(), FileName(implName_).string()); - sb.Append(g_tab).AppendFormat("if (%s->dlHandler == NULL) {\n", objName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: %s->dlHanlder is null\", __func__);\n", - objName.string()); + sb.Append(g_tab).AppendFormat("%s->dispatcher.Dispatch = OnRemoteRequest;\n", objName.string()); + sb.Append(g_tab).AppendFormat( + "%s->remote = HdfRemoteServiceObtain((struct HdfObject*)%s, &(%s->dispatcher));\n", + objName.string(), objName.string(), objName.string()); + sb.Append(g_tab).AppendFormat("if (%s->remote == NULL) {\n", objName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat( + "HDF_LOGE(\"%%{public}s: %s->remote is null\", __func__);\n", objName.string()); sb.Append(g_tab).Append(g_tab).AppendFormat("OsalMemFree(%s);\n", objName.string()); sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); sb.Append(g_tab).Append("}\n\n"); - sb.Append(g_tab).AppendFormat("serviceConstructFunc = "); - sb.AppendFormat("(SERVICE_CONSTRUCT_FUNC)dlsym(%s->dlHandler, \"%sServiceConstruct\");\n", - objName.string(), infName_.string()); - sb.Append(g_tab).Append("if (serviceConstructFunc == NULL) {\n"); - sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: dlsym failed %{public}s\", __func__, dlerror());\n"); - sb.Append(g_tab).Append(g_tab).AppendFormat("dlclose(%s->dlHandler);\n", objName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("OsalMemFree(%s);\n", objName.string()); - sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); - sb.Append(g_tab).Append("}\n\n"); - sb.Append(g_tab).AppendFormat("serviceConstructFunc(&%s->service);\n", objName.string()); - sb.Append(g_tab).AppendFormat("return &%s->service;\n", objName.string()); + + sb.Append(g_tab).AppendFormat("%s->impl.AsObject = %sStubAsObject;\n", objName.string(), infName_.string()); + sb.Append(g_tab).AppendFormat("return &%s->impl;\n", objName.string()); sb.Append("}\n"); } @@ -522,14 +521,15 @@ void CServiceStubCodeEmitter::EmitKernelStubGetMethodImpl(StringBuilder& sb) void CServiceStubCodeEmitter::EmitStubReleaseImpl(StringBuilder& sb) { - sb.AppendFormat("void %sStubRelease(struct %s *instance)\n", infName_.string(), interfaceName_.string()); + String objName = "instance"; + sb.AppendFormat("void %sStubRelease(struct %s *%s)\n", infName_.string(), interfaceName_.string(), + objName.string()); sb.Append("{\n"); - sb.Append(g_tab).Append("if (instance == NULL) {\n"); + sb.Append(g_tab).AppendFormat("if (%s == NULL) {\n", objName.string()); sb.Append(g_tab).Append(g_tab).Append("return;\n"); - sb.Append(g_tab).Append("}\n"); - sb.Append(g_tab).AppendFormat("struct %s *stub = CONTAINER_OF(instance, struct %s, service);\n", - stubName_.string(), stubName_.string()); - sb.Append(g_tab).Append("dlclose(stub->dlHandler);\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).AppendFormat("struct %s *stub = CONTAINER_OF(%s, struct %s, impl);\n", stubName_.string(), + objName.string(), stubName_.string()); sb.Append(g_tab).Append("OsalMemFree(stub);\n"); sb.Append("}"); } diff --git a/tools/hdi-gen/codegen/c_service_stub_code_emitter.h b/tools/hdi-gen/codegen/c_service_stub_code_emitter.h index e888015e..885604c2 100755 --- a/tools/hdi-gen/codegen/c_service_stub_code_emitter.h +++ b/tools/hdi-gen/codegen/c_service_stub_code_emitter.h @@ -35,9 +35,7 @@ private: void GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet& headerFiles); - void EmitDriverLibPath(StringBuilder& sb); - - void EmitServConstructTypedef(StringBuilder& sb); + void EmitStubDefinitions(StringBuilder& sb); void EmitServiceStubMethodImpls(StringBuilder& sb, const String& prefix); @@ -56,16 +54,18 @@ private: void EmitCallParameter(StringBuilder& sb, const AutoPtr& type, ParamAttr attribute, const String& name); - void EmitServiceStubOnRequestMethodImpl(StringBuilder& sb, const String& prefix); + void EmitStubGetVerMethodImpl(const AutoPtr& method, StringBuilder& sb, const String& prefix); - void EmitCbStubDefinitions(StringBuilder& sb); + void EmitStubAsObjectMethodImpl(StringBuilder& sb, const String& prefix); + + void EmitStubOnRequestMethodImpl(StringBuilder& sb, const String& prefix); + + void EmitServiceStubOnRequestMethodImpl(StringBuilder& sb, const String& prefix); void EmitStubGetMethodImpl(StringBuilder& sb); void EmitKernelStubGetMethodImpl(StringBuilder& sb); - void EmitStubLinkService(StringBuilder& sb); - void EmitStubReleaseImpl(StringBuilder& sb); void EmitKernelStubReleaseImpl(StringBuilder& sb); diff --git a/tools/hdi-gen/codegen/code_emitter.cpp b/tools/hdi-gen/codegen/code_emitter.cpp index e092349f..7fd4209c 100755 --- a/tools/hdi-gen/codegen/code_emitter.cpp +++ b/tools/hdi-gen/codegen/code_emitter.cpp @@ -7,6 +7,8 @@ */ #include "codegen/code_emitter.h" +#include "util/file.h" +#include "util/options.h" namespace OHOS { namespace HDI { @@ -47,6 +49,9 @@ bool CodeEmitter::Reset(const AutoPtr& ast, const String& targetDirectory, infName_ = ast_->GetName(); } + majorVerName_ = String::Format("%s_MAJOR_VERSION", interfaceName_.ToUnderLineUpper().string()); + minorVerName_ = String::Format("%s_MINOR_VERSION", interfaceName_.ToUnderLineUpper().string()); + if (!ResolveDirectory(targetDirectory)) { return false; } @@ -70,5 +75,18 @@ void CodeEmitter::CleanData() implName_ = ""; implFullName_ = ""; } + +String CodeEmitter::GetFilePath(const String& outDir) +{ + String outPath = outDir.EndsWith(File::pathSeparator) ? + outDir.Substring(0, outDir.GetLength() - 1) : outDir; + String packagePath = Options::GetInstance().GetPackagePath(ast_->GetPackageName()); + + if (packagePath.EndsWith(File::pathSeparator)) { + return String::Format("%s/%s", outPath.string(), packagePath.string()); + } else { + return String::Format("%s/%s/", outPath.string(), packagePath.string()); + } +} } // namespace HDI } // namespace OHOS \ No newline at end of file diff --git a/tools/hdi-gen/codegen/code_emitter.h b/tools/hdi-gen/codegen/code_emitter.h index fdacbfd0..14d946d2 100755 --- a/tools/hdi-gen/codegen/code_emitter.h +++ b/tools/hdi-gen/codegen/code_emitter.h @@ -42,8 +42,7 @@ struct HeaderFile { } }; - String ToString() const - { + String ToString() const { switch(type_) { case HeaderFileType::OWN_HEADER_FILE: case HeaderFileType::OWN_MODULE_HEADER_FILE: @@ -80,6 +79,8 @@ protected: virtual void EmitCode() = 0; + String GetFilePath(const String& outDir); + bool isKernelCode_ = false; AutoPtr ast_ = nullptr; AutoPtr interface_ = nullptr; @@ -94,6 +95,8 @@ protected: String stubFullName_; String implName_; String implFullName_; + String majorVerName_; + String minorVerName_; }; } } diff --git a/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.cpp b/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.cpp index bbb0ad13..5f672ada 100755 --- a/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.cpp +++ b/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.cpp @@ -16,8 +16,7 @@ bool CppClientProxyCodeEmitter::ResolveDirectory(const String& targetDirectory) { if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { - directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); + directory_ = GetFilePath(targetDirectory); } else { return false; } @@ -38,7 +37,7 @@ void CppClientProxyCodeEmitter::EmitCode() void CppClientProxyCodeEmitter::EmitProxyHeaderFile() { - String filePath = String::Format("%s%s.h", directory_.string(), FileName(infName_ + "Proxy").string()); + String filePath = String::Format("%s/%s.h", directory_.string(), FileName(infName_ + "Proxy").string()); File file(filePath, File::WRITE); StringBuilder sb; @@ -104,10 +103,10 @@ void CppClientProxyCodeEmitter::EmitProxyMethodDecls(StringBuilder& sb, const St for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { AutoPtr method = interface_->GetMethod(i); EmitProxyMethodDecl(method, sb, prefix); - if (i + 1 < interface_->GetMethodNumber()) { - sb.Append("\n"); - } + sb.Append("\n"); } + + EmitProxyMethodDecl(interface_->GetVersionMethod(), sb, prefix); } void CppClientProxyCodeEmitter::EmitProxyMethodDecl(const AutoPtr& method, StringBuilder& sb, @@ -147,7 +146,7 @@ void CppClientProxyCodeEmitter::EmitProxyMethodParameter(const AutoPtr %s::GetInstance(const std::string& serviceName)\n", interface_->GetName().string(), interface_->GetName().string()); sb.Append(prefix).Append("{\n"); - sb.Append(prefix + g_tab).Append("do {\n"); - sb.Append(prefix + g_tab + g_tab).Append("using namespace OHOS::HDI::ServiceManager::V1_0;\n"); - sb.Append(prefix + g_tab + g_tab).Append("auto servMgr = IServiceManager::Get();\n"); - sb.Append(prefix + g_tab + g_tab).Append("if (servMgr == nullptr) {\n"); - sb.Append(prefix + g_tab + g_tab + g_tab).Append( + sb.Append(prefix + g_tab).Append("using namespace OHOS::HDI::ServiceManager::V1_0;\n"); + sb.Append(prefix + g_tab).Append("auto servMgr = IServiceManager::Get();\n"); + sb.Append(prefix + g_tab).Append("if (servMgr == nullptr) {\n"); + sb.Append(prefix + g_tab + g_tab).Append( "HDF_LOGE(\"%{public}s:get IServiceManager failed!\", __func__);\n"); - sb.Append(prefix + g_tab + g_tab + g_tab).Append("break;\n"); - sb.Append(prefix + g_tab + g_tab).Append("}\n\n"); - sb.Append(prefix + g_tab + g_tab).Append("sptr remote = "); + sb.Append(prefix + g_tab + g_tab).Append("return nullptr;\n"); + sb.Append(prefix + g_tab).Append("}\n\n"); + + sb.Append(prefix + g_tab).Append("sptr remote = "); sb.Append("servMgr->GetService(serviceName.c_str());\n"); - sb.Append(prefix + g_tab + g_tab).Append("if (remote != nullptr) {\n"); - sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat("return iface_cast<%s>(remote);\n", - interface_->GetName().string()); - sb.Append(prefix + g_tab + g_tab).Append("}\n"); - sb.Append(prefix + g_tab).Append("} while(false);\n"); - sb.Append(prefix + g_tab).AppendFormat( - "HDF_LOGE(\"%%{public}s: get %s failed!\", __func__);\n", FileName(implName_).string()); - sb.Append(prefix + g_tab).Append("return nullptr;\n"); + sb.Append(prefix + g_tab).Append("if (remote == nullptr) {\n"); + sb.Append(prefix + g_tab + g_tab).Append( + "HDF_LOGE(\"%{public}s:get remote object failed!\", __func__);\n"); + sb.Append(prefix + g_tab + g_tab).Append("return nullptr;\n"); + sb.Append(prefix + g_tab).Append("}\n\n"); + + sb.Append(prefix + g_tab).AppendFormat("sptr<%s> %s = iface_cast<%s>(remote);\n", + interfaceName_.string(), objName.string(), interfaceName_.string()); + sb.Append(prefix + g_tab).AppendFormat("if (%s == nullptr) {\n", objName.string()); + sb.Append(prefix + g_tab + g_tab).Append("HDF_LOGE(\"%{public}s:iface_cast failed!\", __func__);\n"); + sb.Append(prefix + g_tab + g_tab).Append("return nullptr;\n"); + sb.Append(prefix + g_tab).Append("}\n\n"); + + sb.Append(prefix + g_tab).AppendFormat("uint32_t %s = 0;\n", SerMajorName.string()); + sb.Append(prefix + g_tab).AppendFormat("uint32_t %s = 0;\n", SerMinorName.string()); + sb.Append(prefix + g_tab).AppendFormat("int32_t ec = %s->GetVersion(%s, %s);\n", + objName.string(), SerMajorName.string(), SerMinorName.string()); + sb.Append(prefix + g_tab).AppendFormat("if (ec != HDF_SUCCESS) {\n"); + sb.Append(prefix + g_tab + g_tab).Append("HDF_LOGE(\"%{public}s:get version failed!\", __func__);\n"); + sb.Append(prefix + g_tab + g_tab).Append("return nullptr;\n"); + sb.Append(prefix + g_tab).Append("}\n\n"); + + sb.Append(prefix + g_tab).AppendFormat("if (%s != %s) {\n", SerMajorName.string(), majorVerName_.string()); + sb.Append(prefix + g_tab + g_tab).Append("HDF_LOGE(\"%{public}s:check version failed! "); + sb.Append("version of service:%u.%u, version of client:%u.%u\", __func__,\n"); + sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat("%s, %s, %s, %s);\n", + SerMajorName.string(), SerMinorName.string(), majorVerName_.string(), minorVerName_.string()); + sb.Append(prefix + g_tab + g_tab).Append("return nullptr;\n"); + sb.Append(prefix + g_tab).Append("}\n\n"); + sb.Append(prefix + g_tab).AppendFormat("return %s;\n", objName.string()); sb.Append(prefix).Append("}\n"); } - void CppClientProxyCodeEmitter::EmitProxyMethodImpls(StringBuilder& sb, const String& prefix) { for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { AutoPtr method = interface_->GetMethod(i); EmitProxyMethodImpl(method, sb, prefix); - if (i + 1 < interface_->GetMethodNumber()) { - sb.Append("\n"); - } + sb.Append("\n"); } + + EmitProxyMethodImpl(interface_->GetVersionMethod(), sb, prefix); } void CppClientProxyCodeEmitter::EmitProxyMethodImpl(const AutoPtr& method, StringBuilder& sb, @@ -281,10 +304,11 @@ void CppClientProxyCodeEmitter::EmitProxyMethodBody(const AutoPtr& me String dataName = "data_"; String replyName = "reply_"; String optionName = "option_"; + String option = method->IsOneWay() ? "MessageOption::TF_ASYNC" : "MessageOption::TF_SYNC"; sb.Append(prefix).Append("{\n"); sb.Append(prefix + g_tab).AppendFormat("MessageParcel %s;\n", dataName.string()); sb.Append(prefix + g_tab).AppendFormat("MessageParcel %s;\n", replyName.string()); - sb.Append(prefix + g_tab).AppendFormat("MessageOption %s(MessageOption::TF_SYNC);\n", optionName.string()); + sb.Append(prefix + g_tab).AppendFormat("MessageOption %s(%s);\n", optionName.string(), option.string()); sb.Append("\n"); if (method->GetParameterNumber() > 0) { @@ -292,13 +316,13 @@ void CppClientProxyCodeEmitter::EmitProxyMethodBody(const AutoPtr& me AutoPtr param = method->GetParameter(i); if (param->GetAttribute() == ParamAttr::PARAM_IN) { EmitWriteMethodParameter(param, dataName, sb, prefix + g_tab); + sb.Append("\n"); } } - sb.Append("\n"); } - sb.Append(prefix + g_tab).AppendFormat("int32_t ec = Remote()->SendRequest(CMD_%s, %s, %s, %s);\n", - ConstantName(method->GetName()).string(), dataName.string(), replyName.string(), optionName.string()); + sb.Append(prefix + g_tab).AppendFormat("int32_t ec = Remote()->SendRequest(%s, %s, %s, %s);\n", + EmitMethodCmdID(method).string(), dataName.string(), replyName.string(), optionName.string()); sb.Append(prefix + g_tab).Append("if (ec != HDF_SUCCESS) {\n"); sb.Append(prefix + g_tab + g_tab).AppendFormat( "HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, ec);\n", method->GetName().string()); diff --git a/tools/hdi-gen/codegen/cpp_code_emitter.cpp b/tools/hdi-gen/codegen/cpp_code_emitter.cpp index 4a791c6e..f3eba9b8 100755 --- a/tools/hdi-gen/codegen/cpp_code_emitter.cpp +++ b/tools/hdi-gen/codegen/cpp_code_emitter.cpp @@ -11,6 +11,7 @@ #include #include #include +#include "util/options.h" namespace OHOS { namespace HDI { @@ -20,13 +21,13 @@ String CppCodeEmitter::FileName(const String& name) return name; } + String subName = Options::GetInstance().GetSubPackage(name); StringBuilder sb; - - for (int i = 0; i < name.GetLength(); i++) { - char c = name[i]; + for (int i = 0; i < subName.GetLength(); i++) { + char c = subName[i]; if (isupper(c) != 0) { // 2->Index of the last char array. - if (i > 1 && name[i - 1] != '.' && name[i - 2] != '.') { + if (i > 1 && subName[i - 1] != '.' && subName[i - 2] != '.') { sb.Append('_'); } sb.Append(tolower(c)); @@ -38,13 +39,21 @@ String CppCodeEmitter::FileName(const String& name) return sb.ToString().Replace('.', '/'); } +String CppCodeEmitter::EmitMethodCmdID(const AutoPtr& method) +{ + return String::Format("CMD_%s_%s", infName_.ToUnderLineUpper().string(), + method->GetName().ToUnderLineUpper().string()); +} + void CppCodeEmitter::EmitInterfaceMethodCommands(StringBuilder& sb, const String& prefix) { - sb.Append(prefix).Append("enum {\n"); + sb.Append(prefix).AppendFormat("enum {\n"); for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { AutoPtr method = interface_->GetMethod(i); - sb.Append(g_tab).AppendFormat("CMD_%s,\n", ConstantName(method->GetName()).string()); + sb.Append(prefix + g_tab).Append(EmitMethodCmdID(method)).Append(",\n"); } + + sb.Append(g_tab).Append(EmitMethodCmdID(interface_->GetVersionMethod())).Append(",\n"); sb.Append(prefix).Append("};\n"); } @@ -53,6 +62,7 @@ void CppCodeEmitter::GetStdlibInclusions(HeaderFile::HeaderFileSet& headerFiles) bool includeString = false; bool includeList = false; bool includeMap = false; + bool includeSmq = false; const AST::TypeStringMap& types = ast_->GetTypes(); for (const auto& pair : types) { @@ -80,6 +90,12 @@ void CppCodeEmitter::GetStdlibInclusions(HeaderFile::HeaderFileSet& headerFiles) } break; } + case TypeKind::TYPE_SMQ: { + if (!includeSmq) { + headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_smq")); + includeSmq = true; + } + } default: break; } @@ -119,7 +135,7 @@ void CppCodeEmitter::EmitHeadMacro(StringBuilder& sb, const String& fullName) void CppCodeEmitter::EmitTailMacro(StringBuilder& sb, const String& fullName) { String macroName = MacroName(fullName); - sb.Append("#endif // ").Append(macroName).Append("\n\n"); + sb.Append("#endif // ").Append(macroName); } void CppCodeEmitter::EmitHeadExternC(StringBuilder& sb) @@ -180,6 +196,15 @@ void CppCodeEmitter::EmitImportUsingNamespace(StringBuilder& sb) namespaceSet.emplace(nameSpace); } + const AST::TypeStringMap& types = ast_->GetTypes(); + for (const auto& pair : types) { + AutoPtr type = pair.second; + if (type->GetTypeKind() == TypeKind::TYPE_SMQ) { + namespaceSet.emplace("OHOS::HDI::Base"); + break; + } + } + for (const auto& nspace : namespaceSet) { sb.Append("using namespace ").AppendFormat("%s;\n", nspace.string()); } diff --git a/tools/hdi-gen/codegen/cpp_code_emitter.h b/tools/hdi-gen/codegen/cpp_code_emitter.h index 1ce214c2..d93f9482 100755 --- a/tools/hdi-gen/codegen/cpp_code_emitter.h +++ b/tools/hdi-gen/codegen/cpp_code_emitter.h @@ -25,6 +25,8 @@ public: static String FileName(const String& name); protected: + String EmitMethodCmdID(const AutoPtr& method); + void EmitInterfaceMethodCommands(StringBuilder& sb, const String& prefix); void GetStdlibInclusions(HeaderFile::HeaderFileSet& headerFiles); diff --git a/tools/hdi-gen/codegen/cpp_custom_types_code_emitter.cpp b/tools/hdi-gen/codegen/cpp_custom_types_code_emitter.cpp index ee6ef607..0f19e92c 100755 --- a/tools/hdi-gen/codegen/cpp_custom_types_code_emitter.cpp +++ b/tools/hdi-gen/codegen/cpp_custom_types_code_emitter.cpp @@ -18,8 +18,7 @@ bool CppCustomTypesCodeEmitter::ResolveDirectory(const String& targetDirectory) return false; } - directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); + directory_ = GetFilePath(targetDirectory); if (!File::CreateParentDir(directory_)) { Logger::E("CppCustomTypesCodeEmitter", "Create '%s' failed!", directory_.string()); return false; @@ -36,7 +35,7 @@ void CppCustomTypesCodeEmitter::EmitCode() void CppCustomTypesCodeEmitter::EmitCustomTypesHeaderFile() { - String filePath = String::Format("%s%s.h", directory_.string(), FileName(infName_).string()); + String filePath = String::Format("%s/%s.h", directory_.string(), FileName(infName_).string()); File file(filePath, File::WRITE); String marcoName = String::Format("%s.%s", ast_->GetPackageName().string(), infName_.string()); StringBuilder sb; @@ -148,7 +147,7 @@ void CppCustomTypesCodeEmitter::EmitCustomTypeUnmarshallingDecl(StringBuilder& s void CppCustomTypesCodeEmitter::EmitCustomTypesSourceFile() { - String filePath = String::Format("%s%s.cpp", directory_.string(), FileName(infName_).string()); + String filePath = String::Format("%s/%s.cpp", directory_.string(), FileName(infName_).string()); File file(filePath, File::WRITE); StringBuilder sb; diff --git a/tools/hdi-gen/codegen/cpp_interface_code_emitter.cpp b/tools/hdi-gen/codegen/cpp_interface_code_emitter.cpp index 1686880f..2dba26f8 100755 --- a/tools/hdi-gen/codegen/cpp_interface_code_emitter.cpp +++ b/tools/hdi-gen/codegen/cpp_interface_code_emitter.cpp @@ -16,8 +16,7 @@ bool CppInterfaceCodeEmitter::ResolveDirectory(const String& targetDirectory) { if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { - directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); + directory_ = GetFilePath(targetDirectory); } else { return false; } @@ -46,14 +45,14 @@ void CppInterfaceCodeEmitter::EmitInterfaceHeaderFile() sb.Append("\n"); EmitInterfaceInclusions(sb); sb.Append("\n"); - EmitBeginNamespace(sb); + EmitInterfaceVersionMacro(sb); sb.Append("\n"); + EmitBeginNamespace(sb); EmitUsingNamespace(sb); sb.Append("\n"); EmitInterfaceMethodCommands(sb, ""); sb.Append("\n"); EmitInterfaceDefinition(sb); - sb.Append("\n"); EmitEndNamespace(sb); sb.Append("\n"); EmitTailMacro(sb, interfaceFullName_); @@ -83,25 +82,27 @@ void CppInterfaceCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFile headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iremote_broker")); } +void CppInterfaceCodeEmitter::EmitInterfaceVersionMacro(StringBuilder& sb) +{ + sb.AppendFormat("#define %s %u\n", majorVerName_.string(), ast_->GetMajorVer()); + sb.AppendFormat("#define %s %u\n", minorVerName_.string(), ast_->GetMinorVer()); +} + void CppInterfaceCodeEmitter::EmitInterfaceDefinition(StringBuilder& sb) { if (!isCallbackInterface()) { - sb.Append("#ifndef __HDI_SERVER__\n"); sb.AppendFormat("class %s : public IRemoteBroker {\n", interfaceName_.string()); sb.Append("public:\n"); EmitInterfaceDescriptor(sb, g_tab); sb.Append("\n"); + EmitInterfaceDestruction(sb, g_tab); + sb.Append("\n"); EmitGetMethodDecl(sb, g_tab); sb.Append("\n"); EmitGetInstanceMethodDecl(sb, g_tab); - sb.Append("#else\n"); - sb.AppendFormat("class %s {\n", interfaceName_.string()); - sb.Append("public:\n"); - sb.Append("#endif\n"); - EmitInterfaceDestruction(sb, g_tab); sb.Append("\n"); EmitInterfaceMethodsDecl(sb, g_tab); - sb.Append("};\n\n"); + sb.Append("};\n"); } else { sb.AppendFormat("class %s : public IRemoteBroker {\n", interfaceName_.string()); sb.Append("public:\n"); @@ -110,7 +111,7 @@ void CppInterfaceCodeEmitter::EmitInterfaceDefinition(StringBuilder& sb) EmitInterfaceDestruction(sb, g_tab); sb.Append("\n"); EmitInterfaceMethodsDecl(sb, g_tab); - sb.Append("};\n\n"); + sb.Append("};\n"); } } @@ -140,10 +141,10 @@ void CppInterfaceCodeEmitter::EmitInterfaceMethodsDecl(StringBuilder& sb, const for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { AutoPtr method = interface_->GetMethod(i); EmitInterfaceMethodDecl(method, sb, prefix); - if (i + 1 < interface_->GetMethodNumber()) { - sb.Append("\n"); - } + sb.Append("\n"); } + + EmitInterfaceMethodDecl(interface_->GetVersionMethod(), sb, prefix); } void CppInterfaceCodeEmitter::EmitInterfaceMethodDecl(const AutoPtr& method, StringBuilder& sb, diff --git a/tools/hdi-gen/codegen/cpp_interface_code_emitter.h b/tools/hdi-gen/codegen/cpp_interface_code_emitter.h index 2a3effe8..72b49b8b 100755 --- a/tools/hdi-gen/codegen/cpp_interface_code_emitter.h +++ b/tools/hdi-gen/codegen/cpp_interface_code_emitter.h @@ -13,6 +13,7 @@ namespace OHOS { namespace HDI { + class CppInterfaceCodeEmitter : public CppCodeEmitter { public: CppInterfaceCodeEmitter() : CppCodeEmitter() {} @@ -29,6 +30,8 @@ private: void GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet& headerFiles); + void EmitInterfaceVersionMacro(StringBuilder& sb); + void EmitInterfaceDefinition(StringBuilder& sb); void EmitInterfaceDescriptor(StringBuilder& sb, const String& prefix); @@ -45,6 +48,7 @@ private: void EmitInterfaceMethodParameter(const AutoPtr& param, StringBuilder& sb, const String& prefix); }; + } // namespace HDI } // namespace OHOS diff --git a/tools/hdi-gen/codegen/cpp_service_driver_code_emitter.cpp b/tools/hdi-gen/codegen/cpp_service_driver_code_emitter.cpp index 736f665b..a2fa7ab4 100755 --- a/tools/hdi-gen/codegen/cpp_service_driver_code_emitter.cpp +++ b/tools/hdi-gen/codegen/cpp_service_driver_code_emitter.cpp @@ -19,8 +19,7 @@ bool CppServiceDriverCodeEmitter::ResolveDirectory(const String& targetDirectory return false; } - directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); + directory_ = GetFilePath(targetDirectory); if (!File::CreateParentDir(directory_)) { Logger::E("CppServiceDriverCodeEmitter", "Create '%s' failed!", directory_.string()); return false; @@ -39,7 +38,7 @@ void CppServiceDriverCodeEmitter::EmitCode() void CppServiceDriverCodeEmitter::EmitDriverSourceFile() { - String filePath = String::Format("%s%s.cpp", directory_.string(), FileName(infName_ + "Driver").string()); + String filePath = String::Format("%s/%s.cpp", directory_.string(), FileName(infName_ + "Driver").string()); File file(filePath, File::WRITE); StringBuilder sb; @@ -68,11 +67,18 @@ void CppServiceDriverCodeEmitter::EmitDriverSourceFile() void CppServiceDriverCodeEmitter::EmitDriverIncluions(StringBuilder& sb) { - sb.Append("#include \n"); - sb.Append("#include \n"); - sb.Append("#include \n"); - sb.Append("#include \n"); - sb.AppendFormat("#include \"%s.h\"\n", FileName(stubName_).string()); + HeaderFile::HeaderFileSet headerFiles; + + headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base")); + headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log")); + headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "osal_mem")); + headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_device_desc")); + headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_sbuf_ipc")); + headerFiles.emplace(HeaderFile(HeaderFileType::OWN_MODULE_HEADER_FILE, FileName(implName_))); + + for (const auto& file : headerFiles) { + sb.AppendFormat("%s\n", file.ToString().string()); + } } void CppServiceDriverCodeEmitter::EmitDriverUsings(StringBuilder& sb) @@ -91,22 +97,33 @@ void CppServiceDriverCodeEmitter::EmitDriverServiceDecl(StringBuilder& sb) { sb.AppendFormat("struct Hdf%sHost {\n", infName_.string()); sb.Append(g_tab).Append("struct IDeviceIoService ioservice;\n"); - sb.Append(g_tab).Append("void *instance;\n"); + sb.Append(g_tab).AppendFormat("%s *service;\n", implName_.string()); sb.Append("};\n"); } void CppServiceDriverCodeEmitter::EmitDriverDispatch(StringBuilder& sb) { - sb.AppendFormat("static int32_t %sDriverDispatch(struct HdfDeviceIoClient *client, int cmdId,\n", - infName_.string()); - sb.Append(g_tab).Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n"); + String objName = String::Format("hdf%sHost", infName_.string()); + sb.AppendFormat("static int32_t %sDriverDispatch(", infName_.string()); + sb.Append("struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data,\n"); + sb.Append(g_tab).Append("struct HdfSBuf *reply)\n"); sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("struct Hdf%sHost *hdf%sHost = CONTAINER_OF(\n", - infName_.string(), infName_.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("client->device->service, struct Hdf%sHost, ioservice);\n", - infName_.string()); - sb.Append(g_tab).AppendFormat("return %sServiceOnRemoteRequest(hdf%sHost->instance, cmdId, data, reply);\n", - infName_.string(), infName_.string()); + sb.Append(g_tab).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", infName_.string(), objName.string()); + sb.AppendFormat("client->device->service, struct Hdf%sHost, ioservice);\n\n", infName_.string()); + + sb.Append(g_tab).Append("OHOS::MessageParcel *dataParcel = nullptr;\n"); + sb.Append(g_tab).Append("OHOS::MessageParcel *replyParcel = nullptr;\n"); + sb.Append(g_tab).Append("OHOS::MessageOption option;\n\n"); + + sb.Append(g_tab).Append("(void)SbufToParcel(reply, &replyParcel);\n"); + sb.Append(g_tab).Append("if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {\n"); + sb.Append(g_tab).Append(g_tab).Append( + "HDF_LOGE(\"%{public}s:invalid data sbuf object to dispatch\", __func__);\n"); + sb.Append(g_tab).Append(g_tab).Append("return HDF_ERR_INVALID_PARAM;\n"); + sb.Append(g_tab).Append("}\n\n"); + + sb.Append(g_tab).AppendFormat("return %s->service->OnRemoteRequest(cmdId, *dataParcel, *replyParcel, option);\n", + objName.string()); sb.Append("}\n"); } @@ -121,39 +138,41 @@ void CppServiceDriverCodeEmitter::EmitDriverInit(StringBuilder& sb) void CppServiceDriverCodeEmitter::EmitDriverBind(StringBuilder& sb) { + String objName = String::Format("hdf%sHost", infName_.string()); sb.AppendFormat("int Hdf%sDriverBind(struct HdfDeviceObject *deviceObject)\n", infName_.string()); sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverBind enter\");\n", infName_.string()); - sb.Append("\n"); - sb.Append(g_tab).AppendFormat("struct Hdf%sHost *hdf%sHost = (struct Hdf%sHost *)OsalMemAlloc(\n", - infName_.string(), infName_.string(), infName_.string()); + sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverBind enter\");\n\n", infName_.string()); + + sb.Append(g_tab).AppendFormat("struct Hdf%sHost *%s = (struct Hdf%sHost *)OsalMemAlloc(\n", + infName_.string(), objName.string(), infName_.string()); sb.Append(g_tab).Append(g_tab).AppendFormat("sizeof(struct Hdf%sHost));\n", infName_.string()); - sb.Append(g_tab).AppendFormat("if (hdf%sHost == nullptr) {\n", infName_.string()); + sb.Append(g_tab).AppendFormat("if (%s == nullptr) {\n", objName.string()); sb.Append(g_tab).Append(g_tab).AppendFormat("HDF_LOGE(\"Hdf%sDriverBind OsalMemAlloc Hdf%sHost failed!\");\n", infName_.string(), infName_.string()); sb.Append(g_tab).Append(g_tab).Append("return HDF_FAILURE;\n"); - sb.Append(g_tab).Append("}\n"); - sb.Append("\n"); - sb.Append(g_tab).AppendFormat("hdf%sHost->ioservice.Dispatch = %sDriverDispatch;\n", - infName_.string(), infName_.string()); - sb.Append(g_tab).AppendFormat("hdf%sHost->ioservice.Open = NULL;\n", infName_.string()); - sb.Append(g_tab).AppendFormat("hdf%sHost->ioservice.Release = NULL;\n", infName_.string()); - sb.Append(g_tab).AppendFormat("hdf%sHost->instance = %sStubInstance();\n", infName_.string(), infName_.string()); - sb.Append("\n"); - sb.Append(g_tab).AppendFormat("deviceObject->service = &hdf%sHost->ioservice;\n", infName_.string()); + sb.Append(g_tab).Append("}\n\n"); + + sb.Append(g_tab).AppendFormat("%s->ioservice.Dispatch = %sDriverDispatch;\n", + objName.string(), infName_.string()); + sb.Append(g_tab).AppendFormat("%s->ioservice.Open = NULL;\n", objName.string()); + sb.Append(g_tab).AppendFormat("%s->ioservice.Release = NULL;\n", objName.string()); + sb.Append(g_tab).AppendFormat("%s->service = new %s();\n\n", objName.string(), implName_.string()); + + sb.Append(g_tab).AppendFormat("deviceObject->service = &%s->ioservice;\n", objName.string()); sb.Append(g_tab).Append("return HDF_SUCCESS;\n"); sb.Append("}\n"); } void CppServiceDriverCodeEmitter::EmitDriverRelease(StringBuilder& sb) { + String objName = String::Format("hdf%sHost", infName_.string()); sb.AppendFormat("void Hdf%sDriverRelease(struct HdfDeviceObject *deviceObject)", infName_.string()); sb.Append("{\n"); sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverRelease enter\");\n\n", infName_.string()); - sb.Append(g_tab).AppendFormat("struct Hdf%sHost *hdf%sHost = CONTAINER_OF(", infName_.string(), infName_.string()); + sb.Append(g_tab).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", infName_.string(), objName.string()); sb.AppendFormat("deviceObject->service, struct Hdf%sHost, ioservice);\n", infName_.string()); - sb.Append(g_tab).AppendFormat("%sStubRelease(hdf%sHost->instance);\n", infName_.string(), infName_.string()); - sb.Append(g_tab).AppendFormat("OsalMemFree(hdf%sHost);\n", infName_.string()); + sb.Append(g_tab).AppendFormat("delete %s->service;\n", objName.string()); + sb.Append(g_tab).AppendFormat("OsalMemFree(%s);\n", objName.string()); sb.Append("}\n"); } diff --git a/tools/hdi-gen/codegen/cpp_service_impl_code_emitter.cpp b/tools/hdi-gen/codegen/cpp_service_impl_code_emitter.cpp index 873ba68d..1261bb5c 100755 --- a/tools/hdi-gen/codegen/cpp_service_impl_code_emitter.cpp +++ b/tools/hdi-gen/codegen/cpp_service_impl_code_emitter.cpp @@ -16,8 +16,7 @@ bool CppServiceImplCodeEmitter::ResolveDirectory(const String& targetDirectory) { if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { - directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); + directory_ = GetFilePath(targetDirectory); } else { return false; } @@ -38,7 +37,7 @@ void CppServiceImplCodeEmitter::EmitCode() void CppServiceImplCodeEmitter::EmitImplHeaderFile() { - String filePath = String::Format("%s%s.h", directory_.string(), FileName(infName_ + "Service").string()); + String filePath = String::Format("%s/%s.h", directory_.string(), FileName(infName_ + "Service").string()); File file(filePath, File::WRITE); StringBuilder sb; @@ -48,18 +47,6 @@ void CppServiceImplCodeEmitter::EmitImplHeaderFile() EmitServiceImplInclusions(sb); sb.Append("\n"); EmitServiceImplDecl(sb); - - if (!isCallbackInterface()) { - sb.Append("\n"); - EmitHeadExternC(sb); - sb.Append("\n"); - EmitExternalGetMethodDecl(sb); - sb.Append("\n"); - EmitExternalReleaseMethodDecl(sb); - sb.Append("\n"); - EmitTailExternC(sb); - } - sb.Append("\n"); EmitTailMacro(sb, implFullName_); @@ -72,11 +59,7 @@ void CppServiceImplCodeEmitter::EmitImplHeaderFile() void CppServiceImplCodeEmitter::EmitServiceImplInclusions(StringBuilder& sb) { HeaderFile::HeaderFileSet headerFiles; - if (!isCallbackInterface()) { - headerFiles.emplace(HeaderFile(HeaderFileType::OWN_MODULE_HEADER_FILE, FileName(interfaceName_))); - } else { - headerFiles.emplace(HeaderFile(HeaderFileType::OWN_HEADER_FILE, FileName(stubName_))); - } + headerFiles.emplace(HeaderFile(HeaderFileType::OWN_HEADER_FILE, FileName(stubName_))); for (const auto& file : headerFiles) { sb.AppendFormat("%s\n", file.ToString().string()); @@ -87,11 +70,7 @@ void CppServiceImplCodeEmitter::EmitServiceImplDecl(StringBuilder& sb) { EmitBeginNamespace(sb); sb.Append("\n"); - if (!isCallbackInterface()) { - sb.AppendFormat("class %sService : public %s {\n", infName_.string(), interfaceName_.string()); - } else { - sb.AppendFormat("class %sService : public %s {\n", infName_.string(), stubName_.string()); - } + sb.AppendFormat("class %sService : public %s {\n", infName_.string(), stubName_.string()); sb.Append("public:\n"); EmitServiceImplBody(sb, g_tab); sb.Append("};\n"); @@ -146,19 +125,9 @@ void CppServiceImplCodeEmitter::EmitServiceImplMethodDecl(const AutoPtr& method, StringBuilder& sb, const String& prefix); - void EmitExternalGetMethodDecl(StringBuilder& sb); - - void EmitExternalReleaseMethodDecl(StringBuilder& sb); - void EmitImplSourceFile(); void EmitImplSourceInclusions(StringBuilder& sb); diff --git a/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.cpp b/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.cpp index e90a0eec..aecd388c 100755 --- a/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.cpp +++ b/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.cpp @@ -16,8 +16,7 @@ bool CppServiceStubCodeEmitter::ResolveDirectory(const String& targetDirectory) { if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { - directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); + directory_ = GetFilePath(targetDirectory); } else { return false; } @@ -38,7 +37,7 @@ void CppServiceStubCodeEmitter::EmitCode() void CppServiceStubCodeEmitter::EmitStubHeaderFile() { - String filePath = String::Format("%s%s.h", directory_.string(), FileName(stubName_).string()); + String filePath = String::Format("%s/%s.h", directory_.string(), FileName(stubName_).string()); File file(filePath, File::WRITE); StringBuilder sb; @@ -47,12 +46,7 @@ void CppServiceStubCodeEmitter::EmitStubHeaderFile() sb.Append("\n"); EmitStubHeaderInclusions(sb); sb.Append("\n"); - - if (!isCallbackInterface()) { - EmitStubDecl(sb); - } else { - EmitCbStubDecl(sb); - } + EmitStubDecl(sb); sb.Append("\n"); EmitTailMacro(sb, stubFullName_); @@ -78,9 +72,7 @@ void CppServiceStubCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFi { headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_parcel")); headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_option")); - if (isCallbackInterface()) { - headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iremote_stub")); - } + headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iremote_stub")); } void CppServiceStubCodeEmitter::EmitStubDecl(StringBuilder& sb) @@ -89,29 +81,11 @@ void CppServiceStubCodeEmitter::EmitStubDecl(StringBuilder& sb) sb.Append("\n"); EmitStubUsingNamespace(sb); sb.Append("\n"); - sb.AppendFormat("class %s {\n", stubName_.string()); + sb.AppendFormat("class %s : public IRemoteStub<%s> {\n", stubName_.string(), interfaceName_.string()); EmitStubBody(sb, g_tab); sb.Append("};\n"); - sb.Append("\n"); EmitEndNamespace(sb); - - sb.Append("\n"); - EmitStubExternalsMethodsDel(sb); -} - -void CppServiceStubCodeEmitter::EmitCbStubDecl(StringBuilder& sb) -{ - EmitBeginNamespace(sb); - sb.Append("\n"); - EmitStubUsingNamespace(sb); - sb.Append("\n"); - sb.AppendFormat("class %s : public IRemoteStub<%s> {\n", stubName_.string(), interfaceName_.string()); - EmitCbStubBody(sb, g_tab); - sb.Append("};\n"); - sb.Append("\n"); - EmitEndNamespace(sb); - sb.Append("\n"); } void CppServiceStubCodeEmitter::EmitStubUsingNamespace(StringBuilder& sb) @@ -124,19 +98,10 @@ void CppServiceStubCodeEmitter::EmitStubBody(StringBuilder& sb, const String& pr sb.Append("public:\n"); EmitStubDestruction(sb, prefix); sb.Append("\n"); - EmitStubMethodDecls(sb, prefix); + EmitStubOnRequestDecl(sb, prefix); sb.Append("\n"); - EmitStubOnRequestMethodDecl(sb, prefix); + EmitGetVersionDecl(sb, prefix); sb.Append("\n"); - EmitStubMembers(sb, prefix); -} - -void CppServiceStubCodeEmitter::EmitCbStubBody(StringBuilder& sb, const String& prefix) -{ - sb.Append("public:\n"); - EmitStubDestruction(sb, prefix); - sb.Append("\n"); - EmitCbStubOnRequestDecl(sb, prefix); EmitStubMethodDecls(sb, prefix); } @@ -145,27 +110,41 @@ void CppServiceStubCodeEmitter::EmitStubDestruction(StringBuilder& sb, const Str sb.Append(prefix).AppendFormat("virtual ~%s() {}\n", stubName_.string()); } -void CppServiceStubCodeEmitter::EmitCbStubOnRequestDecl(StringBuilder& sb, const String& prefix) +void CppServiceStubCodeEmitter::EmitStubOnRequestDecl(StringBuilder& sb, const String& prefix) { - sb.Append(prefix).Append("int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,\n"); - sb.Append(prefix + g_tab).Append("MessageOption &option) override;\n"); + sb.Append(prefix).Append("int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, "); + sb.Append("MessageOption &option) override;\n"); +} + +void CppServiceStubCodeEmitter::EmitGetVersionDecl(StringBuilder& sb, const String& prefix) +{ + AutoPtr method = interface_->GetVersionMethod(); + + StringBuilder paramStr; + sb.Append(prefix).AppendFormat("int32_t %s(", method->GetName().string()); + for (size_t i = 0; i < method->GetParameterNumber(); i++) { + AutoPtr param = method->GetParameter(i); + EmitInterfaceMethodParameter(param, paramStr, ""); + if (i + 1 < method->GetParameterNumber()) { + paramStr.Append(", "); + } + } + + paramStr.Append(") override;"); + + sb.Append(SpecificationParam(paramStr, prefix + g_tab)); + sb.Append("\n"); } void CppServiceStubCodeEmitter::EmitStubMethodDecls(StringBuilder& sb, const String& prefix) { - if (interface_->GetMethodNumber() > 0) { - if (isCallbackInterface()) { - sb.Append("private:\n"); - } - - for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { - AutoPtr method = interface_->GetMethod(i); - EmitStubMethodDecl(method, sb, prefix); - if (i + 1 < interface_->GetMethodNumber()) { - sb.Append("\n"); - } - } + sb.Append("private:\n"); + for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { + AutoPtr method = interface_->GetMethod(i); + EmitStubMethodDecl(method, sb, prefix); + sb.Append("\n"); } + EmitStubMethodDecl(interface_->GetVersionMethod(), sb, prefix); } void CppServiceStubCodeEmitter::EmitStubMethodDecl(const AutoPtr& method, StringBuilder& sb, @@ -178,67 +157,24 @@ void CppServiceStubCodeEmitter::EmitStubMethodDecl(const AutoPtr& met stubName_.string(), method->GetName().string(), dataName.string(), replyName.string(), optionName.string()); } -void CppServiceStubCodeEmitter::EmitStubOnRequestMethodDecl(StringBuilder& sb, const String& prefix) -{ - sb.Append(prefix).AppendFormat("int32_t %sOnRemoteRequest(int cmdId, MessageParcel& data, MessageParcel& reply,\n", - stubName_.string()); - sb.Append(prefix).Append(g_tab).Append("MessageOption& option);\n"); -} - -void CppServiceStubCodeEmitter::EmitStubMembers(StringBuilder& sb, const String& prefix) -{ - sb.Append(prefix).Append("void *dlHandler;\n"); - sb.Append(prefix).AppendFormat("%s *service;\n", interfaceName_.string()); -} - -void CppServiceStubCodeEmitter::EmitStubExternalsMethodsDel(StringBuilder& sb) -{ - sb.AppendFormat("void *%sInstance();\n", stubName_.string()); - sb.Append("\n"); - sb.AppendFormat("void %sRelease(void *obj);\n", stubName_.string()); - sb.Append("\n"); - sb.AppendFormat( - "int32_t %sServiceOnRemoteRequest(void *stub, int cmdId, struct HdfSBuf* data, struct HdfSBuf* reply);\n", - infName_.string()); -} - void CppServiceStubCodeEmitter::EmitStubSourceFile() { - String filePath = String::Format("%s%s.cpp", directory_.string(), FileName(stubName_).string()); + String filePath = String::Format("%s/%s.cpp", directory_.string(), FileName(stubName_).string()); File file(filePath, File::WRITE); StringBuilder sb; EmitLicense(sb); EmitStubSourceInclusions(sb); - - if (!isCallbackInterface()) { - sb.Append("\n"); - EmitDriverLibPath(sb); - sb.Append("\n"); - EmitHeadExternC(sb); - sb.Append("\n"); - EmitLibFuncTypeDef(sb); - sb.Append("\n"); - EmitTailExternC(sb); - } - sb.Append("\n"); EmitBeginNamespace(sb); sb.Append("\n"); - if (!isCallbackInterface()) { - EmitStubOnRequestMethodImpl(sb, ""); - } else { - EmitCbStubOnRequestMethodImpl(sb, ""); - } + EmitStubOnRequestMethodImpl(sb, ""); + sb.Append("\n"); + EmitGetVersionMethodImpl(sb, ""); sb.Append("\n"); EmitStubMethodImpls(sb, ""); sb.Append("\n"); EmitEndNamespace(sb); - sb.Append("\n"); - - if (!isCallbackInterface()) { - EmitStubExternalsMethodsImpl(sb, ""); - } String data = sb.ToString(); file.WriteData(data.string(), data.GetLength()); @@ -260,8 +196,6 @@ void CppServiceStubCodeEmitter::EmitStubSourceInclusions(StringBuilder& sb) void CppServiceStubCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet& headerFiles) { if (!isCallbackInterface()) { - headerFiles.emplace(HeaderFile(HeaderFileType::SYSTEM_HEADER_FILE, "dlfcn")); - headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_sbuf_ipc")); headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec")); } else { const AST::TypeStringMap& types = ast_->GetTypes(); @@ -278,20 +212,58 @@ void CppServiceStubCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFi headerFiles.emplace(HeaderFile(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log")); } -void CppServiceStubCodeEmitter::EmitDriverLibPath(StringBuilder& sb) +void CppServiceStubCodeEmitter::EmitStubOnRequestMethodImpl(StringBuilder& sb, const String& prefix) { - sb.Append("#ifdef __ARM64__\n"); - sb.Append("#define DRIVER_PATH \"system/lib64\"\n"); - sb.Append("#else\n"); - sb.Append("#define DRIVER_PATH \"system/lib\"\n"); - sb.Append("#endif\n"); + sb.Append(prefix).AppendFormat("int32_t %s::OnRemoteRequest(uint32_t code, ", stubName_.string()); + sb.Append("MessageParcel& data, MessageParcel& reply, MessageOption& option)\n"); + sb.Append(prefix).Append("{\n"); + + sb.Append(prefix + g_tab).Append("switch (code) {\n"); + + for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { + AutoPtr method = interface_->GetMethod(i); + sb.Append(prefix + g_tab + g_tab).AppendFormat("case %s:\n", EmitMethodCmdID(method).string()); + sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat("return %sStub%s(data, reply, option);\n", + infName_.string(), method->GetName().string()); + } + + AutoPtr getVerMethod = interface_->GetVersionMethod(); + sb.Append(prefix + g_tab + g_tab).AppendFormat("case %s:\n", EmitMethodCmdID(getVerMethod).string()); + sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat("return %sStub%s(data, reply, option);\n", + infName_.string(), getVerMethod->GetName().string()); + + sb.Append(prefix + g_tab + g_tab).Append("default: {\n"); + sb.Append(prefix + g_tab + g_tab + g_tab).Append( + "HDF_LOGE(\"%{public}s: not support cmd %{public}d\", __func__, code);\n"); + sb.Append(prefix + g_tab + g_tab + g_tab).Append( + "return IPCObjectStub::OnRemoteRequest(code, data, reply, option);\n"); + sb.Append(prefix + g_tab + g_tab).Append("}\n"); + sb.Append(prefix + g_tab).Append("}\n"); + sb.Append("}\n"); } -void CppServiceStubCodeEmitter::EmitLibFuncTypeDef(StringBuilder& sb) +void CppServiceStubCodeEmitter::EmitGetVersionMethodImpl(StringBuilder& sb, const String& prefix) { - sb.AppendFormat("typedef %s* (*SERVICE_CONSTRUCT_FUNC)();\n", CppFullName(interface_->GetFullName()).string()); - sb.AppendFormat("typedef void (*SERVICE_RELEASE_FUNC)(%s *obj);\n", - CppFullName(interface_->GetFullName()).string()); + AutoPtr method = interface_->GetVersionMethod(); + sb.Append(prefix).AppendFormat("int32_t %sStub::%s(", infName_.string(), method->GetName().string()); + for (size_t i = 0; i < method->GetParameterNumber(); i++) { + AutoPtr param = method->GetParameter(i); + EmitInterfaceMethodParameter(param, sb, ""); + if (i + 1 < method->GetParameterNumber()) { + sb.Append(", "); + } + } + + sb.AppendFormat(")\n"); + sb.Append(prefix).Append("{\n"); + + AutoPtr majorParam = method->GetParameter(0); + sb.Append(prefix + g_tab).AppendFormat("%s = %s;\n", majorParam->GetName().string(), majorVerName_.string()); + AutoPtr minorParam = method->GetParameter(1); + sb.Append(prefix + g_tab).AppendFormat("%s = %s;\n", minorParam->GetName().string(), minorVerName_.string()); + + sb.Append(prefix + g_tab).Append("return HDF_SUCCESS;\n"); + sb.Append(prefix).Append("}\n"); } void CppServiceStubCodeEmitter::EmitStubMethodImpls(StringBuilder& sb, const String& prefix) @@ -299,10 +271,10 @@ void CppServiceStubCodeEmitter::EmitStubMethodImpls(StringBuilder& sb, const Str for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { AutoPtr method = interface_->GetMethod(i); EmitStubMethodImpl(method, sb, prefix); - if (i + 1 < interface_->GetMethodNumber()) { - sb.Append("\n"); - } + sb.Append("\n"); } + + EmitStubMethodImpl(interface_->GetVersionMethod(), sb, prefix); } void CppServiceStubCodeEmitter::EmitStubMethodImpl(const AutoPtr& method, StringBuilder& sb, @@ -348,11 +320,7 @@ void CppServiceStubCodeEmitter::EmitStubMethodImpl(const AutoPtr& met void CppServiceStubCodeEmitter::EmitStubCallMethod(const AutoPtr& method, StringBuilder& sb, const String& prefix) { - if (!isCallbackInterface()) { - sb.Append(prefix).AppendFormat("int32_t ec = service->%s(", method->GetName().string()); - } else { - sb.Append(prefix).AppendFormat("int32_t ec = %s(", method->GetName().string()); - } + sb.Append(prefix).AppendFormat("int32_t ec = %s(", method->GetName().string()); for (size_t i = 0; i < method->GetParameterNumber(); i++) { AutoPtr param = method->GetParameter(i); sb.Append(param->GetName()); @@ -369,194 +337,6 @@ void CppServiceStubCodeEmitter::EmitStubCallMethod(const AutoPtr& met sb.Append(prefix).Append("}\n"); } -void CppServiceStubCodeEmitter::EmitStubOnRequestMethodImpl(StringBuilder& sb, const String& prefix) -{ - sb.Append(prefix).AppendFormat("int32_t %s::%sOnRemoteRequest(int cmdId,\n", - stubName_.string(), stubName_.string()); - sb.Append(prefix + g_tab).Append("MessageParcel& data, MessageParcel& reply, MessageOption& option)\n"); - sb.Append(prefix).Append("{\n"); - - sb.Append(prefix + g_tab).Append("switch (cmdId) {\n"); - for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { - AutoPtr method = interface_->GetMethod(i); - sb.Append(prefix + g_tab + g_tab).AppendFormat("case CMD_%s:\n", ConstantName(method->GetName()).string()); - sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat("return %sStub%s(data, reply, option);\n", - infName_.string(), method->GetName().string()); - } - - sb.Append(prefix + g_tab + g_tab).Append("default: {\n"); - sb.Append(prefix + g_tab + g_tab + g_tab).Append( - "HDF_LOGE(\"%{public}s: not support cmd %{public}d\", __func__, cmdId);\n"); - sb.Append(prefix + g_tab + g_tab + g_tab).Append("return HDF_ERR_INVALID_PARAM;\n"); - sb.Append(prefix + g_tab + g_tab).Append("}\n"); - sb.Append(prefix + g_tab).Append("}\n"); - sb.Append("}\n"); -} - -void CppServiceStubCodeEmitter::EmitCbStubOnRequestMethodImpl(StringBuilder& sb, const String& prefix) -{ - sb.Append(prefix).AppendFormat("int32_t %s::OnRemoteRequest(uint32_t code,\n", stubName_.string()); - sb.Append(prefix + g_tab).Append("MessageParcel& data, MessageParcel& reply, MessageOption& option)\n"); - sb.Append(prefix).Append("{\n"); - - sb.Append(prefix + g_tab).Append("switch (code) {\n"); - - for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { - AutoPtr method = interface_->GetMethod(i); - sb.Append(prefix + g_tab + g_tab).AppendFormat("case CMD_%s:\n", ConstantName(method->GetName()).string()); - sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat("return %sStub%s(data, reply, option);\n", - infName_.string(), method->GetName().string()); - } - - sb.Append(prefix + g_tab + g_tab).Append("default: {\n"); - sb.Append(prefix + g_tab + g_tab + g_tab).Append( - "HDF_LOGE(\"%{public}s: not support cmd %{public}d\", __func__, code);\n"); - sb.Append(prefix + g_tab + g_tab + g_tab).Append( - "return IPCObjectStub::OnRemoteRequest(code, data, reply, option);\n"); - sb.Append(prefix + g_tab + g_tab).Append("}\n"); - sb.Append(prefix + g_tab).Append("}\n"); - sb.Append("}\n"); -} - -void CppServiceStubCodeEmitter::EmitStubExternalsMethodsImpl(StringBuilder& sb, const String& prefix) -{ - EmitStubLinkService(sb); - sb.Append("\n"); - EmitStubInstanceMethodImpl(sb); - sb.Append("\n"); - EmitStubReleaseMethodImpl(sb); - sb.Append("\n"); - EmitServiceOnRemoteRequest(sb); -} - -void CppServiceStubCodeEmitter::EmitStubLinkService(StringBuilder& sb) -{ - sb.Append("static void *LoadServiceHandler(const char* libFileName)\n"); - sb.Append("{\n"); - sb.Append(g_tab).Append("char path[PATH_MAX + 1] = {0};\n"); - sb.Append(g_tab).Append("char libPath[PATH_MAX + 1] = {0};\n"); - sb.Append(g_tab).Append("void *handler = NULL;\n"); - sb.Append("\n"); - sb.Append(g_tab).AppendFormat("if (snprintf_s(path, sizeof(path), sizeof(path) - 1, \"%%s/%%s\", "); - sb.Append("DRIVER_PATH, libFileName) < 0) {\n"); - sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: snprintf_s failed\", __func__);\n"); - sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); - sb.Append(g_tab).Append("}\n"); - sb.Append("\n"); - sb.Append(g_tab).Append("if (realpath(path, libPath) == NULL) {\n"); - sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s file name invalid\", __func__);\n"); - sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); - sb.Append(g_tab).Append("}\n"); - sb.Append("\n"); - sb.Append(g_tab).Append("handler = dlopen(libPath, RTLD_LAZY);\n"); - sb.Append(g_tab).Append("if (handler == NULL) {\n"); - sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: dlopen failed %{public}s\", "); - sb.AppendFormat("__func__, dlerror());\n"); - sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); - sb.Append(g_tab).Append("}\n"); - sb.Append("\n"); - sb.Append(g_tab).Append("return handler;\n"); - sb.Append("}\n"); -} - -void CppServiceStubCodeEmitter::EmitStubInstanceMethodImpl(StringBuilder& sb) -{ - String objName = "stub"; - String libName = String::Format("lib%s.z.so", FileName(implName_).string()); - sb.AppendFormat("void *%sInstance()\n", stubName_.string()); - sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("using namespace %s;\n", - EmitStubServiceUsings(interface_->GetNamespace()->ToString()).string()); - sb.Append(g_tab).Append("SERVICE_CONSTRUCT_FUNC serviceConstructFunc = nullptr;\n"); - sb.Append(g_tab).AppendFormat("%sStub *%s = new %sStub();\n", infName_.string(), objName.string(), - infName_.string()); - sb.Append(g_tab).AppendFormat("if (%s == nullptr) {\n", objName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: OsalMemAlloc %s failed!\", __func__);\n", - objName.string()); - sb.Append(g_tab).Append(g_tab).Append("return nullptr;\n"); - sb.Append(g_tab).Append("}\n\n"); - sb.Append(g_tab).AppendFormat("%s->dlHandler = LoadServiceHandler(\"%s\");\n", objName.string(), libName.string()); - sb.Append(g_tab).AppendFormat("if (%s->dlHandler == nullptr) {\n", objName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: %s->dlHanlder is null\", __func__);\n", - objName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("delete %s;\n", objName.string()); - sb.Append(g_tab).Append(g_tab).Append("return nullptr;\n"); - sb.Append(g_tab).Append("}\n\n"); - sb.Append(g_tab).AppendFormat("serviceConstructFunc = "); - sb.AppendFormat("(SERVICE_CONSTRUCT_FUNC)dlsym(%s->dlHandler, \"%sServiceConstruct\");\n", - objName.string(), infName_.string()); - sb.Append(g_tab).Append("if (serviceConstructFunc == nullptr) {\n"); - sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: dlsym failed %{public}s\", __func__, dlerror());\n"); - sb.Append(g_tab).Append(g_tab).AppendFormat("dlclose(%s->dlHandler);\n", objName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("delete %s;\n", objName.string()); - sb.Append(g_tab).Append(g_tab).Append("return nullptr;\n"); - sb.Append(g_tab).Append("}\n\n"); - sb.Append(g_tab).AppendFormat("%s->service = serviceConstructFunc();\n", objName.string()); - sb.Append(g_tab).AppendFormat("if (%s->service == nullptr) {\n", objName.string()); - sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: get service failed %{public}s\", "); - sb.Append("__func__, dlerror());\n"); - sb.Append(g_tab).Append(g_tab).AppendFormat("dlclose(%s->dlHandler);\n", objName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("delete %s;\n", objName.string()); - sb.Append(g_tab).Append(g_tab).Append("return nullptr;\n"); - sb.Append(g_tab).Append("}\n\n"); - sb.Append(g_tab).Append("return reinterpret_cast(stub);\n"); - sb.Append("}\n"); -} - -void CppServiceStubCodeEmitter::EmitStubReleaseMethodImpl(StringBuilder& sb) -{ - String objName = "stub"; - sb.AppendFormat("void %sRelease(void *obj)\n", stubName_.string()); - sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("using namespace %s;\n", - EmitStubServiceUsings(interface_->GetNamespace()->ToString()).string()); - sb.Append(g_tab).Append("if (obj == nullptr) {\n"); - sb.Append(g_tab).Append(g_tab).Append("return;\n"); - sb.Append(g_tab).Append("}\n\n"); - sb.Append(g_tab).AppendFormat("%sStub *%s = reinterpret_cast<%sStub *>(obj);\n", infName_.string(), - objName.string(), infName_.string()); - sb.Append(g_tab).AppendFormat("if (%s == nullptr) {\n", objName.string()); - sb.Append(g_tab).Append(g_tab).Append("return;\n"); - sb.Append(g_tab).Append("}\n\n"); - sb.Append(g_tab).Append("SERVICE_RELEASE_FUNC serviceReleaseFunc = "); - sb.AppendFormat("(SERVICE_RELEASE_FUNC)dlsym(%s->dlHandler, \"SampleServiceRelease\");\n", objName.string()); - sb.Append(g_tab).Append("if (serviceReleaseFunc == nullptr) {\n"); - sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: dlsym failed %{public}s\", __func__, dlerror());\n"); - sb.Append(g_tab).Append("} else {\n"); - sb.Append(g_tab).Append(g_tab).AppendFormat("serviceReleaseFunc(%s->service);\n", objName.string()); - sb.Append(g_tab).Append("}\n\n"); - sb.Append(g_tab).AppendFormat("dlclose(%s->dlHandler);\n", objName.string()); - sb.Append(g_tab).AppendFormat("delete %s;\n", objName.string()); - sb.Append("}\n"); -} - -void CppServiceStubCodeEmitter::EmitServiceOnRemoteRequest(StringBuilder& sb) -{ - String stubObjName = String::Format("%sStub", infName_.ToLowerCase().string()); - sb.AppendFormat( - "int32_t %sServiceOnRemoteRequest(void *stub, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)\n", - infName_.string()); - sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("using namespace %s;\n", - EmitStubServiceUsings(interface_->GetNamespace()->ToString()).string()); - sb.Append(g_tab).AppendFormat("%s *%s = reinterpret_cast<%s *>(stub);\n", - stubName_.string(), stubObjName.string(), stubName_.string()); - sb.Append(g_tab).Append("OHOS::MessageParcel *dataParcel = nullptr;\n"); - sb.Append(g_tab).Append("OHOS::MessageParcel *replyParcel = nullptr;\n"); - sb.Append("\n"); - - sb.Append(g_tab).Append("(void)SbufToParcel(reply, &replyParcel);\n"); - sb.Append(g_tab).Append("if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {\n"); - sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s:invalid data sbuf object to dispatch\","); - sb.Append(" __func__);\n"); - sb.Append(g_tab).Append(g_tab).Append("return HDF_ERR_INVALID_PARAM;\n"); - sb.Append(g_tab).Append("}\n\n"); - sb.Append(g_tab).Append("OHOS::MessageOption option;\n"); - sb.Append(g_tab).AppendFormat("return %s->%sOnRemoteRequest(cmdId, *dataParcel, *replyParcel, option);\n", - stubObjName.string(), stubName_.string()); - sb.Append("}\n"); -} - String CppServiceStubCodeEmitter::EmitStubServiceUsings(String nameSpace) { int index = nameSpace.LastIndexOf('.'); diff --git a/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.h b/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.h index c0dd1fd4..afe28f43 100755 --- a/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.h +++ b/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.h @@ -34,26 +34,18 @@ private: void EmitStubDecl(StringBuilder& sb); - void EmitCbStubDecl(StringBuilder& sb); - void EmitStubBody(StringBuilder& sb, const String& prefix); - void EmitCbStubBody(StringBuilder& sb, const String& prefix); - void EmitStubDestruction(StringBuilder& sb, const String& prefix); - void EmitCbStubOnRequestDecl(StringBuilder& sb, const String& prefix); + void EmitStubOnRequestDecl(StringBuilder& sb, const String& prefix); + + void EmitGetVersionDecl(StringBuilder& sb, const String& prefix); void EmitStubMethodDecls(StringBuilder& sb, const String& prefix); void EmitStubMethodDecl(const AutoPtr& method, StringBuilder& sb, const String& prefix); - void EmitStubOnRequestMethodDecl(StringBuilder& sb, const String& prefix); - - void EmitStubMembers(StringBuilder& sb, const String& prefix); - - void EmitStubExternalsMethodsDel(StringBuilder& sb); - // ISample.idl -> sample_service_stub.cpp void EmitStubSourceFile(); @@ -61,9 +53,9 @@ private: void GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet& headerFiles); - void EmitDriverLibPath(StringBuilder& sb); + void EmitStubOnRequestMethodImpl(StringBuilder& sb, const String& prefix); - void EmitLibFuncTypeDef(StringBuilder& sb); + void EmitGetVersionMethodImpl(StringBuilder& sb, const String& prefix); void EmitStubMethodImpls(StringBuilder& sb, const String& prefix); @@ -71,20 +63,6 @@ private: void EmitStubCallMethod(const AutoPtr& method, StringBuilder& sb, const String& prefix); - void EmitStubOnRequestMethodImpl(StringBuilder& sb, const String& prefix); - - void EmitCbStubOnRequestMethodImpl(StringBuilder& sb, const String& prefix); - - void EmitStubExternalsMethodsImpl(StringBuilder& sb, const String& prefix); - - void EmitStubLinkService(StringBuilder& sb); - - void EmitStubInstanceMethodImpl(StringBuilder& sb); - - void EmitStubReleaseMethodImpl(StringBuilder& sb); - - void EmitServiceOnRemoteRequest(StringBuilder& sb); - String EmitStubServiceUsings(String nameSpace); }; } // namespace HDI diff --git a/tools/hdi-gen/parser/file_detail.cpp b/tools/hdi-gen/parser/file_detail.cpp index f4544895..70c499bd 100755 --- a/tools/hdi-gen/parser/file_detail.cpp +++ b/tools/hdi-gen/parser/file_detail.cpp @@ -7,6 +7,7 @@ */ #include "parser/file_detail.h" +#include "util/file.h" #include "util/string_builder.h" namespace OHOS { diff --git a/tools/hdi-gen/parser/file_detail.h b/tools/hdi-gen/parser/file_detail.h index 1684c1e5..88fb2dff 100755 --- a/tools/hdi-gen/parser/file_detail.h +++ b/tools/hdi-gen/parser/file_detail.h @@ -10,6 +10,7 @@ #define OHOS_HDI_FILE_DETAIL_H #include +#include "util/options.h" #include "util/string.h" namespace OHOS { @@ -64,13 +65,13 @@ public: inline static String ImportsToPath(const String& importPkgName) { - return importPkgName.Replace('.', '/') + ".idl"; + return Options::GetInstance().GetPackagePath(importPkgName) + ".idl"; } String Dump(); - private: String idlFilePath_; + String rootPackageName_; String packageName_; String idlName_; StringSet imports_; diff --git a/tools/hdi-gen/parser/lexer.cpp b/tools/hdi-gen/parser/lexer.cpp index 81677a96..1fc0b838 100755 --- a/tools/hdi-gen/parser/lexer.cpp +++ b/tools/hdi-gen/parser/lexer.cpp @@ -35,7 +35,8 @@ void Lexer::InitializeKeywords() { "Map", Token::MAP }, { "oneway", Token::ONEWAY }, { "out", Token::OUT }, { "package", Token::PACKAGE}, { "sequenceable", Token::SEQUENCEABLE }, { "short", Token::SHORT }, { "String", Token::STRING }, { "struct", Token::STRUCT }, { "union", Token::UNION }, - { "unsigned", Token::UNSIGNED }, { "FileDescriptor", Token::FILEDESCRIPTOR } + { "unsigned", Token::UNSIGNED }, { "FileDescriptor", Token::FILEDESCRIPTOR }, + {"SharedMemQueue", Token::SMEMQUEUE}, }; delimiters_ = { @@ -62,7 +63,7 @@ void Lexer::InitializeKeywords() { Token::SEQUENCEABLE, "sequenceable"}, { Token::STRUCT, "struct"}, { Token::PARENTHESES_LEFT, "("}, { Token::PARENTHESES_RIGHT, ")"}, { Token::SEMICOLON, ";"}, { Token::SHORT, "short"}, { Token::STRING, "String"}, { Token::UNION, "union"}, { Token::UNSIGNED, "unsigned"}, - { Token::FILEDESCRIPTOR, "FileDescriptor"} + { Token::FILEDESCRIPTOR, "FileDescriptor"}, {Token::SMEMQUEUE, "SharedMemQueue"}, }; } diff --git a/tools/hdi-gen/parser/lexer.h b/tools/hdi-gen/parser/lexer.h index dde09fda..34c11f84 100755 --- a/tools/hdi-gen/parser/lexer.h +++ b/tools/hdi-gen/parser/lexer.h @@ -9,9 +9,9 @@ #ifndef OHOS_HDI_LEXER_H #define OHOS_HDI_LEXER_H +#include #include #include -#include #include #include "parser/token.h" #include "util/file.h" diff --git a/tools/hdi-gen/parser/parser.cpp b/tools/hdi-gen/parser/parser.cpp index 4a47a31d..92d40c77 100755 --- a/tools/hdi-gen/parser/parser.cpp +++ b/tools/hdi-gen/parser/parser.cpp @@ -7,10 +7,12 @@ */ #include "parser/parser.h" +#include #include "ast/ast_array_type.h" #include "ast/ast_enum_type.h" #include "ast/ast_list_type.h" #include "ast/ast_map_type.h" +#include "ast/ast_smq_type.h" #include "ast/ast_parameter.h" #include "ast/ast_sequenceable_type.h" #include "ast/ast_struct_type.h" @@ -18,6 +20,12 @@ #include "util/logger.h" #include "util/string_builder.h" +#define RE_DIGIT "[0-9]+" +#define RE_IDENTIFIER "[a-zA-Z_][a-zA-Z0-9_]*" + +static const std::regex rePackage(RE_IDENTIFIER "(?:\\." RE_IDENTIFIER ")*\\.[V|v]" "(" RE_DIGIT ")_(" RE_DIGIT ")"); +static const std::regex reImport(RE_IDENTIFIER "(?:\\." RE_IDENTIFIER ")*\\.[V|v]" RE_DIGIT "_" RE_DIGIT "." RE_IDENTIFIER); + namespace OHOS { namespace HDI { const char* Parser::TAG = "Parser"; @@ -249,9 +257,7 @@ bool Parser::ParseLicense() bool Parser::ParsePackageName() { lexer_->GetToken(); - String packageFullName; - Token token = lexer_->PeekToken(); if (token != Token::IDENTIFIER) { if (token == Token::SEMICOLON) { @@ -275,7 +281,6 @@ bool Parser::ParsePackageName() // read ';' lexer_->GetToken(); - if (packageFullName.IsEmpty()) { LogError(String("Package name is not expected.")); return false; @@ -288,11 +293,32 @@ bool Parser::ParsePackageName() return false; } - ast_->SetPackageName(packageFullName); + if (!ParserPackageInfo(packageFullName)) { + LogError(String::Format("Parse package '%s' infomation failed.", packageFullName.string())); + return false; + } return true; } +bool Parser::ParserPackageInfo(const String& packageName) +{ + std::cmatch result; + if (!std::regex_match(packageName.string(), result, rePackage)) { + return false; + } + + if (result.size() < 3) { + return false; + } + + ast_->SetPackageName(result.str(0).c_str()); + size_t majorVersion = std::atoi(result.str(1).c_str()); + size_t minorVersion = std::atoi(result.str(2).c_str()); + ast_->SetVersion(majorVersion, minorVersion); + return true; +} + bool Parser::ParseImport() { lexer_->GetToken(); @@ -497,6 +523,8 @@ bool Parser::ParseInterfaceBody(const AutoPtr& interface) return false; } + SetVersionInterfaceMethod(interface); + ast_->AddInterfaceDef(interface); return ret; } @@ -531,7 +559,7 @@ bool Parser::ParseMethod(const AutoPtr& interface) method->SetName(lexer_->GetIdentifier()); if (attributes != nullptr) { - method->SetOneWay(attributes->isOneWay); + method->SetOneWay(attributes->isOneWay || interface->IsOneWay()); method->SetFull(attributes->isFull); method->SetLite(attributes->isLite); } @@ -544,6 +572,23 @@ bool Parser::ParseMethod(const AutoPtr& interface) return true; } +void Parser::SetVersionInterfaceMethod(const AutoPtr& interface) +{ + AutoPtr method = new ASTMethod(); + method->SetName("GetVersion"); + + AutoPtr type = ast_->FindType("unsigned int"); + if (type == nullptr) { + type = new ASTUintType(); + } + AutoPtr majorParam = new ASTParameter("majorVer", ParamAttr::PARAM_OUT, type); + AutoPtr minorParam = new ASTParameter("minorVer", ParamAttr::PARAM_OUT, type); + + method->AddParameter(majorParam); + method->AddParameter(minorParam); + interface->AddVersionMethod(method); +} + bool Parser::ParseAttributeBody(AutoPtr& attributes) { Token token = lexer_->PeekToken(); @@ -551,31 +596,13 @@ bool Parser::ParseAttributeBody(AutoPtr& attributes) return true; } lexer_->GetToken(); - attributes = new Attribute(); token = lexer_->PeekToken(); while (token != Token::BRACKETS_RIGHT) { - switch (token) { - case Token::ONEWAY: - attributes->isOneWay = true; - break; - case Token::CALLBACK: - attributes->isCallback = true; - break; - case Token::FULL: - attributes->isFull = true; - break; - case Token::LITE: - attributes->isLite = true; - break; - default: { - LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string())); - lexer_->Skip(Lexer::TokenToChar(Token::BRACKETS_RIGHT)); - lexer_->GetToken(); - return false; - } + if (!ParseAttributeParam(attributes)) { + return false; } - lexer_->GetToken(); + token = lexer_->PeekToken(); if (token == Token::COMMA) { lexer_->GetToken(); @@ -593,6 +620,38 @@ bool Parser::ParseAttributeBody(AutoPtr& attributes) return true; } +bool Parser::ParseAttributeParam(AutoPtr& attributes) +{ + Token token = lexer_->GetToken(); + switch (token) { + case Token::ONEWAY: + if (options_.DoGenerateKernelCode()) { + LogError(String::Format("'%s' is not supported in kernel code.", lexer_->DumpToken().string())); + lexer_->Skip(Lexer::TokenToChar(Token::BRACKETS_RIGHT)); + lexer_->GetToken(); + return false; + } + attributes->isOneWay = true; + break; + case Token::CALLBACK: + attributes->isCallback = true; + break; + case Token::FULL: + attributes->isFull = true; + break; + case Token::LITE: + attributes->isLite = true; + break; + default: { + LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string())); + lexer_->Skip(Lexer::TokenToChar(Token::BRACKETS_RIGHT)); + lexer_->GetToken(); + return false; + } + } + return true; +} + bool Parser::ParseParameterList(AutoPtr& method) { bool ret = true; @@ -664,6 +723,12 @@ bool Parser::ParseParameter(const AutoPtr& method) parameter->SetName(lexer_->GetIdentifier()); parameter->SetType(type); + + if (method->IsOneWay() && parameter->GetAttribute() == ParamAttr::PARAM_OUT) { + LogError(String::Format("The attribute of parameter '%s' cannot be 'out'.", parameter->GetName().string())); + return false; + } + method->AddParameter(parameter); return true; } @@ -730,6 +795,8 @@ AutoPtr Parser::ParseType() type = ParseList(); } else if (token == Token::MAP) { type = ParseMap(); + } else if (token == Token::SMEMQUEUE) { + type = ParseSharedMemQueueMetaType(); } else if (token == Token::ENUM || token == Token::STRUCT || token == Token::UNION) { type = ParseCustomType(); } else if (token == Token::IDENTIFIER) { @@ -873,6 +940,41 @@ AutoPtr Parser::ParseMap() return ret; } +AutoPtr Parser::ParseSharedMemQueueMetaType() +{ + lexer_->GetToken(); + + Token token = lexer_->PeekToken(); + if (token != Token::ANGLE_BRACKETS_LEFT) { + LogError(String("'<' is expected.")); + return nullptr; + } + lexer_->GetToken(); + + AutoPtr InnerType = ParseType(); + if (InnerType == nullptr) { + lexer_->SkipCurrentLine('>'); + return nullptr; + } + + token = lexer_->PeekToken(); + if (token != Token::ANGLE_BRACKETS_RIGHT) { + LogError(String("'>' is expected.")); + return nullptr; + } + lexer_->GetToken(); + + AutoPtr type = new ASTSharedMemQueueType(); + type->SetInnerType(InnerType); + AutoPtr ret = ast_->FindType(type->ToString()); + if (ret == nullptr) { + ast_->AddType(type.Get()); + ret = type.Get(); + } + + return ret; +} + AutoPtr Parser::ParseArrayType(const AutoPtr& elementType) { Token token = lexer_->PeekToken(); @@ -1363,19 +1465,14 @@ bool Parser::IsValidTypeName(const String& typeName) /* * For example -* filePath: ./test/cpp_test/data_test/v1_0/IDataTest.idl -* package test.cpp_test.data_test.v1_0; +* filePath: ./ohos/interface/foo/v1_0/IFoo.idl +* package OHOS.Hdi.foo.v1_0; */ bool Parser::CheckPackageName(const String& filePath, const String& packageName) { -#ifndef __MINGW32__ - char delimiter = '/'; -#else - char delimiter = '\\'; -#endif + String pkgToPath = Options::GetInstance().GetPackagePath(packageName); - String pkgToPath = packageName.Replace('.', delimiter); - int index = filePath.LastIndexOf(delimiter); + int index = filePath.LastIndexOf(File::pathSeparator); if (index == -1) { return false; } @@ -1385,7 +1482,7 @@ bool Parser::CheckPackageName(const String& filePath, const String& packageName) return false; } - return true; + return parentDir.EndsWith(pkgToPath); } bool Parser::AddAst() diff --git a/tools/hdi-gen/parser/parser.h b/tools/hdi-gen/parser/parser.h index bfd1f02d..42b39c14 100755 --- a/tools/hdi-gen/parser/parser.h +++ b/tools/hdi-gen/parser/parser.h @@ -73,6 +73,8 @@ private: bool ParsePackageName(); + bool ParserPackageInfo(const String& packageFullName); + bool ParseImport(); bool ParseSequenceable(); @@ -85,8 +87,12 @@ private: bool ParseMethod(const AutoPtr& interface); + void SetVersionInterfaceMethod(const AutoPtr& interface); + bool ParseAttributeBody(AutoPtr& attributes); + bool ParseAttributeParam(AutoPtr& attributes); + bool ParseParameterList(AutoPtr& method); bool ParseParameter(const AutoPtr& method); @@ -101,6 +107,8 @@ private: AutoPtr ParseMap(); + AutoPtr ParseSharedMemQueueMetaType(); + AutoPtr ParseArrayType(const AutoPtr& elementType); AutoPtr ParseCustomType(); diff --git a/tools/hdi-gen/parser/token.h b/tools/hdi-gen/parser/token.h index 108ca1a2..fe11cb46 100755 --- a/tools/hdi-gen/parser/token.h +++ b/tools/hdi-gen/parser/token.h @@ -26,6 +26,7 @@ enum class Token { FILEDESCRIPTOR, LIST, MAP, + SMEMQUEUE, CHAR, // qualifier UNSIGNED, diff --git a/tools/hdi-gen/util/file.cpp b/tools/hdi-gen/util/file.cpp index da620328..76c53646 100755 --- a/tools/hdi-gen/util/file.cpp +++ b/tools/hdi-gen/util/file.cpp @@ -9,8 +9,8 @@ #include "util/file.h" #include #include -#include #include +#include #include #include #include "securec.h" diff --git a/tools/hdi-gen/util/file.h b/tools/hdi-gen/util/file.h index 94de48c8..7bb440b9 100755 --- a/tools/hdi-gen/util/file.h +++ b/tools/hdi-gen/util/file.h @@ -68,6 +68,12 @@ public: static constexpr unsigned int WRITE = 0x2; static constexpr unsigned int APPEND = 0x4; +#ifndef __MINGW32__ + static constexpr char pathSeparator = '/'; +#else + static constexpr char pathSeparator = '\\'; +#endif + private: int Read(); diff --git a/tools/hdi-gen/util/options.cpp b/tools/hdi-gen/util/options.cpp index 6c5b579c..01ef934e 100755 --- a/tools/hdi-gen/util/options.cpp +++ b/tools/hdi-gen/util/options.cpp @@ -13,10 +13,11 @@ #include #include #include +#include "util/file.h" namespace OHOS { namespace HDI { -const char* Options::optSupportArgs = "c:d:"; +const char* Options::optSupportArgs = "c:d:r:"; static struct option g_longOpts[] = { {"help", no_argument, nullptr, 'h'}, {"version", no_argument, nullptr, 'v'}, @@ -48,6 +49,7 @@ Options& Options::Parse(int argc, char* const argv[]) SetOptionData(op); } CheckOptions(); + return *this; } @@ -68,6 +70,9 @@ void Options::SetOptionData(char op) case 'v': doShowVersion_ = true; break; + case 'r': + AddPackagePath(optarg); + break; case 'K': doModeKernel_ = true; break; @@ -100,6 +105,26 @@ void Options::SetOptionData(char op) } } +void Options::AddPackagePath(const String& packagePath) +{ + int index = packagePath.IndexOf(":"); + if (index == -1 || index == packagePath.GetLength() - 1) { + errors_.push_back(String::Format("%s: invalid option parameters '%s'.", program_.string(), + packagePath.string())); + return; + } + + String package = packagePath.Substring(0, index); + String path = packagePath.Substring(index + 1); + + auto it = packagePath_.find(package); + if (it != packagePath_.end()) { + errors_.push_back(String::Format("%s: The '%s:%s' has been set.", program_.string())); + } + + packagePath_[package] = path; +} + void Options::SetLanguage(const String& language) { doGenerateCode_ = true; @@ -171,6 +196,7 @@ void Options::ShowUsage() const " --help Display command line options\n" " --version Display toolchain version information\n" " --dump-ast Display the AST of the compiled file\n" + " -r : set root path of root package\n" " -c <*.idl> Compile the .idl file\n" " --gen-hash Generate hash key of the idl file\n" " --gen-c Generate C code\n" @@ -182,5 +208,68 @@ void Options::ShowUsage() const " --build-target Generate client code, server code or all code\n" " -d Place generated codes into \n"); } + +/* +*For Example +*-r option: -r OHOS.Hdi:drivers/interface +*package:OHOS.Hdi.foo.v1_0 +*rootPackage:OHOS.Hdi +*/ +String Options::GetRootPackage(const String& package) +{ + const auto& packagePaths = GetPackagePath(); + for (const auto& packageRoot : packagePaths) { + if (package.StartsWith(packageRoot.first)) { + return packageRoot.first; + } + } + + return String(""); +} + +/* +*For Example +*-r option: -r OHOS.Hdi:drivers/interface +*package:OHOS.Hdi.foo.v1_0 +*subPackage:foo.v1_0 +*/ +String Options::GetSubPackage(const String& package) +{ + String rootPackage = GetRootPackage(package); + if (rootPackage.IsEmpty()) { + return package; + } + + return package.Substring(rootPackage.GetLength() + 1); +} + +/* +*For Example +*-r option: -r OHOS.Hdi:drivers/interface +*package:OHOS.Hdi.foo.v1_0 +*packagePath:drivers/interface/foo/v1_0 +*/ +String Options::GetPackagePath(const String& package) +{ + String rootPackage = ""; + String rootPath = ""; + const auto& packagePaths = GetPackagePath(); + for (const auto& packageRoot : packagePaths) { + if (package.StartsWith(packageRoot.first)) { + rootPackage = packageRoot.first; + rootPath = packageRoot.second; + } + } + + if (rootPackage.IsEmpty()) { + return package.Replace('.', File::pathSeparator); + } + + if (rootPath.EndsWith(File::pathSeparator)) { + rootPath = rootPath.Substring(0, rootPath.GetLength() - 1); + } + + return package.Replace(rootPackage, rootPath).Replace('.', File::pathSeparator); +} } // namespace HDI } // namespace OHOS \ No newline at end of file diff --git a/tools/hdi-gen/util/options.h b/tools/hdi-gen/util/options.h index d33f1aec..e3dccec8 100755 --- a/tools/hdi-gen/util/options.h +++ b/tools/hdi-gen/util/options.h @@ -9,6 +9,7 @@ #ifndef OHOS_HDI_OPTION_H #define OHOS_HDI_OPTION_H +#include #include #include "util/string.h" @@ -16,6 +17,8 @@ namespace OHOS { namespace HDI { class Options { public: + using PkgPathMap = std::unordered_map; + static Options& GetInstance(); Options(const Options& other) = delete; @@ -70,6 +73,11 @@ public: return sourceFiles_; } + inline PkgPathMap GetPackagePath() const + { + return packagePath_; + } + inline String GetTargetLanguage() const { return targetLanguage_; @@ -96,6 +104,11 @@ public: void ShowUsage() const; + String GetRootPackage(const String& package); + + String GetSubPackage(const String& package); + + String GetPackagePath(const String& package); private: Options() : program_(), sourceFiles_(0), @@ -117,6 +130,8 @@ private: void SetOptionData(char op); + void AddPackagePath(const String& packagePath); + void SetLanguage(const String& language); void SetCodePart(const String& part); @@ -137,6 +152,7 @@ private: String generationDirectory_; String illegalOptions_; std::vector errors_; + PkgPathMap packagePath_; bool doShowUsage_; bool doShowVersion_; diff --git a/tools/hdi-gen/util/string.cpp b/tools/hdi-gen/util/string.cpp index 3359e790..9f4d3a64 100755 --- a/tools/hdi-gen/util/string.cpp +++ b/tools/hdi-gen/util/string.cpp @@ -409,6 +409,20 @@ bool String::StartsWith(const String& other) const return memcmp(string_, other.string_, count) == 0; } +bool String::EndsWith(char c) const +{ + if (string_ == nullptr) { + return false; + } + + size_t len = GetLength(); + if (len < 1) { + return false; + } + + return string_[len - 1] == c; +} + bool String::EndsWith(const char* string) const { if (string == nullptr || string_ == nullptr) { @@ -485,6 +499,29 @@ String String::ToUpperCase() const return *this; } +String String::ToUnderLineUpper() const +{ + if (IsEmpty()) { + return *this; + } + + StringBuilder sb; + + for (int i = 0; i < GetLength(); i++) { + char c = string_[i]; + if (isupper(c) != 0) { + if (i > 1) { + sb.Append('_');; + } + sb.Append(c); + } else { + sb.Append(toupper(c)); + } + } + + return sb.ToString(); +} + String String::Substring(int begin) const { if (begin < 0 || begin >= GetLength()) { diff --git a/tools/hdi-gen/util/string.h b/tools/hdi-gen/util/string.h index 2330f88a..f11e9394 100755 --- a/tools/hdi-gen/util/string.h +++ b/tools/hdi-gen/util/string.h @@ -77,6 +77,8 @@ public: bool StartsWith(const String& other) const; + bool EndsWith(char c) const; + bool EndsWith(const char* string) const; bool EndsWith(const String& other) const; @@ -85,6 +87,8 @@ public: String ToUpperCase() const; + String ToUnderLineUpper() const; + String Substring(int begin) const; String Substring(int begin, int end) const;